summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSungmin Choi <sungmin.choi@lge.com>2012-07-18 01:49:40 -0700
committerBrian Muramatsu <btmura@google.com>2012-07-18 19:25:32 -0700
commit5fd819dcca2ce41b0c7fa56d010dca6cbc3cc0d0 (patch)
tree95daf09cd07b7868258c3f7c1ac8e9dcc8577309
parent2cfa86f69206d8d901592ecfaab05f55ebd0b5e5 (diff)
downloadmako-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.mk78
-rw-r--r--conn_init/NOTICE190
-rw-r--r--conn_init/conn_init.c56
-rw-r--r--conn_init/wfc_util_common.c135
-rw-r--r--conn_init/wfc_util_common.h51
-rw-r--r--conn_init/wfc_util_fctrl.c664
-rw-r--r--conn_init/wfc_util_fctrl.h92
-rw-r--r--conn_init/wfc_util_log.h32
-rw-r--r--conn_init/wfc_util_main.c139
-rw-r--r--conn_init/wfc_util_qcom.c676
-rw-r--r--conn_init/wfc_util_qcom.h52
-rw-r--r--device.mk10
-rw-r--r--init.mako.rc5
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
+
diff --git a/device.mk b/device.mk
index bf52fad..9945fe0 100644
--- a/device.mk
+++ b/device.mk
@@ -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