blob: 7596d47cd2faa1c004c8ddb23fc271a75d33c87f [file] [log] [blame]
R. Andrew Ohana81c2e052012-10-03 19:52:52 -07001/*
2 * Copyright (C) 2012, The CyanogenMod Project
3 * Daniel Hillenbrand <codeworkx@cyanogenmod.com>
4 * Marco Hillenbrand <marco.hillenbrand@googlemail.com>
Paul Keith59ba89e2017-02-07 12:30:45 -06005 * Copyright (C) 2017, The LineageOS Project
R. Andrew Ohana81c2e052012-10-03 19:52:52 -07006 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 */
19
Andreas Schneider2b601792015-01-26 23:14:17 +010020#define LOG_TAG "macloader"
21#define LOG_NDEBUG 0
R. Andrew Ohana81c2e052012-10-03 19:52:52 -070022
23#include <stdio.h>
24#include <stdlib.h>
25#include <string.h>
Andreas Schneider3ff947b2015-01-26 22:56:30 +010026#include <sys/types.h>
R. Andrew Ohana81c2e052012-10-03 19:52:52 -070027#include <sys/stat.h>
Andreas Schneider3ff947b2015-01-26 22:56:30 +010028#include <fcntl.h>
Andreas Schneider7f517d72015-01-26 23:19:03 +010029#include <unistd.h>
Andreas Schneider7558b9d2015-01-26 23:29:18 +010030#include <pwd.h>
Caio Schnepper02c9c712015-10-10 02:14:28 -030031#include <errno.h>
R. Andrew Ohana81c2e052012-10-03 19:52:52 -070032
Andreas Schneider2b601792015-01-26 23:14:17 +010033#include <cutils/log.h>
R. Andrew Ohana81c2e052012-10-03 19:52:52 -070034
Paul Keith59ba89e2017-02-07 12:30:45 -060035#include <samsung_macloader.h>
R. Andrew Ohana81c2e052012-10-03 19:52:52 -070036
Christopher N. Hesseafec0fd2017-02-09 19:17:06 +010037#include "macaddr_mappings.h"
R. Andrew Ohana81c2e052012-10-03 19:52:52 -070038
Andreas Schneider3ff947b2015-01-26 22:56:30 +010039static int wifi_change_nvram_calibration(const char *nvram_file,
40 const char *type)
41{
42 int len;
43 int fd = -1;
44 int ret = 0;
45 struct stat sb;
46 char nvram_str[1024] = { 0 };
47
48 if (nvram_file == NULL || type == NULL) {
Christopher N. Hesseafec0fd2017-02-09 19:17:06 +010049 ret = -1;
50 goto out;
Andreas Schneider3ff947b2015-01-26 22:56:30 +010051 }
52
53 ret = stat(nvram_file, &sb);
54 if (ret != 0) {
55 ALOGE("Failed to check for NVRAM calibration file '%s' - error: %s",
56 nvram_file,
57 strerror(errno));
Christopher N. Hesseafec0fd2017-02-09 19:17:06 +010058 ret = -1;
59 goto out;
Andreas Schneider3ff947b2015-01-26 22:56:30 +010060 }
61
62 ALOGD("Using NVRAM calibration file: %s\n", nvram_file);
63
64 fd = TEMP_FAILURE_RETRY(open(WIFI_DRIVER_NVRAM_PATH_PARAM, O_WRONLY));
65 if (fd < 0) {
66 ALOGE("Failed to open wifi nvram config path %s - error: %s",
67 WIFI_DRIVER_NVRAM_PATH_PARAM, strerror(errno));
Christopher N. Hesseafec0fd2017-02-09 19:17:06 +010068 ret = -1;
69 goto out;
Andreas Schneider3ff947b2015-01-26 22:56:30 +010070 }
71
72 len = strlen(nvram_file) + 1;
73 if (TEMP_FAILURE_RETRY(write(fd, nvram_file, len)) != len) {
74 ALOGE("Failed to write to wifi config path %s - error: %s",
75 WIFI_DRIVER_NVRAM_PATH_PARAM, strerror(errno));
76 ret = -1;
77 goto out;
78 }
79
80 snprintf(nvram_str, sizeof(nvram_str), "%s_%s",
81 nvram_file, type);
82
83 ALOGD("Changing NVRAM calibration file for %s chipset\n", type);
84
85 ret = stat(nvram_str, &sb);
86 if (ret != 0) {
87 ALOGW("NVRAM calibration file '%s' doesn't exist", nvram_str);
88 /*
89 * We were able to write the default calibration file. So
90 * continue here without returning an error.
91 */
92 ret = 0;
93 goto out;
94 }
95
96 len = strlen(nvram_str) + 1;
97 if (TEMP_FAILURE_RETRY(write(fd, nvram_str, len)) != len) {
98 ALOGW("Failed to write to wifi config path %s - error: %s",
99 WIFI_DRIVER_NVRAM_PATH_PARAM, strerror(errno));
100 /*
101 * We were able to write the default calibration file. So
102 * continue here without returning an error.
103 */
104 ret = 0;
105 goto out;
106 }
107
108 ALOGD("NVRAM calibration file set to '%s'\n", nvram_str);
109
Andreas Schneider3ff947b2015-01-26 22:56:30 +0100110out:
111 if (fd != -1) {
112 close(fd);
113 }
114 return ret;
115}
116
Christopher N. Hesseafec0fd2017-02-09 19:17:06 +0100117static int classify_macaddr_half(char const *macaddr_half)
118{
119 int type = NONE;
120 unsigned int i, j;
121 char const *macaddr;
122
123 for (i = 0; i < TYPE_MAX; i++) {
124 for (j = 0; j < MAX_RANGE_ENTRIES; j++) {
125 macaddr = all_ranges[i]->macaddrs[j];
126 if (macaddr[0] == '\0') {
127 break;
128 }
129 // macaddr_half is guaranteed to be null terminated
130 if (strcasecmp(macaddr_half, macaddr) == 0) {
131 type = all_ranges[i]->type;
132 goto exit;
133 }
134 }
135 }
136
137exit:
138 if (type != NONE) {
139 ALOGV("Found CID type: %d", type);
140 }
141 return type;
142}
143
R. Andrew Ohana81c2e052012-10-03 19:52:52 -0700144int main() {
Christopher N. Hesseafec0fd2017-02-09 19:17:06 +0100145 FILE* file = NULL;
146 FILE* cidfile = NULL;
R. Andrew Ohana81c2e052012-10-03 19:52:52 -0700147 char* str;
Christopher N. Hesseafec0fd2017-02-09 19:17:06 +0100148 char mac_addr_half[RANGE_ENTRY_LEN + 1] = {0};
149 int ret = 0;
R. Andrew Ohana81c2e052012-10-03 19:52:52 -0700150 int amode;
151 enum Type type = NONE;
152
153 /* open mac addr file */
154 file = fopen(MACADDR_PATH, "r");
codeworkx84f8d1d2012-12-13 17:23:45 +0100155 if (file == 0) {
R. Andrew Ohana81c2e052012-10-03 19:52:52 -0700156 fprintf(stderr, "open(%s) failed\n", MACADDR_PATH);
157 ALOGE("Can't open %s\n", MACADDR_PATH);
Christopher N. Hesseafec0fd2017-02-09 19:17:06 +0100158 ret = -1;
159 goto out;
R. Andrew Ohana81c2e052012-10-03 19:52:52 -0700160 }
161
162 /* get and compare mac addr */
Christopher N. Hesseafec0fd2017-02-09 19:17:06 +0100163 str = fgets(mac_addr_half, RANGE_ENTRY_LEN, file);
Andreas Schneider3a73bd32015-01-26 23:30:13 +0100164 fclose(file);
codeworkx84f8d1d2012-12-13 17:23:45 +0100165 if (str == 0) {
R. Andrew Ohana81c2e052012-10-03 19:52:52 -0700166 fprintf(stderr, "fgets() from file %s failed\n", MACADDR_PATH);
167 ALOGE("Can't read from %s\n", MACADDR_PATH);
Christopher N. Hesseafec0fd2017-02-09 19:17:06 +0100168 ret = -1;
169 goto out;
R. Andrew Ohana81c2e052012-10-03 19:52:52 -0700170 }
171
Christopher N. Hesseafec0fd2017-02-09 19:17:06 +0100172 type = classify_macaddr_half(mac_addr_half);
173 if (type == NONE) {
R. Andrew Ohana81c2e052012-10-03 19:52:52 -0700174 /* delete cid file if no specific type */
175 ALOGD("Deleting file %s\n", CID_PATH);
176 remove(CID_PATH);
Christopher N. Hesseafec0fd2017-02-09 19:17:06 +0100177 ret = 0;
178 goto out;
R. Andrew Ohana81c2e052012-10-03 19:52:52 -0700179 }
Christopher N. Hesseafec0fd2017-02-09 19:17:06 +0100180
181 const char *nvram_file;
182 const char *type_str;
183 struct passwd *pwd;
184 int fd;
185
186 switch(type) {
187 case MURATA:
188 type_str = "murata";
189 break;
190 case SEMCOSH:
191 type_str = "semcosh";
192 break;
193 case SEMCOVE:
194 type_str = "semcove";
195 break;
196 case SEMCO3RD:
197 type_str = "semco3rd";
198 break;
199 case SEMCO:
200 type_str = "semco";
201 break;
202 case WISOL:
203 type_str = "wisol";
204 break;
205 default:
206 ALOGE("Unknown CID type: %d", type);
207 ret = -1;
208 goto out;
209 }
210
211 ALOGI("Settting wifi type to %s in %s\n", type_str, CID_PATH);
212
213 /* open cid file */
214 cidfile = fopen(CID_PATH, "w");
215 if (cidfile == NULL) {
216 fprintf(stderr,
217 "open(%s) failed: %s\n",
218 CID_PATH,
219 strerror(errno));
220 ALOGE("Can't open %s: %s\n", CID_PATH, strerror(errno));
221 ret = -1;
222 goto out;
223 }
224
225 ret = fputs(type_str, cidfile);
226 if (ret != 0) {
227 ALOGE("Can't write to %s\n", CID_PATH);
228 ret = -1;
229 goto out;
230 }
231
232 /* Change permissions of cid file */
233 ALOGD("Change permissions of %s\n", CID_PATH);
234
235 fd = fileno(cidfile);
236 amode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
237 ret = fchmod(fd, amode);
238 if (ret != 0) {
239 ALOGE("Can't set permissions on %s - %s\n",
240 CID_PATH, strerror(errno));
241 ret = -1;
242 goto out;
243 }
244
245 pwd = getpwnam("system");
246 if (pwd == NULL) {
247 ALOGE("Failed to find 'system' user - %s\n",
248 strerror(errno));
249 ret = -1;
250 goto out;
251 }
252
253 ret = fchown(fd, pwd->pw_uid, pwd->pw_gid);
254 if (ret != 0) {
255 ALOGE("Failed to change owner of %s - %s\n",
256 CID_PATH, strerror(errno));
257 ret = -1;
258 goto out;
259 }
260
261 nvram_file = WIFI_DRIVER_NVRAM_PATH;
262 if (nvram_file != NULL) {
263 ret = wifi_change_nvram_calibration(nvram_file, type_str);
264 if (ret != 0) {
265 ret = -1;
266 goto out;
267 }
268 }
269
270out:
271 if (file) {
272 fclose(file);
273 }
274 if (cidfile) {
275 fclose(cidfile);
276 }
277 if (ret < 0) {
278 ALOGE("Macloader error return code: %d", ret);
279 }
280
281 return ret;
R. Andrew Ohana81c2e052012-10-03 19:52:52 -0700282}