.. | .. |
---|
29 | 29 | #include <log/log.h> |
---|
30 | 30 | #include <cutils/properties.h> |
---|
31 | 31 | #include <pthread.h> |
---|
| 32 | +#include <regex.h> |
---|
32 | 33 | |
---|
33 | 34 | #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) |
---|
34 | 35 | #define UEVENT_MSG_LEN 1024 |
---|
.. | .. |
---|
111 | 112 | |
---|
112 | 113 | static const struct info_t wifi_drv_para[] = { |
---|
113 | 114 | {"broadcom", |
---|
114 | | - {"nvram_path=/vendor/etc/firmware/nvram_", |
---|
115 | | - "$module_name", |
---|
116 | | - ".txt ", |
---|
117 | | - "config_path=/vendor/etc/firmware/config_", |
---|
118 | | - "$module_name", |
---|
119 | | - ".txt", |
---|
| 115 | + {"nvram_path=/vendor/etc/firmware/nvram_${module_name}.txt", |
---|
| 116 | + "config_path=/vendor/etc/firmware/config_${module_name}.txt", |
---|
120 | 117 | 0, |
---|
121 | 118 | } |
---|
122 | 119 | }, |
---|
.. | .. |
---|
126 | 123 | } |
---|
127 | 124 | }, |
---|
128 | 125 | {"ssv", |
---|
129 | | - {"stacfgpath=/vendor/etc/firmware/", |
---|
130 | | - "$module_name", |
---|
131 | | - "/", |
---|
132 | | - "$module_name", |
---|
133 | | - "-wifi.cfg", |
---|
| 126 | + {"stacfgpath=/vendor/etc/firmware/${module_name}/${module_name}-wifi.cfg", |
---|
134 | 127 | 0, |
---|
135 | 128 | } |
---|
136 | 129 | }, |
---|
.. | .. |
---|
253 | 246 | p++; |
---|
254 | 247 | strncpy(val, dst, p -dst); |
---|
255 | 248 | val[p - dst] = 0; |
---|
| 249 | + return 0; |
---|
| 250 | +} |
---|
| 251 | + |
---|
| 252 | +// You must free the result if result is non-NULL. |
---|
| 253 | +static char *str_replace(char *orig, char *rep, char *with) |
---|
| 254 | +{ |
---|
| 255 | + char *result; // the return string |
---|
| 256 | + char *ins; // the next insert point |
---|
| 257 | + char *tmp; // varies |
---|
| 258 | + int len_rep; // length of rep (the string to remove) |
---|
| 259 | + int len_with; // length of with (the string to replace rep with) |
---|
| 260 | + int len_front; // distance between rep and end of last rep |
---|
| 261 | + int count; // number of replacements |
---|
| 262 | + |
---|
| 263 | + // sanity checks and initialization |
---|
| 264 | + if (!orig || !rep) |
---|
| 265 | + return NULL; |
---|
| 266 | + len_rep = strlen(rep); |
---|
| 267 | + if (len_rep == 0) |
---|
| 268 | + return NULL; // empty rep causes infinite loop during count |
---|
| 269 | + if (!with) |
---|
| 270 | + with = ""; |
---|
| 271 | + len_with = strlen(with); |
---|
| 272 | + |
---|
| 273 | + // count the number of replacements needed |
---|
| 274 | + ins = orig; |
---|
| 275 | + for (count = 0; (tmp = strstr(ins, rep)); ++count) { |
---|
| 276 | + ins = tmp + len_rep; |
---|
| 277 | + } |
---|
| 278 | + |
---|
| 279 | + tmp = result = malloc(strlen(orig) + (len_with - len_rep) * count + 1); |
---|
| 280 | + |
---|
| 281 | + if (!result) |
---|
| 282 | + return NULL; |
---|
| 283 | + |
---|
| 284 | + // first time through the loop, all the variable are set correctly |
---|
| 285 | + // from here on, |
---|
| 286 | + // tmp points to the end of the result string |
---|
| 287 | + // ins points to the next occurrence of rep in orig |
---|
| 288 | + // orig points to the remainder of orig after "end of rep" |
---|
| 289 | + while (count--) { |
---|
| 290 | + ins = strstr(orig, rep); |
---|
| 291 | + len_front = ins - orig; |
---|
| 292 | + tmp = strncpy(tmp, orig, len_front) + len_front; |
---|
| 293 | + tmp = strcpy(tmp, with) + len_with; |
---|
| 294 | + orig += len_front + len_rep; // move to next "end of rep" |
---|
| 295 | + } |
---|
| 296 | + strcpy(tmp, orig); |
---|
| 297 | + return result; |
---|
| 298 | +} |
---|
| 299 | + |
---|
| 300 | +static int str_expand(char *text, char *expand) |
---|
| 301 | +{ |
---|
| 302 | + static const char *pattern = "\\$\\{[^}]+\\}"; |
---|
| 303 | + regex_t reg; |
---|
| 304 | + const size_t nmatch = 1; |
---|
| 305 | + int i, j, status; |
---|
| 306 | + regmatch_t pmatch[1]; |
---|
| 307 | + char matchstr[32]; |
---|
| 308 | + char env_name[32]; |
---|
| 309 | + char *env_val = NULL; |
---|
| 310 | + char *orig = text; |
---|
| 311 | + char *out; |
---|
| 312 | + |
---|
| 313 | + status = regcomp(®, pattern, REG_EXTENDED); |
---|
| 314 | + while (regexec(®, orig, nmatch, pmatch, 0) == 0) { |
---|
| 315 | + memcpy(matchstr, orig + pmatch[0].rm_so, pmatch[0].rm_eo - pmatch[0].rm_so); |
---|
| 316 | + matchstr[pmatch[0].rm_eo - pmatch[0].rm_so] = 0; |
---|
| 317 | + |
---|
| 318 | + memcpy(env_name, orig + pmatch[0].rm_so + 2, pmatch[0].rm_eo - pmatch[0].rm_so - 3); |
---|
| 319 | + env_name[pmatch[0].rm_eo - pmatch[0].rm_so - 3] = 0; |
---|
| 320 | + |
---|
| 321 | + env_val = getenv(env_name); |
---|
| 322 | + out = str_replace(orig, matchstr, env_val); |
---|
| 323 | + |
---|
| 324 | + if (out) { |
---|
| 325 | + memcpy(expand, out, strlen(out)); |
---|
| 326 | + expand[strlen(out)] = 0; |
---|
| 327 | + free(out); |
---|
| 328 | + orig = expand; |
---|
| 329 | + } |
---|
| 330 | + } |
---|
| 331 | + regfree(®); |
---|
| 332 | + |
---|
256 | 333 | return 0; |
---|
257 | 334 | } |
---|
258 | 335 | |
---|
.. | .. |
---|
783 | 860 | property_set(MODULE_BT_SUPPORT_PROP, wifiinfo->bt_support ? "1" : "0"); |
---|
784 | 861 | } |
---|
785 | 862 | } |
---|
| 863 | + |
---|
| 864 | + for (i = 0; i < ARRAY_SIZE(matchtab); i++) { |
---|
| 865 | + if (matchtab[i].type == TYPE_PCHAR) |
---|
| 866 | + setenv(matchtab[i].keyname, (char *)(*(ADDR_T *)((ADDR_T)wifiinfo + matchtab[i].offset)), 1); |
---|
| 867 | + } |
---|
| 868 | + |
---|
786 | 869 | return wifiinfo; |
---|
787 | 870 | } |
---|
788 | 871 | |
---|
.. | .. |
---|
812 | 895 | |
---|
813 | 896 | const char *get_driver_module_arg(void) |
---|
814 | 897 | { |
---|
815 | | - static char module_arg[256] = {0}; |
---|
| 898 | + static char module_arg[1024] = {0}; |
---|
816 | 899 | struct wifi_hardware_info *hwinfo = get_wifi_hardware_info(); |
---|
817 | | - const char *para; |
---|
| 900 | + char buffer[1024]; |
---|
818 | 901 | int n = 0; |
---|
819 | 902 | for (int i = 0; i < ARRAY_SIZE(wifi_drv_para); i++) { |
---|
820 | 903 | if (strncmp(hwinfo->vendor_name, wifi_drv_para[i].vendor, strlen(hwinfo->vendor_name)) == 0) { |
---|
821 | | - for (int j = 0; (j < INFO_SESSION_MAX) && ((para = wifi_drv_para[i].info[j]) != NULL); j++) { |
---|
822 | | - if (*para == '$') { |
---|
823 | | - for (int k = 0; k < ARRAY_SIZE(matchtab); k++) { |
---|
824 | | - if (strncmp(para + 1, matchtab[k].keyname, strlen(matchtab[k].keyname)) == 0) { |
---|
825 | | - para = (const char *)(*(ADDR_T *)((ADDR_T)hwinfo + matchtab[k].offset)); |
---|
826 | | - break; |
---|
827 | | - } |
---|
828 | | - } |
---|
829 | | - } |
---|
830 | | - n += sprintf(&module_arg[n], "%s", para); |
---|
| 904 | + for (int j = 0; (j < INFO_SESSION_MAX) && wifi_drv_para[i].info[j] != NULL; j++) { |
---|
| 905 | + n += sprintf(&buffer[n], "%s ", wifi_drv_para[i].info[j]); |
---|
831 | 906 | } |
---|
| 907 | + buffer[n - 2] = '\0'; |
---|
| 908 | + str_expand(buffer, module_arg); |
---|
832 | 909 | return module_arg; |
---|
833 | 910 | } |
---|
834 | 911 | } |
---|