macloader: Rework mac address half classification

* Don't return in the middle of a function, set the
   return code and jump to the exit point instead.
 * Close file pointers properly.
 * Unify error code returns (macloader will always exit
   with -1 on error now).

Change-Id: I32ac8ea85fcbabed45550a4d176ac999eff9f9e9
tirimbino
Christopher N. Hesse 8 years ago
parent 759368fbc0
commit afec0fd5ca
  1. 146
      macloader/macaddr_mappings.h
  2. 310
      macloader/macloader.c

@ -0,0 +1,146 @@
/*
* Copyright (C) 2017, The LineageOS Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MACADDR_MAPPINGS_H
#define MACADDR_MAPPINGS_H
#define MAX_RANGE_ENTRIES 100
#define RANGE_ENTRY_LEN 9
enum Type {
NONE,
MURATA,
SEMCOSH,
SEMCOVE,
SEMCO3RD,
SEMCO,
WISOL,
TYPE_MAX = WISOL
};
struct company_range {
int type;
char macaddrs[MAX_RANGE_ENTRIES][RANGE_ENTRY_LEN];
};
/*
* address mappings from http://hwaddress.com
*/
static const struct company_range murata_ranges = {
.type = MURATA,
.macaddrs = {
"00:0e:6d",
"00:13:e0",
"00:21:e8",
"00:26:e8",
"00:37:6d",
"00:60:57",
"00:ae:fa",
"04:46:65",
"10:5f:06",
"10:a5:d0",
"10:d5:42",
"14:7d:c5",
"1c:99:4c",
"20:02:af",
"40:f3:08",
"44:a7:cf",
"5c:da:d4",
"5c:f8:a1",
"60:21:c0",
"60:f1:89",
"78:4b:87",
"78:52:1a",
"88:30:8a",
"90:b6:86",
"98:f1:70",
"a0:cc:2b",
"a4:08:ea",
"b0:72:bf",
"b8:d7:af",
"c8:14:79",
"d0:e4:4a",
"d8:c4:6a",
"dc:ef:ca",
"f0:27:65",
"fc:c2:de",
"fc:db:b3"
}
};
static const struct company_range semcosh_ranges = {
.type = SEMCOSH,
.macaddrs = {
"34:23:ba",
"38:aa:3c",
"5c:0a:5b",
"88:32:9b",
"90:18:7c",
"cc:3a:61"
}
};
static const struct company_range semco3rd_ranges = {
.type = SEMCO3RD,
.macaddrs = {
"2c:0e:3d",
"54:88:0e",
"84:38:38",
"8c:f5:a3",
"ac:36:13",
"ac:5f:3e",
"b4:79:a7",
"c0:97:27",
"c0:bd:d1",
"c8:ba:94",
"d0:25:44",
"e8:50:8b",
"ec:1f:72",
"ec:9b:f3",
"f0:25:b7",
"f4:09:d8",
"f8:04:2e"
}
};
static const struct company_range semco_ranges = {
.type = SEMCO,
.macaddrs = {
"4c:66:41",
"51:f6:6b",
"d8:c4:e9",
"ec:9b:f3"
}
};
static const struct company_range wisol_ranges = {
.type = WISOL,
.macaddrs = {
"48:5a:3f",
"70:2c:1f"
}
};
static const struct company_range *all_ranges[TYPE_MAX] = {
&murata_ranges,
&semcosh_ranges,
&semco3rd_ranges,
&semco_ranges,
&wisol_ranges
};
#endif // MACADDR_MAPPINGS_H

