blob: 343ed95874ef15cf92d7d8f7cf3a7cb4277cfa49 [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;
Christopher N. Hesseafec0fd2017-02-09 19:17:06 +0100193 case SEMCO3RD:
194 type_str = "semco3rd";
195 break;
196 case SEMCO:
197 type_str = "semco";
198 break;
199 case WISOL:
200 type_str = "wisol";
201 break;
202 default:
203 ALOGE("Unknown CID type: %d", type);
204 ret = -1;
205 goto out;
206 }
207
208 ALOGI("Settting wifi type to %s in %s\n", type_str, CID_PATH);
209
210 /* open cid file */
211 cidfile = fopen(CID_PATH, "w");
212 if (cidfile == NULL) {
213 fprintf(stderr,
214 "open(%s) failed: %s\n",
215 CID_PATH,
216 strerror(errno));
217 ALOGE("Can't open %s: %s\n", CID_PATH, strerror(errno));
218 ret = -1;
219 goto out;
220 }
221
222 ret = fputs(type_str, cidfile);
223 if (ret != 0) {
224 ALOGE("Can't write to %s\n", CID_PATH);
225 ret = -1;
226 goto out;
227 }
228
229 /* Change permissions of cid file */
230 ALOGD("Change permissions of %s\n", CID_PATH);
231
232 fd = fileno(cidfile);
Kevin F. Haggerty523971c2017-12-28 09:01:32 -0700233 amode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
Christopher N. Hesseafec0fd2017-02-09 19:17:06 +0100234 ret = fchmod(fd, amode);
235 if (ret != 0) {
236 ALOGE("Can't set permissions on %s - %s\n",
237 CID_PATH, strerror(errno));
238 ret = -1;
239 goto out;
240 }
241
242 pwd = getpwnam("system");
243 if (pwd == NULL) {
244 ALOGE("Failed to find 'system' user - %s\n",
245 strerror(errno));
246 ret = -1;
247 goto out;
248 }
249
250 ret = fchown(fd, pwd->pw_uid, pwd->pw_gid);
251 if (ret != 0) {
252 ALOGE("Failed to change owner of %s - %s\n",
253 CID_PATH, strerror(errno));
254 ret = -1;
255 goto out;
256 }
257
258 nvram_file = WIFI_DRIVER_NVRAM_PATH;
259 if (nvram_file != NULL) {
260 ret = wifi_change_nvram_calibration(nvram_file, type_str);
261 if (ret != 0) {
262 ret = -1;
263 goto out;
264 }
265 }
266
267out:
268 if (file) {
269 fclose(file);
270 }
271 if (cidfile) {
272 fclose(cidfile);
273 }
274 if (ret < 0) {
275 ALOGE("Macloader error return code: %d", ret);
276 }
277
278 return ret;
R. Andrew Ohana81c2e052012-10-03 19:52:52 -0700279}