diff options
-rw-r--r-- | qcwcn/wifi_hal/nan.h | 30 | ||||
-rw-r--r-- | qcwcn/wifi_hal/nan_i.h | 26 | ||||
-rw-r--r-- | qcwcn/wifi_hal/nan_ind.cpp | 54 | ||||
-rw-r--r-- | qcwcn/wifi_hal/nan_req.cpp | 68 | ||||
-rw-r--r-- | qcwcn/wifi_hal/nancommand.h | 2 | ||||
-rw-r--r-- | qcwcn/wifi_hal/wifi_hal.cpp | 14 | ||||
-rw-r--r-- | qcwcn/wpa_supplicant_8_lib/driver_cmd_nl80211.c | 13 | ||||
-rw-r--r-- | wcnss-service/Android.mk | 59 | ||||
-rw-r--r-- | wcnss-service/wcnss_qmi_client.c | 70 | ||||
-rw-r--r-- | wcnss-service/wcnss_service.c | 99 |
10 files changed, 353 insertions, 82 deletions
diff --git a/qcwcn/wifi_hal/nan.h b/qcwcn/wifi_hal/nan.h index 688a8b5..02a5551 100644 --- a/qcwcn/wifi_hal/nan.h +++ b/qcwcn/wifi_hal/nan.h @@ -44,8 +44,6 @@ typedef int NanVersion; #define NAN_MAJOR_VERSION 2 #define NAN_MINOR_VERSION 0 #define NAN_MICRO_VERSION 0 -#define NAN_TRANSMIT_POST_CONNECTIVITY_CAPABILITY_SIZE 4 -#define NAN_FURTHER_AVAILABILITY_MAP_SIZE 8 #define NAN_MAX_SOCIAL_CHANNEL 3 /* NAN Maximum Lengths */ @@ -56,6 +54,7 @@ typedef int NanVersion; #define NAN_MAX_MESH_DATA_LEN 32 #define NAN_MAX_CLUSTER_ATTRIBUTE_LEN 255 #define NAN_MAX_SUBSCRIBE_MAX_ADDRESS 42 +#define NAN_MAX_FAM_CHANNELS 32 /* Definition of various NanRequestType @@ -488,16 +487,9 @@ typedef enum { NAN_DURATION_32MS = 1, NAN_DURATION_64MS = 2 } NanAvailDuration; -/* - Further availability map which can sent and received from - Discovery engine -*/ + +/* Further availability per channel information */ typedef struct { - /* - Number of channels indicates the number of entries - in vector which is part of fam - */ - u8 numchans; /* Defined above */ NanAvailDuration entry_control; /* @@ -541,9 +533,19 @@ typedef struct { - Duration field is equal to 2, AIB [0], AIB [1], AIB [2] and AIB [3] are valid */ u32 avail_interval_bitmap; - /* Additional Vendor elements if numchans > 1*/ - u32 vendor_elements_len; - u8 vendor_elements[NAN_MAX_VSA_DATA_LEN]; +} NanFurtherAvailabilityChannel; + +/* + Further availability map which can be sent and received from + Discovery engine +*/ +typedef struct { + /* + Number of channels indicates the number of channel + entries which is part of fam + */ + u8 numchans; + NanFurtherAvailabilityChannel famchan[NAN_MAX_FAM_CHANNELS]; } NanFurtherAvailabilityMap; /* diff --git a/qcwcn/wifi_hal/nan_i.h b/qcwcn/wifi_hal/nan_i.h index e269250..3bb531a 100644 --- a/qcwcn/wifi_hal/nan_i.h +++ b/qcwcn/wifi_hal/nan_i.h @@ -865,6 +865,32 @@ typedef enum /* Reserved 20480 - 65535*/ NAN_TLV_TYPE_FW_LAST = 65535 } NanFwTlvType; + +typedef struct PACKED +{ + u8 availIntDuration:2; + u8 mapId:4; + u8 reserved:2; +} NanApiEntryCtrl; + +/* + * Valid Operating Classes were derived from IEEE Std. 802.11-2012 Annex E + * Table E-4 Global Operating Classe and, filtered by channel, are: 81, 83, + * 84, 103, 114, 115, 116, 124, 125. + */ +typedef struct PACKED +{ + NanApiEntryCtrl entryCtrl; + u8 opClass; + u8 channel; + u8 availIntBitmap[4]; +} NanFurtherAvailabilityChan, *pNanFurtherAvailabilityChan; + +typedef struct PACKED +{ + u8 numChan; + u8 pFaChan[]; +} NanFurtherAvailabilityMapAttrTlv, *pNanFurtherAvailabilityMapAttrTlv; #endif /* NAN_2_0 */ #ifdef __cplusplus diff --git a/qcwcn/wifi_hal/nan_ind.cpp b/qcwcn/wifi_hal/nan_ind.cpp index 41fb0f0..cdf61d3 100644 --- a/qcwcn/wifi_hal/nan_ind.cpp +++ b/qcwcn/wifi_hal/nan_ind.cpp @@ -264,8 +264,8 @@ int NanCommand::getNanPublishReplied(NanPublishRepliedInd *event) /* Populate further availability bitmap from received TLV */ ret = getNanFurtherAvailabilityMap(outputTlv.value, - outputTlv.length, - &event->fam); + outputTlv.length, + &event->fam); if (ret == 0) { event->is_fam_valid = 1; } @@ -411,8 +411,8 @@ int NanCommand::getNanMatch(NanMatchInd *event) /* Populate further availability bitmap from received TLV */ ret = getNanFurtherAvailabilityMap(outputTlv.value, - outputTlv.length, - &event->fam); + outputTlv.length, + &event->fam); if (ret == 0) { event->is_fam_valid = 1; } @@ -882,34 +882,34 @@ int NanCommand::getNanFurtherAvailabilityMap(const u8 *pInValue, NanFurtherAvailabilityMap *pFam) { #ifdef NAN_2_0 - if ((length <= NAN_FURTHER_AVAILABILITY_MAP_SIZE) || - pInValue == NULL) { - ALOGE("%s: Invalid Arg TLV Len %d < %d", __func__, - length, NAN_FURTHER_AVAILABILITY_MAP_SIZE); + int idx = 0; + + if ((length == 0) || pInValue == NULL) { + ALOGE("%s: Invalid Arg TLV Len %d or pInValue NULL", + __func__, length); return -1; } pFam->numchans = pInValue[0]; - pFam->entry_control = (NanAvailDuration)(pInValue[1] & 0x03); - pFam->class_val = pInValue[2]; - pFam->channel = pInValue[3]; - pFam->mapid = (pInValue[1] >> 2) & 0x0F; - memcpy(&pFam->avail_interval_bitmap, - &pInValue[4], - sizeof(pFam->avail_interval_bitmap)); - pFam->vendor_elements_len = 0; - if (pFam->numchans > 1) { - pFam->vendor_elements_len = length - \ - NAN_FURTHER_AVAILABILITY_MAP_SIZE; - if (pFam->vendor_elements_len > NAN_MAX_VSA_DATA_LEN) { - pFam->vendor_elements_len = NAN_MAX_VSA_DATA_LEN; - } - memcpy(pFam->vendor_elements, &pInValue[8], - pFam->vendor_elements_len); + if (pFam->numchans > NAN_MAX_FAM_CHANNELS) { + ALOGE("%s: Unable to accommodate numchans %d", + __func__, pFam->numchans); + return -1; } - else { - memset(pFam->vendor_elements, 0, - sizeof(pFam->vendor_elements)); + for (idx = 0; idx < pFam->numchans; idx++) { + pNanFurtherAvailabilityChan pRsp = \ + (pNanFurtherAvailabilityChan)((u8*)pInValue[1] + \ + (idx * sizeof(NanFurtherAvailabilityChan))); + NanFurtherAvailabilityChannel *pFamChan = &pFam->famchan[idx]; + + pFamChan->entry_control = \ + (NanAvailDuration)(pRsp->entryCtrl.availIntDuration); + pFamChan->mapid = pRsp->entryCtrl.mapId; + pFamChan->class_val = pRsp->opClass; + pFamChan->channel = pRsp->channel; + memcpy(&pFamChan->avail_interval_bitmap, + &pRsp->availIntBitmap, + sizeof(pFamChan->avail_interval_bitmap)); } #endif /* NAN_2_0*/ return 0; diff --git a/qcwcn/wifi_hal/nan_req.cpp b/qcwcn/wifi_hal/nan_req.cpp index 250a5bd..4179398 100644 --- a/qcwcn/wifi_hal/nan_req.cpp +++ b/qcwcn/wifi_hal/nan_req.cpp @@ -324,12 +324,13 @@ int NanCommand::putNanConfig(const NanConfigRequest *pReq) ( pReq->config_discovery_attr ? (SIZEOF_TLV_HDR + \ calcNanTransmitPostDiscoverySize(&pReq->discovery_attr_val)) : 0 \ - ) + \ - ( - pReq->config_fam ? (SIZEOF_TLV_HDR + \ - NAN_FURTHER_AVAILABILITY_MAP_SIZE + \ - pReq->fam_val.vendor_elements_len) : 0 \ ); + + if (pReq->config_fam && \ + calcNanFurtherAvailabilityMapSize(&pReq->fam_val)) { + message_len += (SIZEOF_TLV_HDR + \ + calcNanFurtherAvailabilityMapSize(&pReq->fam_val)); + } #endif /* NAN_2_0 */ pNanConfigurationReqMsg pFwReq = (pNanConfigurationReqMsg)malloc(message_len); @@ -428,12 +429,12 @@ int NanCommand::putNanConfig(const NanConfigRequest *pReq) calcNanTransmitPostDiscoverySize(&pReq->discovery_attr_val), (const u8*)(tlvs + SIZEOF_TLV_HDR), tlvs); } - if (pReq->config_fam) { + if (pReq->config_fam && \ + calcNanFurtherAvailabilityMapSize(&pReq->fam_val)) { fillNanFurtherAvailabilityMapVal(&pReq->fam_val, (u8*)(tlvs + SIZEOF_TLV_HDR)); tlvs = addTlv(NAN_TLV_TYPE_FURTHER_AVAILABILITY_MAP, - (NAN_FURTHER_AVAILABILITY_MAP_SIZE + \ - pReq->fam_val.vendor_elements_len), + calcNanFurtherAvailabilityMapSize(&pReq->fam_val), (const u8*)(tlvs + SIZEOF_TLV_HDR), tlvs); } #endif /* NAN_2_0 */ @@ -1049,23 +1050,50 @@ void NanCommand::fillNanFurtherAvailabilityMapVal( const NanFurtherAvailabilityMap *pFam, u8 *pOutValue) { + int idx = 0; + if (pFam && pOutValue) { - u32 famsize = NAN_FURTHER_AVAILABILITY_MAP_SIZE + \ - pFam->vendor_elements_len; + u32 famsize = calcNanFurtherAvailabilityMapSize(pFam); + pNanFurtherAvailabilityMapAttrTlv pFwReq = \ + (pNanFurtherAvailabilityMapAttrTlv)pOutValue; + memset(pOutValue, 0, famsize); - pOutValue[0] = pFam->numchans; - pOutValue[1] = (pFam->mapid & 0x0F) << 2; - pOutValue[1] |= (pFam->entry_control & 0x03); - pOutValue[2] = pFam->class_val; - pOutValue[3] = pFam->channel; - memcpy(&pOutValue[4], &pFam->avail_interval_bitmap, - sizeof(pFam->avail_interval_bitmap)); - memcpy(&pOutValue[NAN_FURTHER_AVAILABILITY_MAP_SIZE], - pFam->vendor_elements, - pFam->vendor_elements_len); + pFwReq->numChan = pFam->numchans; + for (idx = 0; idx < pFam->numchans; idx++) { + const NanFurtherAvailabilityChannel *pFamChan = \ + &pFam->famchan[idx]; + pNanFurtherAvailabilityChan pFwFamChan = \ + (pNanFurtherAvailabilityChan)((u8*)&pFwReq->pFaChan[0] + \ + (idx * sizeof(NanFurtherAvailabilityChan))); + + pFwFamChan->entryCtrl.availIntDuration = \ + pFamChan->entry_control; + pFwFamChan->entryCtrl.mapId = \ + pFamChan->mapid; + pFwFamChan->opClass = pFamChan->class_val; + pFwFamChan->channel = pFamChan->channel; + memcpy(&pFwFamChan->availIntBitmap, + &pFamChan->avail_interval_bitmap, + sizeof(pFwFamChan->availIntBitmap)); + } ALOGI("%s: Filled FurtherAvailabilityMapVal", __func__); hexdump((char*)pOutValue, famsize); } return; } +int NanCommand::calcNanFurtherAvailabilityMapSize( + const NanFurtherAvailabilityMap *pFam) +{ + int ret = 0; + if (pFam && pFam->numchans && + pFam->numchans <= NAN_MAX_FAM_CHANNELS) { + /* Fixed size of u8 for numchans*/ + ret = sizeof(u8); + /* numchans * sizeof(FamChannels) */ + ret += (pFam->numchans * sizeof(NanFurtherAvailabilityChan)); + } + ALOGI("%s:size:%d", __func__, ret); + return ret; +} + diff --git a/qcwcn/wifi_hal/nancommand.h b/qcwcn/wifi_hal/nancommand.h index dabc115..096fc71 100644 --- a/qcwcn/wifi_hal/nancommand.h +++ b/qcwcn/wifi_hal/nancommand.h @@ -73,6 +73,8 @@ private: void fillNanTransmitPostDiscoveryVal( const NanTransmitPostDiscovery *pTxDisc, u8 *pOutValue); + int calcNanFurtherAvailabilityMapSize( + const NanFurtherAvailabilityMap *pFam); void fillNanFurtherAvailabilityMapVal( const NanFurtherAvailabilityMap *pFam, u8 *pOutValue); diff --git a/qcwcn/wifi_hal/wifi_hal.cpp b/qcwcn/wifi_hal/wifi_hal.cpp index 5d089b9..b9573e0 100644 --- a/qcwcn/wifi_hal/wifi_hal.cpp +++ b/qcwcn/wifi_hal/wifi_hal.cpp @@ -152,7 +152,7 @@ int error_handler(struct sockaddr_nl *nla, } static int no_seq_check(struct nl_msg *msg, void *arg) { - ALOGD("no_seq_check received"); + ALOGV("no_seq_check received"); return NL_OK; } @@ -383,7 +383,7 @@ static void internal_event_handler(wifi_handle handle, int events) } else if (events & POLLHUP) { ALOGE("Remote side hung up"); } else if (events & POLLIN) { - ALOGI("Found some events!!!"); + ALOGV("Found some events!!!"); internal_pollin_handler(handle); } else { ALOGE("Unknown event - %0x", events); @@ -413,7 +413,7 @@ void wifi_event_loop(wifi_handle handle) pfd.revents = 0; //ALOGI("Polling socket"); int result = poll(&pfd, 1, -1); - ALOGI("Poll result = %0x", result); + ALOGV("Poll result = %0x", result); if (result < 0) { ALOGE("Error polling socket"); } else if (pfd.revents & (POLLIN | POLLHUP | POLLERR)) { @@ -447,13 +447,13 @@ static int internal_valid_message_handler(nl_msg *msg, void *arg) if (cmd == NL80211_CMD_VENDOR) { vendor_id = event.get_u32(NL80211_ATTR_VENDOR_ID); subcmd = event.get_u32(NL80211_ATTR_VENDOR_SUBCMD); - ALOGI("event received %s, vendor_id = 0x%0x, subcmd = 0x%0x", + ALOGV("event received %s, vendor_id = 0x%0x, subcmd = 0x%0x", event.get_cmdString(), vendor_id, subcmd); } else { - ALOGI("event received %s", event.get_cmdString()); + ALOGV("event received %s", event.get_cmdString()); } - ALOGI("event received %s, vendor_id = 0x%0x", event.get_cmdString(), + ALOGV("event received %s, vendor_id = 0x%0x", event.get_cmdString(), vendor_id); // event.log(); @@ -475,7 +475,7 @@ static int internal_valid_message_handler(nl_msg *msg, void *arg) } if (!dispatched) { - ALOGI("event ignored!!"); + ALOGV("event ignored!!"); } return NL_OK; diff --git a/qcwcn/wpa_supplicant_8_lib/driver_cmd_nl80211.c b/qcwcn/wpa_supplicant_8_lib/driver_cmd_nl80211.c index 59717c0..e82da16 100644 --- a/qcwcn/wpa_supplicant_8_lib/driver_cmd_nl80211.c +++ b/qcwcn/wpa_supplicant_8_lib/driver_cmd_nl80211.c @@ -70,16 +70,21 @@ int wpa_driver_nl80211_driver_cmd(void *priv, char *cmd, char *buf, { struct i802_bss *bss = priv; struct wpa_driver_nl80211_data *drv = bss->drv; + struct wpa_driver_nl80211_data *driver; struct ifreq ifr; android_wifi_priv_cmd priv_cmd; int ret = 0; if (os_strcasecmp(cmd, "STOP") == 0) { - linux_set_iface_flags(drv->global->ioctl_sock, bss->ifname, 0); - wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "STOPPED"); + dl_list_for_each(driver, &drv->global->interfaces, struct wpa_driver_nl80211_data, list) { + linux_set_iface_flags(drv->global->ioctl_sock, driver->first_bss->ifname, 0); + wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "STOPPED"); + } } else if (os_strcasecmp(cmd, "START") == 0) { - linux_set_iface_flags(drv->global->ioctl_sock, bss->ifname, 1); - wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "STARTED"); + dl_list_for_each(driver, &drv->global->interfaces, struct wpa_driver_nl80211_data, list) { + linux_set_iface_flags(drv->global->ioctl_sock, driver->first_bss->ifname, 1); + wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "STARTED"); + } } else if (os_strcasecmp(cmd, "MACADDR") == 0) { u8 macaddr[ETH_ALEN] = {}; diff --git a/wcnss-service/Android.mk b/wcnss-service/Android.mk index 6c75660..ab93d4e 100644 --- a/wcnss-service/Android.mk +++ b/wcnss-service/Android.mk @@ -1,23 +1,70 @@ ifneq (,$(filter arm aarch64 arm64, $(TARGET_ARCH))) + LOCAL_PATH := $(call my-dir) + include $(CLEAR_VARS) + LOCAL_MODULE := wcnss_service LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/common/inc/ LOCAL_SRC_FILES := wcnss_service.c +LOCAL_SHARED_LIBRARIES := libc libcutils libutils liblog + ifeq ($(strip $(TARGET_USES_QCOM_WCNSS_QMI)),true) + +ifeq ($(TARGET_PROVIDES_WCNSS_QMI),true) +LOCAL_CFLAGS += -DWCNSS_QMI_OSS +LOCAL_SHARED_LIBRARIES += libdl +else +ifeq ($(TARGET_USES_WCNSS_MAC_ADDR_REV),true) +LOCAL_CFLAGS += -DWCNSS_QMI_MAC_ADDR_REV +endif + +ifneq ($(QCPATH),) LOCAL_CFLAGS += -DWCNSS_QMI +LOCAL_SHARED_LIBRARIES += libwcnss_qmi +else +LOCAL_CFLAGS += -DWCNSS_QMI_OSS +LOCAL_SHARED_LIBRARIES += libdl +endif #QCPATH + +endif #TARGET_PROVIDES_WCNSS_QMI + +endif #TARGET_USES_QCOM_WCNSS_QMI + +LOCAL_MODULE_TAGS := optional +LOCAL_CFLAGS += -Wall + +include $(BUILD_EXECUTABLE) + +ifneq ($(TARGET_PROVIDES_WCNSS_QMI),true) +ifeq ($(strip $(TARGET_USES_QCOM_WCNSS_QMI)),true) +ifneq ($(QCPATH),) +include $(CLEAR_VARS) + LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/qmi/inc LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/qmi/services LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/qmi/platform LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/qmi/src LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/qmi/core/lib/inc -LOCAL_SRC_FILES += wcnss_qmi_client.c -endif #TARGET_USES_QCOM_WCNSS_QMI + LOCAL_SHARED_LIBRARIES := libc libcutils libutils liblog -ifeq ($(strip $(TARGET_USES_QCOM_WCNSS_QMI)),true) LOCAL_SHARED_LIBRARIES += libqmiservices libqmi libqcci_legacy libqmi_client_qmux -endif #TARGET_USES_QCOM_WCNSS_QMI + +ifneq ($(TARGET_WCNSS_MAC_PREFIX),) + LOCAL_CFLAGS += -DWCNSS_INVALID_MAC_PREFIX=\"$(TARGET_WCNSS_MAC_PREFIX)\" +endif + +LOCAL_CFLAGS += -DWCNSS_QMI +LOCAL_SRC_FILES += wcnss_qmi_client.c + +LOCAL_MODULE := libwcnss_qmi LOCAL_MODULE_TAGS := optional LOCAL_CFLAGS += -Wall -include $(BUILD_EXECUTABLE) -endif + +include $(BUILD_SHARED_LIBRARY) + +endif #QCPATH +endif #TARGET_USES_QCOM_WCNSS_QMI +endif #TARGET_PROVIDES_WCNSS_QMI + +endif #TARGET_ARCH == arm diff --git a/wcnss-service/wcnss_qmi_client.c b/wcnss-service/wcnss_qmi_client.c index a44d439..85a3a63 100644 --- a/wcnss-service/wcnss_qmi_client.c +++ b/wcnss-service/wcnss_qmi_client.c @@ -29,6 +29,8 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifdef WCNSS_QMI #define LOG_TAG "wcnss_qmi" #include <cutils/log.h> +#include <stdlib.h> +#include <sys/stat.h> #include "wcnss_qmi_client.h" #include "qmi.h" #include "qmi_client.h" @@ -62,7 +64,7 @@ static int dms_init_done = FAILED; static char *dms_find_modem_port( char *prop_value_ptr) { - char *qmi_modem_port_ptr = QMI_PORT_RMNET_1; + char *qmi_modem_port_ptr = QMI_PORT_RMNET_0; /* Sanity check */ if (prop_value_ptr == NULL) { @@ -93,7 +95,7 @@ static char *dms_find_modem_port( char *prop_value_ptr) QMI_UIM_PROP_BASEBAND_VALUE_APQ) == 0) || (strcmp(prop_value_ptr, QMI_UIM_PROP_BASEBAND_VALUE_SGLTE) == 0)) { - qmi_modem_port_ptr = QMI_PORT_RMNET_1; + qmi_modem_port_ptr = QMI_PORT_RMNET_0; } else if (strcmp(prop_value_ptr, QMI_UIM_PROP_BASEBAND_VALUE_DSDA) == 0) { /* If it is a DSDA configuration, use the existing API */ @@ -147,6 +149,15 @@ int wcnss_init_qmi() qmi_client_err = qmi_client_init((const char *)qmi_modem_port, dms_service, NULL, dms_service, &dms_qmi_client); + if ((qmi_client_err == QMI_PORT_NOT_OPEN_ERR) && + (strcmp(qmi_modem_port, QMI_PORT_RMNET_0) == 0)){ + ALOGE("%s: Retrying with port RMNET_1: %d", + __func__, qmi_client_err); + qmi_modem_port = QMI_PORT_RMNET_1; + qmi_client_err = qmi_client_init((const char *)qmi_modem_port, + dms_service, NULL, dms_service, &dms_qmi_client); + } + if (qmi_client_err != QMI_NO_ERR){ ALOGE("%s: Error while Initializing QMI Client: %d", __func__, qmi_client_err); @@ -203,8 +214,63 @@ int wcnss_qmi_get_wlan_address(unsigned char *pBdAddr) ALOGE("%s: Succesfully Read WLAN MAC Address", __func__); return SUCCESS; } else { +#ifdef WCNSS_INVALID_MAC_PREFIX +#ifndef WCNSS_GENMAC_FILE +#define WCNSS_GENMAC_FILE "/persist/.genmac" +#endif + int i = 0; + struct stat statbuf; + FILE *genmac; + int macbytes[6] = { 0, }; + // Limit the prefix to 4 bytes, we want at least 2 to be random + int prefixlen = strnlen(WCNSS_INVALID_MAC_PREFIX,8)/2; + + // Misconfigured device source...? + if (prefixlen < 2) { + return FAILED; + } + + // Use a previously stored value if it exists + if (!stat(WCNSS_GENMAC_FILE, &statbuf)) { + genmac = fopen(WCNSS_GENMAC_FILE,"r"); + if (fscanf(genmac, "%c%c%c%c%c%c", &pBdAddr[0], + &pBdAddr[1], &pBdAddr[2], &pBdAddr[3], + &pBdAddr[4], &pBdAddr[5]) == 6) { + fclose(genmac); + ALOGE("%s: Succesfully Read local WLAN MAC Address", __func__); + return SUCCESS; + } + fclose(genmac); + } + + sscanf(WCNSS_INVALID_MAC_PREFIX, "%2x%2x%2x%2x", + &macbytes[0], &macbytes[1], + &macbytes[2], &macbytes[3]); + + // We don't need strong randomness, and if the NV is corrupted + // any hardware values are suspect, so just seed it with the + // current time + srand(time(NULL)); + + for (i = prefixlen; i<6; i++) { + macbytes[i] = rand() % 255; + } + // Invert them + for (i = 0; i < 6; i++) { + pBdAddr[i] = macbytes[5-i]; + } + + // Store for reuse + genmac = fopen(WCNSS_GENMAC_FILE,"w"); + fwrite(pBdAddr, 1, 6, genmac); + fclose(genmac); + + ALOGE("%s: Failed to Read WLAN MAC Address, successfully randomized one", __func__); + return SUCCESS; +#else ALOGE("%s: Failed to Read WLAN MAC Address", __func__); return FAILED; +#endif } } diff --git a/wcnss-service/wcnss_service.c b/wcnss-service/wcnss_service.c index 214b8a5..dc371da 100644 --- a/wcnss-service/wcnss_service.c +++ b/wcnss-service/wcnss_service.c @@ -40,6 +40,9 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifdef WCNSS_QMI #include "wcnss_qmi_client.h" #endif +#ifdef WCNSS_QMI_OSS +#include <dlfcn.h> +#endif #define SUCCESS 0 #define FAILED -1 @@ -69,10 +72,14 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. "/sys/module/wcnsscore/parameters/has_calibrated_data" #define WLAN_DRIVER_ATH_DEFAULT_VAL "0" -#ifdef WCNSS_QMI +#if defined (WCNSS_QMI) || defined(WCNSS_QMI_OSS) #define WLAN_ADDR_SIZE 6 unsigned char wlan_nv_mac_addr[WLAN_ADDR_SIZE]; +#ifdef WCNSS_QMI_MAC_ADDR_REV +#define MAC_ADDR_ARRAY(a) (a)[5], (a)[4], (a)[3], (a)[2], (a)[1], (a)[0] +#else #define MAC_ADDR_ARRAY(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5] +#endif #define MAC_ADDRESS_STR "%02x:%02x:%02x:%02x:%02x:%02x" /* As we Want to write in 00:0a:f5:11:22:33 format in sysfs file @@ -363,18 +370,27 @@ void setup_wcnss_parameters(int *cal, int nv_mac_addr) } } -#ifdef WCNSS_QMI +#if defined(WCNSS_QMI) || defined (WCNSS_QMI_OSS) if (SUCCESS == nv_mac_addr) { pos = 0; msg[pos++] = WCNSS_USR_WLAN_MAC_ADDR >> BYTE_1; msg[pos++] = WCNSS_USR_WLAN_MAC_ADDR >> BYTE_0; +#ifdef WCNSS_QMI_MAC_ADDR_REV + msg[pos++] = wlan_nv_mac_addr[5]; + msg[pos++] = wlan_nv_mac_addr[4]; + msg[pos++] = wlan_nv_mac_addr[3]; + msg[pos++] = wlan_nv_mac_addr[2]; + msg[pos++] = wlan_nv_mac_addr[1]; + msg[pos++] = wlan_nv_mac_addr[0]; +#else msg[pos++] = wlan_nv_mac_addr[0]; msg[pos++] = wlan_nv_mac_addr[1]; msg[pos++] = wlan_nv_mac_addr[2]; msg[pos++] = wlan_nv_mac_addr[3]; msg[pos++] = wlan_nv_mac_addr[4]; msg[pos++] = wlan_nv_mac_addr[5]; +#endif ALOGI("WLAN MAC Addr:" MAC_ADDRESS_STR, MAC_ADDR_ARRAY(wlan_nv_mac_addr)); @@ -435,6 +451,59 @@ void setup_wlan_driver_ath_prop() property_set("wlan.driver.ath", WLAN_DRIVER_ATH_DEFAULT_VAL); } +#ifdef WCNSS_QMI_OSS +static void *wcnss_qmi_handle = NULL; +static int (*wcnss_init_qmi)(void) = NULL; +static int (*wcnss_qmi_get_wlan_address)(unsigned char *) = NULL; +static void (*wcnss_qmi_deinit)(void) = NULL; + +static int setup_wcnss_qmi(void) +{ + const char *error = NULL; + + /* initialize the DMS client and request the wlan mac address */ + wcnss_qmi_handle = dlopen("libwcnss_qmi.so", RTLD_NOW); + if (!wcnss_qmi_handle) { + ALOGE("Failed to open libwcnss_qmi.so: %s", dlerror()); + goto dlopen_err; + } + + dlerror(); + + wcnss_init_qmi = dlsym(wcnss_qmi_handle, "wcnss_init_qmi"); + if ((error = dlerror()) != NULL) { + ALOGE("Failed to resolve function: %s: %s", + "wcnss_init_qmi", error); + goto dlsym_err; + } + + dlerror(); + + wcnss_qmi_get_wlan_address = dlsym(wcnss_qmi_handle, + "wcnss_qmi_get_wlan_address"); + if ((error = dlerror()) != NULL) { + ALOGE("Failed to resolve function: %s: %s", + "wcnss_qmi_get_wlan_address", error); + goto dlsym_err; + } + + dlerror(); + + wcnss_qmi_deinit = dlsym(wcnss_qmi_handle, "wcnss_qmi_deinit"); + if ((error = dlerror()) != NULL) { + ALOGE("Failed to resolve function: %s: %s", + "wcnss_qmi_deinit", error); + goto dlsym_err; + } + + return SUCCESS; + +dlsym_err: + dlclose(wcnss_qmi_handle); +dlopen_err: + return FAILED; +} +#endif int main(int argc, char *argv[]) { @@ -444,6 +513,28 @@ int main(int argc, char *argv[]) setup_wlan_config_file(); +#ifdef WCNSS_QMI_OSS + /* dlopen WCNSS QMI lib */ + + rc = setup_wcnss_qmi(); + if (rc == SUCCESS) { + if (SUCCESS == (*wcnss_init_qmi)()) { + rc = (*wcnss_qmi_get_wlan_address)(wlan_nv_mac_addr); + if (rc == SUCCESS) { + nv_mac_addr = SUCCESS; + ALOGE("WLAN MAC Addr:" MAC_ADDRESS_STR, + MAC_ADDR_ARRAY(wlan_nv_mac_addr)); + } else + ALOGE("Failed to Get MAC addr from modem"); + + (*wcnss_qmi_deinit)(); + } + else + ALOGE("Failed to Initialize wcnss QMI Interface"); + } else { + ALOGE("Failed to Initialize wcnss QMI interface library"); + } +#endif #ifdef WCNSS_QMI /* initialize the DMS client and request the wlan mac address */ @@ -491,5 +582,9 @@ int main(int argc, char *argv[]) close(fd_dev); +#ifdef WCNSS_QMI_OSS + dlclose(wcnss_qmi_handle); +#endif + return rc; } |