diff options
author | Sungmin Choi <sungmin.choi@lge.com> | 2012-07-18 01:49:40 -0700 |
---|---|---|
committer | Brian Muramatsu <btmura@google.com> | 2012-07-18 19:25:32 -0700 |
commit | 5fd819dcca2ce41b0c7fa56d010dca6cbc3cc0d0 (patch) | |
tree | 95daf09cd07b7868258c3f7c1ac8e9dcc8577309 | |
parent | 2cfa86f69206d8d901592ecfaab05f55ebd0b5e5 (diff) | |
download | mako-5fd819dcca2ce41b0c7fa56d010dca6cbc3cc0d0.tar.gz |
mako: enable to modify mac address at boot time
- add conn_init and libwfcu packages
- modify mac address of ini and nv (calibration) file through conn_init service
- change ini and nv files location from /system/etc/firmware/wlan/prima
to /system/etc/wifi, because we must read and write mac address from persist.
We use wifi firmware loaded location to /vendor/firmware.
System partition is read-only, so use some fake links like the followings:
- conn_init operation:
1. copy /system/etc/wifi/WCNSS_qcom_cfg.ini and WCNSS_qcom_wlan_nv.bin
to /data/misc/wifi.
2. read mac address from persist and write to ini and nv.
3. WCNSS_qcom.cfg.ini and WCNSS_qcom_wlan.vn.bin must be loaded
in /etc/firmware, /vendor/firmware, or /firmware/image.
4. To operate 3, we use the fake links between
/data/misc/wifi and /vendor/firmware/wlan/prima
5. Now, we can use modified ini and nv files from /vendor/firmware/wlan/prima/
Change-Id: I161385f6883ecf6350bd71ab9f2fc9b2543937c0
-rw-r--r-- | conn_init/Android.mk | 78 | ||||
-rw-r--r-- | conn_init/NOTICE | 190 | ||||
-rw-r--r-- | conn_init/conn_init.c | 56 | ||||
-rw-r--r-- | conn_init/wfc_util_common.c | 135 | ||||
-rw-r--r-- | conn_init/wfc_util_common.h | 51 | ||||
-rw-r--r-- | conn_init/wfc_util_fctrl.c | 664 | ||||
-rw-r--r-- | conn_init/wfc_util_fctrl.h | 92 | ||||
-rw-r--r-- | conn_init/wfc_util_log.h | 32 | ||||
-rw-r--r-- | conn_init/wfc_util_main.c | 139 | ||||
-rw-r--r-- | conn_init/wfc_util_qcom.c | 676 | ||||
-rw-r--r-- | conn_init/wfc_util_qcom.h | 52 | ||||
-rw-r--r-- | device.mk | 10 | ||||
-rw-r--r-- | init.mako.rc | 5 |
13 files changed, 2177 insertions, 3 deletions
diff --git a/conn_init/Android.mk b/conn_init/Android.mk new file mode 100644 index 0000000..c21210e --- /dev/null +++ b/conn_init/Android.mk @@ -0,0 +1,78 @@ +# +# Copyright 2012 The Android Open Source 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. +# + +ifneq ($(filter mako occam,$(TARGET_DEVICE)),) + +LOCAL_PATH:= $(call my-dir) + +include $(CLEAR_VARS) +LOCAL_MODULE := libwfcu +LOCAL_SRC_FILES := wfc_util_fctrl.c \ + wfc_util_common.c +LOCAL_CFLAGS := -Wall \ + -Werror +LOCAL_CFLAGS += -DCONFIG_LGE_WLAN_WIFI_PATCH +ifeq ($(BOARD_HAS_QCOM_WLAN), true) +LOCAL_SRC_FILES += wfc_util_qcom.c +LOCAL_CFLAGS += -DCONFIG_LGE_WLAN_QCOM_PATCH +LOCAL_CFLAGS += -DWLAN_CHIP_VERSION_WCNSS +endif +LOCAL_SHARED_LIBRARIES := libcutils +LOCAL_PRELINK_MODULE := false +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_OWNER := lge +include $(BUILD_SHARED_LIBRARY) + +include $(CLEAR_VARS) +LOCAL_SRC_FILES := conn_init.c +LOCAL_SHARED_LIBRARIES := libcutils +LOCAL_SHARED_LIBRARIES += libwfcu +LOCAL_CFLAGS += -Wall -Werror +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_PATH := $(TARGET_OUT)/bin +LOCAL_MODULE := conn_init +LOCAL_MODULE_OWNER := lge +include $(BUILD_EXECUTABLE) + +include $(CLEAR_VARS) +LOCAL_MODULE := WCNSS_qcom_cfg.ini +LOCAL_MODULE_CLASS := ETC +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_OWNER := lge +LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/firmware/wlan/prima +include $(BUILD_SYSTEM)/base_rules.mk +$(LOCAL_BUILT_MODULE): PRIVATE_LINK_PATH := $(LOCAL_MODULE_PATH)/$(LOCAL_MODULE) +$(LOCAL_BUILT_MODULE): PRIVATE_DIRECTORY_PATH := $(LOCAL_MODULE_PATH) +$(LOCAL_BUILT_MODULE): + @echo Creating Wifi Link... WCNSS_qcom_cfg_mako.ini + mkdir -p $(PRIVATE_DIRECTORY_PATH) + ln -sf /data/misc/wifi/WCNSS_qcom_cfg.ini $(PRIVATE_LINK_PATH) + +include $(CLEAR_VARS) +LOCAL_MODULE := WCNSS_qcom_wlan_nv.bin +LOCAL_MODULE_CLASS := ETC +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_OWNER := lge +LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/firmware/wlan/prima +include $(BUILD_SYSTEM)/base_rules.mk +$(LOCAL_BUILT_MODULE): PRIVATE_LINK_PATH := $(LOCAL_MODULE_PATH)/$(LOCAL_MODULE) +$(LOCAL_BUILT_MODULE): PRIVATE_DIRECTORY_PATH := $(LOCAL_MODULE_PATH) +$(LOCAL_BUILT_MODULE): + @echo Creating Wifi Link... WCNSS_qcom_wlan_nv_mako.bin + mkdir -p $(PRIVATE_DIRECTORY_PATH) + ln -sf /data/misc/wifi/WCNSS_qcom_wlan_nv.bin $(PRIVATE_LINK_PATH) + +endif diff --git a/conn_init/NOTICE b/conn_init/NOTICE new file mode 100644 index 0000000..33ff961 --- /dev/null +++ b/conn_init/NOTICE @@ -0,0 +1,190 @@ + + Copyright (c) 2005-2012, The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + + 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. + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + diff --git a/conn_init/conn_init.c b/conn_init/conn_init.c new file mode 100644 index 0000000..2cb5591 --- /dev/null +++ b/conn_init/conn_init.c @@ -0,0 +1,56 @@ +/* + * Copyright 2012 The Android Open Source 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. + */ +#include <stdio.h> +#include <string.h> +#include <unistd.h> + +extern int wfc_util_qcom_check_config(unsigned char *nv_mac_addr); +extern void wfc_util_atoh(char *pAsciiString, int szAsciiString, unsigned char *pHexaBuff, int szHexaBuff); + +static int wifi_check_qcom_cfg_files() +{ + char macAddress[13]; + char hex[7]; + memset(macAddress, 0, 13); + memset(hex, 0, 7); + + // Read MAC String + FILE *fp = NULL; + int n = 0; + fp = fopen("/persist/wifi/.macaddr", "r"); + if ( fp == NULL ) + { + wfc_util_qcom_check_config((unsigned char *)macAddress); + return 0; + } + else + { + n = fread(macAddress, 12, 1, fp); + fclose(fp); + + // Write MAC String + wfc_util_atoh( macAddress, 12, (unsigned char *)hex, 6); + wfc_util_qcom_check_config((unsigned char *)hex); + } + return 1; +} + +int main(void) +{ + wifi_check_qcom_cfg_files(); + + return 0; +} diff --git a/conn_init/wfc_util_common.c b/conn_init/wfc_util_common.c new file mode 100644 index 0000000..b149920 --- /dev/null +++ b/conn_init/wfc_util_common.c @@ -0,0 +1,135 @@ +/* + * Copyright 2012 The Android Open Source 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. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> + +#include "wfc_util_log.h" + +#define WFC_UTIL_RANDOM_MAC_HEADER "001122" + +void wfc_util_htoa(unsigned char *pHexaBuff, int szHexaBuff, char *pAsciiStringBuff, int szAsciiStringBuff) +{ + int i, j; + char hex_table[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + 'A', 'B', 'C', 'D', 'E', 'F'}; + + if ((szHexaBuff*2) > szAsciiStringBuff) { + wfc_util_log_error("wfc_util_htoa : not enough buffer size(%d)", szAsciiStringBuff); + return; + } + + memset(pAsciiStringBuff, 0, szAsciiStringBuff); + + /* for (i = szHexaBuff-1, j = 0; i >= 0; i--, j += 2) { */ + for (i = 0, j = 0; i < szHexaBuff; i++, j += 2) { + /*pAsciiStringBuff[j] = hex_table[(pHexaBuff[i] >> 4) & 0x0F]; + */ + pAsciiStringBuff[j] = hex_table[pHexaBuff[i] >> 4]; + pAsciiStringBuff[j + 1] = hex_table[pHexaBuff[i] & 0x0F]; + } + + return; +} + +void wfc_util_atoh(char *pAsciiString, int szAsciiString, unsigned char *pHexaBuff, int szHexaBuff) +{ + int i, pos; + char temp; + + if ( 0!=(szAsciiString%2) || (szHexaBuff*2) < szAsciiString) { + wfc_util_log_error("wfc_util_atoh : not enough buffer size(%d)", szHexaBuff); + return; + } + + memset(pHexaBuff, 0, szHexaBuff); + + for (i=0 ; i<szAsciiString ; i++) { + + /* pos = (szAsciiString - i - 1) / 2; */ + pos = i / 2; + temp = pAsciiString[i]; + + if (temp >= '0' && temp <= '9') { + temp = temp - '0'; + } else if ( temp >= 'a' && temp <= 'f' ) { + temp = temp - 'a' + 10; + } else if ( temp >= 'A' && temp <= 'F' ) { + temp = temp - 'A' + 10; + } else { + temp = 0; + } + + if (0==i%2) { + pHexaBuff[pos] = temp<<4; + } else { + pHexaBuff[pos] |= temp; + } + } + + return; +} + +/* + * wfc_util_is_random_mac + * + * return : it will return 1 if [mac_add] is same with WFC_UTIL_RANDOM_MAC_HEADER + * or will return 0 if not. + */ +int wfc_util_is_random_mac(char *mac_add) +{ + if(0 == strncmp(mac_add, WFC_UTIL_RANDOM_MAC_HEADER, 6)) { + return 1; + } + + return 0; +} + +/* + * wfc_util_random_mac + * + * Create random MAC address + * + * return : void + */ +void wfc_util_random_mac(unsigned char* mac_addr) +{ + unsigned long int rand_mac; + + if(NULL == mac_addr) { + wfc_util_log_error("wfc_util_random_mac : buffer is NULL"); + return; + } + + /* Create random MAC address: offset 3, 4 and 5 */ + srandom(time(NULL)); + rand_mac=random(); + + #ifndef WFC_UTIL_RANDOM_MAC_HEADER + mac_addr[0] = (unsigned char)0x00; + mac_addr[1] = (unsigned char)0x11; + mac_addr[2] = (unsigned char)0x22; + #else /* WFC_UTIL_RANDOM_MAC_HEADER */ + wfc_util_atoh(WFC_UTIL_RANDOM_MAC_HEADER, 6, mac_addr, 3); + #endif /* WFC_UTIL_RANDOM_MAC_HEADER */ + mac_addr[3] = (unsigned char)rand_mac; + mac_addr[4] = (unsigned char)(rand_mac >> 8); + mac_addr[5] = (unsigned char)(rand_mac >> 16); + + return; +} diff --git a/conn_init/wfc_util_common.h b/conn_init/wfc_util_common.h new file mode 100644 index 0000000..c91f899 --- /dev/null +++ b/conn_init/wfc_util_common.h @@ -0,0 +1,51 @@ +/* + * Copyright 2012 The Android Open Source 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 __WFC_UTIL_COMMON_H__ +#define __WFC_UTIL_COMMON_H__ + +/* + * wfc_util_htoa + * + * return : void + */ +extern void wfc_util_htoa(unsigned char *pHexaBuff, int szHexaBuff, char *pAsciiStringBuff, int szAsciiStringBuff); + +/* + * wfc_util_atoh + * + * return : void + */ +extern void wfc_util_atoh(char *pAsciiString, int szAsciiString, unsigned char *pHexaBuff, int szHexaBuff); + +/* + * wfc_util_is_random_mac + * + * return : it will return 1 if [mac_add] is same with WFC_UTIL_RANDOM_MAC_HEADER + * or will return 0 if not. + */ +extern int wfc_util_is_random_mac(char *mac_add); + +/* + * wfc_util_random_mac + * + * Create random MAC address + * + * return : void + */ +void wfc_util_random_mac(unsigned char* mac_addr); + +#endif diff --git a/conn_init/wfc_util_fctrl.c b/conn_init/wfc_util_fctrl.c new file mode 100644 index 0000000..13a82f1 --- /dev/null +++ b/conn_init/wfc_util_fctrl.c @@ -0,0 +1,664 @@ +/* + * Copyright 2012 The Android Open Source 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. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <fcntl.h> +#include <unistd.h> +#include <errno.h> +#include <sys/stat.h> +#include <sys/types.h> + +#include "wfc_util_log.h" + +/* +static void wfc_util_printf(char *pSPointer, int length) +{ + char *pPrintBuff = NULL; + + if( NULL == pSPointer || 0 >= length ) { + wfc_util_log_error("wfc_util_printf : unvalid parameters"); + return; + } + + wfc_util_log_error("wfc_util_printf : lenght is (%d)", length); + pPrintBuff = malloc(length+1); + + if( NULL != pPrintBuff ) { + memset( pPrintBuff, 0, (length+1) ); + memcpy(pPrintBuff, pSPointer, length); + + wfc_util_log_error("wfc_util_printf : %s", pPrintBuff); + + free(pPrintBuff); + } else { + wfc_util_log_error("wfc_util_printf : can not malloc(%d)", (length+1)); + } + return; +} +*/ + +static void wfc_util_finsert_new_string(int fd, char **ppReadedBuff, char *pNewStringValue, char *pEndOfCfg) +{ + off_t sz_file; + int sz_backupBuff = 0; + char *pReadBuff = NULL, *pBackupBuff = NULL; + char *pSPointer = NULL, *pETagPointer = NULL; + + if( 0 == fd || NULL == pNewStringValue || 0 == strlen(pNewStringValue) ) { + wfc_util_log_error("wfc_util_finsert_new_string : unvalid parameters"); + return; + } + + if( NULL == ppReadedBuff) { + // TODO: + return; + } else { + pReadBuff = *ppReadedBuff; + } + + /* + * find END TAG string + */ + pETagPointer = strstr(pReadBuff, pEndOfCfg); + pSPointer = pETagPointer - 1; + + /* + * calcurate file size and size of the tail of file + */ + sz_file = lseek( fd, 0, SEEK_END ); + sz_backupBuff = (int)sz_file - (pETagPointer - pReadBuff); + + /* + * prefare the buffer to store the tail of file + */ + pBackupBuff = malloc(sz_backupBuff); + + if( NULL != pBackupBuff ) { + /* + * copy the tail of file. + */ + memset( pBackupBuff, 0, sz_backupBuff ); + memcpy( pBackupBuff, pETagPointer, sz_backupBuff ); + + /* + * write new string. + */ + lseek( fd, (int)(pSPointer-pReadBuff), SEEK_SET ); + write( fd, pNewStringValue, strlen(pNewStringValue)); + + /* + * update pETagPointer. + */ + pETagPointer = pSPointer + strlen(pNewStringValue); + + /* + * write the tail of file. + */ + lseek( fd, (int)(pETagPointer-pReadBuff), SEEK_SET ); + write( fd, pBackupBuff, sz_backupBuff ); + + ftruncate(fd, sz_file + strlen(pNewStringValue) - 1); /* we use "-1" becasue of "pSPointer = pETagPointer - 1"*/ + + free(pBackupBuff); + + /* + * make new *ppReadedBuff + */ + if( NULL != ppReadedBuff) { + // TODO: + } + } else { + wfc_util_log_error("wfc_util_finsert_new_string : can not malloc(%d)", sz_backupBuff); + } + + return; +} + +static void wfc_util_fupdate_string(int fd, char **ppReadedBuff, + char *pETagPointer, char *pSValuePointer, char *pNewValueString) +{ + off_t sz_file; + int sz_newReadBuff = 0; + char *pReadBuff = NULL, *pNewReadBuff = NULL, *pCurReadBuff = NULL; + + if( 0 == fd ) { + wfc_util_log_error("wfc_util_fupdate_string : unvalid parameters"); + return; + } + + if( NULL == ppReadedBuff) { + // TODO: + return; + } else { + pReadBuff = *ppReadedBuff; + } + + /* + * calcurate file size and new file size + */ + sz_file = lseek( fd, 0, SEEK_END ); + sz_newReadBuff = (int)sz_file - (int)(pETagPointer - pSValuePointer) + strlen(pNewValueString); + + /* + * prefare the buffer to read file + */ + pNewReadBuff = malloc(sz_newReadBuff); + + if( NULL != pNewReadBuff ) { + /* + * copy buffer + */ + memset( pNewReadBuff, 0, sz_file ); + pCurReadBuff = pNewReadBuff; + memcpy( pNewReadBuff, pReadBuff, (int)(pSValuePointer-pReadBuff) ); + pCurReadBuff += (int)(pSValuePointer-pReadBuff); + + /* + * copy new value string + */ + memcpy( pCurReadBuff, pNewValueString, strlen(pNewValueString)); + pCurReadBuff += strlen(pNewValueString); + + /* + * copy the remained buffer + */ + memcpy( pCurReadBuff, pETagPointer, ((int)(sz_file) - (int)(pETagPointer - pReadBuff) + 1)); + + /* + * write file and update the file size + */ + lseek( fd, 0, SEEK_SET ); + write( fd, pNewReadBuff, sz_newReadBuff); + ftruncate(fd, sz_newReadBuff); + + free(pNewReadBuff); + } else { + wfc_util_log_error("wfc_util_fupdate_string : can not malloc(%d)", (int)sz_newReadBuff); + } + + return; +} + +/* + * wfc_util_fset_buffer + * + * return : void + */ +void wfc_util_fset_buffer(char *pFileName, int positionStart, unsigned char *pNewValue, int newValueLength) +{ + int fd; + off_t sz_file; + char *pReadBuff = NULL; + + fd = open( pFileName, O_RDWR ); + + if( fd >= 0 ) { + /* + * calcurate file size + */ + sz_file = lseek( fd, 0, SEEK_END ); + + /* + * prefare the buffer to read file + */ + pReadBuff = malloc(sz_file + 1); // null terminated + + if( NULL != pReadBuff ) { + /* + * read file + */ + memset( pReadBuff, 0, sz_file + 1); + lseek( fd, 0, SEEK_SET ); + read( fd, pReadBuff, sz_file ); + + if(sz_file >= (positionStart+newValueLength)) { + lseek( fd, positionStart, SEEK_SET ); + write( fd, pNewValue, newValueLength ); + } else { + /* + * insert with new length value buffer + */ + wfc_util_log_error("wfc_util_fset_buffer : file size(%d) is less than to write position(%d)", (int)sz_file, (positionStart+newValueLength)); + // TODO: + } + + free(pReadBuff); + } else { + wfc_util_log_error("wfc_util_fset_buffer : can not malloc(%d)", (int)sz_file); + } + + if ( -1 == fsync( fd ) ) { + wfc_util_log_error("wfc_util_fset_buffer : fail to fsync()"); + } + + close( fd ); + } else { + wfc_util_log_error("wfc_util_fset_buffer : can not open file"); + } + + return; +} + +/* + * wfc_util_fget_buffer + * + * return : it will return the length of the stored buffer value if procedure is success + * or will return 0 if not. + */ +int wfc_util_fget_buffer(char *pFileName, int positionStart, int lengthToRead, unsigned char *pValueBuff, int buffLength) +{ + int result = 0; + int fd; + off_t sz_file; + char *pReadBuff = NULL; + char *pSValuePointer = NULL, *pETagPointer = NULL; + + fd = open( pFileName, O_RDONLY ); + + if( fd >= 0 ) { + /* + * calcurate file size + */ + sz_file = lseek( fd, 0, SEEK_END ); + + if(sz_file >= (positionStart+lengthToRead)) { + /* + * prefare the buffer to read file + */ + pReadBuff = malloc(sz_file + 1); // null terminated + + if( NULL != pReadBuff ) { + /* + * read file + */ + memset( pReadBuff, 0, sz_file + 1 ); + lseek( fd, 0, SEEK_SET ); + read( fd, pReadBuff, sz_file ); + + /* + * calculate the start buffer pointer + */ + pSValuePointer = pReadBuff + positionStart; + + /* + * calculate the end buffer pointer + */ + pETagPointer = pSValuePointer + lengthToRead; + + /* + * read the string value + */ + if( buffLength >= (int)(pETagPointer-pSValuePointer) ) { + memset( pValueBuff, 0, buffLength ); + memcpy( pValueBuff, pSValuePointer, (int)(pETagPointer-pSValuePointer) ); + result = (int)(pETagPointer-pSValuePointer); + } else { + wfc_util_log_error("wfc_util_fget_buffer : not enough string value buffer(%d)", (int)(pETagPointer-pSValuePointer)); + } + + free(pReadBuff); + } else { + wfc_util_log_error("wfc_util_fget_buffer : can not malloc(%d)", (int)sz_file); + } + } else { + wfc_util_log_error("wfc_util_fget_buffer : file size(%d) is less than to read position(%d)", (int)sz_file, (positionStart+lengthToRead)); + } + close( fd ); + } else { + wfc_util_log_error("wfc_util_fget_buffer : can not open file"); + } + + return result; +} + +/* + * wfc_util_fset_string + * + * The following format string will be added or updated to the file pFileName. + * [pSTagString][pNewValueString][pETagString] + * + * pFileName : file name and path + * pEndOfCfg : tag string to notify the end of configuration file + * pSTagString : tag string to notify purpose of the value + * pETagString : tag string to notify the end of the value + * pNewValueString : string to set for pSTagString + * + * return : void + */ +void wfc_util_fset_string(char *pFileName, char *pEndOfCfg, char *pSTagString, char *pETagString, char *pNewValueString) +{ + int fd; + off_t sz_file; + int sz_NewValueBuff = 0; + char *pReadBuff = NULL, *pNewValueBuff = NULL; + char *pSPointer = NULL, *pETagPointer = NULL, *pSValuePointer = NULL; + + fd = open( pFileName, O_RDWR ); + + if( fd >= 0 ) { + /* + * calcurate file size + */ + sz_file = lseek( fd, 0, SEEK_END ); + + /* + * prefare the buffer to read file + */ + if (sz_file > 0) + pReadBuff = malloc(sz_file + 1); // null terminated + + if( NULL != pReadBuff ) { + /* + * read file + */ + memset( pReadBuff, 0x00, sz_file + 1); + if(lseek(fd, 0, SEEK_SET) != 0) { + wfc_util_log_error("lseek failure"); + } + read( fd, pReadBuff, sz_file ); + + /* WBT fix, make sure it is terminated with \0 */ + pReadBuff[sz_file] = '\0'; + + /* + * find TAG string + */ + pSPointer = strstr(pReadBuff, pSTagString); + + if(NULL != pSPointer) { + /* + * find END OF LINE string + */ + pETagPointer = strstr(pSPointer, pETagString); + + if(NULL != pETagPointer) { + /* + * write the new string value + */ + pSValuePointer = pSPointer+strlen(pSTagString); + if(strlen(pNewValueString) == (unsigned int)(pETagPointer-pSValuePointer)) { + lseek( fd, (int)(pSValuePointer-pReadBuff), SEEK_SET ); + write( fd, pNewValueString, strlen(pNewValueString)); + } else { + /* + * insert with new length value string + */ + wfc_util_fupdate_string(fd, &pReadBuff, pETagPointer, pSValuePointer, pNewValueString); + } + } else { + wfc_util_log_error("wfc_util_fset_string : can not find End TAG"); + } + } else { + /* + * "\n""[Start TAG][String Value][End TAG]""\n" + */ + sz_NewValueBuff = strlen(pSTagString) + + strlen(pNewValueString) + + strlen(pETagString) + + 2 + 1; + pNewValueBuff = malloc( sz_NewValueBuff); + + if( NULL != pNewValueBuff ) { + /* + * prefare the new string to insert + */ + memset( pNewValueBuff, 0, sz_NewValueBuff ); + sprintf( pNewValueBuff, "%c%s%s%s%c", '\n', pSTagString, pNewValueString, pETagString,'\n' ); + + /* + * insert new string to the file + */ + wfc_util_finsert_new_string(fd, &pReadBuff, pNewValueBuff, pEndOfCfg); + + free( pNewValueBuff ); + } else { + wfc_util_log_error("wfc_util_fset_string : can not malloc(%d)", (int)sz_file); + } + } + + free(pReadBuff); + } else { + wfc_util_log_error("wfc_util_fset_string : can not malloc(%d)", (int)sz_file); + } + + if ( -1 == fsync( fd ) ) { + wfc_util_log_error("wfc_util_fset_string : fail to fsync()"); + } + + close( fd ); + } else { + wfc_util_log_error("wfc_util_fset_string : can not open file"); + } + + return; +} + +/* + * wfc_util_fget_string + * + * Read value from the following format string in the file pFileName. + * [pSTagString][string value to read][pETagString] + * + * pFileName : file name and path + * pEndOfCfg : tag string to notify the end of configuration file + * pSTagString : tag string to notify purpose of the value + * pETagString : tag string to notify the end of the value + * pValueStringBuff : string buffer to get string value + * stringBuffLength : the length of pValueStringBuff + * + * return : it will return the length of the stored string value if procedure is success + * or will return 0 if not. + */ +int wfc_util_fget_string(char *pFileName, char *pEndOfCfg, char *pSTagString, char *pETagString, char *pValueStringBuff, int stringBuffLength) +{ + int result = 0; + int fd; + off_t sz_file; + char *pReadBuff = NULL; + char *pSPointer = NULL, *pETagPointer = NULL, *pSValuePointer = NULL; + + /* unused parameter*/ + pEndOfCfg = pEndOfCfg; + + fd = open( pFileName, O_RDONLY ); + + if( fd >= 0 ) { + /* + * calcurate file size + */ + sz_file = lseek( fd, 0, SEEK_END ); + + /* + * prefare the buffer to read file + */ + if (sz_file > 0) // skip when value is 0 + pReadBuff = malloc(sz_file + 1); + + if( NULL != pReadBuff ) { + /* + * read file + */ + memset( pReadBuff, 0, sz_file + 1); + if(lseek(fd, 0, SEEK_SET) != 0) { + wfc_util_log_error("lseek failure"); + } + read( fd, pReadBuff, sz_file ); + + /* WBT fix, make sure it is terminated with \0 */ + pReadBuff[sz_file] = '\0'; + + /* + * find TAG string + */ + pSPointer = strstr( pReadBuff, pSTagString ); + + if( NULL != pSPointer ) { + /* + * find END OF LINE string + */ + pETagPointer = strstr(pSPointer, pETagString); + + if( NULL != pETagPointer ) { + /* + * read the string value + */ + pSValuePointer = pSPointer+strlen(pSTagString); + if( stringBuffLength >= (int)(pETagPointer-pSValuePointer) ) { + memset( pValueStringBuff, 0, stringBuffLength ); + memcpy( pValueStringBuff, pSValuePointer, (int)(pETagPointer-pSValuePointer) ); + result = (int)(pETagPointer-pSValuePointer); + } else { + wfc_util_log_error("wfc_util_fget_string : not enough string value buffer(%d)", (int)(pETagPointer-pSValuePointer)); + } + } else { + wfc_util_log_error("wfc_util_fget_string : can not find End TAG"); + } + } else { + wfc_util_log_error("wfc_util_fget_string : can not find Start TAG"); + } + free(pReadBuff); + } else { + wfc_util_log_error("wfc_util_fget_string : can not malloc(%d)", (int)sz_file); + } + close( fd ); + } else { + wfc_util_log_error("wfc_util_fget_string : can not open file"); + } + + return result; +} + +/* + * wfc_util_ffile_check + * + * check whether pDestFName file exist or not + * + * pFileName : file name and path + * access_mode : R_OK | W_OK | X_OK | F_OK + * + * return : it will return 0 if the file exist + * or will return -1 if not. + */ +int wfc_util_ffile_check(char *pDestFName, int access_mode) +{ + struct stat st; + + if (access(pDestFName, access_mode) == 0) { + if( stat( pDestFName, &st ) < 0 ) { + wfc_util_log_error("Cannot stat the file \"%s\": %s", pDestFName, strerror(errno)); + return -1; + } + //check if config file has some data or is it empty due to previous errors + if( st.st_size ) { + return 0; + } + } else { + wfc_util_log_error("Cannot access \"%s\": %s", pDestFName, strerror(errno)); + } + + return -1; +} + +/* + * wfc_util_ffile_check_copy + * + * check whether pDestFName file exist if not it will copy from pSourceFName file + * + * return : it will return 0 if procedure is success + * or will return -1 if not. + */ +int wfc_util_ffile_check_copy(char *pDestFName, char *pSourceFName, mode_t mode, uid_t uID, gid_t gID) +{ +#define WFC_BUFFER_SIZE 2048 + char buf[WFC_BUFFER_SIZE] = {0}; // Null terminated + int srcfd, destfd; + int nread; + struct stat st; + + if (access(pDestFName, R_OK|W_OK) == 0) { + if( stat( pDestFName, &st ) < 0 ) { + wfc_util_log_error("Cannot stat the file \"%s\": %s", pDestFName, strerror(errno)); + return -1; + } + //check if config file has some data or is it empty due to previous errors + if( st.st_size ) { + return 0; + } + //else continue to write the config from default template. + } else if (errno != ENOENT) { + wfc_util_log_error("Cannot access \"%s\": %s", pDestFName, strerror(errno)); + return -1; + } + + srcfd = open(pSourceFName, O_RDONLY); + if (srcfd < 0) { + wfc_util_log_error("Cannot open \"%s\": %s", pSourceFName, strerror(errno)); + return -1; + } + + destfd = open(pDestFName, O_CREAT|O_WRONLY, mode); + if (destfd < 0) { + close(srcfd); + wfc_util_log_error("Cannot create \"%s\": %s", pDestFName, strerror(errno)); + return -1; + } + + while ((nread = read(srcfd, buf, WFC_BUFFER_SIZE-1)) != 0) { + if (nread < 0) { + wfc_util_log_error("Error reading \"%s\": %s", pSourceFName, strerror(errno)); + close(srcfd); + close(destfd); + unlink(pDestFName); + return -1; + } + // WBT fix, according to manual, the number of bytes read can't be bigger than read_size. I don't know why WBT complains for this. + if (nread < WFC_BUFFER_SIZE) + buf[nread] = '\0'; + else { + buf[WFC_BUFFER_SIZE-1] = '\0'; + nread = WFC_BUFFER_SIZE-1; + } + write(destfd, buf, nread); + } + + close(destfd); + close(srcfd); + + /* remove this code because of permission problem when it is accessed from "atd" having system permission. */ + { + #ifndef CONFIG_LGE_WLAN_WIFI_PATCH + uid_t uid = getuid(); + gid_t gid = getgid(); + wfc_util_log_error("Error changing group ownership (%d) of %s to %d: %s", gid, pDestFName, gID, strerror(errno)); + if (0 == uid) { + #endif /* CONFIG_LGE_WLAN_WIFI_PATCH */ + if (chown(pDestFName, uID, gID) < 0) { + wfc_util_log_error("Error changing group ownership of %s to %d: %s", pDestFName, gID, strerror(errno)); + unlink(pDestFName); + return -1; + } + #ifndef CONFIG_LGE_WLAN_WIFI_PATCH + } else { + wfc_util_log_error("wfc_util_ffile_check_copy : we can not excute chown[uid = %d, gid = %d]", uid, getgid()); + } + #endif /* CONFIG_LGE_WLAN_WIFI_PATCH */ + } + + return 0; +} + diff --git a/conn_init/wfc_util_fctrl.h b/conn_init/wfc_util_fctrl.h new file mode 100644 index 0000000..5c49899 --- /dev/null +++ b/conn_init/wfc_util_fctrl.h @@ -0,0 +1,92 @@ +/* + * Copyright 2012 The Android Open Source 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 __WFC_UTIL_FCTRL_H__ +#define __WFC_UTIL_FCTRL_H__ + +/* + * wfc_util_fset_buffer + * + * return : void + */ +void wfc_util_fset_buffer(char *pFileName, int positionStart, unsigned char *pNewValue, int newValueLength); + +/* + * wfc_util_fget_buffer + * + * return : it will return the length of the stored buffer value if procedure is success + * or will return 0 if not. + */ +extern int wfc_util_fget_buffer(char *pFileName, int positionStart, int lengthToRead, unsigned char *pValueBuff, int buffLength); + +/* + * wfc_util_fset_string + * + * The following format string will be added or updated to the file pFileName. + * [pSTagString][pNewValueString][pETagString] + * + * pFileName : file name and path + * pEndOfCfg : tag string to notify the end of configuration file + * pSTagString : tag string to notify purpose of the value + * pETagString : tag string to notify the end of the value + * pNewValueString : string to set for pSTagString + * + * return : void + */ +extern void wfc_util_fset_string(char *pFileName, char *pEndOfCfg, char *pSTagString, char *pETagString, char *pNewValueString); + +/* + * wfc_util_fget_string + * + * Read value from the following format string in the file pFileName. + * [pSTagString][string value to read][pETagString] + * + * pFileName : file name and path + * pEndOfCfg : tag string to notify the end of configuration file + * pSTagString : tag string to notify purpose of the value + * pETagString : tag string to notify the end of the value + * pValueStringBuff : string buffer to get string value + * stringBuffLength : the length of pValueStringBuff + * + * return : it will return the length of the stored string value if procedure is success + * or will return 0 if not. + */ +extern int wfc_util_fget_string(char *pFileName, char *pEndOfCfg, char *pSTagString, char *pETagString, char *pValueStringBuff, int stringBuffLength); + +/* + * wfc_util_ffile_check + * + * check whether pDestFName file exist or not + * + * pFileName : file name and path + * access_mode : R_OK | W_OK | X_OK | F_OK + * + * return : it will return 0 if the file exist + * or will return -1 if not. + */ +extern int wfc_util_ffile_check(char *pDestFName, int access_mode); + +/* + * wfc_util_ffile_check_copy + * + * check whether pDestFName file exist if not it will copy from pSourceFName file + * + * return : it will return 0 if procedure is success + * or will return -1 if not. + */ +extern int wfc_util_ffile_check_copy(char *pDestFName, char *pSourceFName, mode_t mode, uid_t uID, gid_t gID); + +#endif diff --git a/conn_init/wfc_util_log.h b/conn_init/wfc_util_log.h new file mode 100644 index 0000000..fcc4239 --- /dev/null +++ b/conn_init/wfc_util_log.h @@ -0,0 +1,32 @@ +/* + * Copyright 2012 The Android Open Source 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 __WFC_UTIL_LOG_H__ +#define __WFC_UTIL_LOG_H__ + +#ifdef ANDROID +#define LOG_TAG "WifiUtil" +#include <cutils/log.h> + +#define wfc_util_log_info(...) ALOGI(__VA_ARGS__) +#define wfc_util_log_error(...) ALOGE(__VA_ARGS__) +#else /* ANDROID */ +#define wfc_util_log_info(...) printf(__VA_ARGS__);printf("\n") +#define wfc_util_log_error(...) printf(__VA_ARGS__);printf("\n") +#endif /* ANDROID */ + +#endif + diff --git a/conn_init/wfc_util_main.c b/conn_init/wfc_util_main.c new file mode 100644 index 0000000..01e1c86 --- /dev/null +++ b/conn_init/wfc_util_main.c @@ -0,0 +1,139 @@ +/* + * Copyright 2012 The Android Open Source 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. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <getopt.h> +#include "wfc_util_fctrl.h" +#include "wfc_util_common.h" + +#ifdef WLAN_CHIP_VERSION_WCNSS +#ifndef WFC_UTIL_CFG_FILE_NAME +#define WFC_UTIL_CFG_FILE_NAME "./WCNSS_qcom_cfg.ini" +#endif +#ifndef WFC_UTIL_NV_BIN_FILE_NAME +#define WFC_UTIL_NV_BIN_FILE_NAME "./WCNSS_qcom_wlan_nv.bin" +#endif +#else /* WLAN_CHIP_VERSION_WCN1314 */ +#ifndef WFC_UTIL_CFG_FILE_NAME +#define WFC_UTIL_CFG_FILE_NAME "./WCN1314_qcom_cfg.ini" +#endif +#ifndef WFC_UTIL_NV_BIN_FILE_NAME +#define WFC_UTIL_NV_BIN_FILE_NAME "./WCN1314_qcom_wlan_nv.bin" +#endif +#endif /* WLAN_CHIP_VERSION_XXXX */ +#define WFC_UTIL_CFG_TAG_END_OF_CFG "END" +#define WFC_UTIL_CFG_TAG_MAC_ADDRESS "NetworkAddress=" +#define WFC_UTIL_CFG_TAG_AP_MAC_ADDRESS "gAPMacAddr=" +#define WFC_UTIL_CFG_TAG_END_OF_LINE "\n" +#define WFC_UTIL_CFG_LENGHT_MAC (6) +#define WFC_UTIL_CFG_LENGHT_MAC_STRING (WFC_UTIL_CFG_LENGHT_MAC*2) + +/* + * persist/WCNSS_qcom_wlan_nv.bin + * + * typedef PACKED_PRE struct PACKED_POST + * { + * //always ensure fields are aligned to 32-bit boundaries + * tANI_U16 productId; + * tANI_U8 productBands; + * tANI_U8 wlanNvRevId; + * + * tANI_U8 numOfTxChains; + * tANI_U8 numOfRxChains; + * tANI_U8 macAddr[NV_FIELD_MAC_ADDR_SIZE]; + * tANI_U8 mfgSN[NV_FIELD_MFG_SN_SIZE]; + * } sNvFields; + */ +#define WFC_UTIL_NV_BIN_HEADER_LENGTH (4) +#define WFC_UTIL_NV_BIN_POS_PRODUCT_ID (WFC_UTIL_NV_BIN_HEADER_LENGTH + 0) +#define WFC_UTIL_NV_BIN_POS_PRODUCT_BAND (WFC_UTIL_NV_BIN_HEADER_LENGTH + 2) +#define WFC_UTIL_NV_BIN_POS_MAC_ADDR (WFC_UTIL_NV_BIN_HEADER_LENGTH + 6) + +int main(int argc, char **argv) +{ + int ret = 0; + char mac_add_buff[WFC_UTIL_CFG_LENGHT_MAC_STRING+1]; + unsigned char mac_add_buff_2[WFC_UTIL_CFG_LENGHT_MAC] = {0x88, 0xcd, 0xba, 0x0c, 0x90, 0x00}; + unsigned char mac_add_buff_3[WFC_UTIL_CFG_LENGHT_MAC] = {0x00, 0x90, 0x0c, 0xba, 0xcd, 0x88}; + + printf("wfc_util_main is started\n"); + + if(0 < wfc_util_fget_string(WFC_UTIL_CFG_FILE_NAME, + WFC_UTIL_CFG_TAG_END_OF_CFG, + WFC_UTIL_CFG_TAG_MAC_ADDRESS, + WFC_UTIL_CFG_TAG_END_OF_LINE, + mac_add_buff, + WFC_UTIL_CFG_LENGHT_MAC_STRING+1)) { + printf("wfc_util_main : %s%s\n", WFC_UTIL_CFG_TAG_MAC_ADDRESS, mac_add_buff); + } else { + printf("wfc_util_main : %s is not found\n", WFC_UTIL_CFG_TAG_MAC_ADDRESS); + } + + wfc_util_fset_string(WFC_UTIL_CFG_FILE_NAME, + WFC_UTIL_CFG_TAG_END_OF_CFG, + WFC_UTIL_CFG_TAG_AP_MAC_ADDRESS, + WFC_UTIL_CFG_TAG_END_OF_LINE, + "00900cbacd88"); + + wfc_util_fset_string(WFC_UTIL_CFG_FILE_NAME, + WFC_UTIL_CFG_TAG_END_OF_CFG, + WFC_UTIL_CFG_TAG_MAC_ADDRESS, + WFC_UTIL_CFG_TAG_END_OF_LINE, + "00900cbacd88"); + + if(0 < wfc_util_fget_string(WFC_UTIL_CFG_FILE_NAME, + WFC_UTIL_CFG_TAG_END_OF_CFG, + WFC_UTIL_CFG_TAG_MAC_ADDRESS, + WFC_UTIL_CFG_TAG_END_OF_LINE, + mac_add_buff, + WFC_UTIL_CFG_LENGHT_MAC_STRING+1)) { + printf("wfc_util_main : %s%s\n", WFC_UTIL_CFG_TAG_MAC_ADDRESS, mac_add_buff); + + wfc_util_atoh(mac_add_buff, strlen(mac_add_buff), mac_add_buff_2, WFC_UTIL_CFG_LENGHT_MAC); + printf("wfc_util_main : %s%02x:%02x:%02x:%02x:%02x:%02x\n", + WFC_UTIL_CFG_TAG_MAC_ADDRESS, + mac_add_buff_2[0], mac_add_buff_2[1], mac_add_buff_2[2], + mac_add_buff_2[3], mac_add_buff_2[4], mac_add_buff_2[5]); + + wfc_util_htoa(mac_add_buff_2, WFC_UTIL_CFG_LENGHT_MAC, mac_add_buff, WFC_UTIL_CFG_LENGHT_MAC_STRING); + printf("wfc_util_main : %s%s\n", WFC_UTIL_CFG_TAG_MAC_ADDRESS, mac_add_buff); + + } else { + printf("wfc_util_main : %s is not found\n", WFC_UTIL_CFG_TAG_MAC_ADDRESS); + } + + wfc_util_fset_buffer(WFC_UTIL_NV_BIN_FILE_NAME, + WFC_UTIL_NV_BIN_POS_MAC_ADDR, + mac_add_buff_3, + WFC_UTIL_CFG_LENGHT_MAC); + + if(0 < wfc_util_fget_buffer(WFC_UTIL_NV_BIN_FILE_NAME, + WFC_UTIL_NV_BIN_POS_MAC_ADDR, + 6, + mac_add_buff_2, + WFC_UTIL_CFG_LENGHT_MAC)) { + printf("wfc_util_main : wfc_util_fget_buffer[%02x:%02x:%02x:%02x:%02x:%02x]\n", + mac_add_buff_2[0], mac_add_buff_2[1], mac_add_buff_2[2], + mac_add_buff_2[3], mac_add_buff_2[4], mac_add_buff_2[5]); + } else { + printf("wfc_util_main : %s is not found\n", WFC_UTIL_CFG_TAG_MAC_ADDRESS); + } + + return ret; +} + diff --git a/conn_init/wfc_util_qcom.c b/conn_init/wfc_util_qcom.c new file mode 100644 index 0000000..b822f4e --- /dev/null +++ b/conn_init/wfc_util_qcom.c @@ -0,0 +1,676 @@ +/* + * Copyright 2012 The Android Open Source 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. + */ + +#ifdef CONFIG_LGE_WLAN_QCOM_PATCH + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "wfc_util_log.h" +#include "wfc_util_fctrl.h" +#include "wfc_util_common.h" + +#include "private/android_filesystem_config.h" + +#define WFC_UTIL_FEAUTRE_COPY_NV_BIN + +#ifdef WLAN_CHIP_VERSION_WCNSS +#ifndef WFC_UTIL_CFG_FILE_NAME +#define WFC_UTIL_CFG_FILE_NAME "/data/misc/wifi/WCNSS_qcom_cfg.ini" +#endif +#ifndef WFC_UTIL_CFG_TEMPFILE_NAME +#define WFC_UTIL_CFG_TEMPFILE_NAME "/system/etc/wifi/WCNSS_qcom_cfg.ini" +#endif +#else /* WLAN_CHIP_VERSION_WCN1314 */ +#ifndef WFC_UTIL_CFG_FILE_NAME +#define WFC_UTIL_CFG_FILE_NAME "/data/misc/wifi/WCN1314_qcom_cfg.ini" +#endif +#ifndef WFC_UTIL_CFG_TEMPFILE_NAME +#define WFC_UTIL_CFG_TEMPFILE_NAME "/system/etc/wifi/WCN1314_qcom_cfg.ini" +#endif +#endif /* WLAN_CHIP_VERSION_XXXX */ + +#ifdef WFC_UTIL_FEAUTRE_COPY_NV_BIN +#ifdef WLAN_CHIP_VERSION_WCNSS +#ifndef WFC_UTIL_NV_BIN_TEMPFILE_NAME +#define WFC_UTIL_NV_BIN_TEMPFILE_NAME "/system/etc/wifi/WCNSS_qcom_wlan_nv.bin" +#endif +#ifndef WFC_UTIL_NV_BIN_FILE_NAME +#define WFC_UTIL_NV_BIN_FILE_NAME "/data/misc/wifi/WCNSS_qcom_wlan_nv.bin" +#endif +#else /* WLAN_CHIP_VERSION_WCN1314 */ +#ifndef WFC_UTIL_NV_BIN_TEMPFILE_NAME +#define WFC_UTIL_NV_BIN_TEMPFILE_NAME "/persist/WCN1314_qcom_wlan_nv.bin" +#endif +#ifndef WFC_UTIL_NV_BIN_FILE_NAME +#define WFC_UTIL_NV_BIN_FILE_NAME "/data/misc/wifi/WCN1314_qcom_wlan_nv.bin" +#endif +#endif /* WLAN_CHIP_VERSION_XXXX */ +#else /* WFC_UTIL_FEAUTRE_COPY_NV_BIN */ +#ifndef WFC_UTIL_NV_BIN_FILE_NAME +#ifdef WLAN_CHIP_VERSION_WCNSS +#define WFC_UTIL_NV_BIN_FILE_NAME "/persist/WCNSS_qcom_wlan_nv.bin" +#else /* WLAN_CHIP_VERSION_WCN1314 */ +#define WFC_UTIL_NV_BIN_FILE_NAME "/persist/WCN1314_qcom_wlan_nv.bin" +#endif /* WLAN_CHIP_VERSION_XXXX */ +#endif +#endif /* WFC_UTIL_FEAUTRE_COPY_NV_BIN */ + +#define WFC_UTIL_CFG_TAG_END_OF_CFG "END" +/* + * Station Mode MAC Address + */ +#ifdef WLAN_CHIP_VERSION_WCNSS +#define WFC_UTIL_CFG_TAG_MAC_ADDRESS "Intf0MacAddress=" +#else /* WLAN_CHIP_VERSION_WCN1314 */ +#define WFC_UTIL_CFG_TAG_MAC_ADDRESS "NetworkAddress=" +#endif /* WLAN_CHIP_VERSION_XXXX */ +/* + * AP Mode MAC Address + */ +#define WFC_UTIL_CFG_TAG_AP_MAC_ADDRESS "gAPMacAddr=" + +/* + * Idle Mode Power Save enable/disable for OTA test + */ +#define WFC_UTIL_CFG_TAG_IDLE_MODE_POWER_SAVE "gEnableImps=" + +/* + * Beacon Mode Power Save enable/disable for OTA test + */ +#define WFC_UTIL_CFG_TAG_POWER_SAVE "gEnableBmps=" + +/* + * L2 roaming on/off for OTA test + */ +#define WFC_UTIL_CFG_TAG_L2Roaming "gEnableHandoff=" + +/* + * Heartbeat24 changing for OtA test + */ +#define WFC_UTIL_CFG_TAG_HEARTBEAT24 "gHeartbeat24=" + +/* + * TAG for end of line + */ +#define WFC_UTIL_CFG_TAG_END_OF_LINE "\n" + +#define WFC_UTIL_CFG_LENGHT_MAC (6) +#define WFC_UTIL_CFG_LENGHT_MAC_STRING (WFC_UTIL_CFG_LENGHT_MAC*2) + +/* + * persist/WCNSS_qcom_wlan_nv.bin + * + * NV validity bitmap (4 bytes) + * { + * Bit 0 - Regulatory domain tables + * Bit 1 - Fields(including product ID, product bands, number of Tx/Rx chains, MAC address, manufacturing board number) + * Bit 2 - Optimal power per rate table + * Bit 3 - Default regulatory domain and country code + * Bit 4:31 - Reserved; always 0 + * } + * + * typedef PACKED_PRE struct PACKED_POST + * { + * //always ensure fields are aligned to 32-bit boundaries + * tANI_U16 productId; + * tANI_U8 productBands; //0: 0.4 GHz, 1: 2.4+5.0 GHz, 2: 5.0 GHz + * tANI_U8 wlanNvRevId; //0: WCN1312, 1: WCN1314, 2: PRIMA + * + * tANI_U8 numOfTxChains; + * tANI_U8 numOfRxChains; + * tANI_U8 macAddr[NV_FIELD_MAC_ADDR_SIZE]; + * tANI_U8 mfgSN[NV_FIELD_MFG_SN_SIZE]; + * } sNvFields; + */ +#define WFC_UTIL_NV_BIN_HEADER_LENGTH (4) +#define WFC_UTIL_NV_BIN_POS_PRODUCT_ID (WFC_UTIL_NV_BIN_HEADER_LENGTH + 0) +#define WFC_UTIL_NV_BIN_POS_MAC_ADDR (WFC_UTIL_NV_BIN_HEADER_LENGTH + 6) + +#ifdef WLAN_CHIP_VERSION_WCNSS +/* refer to prima/CORE/WDA/src/wlan_nv.c */ +static unsigned char nvFilelds_default[6] = {0, 0, /* productId */ + 1, /* productBands */ + 2, /* wlanNvRevId */ + 1, /* numOfTxChains */ + 2}; /* numOfRxChains */ +#else /* WLAN_CHIP_VERSION_WCN1314 */ +static unsigned char nvFilelds_default[6] = {1, 0, /* productId */ + 1, /* productBands */ + 1, /* wlanNvRevId */ + 1, /* numOfTxChains */ + 1}; /* numOfRxChains */ +#endif /* WLAN_CHIP_VERSION_XXXX */ + +/* + * wfc_util_qcom_is_default_mac + * + * + * + * return : it will return 1 if mac_add is default mac address, + * 2 if mac_add is RFT mac address + * or 0 if not. + */ +static int wfc_util_qcom_is_default_mac(char *mac_add) +{ +#define WFC_UTIL_CFG_DEFAULT_MAC_RFT "00900CBACD88" +#define WFC_UTIL_CFG_DEFAULT_MAC_00 "000000000000" +#define WFC_UTIL_CFG_DEFAULT_MAC_FF "FFFFFFFFFFFF" +#define WFC_UTIL_CFG_DEFAULT_MAC_QCOM_I0 "000AF58989FF" +#define WFC_UTIL_CFG_DEFAULT_MAC_QCOM_I1 "000AF58989FE" +#define WFC_UTIL_CFG_DEFAULT_MAC_QCOM_I2 "000AF58989FD" +#define WFC_UTIL_CFG_DEFAULT_MAC_QCOM_I3 "000AF58989FC" +#define WFC_UTIL_CFG_DEFAULT_MAC_QCOM_AP "000AF58989EF" + + int i, sZarray=0; + /* + * default mac address array + */ + char mac_add_buff[][WFC_UTIL_CFG_LENGHT_MAC_STRING+1] = { + {WFC_UTIL_CFG_DEFAULT_MAC_00}, + {WFC_UTIL_CFG_DEFAULT_MAC_FF}, + {WFC_UTIL_CFG_DEFAULT_MAC_QCOM_I0} + }; + + sZarray = sizeof(mac_add_buff) / sizeof(mac_add_buff[0]); + + for(i=0; i<sZarray ;i++) { + if(0 == strncmp(mac_add, mac_add_buff[i], WFC_UTIL_CFG_LENGHT_MAC_STRING)) { + wfc_util_log_error("This is default MAC address [%s]", mac_add_buff[i]); + return 1; + } + } + + /* + if(1 == wfc_util_is_random_mac(mac_add)) { + wfc_util_log_error("This is Random MAC address"); + return 1; + } + */ + + if(0 == strncmp(mac_add, WFC_UTIL_CFG_DEFAULT_MAC_RFT, WFC_UTIL_CFG_LENGHT_MAC_STRING)) { + wfc_util_log_error("This is RFT MAC address [%s]", WFC_UTIL_CFG_DEFAULT_MAC_RFT); + return 2; + } + + return 0; +} + +static void wfc_util_qcom_write_mac(char *mac_add) +{ + /* + * Station Mode MAC Address + */ + wfc_util_fset_string(WFC_UTIL_CFG_FILE_NAME, + WFC_UTIL_CFG_TAG_END_OF_CFG, + WFC_UTIL_CFG_TAG_MAC_ADDRESS, + WFC_UTIL_CFG_TAG_END_OF_LINE, + mac_add); + + /* + * AP Mode MAC Address + */ + wfc_util_fset_string(WFC_UTIL_CFG_FILE_NAME, + WFC_UTIL_CFG_TAG_END_OF_CFG, + WFC_UTIL_CFG_TAG_AP_MAC_ADDRESS, + WFC_UTIL_CFG_TAG_END_OF_LINE, + mac_add); + + return; +} + +/* + * When OTA is enabled, power save mode and L2 roaming trigger should be off + */ +static void wfc_util_qcom_write_ota_enable(void) +{ +/* + * write Beacon Mode Power Save off and L2 Roaming off + */ + char *PowerSaveOff = "0"; + //char *L2RoamingOff = "0"; + char *Heartbeat24 = "120"; + + char string_buff[5]; + + wfc_util_fset_string(WFC_UTIL_CFG_FILE_NAME, + WFC_UTIL_CFG_TAG_END_OF_CFG, + WFC_UTIL_CFG_TAG_IDLE_MODE_POWER_SAVE, + WFC_UTIL_CFG_TAG_END_OF_LINE, + PowerSaveOff); + + wfc_util_fset_string(WFC_UTIL_CFG_FILE_NAME, + WFC_UTIL_CFG_TAG_END_OF_CFG, + WFC_UTIL_CFG_TAG_POWER_SAVE, + WFC_UTIL_CFG_TAG_END_OF_LINE, + PowerSaveOff); + +/* We don't need to change this becasue the default value of WFC_UTIL_CFG_TAG_L2Roaming is 0. + wfc_util_fset_string(WFC_UTIL_CFG_FILE_NAME, + WFC_UTIL_CFG_TAG_END_OF_CFG, + WFC_UTIL_CFG_TAG_L2Roaming, + WFC_UTIL_CFG_TAG_END_OF_LINE, + L2RoamingOff); +*/ + + if(0 < wfc_util_fget_string(WFC_UTIL_CFG_FILE_NAME, + WFC_UTIL_CFG_TAG_END_OF_CFG, + WFC_UTIL_CFG_TAG_HEARTBEAT24, + WFC_UTIL_CFG_TAG_END_OF_LINE, + string_buff, + 5)) { + wfc_util_fset_string(WFC_UTIL_CFG_FILE_NAME, + WFC_UTIL_CFG_TAG_END_OF_CFG, + WFC_UTIL_CFG_TAG_HEARTBEAT24, + WFC_UTIL_CFG_TAG_END_OF_LINE, + Heartbeat24); + } else { + wfc_util_log_error("%s is not exist", WFC_UTIL_CFG_TAG_HEARTBEAT24); + } + + return; +} + +/* + * When OTA is enabled, power save mode and L2 roaming trigger should be off + */ +static void wfc_util_qcom_write_ota_disable(void) +{ +/* + * write Beacon Mode Power Save on and L2 Roaming on + */ + char *PowerSaveOff = "1"; + //char *L2RoamingOff = "1"; + char *Heartbeat24 = "40"; + + char string_buff[5]; + + wfc_util_fset_string(WFC_UTIL_CFG_FILE_NAME, + WFC_UTIL_CFG_TAG_END_OF_CFG, + WFC_UTIL_CFG_TAG_IDLE_MODE_POWER_SAVE, + WFC_UTIL_CFG_TAG_END_OF_LINE, + PowerSaveOff); + + wfc_util_fset_string(WFC_UTIL_CFG_FILE_NAME, + WFC_UTIL_CFG_TAG_END_OF_CFG, + WFC_UTIL_CFG_TAG_POWER_SAVE, + WFC_UTIL_CFG_TAG_END_OF_LINE, + PowerSaveOff); + +/* We don't need to change this becasue the default value of WFC_UTIL_CFG_TAG_L2Roaming is 0. + wfc_util_fset_string(WFC_UTIL_CFG_FILE_NAME, + WFC_UTIL_CFG_TAG_END_OF_CFG, + WFC_UTIL_CFG_TAG_L2Roaming, + WFC_UTIL_CFG_TAG_END_OF_LINE, + L2RoamingOff); +*/ + + if(0 < wfc_util_fget_string(WFC_UTIL_CFG_FILE_NAME, + WFC_UTIL_CFG_TAG_END_OF_CFG, + WFC_UTIL_CFG_TAG_HEARTBEAT24, + WFC_UTIL_CFG_TAG_END_OF_LINE, + string_buff, + 5)) { + wfc_util_fset_string(WFC_UTIL_CFG_FILE_NAME, + WFC_UTIL_CFG_TAG_END_OF_CFG, + WFC_UTIL_CFG_TAG_HEARTBEAT24, + WFC_UTIL_CFG_TAG_END_OF_LINE, + Heartbeat24); + } else { + wfc_util_log_error("%s is not exist", WFC_UTIL_CFG_TAG_HEARTBEAT24); + } + + return; +} + +static void wfc_util_qcom_write_mac_to_bin(unsigned char *mac_add) +{ + unsigned char nvValidityBitmap[WFC_UTIL_NV_BIN_HEADER_LENGTH]; + + if(0 != wfc_util_ffile_check(WFC_UTIL_NV_BIN_FILE_NAME, + F_OK|R_OK|W_OK)) { + wfc_util_log_error("We don't access file [%s]", WFC_UTIL_NV_BIN_FILE_NAME); + return; + } + + memset(nvValidityBitmap, 0, WFC_UTIL_NV_BIN_HEADER_LENGTH); + + /* + * Write RFT MAC Address + */ + wfc_util_fset_buffer(WFC_UTIL_NV_BIN_FILE_NAME, + WFC_UTIL_NV_BIN_POS_MAC_ADDR, + mac_add, + WFC_UTIL_CFG_LENGHT_MAC); + + /* + * Read NV validity bitmap + */ + if (0 < wfc_util_fget_buffer(WFC_UTIL_NV_BIN_FILE_NAME, + 0, + WFC_UTIL_NV_BIN_HEADER_LENGTH, + nvValidityBitmap, + WFC_UTIL_NV_BIN_HEADER_LENGTH)){ + /* + * Check whether Fields bit(Bit 1) is set + */ + if (0x02 & nvValidityBitmap[0]) { + wfc_util_log_info("We don't need to write the default value for NvFilelds"); + } else { + /* + * Update the Fields bit(Bit 1) + */ + nvValidityBitmap[0] |= 0x02; + wfc_util_fset_buffer(WFC_UTIL_NV_BIN_FILE_NAME, + 0, + nvValidityBitmap, + WFC_UTIL_NV_BIN_HEADER_LENGTH); + + /* + * Write the default value for NvFilelds + */ + wfc_util_fset_buffer(WFC_UTIL_NV_BIN_FILE_NAME, + WFC_UTIL_NV_BIN_POS_PRODUCT_ID, + nvFilelds_default, + 6); + } + } else { + wfc_util_log_error("Read Fail nvValidityBitmap"); + } + + return; +} + +/* + * wfc_util_qcom_reset_mac_to_bin + * + * reset the mac address of nv bin file + * + * return : void + */ +static void wfc_util_qcom_reset_mac_to_bin(void) +{ + unsigned char mac_addr[WFC_UTIL_CFG_LENGHT_MAC]; + + if(0 != wfc_util_ffile_check(WFC_UTIL_NV_BIN_FILE_NAME, + F_OK|R_OK|W_OK)) { + wfc_util_log_error("We don't access file [%s]", WFC_UTIL_NV_BIN_FILE_NAME); + return; + } + + if(0 < wfc_util_fget_buffer(WFC_UTIL_NV_BIN_FILE_NAME, + WFC_UTIL_NV_BIN_POS_MAC_ADDR, + WFC_UTIL_CFG_LENGHT_MAC, + mac_addr, + WFC_UTIL_CFG_LENGHT_MAC)) { + if(0x00 == mac_addr[0] && 0x00 == mac_addr[1] && 0x00 == mac_addr[2] && + 0x00 == mac_addr[3] && 0x00 == mac_addr[4] && 0x00 == mac_addr[5]) + { + return; + } + } + + memset(mac_addr, 0, WFC_UTIL_CFG_LENGHT_MAC); + + wfc_util_fset_buffer(WFC_UTIL_NV_BIN_FILE_NAME, + WFC_UTIL_NV_BIN_POS_MAC_ADDR, + mac_addr, + WFC_UTIL_CFG_LENGHT_MAC); + + return; +} + +static int wfc_util_qcom_write_mac_process(unsigned char *nv_mac_addr, char *mac_add_buff) +{ + char nv_mac_add_buff[WFC_UTIL_CFG_LENGHT_MAC_STRING+1]; + int is_default_nv_mac = 0; + int is_same_mac = -1; + + if (NULL == nv_mac_addr) { + return 0; + } + + wfc_util_htoa(nv_mac_addr, WFC_UTIL_CFG_LENGHT_MAC, + nv_mac_add_buff, WFC_UTIL_CFG_LENGHT_MAC_STRING+1); + + is_default_nv_mac = wfc_util_qcom_is_default_mac(nv_mac_add_buff); + + is_same_mac = strncmp(mac_add_buff, nv_mac_add_buff, WFC_UTIL_CFG_LENGHT_MAC_STRING); + + /* + * 1. nv mac address is not a default mac address + * 2. same with mac address of config file + */ + if (((!is_default_nv_mac) && (0==is_same_mac)) || + /* + * 1. nv mac address is RFT mac address + * 2. same with mac address of config file + */ + ((2==is_default_nv_mac) && (0==is_same_mac)) + ) { + return 1; + } + /* + * 1. nv mac address not a default mac address excepting RFT mac address + * 2. does not same with mac address of config file + */ + else if ((1!=is_default_nv_mac) && (0!=is_same_mac)) { + wfc_util_log_error("Change %s%s", WFC_UTIL_CFG_TAG_MAC_ADDRESS, nv_mac_add_buff); + /* + * Update MAC address + */ + wfc_util_qcom_write_mac(nv_mac_add_buff); + +#ifdef WFC_UTIL_FEATURE_DO_NOT_WRITE_MAC_TO_BIN + /* + * Write RFT MAC address to nv.bin + */ + if (2==is_default_nv_mac) { + wfc_util_qcom_write_mac_to_bin(nv_mac_addr); + /* + * reset mac address of nv.bin if nv_mac_addr is not RFT mac address + */ + } else { + wfc_util_qcom_reset_mac_to_bin(); + } +#else /* WFC_UTIL_FEATURE_DO_NOT_WRITE_MAC_TO_BIN */ + /* + * Write MAC address to nv.bin + */ + wfc_util_qcom_write_mac_to_bin(nv_mac_addr); +#endif /* WFC_UTIL_FEATURE_DO_NOT_WRITE_MAC_TO_BIN */ + + return 1; + } + + return 0; +} + +static void wfc_util_qcom_create_random_mac(void) +{ + unsigned char random_mac_addr[WFC_UTIL_CFG_LENGHT_MAC]; + char mac_add_buff[WFC_UTIL_CFG_LENGHT_MAC_STRING+1]; + + wfc_util_log_info("wfc_util_qcom_create_random_mac"); + + wfc_util_random_mac(random_mac_addr); + + wfc_util_htoa(random_mac_addr, WFC_UTIL_CFG_LENGHT_MAC, mac_add_buff, WFC_UTIL_CFG_LENGHT_MAC_STRING+1); + + wfc_util_qcom_write_mac(mac_add_buff); + +#ifdef WFC_UTIL_FEATURE_DO_NOT_WRITE_MAC_TO_BIN + wfc_util_qcom_reset_mac_to_bin(); +#else /* WFC_UTIL_FEATURE_DO_NOT_WRITE_MAC_TO_BIN */ + wfc_util_qcom_write_mac_to_bin(random_mac_addr); +#endif /* WFC_UTIL_FEATURE_DO_NOT_WRITE_MAC_TO_BIN */ + + return; +} + +/* + * wfc_util_qcom_check_config + * + * check the qcom wlan driver config file + * + * return : it will return 0 if procedure is success + * or will return -1 if not. + */ +int wfc_util_qcom_check_config(unsigned char *nv_mac_addr) +{ + char mac_add_buff[WFC_UTIL_CFG_LENGHT_MAC_STRING+1]; + + /* make sure driver config file exists */ + if(0 > wfc_util_ffile_check_copy(WFC_UTIL_CFG_FILE_NAME, + WFC_UTIL_CFG_TEMPFILE_NAME, + 0660, + AID_SYSTEM, + /* we use "radio" for gid to access from "rild" for AT cmd. */ + AID_WIFI/*AID_WIFI*/)) { + wfc_util_log_error("Fail to Access [%s]", WFC_UTIL_CFG_FILE_NAME); + return -1; + } + +#ifdef WFC_UTIL_FEAUTRE_COPY_NV_BIN + if(0 > wfc_util_ffile_check_copy(WFC_UTIL_NV_BIN_FILE_NAME, + WFC_UTIL_NV_BIN_TEMPFILE_NAME, + 0660, + AID_SYSTEM, + /* we use "radio" for gid to access from "rild" for AT cmd. */ + AID_WIFI/*AID_WIFI*/)) { + wfc_util_log_error("Fail to Access [%s]", WFC_UTIL_NV_BIN_FILE_NAME); + return -1; + } +#endif /* WFC_UTIL_FEAUTRE_COPY_NV_BIN */ + + /* + * Read MAC address from config file + */ + if(0 < wfc_util_fget_string(WFC_UTIL_CFG_FILE_NAME, + WFC_UTIL_CFG_TAG_END_OF_CFG, + WFC_UTIL_CFG_TAG_MAC_ADDRESS, + WFC_UTIL_CFG_TAG_END_OF_LINE, + mac_add_buff, + WFC_UTIL_CFG_LENGHT_MAC_STRING+1)) { + wfc_util_log_info("%s%s", WFC_UTIL_CFG_TAG_MAC_ADDRESS, mac_add_buff); + + /* + * Write nv mac address + */ + if (1 != wfc_util_qcom_write_mac_process(nv_mac_addr, mac_add_buff)) { + /* + * Check whether this is default mac address or not + */ + if (wfc_util_qcom_is_default_mac(mac_add_buff)) { + /* + * Create random MAC address + */ + wfc_util_qcom_create_random_mac(); + } + } + } else { + wfc_util_log_error("%s does not have mac address", WFC_UTIL_CFG_FILE_NAME); + + memset( mac_add_buff, 0, WFC_UTIL_CFG_LENGHT_MAC_STRING+1 ); + + /* + * Write nv mac address + */ + if (1 != wfc_util_qcom_write_mac_process(nv_mac_addr, mac_add_buff)) { + /* + * Create random MAC address + */ + wfc_util_qcom_create_random_mac(); + } + } + + return 0; +} + +/* + * wfc_util_qcom_reset_mac + * + * reset the mac address of config file + * + * return : void + */ +void wfc_util_qcom_reset_mac(void) +{ + wfc_util_qcom_write_mac("000000000000"); + + wfc_util_qcom_reset_mac_to_bin(); + + return; +} + +/* + * wfc_util_qcom_ota_enable + * + * enable ota mode by reconfiguring BMPS and L2Roaming + * + * return : int (boolean) + */ +int wfc_util_qcom_ota_enable(void) +{ + wfc_util_qcom_write_ota_enable(); + return 1; +} + +/* + * wfc_util_qcom_ota_disable + * + * disable ota mode by reconfiguring BMPS and L2Roaming + * + * return : int (boolean) + */ +int wfc_util_qcom_ota_disable(void) +{ + wfc_util_qcom_write_ota_disable(); + return 1; +} + +/* + * wfc_util_qcom_checkt_roaming_off + * + * Check L2Roaming configuration + * + * return : int (boolean) + */ +int wfc_util_qcom_checkt_roaming_off(void) +{ + char string_buff[5]; + /* + * check whether OTA test is enabled or not. + */ + if(0 < wfc_util_fget_string(WFC_UTIL_CFG_FILE_NAME, + WFC_UTIL_CFG_TAG_END_OF_CFG, + //WFC_UTIL_CFG_TAG_L2Roaming, + WFC_UTIL_CFG_TAG_POWER_SAVE, + WFC_UTIL_CFG_TAG_END_OF_LINE, + string_buff, + 5)) { + //wfc_util_log_info("%s%s", WFC_UTIL_CFG_TAG_L2Roaming, string_buff); + wfc_util_log_info("%s%s", WFC_UTIL_CFG_TAG_POWER_SAVE, string_buff); + if(0 == strncmp(string_buff, "0", 1)) { + return 1; + } + } + return 0; +} + +#endif /* CONFIG_LGE_WLAN_QCOM_PATCH */ + diff --git a/conn_init/wfc_util_qcom.h b/conn_init/wfc_util_qcom.h new file mode 100644 index 0000000..1bd4cc1 --- /dev/null +++ b/conn_init/wfc_util_qcom.h @@ -0,0 +1,52 @@ +/* + * Copyright 2012 The Android Open Source 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 __WFC_UTIL_QCOM_H__ +#define __WFC_UTIL_QCOM_H__ + +#ifdef CONFIG_LGE_WLAN_QCOM_PATCH +/* + * wfc_util_qcom_check_config + * + * check the qcom wlan driver config file + * + * return : it will return 0 if procedure is success + * or will return -1 if not. + */ +extern int wfc_util_qcom_check_config(unsigned char *nv_mac_addr); + +/* + * wfc_util_qcom_reset_mac + * + * reset the mac address of config file + * + * return : void + */ +extern void wfc_util_qcom_reset_mac(void); + +/* + * wfc_util_qcom_ota_enable/disable + * + * enable OTA mode for Wi-Fi related certificiation + * + * return : int (boolean) + */ +extern int wfc_util_qcom_ota_enable(void); +extern int wfc_util_qcom_ota_disable(void); +extern int wfc_util_qcom_checkt_roaming_off(void); +#endif /* CONFIG_LGE_WLAN_QCOM_PATCH */ +#endif + @@ -45,9 +45,9 @@ PRODUCT_COPY_FILES := \ PRODUCT_COPY_FILES += \ device/lge/mako-kernel/prima_wlan.ko:system/lib/modules/wlan.ko \ - device/lge/mako/WCNSS_cfg.dat:system/etc/firmware/wlan/prima/WCNSS_cfg.dat \ - device/lge/mako/WCNSS_qcom_cfg.ini:system/etc/firmware/wlan/prima/WCNSS_qcom_cfg.ini \ - device/lge/mako/WCNSS_qcom_wlan_nv.bin:system/etc/firmware/wlan/prima/WCNSS_qcom_wlan_nv.bin + device/lge/mako/WCNSS_cfg.dat:system/vendor/firmware/wlan/prima/WCNSS_cfg.dat \ + device/lge/mako/WCNSS_qcom_cfg.ini:system/etc/wifi/WCNSS_qcom_cfg.ini \ + device/lge/mako/WCNSS_qcom_wlan_nv.bin:system/etc/wifi/WCNSS_qcom_wlan_nv.bin PRODUCT_COPY_FILES += \ system/bluetooth/data/main.conf:system/etc/bluetooth/main.conf @@ -160,6 +160,10 @@ PRODUCT_PACKAGES += \ libgps.utils \ gps.msm8960 +PRODUCT_PACKAGES += \ + libwfcu \ + conn_init + PRODUCT_DEFAULT_PROPERTY_OVERRIDES += \ rild.libpath=/system/lib/libril-qc-qmi-1.so diff --git a/init.mako.rc b/init.mako.rc index 4c0a26b..7cdd667 100644 --- a/init.mako.rc +++ b/init.mako.rc @@ -596,3 +596,8 @@ service qcamerasvr /system/bin/mm-qcamera-daemon user camera group camera system inet input +service conn_init /system/bin/logwrapper /system/bin/conn_init + class late_start + user system + group system wifi + oneshot |