@ -34,15 +34,7 @@
#include <samsung_macloader.h>
enum Type {
NONE,
MURATA,
SEMCOSH,
SEMCOVE,
SEMCO3RD,
SEMCO,
WISOL
};
#include "macaddr_mappings.h"
static int wifi_change_nvram_calibration(const char *nvram_file,
const char *type)
@ -54,7 +46,8 @@ static int wifi_change_nvram_calibration(const char *nvram_file,
char nvram_str[1024] = { 0 };
if (nvram_file == NULL || type == NULL) {
return -1;
ret = -1;
goto out;
}
ret = stat(nvram_file, &sb);
@ -62,7 +55,8 @@ static int wifi_change_nvram_calibration(const char *nvram_file,
ALOGE("Failed to check for NVRAM calibration file '%s' - error: %s",
nvram_file,
strerror(errno));
return -1;
ret = -1;
goto out;
}
ALOGD("Using NVRAM calibration file: %s\n", nvram_file);
@ -71,7 +65,8 @@ static int wifi_change_nvram_calibration(const char *nvram_file,
if (fd < 0) {
ALOGE("Failed to open wifi nvram config path %s - error: %s",
WIFI_DRIVER_NVRAM_PATH_PARAM, strerror(errno));
return -1;
ret = -1;
goto out;
}
len = strlen(nvram_file) + 1;
@ -112,7 +107,6 @@ static int wifi_change_nvram_calibration(const char *nvram_file,
ALOGD("NVRAM calibration file set to '%s'\n", nvram_str);
ret = 0;
out:
if (fd != -1) {
close(fd);
@ -120,12 +114,39 @@ out:
return ret;
}
static int classify_macaddr_half(char const *macaddr_half)
{
int type = NONE;
unsigned int i, j;
char const *macaddr;
for (i = 0; i < TYPE_MAX; i++) {
for (j = 0; j < MAX_RANGE_ENTRIES; j++) {
macaddr = all_ranges[i]->macaddrs[j];
if (macaddr[0] == '\0') {
break;
}
// macaddr_half is guaranteed to be null terminated
if (strcasecmp(macaddr_half, macaddr) == 0) {
type = all_ranges[i]->type;
goto exit;
}
}
}
exit:
if (type != NONE) {
ALOGV("Found CID type: %d", type);
}
return type;
}
int main() {
FILE* file;
FILE* cidfile;
FILE* file = NULL;
FILE* cidfile = NULL;
char* str;
char mac_addr_half[9];
int ret = -1;
char mac_addr_half[RANGE_ENTRY_LEN + 1] = {0};
int ret = 0;
int amode;
enum Type type = NONE;
@ -134,189 +155,128 @@ int main() {
if (file == 0) {
fprintf(stderr, "open(%s) failed\n", MACADDR_PATH);
ALOGE("Can't open %s\n", MACADDR_PATH);
return -1;
ret = -1;
goto out;
}
/* get and compare mac addr */
str = fgets(mac_addr_half, 9, file);
str = fgets(mac_addr_half, RANGE_ENTRY_LEN, file);
fclose(file);
if (str == 0) {
fprintf(stderr, "fgets() from file %s failed\n", MACADDR_PATH);
ALOGE("Can't read from %s\n", MACADDR_PATH);
return -1;
ret = -1;
goto out;
}
/* murata
ref: http://hwaddress.com/?q=ACT */
if (strncasecmp(mac_addr_half, "00:0e:6d", 9) == 0 ||
strncasecmp(mac_addr_half, "00:13:e0", 9) == 0 ||
strncasecmp(mac_addr_half, "00:21:e8", 9) == 0 ||
strncasecmp(mac_addr_half, "00:26:e8", 9) == 0 ||
strncasecmp(mac_addr_half, "00:37:6d", 9) == 0 ||
strncasecmp(mac_addr_half, "00:60:57", 9) == 0 ||
strncasecmp(mac_addr_half, "00:ae:fa", 9) == 0 ||
strncasecmp(mac_addr_half, "04:46:65", 9) == 0 ||
strncasecmp(mac_addr_half, "10:5f:06", 9) == 0 ||
strncasecmp(mac_addr_half, "10:a5:d0", 9) == 0 ||
strncasecmp(mac_addr_half, "10:d5:42", 9) == 0 ||
strncasecmp(mac_addr_half, "14:7d:c5", 9) == 0 ||
strncasecmp(mac_addr_half, "1c:99:4c", 9) == 0 ||
strncasecmp(mac_addr_half, "20:02:af", 9) == 0 ||
strncasecmp(mac_addr_half, "40:f3:08", 9) == 0 ||
strncasecmp(mac_addr_half, "44:a7:cf", 9) == 0 ||
strncasecmp(mac_addr_half, "5c:da:d4", 9) == 0 ||
strncasecmp(mac_addr_half, "5c:f8:a1", 9) == 0 ||
strncasecmp(mac_addr_half, "60:21:c0", 9) == 0 ||
strncasecmp(mac_addr_half, "60:f1:89", 9) == 0 ||
strncasecmp(mac_addr_half, "78:4b:87", 9) == 0 ||
strncasecmp(mac_addr_half, "78:52:1a", 9) == 0 ||
strncasecmp(mac_addr_half, "88:30:8a", 9) == 0 ||
strncasecmp(mac_addr_half, "90:b6:86", 9) == 0 ||
strncasecmp(mac_addr_half, "98:f1:70", 9) == 0 ||
strncasecmp(mac_addr_half, "a0:cc:2b", 9) == 0 ||
strncasecmp(mac_addr_half, "a4:08:ea", 9) == 0 ||
strncasecmp(mac_addr_half, "b0:72:bf", 9) == 0 ||
strncasecmp(mac_addr_half, "b8:d7:af", 9) == 0 ||
strncasecmp(mac_addr_half, "c8:14:79", 9) == 0 ||
strncasecmp(mac_addr_half, "d0:e4:4a", 9) == 0 ||
strncasecmp(mac_addr_half, "d8:c4:6a", 9) == 0 ||
strncasecmp(mac_addr_half, "dc:ef:ca", 9) == 0 ||
strncasecmp(mac_addr_half, "f0:27:65", 9) == 0 ||
strncasecmp(mac_addr_half, "fc:c2:de", 9) == 0 ||
strncasecmp(mac_addr_half, "fc:db:b3", 9) == 0) {
type = MURATA;
type = classify_macaddr_half(mac_addr_half);
if (type == NONE) {
/* delete cid file if no specific type */
ALOGD("Deleting file %s\n", CID_PATH);
remove(CID_PATH);
ret = 0;
goto out;
}
/* semcosh */
if (strncasecmp(mac_addr_half, "34:23:ba", 9) == 0 ||
strncasecmp(mac_addr_half, "38:aa:3c", 9) == 0 ||
strncasecmp(mac_addr_half, "5c:0a:5b", 9) == 0 ||
strncasecmp(mac_addr_half, "88:32:9b", 9) == 0 ||
strncasecmp(mac_addr_half, "90:18:7c", 9) == 0 ||
strncasecmp(mac_addr_half, "cc:3a:61", 9) == 0) {
type = SEMCOSH;
}
const char *nvram_file;
const char *type_str;
struct passwd *pwd;
int fd;
/* semco3rd */
if (strncasecmp(mac_addr_half, "2c:0e:3d", 9) == 0 ||
strncasecmp(mac_addr_half, "54:88:0e", 9) == 0 ||
strncasecmp(mac_addr_half, "84:38:38", 9) == 0 ||
strncasecmp(mac_addr_half, "8c:f5:a3", 9) == 0 ||
strncasecmp(mac_addr_half, "ac:36:13", 9) == 0 ||
strncasecmp(mac_addr_half, "ac:5f:3e", 9) == 0 ||
strncasecmp(mac_addr_half, "b4:79:a7", 9) == 0 ||
strncasecmp(mac_addr_half, "c0:97:27", 9) == 0 ||
strncasecmp(mac_addr_half, "c0:bd:d1", 9) == 0 ||
strncasecmp(mac_addr_half, "c8:ba:94", 9) == 0 ||
strncasecmp(mac_addr_half, "d0:25:44", 9) == 0 ||
strncasecmp(mac_addr_half, "e8:50:8b", 9) == 0 ||
strncasecmp(mac_addr_half, "ec:1f:72", 9) == 0 ||
strncasecmp(mac_addr_half, "ec:9b:f3", 9) == 0 ||
strncasecmp(mac_addr_half, "f0:25:b7", 9) == 0 ||
strncasecmp(mac_addr_half, "f4:09:d8", 9) == 0 ||
strncasecmp(mac_addr_half, "f8:04:2e", 9) == 0) {
type = SEMCO3RD;
switch(type) {
case MURATA:
type_str = "murata";
break;
case SEMCOSH:
type_str = "semcosh";
break;
case SEMCOVE:
type_str = "semcove";
break;
case SEMCO3RD:
type_str = "semco3rd";
break;
case SEMCO:
type_str = "semco";
break;
case WISOL:
type_str = "wisol";
break;
default:
ALOGE("Unknown CID type: %d", type);
ret = -1;
goto out;
}
/* semco */
if (strncasecmp(mac_addr_half, "4c:66:41", 9) == 0 ||
strncasecmp(mac_addr_half, "51:f6:6b", 9) == 0 ||
strncasecmp(mac_addr_half, "ec:9b:f3", 9) == 0 ||
strncasecmp(mac_addr_half, "d8:c4:e9", 9) == 0) {
type = SEMCO;
}
ALOGI("Settting wifi type to %s in %s\n", type_str, CID_PATH);
/* wisol */
if (strncasecmp(mac_addr_half, "48:5a:3f", 9) == 0 ||
strncasecmp(mac_addr_half, "70:2c:1f", 9) == 0) {
type = WISOL;
/* open cid file */
cidfile = fopen(CID_PATH, "w");
if (cidfile == NULL) {
fprintf(stderr,
"open(%s) failed: %s\n",
CID_PATH,
strerror(errno));
ALOGE("Can't open %s: %s\n", CID_PATH, strerror(errno));
ret = -1;
goto out;
}
if (type != NONE) {
const char *nvram_file;
const char *type_str;
struct passwd *pwd;
int fd;
/* open cid file */
cidfile = fopen(CID_PATH, "w");
if(cidfile == 0) {
fprintf(stderr, "open(%s) failed\n", CID_PATH);
ALOGE("Can't open %s\n", CID_PATH);
return -1;
}
ret = fputs(type_str, cidfile);
if (ret != 0) {
ALOGE("Can't write to %s\n", CID_PATH);
ret = -1;
goto out;
}
switch(type) {
case NONE:
return -1;
case MURATA:
type_str = "murata";
break;
case SEMCOSH:
type_str = "semcosh";
break;
case SEMCOVE:
type_str = "semcove";
break;
case SEMCO3RD:
type_str = "semco3rd";
break;
case SEMCO:
type_str = "semco";
break;
case WISOL:
type_str = "wisol";
break;
}
/* Change permissions of cid file */
ALOGD("Change permissions of %s\n", CID_PATH);
ALOGI("Settting wifi type to %s in %s\n", type_str, CID_PATH);
fd = fileno(cidfile);
amode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
ret = fchmod(fd, amode);
if (ret != 0) {
ALOGE("Can't set permissions on %s - %s\n",
CID_PATH, strerror(errno));
ret = -1;
goto out;
}
ret = fputs(type_str, cidfile);
if (ret != 0) {
ALOGE("Can't write to %s\n", CID_PATH);
return 1;
}
pwd = getpwnam("system");
if (pwd == NULL) {
ALOGE("Failed to find 'system' user - %s\n",
strerror(errno));
ret = -1;
goto out;
}
/* Change permissions of cid file */
ALOGD("Change permissions of %s\n", CID_PATH);
ret = fchown(fd, pwd->pw_uid, pwd->pw_gid);
if (ret != 0) {
ALOGE("Failed to change owner of %s - %s\n",
CID_PATH, strerror(errno));
ret = -1;
goto out;
}
fd = fileno(cidfile);
amode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
ret = fchmod(fd, amode);
nvram_file = WIFI_DRIVER_NVRAM_PATH;
if (nvram_file != NULL) {
ret = wifi_change_nvram_calibration(nvram_file, type_str);
if (ret != 0) {
fclose(cidfile);
ALOGE("Can't set permissions on %s - %s\n",
CID_PATH, strerror(errno));
return 1;
}
pwd = getpwnam("system");
if (pwd == NULL) {
fclose(cidfile);
ALOGE("Failed to find 'system' user - %s\n",
strerror(errno));
return 1;
ret = -1;
goto out;
}
}
ret = fchown(fd, pwd->pw_uid, pwd->pw_gid);
out:
if (file) {
fclose(file);
}
if (cidfile) {
fclose(cidfile);
if (ret != 0) {
ALOGE("Failed to change owner of %s - %s\n",
CID_PATH, strerror(errno));
return 1;
}
nvram_file = WIFI_DRIVER_NVRAM_PATH;
if (nvram_file != NULL) {
ret = wifi_change_nvram_calibration(nvram_file, type_str);
if (ret != 0) {
return 1;
}
}
} else {
/* delete cid file if no specific type */
ALOGD("Deleting file %s\n", CID_PATH);
remove(CID_PATH);
}
return 0;
if (ret < 0) {
ALOGE("Macloader error return code: %d", ret);
}
return ret;
}

Loading…
Cancel
Save