summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2017-12-07 10:51:09 -0800
committerLinux Build Service Account <lnxbuild@localhost>2017-12-07 10:51:09 -0800
commitada199d329c118b195526a486893eb788da3a1ed (patch)
treee1259c3a2693a6ea6a7dcbb9f0e1ed75495c4447
parent5f1192cf8e1e39e83201adbd0b8ceb127b3c90aa (diff)
parent78239a5e694d23182697282937f7422ac54eeb98 (diff)
downloadandroid_hardware_qcom_wlan-ada199d329c118b195526a486893eb788da3a1ed.tar.gz
android_hardware_qcom_wlan-ada199d329c118b195526a486893eb788da3a1ed.tar.bz2
android_hardware_qcom_wlan-ada199d329c118b195526a486893eb788da3a1ed.zip
Merge 78239a5e694d23182697282937f7422ac54eeb98 on remote branch
Change-Id: Ib5d1eca65d4f01ebea6ba373cc7bd04acaaddd21
-rw-r--r--cld80211-lib/cld80211_lib.h5
-rw-r--r--qcwcn/Android.mk6
-rw-r--r--qcwcn/wifi_hal/Android.mk6
-rw-r--r--qcwcn/wifi_hal/cpp_bindings.cpp5
-rw-r--r--qcwcn/wifi_hal/cpp_bindings.h11
-rw-r--r--qcwcn/wifi_hal/gscan.cpp2
-rw-r--r--qcwcn/wifi_hal/llstats.cpp13
-rw-r--r--qcwcn/wifi_hal/nan.cpp100
-rw-r--r--qcwcn/wifi_hal/nan_cert.h13
-rw-r--r--qcwcn/wifi_hal/nan_i.h32
-rw-r--r--qcwcn/wifi_hal/nan_ind.cpp75
-rw-r--r--qcwcn/wifi_hal/nan_req.cpp121
-rw-r--r--qcwcn/wifi_hal/nan_rsp.cpp17
-rw-r--r--qcwcn/wifi_hal/nancommand.h1
-rw-r--r--qcwcn/wifi_hal/nud_stats.h65
-rw-r--r--qcwcn/wifi_hal/rssi_monitor.cpp2
-rw-r--r--qcwcn/wifi_hal/wifi_hal.cpp12
-rw-r--r--qcwcn/wifi_hal/wifihal_vendor.cpp380
-rw-r--r--qcwcn/wifi_hal/wifihal_vendorcommand.h70
-rw-r--r--qcwcn/wifi_hal/wifilogger.cpp4
-rw-r--r--qcwcn/wifi_hal/wifilogger_diag.cpp3
-rw-r--r--wcnss-service/Android.mk7
-rw-r--r--wcnss-service/wcnss_qmi_client.c121
23 files changed, 838 insertions, 233 deletions
diff --git a/cld80211-lib/cld80211_lib.h b/cld80211-lib/cld80211_lib.h
index 16b3f20..3dd53bb 100644
--- a/cld80211-lib/cld80211_lib.h
+++ b/cld80211-lib/cld80211_lib.h
@@ -55,11 +55,16 @@ struct cld80211_ctx {
* CLD80211_ATTR_VENDOR_DATA: Embed all other attributes in this nested
* attribute.
* CLD80211_ATTR_DATA: Embed driver/application data in this attribute
+ * CLD80211_ATTR_META_DATA: Embed meta data for above data. This will help
+ * wlan driver to peek into request message packet without opening up definition
+ * of complete request message.
+ *
* Any new message in future can be added as another attribute
*/
enum cld80211_attr {
CLD80211_ATTR_VENDOR_DATA = 1,
CLD80211_ATTR_DATA,
+ CLD80211_ATTR_META_DATA,
__CLD80211_ATTR_AFTER_LAST,
CLD80211_ATTR_MAX = __CLD80211_ATTR_AFTER_LAST - 1
diff --git a/qcwcn/Android.mk b/qcwcn/Android.mk
index d7e0509..7f20af1 100644
--- a/qcwcn/Android.mk
+++ b/qcwcn/Android.mk
@@ -1,5 +1,3 @@
-ifneq ($(TARGET_BOARD_AUTO),true)
- ifeq ($(BOARD_WLAN_DEVICE),qcwcn)
- include $(call all-subdir-makefiles)
- endif
+ifeq ($(BOARD_WLAN_DEVICE),qcwcn)
+ include $(call all-subdir-makefiles)
endif
diff --git a/qcwcn/wifi_hal/Android.mk b/qcwcn/wifi_hal/Android.mk
index 10a5d42..77dcd7f 100644
--- a/qcwcn/wifi_hal/Android.mk
+++ b/qcwcn/wifi_hal/Android.mk
@@ -55,7 +55,8 @@ LOCAL_SRC_FILES := \
ring_buffer.cpp \
rb_wrapper.cpp \
rssi_monitor.cpp \
- roam.cpp
+ roam.cpp \
+ wifihal_vendor.cpp
LOCAL_MODULE := libwifi-hal-qcom
LOCAL_CLANG := true
@@ -113,7 +114,8 @@ LOCAL_SRC_FILES := \
ring_buffer.cpp \
rb_wrapper.cpp \
rssi_monitor.cpp \
- roam.cpp
+ roam.cpp \
+ wifihal_vendor.cpp
LOCAL_MODULE := libwifi-hal-qcom
LOCAL_PROPRIETARY_MODULE := true
diff --git a/qcwcn/wifi_hal/cpp_bindings.cpp b/qcwcn/wifi_hal/cpp_bindings.cpp
index c0aae67..cbb865a 100644
--- a/qcwcn/wifi_hal/cpp_bindings.cpp
+++ b/qcwcn/wifi_hal/cpp_bindings.cpp
@@ -879,6 +879,11 @@ wifi_error WifiVendorCommand::put_s64(int attribute, s64 value)
return mMsg.put_s64(attribute, value);
}
+wifi_error WifiVendorCommand::put_flag(int attribute)
+{
+ return mMsg.put_flag(attribute);
+}
+
u8 WifiVendorCommand::get_u8(const struct nlattr *nla)
{
return mMsg.get_u8(nla);
diff --git a/qcwcn/wifi_hal/cpp_bindings.h b/qcwcn/wifi_hal/cpp_bindings.h
index 1c68a36..42705c3 100644
--- a/qcwcn/wifi_hal/cpp_bindings.h
+++ b/qcwcn/wifi_hal/cpp_bindings.h
@@ -230,6 +230,15 @@ public:
wifi_error put_s64(int attribute, s64 value) {
return wifi_nla_put(mMsg, attribute, sizeof(int64_t), &value);
}
+ wifi_error put_flag(int attribute) {
+ int status;
+
+ status = nla_put_flag(mMsg, attribute);
+ if(status < 0)
+ ALOGE("Failed to put flag attr of type = %d, error = %d",
+ attribute, status);
+ return mapKernelErrortoWifiHalError(status);
+ }
u8 get_u8(const struct nlattr *nla)
{
@@ -438,6 +447,8 @@ public:
virtual wifi_error put_s64(int attribute, s64 value);
+ wifi_error put_flag(int attribute);
+
virtual u8 get_u8(const struct nlattr *nla);
virtual u16 get_u16(const struct nlattr *nla);
virtual u32 get_u32(const struct nlattr *nla);
diff --git a/qcwcn/wifi_hal/gscan.cpp b/qcwcn/wifi_hal/gscan.cpp
index 600b49c..7a5aae0 100644
--- a/qcwcn/wifi_hal/gscan.cpp
+++ b/qcwcn/wifi_hal/gscan.cpp
@@ -82,6 +82,8 @@ wifi_error cleanupGscanHandlers(hal_info *info)
delete event_handlers->gScanPnoSetPasspointListCmdEventHandler;
}
memset(event_handlers, 0, sizeof(gscan_event_handlers));
+ free(info->gscan_handlers);
+ info->gscan_handlers = NULL;
return WIFI_SUCCESS;
}
ALOGE ("%s: info or info->gscan_handlers NULL", __FUNCTION__);
diff --git a/qcwcn/wifi_hal/llstats.cpp b/qcwcn/wifi_hal/llstats.cpp
index 4013e01..23e5e7b 100644
--- a/qcwcn/wifi_hal/llstats.cpp
+++ b/qcwcn/wifi_hal/llstats.cpp
@@ -877,10 +877,15 @@ void LLStatsCommand::clearStats()
{
if(mResultsParams.radio_stat)
{
- if (mResultsParams.radio_stat->tx_time_per_levels)
- {
- free(mResultsParams.radio_stat->tx_time_per_levels);
- mResultsParams.radio_stat->tx_time_per_levels = NULL;
+ wifi_radio_stat *radioStat = mResultsParams.radio_stat;
+ for (u8 radio = 0; radio < mNumRadios; radio++) {
+ if (radioStat->tx_time_per_levels) {
+ free(radioStat->tx_time_per_levels);
+ radioStat->tx_time_per_levels = NULL;
+ }
+ radioStat = (wifi_radio_stat *)((u8 *)radioStat +
+ sizeof(wifi_radio_stat) + (sizeof(wifi_channel_stat) *
+ radioStat->num_channels));
}
free(mResultsParams.radio_stat);
mResultsParams.radio_stat = NULL;
diff --git a/qcwcn/wifi_hal/nan.cpp b/qcwcn/wifi_hal/nan.cpp
index 0fd7e5e..9ac00fe 100644
--- a/qcwcn/wifi_hal/nan.cpp
+++ b/qcwcn/wifi_hal/nan.cpp
@@ -614,6 +614,12 @@ wifi_error nan_debug_command_config(transaction_id id,
interface_info *ifaceInfo = getIfaceInfo(iface);
wifi_handle wifiHandle = getWifiHandle(iface);
+ if (debug_msg_length <= 0) {
+ ALOGE("%s: Invalid debug message length = %d", __FUNCTION__,
+ debug_msg_length);
+ return WIFI_ERROR_UNKNOWN;
+ }
+
nanCommand = new NanCommand(wifiHandle,
0,
OUI_QCA,
@@ -623,12 +629,6 @@ wifi_error nan_debug_command_config(transaction_id id,
return WIFI_ERROR_UNKNOWN;
}
- if (debug_msg_length <= 0) {
- ALOGE("%s: Invalid debug message length = %d", __FUNCTION__,
- debug_msg_length);
- return WIFI_ERROR_UNKNOWN;
- }
-
ret = nanCommand->create();
if (ret != WIFI_SUCCESS)
goto cleanup;
@@ -887,30 +887,27 @@ wifi_error nan_data_request_initiator(transaction_id id,
if (nanCommand->put_u32(QCA_WLAN_VENDOR_ATTR_NDP_CSID,
msg->cipher_type))
goto cleanup;
-
- if ( msg->key_info.key_type == NAN_SECURITY_KEY_INPUT_PMK &&
- msg->key_info.body.pmk_info.pmk_len == NAN_PMK_INFO_LEN) {
- if (nanCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_NDP_PMK,
- (char *)msg->key_info.body.pmk_info.pmk,
- msg->key_info.body.pmk_info.pmk_len))
- goto cleanup;
- } else if (msg->key_info.key_type ==
- NAN_SECURITY_KEY_INPUT_PASSPHRASE &&
- msg->key_info.body.passphrase_info.passphrase_len >=
- NAN_SECURITY_MIN_PASSPHRASE_LEN &&
- msg->key_info.body.passphrase_info.passphrase_len <=
- NAN_SECURITY_MAX_PASSPHRASE_LEN) {
- if (nanCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_NDP_PASSPHRASE,
- (char *)msg->key_info.body.passphrase_info.passphrase,
- msg->key_info.body.passphrase_info.passphrase_len))
- goto cleanup;
- }
-
- if (msg->service_name_len) {
- if (nanCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_NAME,
- (char *)msg->service_name, msg->service_name_len))
- goto cleanup;
- }
+ }
+ if ( msg->key_info.key_type == NAN_SECURITY_KEY_INPUT_PMK &&
+ msg->key_info.body.pmk_info.pmk_len == NAN_PMK_INFO_LEN) {
+ if (nanCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_NDP_PMK,
+ (char *)msg->key_info.body.pmk_info.pmk,
+ msg->key_info.body.pmk_info.pmk_len))
+ goto cleanup;
+ } else if (msg->key_info.key_type == NAN_SECURITY_KEY_INPUT_PASSPHRASE &&
+ msg->key_info.body.passphrase_info.passphrase_len >=
+ NAN_SECURITY_MIN_PASSPHRASE_LEN &&
+ msg->key_info.body.passphrase_info.passphrase_len <=
+ NAN_SECURITY_MAX_PASSPHRASE_LEN) {
+ if (nanCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_NDP_PASSPHRASE,
+ (char *)msg->key_info.body.passphrase_info.passphrase,
+ msg->key_info.body.passphrase_info.passphrase_len))
+ goto cleanup;
+ }
+ if (msg->service_name_len) {
+ if (nanCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_NAME,
+ (char *)msg->service_name, msg->service_name_len))
+ goto cleanup;
}
nanCommand->attr_end(nlData);
@@ -1006,29 +1003,28 @@ wifi_error nan_data_indication_response(transaction_id id,
if (nanCommand->put_u32(QCA_WLAN_VENDOR_ATTR_NDP_CSID,
msg->cipher_type))
goto cleanup;
+ }
+ if ( msg->key_info.key_type == NAN_SECURITY_KEY_INPUT_PMK &&
+ msg->key_info.body.pmk_info.pmk_len == NAN_PMK_INFO_LEN) {
+ if (nanCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_NDP_PMK,
+ (char *)msg->key_info.body.pmk_info.pmk,
+ msg->key_info.body.pmk_info.pmk_len))
+ goto cleanup;
+ } else if (msg->key_info.key_type == NAN_SECURITY_KEY_INPUT_PASSPHRASE &&
+ msg->key_info.body.passphrase_info.passphrase_len >=
+ NAN_SECURITY_MIN_PASSPHRASE_LEN &&
+ msg->key_info.body.passphrase_info.passphrase_len <=
+ NAN_SECURITY_MAX_PASSPHRASE_LEN) {
+ if (nanCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_NDP_PASSPHRASE,
+ (char *)msg->key_info.body.passphrase_info.passphrase,
+ msg->key_info.body.passphrase_info.passphrase_len))
+ goto cleanup;
+ }
- if ( msg->key_info.key_type == NAN_SECURITY_KEY_INPUT_PMK &&
- msg->key_info.body.pmk_info.pmk_len == NAN_PMK_INFO_LEN) {
- if (nanCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_NDP_PMK,
- (char *)msg->key_info.body.pmk_info.pmk,
- msg->key_info.body.pmk_info.pmk_len))
- goto cleanup;
- } else if (msg->key_info.key_type == NAN_SECURITY_KEY_INPUT_PASSPHRASE &&
- msg->key_info.body.passphrase_info.passphrase_len >=
- NAN_SECURITY_MIN_PASSPHRASE_LEN &&
- msg->key_info.body.passphrase_info.passphrase_len <=
- NAN_SECURITY_MAX_PASSPHRASE_LEN) {
- if (nanCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_NDP_PASSPHRASE,
- (char *)msg->key_info.body.passphrase_info.passphrase,
- msg->key_info.body.passphrase_info.passphrase_len))
- goto cleanup;
- }
-
- if (msg->service_name_len) {
- if (nanCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_NAME,
- (char *)msg->service_name, msg->service_name_len))
- goto cleanup;
- }
+ if (msg->service_name_len) {
+ if (nanCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_NAME,
+ (char *)msg->service_name, msg->service_name_len))
+ goto cleanup;
}
nanCommand->attr_end(nlData);
diff --git a/qcwcn/wifi_hal/nan_cert.h b/qcwcn/wifi_hal/nan_cert.h
index d84b806..040471a 100644
--- a/qcwcn/wifi_hal/nan_cert.h
+++ b/qcwcn/wifi_hal/nan_cert.h
@@ -36,8 +36,9 @@ extern "C"
{
#endif /* __cplusplus */
-#define NAN_CERT_VERSION 2
+#define NAN_CERT_VERSION 4
#define NAN_MAX_DEBUG_MESSAGE_DATA_LEN 100
+#define NAN_MAX_ALLOWED_DW_AWAKE_INTERVAL 16
typedef struct {
/* NAN master rank being advertised by DE */
@@ -90,6 +91,12 @@ typedef enum {
NAN_SCHED_INVALID_BAD_IMMU = 3
} NanSchedType;
+/* NAN device type */
+typedef enum {
+ NAN_DEVICE_TYPE_TEST_BED = 1,
+ NAN_DEVICE_TYPE_DUT = 2
+} NanDeviceType;
+
/*
* Definitions of debug subcommand type for the
* generic debug command.
@@ -106,7 +113,9 @@ typedef enum {
NAN_TEST_MODE_CMD_NAN_SCHED_UPDATE_ULW_NOTIFY = 9,
NAN_TEST_MODE_CMD_NAN_SCHED_UPDATE_NDL_NEGOTIATE = 10,
NAN_TEST_MODE_CMD_NAN_SCHED_UPDATE_NDL_NOTIFY = 11,
- NAN_TEST_MODE_CMD_NAN_AVAILABILITY_MAP_ORDER = 12
+ NAN_TEST_MODE_CMD_NAN_AVAILABILITY_MAP_ORDER = 12,
+ NAN_TEST_MODE_CMD_CONFIG_QOS = 13,
+ NAN_TEST_MODE_CMD_DEVICE_TYPE = 14
} NanDebugModeCmd;
/*
diff --git a/qcwcn/wifi_hal/nan_i.h b/qcwcn/wifi_hal/nan_i.h
index 7202751..08ebb4b 100644
--- a/qcwcn/wifi_hal/nan_i.h
+++ b/qcwcn/wifi_hal/nan_i.h
@@ -211,6 +211,7 @@ typedef enum
NAN_TLV_TYPE_5G_CHANNEL,
NAN_TLV_TYPE_DISC_MAC_ADDR_RANDOM_INTERVAL,
NAN_TLV_TYPE_RANGING_AUTO_RESPONSE_CFG = 4134,
+ NAN_TLV_TYPE_SUBSCRIBE_SID_BEACON = 4135,
NAN_TLV_TYPE_CONFIG_LAST = 8191,
/* Attributes types */
@@ -347,7 +348,7 @@ typedef struct PACKED
{
u16 ttl;
u16 period;
- u32 reserved:1;
+ u32 replyIndFlag:1;
u32 publishType:2;
u32 txType:1;
u32 rssiThresholdFlag:1;
@@ -407,6 +408,27 @@ typedef struct PACKED
u16 reserved;
} NanPublishTerminatedIndMsg, *pNanPublishTerminatedIndMsg;
+/* Params for NAN Publish Replied Ind */
+typedef struct PACKED
+{
+ u32 matchHandle;
+} NanPublishRepliedIndParams;
+
+/* NAN Publish Replied Ind */
+typedef struct PACKED
+{
+ NanMsgHeader fwHeader;
+ NanPublishRepliedIndParams publishRepliedIndParams;
+ /*
+ * Excludes TLVs
+ *
+ * Required: MAC Address
+ * Optional: Received RSSI Value
+ *
+ */
+ u8 ptlv[];
+} NanPublishRepliedIndMsg, *pNanPublishRepliedIndMsg;
+
/* NAN Subscribe Service Req */
typedef struct PACKED
{
@@ -940,6 +962,8 @@ typedef struct PACKED
u32 discBeaconTxFailures;
u32 amHopCountExpireCount;
u32 ndpChannelFreq;
+ u32 ndpChannelFreq2;
+ u32 schedUpdateChannelFreq;
} FwNanSyncStats, *pFwNanSyncStats;
/* NAN Misc DE Statistics */
@@ -974,6 +998,7 @@ typedef struct PACKED
Definition of various NanIndication(events)
*/
typedef enum {
+ NAN_INDICATION_PUBLISH_REPLIED =0,
NAN_INDICATION_PUBLISH_TERMINATED =1,
NAN_INDICATION_MATCH =2,
NAN_INDICATION_MATCH_EXPIRED =3,
@@ -1049,8 +1074,10 @@ typedef struct PACKED
u32 security_required:1;
u32 ranging_required:1;
u32 range_limit_present:1;
+ u32 service_update_ind_present:1;
+ u32 reserved1:6;
u32 range_report:1;
- u32 reserved:22;
+ u32 reserved2:15;
} NanFWSdeaCtrlParams;
/* NAN Ranging Configuration params */
@@ -1166,6 +1193,7 @@ typedef enum {
NDP_I_MGMT_FRAME_CONFIRM_FAILED = 9011,
NDP_I_END_FAILED = 9012,
NDP_I_MGMT_FRAME_END_REQUEST_FAILED = 9013,
+ NDP_I_MGMT_FRAME_SECURITY_INSTALL_FAILED = 9014,
/* 9500 onwards vendor specific error codes */
NDP_I_VENDOR_SPECIFIC_ERROR = 9500
diff --git a/qcwcn/wifi_hal/nan_ind.cpp b/qcwcn/wifi_hal/nan_ind.cpp
index 5f12177..2477523 100644
--- a/qcwcn/wifi_hal/nan_ind.cpp
+++ b/qcwcn/wifi_hal/nan_ind.cpp
@@ -35,6 +35,15 @@ int NanCommand::handleNanIndication()
ALOGV("handleNanIndication msg_id:%u", msg_id);
switch (msg_id) {
+ case NAN_INDICATION_PUBLISH_REPLIED:
+ NanPublishRepliedInd publishRepliedInd;
+ memset(&publishRepliedInd, 0, sizeof(publishRepliedInd));
+ res = getNanPublishReplied(&publishRepliedInd);
+ if (!res && mHandler.EventPublishReplied) {
+ (*mHandler.EventPublishReplied)(&publishRepliedInd);
+ }
+ break;
+
case NAN_INDICATION_PUBLISH_TERMINATED:
NanPublishTerminatedInd publishTerminatedInd;
memset(&publishTerminatedInd, 0, sizeof(publishTerminatedInd));
@@ -165,7 +174,7 @@ NanIndicationType NanCommand::getIndicationType()
switch (pHeader->msgId) {
case NAN_MSG_ID_PUBLISH_REPLIED_IND:
- return NAN_INDICATION_UNKNOWN;
+ return NAN_INDICATION_PUBLISH_REPLIED;
case NAN_MSG_ID_PUBLISH_TERMINATED_IND:
return NAN_INDICATION_PUBLISH_TERMINATED;
case NAN_MSG_ID_MATCH_IND:
@@ -195,6 +204,55 @@ NanIndicationType NanCommand::getIndicationType()
}
}
+int NanCommand::getNanPublishReplied(NanPublishRepliedInd *event)
+{
+ if (event == NULL || mNanVendorEvent == NULL) {
+ ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p",
+ __func__, event, mNanVendorEvent);
+ return WIFI_ERROR_INVALID_ARGS;
+ }
+
+ pNanPublishRepliedIndMsg pRsp = (pNanPublishRepliedIndMsg)mNanVendorEvent;
+ event->requestor_instance_id = pRsp->publishRepliedIndParams.matchHandle;
+
+ event->rssi_value = 0;
+ u8 *pInputTlv = pRsp->ptlv;
+ NanTlv outputTlv;
+ u16 readLen = 0;
+ int remainingLen = (mNanDataLen - \
+ (sizeof(NanMsgHeader)));
+
+ if (remainingLen <= 0) {
+ ALOGI("%s: No TLV's present",__func__);
+ return WIFI_SUCCESS;
+ }
+ while ((remainingLen > 0) &&
+ (0 != (readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv)))) {
+ switch (outputTlv.type) {
+ case NAN_TLV_TYPE_MAC_ADDRESS:
+ if (outputTlv.length > sizeof(event->addr)) {
+ outputTlv.length = sizeof(event->addr);
+ }
+ memcpy(event->addr, outputTlv.value, outputTlv.length);
+ break;
+ case NAN_TLV_TYPE_RECEIVED_RSSI_VALUE:
+ if (outputTlv.length > sizeof(event->rssi_value)) {
+ outputTlv.length = sizeof(event->rssi_value);
+ }
+ memcpy(&event->rssi_value, outputTlv.value,
+ outputTlv.length);
+ break;
+ default:
+ ALOGI("Unknown TLV type skipped");
+ break;
+ }
+ remainingLen -= readLen;
+ pInputTlv += readLen;
+ memset(&outputTlv, 0, sizeof(outputTlv));
+ }
+ return WIFI_SUCCESS;
+}
+
int NanCommand::getNanPublishTerminated(NanPublishTerminatedInd *event)
{
if (event == NULL || mNanVendorEvent == NULL) {
@@ -1010,6 +1068,7 @@ int NanCommand::getNdpConfirm(struct nlattr **tb_vendor,
NanDataPathConfirmInd *event)
{
u32 len = 0;
+ NanInternalStatusType drv_reason_code;
if (event == NULL || tb_vendor == NULL) {
ALOGE("%s: Invalid input argument event:%p tb_vendor:%p",
@@ -1041,6 +1100,20 @@ int NanCommand::getNdpConfirm(struct nlattr **tb_vendor,
} else {
ALOGD("%s: NDP App Info not present", __FUNCTION__);
}
+ drv_reason_code = (NanInternalStatusType)nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE]);
+ ALOGD("%s: Drv reason code %d", __FUNCTION__, drv_reason_code);
+ switch (drv_reason_code) {
+ case NDP_I_MGMT_FRAME_REQUEST_FAILED:
+ case NDP_I_MGMT_FRAME_RESPONSE_FAILED:
+ case NDP_I_MGMT_FRAME_CONFIRM_FAILED:
+ case NDP_I_MGMT_FRAME_SECURITY_INSTALL_FAILED:
+ event->reason_code = NAN_STATUS_PROTOCOL_FAILURE;
+ break;
+ default:
+ event->reason_code = (NanStatusType)drv_reason_code;
+ break;
+ }
+ ALOGD("%s: Reason code %d", __FUNCTION__, event->reason_code);
return WIFI_SUCCESS;
}
diff --git a/qcwcn/wifi_hal/nan_req.cpp b/qcwcn/wifi_hal/nan_req.cpp
index f83a48a..d64c26d 100644
--- a/qcwcn/wifi_hal/nan_req.cpp
+++ b/qcwcn/wifi_hal/nan_req.cpp
@@ -105,8 +105,8 @@ wifi_error NanCommand::putNanEnable(transaction_id id, const NanEnableRequest *p
sizeof(pReq->config_cluster_attribute_val)) : 0 \
) + \
(
- pReq->config_scan_params ? (SIZEOF_TLV_HDR + \
- NAN_MAX_SOCIAL_CHANNELS * sizeof(u32)) : 0 \
+ pReq->config_scan_params ? NAN_MAX_SOCIAL_CHANNELS *
+ (SIZEOF_TLV_HDR + sizeof(u32)) : 0 \
) + \
(
pReq->config_random_factor_force ? (SIZEOF_TLV_HDR + \
@@ -137,7 +137,15 @@ wifi_error NanCommand::putNanEnable(transaction_id id, const NanEnableRequest *p
sizeof(u32)) : 0 \
) + \
(
- pReq->discovery_indication_cfg ? (SIZEOF_TLV_HDR + \
+ /* Always include cfg discovery indication TLV */
+ SIZEOF_TLV_HDR + sizeof(u32) \
+ ) + \
+ (
+ pReq->config_subscribe_sid_beacon ? (SIZEOF_TLV_HDR + \
+ sizeof(pReq->subscribe_sid_beacon_val)) : 0 \
+ ) + \
+ (
+ pReq->config_discovery_beacon_int ? (SIZEOF_TLV_HDR + \
sizeof(u32)) : 0 \
);
pNanEnableReqMsg pFwReq = (pNanEnableReqMsg)malloc(message_len);
@@ -288,18 +296,21 @@ wifi_error NanCommand::putNanEnable(transaction_id id, const NanEnableRequest *p
sizeof(u32),
(const u8*)&pReq->disc_mac_addr_rand_interval_sec, tlvs);
}
- if (pReq->discovery_indication_cfg) {
- NanConfigDiscoveryIndications discovery_indications;
- discovery_indications.disableDiscoveryMacAddressEvent =
- (pReq->discovery_indication_cfg & BIT_0) ? 1 : 0;
- discovery_indications.disableDiscoveryStartedClusterEvent =
- (pReq->discovery_indication_cfg & BIT_1) ? 1 : 0;
- discovery_indications.disableDiscoveryJoinedClusterEvent =
- (pReq->discovery_indication_cfg & BIT_2) ? 1 : 0;
- tlvs = addTlv(NAN_TLV_TYPE_CONFIG_DISCOVERY_INDICATIONS,
- sizeof(u32),
- (const u8*)&discovery_indications, tlvs);
+ u32 config_discovery_indications;
+ config_discovery_indications = (u32)pReq->discovery_indication_cfg;
+ tlvs = addTlv(NAN_TLV_TYPE_CONFIG_DISCOVERY_INDICATIONS,
+ sizeof(u32),
+ (const u8*)&config_discovery_indications, tlvs);
+
+ if (pReq->config_subscribe_sid_beacon) {
+ tlvs = addTlv(NAN_TLV_TYPE_SUBSCRIBE_SID_BEACON,
+ sizeof(pReq->subscribe_sid_beacon_val),
+ (const u8*)&pReq->subscribe_sid_beacon_val, tlvs);
+ }
+ if (pReq->config_discovery_beacon_int) {
+ tlvs = addTlv(NAN_TLV_TYPE_DB_INTERVAL, sizeof(u32),
+ (const u8*)&pReq->discovery_beacon_interval, tlvs);
}
mVendorData = (char*)pFwReq;
@@ -352,7 +363,7 @@ wifi_error NanCommand::putNanConfig(transaction_id id, const NanConfigRequest *p
{
wifi_error ret;
ALOGV("NAN_CONFIG");
- size_t message_len = NAN_MAX_CONFIGURATION_REQ_SIZE;
+ size_t message_len = 0;
int idx = 0;
if (pReq == NULL ||
@@ -389,8 +400,8 @@ wifi_error NanCommand::putNanConfig(transaction_id id, const NanConfigRequest *p
sizeof(pReq->config_cluster_attribute_val)) : 0 \
) + \
(
- pReq->config_scan_params ? (SIZEOF_TLV_HDR + \
- NAN_MAX_SOCIAL_CHANNELS * sizeof(u32)) : 0 \
+ pReq->config_scan_params ? NAN_MAX_SOCIAL_CHANNELS *
+ (SIZEOF_TLV_HDR + sizeof(u32)) : 0 \
) + \
(
pReq->config_random_factor_force ? (SIZEOF_TLV_HDR + \
@@ -417,7 +428,15 @@ wifi_error NanCommand::putNanConfig(transaction_id id, const NanConfigRequest *p
sizeof(u32)) : 0 \
) + \
(
- pReq->discovery_indication_cfg ? (SIZEOF_TLV_HDR + \
+ pReq->config_subscribe_sid_beacon ? (SIZEOF_TLV_HDR + \
+ sizeof(pReq->subscribe_sid_beacon_val)) : 0 \
+ ) + \
+ (
+ /* Always include cfg discovery indication TLV */
+ SIZEOF_TLV_HDR + sizeof(u32) \
+ ) + \
+ (
+ pReq->config_discovery_beacon_int ? (SIZEOF_TLV_HDR + \
sizeof(u32)) : 0 \
);
@@ -456,7 +475,6 @@ wifi_error NanCommand::putNanConfig(transaction_id id, const NanConfigRequest *p
tlvs = addTlv(NAN_TLV_TYPE_MASTER_PREFERENCE, sizeof(pReq->master_pref),
(const u8*)&pReq->master_pref, tlvs);
}
-
if (pReq->config_rssi_window_size) {
tlvs = addTlv(NAN_TLV_TYPE_RSSI_AVERAGING_WINDOW_SIZE, sizeof(pReq->rssi_window_size_val),
(const u8*)&pReq->rssi_window_size_val, tlvs);
@@ -465,6 +483,15 @@ wifi_error NanCommand::putNanConfig(transaction_id id, const NanConfigRequest *p
tlvs = addTlv(NAN_TLV_TYPE_24G_RSSI_CLOSE_PROXIMITY, sizeof(pReq->rssi_proximity),
(const u8*)&pReq->rssi_proximity, tlvs);
}
+ if (pReq->config_5g_rssi_close_proximity) {
+ tlvs = addTlv(NAN_TLV_TYPE_5G_RSSI_CLOSE_PROXIMITY,
+ sizeof(pReq->rssi_close_proximity_5g_val),
+ (const u8*)&pReq->rssi_close_proximity_5g_val, tlvs);
+ }
+ if (pReq->config_cluster_attribute_val) {
+ tlvs = addTlv(NAN_TLV_TYPE_CLUSTER_ATTRIBUTE_IN_SDF, sizeof(pReq->config_cluster_attribute_val),
+ (const u8*)&pReq->config_cluster_attribute_val, tlvs);
+ }
if (pReq->config_scan_params) {
u32 socialChannelParamVal[NAN_MAX_SOCIAL_CHANNELS];
/* Fill the social channel param */
@@ -511,7 +538,6 @@ wifi_error NanCommand::putNanConfig(transaction_id id, const NanConfigRequest *p
calcNanFurtherAvailabilityMapSize(&pReq->fam_val),
(const u8*)(tlvs + SIZEOF_TLV_HDR), tlvs);
}
-
if (pReq->config_dw.config_2dot4g_dw_band) {
tlvs = addTlv(NAN_TLV_TYPE_2G_COMMITTED_DW,
sizeof(pReq->config_dw.dw_2dot4g_interval_val),
@@ -527,20 +553,22 @@ wifi_error NanCommand::putNanConfig(transaction_id id, const NanConfigRequest *p
sizeof(u32),
(const u8*)&pReq->disc_mac_addr_rand_interval_sec, tlvs);
}
-
- if (pReq->discovery_indication_cfg) {
- NanConfigDiscoveryIndications discovery_indications;
- discovery_indications.disableDiscoveryMacAddressEvent =
- (pReq->discovery_indication_cfg & BIT_0) ? 1 : 0;
- discovery_indications.disableDiscoveryStartedClusterEvent =
- (pReq->discovery_indication_cfg & BIT_1) ? 1 : 0;
- discovery_indications.disableDiscoveryJoinedClusterEvent =
- (pReq->discovery_indication_cfg & BIT_2) ? 1 : 0;
-
- tlvs = addTlv(NAN_TLV_TYPE_CONFIG_DISCOVERY_INDICATIONS,
- sizeof(u32),
- (const u8*)&discovery_indications, tlvs);
+ if (pReq->config_subscribe_sid_beacon) {
+ tlvs = addTlv(NAN_TLV_TYPE_SUBSCRIBE_SID_BEACON,
+ sizeof(pReq->subscribe_sid_beacon_val),
+ (const u8*)&pReq->subscribe_sid_beacon_val, tlvs);
}
+ if (pReq->config_discovery_beacon_int) {
+ tlvs = addTlv(NAN_TLV_TYPE_DB_INTERVAL, sizeof(u32),
+ (const u8*)&pReq->discovery_beacon_interval, tlvs);
+ }
+
+ u32 config_discovery_indications;
+ config_discovery_indications = (u32)(pReq->discovery_indication_cfg);
+ /* Always include the discovery cfg TLV as there is no cfg flag */
+ tlvs = addTlv(NAN_TLV_TYPE_CONFIG_DISCOVERY_INDICATIONS,
+ sizeof(u32),
+ (const u8*)&config_discovery_indications, tlvs);
mVendorData = (char*)pFwReq;
mDataLen = message_len;
@@ -573,7 +601,8 @@ wifi_error NanCommand::putNanPublish(transaction_id id, const NanPublishRequest
(SIZEOF_TLV_HDR + sizeof(NanServiceAcceptPolicy)) +
(pReq->cipher_type ? SIZEOF_TLV_HDR + sizeof(NanCsidType) : 0) +
((pReq->sdea_params.config_nan_data_path || pReq->sdea_params.security_cfg ||
- pReq->sdea_params.ranging_state || pReq->sdea_params.range_report) ?
+ pReq->sdea_params.ranging_state || pReq->sdea_params.range_report ||
+ pReq->sdea_params.qos_cfg) ?
SIZEOF_TLV_HDR + sizeof(NanFWSdeaCtrlParams) : 0) +
((pReq->ranging_cfg.ranging_interval_msec || pReq->ranging_cfg.config_ranging_indications ||
pReq->ranging_cfg.distance_ingress_cm || pReq->ranging_cfg.distance_egress_cm) ?
@@ -614,7 +643,8 @@ wifi_error NanCommand::putNanPublish(transaction_id id, const NanPublishRequest
pFwReq->publishServiceReqParams.ttl = pReq->ttl;
pFwReq->publishServiceReqParams.period = pReq->period;
- pFwReq->publishServiceReqParams.reserved = 0;
+ pFwReq->publishServiceReqParams.replyIndFlag =
+ (pReq->recv_indication_cfg & BIT_3) ? 0 : 1;
pFwReq->publishServiceReqParams.publishType = pReq->publish_type;
pFwReq->publishServiceReqParams.txType = pReq->tx_type;
@@ -679,7 +709,8 @@ wifi_error NanCommand::putNanPublish(transaction_id id, const NanPublishRequest
if (pReq->sdea_params.config_nan_data_path ||
pReq->sdea_params.security_cfg ||
pReq->sdea_params.ranging_state ||
- pReq->sdea_params.range_report) {
+ pReq->sdea_params.range_report ||
+ pReq->sdea_params.qos_cfg) {
NanFWSdeaCtrlParams pNanFWSdeaCtrlParams;
memset(&pNanFWSdeaCtrlParams, 0, sizeof(NanFWSdeaCtrlParams));
@@ -703,6 +734,9 @@ wifi_error NanCommand::putNanPublish(transaction_id id, const NanPublishRequest
pNanFWSdeaCtrlParams.range_report =
(((pReq->sdea_params.range_report & NAN_ENABLE_RANGE_REPORT) >> 1) ? 1 : 0);
}
+ if (pReq->sdea_params.qos_cfg) {
+ pNanFWSdeaCtrlParams.qos_required = pReq->sdea_params.qos_cfg;
+ }
tlvs = addTlv(NAN_TLV_TYPE_SDEA_CTRL_PARAMS, sizeof(NanFWSdeaCtrlParams),
(const u8*)&pNanFWSdeaCtrlParams, tlvs);
}
@@ -824,7 +858,8 @@ wifi_error NanCommand::putNanSubscribe(transaction_id id,
(pReq->tx_match_filter_len ? SIZEOF_TLV_HDR + pReq->tx_match_filter_len : 0) +
(pReq->cipher_type ? SIZEOF_TLV_HDR + sizeof(NanCsidType) : 0) +
((pReq->sdea_params.config_nan_data_path || pReq->sdea_params.security_cfg ||
- pReq->sdea_params.ranging_state || pReq->sdea_params.range_report) ?
+ pReq->sdea_params.ranging_state || pReq->sdea_params.range_report ||
+ pReq->sdea_params.qos_cfg) ?
SIZEOF_TLV_HDR + sizeof(NanFWSdeaCtrlParams) : 0) +
((pReq->ranging_cfg.ranging_interval_msec || pReq->ranging_cfg.config_ranging_indications ||
pReq->ranging_cfg.distance_ingress_cm || pReq->ranging_cfg.distance_egress_cm) ?
@@ -939,7 +974,8 @@ wifi_error NanCommand::putNanSubscribe(transaction_id id,
if (pReq->sdea_params.config_nan_data_path ||
pReq->sdea_params.security_cfg ||
pReq->sdea_params.ranging_state ||
- pReq->sdea_params.range_report) {
+ pReq->sdea_params.range_report ||
+ pReq->sdea_params.qos_cfg) {
NanFWSdeaCtrlParams pNanFWSdeaCtrlParams;
memset(&pNanFWSdeaCtrlParams, 0, sizeof(NanFWSdeaCtrlParams));
@@ -963,6 +999,9 @@ wifi_error NanCommand::putNanSubscribe(transaction_id id,
pNanFWSdeaCtrlParams.range_report =
((pReq->sdea_params.range_report & NAN_ENABLE_RANGE_REPORT >> 1) ? 1 : 0);
}
+ if (pReq->sdea_params.qos_cfg) {
+ pNanFWSdeaCtrlParams.qos_required = pReq->sdea_params.qos_cfg;
+ }
tlvs = addTlv(NAN_TLV_TYPE_SDEA_CTRL_PARAMS, sizeof(NanFWSdeaCtrlParams),
(const u8*)&pNanFWSdeaCtrlParams, tlvs);
@@ -1354,6 +1393,12 @@ wifi_error NanCommand::requestEvent()
goto out;
}
+ if (!mInfo->cmd_sock) {
+ ALOGE("%s: Command socket is null",__func__);
+ res = WIFI_ERROR_OUT_OF_MEMORY;
+ goto out;
+ }
+
/* send message */
ALOGV("%s:Handle:%p Socket Value:%p", __func__, mInfo, mInfo->cmd_sock);
status = nl_send_auto_complete(mInfo->cmd_sock, mMsg.getMessage());
diff --git a/qcwcn/wifi_hal/nan_rsp.cpp b/qcwcn/wifi_hal/nan_rsp.cpp
index 5e614e4..31f3e7b 100644
--- a/qcwcn/wifi_hal/nan_rsp.cpp
+++ b/qcwcn/wifi_hal/nan_rsp.cpp
@@ -347,6 +347,7 @@ void NanCommand::NanErrorTranslation(NanInternalStatusType firmwareErrorRecvd,
NanPublishTerminatedInd* pRspInd;
NanDisabledInd* pRspdInd;
char tlvInfo[NAN_ERROR_STR_LEN];
+ tlvInfo[0] = '\0';
if (isNanResponse()) {
pRsp = (NanResponseMsg*)pResponse;
@@ -701,7 +702,7 @@ void NanCommand::handleNanStatsResponse(NanStatsType stats_type,
publish_stats.publishNewMatchCount = pPubStats->publishNewMatchCount;
publish_stats.pubsubGlobalNewMatchCount =
pPubStats->pubsubGlobalNewMatchCount;
- memcpy(&pRsp->data, &publish_stats, sizeof(NanPublishStats));
+ memcpy(&pRsp->data.publish_stats, &publish_stats, sizeof(NanPublishStats));
} else if (stats_type == NAN_STATS_ID_DE_SUBSCRIBE) {
NanSubscribeStats sub_stats;
if (message_len != sizeof(NanSubscribeStats)) {
@@ -744,7 +745,7 @@ void NanCommand::handleNanStatsResponse(NanStatsType stats_type,
sub_stats.subscribeNewMatchCount = pSubStats->subscribeNewMatchCount;
sub_stats.pubsubGlobalNewMatchCount =
pSubStats->pubsubGlobalNewMatchCount;
- memcpy(&pRsp->data, &sub_stats, sizeof(NanSubscribeStats));
+ memcpy(&pRsp->data.subscribe_stats, &sub_stats, sizeof(NanSubscribeStats));
} else if (stats_type == NAN_STATS_ID_DE_DW) {
NanDWStats dw_stats;
if (message_len != sizeof(NanDWStats)) {
@@ -758,6 +759,7 @@ void NanCommand::handleNanStatsResponse(NanStatsType stats_type,
dw_stats.validActionFrames = pMacStats->validActionFrames;
dw_stats.validBeaconFrames = pMacStats->validBeaconFrames;
dw_stats.ignoredActionFrames = pMacStats->ignoredActionFrames;
+ dw_stats.ignoredBeaconFrames = pMacStats->ignoredBeaconFrames;
dw_stats.invalidFrames = pMacStats->invalidFrames;
dw_stats.invalidActionFrames = pMacStats->invalidActionFrames;
dw_stats.invalidBeaconFrames = pMacStats->invalidBeaconFrames;
@@ -773,7 +775,7 @@ void NanCommand::handleNanStatsResponse(NanStatsType stats_type,
dw_stats.completeByTp75DW = pMacStats->completeByTp75DW;
dw_stats.completeByTendDW = pMacStats->completeByTendDW;
dw_stats.lateActionFramesTx = pMacStats->lateActionFramesTx;
- memcpy(&pRsp->data, &dw_stats, sizeof(NanDWStats));
+ memcpy(&pRsp->data.dw_stats, &dw_stats, sizeof(NanDWStats));
} else if (stats_type == NAN_STATS_ID_DE_MAC) {
NanMacStats mac_stats;
if (message_len != sizeof(NanMacStats)) {
@@ -787,6 +789,7 @@ void NanCommand::handleNanStatsResponse(NanStatsType stats_type,
mac_stats.validActionFrames = pMacStats->validActionFrames;
mac_stats.validBeaconFrames = pMacStats->validBeaconFrames;
mac_stats.ignoredActionFrames = pMacStats->ignoredActionFrames;
+ mac_stats.ignoredBeaconFrames = pMacStats->ignoredBeaconFrames;
mac_stats.invalidFrames = pMacStats->invalidFrames;
mac_stats.invalidActionFrames = pMacStats->invalidActionFrames;
mac_stats.invalidBeaconFrames = pMacStats->invalidBeaconFrames;
@@ -807,7 +810,7 @@ void NanCommand::handleNanStatsResponse(NanStatsType stats_type,
mac_stats.twChanges = pMacStats->twChanges;
mac_stats.twHighwater = pMacStats->twHighwater;
mac_stats.bloomFilterIndex = pMacStats->bloomFilterIndex;
- memcpy(&pRsp->data, &mac_stats, sizeof(NanMacStats));
+ memcpy(&pRsp->data.mac_stats, &mac_stats, sizeof(NanMacStats));
} else if (stats_type == NAN_STATS_ID_DE_TIMING_SYNC) {
NanSyncStats sync_stats;
if (message_len != sizeof(NanSyncStats)) {
@@ -867,7 +870,9 @@ void NanCommand::handleNanStatsResponse(NanStatsType stats_type,
sync_stats.discBeaconTxFailures = pSyncStats->discBeaconTxFailures;
sync_stats.amHopCountExpireCount = pSyncStats->amHopCountExpireCount;
sync_stats.ndpChannelFreq = pSyncStats->ndpChannelFreq;
- memcpy(&pRsp->data, &sync_stats, sizeof(NanSyncStats));
+ sync_stats.ndpChannelFreq2 = pSyncStats->ndpChannelFreq2;
+ sync_stats.schedUpdateChannelFreq = pSyncStats->schedUpdateChannelFreq;
+ memcpy(&pRsp->data.sync_stats, &sync_stats, sizeof(NanSyncStats));
} else if (stats_type == NAN_STATS_ID_DE) {
NanDeStats de_stats;
if (message_len != sizeof(NanDeStats)) {
@@ -907,7 +912,7 @@ void NanCommand::handleNanStatsResponse(NanStatsType stats_type,
de_stats.invalidEnableReqMsgs = pDeStats->invalidEnableReqMsgs;
de_stats.invalidDisableReqMsgs = pDeStats->invalidDisableReqMsgs;
de_stats.invalidTcaReqMsgs = pDeStats->invalidTcaReqMsgs;
- memcpy(&pRsp->data, &de_stats, sizeof(NanDeStats));
+ memcpy(&pRsp->data.de_stats, &de_stats, sizeof(NanDeStats));
} else {
ALOGE("Unknown stats_type:%d\n", stats_type);
}
diff --git a/qcwcn/wifi_hal/nancommand.h b/qcwcn/wifi_hal/nancommand.h
index bcda90f..bbe62c5 100644
--- a/qcwcn/wifi_hal/nancommand.h
+++ b/qcwcn/wifi_hal/nancommand.h
@@ -46,6 +46,7 @@ private:
//based on the indication type
int handleNanIndication();
//Various Functions to get the appropriate indications
+ int getNanPublishReplied(NanPublishRepliedInd *event);
int getNanPublishTerminated(NanPublishTerminatedInd *event);
int getNanMatch(NanMatchInd *event);
int getNanMatchExpired(NanMatchExpiredInd *event);
diff --git a/qcwcn/wifi_hal/nud_stats.h b/qcwcn/wifi_hal/nud_stats.h
new file mode 100644
index 0000000..d6f7ecd
--- /dev/null
+++ b/qcwcn/wifi_hal/nud_stats.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdint.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <sys/socket.h>
+#include <netlink/genl/genl.h>
+#include <netlink/genl/family.h>
+#include <netlink/genl/ctrl.h>
+#include <linux/rtnetlink.h>
+#include <netpacket/packet.h>
+#include <linux/filter.h>
+#include <linux/errqueue.h>
+
+#include <linux/pkt_sched.h>
+#include <netlink/object-api.h>
+#include <netlink/netlink.h>
+#include <netlink/socket.h>
+#include "wifi_hal.h"
+
+typedef struct {
+ uint16_t arp_req_count_from_netdev;
+ uint16_t arp_req_count_to_lower_mac;
+ uint16_t arp_req_rx_count_by_lower_mac;
+ uint16_t arp_req_count_tx_success;
+ uint16_t arp_rsp_rx_count_by_lower_mac;
+ uint16_t arp_rsp_rx_count_by_upper_mac;
+ uint16_t arp_rsp_count_to_netdev;
+ uint16_t arp_rsp_count_out_of_order_drop;
+ uint8_t ap_link_active;
+ uint8_t is_duplicate_addr_detection;
+} nud_stats;
+
+
+wifi_error wifi_set_nud_stats(wifi_interface_handle iface, u32 gw_addr);
+wifi_error wifi_get_nud_stats(wifi_interface_handle iface,
+ nud_stats *stats);
+wifi_error wifi_clear_nud_stats(wifi_interface_handle iface);
diff --git a/qcwcn/wifi_hal/rssi_monitor.cpp b/qcwcn/wifi_hal/rssi_monitor.cpp
index 809bc31..5147d87 100644
--- a/qcwcn/wifi_hal/rssi_monitor.cpp
+++ b/qcwcn/wifi_hal/rssi_monitor.cpp
@@ -67,6 +67,8 @@ wifi_error cleanupRSSIMonitorHandler(hal_info *info)
delete event_handlers->mRSSIMonitorCommandInstance;
}
memset(event_handlers, 0, sizeof(rssi_monitor_event_handlers));
+ free(info->rssi_handlers);
+ info->rssi_handlers = NULL;
return WIFI_SUCCESS;
}
ALOGE ("%s: info or info->rssi_handlers NULL", __FUNCTION__);
diff --git a/qcwcn/wifi_hal/wifi_hal.cpp b/qcwcn/wifi_hal/wifi_hal.cpp
index 083778f..4a50f0f 100644
--- a/qcwcn/wifi_hal/wifi_hal.cpp
+++ b/qcwcn/wifi_hal/wifi_hal.cpp
@@ -731,6 +731,18 @@ static void internal_cleaned_up_handler(wifi_handle handle)
info->event_sock = NULL;
}
+ if (info->interfaces) {
+ for (int i = 0; i < info->num_interfaces; i++)
+ free(info->interfaces[i]);
+ free(info->interfaces);
+ }
+
+ if (info->cmd)
+ free(info->cmd);
+
+ if (info->event_cb)
+ free(info->event_cb);
+
if (info->cldctx != NULL) {
cld80211lib_cleanup(info);
} else if (info->user_sock != 0) {
diff --git a/qcwcn/wifi_hal/wifihal_vendor.cpp b/qcwcn/wifi_hal/wifihal_vendor.cpp
new file mode 100644
index 0000000..33842f2
--- /dev/null
+++ b/qcwcn/wifi_hal/wifihal_vendor.cpp
@@ -0,0 +1,380 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "sync.h"
+
+#define LOG_TAG "WifiHAL"
+
+#include <utils/Log.h>
+
+#include "wifi_hal.h"
+#include "common.h"
+#include "cpp_bindings.h"
+#include "wifihal_vendorcommand.h"
+#include "vendor_definitions.h"
+
+//Singleton Static Instance
+NUDStatsCommand* NUDStatsCommand::mNUDStatsCommandInstance = NULL;
+
+// This function implements creation of Vendor command
+// For NUDStats just call base Vendor command create
+wifi_error NUDStatsCommand::create() {
+ wifi_error ret = mMsg.create(NL80211_CMD_VENDOR, 0, 0);
+ if (ret != WIFI_SUCCESS) {
+ return ret;
+ }
+ // insert the oui in the msg
+ ret = mMsg.put_u32(NL80211_ATTR_VENDOR_ID, mVendor_id);
+ if (ret != WIFI_SUCCESS)
+ goto out;
+
+ // insert the subcmd in the msg
+ ret = mMsg.put_u32(NL80211_ATTR_VENDOR_SUBCMD, mSubcmd);
+ if (ret != WIFI_SUCCESS)
+ goto out;
+
+out:
+ return ret;
+}
+
+NUDStatsCommand::NUDStatsCommand(wifi_handle handle, int id, u32 vendor_id, u32 subcmd)
+ : WifiVendorCommand(handle, id, vendor_id, subcmd)
+{
+ memset(&mStats, 0,sizeof(nud_stats));
+}
+
+NUDStatsCommand::~NUDStatsCommand()
+{
+ mNUDStatsCommandInstance = NULL;
+}
+
+NUDStatsCommand* NUDStatsCommand::instance(wifi_handle handle)
+{
+ if (handle == NULL) {
+ ALOGE("Interface Handle is invalid");
+ return NULL;
+ }
+ if (mNUDStatsCommandInstance == NULL) {
+ mNUDStatsCommandInstance = new NUDStatsCommand(handle, 0,
+ OUI_QCA,
+ QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_SET);
+ return mNUDStatsCommandInstance;
+ }
+ else
+ {
+ if (handle != getWifiHandle(mNUDStatsCommandInstance->mInfo))
+ {
+ /* upper layer must have cleaned up the handle and reinitialized,
+ so we need to update the same */
+ ALOGE("Handle different, update the handle");
+ mNUDStatsCommandInstance->mInfo = (hal_info *)handle;
+ }
+ }
+ return mNUDStatsCommandInstance;
+}
+
+void NUDStatsCommand::setSubCmd(u32 subcmd)
+{
+ mSubcmd = subcmd;
+}
+
+wifi_error NUDStatsCommand::requestResponse()
+{
+ return WifiCommand::requestResponse(mMsg);
+}
+
+int NUDStatsCommand::handleResponse(WifiEvent &reply)
+{
+ int status = WIFI_ERROR_NONE;
+ WifiVendorCommand::handleResponse(reply);
+
+ // Parse the vendordata and get the attribute
+
+ switch(mSubcmd)
+ {
+ case QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET:
+ {
+ struct nlattr *tb_vendor[QCA_ATTR_NUD_STATS_GET_MAX + 1];
+ nud_stats *stats = &mStats;
+
+ memset(stats, 0, sizeof(nud_stats));
+ nla_parse(tb_vendor, QCA_ATTR_NUD_STATS_GET_MAX,
+ (struct nlattr *)mVendorData, mDataLen, NULL);
+
+ if (!tb_vendor[QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV])
+ {
+ ALOGE("%s: QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV"
+ " not found", __FUNCTION__);
+ status = WIFI_ERROR_INVALID_ARGS;
+ goto cleanup;
+ }
+ stats->arp_req_count_from_netdev = nla_get_u16(tb_vendor[
+ QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV]);
+
+ if (!tb_vendor[QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC])
+ {
+ ALOGE("%s: QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC"
+ " not found", __FUNCTION__);
+ status = WIFI_ERROR_INVALID_ARGS;
+ goto cleanup;
+ }
+ stats->arp_req_count_to_lower_mac = nla_get_u16(tb_vendor[
+ QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC]);
+
+ if (!tb_vendor[QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC])
+ {
+ ALOGE("%s: QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC"
+ " not found", __FUNCTION__);
+ status = WIFI_ERROR_INVALID_ARGS;
+ goto cleanup;
+ }
+ stats->arp_req_rx_count_by_lower_mac = nla_get_u16(tb_vendor[
+ QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC]);
+
+ if (!tb_vendor[QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS])
+ {
+ ALOGE("%s: QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS"
+ " not found", __FUNCTION__);
+ status = WIFI_ERROR_INVALID_ARGS;
+ goto cleanup;
+ }
+ stats->arp_req_count_tx_success = nla_get_u16(tb_vendor[
+ QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS]);
+
+ if (!tb_vendor[QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC])
+ {
+ ALOGE("%s: QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC"
+ " not found", __FUNCTION__);
+ status = WIFI_ERROR_INVALID_ARGS;
+ goto cleanup;
+ }
+ stats->arp_rsp_rx_count_by_lower_mac = nla_get_u16(tb_vendor[
+ QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC]);
+
+ if (!tb_vendor[QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC])
+ {
+ ALOGE("%s: QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC"
+ " not found", __FUNCTION__);
+ status = WIFI_ERROR_INVALID_ARGS;
+ goto cleanup;
+ }
+ stats->arp_rsp_rx_count_by_upper_mac = nla_get_u16(tb_vendor[
+ QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC]);
+
+ if (!tb_vendor[QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV])
+ {
+ ALOGE("%s: QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV"
+ " not found", __FUNCTION__);
+ status = WIFI_ERROR_INVALID_ARGS;
+ goto cleanup;
+ }
+ stats->arp_rsp_count_to_netdev = nla_get_u16(tb_vendor[
+ QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV]);
+
+ if (!tb_vendor[QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP])
+ {
+ ALOGE("%s: QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP"
+ " not found", __FUNCTION__);
+ status = WIFI_ERROR_INVALID_ARGS;
+ goto cleanup;
+ }
+ stats->arp_rsp_count_out_of_order_drop = nla_get_u16(tb_vendor[
+ QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP]);
+
+ if (tb_vendor[QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE])
+ stats->ap_link_active = 1;
+
+ if (tb_vendor[QCA_ATTR_NUD_STATS_IS_DAD])
+ stats->is_duplicate_addr_detection = 1;
+
+ ALOGV(" req_from_netdev %d count_to_lower :%d"
+ " count_by_lower :%d"
+ " count_tx_succ :%d rsp_count_lower :%d"
+ " rsp_count_upper :%d rsp_count_netdev :%d"
+ " out_of_order_drop :%d active_aplink %d"
+ " DAD %d ",
+ stats->arp_req_count_from_netdev,
+ stats->arp_req_count_to_lower_mac,
+ stats->arp_req_rx_count_by_lower_mac,
+ stats->arp_req_count_tx_success,
+ stats->arp_rsp_rx_count_by_lower_mac,
+ stats->arp_rsp_rx_count_by_upper_mac,
+ stats->arp_rsp_count_to_netdev,
+ stats->arp_rsp_count_out_of_order_drop,
+ stats->ap_link_active,
+ stats->is_duplicate_addr_detection);
+ }
+ }
+cleanup:
+ if (status == WIFI_ERROR_INVALID_ARGS)
+ memset(&mStats,0,sizeof(nud_stats));
+
+ return status;
+}
+
+void NUDStatsCommand::copyStats(nud_stats *stats)
+{
+ memcpy(stats, &mStats, sizeof(nud_stats));
+}
+
+wifi_error wifi_set_nud_stats(wifi_interface_handle iface, u32 gw_addr)
+{
+ wifi_error ret;
+ NUDStatsCommand *NUDCommand;
+ struct nlattr *nl_data;
+ interface_info *iinfo = getIfaceInfo(iface);
+ wifi_handle handle = getWifiHandle(iface);
+
+ ALOGV("gw_addr : %x", gw_addr);
+ NUDCommand = NUDStatsCommand::instance(handle);
+ if (NUDCommand == NULL) {
+ ALOGE("%s: Error NUDStatsCommand NULL", __FUNCTION__);
+ return WIFI_ERROR_INVALID_ARGS;
+ }
+ NUDCommand->setSubCmd(QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_SET);
+
+ /* create the message */
+ ret = NUDCommand->create();
+ if (ret != WIFI_SUCCESS)
+ goto cleanup;
+
+ ret = NUDCommand->set_iface_id(iinfo->name);
+ if (ret != WIFI_SUCCESS)
+ goto cleanup;
+
+ /*add the attributes*/
+ nl_data = NUDCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
+ if (!nl_data)
+ goto cleanup;
+ /**/
+ ret = NUDCommand->put_flag(QCA_ATTR_NUD_STATS_SET_START);
+
+ ret = NUDCommand->put_u32(QCA_ATTR_NUD_STATS_GW_IPV4, gw_addr);
+ if (ret != WIFI_SUCCESS)
+ goto cleanup;
+ /**/
+ NUDCommand->attr_end(nl_data);
+
+ ret = NUDCommand->requestResponse();
+ if (ret != WIFI_SUCCESS) {
+ ALOGE("%s: requestResponse Error:%d",__FUNCTION__, ret);
+ }
+
+cleanup:
+ return ret;
+}
+
+
+wifi_error wifi_get_nud_stats(wifi_interface_handle iface,
+ nud_stats *stats)
+{
+ wifi_error ret;
+ NUDStatsCommand *NUDCommand;
+ struct nlattr *nl_data;
+ interface_info *iinfo = getIfaceInfo(iface);
+ wifi_handle handle = getWifiHandle(iface);
+
+ if (stats == NULL) {
+ ALOGE("%s: Error stats is NULL", __FUNCTION__);
+ return WIFI_ERROR_INVALID_ARGS;
+ }
+
+ NUDCommand = NUDStatsCommand::instance(handle);
+ if (NUDCommand == NULL) {
+ ALOGE("%s: Error NUDStatsCommand NULL", __FUNCTION__);
+ return WIFI_ERROR_INVALID_ARGS;
+ }
+ NUDCommand->setSubCmd(QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET);
+
+ /* create the message */
+ ret = NUDCommand->create();
+ if (ret != WIFI_SUCCESS)
+ goto cleanup;
+
+ ret = NUDCommand->set_iface_id(iinfo->name);
+ if (ret != WIFI_SUCCESS)
+ goto cleanup;
+ /*add the attributes*/
+ nl_data = NUDCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
+ if (!nl_data)
+ goto cleanup;
+ /**/
+ NUDCommand->attr_end(nl_data);
+
+ ret = NUDCommand->requestResponse();
+ if (ret != WIFI_SUCCESS) {
+ ALOGE("%s: requestResponse Error:%d",__FUNCTION__, ret);
+ goto cleanup;
+ }
+
+ NUDCommand->copyStats(stats);
+
+cleanup:
+ return ret;
+}
+
+
+wifi_error wifi_clear_nud_stats(wifi_interface_handle iface)
+{
+ wifi_error ret;
+ NUDStatsCommand *NUDCommand;
+ struct nlattr *nl_data;
+ interface_info *iinfo = getIfaceInfo(iface);
+ wifi_handle handle = getWifiHandle(iface);
+
+ NUDCommand = NUDStatsCommand::instance(handle);
+ if (NUDCommand == NULL) {
+ ALOGE("%s: Error NUDStatsCommand NULL", __FUNCTION__);
+ return WIFI_ERROR_INVALID_ARGS;
+ }
+ NUDCommand->setSubCmd(QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_SET);
+
+ /* create the message */
+ ret = NUDCommand->create();
+ if (ret != WIFI_SUCCESS)
+ goto cleanup;
+
+ ret = NUDCommand->set_iface_id(iinfo->name);
+ if (ret != WIFI_SUCCESS)
+ goto cleanup;
+
+ /*add the attributes*/
+ nl_data = NUDCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
+ if (!nl_data)
+ goto cleanup;
+
+ NUDCommand->attr_end(nl_data);
+
+ ret = NUDCommand->requestResponse();
+ if (ret != WIFI_SUCCESS)
+ ALOGE("%s: requestResponse Error:%d",__FUNCTION__, ret);
+
+cleanup:
+ return ret;
+}
diff --git a/qcwcn/wifi_hal/wifihal_vendorcommand.h b/qcwcn/wifi_hal/wifihal_vendorcommand.h
new file mode 100644
index 0000000..2a73902
--- /dev/null
+++ b/qcwcn/wifi_hal/wifihal_vendorcommand.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __WIFI_HAL_NUDSTATSCOMMAND_H__
+#define __WIFI_HAL_NUDSTATSCOMMAND_H__
+
+#include "nud_stats.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+class NUDStatsCommand: public WifiVendorCommand
+{
+private:
+ static NUDStatsCommand *mNUDStatsCommandInstance;
+
+ nud_stats mStats;
+
+ NUDStatsCommand(wifi_handle handle, int id, u32 vendor_id, u32 subcmd);
+
+public:
+ static NUDStatsCommand* instance(wifi_handle handle);
+
+ virtual ~NUDStatsCommand();
+
+ // This function implements creation of NUDStats specific Request
+ // based on the request type
+ virtual wifi_error create();
+
+ virtual void setSubCmd(u32 subcmd);
+
+ virtual wifi_error requestResponse();
+
+ virtual int handleResponse(WifiEvent &reply);
+
+ void copyStats(nud_stats *stats);
+};
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif
diff --git a/qcwcn/wifi_hal/wifilogger.cpp b/qcwcn/wifi_hal/wifilogger.cpp
index 9acff62..81165a2 100644
--- a/qcwcn/wifi_hal/wifilogger.cpp
+++ b/qcwcn/wifi_hal/wifilogger.cpp
@@ -191,13 +191,13 @@ void push_out_all_ring_buffers(hal_info *info)
void send_alert(hal_info *info, int reason_code)
{
wifi_alert_handler handler;
-
+ char alert_msg[20] = "Fatal Event";
pthread_mutex_lock(&info->ah_lock);
handler.on_alert = info->on_alert;
pthread_mutex_unlock(&info->ah_lock);
if (handler.on_alert) {
- handler.on_alert(0, NULL, 0, reason_code);
+ handler.on_alert(0, alert_msg, strlen(alert_msg), reason_code);
}
}
diff --git a/qcwcn/wifi_hal/wifilogger_diag.cpp b/qcwcn/wifi_hal/wifilogger_diag.cpp
index 5e9227b..da397af 100644
--- a/qcwcn/wifi_hal/wifilogger_diag.cpp
+++ b/qcwcn/wifi_hal/wifilogger_diag.cpp
@@ -136,6 +136,7 @@ static wifi_error process_log_extscan_capabilities(hal_info *info,
pRingBufferEntry = (wifi_ring_buffer_entry *)&out_buf[0];
memset(pRingBufferEntry, 0, SCAN_CAP_ENTRY_SIZE);
+ memset(&cap_vendor_data, 0, sizeof(gscan_capabilities_vendor_data_t));
pConnectEvent = (wifi_ring_buffer_driver_connectivity_event *)
(pRingBufferEntry + 1);
@@ -701,6 +702,8 @@ static wifi_error process_roam_event(hal_info *info, u32 id,
roam_candidate_found_vendor_data_t roamCandidateFoundVendata;
pConnectEvent->event = WIFI_EVENT_ROAM_CANDIDATE_FOUND;
pRoamCandidateFound = (wlan_roam_candidate_found_payload_type *)buf;
+ memset(&roamCandidateFoundVendata, 0,
+ sizeof(roam_candidate_found_vendor_data_t));
pTlv = &pConnectEvent->tlvs[0];
pTlv = addLoggerTlv(WIFI_TAG_CHANNEL,
sizeof(pRoamCandidateFound->channel),
diff --git a/wcnss-service/Android.mk b/wcnss-service/Android.mk
index 6a6cb48..77b859b 100644
--- a/wcnss-service/Android.mk
+++ b/wcnss-service/Android.mk
@@ -9,16 +9,15 @@ LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/common/inc/
LOCAL_SRC_FILES := wcnss_service.c
ifeq ($(strip $(TARGET_USES_QCOM_WCNSS_QMI)),true)
LOCAL_CFLAGS += -DWCNSS_QMI
-LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/qmi/inc
+LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/qmi-framework/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_C_INCLUDES += $(TARGET_OUT_HEADERS)/qmi/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
+LOCAL_SHARED_LIBRARIES += libqmiservices libqmi_cci
LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/libmdmdetect/inc
LOCAL_SHARED_LIBRARIES += libmdmdetect
endif #TARGET_USES_QCOM_WCNSS_QMI
diff --git a/wcnss-service/wcnss_qmi_client.c b/wcnss-service/wcnss_qmi_client.c
index b9f94f7..3e1fb0e 100644
--- a/wcnss-service/wcnss_qmi_client.c
+++ b/wcnss-service/wcnss_qmi_client.c
@@ -30,7 +30,6 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define LOG_TAG "wcnss_qmi"
#include <cutils/log.h>
#include "wcnss_qmi_client.h"
-#include "qmi.h"
#include "qmi_client.h"
#include "device_management_service_v01.h"
#include <cutils/properties.h>
@@ -43,118 +42,19 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define DMS_QMI_TIMEOUT (2000)
static qmi_client_type dms_qmi_client;
-static int qmi_handle;
static int dms_init_done = FAILED;
-/* Android system property for fetching the modem type */
-#define QMI_UIM_PROPERTY_BASEBAND "ro.baseband"
-
-/* Android system property values for various modem types */
-#define QMI_UIM_PROP_BASEBAND_VALUE_SVLTE_1 "svlte1"
-#define QMI_UIM_PROP_BASEBAND_VALUE_SVLTE_2A "svlte2a"
-#define QMI_UIM_PROP_BASEBAND_VALUE_CSFB "csfb"
-#define QMI_UIM_PROP_BASEBAND_VALUE_SGLTE "sglte"
-#define QMI_UIM_PROP_BASEBAND_VALUE_SGLTE2 "sglte2"
-#define QMI_UIM_PROP_BASEBAND_VALUE_MSM "msm"
-#define QMI_UIM_PROP_BASEBAND_VALUE_APQ "apq"
-#define QMI_UIM_PROP_BASEBAND_VALUE_MDMUSB "mdm"
-#define QMI_UIM_PROP_BASEBAND_VALUE_DSDA "dsda"
-#define QMI_UIM_PROP_BASEBAND_VALUE_DSDA_2 "dsda2"
-
-static char *dms_find_modem_port( char *prop_value_ptr)
-{
- char *qmi_modem_port_ptr = QMI_PORT_RMNET_0;
-
- /* Sanity check */
- if (prop_value_ptr == NULL) {
- ALOGE("%s: NULL prop_value_ptr, using default port", __func__);
- return qmi_modem_port_ptr;
- }
-
- ALOGE("%s: Baseband property value read: %s", __func__,
- prop_value_ptr);
-
- /* Map the port based on the read property */
- if ((strcmp(prop_value_ptr,
- QMI_UIM_PROP_BASEBAND_VALUE_SVLTE_1) == 0) ||
- (strcmp(prop_value_ptr,
- QMI_UIM_PROP_BASEBAND_VALUE_SVLTE_2A) == 0) ||
- (strcmp(prop_value_ptr,
- QMI_UIM_PROP_BASEBAND_VALUE_CSFB) == 0)) {
- qmi_modem_port_ptr = QMI_PORT_RMNET_SDIO_0;
- } else if ((strcmp(prop_value_ptr,
- QMI_UIM_PROP_BASEBAND_VALUE_MDMUSB) == 0) ||
- (strcmp(prop_value_ptr,
- QMI_UIM_PROP_BASEBAND_VALUE_SGLTE2) == 0)) {
- qmi_modem_port_ptr = QMI_PORT_RMNET_USB_0;
- } else if ((strcmp(prop_value_ptr,
- QMI_UIM_PROP_BASEBAND_VALUE_MSM) == 0) ||
- (strcmp(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_0;
- } else if (strcmp(prop_value_ptr,
- QMI_UIM_PROP_BASEBAND_VALUE_DSDA) == 0) {
- /* If it is a DSDA configuration, use the existing API */
- qmi_modem_port_ptr = (char *)QMI_PLATFORM_INTERNAL_USE_PORT_ID;
- } else if (strcmp(prop_value_ptr,
- QMI_UIM_PROP_BASEBAND_VALUE_DSDA_2) == 0) {
- /* If it is a DSDA2 configuration, use the existing API */
- qmi_modem_port_ptr = (char *)QMI_PLATFORM_INTERNAL_USE_PORT_ID;
- } else {
- ALOGE("%s: Property value does not match,using default port:%s",
- __func__, qmi_modem_port_ptr);
- }
-
- ALOGE("%s: QMI port found for modem: %s", __func__, qmi_modem_port_ptr);
-
- return qmi_modem_port_ptr;
-}
-
int wcnss_init_qmi()
{
qmi_client_error_type qmi_client_err;
- qmi_idl_service_object_type dms_service;
- char prop_value[PROPERTY_VALUE_MAX];
- char *qmi_modem_port = NULL;
ALOGE("%s: Initialize wcnss QMI Interface", __func__);
+ qmi_client_os_params dms_os_params;
- qmi_handle = qmi_init(NULL, NULL);
- if (qmi_handle < 0) {
- ALOGE("%s: Error while initializing qmi", __func__);
- return FAILED;
- }
-
- dms_service = dms_get_service_object_v01();
- if (dms_service == NULL) {
- ALOGE("%s: Not able to get the service handle", __func__);
- goto exit;
- }
-
- /* Find out the modem type */
- memset(prop_value, 0x00, sizeof(prop_value));
- property_get(QMI_UIM_PROPERTY_BASEBAND, prop_value, "");
-
- /* Map to a respective QMI port */
- qmi_modem_port = dms_find_modem_port(prop_value);
- if (qmi_modem_port == NULL) {
- ALOGE("%s: qmi_modem_port is NULL", __func__);
- goto exit;
- }
-
- 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);
- }
+ memset(&dms_os_params, 0, sizeof(qmi_client_os_params));
+ qmi_client_err = qmi_client_init_instance(dms_get_service_object_v01(),
+ QMI_CLIENT_INSTANCE_ANY, NULL, NULL,
+ &dms_os_params, 5000, &dms_qmi_client);
if (qmi_client_err != QMI_NO_ERR){
ALOGE("%s: Error while Initializing QMI Client: %d",
@@ -166,11 +66,6 @@ int wcnss_init_qmi()
return SUCCESS;
exit:
- qmi_handle = qmi_release(qmi_handle);
- if ( qmi_handle < 0 ) {
- ALOGE("%s: Error while releasing qmi %d",
- __func__, qmi_handle);
- }
return FAILED;
}
@@ -235,12 +130,6 @@ void wcnss_qmi_deinit()
__func__, qmi_client_err);
}
- qmi_handle = qmi_release(qmi_handle);
- if (qmi_handle < 0) {
- ALOGE("%s: Error while releasing qmi %d",
- __func__, qmi_handle);
- }
-
dms_init_done = FAILED;
}
#endif