summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--qcwcn/wifi_hal/nan.h30
-rw-r--r--qcwcn/wifi_hal/nan_i.h26
-rw-r--r--qcwcn/wifi_hal/nan_ind.cpp54
-rw-r--r--qcwcn/wifi_hal/nan_req.cpp68
-rw-r--r--qcwcn/wifi_hal/nancommand.h2
-rw-r--r--qcwcn/wifi_hal/wifi_hal.cpp14
-rw-r--r--qcwcn/wpa_supplicant_8_lib/driver_cmd_nl80211.c13
-rw-r--r--wcnss-service/Android.mk59
-rw-r--r--wcnss-service/wcnss_qmi_client.c70
-rw-r--r--wcnss-service/wcnss_service.c99
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;
}