summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2014-10-14 18:32:47 -0700
committerGerrit - the friendly Code Review server <code-review@localhost>2014-10-14 18:32:47 -0700
commit7a861371f6f8fc61c342ec0fa17892e9796091fa (patch)
treecaf3e393d00b1603cd1ba77f3e7e265d01ac91ba
parent8bc8d61f47b31c12b3e858febca6c62f1e93fef5 (diff)
parent647566496b620f6f9b604271f6d7faa5e8d391ef (diff)
downloadandroid_hardware_qcom_wlan-7a861371f6f8fc61c342ec0fa17892e9796091fa.tar.gz
android_hardware_qcom_wlan-7a861371f6f8fc61c342ec0fa17892e9796091fa.tar.bz2
android_hardware_qcom_wlan-7a861371f6f8fc61c342ec0fa17892e9796091fa.zip
Merge "Nan Wifihal related changes."
-rw-r--r--qcwcn/wifi_hal/Android.mk18
-rw-r--r--qcwcn/wifi_hal/nan.cpp876
-rw-r--r--qcwcn/wifi_hal/nan.h1764
-rw-r--r--qcwcn/wifi_hal/nan_i.h875
-rw-r--r--qcwcn/wifi_hal/nan_ind.cpp956
-rw-r--r--qcwcn/wifi_hal/nan_req.cpp1071
-rw-r--r--qcwcn/wifi_hal/nan_rsp.cpp276
-rw-r--r--qcwcn/wifi_hal/nancommand.h120
8 files changed, 5952 insertions, 4 deletions
diff --git a/qcwcn/wifi_hal/Android.mk b/qcwcn/wifi_hal/Android.mk
index 1800ff9..2ee9d6b 100644
--- a/qcwcn/wifi_hal/Android.mk
+++ b/qcwcn/wifi_hal/Android.mk
@@ -21,10 +21,11 @@ include $(CLEAR_VARS)
LOCAL_REQUIRED_MODULES :=
LOCAL_CFLAGS += -Wno-unused-parameter -Wno-int-to-pointer-cast
-LOCAL_CFLAGS += -Wno-maybe-uninitialized -Wno-parentheses
+LOCAL_CFLAGS += -Wno-maybe-uninitialized -Wno-parentheses -DNAN_2_0
LOCAL_CPPFLAGS += -Wno-conversion-null
LOCAL_C_INCLUDES += \
+ $(LOCAL_PATH) \
external/libnl/include \
$(call include-path-for, libhardware_legacy)/hardware_legacy \
external/wpa_supplicant_8/src/drivers \
@@ -40,7 +41,11 @@ LOCAL_SRC_FILES := \
gscan_event_handler.cpp \
rtt.cpp \
ifaceeventhandler.cpp \
- tdls.cpp
+ tdls.cpp \
+ nan.cpp \
+ nan_ind.cpp \
+ nan_req.cpp \
+ nan_rsp.cpp
LOCAL_MODULE := libwifi-hal-qcom
LOCAL_SHARED_LIBRARIES += libnetutils liblog
@@ -61,10 +66,11 @@ include $(CLEAR_VARS)
LOCAL_REQUIRED_MODULES :=
LOCAL_CFLAGS += -Wno-unused-parameter -Wno-int-to-pointer-cast
-LOCAL_CFLAGS += -Wno-maybe-uninitialized -Wno-parentheses
+LOCAL_CFLAGS += -Wno-maybe-uninitialized -Wno-parentheses -DNAN_2_0
LOCAL_CPPFLAGS += -Wno-conversion-null
LOCAL_C_INCLUDES += \
+ $(LOCAL_PATH) \
external/libnl/include \
$(call include-path-for, libhardware_legacy)/hardware_legacy \
external/wpa_supplicant_8/src/drivers \
@@ -80,7 +86,11 @@ LOCAL_SRC_FILES := \
gscan_event_handler.cpp \
rtt.cpp \
ifaceeventhandler.cpp \
- tdls.cpp
+ tdls.cpp \
+ nan.cpp \
+ nan_ind.cpp \
+ nan_req.cpp \
+ nan_rsp.cpp
LOCAL_MODULE := libwifi-hal-qcom
LOCAL_SHARED_LIBRARIES += libnetutils liblog
diff --git a/qcwcn/wifi_hal/nan.cpp b/qcwcn/wifi_hal/nan.cpp
new file mode 100644
index 0000000..9cfa779
--- /dev/null
+++ b/qcwcn/wifi_hal/nan.cpp
@@ -0,0 +1,876 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "sync.h"
+
+#include "nan_i.h"
+#include "wifi_hal.h"
+#include "common.h"
+#include "cpp_bindings.h"
+#include <utils/Log.h>
+#include "nancommand.h"
+
+#ifdef __GNUC__
+#define PRINTF_FORMAT(a,b) __attribute__ ((format (printf, (a), (b))))
+#define STRUCT_PACKED __attribute__ ((packed))
+#else
+#define PRINTF_FORMAT(a,b)
+#define STRUCT_PACKED
+#endif
+
+#include "qca-vendor.h"
+
+//Singleton Static Instance
+NanCommand* NanCommand::mNanCommandInstance = NULL;
+
+//Implementation of the functions exposed in nan.h
+wifi_error nan_register_handler(wifi_handle handle,
+ NanCallbackHandler handlers)
+{
+ // Obtain the singleton instance
+ int ret = 0;
+ NanCommand *nCommand;
+
+ nCommand = NanCommand::instance(handle);
+ if (nCommand == NULL) {
+ ALOGE("%s: Error NanCommand NULL", __func__);
+ return WIFI_ERROR_UNKNOWN;
+ }
+ ret = nCommand->setCallbackHandler(handlers);
+ return (wifi_error)ret;
+}
+
+wifi_error nan_get_version(wifi_handle handle,
+ NanVersion* version)
+{
+ *version = (NAN_MAJOR_VERSION <<16 | NAN_MINOR_VERSION << 8 | NAN_MICRO_VERSION);
+ return WIFI_SUCCESS;
+}
+
+/* Function to send enable request to the wifi driver.*/
+wifi_error nan_enable_request(wifi_request_id id,
+ wifi_handle handle,
+ NanEnableRequest* msg)
+{
+ int ret = 0;
+ NanCommand *nCommand;
+
+ nCommand = NanCommand::instance(handle);
+ if (nCommand == NULL) {
+ ALOGE("%s: Error NanCommand NULL", __func__);
+ return WIFI_ERROR_UNKNOWN;
+ }
+
+ ret = nCommand->putNanEnable(msg);
+ if (ret != 0) {
+ ALOGE("%s: putNanEnable Error:%d",__func__, ret);
+ goto cleanup;
+ }
+ nCommand->setId(id);
+ ret = nCommand->requestEvent();
+ if (ret != 0) {
+ ALOGE("%s: requestEvent Error:%d",__func__, ret);
+ }
+cleanup:
+ return (wifi_error)ret;
+}
+
+/* Function to send disable request to the wifi driver.*/
+wifi_error nan_disable_request(wifi_request_id id,
+ wifi_handle handle,
+ NanDisableRequest* msg)
+{
+ int ret = 0;
+ NanCommand *nCommand;
+
+ nCommand = NanCommand::instance(handle);
+ if (nCommand == NULL) {
+ ALOGE("%s: Error NanCommand NULL", __func__);
+ return WIFI_ERROR_UNKNOWN;
+ }
+
+ ret = nCommand->putNanDisable(msg);
+ if (ret != 0) {
+ ALOGE("%s: putNanDisable Error:%d",__func__, ret);
+ goto cleanup;
+ }
+ nCommand->setId(id);
+ ret = nCommand->requestEvent();
+ if (ret != 0) {
+ ALOGE("%s: requestEvent Error:%d",__func__, ret);
+ }
+cleanup:
+ return (wifi_error)ret;
+}
+
+/* Function to send publish request to the wifi driver.*/
+wifi_error nan_publish_request(wifi_request_id id,
+ wifi_handle handle,
+ NanPublishRequest* msg)
+{
+ int ret = 0;
+ NanCommand *nCommand;
+
+ nCommand = NanCommand::instance(handle);
+ if (nCommand == NULL) {
+ ALOGE("%s: Error NanCommand NULL", __func__);
+ return WIFI_ERROR_UNKNOWN;
+ }
+
+ ret = nCommand->putNanPublish(msg);
+ if (ret != 0) {
+ ALOGE("%s: putNanPublish Error:%d",__func__, ret);
+ goto cleanup;
+ }
+ nCommand->setId(id);
+ ret = nCommand->requestEvent();
+ if (ret != 0) {
+ ALOGE("%s: requestEvent Error:%d",__func__, ret);
+ }
+cleanup:
+ return (wifi_error)ret;
+}
+
+/* Function to send publish cancel to the wifi driver.*/
+wifi_error nan_publish_cancel_request(wifi_request_id id,
+ wifi_handle handle,
+ NanPublishCancelRequest* msg)
+{
+ int ret = 0;
+ NanCommand *nCommand;
+
+ nCommand = NanCommand::instance(handle);
+ if (nCommand == NULL) {
+ ALOGE("%s: Error NanCommand NULL", __func__);
+ return WIFI_ERROR_UNKNOWN;
+ }
+
+ ret = nCommand->putNanPublishCancel(msg);
+ if (ret != 0) {
+ ALOGE("%s: putNanPublishCancel Error:%d",__func__, ret);
+ goto cleanup;
+ }
+ nCommand->setId(id);
+ ret = nCommand->requestEvent();
+ if (ret != 0) {
+ ALOGE("%s: requestEvent Error:%d",__func__, ret);
+ }
+cleanup:
+ return (wifi_error)ret;
+}
+
+/* Function to send Subscribe request to the wifi driver.*/
+wifi_error nan_subscribe_request(wifi_request_id id,
+ wifi_handle handle,
+ NanSubscribeRequest* msg)
+{
+ int ret = 0;
+ NanCommand *nCommand;
+
+ nCommand = NanCommand::instance(handle);
+ if (nCommand == NULL) {
+ ALOGE("%s: Error NanCommand NULL", __func__);
+ return WIFI_ERROR_UNKNOWN;
+ }
+
+ ret = nCommand->putNanSubscribe(msg);
+ if (ret != 0) {
+ ALOGE("%s: putNanSubscribe Error:%d",__func__, ret);
+ goto cleanup;
+ }
+ nCommand->setId(id);
+ ret = nCommand->requestEvent();
+ if (ret != 0) {
+ ALOGE("%s: requestEvent Error:%d",__func__, ret);
+ }
+cleanup:
+ return (wifi_error)ret;
+}
+
+/* Function to cancel subscribe to the wifi driver.*/
+wifi_error nan_subscribe_cancel_request(wifi_request_id id,
+ wifi_handle handle,
+ NanSubscribeCancelRequest* msg)
+{
+ int ret = 0;
+ NanCommand *nCommand;
+
+ nCommand = NanCommand::instance(handle);
+ if (nCommand == NULL) {
+ ALOGE("%s: Error NanCommand NULL", __func__);
+ return WIFI_ERROR_UNKNOWN;
+ }
+
+ ret = nCommand->putNanSubscribeCancel(msg);
+ if (ret != 0) {
+ ALOGE("%s: putNanSubscribeCancel Error:%d",__func__, ret);
+ goto cleanup;
+ }
+ nCommand->setId(id);
+ ret = nCommand->requestEvent();
+ if (ret != 0) {
+ ALOGE("%s: requestEvent Error:%d",__func__, ret);
+ }
+cleanup:
+ return (wifi_error)ret;
+}
+
+/* Function to send NAN follow up request to the wifi driver.*/
+wifi_error nan_transmit_followup_request(wifi_request_id id,
+ wifi_handle handle,
+ NanTransmitFollowupRequest* msg)
+{
+ int ret = 0;
+ NanCommand *nCommand;
+
+ nCommand = NanCommand::instance(handle);
+ if (nCommand == NULL) {
+ ALOGE("%s: Error NanCommand NULL", __func__);
+ return WIFI_ERROR_UNKNOWN;
+ }
+
+ ret = nCommand->putNanTransmitFollowup(msg);
+ if (ret != 0) {
+ ALOGE("%s: putNanTransmitFollowup Error:%d",__func__, ret);
+ goto cleanup;
+ }
+ nCommand->setId(id);
+ ret = nCommand->requestEvent();
+ if (ret != 0) {
+ ALOGE("%s: requestEvent Error:%d",__func__, ret);
+ }
+cleanup:
+ return (wifi_error)ret;
+}
+
+/* Function to send NAN statistics request to the wifi driver.*/
+wifi_error nan_stats_request(wifi_request_id id,
+ wifi_handle handle,
+ NanStatsRequest* msg)
+{
+ int ret = 0;
+ NanCommand *nCommand;
+
+ nCommand = NanCommand::instance(handle);
+ if (nCommand == NULL) {
+ ALOGE("%s: Error NanCommand NULL", __func__);
+ return WIFI_ERROR_UNKNOWN;
+ }
+
+ ret = nCommand->putNanStats(msg);
+ if (ret != 0) {
+ ALOGE("%s: putNanStats Error:%d",__func__, ret);
+ goto cleanup;
+ }
+ nCommand->setId(id);
+ ret = nCommand->requestEvent();
+ if (ret != 0) {
+ ALOGE("%s: requestEvent Error:%d",__func__, ret);
+ }
+cleanup:
+ return (wifi_error)ret;
+}
+
+/* Function to send NAN configuration request to the wifi driver.*/
+wifi_error nan_config_request(wifi_request_id id,
+ wifi_handle handle,
+ NanConfigRequest* msg)
+{
+ int ret = 0;
+ NanCommand *nCommand;
+
+ nCommand = NanCommand::instance(handle);
+ if (nCommand == NULL) {
+ ALOGE("%s: Error NanCommand NULL", __func__);
+ return WIFI_ERROR_UNKNOWN;
+ }
+
+ ret = nCommand->putNanConfig(msg);
+ if (ret != 0) {
+ ALOGE("%s: putNanConfig Error:%d",__func__, ret);
+ goto cleanup;
+ }
+ nCommand->setId(id);
+ ret = nCommand->requestEvent();
+ if (ret != 0) {
+ ALOGE("%s: requestEvent Error:%d",__func__, ret);
+ }
+cleanup:
+ return (wifi_error)ret;
+}
+
+/* Function to send NAN request to the wifi driver.*/
+wifi_error nan_tca_request(wifi_request_id id,
+ wifi_handle handle,
+ NanTCARequest* msg)
+{
+ int ret = 0;
+ NanCommand *nCommand;
+
+ nCommand = NanCommand::instance(handle);
+ if (nCommand == NULL) {
+ ALOGE("%s: Error NanCommand NULL", __func__);
+ return WIFI_ERROR_UNKNOWN;
+ }
+
+ ret = nCommand->putNanTCA(msg);
+ if (ret != 0) {
+ ALOGE("%s: putNanTCA Error:%d",__func__, ret);
+ goto cleanup;
+ }
+ nCommand->setId(id);
+ ret = nCommand->requestEvent();
+ if (ret != 0) {
+ ALOGE("%s: requestEvent Error:%d",__func__, ret);
+ }
+cleanup:
+ return (wifi_error)ret;
+}
+
+/* Function to send NAN Beacon sdf payload to the wifi driver.
+ This instructs the Discovery Engine to begin publishing the
+ received payload in any Beacon or Service Discovery Frame
+ transmitted*/
+wifi_error nan_beacon_sdf_payload_request(wifi_request_id id,
+ wifi_handle handle,
+ NanBeaconSdfPayloadRequest* msg)
+{
+ int ret = WIFI_ERROR_NOT_SUPPORTED;
+#ifdef NAN_2_0
+ NanCommand *nCommand;
+
+ nCommand = NanCommand::instance(handle);
+ if (nCommand == NULL) {
+ ALOGE("%s: Error NanCommand NULL", __func__);
+ return WIFI_ERROR_UNKNOWN;
+ }
+
+ ret = nCommand->putNanBeaconSdfPayload(msg);
+ if (ret != 0) {
+ ALOGE("%s: putNanBeaconSdfPayload Error:%d",__func__, ret);
+ goto cleanup;
+ }
+ nCommand->setId(id);
+ ret = nCommand->requestEvent();
+ if (ret != 0) {
+ ALOGE("%s: requestEvent Error:%d",__func__, ret);
+ }
+#endif /* NAN_2_0 */
+cleanup:
+ return (wifi_error)ret;
+}
+
+wifi_error nan_get_sta_parameter(wifi_request_id id,
+ wifi_handle handle,
+ NanStaParameter* msg)
+{
+ int ret = WIFI_ERROR_NOT_SUPPORTED;
+#ifdef NAN_2_0
+ NanCommand *nCommand;
+
+ nCommand = NanCommand::instance(handle);
+ if (nCommand == NULL) {
+ ALOGE("%s: Error NanCommand NULL", __func__);
+ return WIFI_ERROR_UNKNOWN;
+ }
+
+ nCommand->setId(id);
+ ret = nCommand->getNanStaParameter(msg);
+ if (ret != 0) {
+ ALOGE("%s: getNanStaParameter Error:%d",__func__, ret);
+ goto cleanup;
+ }
+#endif /* NAN_2_0 */
+cleanup:
+ return (wifi_error)ret;
+}
+
+// Implementation related to nan class common functions
+// Constructor
+//Making the constructor private since this class is a singleton
+NanCommand::NanCommand(wifi_handle handle, int id, u32 vendor_id, u32 subcmd)
+ : WifiVendorCommand(handle, id, vendor_id, subcmd)
+{
+ ALOGV("NanCommand %p constructed", this);
+ memset(&mHandler, 0,sizeof(mHandler));
+ mNanVendorEvent = NULL;
+ mNanDataLen = 0;
+ mStaParam = NULL;
+}
+
+NanCommand* NanCommand::instance(wifi_handle handle)
+{
+ if (handle == NULL) {
+ ALOGE("Handle is invalid");
+ return NULL;
+ }
+ if (mNanCommandInstance == NULL) {
+ mNanCommandInstance = new NanCommand(handle, 0,
+ OUI_QCA,
+ QCA_NL80211_VENDOR_SUBCMD_NAN);
+ ALOGV("NanCommand %p created", mNanCommandInstance);
+ return mNanCommandInstance;
+ }
+ else
+ {
+ if (handle != getWifiHandle(mNanCommandInstance->mInfo)) {
+ ALOGE("Handle different");
+ return NULL;
+ }
+ }
+ ALOGV("NanCommand %p created already", mNanCommandInstance);
+ return mNanCommandInstance;
+}
+
+NanCommand::~NanCommand()
+{
+ ALOGV("NanCommand %p destroyed", this);
+ unregisterVendorHandler(mVendor_id, mSubcmd);
+}
+
+// This function implements creation of Vendor command
+// For NAN just call base Vendor command create
+int NanCommand::create() {
+ return (WifiVendorCommand::create());
+}
+
+int NanCommand::handleResponse(WifiEvent reply){
+ ALOGI("skipping a response");
+ return NL_SKIP;
+}
+
+int NanCommand::setCallbackHandler(NanCallbackHandler nHandler)
+{
+ int res = 0;
+ mHandler = nHandler;
+ res = registerVendorHandler(mVendor_id, mSubcmd);
+ if (res != 0) {
+ //error case should not happen print log
+ ALOGE("%s: Unable to register Vendor Handler Vendor Id=0x%x subcmd=%u",
+ __func__, mVendor_id, mSubcmd);
+ }
+ return res;
+}
+
+// This function will be the main handler for incoming event
+// QCA_NL80211_VENDOR_SUBCMD_NAN
+//Call the appropriate callback handler after parsing the vendor data.
+int NanCommand::handleEvent(WifiEvent &event)
+{
+ ALOGI("Got a NAN message from Driver");
+ WifiVendorCommand::handleEvent(event);
+
+ if (mSubcmd == QCA_NL80211_VENDOR_SUBCMD_NAN){
+ // Parse the vendordata and get the NAN attribute
+ struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_MAX + 1];
+ nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_MAX,
+ (struct nlattr *)mVendorData,
+ mDataLen, NULL);
+ // Populating the mNanVendorEvent and mNanDataLen to point to NAN data.
+ mNanVendorEvent = (char *)nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_NAN]);
+ mNanDataLen = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_NAN]);
+
+ if (isNanResponse()) {
+ //handleNanResponse will parse the data and call
+ //the response callback handler with the populated
+ //NanResponseMsg
+ handleNanResponse();
+ }
+ else {
+ //handleNanIndication will parse the data and call
+ //the corresponding Indication callback handler
+ //with the corresponding populated Indication event
+ handleNanIndication();
+ }
+ }
+ else {
+ //error case should not happen print log
+ ALOGE("%s: Wrong NAN subcmd received %d", __func__, mSubcmd);
+ }
+ return NL_SKIP;
+}
+
+/*Helper function to Write and Read TLV called in indication as well as request */
+u16 NANTLV_WriteTlv(pNanTlv pInTlv, u8 *pOutTlv)
+{
+ u16 writeLen = 0;
+ u16 i;
+
+ if (!pInTlv)
+ {
+ ALOGE("NULL pInTlv");
+ return writeLen;
+ }
+
+ if (!pOutTlv)
+ {
+ ALOGE("NULL pOutTlv");
+ return writeLen;
+ }
+
+ *pOutTlv++ = pInTlv->type & 0xFF;
+ *pOutTlv++ = (pInTlv->type & 0xFF00) >> 8;
+ writeLen += 2;
+
+ ALOGV("WRITE TLV type %u, writeLen %u", pInTlv->type, writeLen);
+
+ *pOutTlv++ = pInTlv->length & 0xFF;
+ *pOutTlv++ = (pInTlv->length & 0xFF00) >> 8;
+ writeLen += 2;
+
+ ALOGV("WRITE TLV length %u, writeLen %u", pInTlv->length, writeLen);
+
+ for (i=0; i < pInTlv->length; ++i)
+ {
+ *pOutTlv++ = pInTlv->value[i];
+ }
+
+ writeLen += pInTlv->length;
+ ALOGV("WRITE TLV value, writeLen %u", writeLen);
+ return writeLen;
+}
+
+u16 NANTLV_ReadTlv(u8 *pInTlv, pNanTlv pOutTlv)
+{
+ u16 readLen = 0;
+ u16 tmp = 0;
+
+ if (!pInTlv)
+ {
+ ALOGE("NULL pInTlv");
+ return readLen;
+ }
+
+ if (!pOutTlv)
+ {
+ ALOGE("NULL pOutTlv");
+ return readLen;
+ }
+
+ pOutTlv->type = *pInTlv++;
+ pOutTlv->type |= *pInTlv++ << 8;
+ readLen += 2;
+
+ ALOGV("READ TLV type %u, readLen %u", pOutTlv->type, readLen);
+
+ pOutTlv->length = *pInTlv++;
+ pOutTlv->length |= *pInTlv++ << 8;
+ readLen += 2;
+
+ ALOGV("READ TLV length %u, readLen %u", pOutTlv->length, readLen);
+
+ if (pOutTlv->length)
+ {
+ pOutTlv->value = pInTlv;
+ readLen += pOutTlv->length;
+ }
+ else
+ {
+ pOutTlv->value = NULL;
+ }
+
+ ALOGV("READ TLV value %u, readLen %u", pOutTlv->value, readLen);
+
+ /* Map the right TLV value based on NAN version in Firmware
+ which the framework can understand*/
+ tmp = pOutTlv->type;
+ pOutTlv->type = getNanTlvtypeFromFWTlvtype(pOutTlv->type);
+ ALOGI("%s: FWTlvtype:%d NanTlvtype:%d", __func__,
+ tmp, pOutTlv->type);
+ return readLen;
+}
+
+u8* addTlv(u16 type, u16 length, const u8* value, u8* pOutTlv)
+{
+ NanTlv nanTlv;
+ u16 len;
+ u16 tmp =0;
+
+ /* Set the right TLV based on NAN version in Firmware */
+ tmp = type;
+ type = getFWTlvtypeFromNanTlvtype(type);
+ ALOGI("%s: NanTlvtype:%d FWTlvtype:%d", __func__,
+ tmp, type);
+
+ nanTlv.type = type;
+ nanTlv.length = length;
+ nanTlv.value = (u8*)value;
+
+ len = NANTLV_WriteTlv(&nanTlv, pOutTlv);
+ return (pOutTlv + len);
+}
+
+void NanCommand::setId(int nId)
+{
+ mId = nId;
+}
+
+u16 getNanTlvtypeFromFWTlvtype(u16 fwTlvtype)
+{
+#ifndef NAN_2_0
+ /* In case of Pronto no mapping required */
+ return fwTlvtype;
+#else /* NAN_2_0 */
+ if (fwTlvtype <= NAN_TLV_TYPE_FW_SERVICE_SPECIFIC_INFO) {
+ /* return the TLV value as is */
+ return fwTlvtype;
+ }
+ if (fwTlvtype >= NAN_TLV_TYPE_FW_TCA_LAST) {
+ return fwTlvtype;
+ }
+ /* Other FW TLV values and Config types map it
+ appropriately
+ */
+ switch (fwTlvtype) {
+ case NAN_TLV_TYPE_FW_EXT_SERVICE_SPECIFIC_INFO:
+ return NAN_TLV_TYPE_EXT_SERVICE_SPECIFIC_INFO;
+ case NAN_TLV_TYPE_FW_VENDOR_SPECIFIC_ATTRIBUTE_TRANSMIT:
+ return NAN_TLV_TYPE_VENDOR_SPECIFIC_ATTRIBUTE_TRANSMIT;
+ case NAN_TLV_TYPE_FW_VENDOR_SPECIFIC_ATTRIBUTE_RECEIVE:
+ return NAN_TLV_TYPE_VENDOR_SPECIFIC_ATTRIBUTE_RECEIVE;
+ case NAN_TLV_TYPE_FW_POST_NAN_CONNECTIVITY_CAPABILITIES_RECEIVE:
+ return NAN_TLV_TYPE_POST_NAN_CONNECTIVITY_CAPABILITIES_RECEIVE;
+ case NAN_TLV_TYPE_FW_POST_NAN_DISCOVERY_ATTRIBUTE_RECEIVE:
+ return NAN_TLV_TYPE_POST_NAN_DISCOVERY_ATTRIBUTE_RECEIVE;
+ case NAN_TLV_TYPE_FW_BEACON_SDF_PAYLOAD_RECEIVE:
+ return NAN_TLV_TYPE_BEACON_SDF_PAYLOAD_RECEIVE;
+
+ case NAN_TLV_TYPE_FW_24G_SUPPORT:
+ return NAN_TLV_TYPE_2DOT4G_SUPPORT;
+ case NAN_TLV_TYPE_FW_24G_BEACON:
+ return NAN_TLV_TYPE_2DOT4G_BEACONS;
+ case NAN_TLV_TYPE_FW_24G_SDF:
+ return NAN_TLV_TYPE_2DOT4G_SDF;
+ case NAN_TLV_TYPE_FW_24G_RSSI_CLOSE:
+ return NAN_TLV_TYPE_RSSI_CLOSE;
+ case NAN_TLV_TYPE_FW_24G_RSSI_MIDDLE:
+ return NAN_TLV_TYPE_RSSI_MEDIUM;
+ case NAN_TLV_TYPE_FW_24G_RSSI_CLOSE_PROXIMITY:
+ return NAN_TLV_TYPE_RSSI_CLOSE_PROXIMITY;
+ case NAN_TLV_TYPE_FW_5G_SUPPORT:
+ return NAN_TLV_TYPE_5G_SUPPORT;
+ case NAN_TLV_TYPE_FW_5G_BEACON:
+ return NAN_TLV_TYPE_5G_BEACON;
+ case NAN_TLV_TYPE_FW_5G_SDF:
+ return NAN_TLV_TYPE_5G_SDF;
+ case NAN_TLV_TYPE_FW_5G_RSSI_CLOSE:
+ return NAN_TLV_TYPE_5G_RSSI_CLOSE;
+ case NAN_TLV_TYPE_FW_5G_RSSI_MIDDLE:
+ return NAN_TLV_TYPE_5G_RSSI_MEDIUM;
+ case NAN_TLV_TYPE_FW_5G_RSSI_CLOSE_PROXIMITY:
+ return NAN_TLV_TYPE_5G_RSSI_CLOSE_PROXIMITY;
+ case NAN_TLV_TYPE_FW_SID_BEACON:
+ return NAN_TLV_TYPE_SID_BEACON;
+ case NAN_TLV_TYPE_FW_HOP_COUNT_LIMIT:
+ return NAN_TLV_TYPE_HOP_COUNT_LIMIT;
+ case NAN_TLV_TYPE_FW_MASTER_PREFERENCE:
+ return NAN_TLV_TYPE_MASTER_PREFERENCE;
+ case NAN_TLV_TYPE_FW_CLUSTER_ID_LOW:
+ return NAN_TLV_TYPE_CLUSTER_ID_LOW;
+ case NAN_TLV_TYPE_FW_CLUSTER_ID_HIGH:
+ return NAN_TLV_TYPE_CLUSTER_ID_HIGH;
+ case NAN_TLV_TYPE_FW_RSSI_AVERAGING_WINDOW_SIZE:
+ return NAN_TLV_TYPE_RSSI_AVERAGING_WINDOW_SIZE;
+ case NAN_TLV_TYPE_FW_CLUSTER_OUI_NETWORK_ID:
+ return NAN_TLV_TYPE_CLUSTER_OUI_NETWORK_ID;
+ case NAN_TLV_TYPE_FW_SOURCE_MAC_ADDRESS:
+ return NAN_TLV_TYPE_SOURCE_MAC_ADDRESS;
+ case NAN_TLV_TYPE_FW_CLUSTER_ATTRIBUTE_IN_SDF:
+ return NAN_TLV_TYPE_CLUSTER_ATTRIBUTE_IN_SDF;
+ case NAN_TLV_TYPE_FW_SOCIAL_CHANNEL_SCAN_PARAMS:
+ return NAN_TLV_TYPE_SOCIAL_CHANNEL_SCAN_PARAMETERS;
+ case NAN_TLV_TYPE_FW_DEBUGGING_FLAGS:
+ return NAN_TLV_TYPE_DEBUGGING_FLAGS;
+ case NAN_TLV_TYPE_FW_POST_NAN_CONNECTIVITY_CAPABILITIES_TRANSMIT:
+ return NAN_TLV_TYPE_POST_NAN_CONNECTIVITY_CAPABILITIES_TRANSMIT;
+ case NAN_TLV_TYPE_FW_POST_NAN_DISCOVERY_ATTRIBUTE_TRANSMIT:
+ return NAN_TLV_TYPE_POST_NAN_DISCOVERY_ATTRIBUTE_TRANSMIT;
+ case NAN_TLV_TYPE_FW_FURTHER_AVAILABILITY_MAP:
+ return NAN_TLV_TYPE_FURTHER_AVAILABILITY_MAP;
+ case NAN_TLV_TYPE_FW_HOP_COUNT_FORCE:
+ return NAN_TLV_TYPE_HOP_COUNT_FORCE;
+ case NAN_TLV_TYPE_FW_RANDOM_FACTOR_FORCE:
+ return NAN_TLV_TYPE_RANDOM_FACTOR_FORCE;
+
+ /* Attrib types */
+ /* Unmapped attrib types */
+ case NAN_TLV_TYPE_FW_AVAILABILITY_INTERVALS_MAP:
+ break;
+ case NAN_TLV_TYPE_FW_WLAN_MESH_ID:
+ return NAN_TLV_TYPE_WLAN_MESH_ID;
+ case NAN_TLV_TYPE_FW_MAC_ADDRESS:
+ return NAN_TLV_TYPE_MAC_ADDRESS;
+ case NAN_TLV_TYPE_FW_RECEIVED_RSSI_VALUE:
+ return NAN_TLV_TYPE_RECEIVED_RSSI_VALUE;
+ case NAN_TLV_TYPE_FW_CLUSTER_ATTRIBUTE:
+ return NAN_TLV_TYPE_CLUSTER_ATTIBUTE;
+ case NAN_TLV_TYPE_FW_WLAN_INFRASTRUCTURE_SSID:
+ return NAN_TLV_TYPE_WLAN_INFRASTRUCTURE_SSID;
+
+ /* Events Type */
+ case NAN_TLV_TYPE_FW_EVENT_SELF_STATION_MAC_ADDRESS:
+ return NAN_EVENT_ID_STA_MAC_ADDR;
+ case NAN_TLV_TYPE_FW_EVENT_STARTED_CLUSTER:
+ return NAN_EVENT_ID_STARTED_CLUSTER;
+ case NAN_TLV_TYPE_FW_EVENT_JOINED_CLUSTER:
+ return NAN_EVENT_ID_JOINED_CLUSTER;
+ /* unmapped Event Type */
+ case NAN_TLV_TYPE_FW_EVENT_CLUSTER_SCAN_RESULTS:
+ break;
+
+ case NAN_TLV_TYPE_FW_TCA_CLUSTER_SIZE_REQ:
+ case NAN_TLV_TYPE_FW_TCA_CLUSTER_SIZE_RSP:
+ return NAN_TCA_ID_CLUSTER_SIZE;
+
+ default:
+ break;
+ }
+ ALOGE("%s: Unhandled FW TLV value:%d", __func__, fwTlvtype);
+ return 0xFFFF;
+#endif /*NAN_2_0*/
+}
+
+u16 getFWTlvtypeFromNanTlvtype(u16 nanTlvtype)
+{
+#ifndef NAN_2_0
+ /* In case of Pronto no mapping required */
+ return nanTlvtype;
+#else /* NAN_2_0 */
+ if (nanTlvtype <= NAN_TLV_TYPE_SERVICE_SPECIFIC_INFO) {
+ /* return the TLV value as is */
+ return nanTlvtype;
+ }
+ if (nanTlvtype >= NAN_TLV_TYPE_STATS_FIRST &&
+ nanTlvtype <= NAN_TLV_TYPE_STATS_LAST) {
+ return nanTlvtype;
+ }
+ /* Other NAN TLV values and Config types map it
+ appropriately
+ */
+ switch (nanTlvtype) {
+ case NAN_TLV_TYPE_EXT_SERVICE_SPECIFIC_INFO:
+ return NAN_TLV_TYPE_FW_EXT_SERVICE_SPECIFIC_INFO;
+ case NAN_TLV_TYPE_SDF_LAST:
+ return NAN_TLV_TYPE_FW_SDF_LAST;
+
+ /* Configuration types */
+ case NAN_TLV_TYPE_5G_SUPPORT:
+ return NAN_TLV_TYPE_FW_5G_SUPPORT;
+ case NAN_TLV_TYPE_SID_BEACON:
+ return NAN_TLV_TYPE_FW_SID_BEACON;
+ case NAN_TLV_TYPE_5G_SYNC_DISC:
+ break;
+ case NAN_TLV_TYPE_RSSI_CLOSE:
+ return NAN_TLV_TYPE_FW_24G_RSSI_CLOSE;
+ case NAN_TLV_TYPE_RSSI_MEDIUM:
+ return NAN_TLV_TYPE_FW_24G_RSSI_MIDDLE;
+ case NAN_TLV_TYPE_HOP_COUNT_LIMIT:
+ return NAN_TLV_TYPE_FW_HOP_COUNT_LIMIT;
+ /* unmapped */
+ case NAN_TLV_TYPE_RANDOM_UPDATE_TIME:
+ break;
+ case NAN_TLV_TYPE_MASTER_PREFERENCE:
+ return NAN_TLV_TYPE_FW_MASTER_PREFERENCE;
+ /* unmapped */
+ case NAN_TLV_TYPE_EARLY_WAKEUP:
+ break;
+ case NAN_TLV_TYPE_PERIODIC_SCAN_INTERVAL:
+ break;
+ case NAN_TLV_TYPE_CLUSTER_ID_LOW:
+ return NAN_TLV_TYPE_FW_CLUSTER_ID_LOW;
+ case NAN_TLV_TYPE_CLUSTER_ID_HIGH:
+ return NAN_TLV_TYPE_FW_CLUSTER_ID_HIGH;
+ case NAN_TLV_TYPE_RSSI_CLOSE_PROXIMITY:
+ return NAN_TLV_TYPE_FW_24G_RSSI_CLOSE_PROXIMITY;
+ case NAN_TLV_TYPE_CONFIG_LAST:
+ return NAN_TLV_TYPE_FW_CONFIG_LAST;
+ case NAN_TLV_TYPE_FURTHER_AVAILABILITY:
+ break;
+
+ /* All Stats type are unmapped as of now */
+
+ /* Attributes types */
+ case NAN_TLV_TYPE_WLAN_MESH_ID:
+ return NAN_TLV_TYPE_FW_WLAN_MESH_ID;
+ case NAN_TLV_TYPE_MAC_ADDRESS:
+ return NAN_TLV_TYPE_FW_MAC_ADDRESS;
+ case NAN_TLV_TYPE_RECEIVED_RSSI_VALUE:
+ return NAN_TLV_TYPE_FW_RECEIVED_RSSI_VALUE;
+ case NAN_TLV_TYPE_TCA_CLUSTER_SIZE_REQ:
+ return NAN_TLV_TYPE_FW_TCA_CLUSTER_SIZE_REQ;
+ case NAN_TLV_TYPE_ATTRS_LAST:
+ return NAN_TLV_TYPE_FW_ATTRS_LAST;
+
+ case NAN_TLV_TYPE_VENDOR_SPECIFIC_ATTRIBUTE_TRANSMIT:
+ return NAN_TLV_TYPE_FW_VENDOR_SPECIFIC_ATTRIBUTE_TRANSMIT;
+ case NAN_TLV_TYPE_VENDOR_SPECIFIC_ATTRIBUTE_RECEIVE:
+ return NAN_TLV_TYPE_FW_VENDOR_SPECIFIC_ATTRIBUTE_RECEIVE;
+ case NAN_TLV_TYPE_POST_NAN_CONNECTIVITY_CAPABILITIES_TRANSMIT:
+ return NAN_TLV_TYPE_FW_POST_NAN_CONNECTIVITY_CAPABILITIES_TRANSMIT;
+ case NAN_TLV_TYPE_POST_NAN_CONNECTIVITY_CAPABILITIES_RECEIVE:
+ return NAN_TLV_TYPE_FW_POST_NAN_CONNECTIVITY_CAPABILITIES_RECEIVE;
+ case NAN_TLV_TYPE_POST_NAN_DISCOVERY_ATTRIBUTE_TRANSMIT:
+ return NAN_TLV_TYPE_FW_POST_NAN_DISCOVERY_ATTRIBUTE_TRANSMIT;
+ case NAN_TLV_TYPE_POST_NAN_DISCOVERY_ATTRIBUTE_RECEIVE:
+ return NAN_TLV_TYPE_FW_POST_NAN_DISCOVERY_ATTRIBUTE_RECEIVE;
+ case NAN_TLV_TYPE_FURTHER_AVAILABILITY_MAP:
+ return NAN_TLV_TYPE_FW_FURTHER_AVAILABILITY_MAP;
+ case NAN_TLV_TYPE_BEACON_SDF_PAYLOAD_RECEIVE:
+ return NAN_TLV_TYPE_FW_BEACON_SDF_PAYLOAD_RECEIVE;
+
+ case NAN_TLV_TYPE_2DOT4G_SUPPORT:
+ return NAN_TLV_TYPE_FW_24G_SUPPORT;
+ case NAN_TLV_TYPE_2DOT4G_BEACONS:
+ return NAN_TLV_TYPE_FW_24G_BEACON;
+ case NAN_TLV_TYPE_2DOT4G_SDF:
+ return NAN_TLV_TYPE_FW_24G_SDF;
+ case NAN_TLV_TYPE_5G_BEACON:
+ return NAN_TLV_TYPE_FW_5G_BEACON;
+ case NAN_TLV_TYPE_5G_SDF:
+ return NAN_TLV_TYPE_FW_5G_SDF;
+ case NAN_TLV_TYPE_5G_RSSI_CLOSE:
+ return NAN_TLV_TYPE_FW_5G_RSSI_CLOSE;
+ case NAN_TLV_TYPE_5G_RSSI_MEDIUM:
+ return NAN_TLV_TYPE_FW_5G_RSSI_MIDDLE;
+ case NAN_TLV_TYPE_5G_RSSI_CLOSE_PROXIMITY:
+ return NAN_TLV_TYPE_FW_5G_RSSI_CLOSE_PROXIMITY;
+ case NAN_TLV_TYPE_RSSI_AVERAGING_WINDOW_SIZE:
+ return NAN_TLV_TYPE_FW_RSSI_AVERAGING_WINDOW_SIZE;
+ case NAN_TLV_TYPE_CLUSTER_OUI_NETWORK_ID:
+ return NAN_TLV_TYPE_FW_CLUSTER_OUI_NETWORK_ID;
+ case NAN_TLV_TYPE_SOURCE_MAC_ADDRESS:
+ return NAN_TLV_TYPE_FW_SOURCE_MAC_ADDRESS;
+ case NAN_TLV_TYPE_CLUSTER_ATTRIBUTE_IN_SDF:
+ return NAN_TLV_TYPE_FW_CLUSTER_ATTRIBUTE_IN_SDF;
+ case NAN_TLV_TYPE_SOCIAL_CHANNEL_SCAN_PARAMETERS:
+ return NAN_TLV_TYPE_FW_SOCIAL_CHANNEL_SCAN_PARAMS;
+ case NAN_TLV_TYPE_DEBUGGING_FLAGS:
+ return NAN_TLV_TYPE_FW_DEBUGGING_FLAGS;
+ case NAN_TLV_TYPE_WLAN_INFRASTRUCTURE_SSID:
+ return NAN_TLV_TYPE_FW_WLAN_INFRASTRUCTURE_SSID;
+ case NAN_TLV_TYPE_RANDOM_FACTOR_FORCE:
+ return NAN_TLV_TYPE_FW_RANDOM_FACTOR_FORCE;
+ case NAN_TLV_TYPE_HOP_COUNT_FORCE:
+ return NAN_TLV_TYPE_FW_HOP_COUNT_FORCE;
+
+
+ default:
+ break;
+ }
+ ALOGE("%s: Unhandled NAN TLV value:%d", __func__, nanTlvtype);
+ return 0xFFFF;
+#endif /* NAN_2_0 */
+}
diff --git a/qcwcn/wifi_hal/nan.h b/qcwcn/wifi_hal/nan.h
new file mode 100644
index 0000000..324d630
--- /dev/null
+++ b/qcwcn/wifi_hal/nan.h
@@ -0,0 +1,1764 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __NAN_H__
+#define __NAN_H__
+
+#include "wifi_hal.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+/*****************************************************************************
+ * Neighbour Aware Network Service Structures and Functions
+ *****************************************************************************/
+
+#ifndef PACKED
+#define PACKED __attribute__((packed))
+#endif
+
+/*
+ Definitions
+ All multi-byte fields within all NAN protocol stack messages are assumed to be in Little Endian order.
+*/
+
+typedef int NanVersion;
+
+#define NAN_MAC_ADDR_LEN 6
+#define NAN_COUNTRY_STRING_LEN 3
+#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 */
+#define NAN_MAX_SERVICE_NAME_LEN 255
+#define NAN_MAX_MATCH_FILTER_LEN 255
+#define NAN_MAX_SERVICE_SPECIFIC_INFO_LEN 1024
+#define NAN_MAX_VSA_DATA_LEN 1024
+#define NAN_MAX_MESH_DATA_LEN 32
+#define NAN_MAX_CLUSTER_ATTRIBUTE_LEN 255
+#define NAN_MAX_SUBSCRIBE_MAX_ADDRESS 42
+
+/*
+ Definition of various NanRequestType
+*/
+typedef enum {
+ NAN_REQUEST_ENABLE =0,
+ NAN_REQUEST_DISABLE =1,
+ NAN_REQUEST_PUBLISH =2,
+ NAN_REQUEST_PUBLISH_CANCEL =3,
+ NAN_REQUEST_TRANSMIT_FOLLOWUP =4,
+ NAN_REQUEST_SUBSCRIBE =5,
+ NAN_REQUEST_SUBSCRIBE_CANCEL =6,
+ NAN_REQUEST_STATS =7,
+ NAN_REQUEST_CONFIG =8,
+ NAN_REQUEST_TCA =9,
+ NAN_REQUEST_BEACON_SDF_PAYLOAD =10,
+ NAN_REQUEST_LAST =0xFFFF
+} NanRequestType;
+
+/*
+ Definition of various NanResponseType
+*/
+typedef enum {
+ NAN_RESPONSE_ENABLED =0,
+ NAN_RESPONSE_DISABLED =1,
+ NAN_RESPONSE_PUBLISH =2,
+ NAN_RESPONSE_PUBLISH_CANCEL =3,
+ NAN_RESPONSE_TRANSMIT_FOLLOWUP =4,
+ NAN_RESPONSE_SUBSCRIBE =5,
+ NAN_RESPONSE_SUBSCRIBE_CANCEL =6,
+ NAN_RESPONSE_STATS =7,
+ NAN_RESPONSE_CONFIG =8,
+ NAN_RESPONSE_TCA =9,
+ NAN_RESPONSE_ERROR =10,
+ NAN_RESPONSE_BEACON_SDF_PAYLOAD =11,
+ NAN_RESPONSE_UNKNOWN =0xFFFF
+} NanResponseType;
+
+/*
+ Definition of various NanIndication(events)
+*/
+typedef enum {
+ NAN_INDICATION_PUBLISH_REPLIED =0,
+ NAN_INDICATION_PUBLISH_TERMINATED =1,
+ NAN_INDICATION_MATCH =2,
+ NAN_INDICATION_UNMATCH =3,
+ NAN_INDICATION_SUBSCRIBE_TERMINATED =4,
+ NAN_INDICATION_DE_EVENT =5,
+ NAN_INDICATION_FOLLOWUP =6,
+ NAN_INDICATION_DISABLED =7,
+ NAN_INDICATION_TCA =8,
+ NAN_INDICATION_BEACON_SDF_PAYLOAD =9,
+ NAN_INDICATION_UNKNOWN =0xFFFF
+} NanIndicationType;
+
+
+/* NAN Publish Types */
+typedef enum {
+ NAN_PUBLISH_TYPE_UNSOLICITED = 0,
+ NAN_PUBLISH_TYPE_SOLICITED,
+ NAN_PUBLISH_TYPE_UNSOLICITED_SOLICITED,
+ NAN_PUBLISH_TYPE_LAST,
+} NanPublishType;
+
+/* NAN Transmit Priorities */
+typedef enum {
+ NAN_TX_PRIORITY_LOW = 0,
+ NAN_TX_PRIORITY_NORMAL,
+ NAN_TX_PRIORITY_HIGH,
+ NAN_TX_PRIORITY_LAST
+} NanTxPriority;
+
+/* NAN Statistics Request ID Codes */
+typedef enum
+{
+ NAN_STATS_ID_FIRST = 0,
+ NAN_STATS_ID_DE_PUBLISH = NAN_STATS_ID_FIRST,
+ NAN_STATS_ID_DE_SUBSCRIBE,
+ NAN_STATS_ID_DE_MAC,
+ NAN_STATS_ID_DE_TIMING_SYNC,
+ NAN_STATS_ID_DE_DW,
+ NAN_STATS_ID_DE,
+ NAN_STATS_ID_LAST
+} NanStatsId;
+
+/* NAN Protocol Event ID Codes */
+typedef enum
+{
+ NAN_EVENT_ID_FIRST = 0,
+ NAN_EVENT_ID_STA_MAC_ADDR = NAN_EVENT_ID_FIRST,
+ NAN_EVENT_ID_STARTED_CLUSTER,
+ NAN_EVENT_ID_JOINED_CLUSTER,
+ NAN_EVENT_ID_LAST
+} NanEventId;
+
+/* TCA IDs */
+typedef enum
+{
+ NAN_TCA_ID_FIRST = 0,
+ NAN_TCA_ID_CLUSTER_SIZE = NAN_TCA_ID_FIRST,
+ NAN_TCA_ID_LAST
+} NanTcaId;
+
+/*
+ Various NAN Protocol Response code
+*/
+#ifndef NAN_2_0
+typedef enum
+{
+ /* NAN Protocol Response Codes */
+ NAN_STATUS_SUCCESS = 0,
+ NAN_STATUS_TIMEOUT,
+ NAN_STATUS_DE_FAILURE,
+ NAN_STATUS_INVALID_MSG_VERSION,
+ NAN_STATUS_INVALID_MSG_LEN,
+ NAN_STATUS_INVALID_MSG_ID,
+ NAN_STATUS_INVALID_HANDLE,
+ NAN_STATUS_NO_SPACE_AVAILABLE,
+ NAN_STATUS_INVALID_PUBLISH_TYPE,
+ NAN_STATUS_INVALID_TX_TYPE,
+ NAN_STATUS_INVALID_MATCH_ALGORITHM,
+ NAN_STATUS_DISABLE_IN_PROGRESS,
+ NAN_STATUS_INVALID_TLV_LEN,
+ NAN_STATUS_INVALID_TLV_TYPE,
+ NAN_STATUS_MISSING_TLV_TYPE,
+ NAN_STATUS_INVALID_TOTAL_TLVS_LEN,
+ NAN_STATUS_INVALID_MATCH_HANDLE,
+ NAN_STATUS_INVALID_TLV_VALUE,
+ NAN_STATUS_INVALID_TX_PRIORITY,
+ NAN_STATUS_INVALID_TCA_ID,
+ NAN_STATUS_INVALID_STATS_ID,
+
+ /* NAN Configuration Response codes */
+ NAN_STATUS_INVALID_RSSI_CLOSE_VALUE = 128,
+ NAN_STATUS_INVALID_RSSI_MEDIUM_VALUE,
+ NAN_STATUS_INVALID_HOP_COUNT_LIMIT,
+ NAN_STATUS_INVALID_CLUSTER_JOIN_COUNT,
+ NAN_STATUS_INVALID_MIN_WAKE_DW_DURATION_VALUE,
+ NAN_STATUS_INVALID_OFDM_DATA_RATE_VALUE,
+ NAN_STATUS_INVALID_RANDOM_FACTOR_UPDATE_TIME_VALUE,
+ NAN_STATUS_INVALID_MASTER_PREFERENCE_VALUE,
+ NAN_STATUS_INVALID_EARLY_DW_WAKE_INTERVAL_VALUE,
+ NAN_STATUS_INVALID_LOW_CLUSTER_ID_VALUE,
+ NAN_STATUS_INVALID_HIGH_CLUSTER_ID_VALUE,
+ NAN_STATUS_INVALID_INITIAL_SCAN_PERIOD,
+ NAN_STATUS_INVALID_ONGOING_SCAN_PERIOD,
+ NAN_STATUS_INVALID_RSSI_PROXIMITY_VALUE,
+ NAN_STATUS_INVALID_BACKGROUND_SCAN_PERIOD,
+ NAN_STATUS_INVALID_SCAN_CHANNEL
+} NanStatusType;
+#else /* NAN_2_0 */
+typedef enum
+{
+ /* NAN Protocol Response Codes */
+ NAN_STATUS_SUCCESS = 0,
+ NAN_STATUS_TIMEOUT = 1,
+ NAN_STATUS_DE_FAILURE = 2,
+ NAN_STATUS_INVALID_MSG_VERSION = 3,
+ NAN_STATUS_INVALID_MSG_LEN = 4,
+ NAN_STATUS_INVALID_MSG_ID = 5,
+ NAN_STATUS_INVALID_HANDLE = 6,
+ NAN_STATUS_NO_SPACE_AVAILABLE = 7,
+ NAN_STATUS_INVALID_PUBLISH_TYPE = 8,
+ NAN_STATUS_INVALID_TX_TYPE = 9,
+ NAN_STATUS_INVALID_MATCH_ALGORITHM = 10,
+ NAN_STATUS_DISABLE_IN_PROGRESS = 11,
+ NAN_STATUS_INVALID_TLV_LEN = 12,
+ NAN_STATUS_INVALID_TLV_TYPE = 13,
+ NAN_STATUS_MISSING_TLV_TYPE = 14,
+ NAN_STATUS_INVALID_TOTAL_TLVS_LEN = 15,
+ NAN_STATUS_INVALID_MATCH_HANDLE= 16,
+ NAN_STATUS_INVALID_TLV_VALUE = 17,
+ NAN_STATUS_INVALID_TX_PRIORITY = 18,
+ NAN_STATUS_INVALID_CONNECTION_MAP = 19,
+ /* 20-4095 Reserved */
+
+ /* NAN Configuration Response codes */
+ NAN_STATUS_INVALID_RSSI_CLOSE_VALUE = 4096,
+ NAN_STATUS_INVALID_RSSI_MIDDLE_VALUE = 4097,
+ NAN_STATUS_INVALID_HOP_COUNT_LIMIT = 4098,
+ NAN_STATUS_INVALID_MASTER_PREFERENCE_VALUE = 4099,
+ NAN_STATUS_INVALID_LOW_CLUSTER_ID_VALUE = 4100,
+ NAN_STATUS_INVALID_HIGH_CLUSTER_ID_VALUE = 4101,
+ NAN_STATUS_INVALID_BACKGROUND_SCAN_PERIOD = 4102,
+ NAN_STATUS_INVALID_RSSI_PROXIMITY_VALUE = 4103,
+ NAN_STATUS_INVALID_SCAN_CHANNEL = 4104,
+ NAN_STATUS_INVALID_POST_NAN_CONNECTIVITY_CAPABILITIES_BITMAP = 4105,
+ NAN_STATUS_INVALID_FURTHER_AVAILABILITY_MAP_NUMCHAN_VALUE = 4106,
+ NAN_STATUS_INVALID_FURTHER_AVAILABILITY_MAP_DURATION_VALUE = 4107,
+ NAN_STATUS_INVALID_FURTHER_AVAILABILITY_MAP_CLASS_VALUE = 4108,
+ NAN_STATUS_INVALID_FURTHER_AVAILABILITY_MAP_CHANNEL_VALUE = 4109,
+ NAN_STATUS_INVALID_FURTHER_AVAILABILITY_MAP_AVAILABILITY_INTERVAL_BITMAP_VALUE = 4110,
+ NAN_STATUS_INVALID_FURTHER_AVAILABILITY_MAP_MAP_ID = 4111,
+ NAN_STATUS_INVALID_POST_NAN_DISCOVERY_CONN_TYPE_VALUE = 4112,
+ NAN_STATUS_INVALID_POST_NAN_DISCOVERY_DEVICE_ROLE_VALUE = 4113,
+ NAN_STATUS_INVALID_POST_NAN_DISCOVERY_DURATION_VALUE = 4114,
+ NAN_STATUS_INVALID_POST_NAN_DISCOVERY_BITMAP_VALUE = 4115,
+ NAN_STATUS_MISSING_FUTHER_AVAILABILITY_MAP = 4116,
+ NAN_STATUS_INVALID_BAND_CONFIG_FLAGS = 4117,
+ /* 4118 RESERVED */
+} NanStatusType;
+#endif /* NAN_2_0 */
+/*
+ Various NAN Terminated Indication Code
+*/
+typedef enum
+{
+ NAN_TERMINATED_REASON_INVALID = 0,
+ NAN_TERMINATED_REASON_TIMEOUT,
+ NAN_TERMINATED_REASON_USER_REQUEST,
+ NAN_TERMINATED_REASON_FAILURE,
+ NAN_TERMINATED_REASON_COUNT_REACHED,
+ NAN_TERMINATED_REASON_DE_SHUTDOWN,
+ NAN_TERMINATED_REASON_DISABLE_IN_PROGRESS,
+ NAN_TERMINATED_REASON_POST_DISC_ATTR_EXPIRED,
+ NAN_TERMINATED_REASON_POST_DISC_LEN_EXCEEDED,
+ NAN_TERMINATED_REASON_FURTHER_AVAIL_MAP_EMPTY
+} NanTerminatedStatus;
+
+/* NAN Transmit Types */
+typedef enum
+{
+ NAN_TX_TYPE_BROADCAST = 0,
+ NAN_TX_TYPE_UNICAST,
+ NAN_TX_TYPE_LAST
+} NanTxType;
+
+/* NAN Subscribe Type Bit */
+#define NAN_SUBSCRIBE_TYPE_PASSIVE 0
+#define NAN_SUBSCRIBE_TYPE_ACTIVE 1
+
+/* NAN Service Response Filter Attribute Bit */
+#define NAN_SRF_ATTR_BLOOM_FILTER 0
+#define NAN_SRF_ATTR_PARTIAL_MAC_ADDR 1
+
+/* NAN Service Response Filter Include Bit */
+#define NAN_SRF_INCLUDE_DO_NOT_RESPOND 0
+#define NAN_SRF_INCLUDE_RESPOND 1
+
+/* NAN Match Algorithms */
+typedef enum
+{
+ NAN_MATCH_ALG_FIRST = 0,
+ NAN_MATCH_ALG_MATCH_ONCE = NAN_MATCH_ALG_FIRST,
+ NAN_MATCH_ALG_MATCH_CONTINUOUS,
+ NAN_MATCH_ALG_MATCH_NEVER,
+ NAN_MATCH_ALG_LAST
+} NanMatchAlg;
+
+/* NAN Header */
+typedef struct {
+ /*
+ 16-bit quantity which is allocated by the FW.
+ Pass the Handle as 0xFFFF if the Host would like to set up a new
+ Publish/Subscribe and the FW will pass back a valid handle in response msg.
+ To update an already opened Publish/Subscribe Host can pass a Handle
+ which has already been allocated by the FW.
+ */
+ u16 handle;
+
+ /*
+ 16-bit quantity which is allocated in 2 contexts. For all Request
+ messages the TransactionId is allocated by the Service Layer and
+ passed down to the DE. In all Indication messages the TransactionId
+ field is allocated by the DE. There is no correlation between the
+ TransactionIds allocated by the Service Layer and those allocated by the DE
+ */
+ u16 transaction_id;
+} NanHeader;
+
+/*
+ Host can send Vendor specific attributes which the Discovery Engine can
+ enclose in Beacons and/or Service Discovery frames transmitted.
+ Below structure is used to populate that.
+*/
+typedef struct {
+ /*
+ 0 = transmit only in the next discovery window
+ 1 = transmit in next 16 discovery window
+ */
+ u8 payload_transmit_flag;
+ /*
+ Below flags will determine in which all frames
+ the vendor specific attributes should be included
+ */
+ u8 tx_in_discovery_beacon;
+ u8 tx_in_sync_beacon;
+ u8 tx_in_service_discovery;
+ /* Organizationally Unique Identifier */
+ u32 vendor_oui;
+ /*
+ vendor specific attribute to be transmitted
+ vsa_len : Length of the vsa data.
+ */
+ u32 vsa_len;
+ u8 vsa[NAN_MAX_VSA_DATA_LEN];
+} NanTransmitVendorSpecificAttribute;
+
+
+/*
+ Discovery Engine will forward any Vendor Specific Attributes
+ which it received as part of this structure.
+*/
+/* Mask to determine on which frames attribute was received */
+#define RX_DISCOVERY_BEACON_MASK 0x00
+#define RX_SYNC_BEACON_MASK 0x01
+#define RX_SERVICE_DISCOVERY_MASK 0x02
+typedef struct {
+ /*
+ Frames on which this vendor specific attribute
+ was received. Mask defined above
+ */
+ u8 vsa_received_on;
+ /* Organizationally Unique Identifier */
+ u32 vendor_oui;
+ /* vendor specific attribute */
+ u32 attr_len;
+ u8 vsa[NAN_MAX_VSA_DATA_LEN];
+} NanReceiveVendorSpecificAttribute;
+
+/* Discovery engine cluster state*/
+typedef enum {
+ NAN_NORMAL_OPERATION = 0,
+ NAN_NON_MASTER_NON_SYNC = 1,
+ NAN_NON_MASTER_SYNC = 2,
+ NAN_MASTER = 3,
+ NAN_ANCHOR_MASTER = 4
+} NanDebugDEClusterState;
+
+/*
+ NAN Beacon SDF Payload Received structure
+ Discovery engine sends the details of received Beacon or
+ Service Discovery Frames as part of this structure.
+*/
+typedef struct {
+ /* Frame data */
+ u32 frame_len;
+ u8 frame_data[NAN_MAX_VSA_DATA_LEN];
+} NanBeaconSdfPayloadReceive;
+
+/*
+ Host can set the Periodic scan parameters for each of the
+ 3(6, 44, 149) Social channels. Only these channels are allowed
+ any other channels are rejected
+*/
+#define MAX_SOCIAL_CHANNELS 3
+typedef enum
+{
+ NAN_CHANNEL_6 = 0,
+ NAN_CHANNEL_44 = 1,
+ NAN_CHANNEL_149 = 2
+} NanChannelIndex;
+
+/*
+ Structure to set the Social Channel Scan parameters
+ passed as part of NanEnableRequest/NanConfigRequest
+*/
+typedef struct {
+ /*
+ Dwell time of each social channel in milliseconds
+ NanChannelIndex corresponds to the respective channel
+ If time set to 0 then the FW default time will be used.
+ */
+ u8 dwell_time[MAX_SOCIAL_CHANNELS];
+
+ /*
+ Scan period of each social channel in seconds
+ NanChannelIndex corresponds to the respective channel
+ If time set to 0 then the FW default time will be used.
+ */
+ u16 scan_period[MAX_SOCIAL_CHANNELS];
+} NanSocialChannelScanParams;
+
+/*
+ Host can send Post Connectivity Capability attributes
+ to be included in Service Discovery frames transmitted
+ as part of this structure.
+*/
+typedef struct {
+ /*
+ 0 = transmit only in the next discovery window
+ 1 = transmit in next 16 discovery window
+ */
+ u8 payload_transmit_flag;
+ /* 1 - Wifi Direct supported 0 - Not supported */
+ u8 is_wfd_supported;
+ /* 1 - Wifi Direct Services supported 0 - Not supported */
+ u8 is_wfds_supported;
+ /* 1 - TDLS supported 0 - Not supported */
+ u8 is_tdls_supported;
+ /* 1 - IBSS supported 0 - Not supported */
+ u8 is_ibss_supported;
+ /* 1 - Mesh supported 0 - Not supported */
+ u8 is_mesh_supported;
+ /*
+ 1 - NAN Device currently connect to WLAN Infra AP
+ 0 - otherwise
+ */
+ u8 wlan_infra_field;
+} NanTransmitPostConnectivityCapability;
+
+/*
+ Discovery engine providing the post connectivity capability
+ received.
+*/
+typedef struct {
+ /* 1 - Wifi Direct supported 0 - Not supported */
+ u8 is_wfd_supported;
+ /* 1 - Wifi Direct Services supported 0 - Not supported */
+ u8 is_wfds_supported;
+ /* 1 - TDLS supported 0 - Not supported */
+ u8 is_tdls_supported;
+ /* 1 - IBSS supported 0 - Not supported */
+ u8 is_ibss_supported;
+ /* 1 - Mesh supported 0 - Not supported */
+ u8 is_mesh_supported;
+ /*
+ 1 - NAN Device currently connect to WLAN Infra AP
+ 0 - otherwise
+ */
+ u8 wlan_infra_field;
+} NanReceivePostConnectivityCapability;
+
+/*
+ Indicates the availability interval duration associated with the
+ Availability Intervals Bitmap field
+*/
+typedef enum {
+ NAN_DURATION_16MS = 0,
+ NAN_DURATION_32MS = 1,
+ NAN_DURATION_64MS = 2
+} NanAvailDuration;
+/*
+ Further availability map which can sent and received from
+ Discovery engine
+*/
+typedef struct {
+ /*
+ Number of channels indicates the number of entries
+ in vector which is part of fam
+ */
+ u8 numchans;
+ /* Defined above */
+ NanAvailDuration entry_control;
+ /*
+ 1 byte field indicating the frequency band the NAN Device
+ will be available as defined in IEEE Std. 802.11-2012
+ Annex E Table E-4 Global Operating Classes
+ */
+ u8 class_val;
+ /*
+ 1 byte field indicating the channel the NAN Device
+ will be available.
+ */
+ u8 channel;
+ /*
+ Map Id - 4 bit field which identifies the Further
+ availability map attribute.
+ */
+ u8 mapid;
+ /*
+ divides the time between the beginnings of consecutive Discovery
+ Windows of a given NAN cluster into consecutive time intervals
+ of equal durations. The time interval duration is specified by
+ the Availability Interval Duration subfield of the Entry Control
+ field.
+
+ A Nan device that sets the i-th bit of the Availability
+ Intervals Bitmap to 1 shall be present during the corresponding
+ i-th time interval in the operation channel indicated by the
+ Operating Class and Channel Number fields in the same Availability Entry.
+
+ A Nan device that sets the i-th bit of the Availability Intervals Bitmap to
+ 0 may be present during the corresponding i-th time interval in the operation
+ channel indicated by the Operating Class and Channel Number fields in the same
+ Availability Entry.
+
+ The size of the Bitmap is dependent upon the Availability Interval Duration
+ chosen in the Entry Control Field. The size can be either 1, 2 or 4 bytes long
+
+ - Duration field is equal to 0, only AIB[0] is valid
+ - Duration field is equal to 1, only AIB [0] and AIB [1] is valid
+ - 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];
+} NanFurtherAvailabilityMap;
+
+/*
+ Host can send Post-Nan Discovery attributes which the Discovery Engine can
+ enclose in Service Discovery frames
+*/
+/* Possible connection types in Post NAN Discovery attributes */
+typedef enum {
+ NAN_CONN_WLAN_INFRA = 0,
+ NAN_CONN_P2P_OPER = 1,
+ NAN_CONN_WLAN_IBSS = 2,
+ NAN_CONN_WLAN_MESH = 3,
+ NAN_CONN_FURTHER_SERVICE_AVAILABILITY = 4,
+ NAN_CONN_WLAN_RANGING = 5
+} NanConnectionType;
+
+/* Possible device roles in Post NAN Discovery attributes */
+typedef enum {
+ NAN_WLAN_INFRA_AP = 0,
+ NAN_WLAN_INFRA_STA = 1,
+ NAN_P2P_OPER_GO = 2,
+ NAN_P2P_OPER_DEV = 3,
+ NAN_P2P_OPER_CLI = 4
+} NanDeviceRole;
+
+/* Structure of Post NAN Discovery attribute */
+typedef struct {
+ /* Connection type of the host */
+ NanConnectionType type;
+ /*
+ Device role of the host based on
+ the connection type
+ */
+ NanDeviceRole role;
+ /*
+ Flag to send the information as a single shot or repeated
+ for next 16 discovery windows
+ 0 - Single_shot
+ 1 - next 16 discovery windows
+ */
+ u8 transmit_freq;
+ /* Duration of the availability bitmask */
+ NanAvailDuration duration;
+ /* Availability interval bitmap based on duration */
+ u32 avail_interval_bitmap;
+ /*
+ Mac address depending on the conn type and device role
+ --------------------------------------------------
+ | Conn Type | Device Role | Mac address Usage |
+ --------------------------------------------------
+ | WLAN_INFRA | AP/STA | BSSID of the AP |
+ --------------------------------------------------
+ | P2P_OPER | GO | GO's address |
+ --------------------------------------------------
+ | P2P_OPER | P2P_DEVICE | Address of who |
+ | | | would become GO |
+ --------------------------------------------------
+ | WLAN_IBSS | NA | BSSID |
+ --------------------------------------------------
+ | WLAN_MESH | NA | BSSID |
+ --------------------------------------------------
+ */
+ u8 addr[NAN_MAC_ADDR_LEN];
+ /*
+ Mandatory mesh id value if connection type is WLAN_MESH
+ Mesh id contains 0-32 octet identifier and should be
+ as per IEEE Std.802.11-2012 spec.
+ */
+ u16 mesh_id_len;
+ u8 mesh_id[NAN_MAX_MESH_DATA_LEN];
+ /*
+ Optional infrastructure SSID if conn_type is set to
+ NAN_CONN_WLAN_INFRA
+ */
+ u16 infrastructure_ssid_len;
+ u8 infrastructure_ssid_val[NAN_MAX_MESH_DATA_LEN];
+} NanTransmitPostDiscovery;
+
+/*
+ Discovery engine providing the structure of Post NAN
+ Discovery
+*/
+typedef struct {
+ /* Connection type of the host */
+ NanConnectionType type;
+ /*
+ Device role of the host based on
+ the connection type
+ */
+ NanDeviceRole role;
+ /* Duration of the availability bitmask */
+ NanAvailDuration duration;
+ /* Availability interval bitmap based on duration */
+ u32 avail_interval_bitmap;
+ /*
+ Map Id - 4 bit field which identifies the Further
+ availability map attribute.
+ */
+ u8 mapid;
+ /*
+ Mac address depending on the conn type and device role
+ --------------------------------------------------
+ | Conn Type | Device Role | Mac address Usage |
+ --------------------------------------------------
+ | WLAN_INFRA | AP/STA | BSSID of the AP |
+ --------------------------------------------------
+ | P2P_OPER | GO | GO's address |
+ --------------------------------------------------
+ | P2P_OPER | P2P_DEVICE | Address of who |
+ | | | would become GO |
+ --------------------------------------------------
+ | WLAN_IBSS | NA | BSSID |
+ --------------------------------------------------
+ | WLAN_MESH | NA | BSSID |
+ --------------------------------------------------
+ */
+ u8 addr[NAN_MAC_ADDR_LEN];
+ /*
+ Mandatory mesh id value if connection type is WLAN_MESH
+ Mesh id contains 0-32 octet identifier and should be
+ as per IEEE Std.802.11-2012 spec.
+ */
+ u16 mesh_id_len;
+ u8 mesh_id[NAN_MAX_MESH_DATA_LEN];
+ /*
+ Optional infrastructure SSID if conn_type is set to
+ NAN_CONN_WLAN_INFRA
+ */
+ u16 infrastructure_ssid_len;
+ u8 infrastructure_ssid_val[NAN_MAX_MESH_DATA_LEN];
+} NanReceivePostDiscovery;
+
+/*
+ Enable Request Message Structure
+ The NanEnableReq message instructs the Discovery Engine to enter an operational state
+*/
+typedef struct {
+ NanHeader header;
+ /* Mandatory parameters below */
+ u8 support_5g; /* default = 0 */
+ u16 cluster_low; /* default = 0 */
+ u16 cluster_high; /* default = 0 */
+ /*
+ BIT 0 is used to specify to include Service IDs in Sync/Discovery beacons
+ 0 - Do not include SIDs in any beacons
+ 1 - Include SIDs in all beacons.
+ Rest 7 bits are count field which allows control over the number of SIDs
+ included in the Beacon. 0 means to include as many SIDs that fit into
+ the maximum allow Beacon frame size
+ */
+ u8 sid_beacon; /* default = 0x01*/
+ u8 rssi_close; /* default = 60 (-60 dBm) */
+ u8 rssi_middle; /* default = 70 (-70 dBm) */
+ u8 rssi_proximity; /* default = 70 (-70 dBm) */
+ u8 hop_count_limit; /* default = 2 */
+ u8 random_time; /* default = 120 (DWs) */
+ u8 master_pref; /* default = 0 */
+ u8 periodic_scan_interval; /* default = 20 seconds */
+ /* TBD: Google specific IE */
+
+ /*
+ Optional configuration of Enable request.
+ Each of the optional parameters have configure flag which
+ determine whether configuration is to be passed or not.
+ */
+ /*
+ Defines 2.4G channel access support
+ 0 - No Support
+ 1 - Supported
+ If not configured, default value = 1
+ */
+ u8 config_2dot4g_support;
+ u8 support_2dot4g_val;
+ /*
+ Defines 2.4G channels will be used for sync/discovery beacons
+ 0 - 2.4G channels not used for beacons
+ 1 - 2.4G channels used for beacons
+ If not configured, default value = 1
+ */
+ u8 config_2dot4g_beacons;
+ u8 beacon_2dot4g_val;
+ /*
+ Defines 2.4G channels will be used for discovery frames
+ 0 - 2.4G channels not used for discovery frames
+ 1 - 2.4G channels used for discovery frames
+ If not configured, default value = 1
+ */
+ u8 config_2dot4g_discovery;
+ u8 discovery_2dot4g_val;
+ /*
+ Defines 5G channels will be used for sync/discovery beacons
+ 0 - 5G channels not used for beacons
+ 1 - 5G channels used for beacons
+ If not configured, default value = 1
+ */
+ u8 config_5g_beacons;
+ u8 beacon_5g_val;
+ /*
+ Defines 5G channels will be used for discovery frames
+ 0 - 5G channels not used for discovery frames
+ 1 - 5G channels used for discovery frames
+ If not configured, default value = 0
+ */
+ u8 config_5g_discovery;
+ u8 discovery_5g_val;
+ /*
+ 1 byte signed quantity which defines the RSSI value in
+ dBm for a close by Peer in 5 Ghz channels.
+ */
+ u8 config_5g_rssi_close;
+ u8 rssi_close_5g_val;
+ /*
+ 1 byte signed quantity which defines the RSSI value in
+ dBm for a close by Peer in 5 Ghz channels.
+ */
+ u8 config_5g_rssi_middle;
+ u8 rssi_middle_5g_val;
+ /*
+ 1 byte signed quantity which defines the RSSI filter
+ threshold. Any Service Descriptors received above this
+ value that are configured for RSSI filtering will be dropped.
+ */
+ u8 config_5g_rssi_close_proximity;
+ u8 rssi_close_proximity_5g_val;
+ /*
+ 2 byte quantity which defines the window size over
+ which the “average RSSI” will be calculated over.
+ */
+ u8 config_rssi_window_size;
+ u16 rssi_window_size_val;
+ /*
+ The 24 bit Organizationally Unique ID + the 8 bit Network Id.
+ */
+ u8 config_oui;
+ u32 oui_val;
+ /*
+ NAN Interface Address, If not configured the Discovery Engine
+ will generate a 6 byte Random MAC.
+ */
+ u8 config_intf_addr;
+ u8 intf_addr_val[NAN_MAC_ADDR_LEN];
+ /*
+ If set to 1, the Discovery Engine will enclose the Cluster
+ Attribute only sent in Beacons in a Vendor Specific Attribute
+ and transmit in a Service Descriptor Frame.
+ */
+ u8 config_cluster_attribute_val;
+ /*
+ The periodicity in seconds between full scan’s to find any new
+ clusters available in the area. A Full scan should not be done
+ more than every 10 seconds and should not be done less than every
+ 30 seconds.
+ */
+ u8 config_scan_params;
+ NanSocialChannelScanParams scan_params_val;
+ /*
+ Debugging mode for Discovery engine
+ */
+ u8 config_debug_flags;
+ u64 debug_flags_val;
+ /*
+ 1 byte quantity which forces the Random Factor to a particular
+ value for all transmitted Sync/Discovery beacons
+ */
+ u8 config_random_factor_force;
+ u8 random_factor_force_val;
+ /*
+ 1 byte quantity which forces the HC for all transmitted Sync and
+ Discovery Beacon NO matter the real HC being received over the
+ air.
+ */
+ u8 config_hop_count_force;
+ u8 hop_count_force_val;
+} NanEnableRequest;
+
+/*
+ Disable Request Message Structure
+ The NanDisableReq message instructs the Discovery Engine to exit an operational state.
+*/
+typedef struct {
+ NanHeader header;
+} NanDisableRequest;
+
+/*
+ Publish Msg Structure
+ Message is used to request the DE to publish the Service Name
+ using the parameters passed into the Discovery Window
+*/
+typedef struct {
+ NanHeader header;
+ u16 ttl; /* how many seconds to run for. 0 means forever until canceled */
+ u16 period; /* periodicity of OTA unsolicited publish. Specified in increments of 500 ms */
+ u8 replied_event_flag; /* 1= RepliedEventInd needed, 0 = Not needed */
+ NanPublishType publish_type;/* 0= unsolicited, solicited = 1, 2= both */
+ NanTxType tx_type; /* 0 = broadcast, 1= unicast if solicited publish */
+ u8 publish_count; /* number of OTA Publish, 0 means forever until canceled */
+ u16 service_name_len; /* length of service name */
+ u8 service_name[NAN_MAX_SERVICE_NAME_LEN];/* UTF-8 encoded string identifying the service */
+ /*
+ Field which allows the matching behavior to be controlled.
+ 0 - Match Once
+ 1 - Match continuous
+ 2 - Match never
+ 3 - Reserved
+ */
+ NanMatchAlg publish_match;
+
+ /*
+ Sequence of values which should be conveyed to the Discovery Engine of a
+ NAN Device that has invoked a Subscribe method corresponding to this Publish method
+ */
+ u16 service_specific_info_len;
+ u8 service_specific_info[NAN_MAX_SERVICE_SPECIFIC_INFO_LEN];
+
+ /*
+ Ordered sequence of <length, value> pairs which specify further response conditions
+ beyond the service name used to filter subscribe messages to respond to.
+ This is only needed when the PT is set to NAN_SOLICITED or NAN_SOLICITED_UNSOLICITED.
+ */
+ u16 rx_match_filter_len;
+ u8 rx_match_filter[NAN_MAX_MATCH_FILTER_LEN];
+
+ /*
+ Ordered sequence of <length, value> pairs to be included in the Discovery Frame.
+ If present it is always sent in a Discovery Frame
+ */
+ u16 tx_match_filter_len;
+ u8 tx_match_filter[NAN_MAX_MATCH_FILTER_LEN];
+
+ /*
+ flag which specifies that the Publish should use the configured RSSI
+ threshold and the received RSSI in order to filter requests
+ 0 – ignore the configured RSSI threshold when running a Service
+ Descriptor attribute or Service ID List Attribute through the DE matching logic.
+ 1 – use the configured RSSI threshold when running a Service
+ Descriptor attribute or Service ID List Attribute through the DE matching logic.
+
+ */
+ u8 rssi_threshold_flag;
+
+ /*
+ flag which control whether or not the Service is sent over the air
+ in order to filter requests
+ 0 – Send the Publish Service ID over the air in both Service
+ Discovery Frames, as well as, in the Service ID List Attribute
+ in Sync/Discovery Beacons(assuming we are not NM-NS role).
+ 1 – Do not send the Publish Service ID over the air
+
+ */
+ u8 ota_flag;
+
+ /*
+ 8-bit bitmap which allows the Host to associate this publish
+ with a particular Post-NAN Connectivity attribute
+ which has been sent down in a NanConfigureRequest/NanEnableRequest
+ message. If the DE fails to find a configured Post-NAN
+ connectivity attributes referenced by the bitmap,
+ the DE will return an error code to the Host.
+ If the Publish is configured to use a Post-NAN Connectivity
+ attribute and the Host does not refresh the Post-NAN Connectivity
+ attribute the Publish will be canceled and the Host will be sent
+ a PublishTerminatedIndication message.
+ */
+ u8 connmap;
+} NanPublishRequest;
+
+/*
+ Publish Cancel Msg Structure
+ The PublishServiceCancelReq Message is used to request the DE to stop publishing
+ the Service Name identified by the handle in the message.
+*/
+typedef struct {
+ NanHeader header;
+} NanPublishCancelRequest;
+
+/*
+ NAN Subscribe Structure
+ The SubscribeServiceReq message is sent to the Discovery Engine
+ whenever the Upper layers would like to listen for a Service Name
+*/
+typedef struct {
+ NanHeader header;
+ u16 ttl; /* how many seconds to run for. 0 means forever until canceled */
+ u16 period;/* periodicity of OTA Active Subscribe. Units in increments of 500 ms , 0 = attempt every DW*/
+
+ /* Flag which specifies how the Subscribe request shall be processed. */
+ u8 subscribe_type; /* 0 - PASSIVE , 1- ACTIVE */
+
+ /* Flag which specifies on Active Subscribes how the Service Response Filter attribute is populated.*/
+ u8 serviceResponseFilter; /* 0 - Bloom Filter, 1 - MAC Addr */
+
+ /* Flag which specifies how the Service Response Filter Include bit is populated.*/
+ u8 serviceResponseInclude; /* 0=Do not respond if in the Address Set, 1= Respond */
+
+ /* Flag which specifies if the Service Response Filter should be used when creating Subscribes.*/
+ u8 useServiceResponseFilter; /* 0=Do not send the Service Response Filter,1= send */
+
+ /*
+ Flag which specifies if the Service Specific Info is needed in
+ the Publish message before creating the MatchIndication
+ */
+ u8 ssiRequiredForMatchIndication; /* 0=Not needed, 1= Required */
+
+ /*
+ Field which allows the matching behavior to be controlled.
+ 0 - Match Once
+ 1 - Match continuous
+ 2 - Match never
+ 3 - Reserved
+ */
+ NanMatchAlg subscribe_match;
+
+ /*
+ The number of Subscribe Matches which should occur
+ before the Subscribe request is automatically terminated.
+ */
+ u8 subscribe_count; /* If this value is 0 this field is not used by the DE.*/
+
+ u16 service_name_len;/* length of service name */
+ u8 service_name[NAN_MAX_SERVICE_NAME_LEN]; /* UTF-8 encoded string identifying the service */
+
+ /* Sequence of values which further specify the published service beyond the service name*/
+ u16 service_specific_info_len;
+ u8 service_specific_info[NAN_MAX_SERVICE_SPECIFIC_INFO_LEN];
+
+ /*
+ Ordered sequence of <length, value> pairs used to filter out received publish discovery messages.
+ This can be sent both for a Passive or an Active Subscribe
+ */
+ u16 rx_match_filter_len;
+ u8 rx_match_filter[NAN_MAX_MATCH_FILTER_LEN];
+
+ /*
+ Ordered sequence of <length, value> pairs included in the
+ Discovery Frame when an Active Subscribe is used.
+ */
+ u16 tx_match_filter_len;
+ u8 tx_match_filter[NAN_MAX_MATCH_FILTER_LEN];
+
+ /*
+ Flag which specifies that the Subscribe should use the configured RSSI
+ threshold and the received RSSI in order to filter requests
+ 0 – ignore the configured RSSI threshold when running a Service
+ Descriptor attribute or Service ID List Attribute through the DE matching logic.
+ 1 – use the configured RSSI threshold when running a Service
+ Descriptor attribute or Service ID List Attribute through the DE matching logic.
+
+ */
+ u8 rssi_threshold_flag;
+
+ /*
+ flag which control whether or not the Service is sent over the air
+ in order to filter requests
+ 0 – Send the Publish Service ID over the air in both Service
+ Discovery Frames, as well as, in the Service ID List Attribute
+ in Sync/Discovery Beacons(assuming we are not NM-NS role).
+ 1 – Do not send the Publish Service ID over the air
+ */
+ u8 ota_flag;
+
+ /*
+ 8-bit bitmap which allows the Host to associate this Active
+ Subscribe with a particular Post-NAN Connectivity attribute
+ which has been sent down in a NanConfigureRequest/NanEnableRequest
+ message. If the DE fails to find a configured Post-NAN
+ connectivity attributes referenced by the bitmap,
+ the DE will return an error code to the Host.
+ If the Subscribe is configured to use a Post-NAN Connectivity
+ attribute and the Host does not refresh the Post-NAN Connectivity
+ attribute the Subscribe will be canceled and the Host will be sent
+ a SubscribeTerminatedIndication message.
+ */
+ u8 connmap;
+ /*
+ NAN Interface Address, conforming to the format as described in
+ 8.2.4.3.2 of IEEE Std. 802.11-2012.
+ */
+ u8 num_intf_addr_present;
+ u8 intf_addr[NAN_MAX_SUBSCRIBE_MAX_ADDRESS][NAN_MAC_ADDR_LEN];
+} NanSubscribeRequest;
+
+
+/*
+ NAN Subscribe Cancel Structure
+ The SubscribeCancelReq Message is used to request the DE to stop looking for the Service Name.
+*/
+typedef struct {
+ NanHeader header;
+} NanSubscribeCancelRequest;
+
+
+/*
+ Transmit follow up Structure
+ The TransmitFollowupReq message is sent to the DE to allow the sending of the Service_Specific_Info
+ to a particular MAC address.
+*/
+typedef struct {
+ NanHeader header;
+ /*
+ A 32 bit Handle which is sent to the Application. This handle will be
+ sent in any subsequent UnmatchInd/FollowupInd messages
+ */
+ u32 match_handle;
+ u8 addr[NAN_MAC_ADDR_LEN]; /* Can be a broadcast/multicast or unicast address */
+ NanTxPriority priority; /* priority of the request 0 = low, 1=normal, 2=high */
+ u8 dw_or_faw; /* 0= send in a DW, 1=send in FAW */
+
+ /*
+ Sequence of values which further specify the published service beyond the service name
+ Treated as service specific info in case dw_or_faw is set to 0
+ Treated as extended service specific info in case dw_or_faw is set to non-zero
+ */
+ u16 service_specific_info_len;
+ u8 service_specific_info[NAN_MAX_SERVICE_SPECIFIC_INFO_LEN];
+} NanTransmitFollowupRequest;
+
+/*
+ Stats Request structure
+ The Discovery Engine can be queried at runtime by the Host processor for statistics
+ concerning various parts of the Discovery Engine.
+*/
+typedef struct {
+ NanHeader header;
+ NanStatsId stats_id; /* NAN Statistics Request ID Codes */
+ u8 clear; /* 0= Do not clear the stats and return the current contents , 1= Clear the associated stats */
+} NanStatsRequest;
+
+/*
+ Config Structure
+ The NanConfigurationReq message is sent by the Host to the
+ Discovery Engine in order to configure the Discovery Engine during runtime.
+*/
+typedef struct {
+ NanHeader header;
+ u8 config_sid_beacon;
+ u8 sid_beacon; /* default = 0x01 */
+ u8 config_rssi_proximity;
+ u8 rssi_proximity; /* default = 70 (-70 dBm) */
+ u8 config_random_time;
+ u8 random_time; /* default = 120 (DWs) */
+ u8 config_master_pref;
+ u8 master_pref; /* default = 0 */
+ u8 config_periodic_scan_interval;
+ u8 periodic_scan_interval; /* default = 20 seconds */
+ /*
+ The number of Additional Discovery Window slots in
+ increments of 16 ms. Since each DW is 512 TUs apart
+ and the DW takes up 1 slot, the maximum number of additional
+ slots which can be specified is 31. This is a hint to the
+ scheduler and there is no guarantee that all 31 slots will
+ be available because of MCC and BT Coexistence channel usage
+ */
+ u8 additional_disc_window_slots; /* default = 0.*/
+
+ /*
+ 1 byte signed quantity which defines the RSSI filter
+ threshold. Any Service Descriptors received above this
+ value that are configured for RSSI filtering will be dropped.
+ */
+ u8 config_5g_rssi_close_proximity;
+ u8 rssi_close_proximity_5g_val;
+ /*
+ Optional configuration of Configure request.
+ Each of the optional parameters have configure flag which
+ determine whether configuration is to be passed or not.
+ */
+ /*
+ 2 byte quantity which defines the window size over
+ which the “average RSSI” will be calculated over.
+ */
+ u8 config_rssi_window_size;
+ u16 rssi_window_size_val;
+ /*
+ If set to 1, the Discovery Engine will enclose the Cluster
+ Attribute only sent in Beacons in a Vendor Specific Attribute
+ and transmit in a Service Descriptor Frame.
+ */
+ u8 config_cluster_attribute_val;
+ /*
+ The periodicity in seconds between full scan’s to find any new
+ clusters available in the area. A Full scan should not be done
+ more than every 10 seconds and should not be done less than every
+ 30 seconds.
+ */
+ u8 config_scan_params;
+ NanSocialChannelScanParams scan_params_val;
+ /*
+ Debugging mode for Discovery engine
+ */
+ u8 config_debug_flags;
+ u64 debug_flags_val;
+ /*
+ 1 byte quantity which forces the Random Factor to a particular
+ value for all transmitted Sync/Discovery beacons
+ */
+ u8 config_random_factor_force;
+ u8 random_factor_force_val;
+ /*
+ 1 byte quantity which forces the HC for all transmitted Sync and
+ Discovery Beacon NO matter the real HC being received over the
+ air.
+ */
+ u8 config_hop_count_force;
+ u8 hop_count_force_val;
+ /* NAN Post Connectivity Capability */
+ u8 config_conn_capability;
+ NanTransmitPostConnectivityCapability conn_capability_val;
+ /* NAN Post Discover Capability */
+ u8 config_discovery_attr;
+ NanTransmitPostDiscovery discovery_attr_val;
+ /* NAN Further availability Map */
+ u8 config_fam;
+ NanFurtherAvailabilityMap fam_val;
+} NanConfigRequest;
+
+/*
+ TCA Structure
+ The Discovery Engine can be configured to send up Events whenever a configured
+ Threshold Crossing Alert (TCA) Id crosses an integral threshold in a particular direction.
+*/
+typedef struct {
+ NanHeader header;
+ NanTcaId tca_id; /* Nan Protocol Threshold Crossing Alert (TCA) Codes */
+
+ /* flag which control whether or not an event is generated for the Rising direction */
+ u8 rising_direction_evt_flag; /* 0 - no event, 1 - event */
+
+ /* flag which control whether or not an event is generated for the Falling direction */
+ u8 falling_direction_evt_flag;/* 0 - no event, 1 - event */
+
+ /* flag which requests a previous TCA request to be cleared from the DE */
+ u8 clear;/*0= Do not clear the TCA, 1=Clear the TCA */
+
+ /* 32 bit value which represents the threshold to be used.*/
+ u32 threshold;
+} NanTCARequest;
+
+
+/*
+ Beacon Sdf Payload Structure
+ The Discovery Engine can be configured to publish vendor specific attributes as part of
+ beacon or service discovery frame transmitted as part of this request..
+*/
+typedef struct {
+ NanHeader header;
+ /*
+ NanVendorAttribute will have the Vendor Specific Attribute which the
+ vendor wants to publish as part of Discovery or Sync or Service discovery frame
+ */
+ NanTransmitVendorSpecificAttribute vsa;
+} NanBeaconSdfPayloadRequest;
+
+/* Publish statistics. */
+typedef struct PACKED
+{
+ u32 validPublishServiceReqMsgs;
+ u32 validPublishServiceRspMsgs;
+ u32 validPublishServiceCancelReqMsgs;
+ u32 validPublishServiceCancelRspMsgs;
+ u32 validPublishRepliedIndMsgs;
+ u32 validPublishTerminatedIndMsgs;
+ u32 validActiveSubscribes;
+ u32 validMatches;
+ u32 validFollowups;
+ u32 invalidPublishServiceReqMsgs;
+ u32 invalidPublishServiceCancelReqMsgs;
+ u32 invalidActiveSubscribes;
+ u32 invalidMatches;
+ u32 invalidFollowups;
+ u32 publishCount;
+} NanPublishStats;
+
+/* Subscribe statistics. */
+typedef struct PACKED
+{
+ u32 validSubscribeServiceReqMsgs;
+ u32 validSubscribeServiceRspMsgs;
+ u32 validSubscribeServiceCancelReqMsgs;
+ u32 validSubscribeServiceCancelRspMsgs;
+ u32 validSubscribeTerminatedIndMsgs;
+ u32 validSubscribeMatchIndMsgs;
+ u32 validSubscribeUnmatchIndMsgs;
+ u32 validSolicitedPublishes;
+ u32 validMatches;
+ u32 validFollowups;
+ u32 invalidSubscribeServiceReqMsgs;
+ u32 invalidSubscribeServiceCancelReqMsgs;
+ u32 invalidSubscribeFollowupReqMsgs;
+ u32 invalidSolicitedPublishes;
+ u32 invalidMatches;
+ u32 invalidFollowups;
+ u32 subscribeCount;
+ u32 bloomFilterIndex;
+} NanSubscribeStats;
+
+/* NAN MAC Statistics. Used for MAC and DW statistics. */
+typedef struct PACKED
+{
+ /* RX stats */
+ u32 validFrames;
+ u32 validActionFrames;
+ u32 validBeaconFrames;
+ u32 ignoredActionFrames;
+ u32 ignoredBeaconFrames;
+ u32 invalidFrames;
+ u32 invalidActionFrames;
+ u32 invalidBeaconFrames;
+ u32 invalidMacHeaders;
+ u32 invalidPafHeaders;
+ u32 nonNanBeaconFrames;
+
+ u32 earlyActionFrames;
+ u32 inDwActionFrames;
+ u32 lateActionFrames;
+
+ /* TX stats */
+ u32 framesQueued;
+ u32 totalTRSpUpdates;
+ u32 completeByTRSp;
+ u32 completeByTp75DW;
+ u32 completeByTendDW;
+ u32 lateActionFramesTx;
+
+ /* Misc stats - ignored for DW. */
+ u32 twIncreases;
+ u32 twDecreases;
+ u32 twChanges;
+ u32 twHighwater;
+ u32 bloomFilterIndex;
+} NanMacStats;
+
+/* NAN Sync Statistics*/
+typedef struct PACKED
+{
+ u64 currTsf;
+ u64 myRank;
+ u64 currAmRank;
+ u64 lastAmRank;
+ u32 currAmBTT;
+ u32 lastAmBTT;
+ u8 currAmHopCount;
+ u8 currRole;
+ u16 currClusterId;
+ u32 reserved1;
+
+ u64 timeSpentInCurrRole;
+ u64 totalTimeSpentAsMaster;
+ u64 totalTimeSpentAsNonMasterSync;
+ u64 totalTimeSpentAsNonMasterNonSync;
+ u32 transitionsToAnchorMaster;
+ u32 transitionsToMaster;
+ u32 transitionsToNonMasterSync;
+ u32 transitionsToNonMasterNonSync;
+ u32 amrUpdateCount;
+ u32 amrUpdateRankChangedCount;
+ u32 amrUpdateBTTChangedCount;
+ u32 amrUpdateHcChangedCount;
+ u32 amrUpdateNewDeviceCount;
+ u32 amrExpireCount;
+ u32 mergeCount;
+ u32 beaconsAboveHcLimit;
+ u32 beaconsBelowRssiThresh;
+ u32 beaconsIgnoredNoSpace;
+ u32 beaconsForOurCluster;
+ u32 beaconsForOtherCluster;
+ u32 beaconCancelRequests;
+ u32 beaconCancelFailures;
+ u32 beaconUpdateRequests;
+ u32 beaconUpdateFailures;
+ u32 syncBeaconTxAttempts;
+ u32 syncBeaconTxFailures;
+ u32 discBeaconTxAttempts;
+ u32 discBeaconTxFailures;
+ u32 amHopCountExpireCount;
+} NanSyncStats;
+
+/* NAN Misc DE Statistics */
+typedef struct PACKED
+{
+ u32 validErrorRspMsgs;
+ u32 validTransmitFollowupReqMsgs;
+ u32 validTransmitFollowupRspMsgs;
+ u32 validFollowupIndMsgs;
+ u32 validConfigurationReqMsgs;
+ u32 validConfigurationRspMsgs;
+ u32 validStatsReqMsgs;
+ u32 validStatsRspMsgs;
+ u32 validEnableReqMsgs;
+ u32 validEnableRspMsgs;
+ u32 validDisableReqMsgs;
+ u32 validDisableRspMsgs;
+ u32 validDisableIndMsgs;
+ u32 validEventIndMsgs;
+ u32 validTcaReqMsgs;
+ u32 validTcaRspMsgs;
+ u32 validTcaIndMsgs;
+ u32 invalidTransmitFollowupReqMsgs;
+ u32 invalidConfigurationReqMsgs;
+ u32 invalidStatsReqMsgs;
+ u32 invalidEnableReqMsgs;
+ u32 invalidDisableReqMsgs;
+ u32 invalidTcaReqMsgs;
+} NanDeStats;
+
+/*
+ Stats Response Message structure
+ The Discovery Engine response to a request by the Host for statistics.
+*/
+typedef struct {
+ NanStatsId stats_id;
+ union {
+ NanPublishStats publish_stats;
+ NanSubscribeStats subscribe_stats;
+ NanMacStats mac_stats;
+ NanSyncStats sync_stats;
+ NanDeStats de_stats;
+ } data;
+} NanStatsResponse;
+
+/*
+ NAN Response messages
+*/
+typedef struct {
+ NanHeader header;
+ u16 status; /* contains the result code */
+ u16 value; /* For error returns the value is returned which was in error */
+ NanResponseType response_type; /* NanResponseType Definitions */
+ union {
+ NanStatsResponse stats_response;
+ } body;
+} NanResponseMsg;
+
+
+/*
+ Publish Replied Indication
+ The PublishRepliedInd Message is sent by the DE when an Active Subscribe is
+ received over the air and it matches a Solicited PublishServiceReq which had
+ been created with the replied_event_flag set.
+*/
+typedef struct {
+ NanHeader header;
+ u8 addr[NAN_MAC_ADDR_LEN];
+ /*
+ If RSSI filtering was configured in NanPublishRequest then this
+ field will contain the received RSSI value. 0 if not
+ */
+ u8 rssi_value;
+ /*
+ optional attributes. Each optional attribute is associated with a flag
+ which specifies whether the attribute is valid or not
+ */
+ /* NAN Post Connectivity Capability received */
+ u8 is_conn_capability_valid;
+ NanReceivePostConnectivityCapability conn_capability;
+
+ /* NAN Post Discover Capability */
+ u8 is_discovery_attr_valid;
+ NanReceivePostDiscovery discovery_attr;
+
+ /* NAN Further availability Map */
+ u8 is_fam_valid;
+ NanFurtherAvailabilityMap fam;
+
+ /* NAN Cluster Attribute */
+ u8 cluster_attribute_len;
+ u8 cluster_attribute[NAN_MAX_CLUSTER_ATTRIBUTE_LEN];
+} NanPublishRepliedInd;
+
+/*
+ Publish Terminated
+ The PublishTerminatedInd message is sent by the DE whenever a Publish
+ terminates from a user-specified timeout or a unrecoverable error in the DE.
+*/
+typedef struct {
+ NanHeader header;
+ NanTerminatedStatus reason;
+} NanPublishTerminatedInd;
+
+/*
+ Match Indication
+ The MatchInd message is sent once per responding MAC address whenever
+ the Discovery Engine detects a match for a previous SubscribeServiceReq
+ or PublishServiceReq.
+*/
+typedef struct {
+ NanHeader header;
+
+ /*
+ A 32 bit Handle which is sent to the Application. This handle will be
+ sent in any subsequent UnmatchInd/FollowupInd messages
+ */
+ u32 match_handle;
+ u8 addr[NAN_MAC_ADDR_LEN];
+
+ /*
+ Sequence of octets which were received in a Discovery Frame matching the
+ Subscribe Request.
+ */
+ u16 service_specific_info_len;
+ u8 service_specific_info[NAN_MAX_SERVICE_NAME_LEN];
+
+ /*
+ Ordered sequence of <length, value> pairs received in the Discovery Frame
+ matching the Subscribe Request.
+ */
+ u16 sdf_match_filter_len;
+ u8 sdf_match_filter[NAN_MAX_MATCH_FILTER_LEN];
+
+ /*
+ flag to indicate if the Match occurred in a Beacon Frame or in a
+ Service Discovery Frame.
+ 0 - Match occured in a Service Discovery Frame
+ 1 - Match occured in a Beacon Frame
+ */
+ u8 match_occured_flag;
+
+ /*
+ flag to indicate FW is out of resource and that it can no longer
+ track this Service Name. The Host still need to send the received
+ Match_Handle but duplicate MatchInd messages may be received on
+ this Handle until the resource frees up.
+ 0 - FW is caching this match
+ 1 - FW is unable to cache this match
+ */
+ u8 out_of_resource_flag;
+
+ /*
+ If RSSI filtering was configured in NanSubscribeRequest then this
+ field will contain the received RSSI value. 0 if not.
+ */
+ u8 rssi_value;
+
+ /*
+ optional attributes. Each optional attribute is associated with a flag
+ which specifies whether the attribute is valid or not
+ */
+ /* NAN Post Connectivity Capability received */
+ u8 is_conn_capability_valid;
+ NanReceivePostConnectivityCapability conn_capability;
+
+ /* NAN Post Discover Capability */
+ u8 is_discovery_attr_valid;
+ NanReceivePostDiscovery discovery_attr;
+
+ /* NAN Further availability Map */
+ u8 is_fam_valid;
+ NanFurtherAvailabilityMap fam;
+
+ /* NAN Cluster Attribute */
+ u8 cluster_attribute_len;
+ u8 cluster_attribute[NAN_MAX_CLUSTER_ATTRIBUTE_LEN];
+} NanMatchInd;
+
+/*
+ UnMatch Indication
+ The UnmatchInd message is sent whenever the Discovery Engine detects that
+ a previously Matched Service has been gone for too long. If the previous
+ MatchInd message for this Handle had the out_of_resource_flag set then
+ this message will not be received
+*/
+typedef struct {
+ NanHeader header;
+ /*
+ 32 bit value sent by the DE in a previous
+ MatchInd/FollowupInd to the application.
+ */
+ u32 match_handle;
+} NanUnmatchInd;
+
+/*
+ Subscribe Terminated
+ The SubscribeTerminatedInd message is sent by the DE whenever a
+ Subscribe terminates from a user-specified timeout or a unrecoverable error in the DE.
+*/
+typedef struct {
+ NanHeader header;
+ NanTerminatedStatus reason;
+} NanSubscribeTerminatedInd;
+
+/*
+ Followup Indication Message
+ The FollowupInd message is sent by the DE to the Host whenever it receives a
+ Followup message from another peer.
+*/
+typedef struct {
+ NanHeader header;
+ /*
+ A 32 bit Handle which is sent to the Application. This handle will be
+ sent in any subsequent UnmatchInd/FollowupInd messages
+ */
+ u32 match_handle;
+ u8 addr[NAN_MAC_ADDR_LEN];
+
+ /* Flag which the DE uses to decide if received in a DW or a FAW*/
+ u8 dw_or_faw; /* 0=Received in a DW, 1 = Received in a FAW*/
+
+ /*
+ Sequence of values which further specify the published service beyond the service name
+ Service specific info in case dw_or_faw is set to 0
+ Extended service specific info in case dw_or_faw is set to non-zero
+ */
+ u16 service_specific_info_len;
+ u8 service_specific_info[NAN_MAX_SERVICE_SPECIFIC_INFO_LEN];
+} NanFollowupInd;
+
+/*
+ Event data notifying the Mac address of the Discovery engine.
+ which is reported as one of the Discovery engine event
+*/
+typedef struct {
+ u8 addr[NAN_MAC_ADDR_LEN];
+} NanMacAddressEvent;
+
+/*
+ Event data notifying the Cluster address of the cluster
+ which is reported as one of the Discovery engine event
+*/
+typedef struct {
+ u8 addr[NAN_MAC_ADDR_LEN];
+} NanClusterEvent;
+
+/*
+ Discovery Engine Event Indication
+ The Discovery Engine can inform the Host when significant events occur
+ The data following the EventId is dependent upon the EventId type.
+ In other words, each new event defined will carry a different
+ structure of information back to the host.
+*/
+typedef struct {
+ NanHeader header;
+ NanEventId event_id; /* NAN Protocol Event Codes */
+ union {
+ /*
+ MacAddressEvent which will have 6 byte mac address
+ of the Discovery engine.
+ */
+ NanMacAddressEvent mac_addr;
+ /*
+ Cluster Event Data which will be obtained when the
+ device starts a new cluster or joins a cluster.
+ The event data will have 6 byte octet string of the
+ cluster started or joined.
+ */
+ NanClusterEvent cluster;
+ } data;
+} NanDiscEngEventInd;
+
+/* Cluster size TCA event*/
+typedef struct {
+ /* size of the cluster*/
+ u32 cluster_size;
+} NanTcaClusterEvent;
+
+/*
+ NAN TCA Indication
+ The Discovery Engine can inform the Host when significant events occur.
+ The data following the TcaId is dependent upon the TcaId type.
+ In other words, each new event defined will carry a different structure
+ of information back to the host.
+*/
+typedef struct {
+ NanHeader header;
+ NanTcaId tca_id;
+ /* flag which defines if the configured Threshold has risen above the threshold */
+ u8 rising_direction_evt_flag; /* 0 - no event, 1 - event */
+
+ /* flag which defines if the configured Threshold has fallen below the threshold */
+ u8 falling_direction_evt_flag;/* 0 - no event, 1 - event */
+ union {
+ /*
+ This event in obtained when the cluser size threshold
+ is crossed. Event will have the cluster size
+ */
+ NanTcaClusterEvent cluster;
+ } data;
+} NanTCAInd;
+
+/*
+ NAN Disabled Indication
+ The NanDisableInd message indicates to the upper layers that the Discovery
+ Engine has flushed all state and has been shutdown. When this message is received
+ the DE is guaranteed to have left the NAN cluster it was part of and will have terminated
+ any in progress Publishes or Subscribes.
+*/
+typedef struct {
+ NanHeader header;
+ NanStatusType reason;
+} NanDisabledInd;
+
+/*
+ NAN Beacon SDF Payload Indication
+ The NanBeaconSdfPayloadInd message indicates to the upper layers that information
+ elements were received either in a Beacon or SDF which needs to be delivered
+ outside of a Publish/Subscribe Handle.
+*/
+typedef struct {
+ NanHeader header;
+ /* The MAC address of the peer which sent the attributes.*/
+ u8 addr[NAN_MAC_ADDR_LEN];
+ /*
+ Optional attributes. Each optional attribute is associated with a flag
+ which specifies whether the attribute is valid or not
+ */
+ /* NAN Receive Vendor Specific Attribute*/
+ u8 is_vsa_received;
+ NanReceiveVendorSpecificAttribute vsa;
+
+ /* NAN Beacon SDF Payload Received*/
+ u8 is_beacon_sdf_payload_received;
+ NanBeaconSdfPayloadReceive data;
+} NanBeaconSdfPayloadInd;
+
+typedef struct {
+ u64 master_rank;
+ u8 master_pref;
+ u8 random_factor;
+ u8 hop_count;
+ u32 beacon_transmit_time;
+} NanStaParameter;
+
+/* Response and Event Callbacks */
+typedef struct {
+ /* NotifyResponse invoked to notify the status of the Request */
+ void (*NotifyResponse)(NanResponseMsg* rsp_data);
+ /* Various Events Callback */
+ void (*EventPublishReplied)(NanPublishRepliedInd* event);
+ void (*EventPublishTerminated)(NanPublishTerminatedInd* event);
+ void (*EventMatch) (NanMatchInd* event);
+ void (*EventUnMatch) (NanUnmatchInd* event);
+ void (*EventSubscribeTerminated) (NanSubscribeTerminatedInd* event);
+ void (*EventFollowup) (NanFollowupInd* event);
+ void (*EventDiscEngEvent) (NanDiscEngEventInd* event);
+ void (*EventDisabled) (NanDisabledInd* event);
+ void (*EventTca) (NanTCAInd* event);
+ void (*EventSdfPayload) (NanBeaconSdfPayloadInd* event);
+} NanCallbackHandler;
+
+
+/* Function to send NAN request to the wifi driver.*/
+wifi_error nan_enable_request(wifi_request_id id,
+ wifi_handle handle,
+ NanEnableRequest* msg);
+
+/* Function to send NAN request to the wifi driver.*/
+wifi_error nan_disable_request(wifi_request_id id,
+ wifi_handle handle,
+ NanDisableRequest* msg);
+
+/* Function to send NAN request to the wifi driver.*/
+wifi_error nan_publish_request(wifi_request_id id,
+ wifi_handle handle,
+ NanPublishRequest* msg);
+
+/* Function to send NAN request to the wifi driver.*/
+wifi_error nan_publish_cancel_request(wifi_request_id id,
+ wifi_handle handle,
+ NanPublishCancelRequest* msg);
+
+/* Function to send NAN request to the wifi driver.*/
+wifi_error nan_subscribe_request(wifi_request_id id,
+ wifi_handle handle,
+ NanSubscribeRequest* msg);
+
+/* Function to send NAN request to the wifi driver.*/
+wifi_error nan_subscribe_cancel_request(wifi_request_id id,
+ wifi_handle handle,
+ NanSubscribeCancelRequest* msg);
+
+/* Function to send NAN request to the wifi driver.*/
+wifi_error nan_transmit_followup_request(wifi_request_id id,
+ wifi_handle handle,
+ NanTransmitFollowupRequest* msg);
+
+/* Function to send NAN statistics request to the wifi driver.*/
+wifi_error nan_stats_request(wifi_request_id id,
+ wifi_handle handle,
+ NanStatsRequest* msg);
+
+/* Function to send NAN configuration request to the wifi driver.*/
+wifi_error nan_config_request(wifi_request_id id,
+ wifi_handle handle,
+ NanConfigRequest* msg);
+
+/* Function to send NAN request to the wifi driver.*/
+wifi_error nan_tca_request(wifi_request_id id,
+ wifi_handle handle,
+ NanTCARequest* msg);
+
+/*
+ Function to send NAN Beacon sdf payload to the wifi driver.
+ This instructs the Discovery Engine to begin publishing the
+ received payload in any Beacon or Service Discovery Frame
+ transmitted
+*/
+wifi_error nan_beacon_sdf_payload_request(wifi_request_id id,
+ wifi_handle handle,
+ NanBeaconSdfPayloadRequest* msg);
+/*
+ Function to get the sta_parameter expected by Sigma
+ as per CAPI spec.
+*/
+wifi_error nan_get_sta_parameter(wifi_request_id id,
+ wifi_handle handle,
+ NanStaParameter* msg);
+
+/* Function to register NAN callback */
+wifi_error nan_register_handler(wifi_handle handle,
+ NanCallbackHandler handlers);
+
+/* Function to get version of the NAN HAL */
+wifi_error nan_get_version(wifi_handle handle,
+ NanVersion* version);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __NAN_H__ */
diff --git a/qcwcn/wifi_hal/nan_i.h b/qcwcn/wifi_hal/nan_i.h
new file mode 100644
index 0000000..e269250
--- /dev/null
+++ b/qcwcn/wifi_hal/nan_i.h
@@ -0,0 +1,875 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __NAN_I_H__
+#define __NAN_I_H__
+
+#include "common.h"
+#include "cpp_bindings.h"
+#include "nan.h"
+#include "wifi_hal.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+#ifndef PACKED
+#define PACKED __attribute__((packed))
+#endif
+
+typedef u8 SirMacAddr[NAN_MAC_ADDR_LEN];
+/*---------------------------------------------------------------------------
+* WLAN NAN CONSTANTS
+*--------------------------------------------------------------------------*/
+
+typedef enum
+{
+ NAN_MSG_ID_ERROR_RSP = 0,
+ NAN_MSG_ID_CONFIGURATION_REQ = 1,
+ NAN_MSG_ID_CONFIGURATION_RSP = 2,
+ NAN_MSG_ID_PUBLISH_SERVICE_REQ = 3,
+ NAN_MSG_ID_PUBLISH_SERVICE_RSP = 4,
+ NAN_MSG_ID_PUBLISH_SERVICE_CANCEL_REQ = 5,
+ NAN_MSG_ID_PUBLISH_SERVICE_CANCEL_RSP = 6,
+ NAN_MSG_ID_PUBLISH_REPLIED_IND = 7,
+ NAN_MSG_ID_PUBLISH_TERMINATED_IND = 8,
+ NAN_MSG_ID_SUBSCRIBE_SERVICE_REQ = 9,
+ NAN_MSG_ID_SUBSCRIBE_SERVICE_RSP = 10,
+ NAN_MSG_ID_SUBSCRIBE_SERVICE_CANCEL_REQ = 11,
+ NAN_MSG_ID_SUBSCRIBE_SERVICE_CANCEL_RSP = 12,
+ NAN_MSG_ID_MATCH_IND = 13,
+ NAN_MSG_ID_UNMATCH_IND = 14,
+ NAN_MSG_ID_SUBSCRIBE_TERMINATED_IND = 15,
+ NAN_MSG_ID_DE_EVENT_IND = 16,
+ NAN_MSG_ID_TRANSMIT_FOLLOWUP_REQ = 17,
+ NAN_MSG_ID_TRANSMIT_FOLLOWUP_RSP = 18,
+ NAN_MSG_ID_FOLLOWUP_IND = 19,
+ NAN_MSG_ID_STATS_REQ = 20,
+ NAN_MSG_ID_STATS_RSP = 21,
+ NAN_MSG_ID_ENABLE_REQ = 22,
+ NAN_MSG_ID_ENABLE_RSP = 23,
+ NAN_MSG_ID_DISABLE_REQ = 24,
+ NAN_MSG_ID_DISABLE_RSP = 25,
+ NAN_MSG_ID_DISABLE_IND = 26,
+ NAN_MSG_ID_TCA_REQ = 27,
+ NAN_MSG_ID_TCA_RSP = 28,
+ NAN_MSG_ID_TCA_IND = 29,
+#ifdef NAN_2_0
+ NAN_MSG_ID_BEACON_SDF_REQ = 30,
+ NAN_MSG_ID_BEACON_SDF_RSP = 31,
+ NAN_MSG_ID_BEACON_SDF_IND = 32
+#endif /* NAN_2_0 */
+} NanMsgId;
+
+/*
+ Various TLV Type ID sent as part of NAN Stats Response
+ or NAN TCA Indication
+*/
+typedef enum
+{
+ NAN_TLV_TYPE_FIRST = 0,
+
+ /* Service Discovery Frame types */
+ NAN_TLV_TYPE_SDF_FIRST = NAN_TLV_TYPE_FIRST,
+ NAN_TLV_TYPE_SERVICE_NAME = NAN_TLV_TYPE_SDF_FIRST,
+ NAN_TLV_TYPE_SDF_MATCH_FILTER,
+ NAN_TLV_TYPE_TX_MATCH_FILTER,
+ NAN_TLV_TYPE_RX_MATCH_FILTER,
+ NAN_TLV_TYPE_SERVICE_SPECIFIC_INFO,
+ NAN_TLV_TYPE_GROUP_KEY,
+ NAN_TLV_TYPE_EXT_SERVICE_SPECIFIC_INFO,
+ NAN_TLV_TYPE_SDF_LAST = 4095,
+
+ /* Configuration types */
+ NAN_TLV_TYPE_CONFIG_FIRST = 4096,
+ NAN_TLV_TYPE_5G_SUPPORT = NAN_TLV_TYPE_CONFIG_FIRST,
+ NAN_TLV_TYPE_SID_BEACON,
+ NAN_TLV_TYPE_5G_SYNC_DISC,
+ NAN_TLV_TYPE_RSSI_CLOSE,
+ NAN_TLV_TYPE_RSSI_MEDIUM,
+ NAN_TLV_TYPE_HOP_COUNT_LIMIT,
+ NAN_TLV_TYPE_RANDOM_UPDATE_TIME,
+ NAN_TLV_TYPE_MASTER_PREFERENCE,
+ NAN_TLV_TYPE_EARLY_WAKEUP,
+ NAN_TLV_TYPE_PERIODIC_SCAN_INTERVAL,
+ NAN_TLV_TYPE_CLUSTER_ID_LOW,
+ NAN_TLV_TYPE_CLUSTER_ID_HIGH,
+ NAN_TLV_TYPE_RSSI_CLOSE_PROXIMITY,
+ NAN_TLV_TYPE_FURTHER_AVAILABILITY,
+ NAN_TLV_TYPE_CONFIG_LAST = 8191,
+
+ /* Statistics types */
+ NAN_TLV_TYPE_STATS_FIRST = 8192,
+ NAN_TLV_TYPE_DE_PUBLISH_STATS = NAN_TLV_TYPE_STATS_FIRST,
+ NAN_TLV_TYPE_DE_SUBSCRIBE_STATS,
+ NAN_TLV_TYPE_DE_MAC_STATS,
+ NAN_TLV_TYPE_DE_TIMING_SYNC_STATS,
+ NAN_TLV_TYPE_DE_DW_STATS,
+ NAN_TLV_TYPE_DE_STATS,
+ NAN_TLV_TYPE_STATS_LAST = 12287,
+
+ /* Attributes types */
+ NAN_TLV_TYPE_ATTRS_FIRST = 12288,
+ NAN_TLV_TYPE_WLAN_INFRA_ATTR = NAN_TLV_TYPE_ATTRS_FIRST,
+ NAN_TLV_TYPE_P2P_OPERATION_ATTR,
+ NAN_TLV_TYPE_WLAN_IBSS_ATTR,
+ NAN_TLV_TYPE_WLAN_MESH_ATTR,
+ NAN_TLV_TYPE_WLAN_MESH_ID,
+ NAN_TLV_TYPE_SELF_MAC_ADDR,
+ NAN_TLV_TYPE_CLUSTER_SIZE,
+ NAN_TLV_TYPE_ATTRS_LAST = 16383,
+
+#ifdef NAN_2_0
+ NAN_TLV_TYPE_VENDOR_SPECIFIC_ATTRIBUTE_TRANSMIT = 30000,
+ NAN_TLV_TYPE_VENDOR_SPECIFIC_ATTRIBUTE_RECEIVE,
+ NAN_TLV_TYPE_POST_NAN_CONNECTIVITY_CAPABILITIES_RECEIVE,
+ NAN_TLV_TYPE_POST_NAN_DISCOVERY_ATTRIBUTE_RECEIVE,
+ NAN_TLV_TYPE_BEACON_SDF_PAYLOAD_RECEIVE,
+
+ NAN_TLV_TYPE_2DOT4G_SUPPORT = 30100,
+ NAN_TLV_TYPE_2DOT4G_BEACONS,
+ NAN_TLV_TYPE_2DOT4G_SDF,
+ NAN_TLV_TYPE_5G_BEACON,
+ NAN_TLV_TYPE_5G_SDF,
+ NAN_TLV_TYPE_5G_RSSI_CLOSE,
+ NAN_TLV_TYPE_5G_RSSI_MEDIUM,
+ NAN_TLV_TYPE_5G_RSSI_CLOSE_PROXIMITY,
+ NAN_TLV_TYPE_RSSI_AVERAGING_WINDOW_SIZE,
+ NAN_TLV_TYPE_CLUSTER_OUI_NETWORK_ID,
+ NAN_TLV_TYPE_SOURCE_MAC_ADDRESS,
+ NAN_TLV_TYPE_CLUSTER_ATTRIBUTE_IN_SDF,
+ NAN_TLV_TYPE_SOCIAL_CHANNEL_SCAN_PARAMETERS,
+ NAN_TLV_TYPE_DEBUGGING_FLAGS,
+ NAN_TLV_TYPE_POST_NAN_CONNECTIVITY_CAPABILITIES_TRANSMIT,
+ NAN_TLV_TYPE_POST_NAN_DISCOVERY_ATTRIBUTE_TRANSMIT,
+ NAN_TLV_TYPE_FURTHER_AVAILABILITY_MAP,
+ NAN_TLV_TYPE_HOP_COUNT_FORCE,
+ NAN_TLV_TYPE_RANDOM_FACTOR_FORCE,
+
+ NAN_TLV_TYPE_MAC_ADDRESS = 30200,
+ NAN_TLV_TYPE_RECEIVED_RSSI_VALUE,
+ NAN_TLV_TYPE_CLUSTER_ATTIBUTE,
+ NAN_TLV_TYPE_WLAN_INFRASTRUCTURE_SSID,
+
+ NAN_TLV_TYPE_TCA_CLUSTER_SIZE_REQ = 30300,
+#endif /* NAN_2_0 */
+ NAN_TLV_TYPE_LAST = 65535
+} NanTlvType;
+
+/* 8-byte control message header used by NAN*/
+typedef struct PACKED
+{
+ u16 msgVersion:4;
+ u16 msgId:12;
+ u16 msgLen;
+ u16 handle;
+ u16 transactionId;
+} NanMsgHeader, *pNanMsgHeader;
+
+/* Enumeration for Version */
+typedef enum
+{
+ NAN_MSG_VERSION1 = 1,
+}NanMsgVersion;
+
+typedef struct PACKED
+{
+ u16 type;
+ u16 length;
+ u8* value;
+} NanTlv, *pNanTlv;
+
+#define SIZEOF_TLV_HDR (sizeof(NanTlv::type) + sizeof(NanTlv::length))
+/* NAN TLV Groups and Types */
+typedef enum
+{
+ NAN_TLV_GROUP_FIRST = 0,
+ NAN_TLV_GROUP_SDF = NAN_TLV_GROUP_FIRST,
+ NAN_TLV_GROUP_CONFIG,
+ NAN_TLV_GROUP_STATS,
+ NAN_TLV_GROUP_ATTRS,
+ NAN_TLV_NUM_GROUPS,
+ NAN_TLV_GROUP_LAST = NAN_TLV_NUM_GROUPS
+} NanTlvGroup;
+
+/* NAN Miscellaneous Constants */
+#define NAN_TTL_INFINITE 0
+#define NAN_REPLY_COUNT_INFINITE 0
+
+/* NAN Confguration 5G Channel Access Bit */
+#define NAN_5G_CHANNEL_ACCESS_UNSUPPORTED 0
+#define NAN_5G_CHANNEL_ACCESS_SUPPORTED 1
+
+/* NAN Configuration Service IDs Enclosure Bit */
+#define NAN_SIDS_NOT_ENCLOSED_IN_BEACONS 0
+#define NAN_SIBS_ENCLOSED_IN_BEACONS 1
+
+/* NAN Configuration Priority */
+#define NAN_CFG_PRIORITY_SERVICE_DISCOVERY 0
+#define NAN_CFG_PRIORITY_DATA_CONNECTION 1
+
+/* NAN Configuration 5G Channel Usage */
+#define NAN_5G_CHANNEL_USAGE_SYNC_AND_DISCOVERY 0
+#define NAN_5G_CHANNEL_USAGE_DISCOVERY_ONLY 1
+
+/* NAN Configuration TX_Beacon Content */
+#define NAN_TX_BEACON_CONTENT_OLD_AM_INFO 0
+#define NAN_TX_BEACON_CONTENT_UPDATED_AM_INFO 1
+
+/* NAN Configuration Miscellaneous Constants */
+#define NAN_MAC_INTERFACE_PERIODICITY_MIN 30
+#define NAN_MAC_INTERFACE_PERIODICITY_MAX 255
+
+#define NAN_DW_RANDOM_TIME_MIN 120
+#define NAN_DW_RANDOM_TIME_MAX 240
+
+#define NAN_INITIAL_SCAN_MIN_IDEAL_PERIOD 200
+#define NAN_INITIAL_SCAN_MAX_IDEAL_PERIOD 300
+
+#define NAN_ONGOING_SCAN_MIN_PERIOD 10
+#define NAN_ONGOING_SCAN_MAX_PERIOD 30
+
+#define NAN_HOP_COUNT_LIMIT 5
+
+#define NAN_WINDOW_DW 0
+#define NAN_WINDOW_FAW 1
+
+/* NAN Error Rsp */
+typedef struct PACKED
+{
+ NanMsgHeader fwHeader;
+ u16 status;
+ u16 value;
+} NanErrorRspMsg, *pNanErrorRspMsg;
+
+//* NAN Publish Service Req */
+typedef struct PACKED
+{
+ u16 ttl;
+ u16 period;
+ u32 replyIndFlag:1;
+ u32 publishType:2;
+ u32 txType:1;
+#ifdef NAN_2_0
+ u32 rssiThresholdFlag:1;
+ u32 ota_flag:1;
+ u32 matchAlg:2;
+#else /* NAN_2_0 */
+ u32 reserved1:4;
+#endif /* NAN_2_0 */
+ u32 count:8;
+#ifdef NAN_2_0
+ u32 connmap:8;
+ u32 reserved2:8;
+#else /* NAN_2_0 */
+ u32 reserved2:16;
+#endif /* NAN_2_0 */
+ /*
+ * Excludes TLVs
+ *
+ * Required: Service Name,
+ * Optional: Tx Match Filter, Rx Match Filter, Service Specific Info,
+ */
+} NanPublishServiceReqParams, *pNanPublishServiceReqParams;
+
+typedef struct PACKED
+{
+ NanMsgHeader fwHeader;
+ NanPublishServiceReqParams publishServiceReqParams;
+ u8 ptlv[];
+} NanPublishServiceReqMsg, *pNanPublishServiceReqMsg;
+
+/* NAN Publish Service Rsp */
+typedef struct PACKED
+{
+ NanMsgHeader fwHeader;
+ /* status of the request */
+ u16 status;
+ u16 value;
+} NanPublishServiceRspMsg, *pNanPublishServiceRspMsg;
+
+/* NAN Publish Service Cancel Req */
+typedef struct PACKED
+{
+ NanMsgHeader fwHeader;
+} NanPublishServiceCancelReqMsg, *pNanPublishServiceCancelReqMsg;
+
+/* NAN Publish Service Cancel Rsp */
+typedef struct PACKED
+{
+ NanMsgHeader fwHeader;
+ /* status of the request */
+ u16 status;
+ u16 value;
+} NanPublishServiceCancelRspMsg, *pNanPublishServiceCancelRspMsg;
+
+/* NAN Publish Replied Ind */
+typedef struct PACKED
+{
+ SirMacAddr macAddr;
+ u16 reserved;
+} NanPublishRepliedIndParams;
+
+typedef struct PACKED
+{
+ NanMsgHeader fwHeader;
+#ifndef NAN_2_0
+ NanPublishRepliedIndParams publishRepliedIndParams;
+#else /* NAN_2_0 */
+ u8 ptlv[];
+#endif /* NAN_2_0 */
+} NanPublishRepliedIndMsg, *pNanPublishRepliedIndMsg;
+
+/* NAN Publish Terminated Ind */
+typedef struct PACKED
+{
+ NanMsgHeader fwHeader;
+ /* reason for the termination */
+ u16 reason;
+ u16 reserved;
+} NanPublishTerminatedIndMsg, *pNanPublishTerminatedIndMsg;
+
+/* NAN Subscribe Service Req */
+typedef struct PACKED
+{
+ u16 ttl;
+ u16 period;
+ u32 subscribeType:1;
+ u32 srfAttr:1;
+ u32 srfInclude:1;
+ u32 srfSend:1;
+ u32 ssiRequired:1;
+#ifndef NAN_2_0
+ u32 matchAlg:3;
+#else /* NAN_2_0 */
+ u32 matchAlg:2;
+ u32 xbit:1;
+#endif
+ u32 count:8;
+#ifdef NAN_2_0
+ u32 rssiThresholdFlag:1;
+ u32 ota_flag:1;
+ u32 reserved:6;
+ u32 connmap:8;
+#else /* NAN_2_0 */
+ u32 reserved:16;
+#endif/* NAN_2_0 */
+ /*
+ * Excludes TLVs
+ *
+ * Required: Service Name
+ * Optional: Rx Match Filter, Tx Match Filter, Service Specific Info,
+ */
+} NanSubscribeServiceReqParams, *pNanSubscribeServiceReqParams;
+
+typedef struct PACKED
+{
+ NanMsgHeader fwHeader;
+ NanSubscribeServiceReqParams subscribeServiceReqParams;
+ u8 ptlv[];
+} NanSubscribeServiceReqMsg, *pNanSubscribeServiceReqMsg;
+
+/* NAN Subscribe Service Rsp */
+typedef struct PACKED
+{
+ NanMsgHeader fwHeader;
+ /* status of the request */
+ u16 status;
+ u16 value;
+} NanSubscribeServiceRspMsg, *pNanSubscribeServiceRspMsg;
+
+/* NAN Subscribe Service Cancel Req */
+typedef struct PACKED
+{
+ NanMsgHeader fwHeader;
+} NanSubscribeServiceCancelReqMsg, *pNanSubscribeServiceCancelReqMsg;
+
+/* NAN Subscribe Service Cancel Rsp */
+typedef struct PACKED
+{
+ NanMsgHeader fwHeader;
+ /* status of the request */
+ u16 status;
+ u16 value;
+} NanSubscribeServiceCancelRspMsg, *pNanSubscribeServiceCancelRspMsg;
+
+/* NAN Subscribe Match Ind */
+typedef struct PACKED
+{
+#ifndef NAN_2_0
+ u16 matchHandle;
+ SirMacAddr macAddr;
+ /*
+ * Excludes TLVs
+ *
+ * Required: Service Name
+ * Optional: SDF Match Filter, Service Specific Info
+ */
+#else /* NAN_2_0 */
+ u32 matchHandle;
+ u32 matchOccuredFlag:1;
+ u32 outOfResourceFlag:1;
+ u32 reserved:30;
+#endif /* NAN_2_0 */
+} NanMatchIndParams;
+
+typedef struct PACKED
+{
+ NanMsgHeader fwHeader;
+ NanMatchIndParams matchIndParams;
+ u8 ptlv[];
+} NanMatchIndMsg, *pNanMatchIndMsg;
+
+/* NAN Subscribe Unmatch Ind */
+typedef struct PACKED
+{
+#ifndef NAN_2_0
+ u16 matchHandle;
+ u16 reserved;
+#else
+ u32 matchHandle;
+#endif
+} NanUnmatchIndParams;
+
+typedef struct PACKED
+{
+ NanMsgHeader fwHeader;
+ NanUnmatchIndParams unmatchIndParams;
+} NanUnmatchIndMsg, *pNanUnmatchIndMsg;
+
+/* NAN Subscribe Terminated Ind */
+typedef struct PACKED
+{
+ NanMsgHeader fwHeader;
+ /* reason for the termination */
+ u16 reason;
+ u16 reserved;
+} NanSubscribeTerminatedIndMsg, *pNanSubscribeTerminatedIndMsg;
+
+/* Event Ind */
+typedef struct PACKED
+{
+ u32 eventId:8;
+ u32 reserved:24;
+} NanEventIndParams;
+
+typedef struct PACKED
+{
+ NanMsgHeader fwHeader;
+#ifndef NAN_2_0
+ NanEventIndParams eventIndParams;
+#endif
+ u8 ptlv[];
+} NanEventIndMsg, *pNanEventIndMsg;
+
+/* NAN Transmit Followup Req */
+typedef struct PACKED
+{
+#ifndef NAN_2_0
+ SirMacAddr macAddr;
+ u16 priority:4;
+ u16 window:1;
+ u16 reserved:11;
+#else /* NAN_2_0 */
+ u32 matchHandle;
+ u32 priority:4;
+ u32 window:1;
+ u32 reserved:27;
+#endif /* NAN_2_0 */
+ /*
+ * Excludes TLVs
+ *
+ * Required: Service Specific Info or Extended Service Specific Info
+ */
+} NanTransmitFollowupReqParams;
+
+typedef struct PACKED
+{
+ NanMsgHeader fwHeader;
+ NanTransmitFollowupReqParams transmitFollowupReqParams;
+ u8 ptlv[];
+} NanTransmitFollowupReqMsg, *pNanTransmitFollowupReqMsg;
+
+/* NAN Transmit Followup Rsp */
+typedef struct PACKED
+{
+ NanMsgHeader fwHeader;
+ /* status of the request */
+ u16 status;
+ u16 value;
+} NanTransmitFollowupRspMsg, *pNanTransmitFollowupRspMsg;
+
+/* NAN Publish Followup Ind */
+typedef struct PACKED
+{
+#ifndef NAN_2_0
+ SirMacAddr macAddr;
+ u16 window:1;
+ u16 reserved:15;
+#else /* NAN_2_0 */
+ u32 matchHandle;
+ u32 window:1;
+ u32 reserved:31;
+#endif /* NAN_2_0 */
+ /*
+ * Excludes TLVs
+ *
+ * Required: Service Specific Info or Extended Service Specific Info
+ */
+} NanFollowupIndParams;
+
+typedef struct PACKED
+{
+ NanMsgHeader fwHeader;
+ NanFollowupIndParams followupIndParams;
+ u8 ptlv[];
+} NanFollowupIndMsg, *pNanFollowupIndMsg;
+
+/* NAN Statistics Req */
+typedef struct PACKED
+{
+ u32 statsId:8;
+ u32 clear:1;
+ u32 reserved:23;
+} NanStatsReqParams, *pNanStatsReqParams;
+
+typedef struct PACKED
+{
+ NanMsgHeader fwHeader;
+ NanStatsReqParams statsReqParams;
+} NanStatsReqMsg, *pNanStatsReqMsg;
+
+/* NAN Statistics Rsp */
+typedef struct PACKED
+{
+ /* status of the request */
+ u16 status;
+ u16 value;
+ u8 statsId;
+ u8 reserved;
+} NanStatsRspParams, *pNanStatsRspParams;
+
+typedef struct PACKED
+{
+ NanMsgHeader fwHeader;
+ NanStatsRspParams statsRspParams;
+ u8 ptlv[];
+} NanStatsRspMsg, *pNanStatsRspMsg;
+
+typedef struct PACKED
+{
+ u8 count:7;
+ u8 s:1;
+} NanSidAttr, *pSidAttr;
+
+
+/* NAN Configuration Req */
+typedef struct PACKED
+{
+ NanMsgHeader fwHeader;
+ /*
+ * TLVs:
+ *
+ * Required: None.
+ * Optional: SID, Random Time, Master Preference, WLAN Intra Attr,
+ * P2P Operation Attr, WLAN IBSS Attr, WLAN Mesh Attr
+ */
+ u8 ptlv[];
+} NanConfigurationReqMsg, *pNanConfigurationReqMsg;
+
+/*
+ * Because the Configuration Req message has TLVs in it use the macro below
+ * for the size argument to buffer allocation functions (vs. sizeof(msg)).
+ */
+#define NAN_MAX_CONFIGURATION_REQ_SIZE \
+ ( \
+ sizeof(NanMsgHeader) + \
+ SIZEOF_TLV_HDR + sizeof(u8) /* SID Beacon */ + \
+ SIZEOF_TLV_HDR + sizeof(u8) /* Random Time */ + \
+ SIZEOF_TLV_HDR + sizeof(u8) /* Master Pref */ \
+ )
+
+/* NAN Configuration Rsp */
+typedef struct PACKED
+{
+ NanMsgHeader fwHeader;
+ /* status of the request */
+ u16 status;
+ u16 value;
+} NanConfigurationRspMsg, *pNanConfigurationRspMsg;
+
+/*
+ * Because the Enable Req message has TLVs in it use the macro below for
+ * the size argument to buffer allocation functions (vs. sizeof(msg)).
+ */
+#define NAN_MAX_ENABLE_REQ_SIZE \
+ ( \
+ sizeof(NanMsgHeader) + \
+ SIZEOF_TLV_HDR + sizeof(u8) /* 5G */ + \
+ SIZEOF_TLV_HDR + sizeof(u16) /* Cluster Low */ + \
+ SIZEOF_TLV_HDR + sizeof(u16) /* Cluster High */ + \
+ SIZEOF_TLV_HDR + sizeof(u8) /* SID Beacon */ + \
+ SIZEOF_TLV_HDR + sizeof(u8) /* RSSI Close */ + \
+ SIZEOF_TLV_HDR + sizeof(u8) /* RSSI Medium */ + \
+ SIZEOF_TLV_HDR + sizeof(u8) /* HC Limit */ + \
+ SIZEOF_TLV_HDR + sizeof(u8) /* Random Time */ + \
+ SIZEOF_TLV_HDR + sizeof(u8) /* Master Pref */ + \
+ SIZEOF_TLV_HDR + sizeof(u8) /* Full Scan Int */ \
+ )
+
+/* NAN Enable Req */
+typedef struct PACKED
+{
+ NanMsgHeader fwHeader;
+ /*
+ * TLVs:
+ *
+ * Required: Cluster Low, Cluster High, Master Preference,
+ * Optional: 5G Support, SID, 5G Sync Disc, RSSI Close, RSSI Medium,
+ * Hop Count Limit, Random Time, Master Preference,
+ * WLAN Intra Attr, P2P Operation Attr, WLAN IBSS Attr,
+ * WLAN Mesh Attr
+ */
+ u8 ptlv[];
+} NanEnableReqMsg, *pNanEnableReqMsg;
+
+/* NAN Enable Rsp */
+typedef struct PACKED
+{
+ NanMsgHeader fwHeader;
+ /* status of the request */
+ u16 status;
+ u16 value;
+} NanEnableRspMsg, *pNanEnableRspMsg;
+
+/* NAN Disable Req */
+typedef struct PACKED
+{
+ NanMsgHeader fwHeader;
+} NanDisableReqMsg, *pNanDisableReqMsg;
+
+/* NAN Disable Rsp */
+typedef struct PACKED
+{
+ NanMsgHeader fwHeader;
+ /* status of the request */
+ u16 status;
+ u16 reserved;
+} NanDisableRspMsg, *pNanDisableRspMsg;
+
+/* NAN Disable Ind */
+typedef struct PACKED
+{
+ NanMsgHeader fwHeader;
+ /* reason for the termination */
+ u16 reason;
+ u16 reserved;
+} NanDisableIndMsg, *pNanDisableIndMsg;
+
+/* NAN TCA Req */
+typedef struct PACKED
+{
+ u32 tcaId:8;
+ u32 rising:1;
+ u32 falling:1;
+ u32 clear:1;
+ u32 reserved:21;
+ u32 threshold;
+} NanTcaReqParams, *pNanTcaReqParams;
+
+typedef struct PACKED
+{
+ NanMsgHeader fwHeader;
+#ifndef NAN_2_0
+ NanTcaReqParams tcaReqParams;
+#else /* NAN_2_0 */
+ u8 ptlv[];
+#endif
+} NanTcaReqMsg, *pNanTcaReqMsg;
+
+/* NAN TCA Rsp */
+typedef struct PACKED
+{
+ NanMsgHeader fwHeader;
+ /* status of the request */
+ u16 status;
+ u16 value;
+} NanTcaRspMsg, *pNanTcaRspMsg;
+
+/* NAN TCA Ind */
+typedef struct PACKED
+{
+ u32 tcaId:8;
+ u32 reserved:24;
+} NanTcaIndParams, *pNanTcaIndParams;
+
+typedef struct PACKED
+{
+ NanMsgHeader fwHeader;
+#ifndef NAN_2_0
+ NanTcaIndParams tcaIndParams;
+#endif /* NAN_2_0 */
+ /*
+ * TLVs:
+ *
+ * Optional: Cluster size.
+ */
+ u8 ptlv[];
+} NanTcaIndMsg, *pNanTcaIndMsg;
+
+/*
+ * Because the TCA Ind message has TLVs in it use the macro below for the
+ * size argument to buffer allocation functions (vs. sizeof(msg)).
+ */
+#define NAN_MAX_TCA_IND_SIZE \
+ ( \
+ sizeof(NanMsgHeader) + \
+ sizeof(NanTcaIndParams) + \
+ SIZEOF_TLV_HDR + sizeof(u16) /* Cluster Size */ \
+ )
+
+/* Function Declarations */
+u8* addTlv(u16 type, u16 length, const u8* value, u8* pOutTlv);
+u16 NANTLV_ReadTlv(u8 *pInTlv, pNanTlv pOutTlv);
+u16 NANTLV_WriteTlv(pNanTlv pInTlv, u8 *pOutTlv);
+
+u16 getNanTlvtypeFromFWTlvtype(u16 fwTlvtype);
+u16 getFWTlvtypeFromNanTlvtype(u16 nanTlvtype);
+
+#ifdef NAN_2_0
+/* NAN Beacon Sdf Payload Req */
+typedef struct PACKED
+{
+ NanMsgHeader fwHeader;
+ /*
+ * TLVs:
+ *
+ * Optional: Vendor specific attribute
+ */
+ u8 ptlv[];
+} NanBeaconSdfPayloadReqMsg, *pNanBeaconSdfPayloadReqMsg;
+
+/* NAN Beacon Sdf Payload Rsp */
+typedef struct PACKED
+{
+ NanMsgHeader fwHeader;
+ /* status of the request */
+ u16 status;
+ u16 reserved;
+} NanBeaconSdfPayloadRspMsg, *pNanBeaconSdfPayloadRspMsg;
+
+/* NAN Beacon Sdf Payload Ind */
+typedef struct PACKED
+{
+ NanMsgHeader fwHeader;
+ /*
+ * TLVs:
+ *
+ * Required: Mac address
+ * Optional: Vendor specific attribute, sdf payload
+ * receive
+ */
+ u8 ptlv[];
+} NanBeaconSdfPayloadIndMsg, *pNanBeaconSdfPayloadIndMsg;
+
+
+typedef enum
+{
+ NAN_TLV_TYPE_FW_FIRST = 0,
+
+ /* Service Discovery Frame types */
+ NAN_TLV_TYPE_FW_SDF_FIRST = NAN_TLV_TYPE_FW_FIRST,
+ NAN_TLV_TYPE_FW_SERVICE_NAME = NAN_TLV_TYPE_FW_SDF_FIRST,
+ NAN_TLV_TYPE_FW_SDF_MATCH_FILTER,
+ NAN_TLV_TYPE_FW_TX_MATCH_FILTER,
+ NAN_TLV_TYPE_FW_RX_MATCH_FILTER,
+ NAN_TLV_TYPE_FW_SERVICE_SPECIFIC_INFO,
+ NAN_TLV_TYPE_FW_EXT_SERVICE_SPECIFIC_INFO =5,
+ NAN_TLV_TYPE_FW_VENDOR_SPECIFIC_ATTRIBUTE_TRANSMIT = 6,
+ NAN_TLV_TYPE_FW_VENDOR_SPECIFIC_ATTRIBUTE_RECEIVE = 7,
+ NAN_TLV_TYPE_FW_POST_NAN_CONNECTIVITY_CAPABILITIES_RECEIVE = 8,
+ NAN_TLV_TYPE_FW_POST_NAN_DISCOVERY_ATTRIBUTE_RECEIVE = 9,
+ NAN_TLV_TYPE_FW_BEACON_SDF_PAYLOAD_RECEIVE = 10,
+ NAN_TLV_TYPE_FW_SDF_LAST = 4095,
+
+ /* Configuration types */
+ NAN_TLV_TYPE_FW_CONFIG_FIRST = 4096,
+ NAN_TLV_TYPE_FW_24G_SUPPORT = NAN_TLV_TYPE_FW_CONFIG_FIRST,
+ NAN_TLV_TYPE_FW_24G_BEACON,
+ NAN_TLV_TYPE_FW_24G_SDF,
+ NAN_TLV_TYPE_FW_24G_RSSI_CLOSE,
+ NAN_TLV_TYPE_FW_24G_RSSI_MIDDLE,
+ NAN_TLV_TYPE_FW_24G_RSSI_CLOSE_PROXIMITY,
+ NAN_TLV_TYPE_FW_5G_SUPPORT,
+ NAN_TLV_TYPE_FW_5G_BEACON,
+ NAN_TLV_TYPE_FW_5G_SDF,
+ NAN_TLV_TYPE_FW_5G_RSSI_CLOSE,
+ NAN_TLV_TYPE_FW_5G_RSSI_MIDDLE,
+ NAN_TLV_TYPE_FW_5G_RSSI_CLOSE_PROXIMITY,
+ NAN_TLV_TYPE_FW_SID_BEACON,
+ NAN_TLV_TYPE_FW_HOP_COUNT_LIMIT,
+ NAN_TLV_TYPE_FW_MASTER_PREFERENCE,
+ NAN_TLV_TYPE_FW_CLUSTER_ID_LOW,
+ NAN_TLV_TYPE_FW_CLUSTER_ID_HIGH,
+ NAN_TLV_TYPE_FW_RSSI_AVERAGING_WINDOW_SIZE,
+ NAN_TLV_TYPE_FW_CLUSTER_OUI_NETWORK_ID,
+ NAN_TLV_TYPE_FW_SOURCE_MAC_ADDRESS,
+ NAN_TLV_TYPE_FW_CLUSTER_ATTRIBUTE_IN_SDF,
+ NAN_TLV_TYPE_FW_SOCIAL_CHANNEL_SCAN_PARAMS,
+ NAN_TLV_TYPE_FW_DEBUGGING_FLAGS,
+ NAN_TLV_TYPE_FW_POST_NAN_CONNECTIVITY_CAPABILITIES_TRANSMIT,
+ NAN_TLV_TYPE_FW_POST_NAN_DISCOVERY_ATTRIBUTE_TRANSMIT,
+ NAN_TLV_TYPE_FW_FURTHER_AVAILABILITY_MAP,
+ NAN_TLV_TYPE_FW_HOP_COUNT_FORCE,
+ NAN_TLV_TYPE_FW_RANDOM_FACTOR_FORCE,
+ NAN_TLV_TYPE_FW_CONFIG_LAST = 8191,
+
+ /* Attributes types */
+ NAN_TLV_TYPE_FW_ATTRS_FIRST = 8192,
+ NAN_TLV_TYPE_FW_AVAILABILITY_INTERVALS_MAP = NAN_TLV_TYPE_FW_ATTRS_FIRST,
+ NAN_TLV_TYPE_FW_WLAN_MESH_ID,
+ NAN_TLV_TYPE_FW_MAC_ADDRESS,
+ NAN_TLV_TYPE_FW_RECEIVED_RSSI_VALUE,
+ NAN_TLV_TYPE_FW_CLUSTER_ATTRIBUTE,
+ NAN_TLV_TYPE_FW_WLAN_INFRASTRUCTURE_SSID,
+ NAN_TLV_TYPE_FW_ATTRS_LAST = 12287,
+
+ /* Events Type */
+ NAN_TLV_TYPE_FW_EVENTS_FIRST = 12288,
+ NAN_TLV_TYPE_FW_EVENT_SELF_STATION_MAC_ADDRESS = NAN_TLV_TYPE_FW_EVENTS_FIRST,
+ NAN_TLV_TYPE_FW_EVENT_STARTED_CLUSTER,
+ NAN_TLV_TYPE_FW_EVENT_JOINED_CLUSTER,
+ NAN_TLV_TYPE_FW_EVENT_CLUSTER_SCAN_RESULTS,
+ NAN_TLV_TYPE_FW_EVENTS_LAST = 16383,
+
+ /* TCA Type */
+ NAN_TLV_TYPE_FW_TCA_FIRST = 16384,
+ NAN_TLV_TYPE_FW_TCA_CLUSTER_SIZE_REQ = NAN_TLV_TYPE_FW_TCA_FIRST,
+ NAN_TLV_TYPE_FW_TCA_CLUSTER_SIZE_RSP,
+ NAN_TLV_TYPE_FW_TCA_LAST = 16385,
+ /* Reserved 16386 - 20479*/
+ /* Reserved 20480 - 65535*/
+ NAN_TLV_TYPE_FW_LAST = 65535
+} NanFwTlvType;
+#endif /* NAN_2_0 */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __NAN_I_H__ */
+
diff --git a/qcwcn/wifi_hal/nan_ind.cpp b/qcwcn/wifi_hal/nan_ind.cpp
new file mode 100644
index 0000000..f69e718
--- /dev/null
+++ b/qcwcn/wifi_hal/nan_ind.cpp
@@ -0,0 +1,956 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "sync.h"
+#include <utils/Log.h>
+#include "wifi_hal.h"
+#include "nan.h"
+#include "nan_i.h"
+#include "nancommand.h"
+
+#define NAN_TERMINATED_BEGINNING_OFFSET 8192
+
+//Function which calls the necessaryIndication callback
+//based on the indication type
+int NanCommand::handleNanIndication()
+{
+ //Based on the message_id in the header determine the Indication type
+ //and call the necessary callback handler
+ u16 msg_id;
+ int res = 0;
+
+ ALOGI("handleNanIndication called %p", this);
+ msg_id = getIndicationType();
+
+ ALOGI("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));
+ res = getNanPublishTerminated(&publishTerminatedInd);
+ if (!res && mHandler.EventPublishTerminated) {
+ (*mHandler.EventPublishTerminated)(&publishTerminatedInd);
+ }
+ break;
+
+ case NAN_INDICATION_MATCH:
+ NanMatchInd matchInd;
+ memset(&matchInd, 0, sizeof(matchInd));
+ res = getNanMatch(&matchInd);
+ if (!res && mHandler.EventMatch) {
+ (*mHandler.EventMatch)(&matchInd);
+ }
+ break;
+
+ case NAN_INDICATION_UNMATCH:
+ NanUnmatchInd unMatchInd;
+ memset(&unMatchInd, 0, sizeof(unMatchInd));
+ res = getNanUnMatch(&unMatchInd);
+ if (!res && mHandler.EventUnMatch) {
+ (*mHandler.EventUnMatch)(&unMatchInd);
+ }
+ break;
+
+ case NAN_INDICATION_SUBSCRIBE_TERMINATED:
+ NanSubscribeTerminatedInd subscribeTerminatedInd;
+ memset(&subscribeTerminatedInd, 0, sizeof(subscribeTerminatedInd));
+ res = getNanSubscribeTerminated(&subscribeTerminatedInd);
+ if (!res && mHandler.EventSubscribeTerminated) {
+ (*mHandler.EventSubscribeTerminated)(&subscribeTerminatedInd);
+ }
+ break;
+
+ case NAN_INDICATION_DE_EVENT:
+ NanDiscEngEventInd discEngEventInd;
+ memset(&discEngEventInd, 0, sizeof(discEngEventInd));
+ res = getNanDiscEngEvent(&discEngEventInd);
+ if (!res && mHandler.EventDiscEngEvent) {
+ (*mHandler.EventDiscEngEvent)(&discEngEventInd);
+ }
+ break;
+
+ case NAN_INDICATION_FOLLOWUP:
+ NanFollowupInd followupInd;
+ memset(&followupInd, 0, sizeof(followupInd));
+ res = getNanFollowup(&followupInd);
+ if (!res && mHandler.EventFollowup) {
+ (*mHandler.EventFollowup)(&followupInd);
+ }
+ break;
+
+ case NAN_INDICATION_DISABLED:
+ NanDisabledInd disabledInd;
+ memset(&disabledInd, 0, sizeof(disabledInd));
+ res = getNanDisabled(&disabledInd);
+ if (!res && mHandler.EventDisabled) {
+ (*mHandler.EventDisabled)(&disabledInd);
+ }
+ break;
+
+ case NAN_INDICATION_TCA:
+ NanTCAInd tcaInd;
+ memset(&tcaInd, 0, sizeof(tcaInd));
+ res = getNanTca(&tcaInd);
+ if (!res && mHandler.EventTca) {
+ (*mHandler.EventTca)(&tcaInd);
+ }
+ break;
+
+ case NAN_INDICATION_BEACON_SDF_PAYLOAD:
+ NanBeaconSdfPayloadInd beaconSdfPayloadInd;
+ memset(&beaconSdfPayloadInd, 0, sizeof(beaconSdfPayloadInd));
+ res = getNanBeaconSdfPayload(&beaconSdfPayloadInd);
+ if (!res && mHandler.EventSdfPayload) {
+ (*mHandler.EventSdfPayload)(&beaconSdfPayloadInd);
+ }
+ break;
+
+ default:
+ ALOGE("handleNanIndication error invalid msg_id:%u", msg_id);
+ res = (int)WIFI_ERROR_INVALID_REQUEST_ID;
+ break;
+ }
+ return res;
+}
+
+//Function which will return the Nan Indication type based on
+//the initial few bytes of mNanVendorEvent
+NanIndicationType NanCommand::getIndicationType()
+{
+ if (mNanVendorEvent == NULL) {
+ ALOGE("%s: Invalid argument mNanVendorEvent:%p",
+ __func__, mNanVendorEvent);
+ return NAN_INDICATION_UNKNOWN;
+ }
+
+ NanMsgHeader *pHeader = (NanMsgHeader *)mNanVendorEvent;
+
+ switch (pHeader->msgId) {
+ case NAN_MSG_ID_PUBLISH_REPLIED_IND:
+ return NAN_INDICATION_PUBLISH_REPLIED;
+ case NAN_MSG_ID_PUBLISH_TERMINATED_IND:
+ return NAN_INDICATION_PUBLISH_TERMINATED;
+ case NAN_MSG_ID_MATCH_IND:
+ return NAN_INDICATION_MATCH;
+ case NAN_MSG_ID_UNMATCH_IND:
+ return NAN_INDICATION_UNMATCH;
+ case NAN_MSG_ID_FOLLOWUP_IND:
+ return NAN_INDICATION_FOLLOWUP;
+ case NAN_MSG_ID_SUBSCRIBE_TERMINATED_IND:
+ return NAN_INDICATION_SUBSCRIBE_TERMINATED;
+ case NAN_MSG_ID_DE_EVENT_IND:
+ return NAN_INDICATION_DE_EVENT;
+ case NAN_MSG_ID_DISABLE_IND:
+ return NAN_INDICATION_DISABLED;
+ case NAN_MSG_ID_TCA_IND:
+ return NAN_INDICATION_TCA;
+#ifdef NAN_2_0
+ case NAN_MSG_ID_BEACON_SDF_IND:
+ return NAN_INDICATION_BEACON_SDF_PAYLOAD;
+#endif /* NAN_2_0 */
+ default:
+ return NAN_INDICATION_UNKNOWN;
+ }
+}
+
+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->header.handle = pRsp->fwHeader.handle;
+ event->header.transaction_id = pRsp->fwHeader.transactionId;
+#ifndef NAN_2_0
+ memcpy(event->addr, pRsp->publishRepliedIndParams.macAddr, sizeof(event->addr));
+#else /* NAN_2_0 */
+ event->rssi_value = 0;
+ u8 *pInputTlv = pRsp->ptlv;
+ NanTlv outputTlv;
+ u16 readLen = 0;
+ int ret = 0;
+ int remainingLen = (mNanDataLen - \
+ (sizeof(NanMsgHeader)));
+
+ //Has NAN Mac address mandatory, received RSSI value optional
+ //POST_NAN_CONNECTIVITY_CAPABILITIES_RECEIVE
+ //POST_NAN_DISCOVERY_ATTRIBUTE_RECEIVE
+ //NAN_FURTHER_AVAILABILITY_MAP
+ //NAN_CLUSTER_ATTRIBUTE
+ if (remainingLen <= 0) {
+ ALOGI("%s: No TLV's present",__func__);
+ return WIFI_SUCCESS;
+ }
+ ALOGI("%s: TLV remaining Len:%d",__func__, remainingLen);
+ while ((remainingLen > 0) &&
+ (0 != (readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv)))) {
+ ALOGI("%s: Remaining Len:%d readLen:%d type:%d length:%d",
+ __func__, remainingLen, readLen, outputTlv.type,
+ outputTlv.length);
+ 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;
+ case NAN_TLV_TYPE_POST_NAN_CONNECTIVITY_CAPABILITIES_RECEIVE:
+ if (outputTlv.length != sizeof(u32)) {
+ ALOGE("NAN_TLV_TYPE_POST_NAN_CONNECTIVITY_CAPABILITIES_RECEIVE"
+ "Incorrect size:%d expecting %d", outputTlv.length,
+ sizeof(u32));
+ break;
+ }
+ event->is_conn_capability_valid = 1;
+ /* Populate conn_capability from received TLV */
+ getNanReceivePostConnectivityCapabilityVal(outputTlv.value,
+ &event->conn_capability);
+ break;
+ case NAN_TLV_TYPE_POST_NAN_DISCOVERY_ATTRIBUTE_RECEIVE:
+ /* Populate receive discovery attribute from
+ received TLV */
+ ret = getNanReceivePostDiscoveryVal(outputTlv.value,
+ outputTlv.length,
+ &event->discovery_attr);
+ if (ret == 0) {
+ event->is_discovery_attr_valid = 1;
+ }
+ else {
+ ALOGE("NAN_TLV_TYPE_POST_NAN_DISCOVERY_ATTRIBUTE_RECEIVE"
+ "Incorrect");
+ }
+ break;
+ case NAN_TLV_TYPE_FURTHER_AVAILABILITY_MAP:
+ /* Populate further availability bitmap from
+ received TLV */
+ ret = getNanFurtherAvailabilityMap(outputTlv.value,
+ outputTlv.length,
+ &event->fam);
+ if (ret == 0) {
+ event->is_fam_valid = 1;
+ }
+ else {
+ ALOGE("NAN_TLV_TYPE_FURTHER_AVAILABILITY_MAP"
+ "Incorrect");
+ }
+ break;
+ case NAN_TLV_TYPE_CLUSTER_ATTIBUTE:
+ if (outputTlv.length > sizeof(event->cluster_attribute)) {
+ outputTlv.length = sizeof(event->cluster_attribute);
+ }
+ memcpy(event->cluster_attribute,
+ outputTlv.value, outputTlv.length);
+ event->cluster_attribute_len = outputTlv.length;
+ break;
+ default:
+ ALOGI("Unknown TLV type skipped");
+ break;
+ }
+ remainingLen -= readLen;
+ pInputTlv += readLen;
+ memset(&outputTlv, 0, sizeof(outputTlv));
+ }
+#endif /* NAN_2_0 */
+ return WIFI_SUCCESS;
+}
+
+
+int NanCommand::getNanPublishTerminated(NanPublishTerminatedInd *event)
+{
+ if (event == NULL || mNanVendorEvent == NULL) {
+ ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p",
+ __func__, event, mNanVendorEvent);
+ return WIFI_ERROR_INVALID_ARGS;
+ }
+
+ pNanPublishTerminatedIndMsg pRsp = (pNanPublishTerminatedIndMsg)mNanVendorEvent;
+ event->header.handle = pRsp->fwHeader.handle;
+ event->header.transaction_id = pRsp->fwHeader.transactionId;
+#ifdef NAN_2_0
+ pRsp->reason -= NAN_TERMINATED_BEGINNING_OFFSET;
+#endif /* NAN_2_0 */
+ event->reason = (NanTerminatedStatus)pRsp->reason;
+ return WIFI_SUCCESS;
+}
+
+int NanCommand::getNanMatch(NanMatchInd *event)
+{
+ if (event == NULL || mNanVendorEvent == NULL) {
+ ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p",
+ __func__, event, mNanVendorEvent);
+ return WIFI_ERROR_INVALID_ARGS;
+ }
+
+ pNanMatchIndMsg pRsp = (pNanMatchIndMsg)mNanVendorEvent;
+ event->header.handle = pRsp->fwHeader.handle;
+ event->header.transaction_id = pRsp->fwHeader.transactionId;
+ event->match_handle = pRsp->matchIndParams.matchHandle;
+#ifndef NAN_2_0
+ memcpy(event->addr, pRsp->matchIndParams.macAddr, sizeof(event->addr));
+#else /* NAN_2_0 */
+ event->match_occured_flag = pRsp->matchIndParams.matchOccuredFlag;
+ event->out_of_resource_flag = pRsp->matchIndParams.outOfResourceFlag;
+#endif /* NAN_2_0 */
+
+ u8 *pInputTlv = pRsp->ptlv;
+ NanTlv outputTlv;
+ u16 readLen = 0;
+ int remainingLen = (mNanDataLen - \
+ (sizeof(NanMsgHeader) + sizeof(NanMatchIndParams)));
+ int ret = 0;
+
+ //Has SDF match filter and service specific info TLV
+ if (remainingLen <= 0) {
+ ALOGI("%s: No TLV's present",__func__);
+ return WIFI_SUCCESS;
+ }
+ ALOGI("%s: TLV remaining Len:%d",__func__, remainingLen);
+ while ((remainingLen > 0) &&
+ (0 != (readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv)))) {
+ ALOGI("%s: Remaining Len:%d readLen:%d type:%d length:%d",
+ __func__, remainingLen, readLen, outputTlv.type,
+ outputTlv.length);
+ switch (outputTlv.type) {
+ case NAN_TLV_TYPE_SERVICE_SPECIFIC_INFO:
+ if (outputTlv.length > NAN_MAX_SERVICE_NAME_LEN) {
+ outputTlv.length = NAN_MAX_SERVICE_NAME_LEN;
+ }
+ event->service_specific_info_len = outputTlv.length;
+ memcpy(event->service_specific_info, outputTlv.value,
+ outputTlv.length);
+ break;
+ case NAN_TLV_TYPE_SDF_MATCH_FILTER:
+ if (outputTlv.length > NAN_MAX_MATCH_FILTER_LEN) {
+ outputTlv.length = NAN_MAX_MATCH_FILTER_LEN;
+ }
+ event->sdf_match_filter_len = outputTlv.length;
+ memcpy(event->sdf_match_filter, outputTlv.value,
+ outputTlv.length);
+ break;
+#ifdef NAN_2_0
+ 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;
+ case NAN_TLV_TYPE_POST_NAN_CONNECTIVITY_CAPABILITIES_RECEIVE:
+ if (outputTlv.length != sizeof(u32)) {
+ ALOGE("NAN_TLV_TYPE_POST_NAN_CONNECTIVITY_CAPABILITIES_RECEIVE"
+ "Incorrect size:%d expecting %d", outputTlv.length,
+ sizeof(u32));
+ break;
+ }
+ event->is_conn_capability_valid = 1;
+ /* Populate conn_capability from received TLV */
+ getNanReceivePostConnectivityCapabilityVal(outputTlv.value,
+ &event->conn_capability);
+ break;
+ case NAN_TLV_TYPE_POST_NAN_DISCOVERY_ATTRIBUTE_RECEIVE:
+ /* Populate receive discovery attribute from
+ received TLV */
+ ret = getNanReceivePostDiscoveryVal(outputTlv.value,
+ outputTlv.length,
+ &event->discovery_attr);
+ if (ret == 0) {
+ event->is_discovery_attr_valid = 1;
+ }
+ else {
+ ALOGE("NAN_TLV_TYPE_POST_NAN_DISCOVERY_ATTRIBUTE_RECEIVE"
+ "Incorrect");
+ }
+ break;
+ case NAN_TLV_TYPE_FURTHER_AVAILABILITY_MAP:
+ /* Populate further availability bitmap from
+ received TLV */
+ ret = getNanFurtherAvailabilityMap(outputTlv.value,
+ outputTlv.length,
+ &event->fam);
+ if (ret == 0) {
+ event->is_fam_valid = 1;
+ }
+ else {
+ ALOGE("NAN_TLV_TYPE_FURTHER_AVAILABILITY_MAP"
+ "Incorrect");
+ }
+ break;
+ case NAN_TLV_TYPE_CLUSTER_ATTIBUTE:
+ if (outputTlv.length > sizeof(event->cluster_attribute)) {
+ outputTlv.length = sizeof(event->cluster_attribute);
+ }
+ memcpy(event->cluster_attribute,
+ outputTlv.value, outputTlv.length);
+ event->cluster_attribute_len = outputTlv.length;
+ break;
+#endif /* NAN_2_0 */
+ default:
+ ALOGI("Unknown TLV type skipped");
+ break;
+ }
+ remainingLen -= readLen;
+ pInputTlv += readLen;
+ memset(&outputTlv, 0, sizeof(outputTlv));
+ }
+ return WIFI_SUCCESS;
+}
+
+int NanCommand::getNanUnMatch(NanUnmatchInd *event)
+{
+ if (event == NULL || mNanVendorEvent == NULL) {
+ ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p",
+ __func__, event, mNanVendorEvent);
+ return WIFI_ERROR_INVALID_ARGS;
+ }
+
+ pNanUnmatchIndMsg pRsp = (pNanUnmatchIndMsg)mNanVendorEvent;
+ event->header.handle = pRsp->fwHeader.handle;
+ event->header.transaction_id = pRsp->fwHeader.transactionId;
+ event->match_handle = pRsp->unmatchIndParams.matchHandle;
+ return WIFI_SUCCESS;
+}
+
+int NanCommand::getNanSubscribeTerminated(NanSubscribeTerminatedInd *event)
+{
+ if (event == NULL || mNanVendorEvent == NULL) {
+ ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p",
+ __func__, event, mNanVendorEvent);
+ return WIFI_ERROR_INVALID_ARGS;
+ }
+
+ pNanSubscribeTerminatedIndMsg pRsp = (pNanSubscribeTerminatedIndMsg)mNanVendorEvent;
+ event->header.handle = pRsp->fwHeader.handle;
+ event->header.transaction_id = pRsp->fwHeader.transactionId;
+#ifdef NAN_2_0
+ pRsp->reason -= NAN_TERMINATED_BEGINNING_OFFSET;
+#endif /* NAN_2_0 */
+ event->reason = (NanTerminatedStatus)pRsp->reason;
+ return WIFI_SUCCESS;
+}
+
+int NanCommand::getNanFollowup(NanFollowupInd *event)
+{
+ if (event == NULL || mNanVendorEvent == NULL) {
+ ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p",
+ __func__, event, mNanVendorEvent);
+ return WIFI_ERROR_INVALID_ARGS;
+ }
+
+ pNanFollowupIndMsg pRsp = (pNanFollowupIndMsg)mNanVendorEvent;
+ event->header.handle = pRsp->fwHeader.handle;
+ event->header.transaction_id = pRsp->fwHeader.transactionId;
+#ifndef NAN_2_0
+ memcpy(event->addr, pRsp->followupIndParams.macAddr, sizeof(event->addr));
+#else /* NAN_2_0*/
+ event->match_handle = pRsp->followupIndParams.matchHandle;
+#endif
+ event->dw_or_faw = pRsp->followupIndParams.window;
+
+ u8 *pInputTlv = pRsp->ptlv;
+ NanTlv outputTlv;
+ u16 readLen = 0;
+ int remainingLen = (mNanDataLen - \
+ (sizeof(NanMsgHeader) + sizeof(NanFollowupIndParams)));
+
+ //Has service specific info and extended service specific info TLV
+ if (remainingLen <= 0) {
+ ALOGI("%s: No TLV's present",__func__);
+ return WIFI_SUCCESS;
+ }
+ ALOGI("%s: TLV remaining Len:%d",__func__, remainingLen);
+ while ((remainingLen > 0) &&
+ (0 != (readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv)))) {
+ ALOGI("%s: Remaining Len:%d readLen:%d type:%d length:%d",
+ __func__, remainingLen, readLen, outputTlv.type,
+ outputTlv.length);
+ switch (outputTlv.type) {
+ case NAN_TLV_TYPE_SERVICE_SPECIFIC_INFO:
+ case NAN_TLV_TYPE_EXT_SERVICE_SPECIFIC_INFO:
+ if (outputTlv.length > NAN_MAX_SERVICE_SPECIFIC_INFO_LEN) {
+ outputTlv.length = NAN_MAX_SERVICE_SPECIFIC_INFO_LEN;
+ }
+ event->service_specific_info_len = outputTlv.length;
+ memcpy(event->service_specific_info, outputTlv.value,
+ outputTlv.length);
+ break;
+#ifdef NAN_2_0
+ 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;
+#endif /* NAN_2_0 */
+ default:
+ ALOGI("Unknown TLV type skipped");
+ break;
+ }
+ remainingLen -= readLen;
+ pInputTlv += readLen;
+ memset(&outputTlv, 0, sizeof(outputTlv));
+ }
+ return WIFI_SUCCESS;
+}
+
+int NanCommand::getNanDiscEngEvent(NanDiscEngEventInd *event)
+{
+ if (event == NULL || mNanVendorEvent == NULL) {
+ ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p",
+ __func__, event, mNanVendorEvent);
+ return WIFI_ERROR_INVALID_ARGS;
+ }
+
+ pNanEventIndMsg pRsp = (pNanEventIndMsg)mNanVendorEvent;
+ event->header.handle = pRsp->fwHeader.handle;
+ event->header.transaction_id = pRsp->fwHeader.transactionId;
+#ifndef NAN_2_0
+ event->event_id = (NanEventId)pRsp->eventIndParams.eventId;
+#endif /* NAN_2_0 */
+ memset(&event->data, 0, sizeof(event->data));
+
+ u8 *pInputTlv = pRsp->ptlv;
+ NanTlv outputTlv;
+ u16 readLen = 0;
+#ifndef NAN_2_0
+ int remainingLen = (mNanDataLen - \
+ (sizeof(NanMsgHeader) + sizeof(NanEventIndParams)));
+#else /* NAN_2_0 */
+ int remainingLen = (mNanDataLen - \
+ (sizeof(NanMsgHeader)));
+#endif /* NAN_2_0 */
+
+ //Has Self-STA Mac TLV
+ if (remainingLen <= 0) {
+ ALOGI("%s: No TLV's present",__func__);
+ return WIFI_SUCCESS;
+ }
+
+ ALOGI("%s: TLV remaining Len:%d event_id:%d",__func__,
+ remainingLen, event->event_id);
+ while ((remainingLen > 0) &&
+ (0 != (readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv)))) {
+ ALOGI("%s: Remaining Len:%d readLen:%d type:%d length:%d",
+ __func__, remainingLen, readLen, outputTlv.type,
+ outputTlv.length);
+#ifdef NAN_2_0
+ event->event_id = (NanEventId)outputTlv.type;
+#endif /* NAN_2_0 */
+ //Here we should check on the event_id
+ switch (event->event_id) {
+ case NAN_EVENT_ID_STA_MAC_ADDR:
+ if (outputTlv.length > NAN_MAC_ADDR_LEN) {
+ ALOGI("%s: Reading only first %d bytes of TLV",
+ __func__, NAN_MAC_ADDR_LEN);
+ outputTlv.length = NAN_MAC_ADDR_LEN;
+ }
+ memcpy(event->data.mac_addr.addr, outputTlv.value,
+ outputTlv.length);
+ break;
+ case NAN_EVENT_ID_STARTED_CLUSTER:
+ case NAN_EVENT_ID_JOINED_CLUSTER:
+ if (outputTlv.length > NAN_MAC_ADDR_LEN) {
+ ALOGI("%s: Reading only first %d bytes of TLV",
+ __func__, NAN_MAC_ADDR_LEN);
+ outputTlv.length = NAN_MAC_ADDR_LEN;
+ }
+ memcpy(event->data.cluster.addr, outputTlv.value,
+ outputTlv.length);
+ break;
+ default:
+ ALOGI("Unhandled eventId:%d", event->event_id);
+ break;
+ }
+ remainingLen -= readLen;
+ pInputTlv += readLen;
+ memset(&outputTlv,0, sizeof(outputTlv));
+ }
+ return WIFI_SUCCESS;
+}
+
+int NanCommand::getNanDisabled(NanDisabledInd *event)
+{
+ if (event == NULL || mNanVendorEvent == NULL) {
+ ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p",
+ __func__, event, mNanVendorEvent);
+ return WIFI_ERROR_INVALID_ARGS;
+ }
+
+ pNanDisableIndMsg pRsp = (pNanDisableIndMsg)mNanVendorEvent;
+ event->header.handle = pRsp->fwHeader.handle;
+ event->header.transaction_id = pRsp->fwHeader.transactionId;
+ event->reason = (NanStatusType)pRsp->reason;
+ return WIFI_SUCCESS;
+
+}
+
+int NanCommand::getNanTca(NanTCAInd *event)
+{
+ if (event == NULL || mNanVendorEvent == NULL) {
+ ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p",
+ __func__, event, mNanVendorEvent);
+ return WIFI_ERROR_INVALID_ARGS;
+ }
+
+ pNanTcaIndMsg pRsp = (pNanTcaIndMsg)mNanVendorEvent;
+ event->header.handle = pRsp->fwHeader.handle;
+ event->header.transaction_id = pRsp->fwHeader.transactionId;
+ memset(&event->data, 0, sizeof(event->data));
+#ifndef NAN_2_0
+ event->tca_id = (NanTcaId)pRsp->tcaIndParams.tcaId;
+#else /* NAN_2_0 */
+ event->tca_id = (NanTcaId)0;
+#endif /* NAN_2_0 */
+
+ u8 *pInputTlv = pRsp->ptlv;
+ NanTlv outputTlv;
+ u16 readLen = 0;
+#ifndef NAN_2_0
+ int remainingLen = (mNanDataLen - \
+ (sizeof(NanMsgHeader) + sizeof(NanTcaIndParams)));
+#else
+ int remainingLen = (mNanDataLen - \
+ (sizeof(NanMsgHeader)));
+#endif
+
+ //Has NAN_TCA_ID_CLUSTER_SIZE
+ if (remainingLen <= 0) {
+ ALOGI("%s: No TLV's present",__func__);
+ return WIFI_SUCCESS;
+ }
+
+ ALOGI("%s: TLV remaining Len:%d tca_id:%d",__func__,
+ remainingLen, event->tca_id);
+ while ((remainingLen > 0) &&
+ (0 != (readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv)))) {
+ ALOGI("%s: Remaining Len:%d readLen:%d type:%d length:%d",
+ __func__, remainingLen, readLen, outputTlv.type,
+ outputTlv.length);
+ //Here we should check on the event_id
+ switch (event->tca_id) {
+ case NAN_TCA_ID_CLUSTER_SIZE:
+#ifndef NAN_2_0
+ if (outputTlv.length > sizeof(event->data.cluster.cluster_size)) {
+ outputTlv.length = sizeof(event->data.cluster.cluster_size);
+ }
+ memcpy(&(event->data.cluster.cluster_size), outputTlv.value,
+ outputTlv.length);
+#else /* NAN_2_0 */
+ if (outputTlv.length != 2 * sizeof(u32)) {
+ ALOGE("%s: Wrong length %d in Tca Indication expecting %d bytes",
+ __func__, outputTlv.length, 2 * sizeof(u32));
+ break;
+ }
+ event->rising_direction_evt_flag = outputTlv.value[0] & 0x01;
+ event->falling_direction_evt_flag = (outputTlv.value[0] & 0x02) >> 1;
+ memcpy(&(event->data.cluster.cluster_size), &outputTlv.value[4],
+ sizeof(event->data.cluster.cluster_size));
+#endif /* NAN_2_0 */
+ break;
+ default:
+ ALOGI("Unhandled eventId:%d", event->tca_id);
+ break;
+ }
+ remainingLen -= readLen;
+ pInputTlv += readLen;
+ memset(&outputTlv,0, sizeof(outputTlv));
+ }
+ return WIFI_SUCCESS;
+}
+
+int NanCommand::getNanBeaconSdfPayload(NanBeaconSdfPayloadInd *event)
+{
+ if (event == NULL || mNanVendorEvent == NULL) {
+ ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p",
+ __func__, event, mNanVendorEvent);
+ return WIFI_ERROR_INVALID_ARGS;
+ }
+
+#ifdef NAN_2_0
+ pNanBeaconSdfPayloadIndMsg pRsp = (pNanBeaconSdfPayloadIndMsg)mNanVendorEvent;
+ event->header.handle = pRsp->fwHeader.handle;
+ event->header.transaction_id = pRsp->fwHeader.transactionId;
+ memset(&event->data, 0, sizeof(event->data));
+
+ u8 *pInputTlv = pRsp->ptlv;
+ NanTlv outputTlv;
+ u16 readLen = 0;
+ int remainingLen = (mNanDataLen - \
+ (sizeof(NanMsgHeader)));
+
+ //Has Mac address
+ if (remainingLen <= 0) {
+ ALOGI("%s: No TLV's present",__func__);
+ return WIFI_SUCCESS;
+ }
+
+ ALOGI("%s: TLV remaining Len:%d",__func__, remainingLen);
+ while ((remainingLen > 0) &&
+ (0 != (readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv)))) {
+ ALOGI("%s: Remaining Len:%d readLen:%d type:%d length:%d",
+ __func__, remainingLen, readLen, outputTlv.type,
+ outputTlv.length);
+ //Here we should check on the event_id
+ switch (outputTlv.type) {
+ case NAN_TLV_TYPE_SELF_MAC_ADDR:
+ if (outputTlv.length > sizeof(event->addr)) {
+ outputTlv.length = sizeof(event->addr);
+ }
+ memcpy(event->addr, outputTlv.value,
+ outputTlv.length);
+ break;
+
+ case NAN_TLV_TYPE_VENDOR_SPECIFIC_ATTRIBUTE_RECEIVE:
+ {
+ NanReceiveVendorSpecificAttribute* recvVsaattr = &event->vsa;
+ if (outputTlv.length < sizeof(u32)) {
+ ALOGE("NAN_TLV_TYPE_VENDOR_SPECIFIC_ATTRIBUTE_RECEIVE"
+ "Incorrect length:%d", outputTlv.length);
+ break;
+ }
+ event->is_vsa_received = 1;
+ recvVsaattr->vsa_received_on = (outputTlv.value[0] >> 1) & 0x07;
+ memcpy(&recvVsaattr->vendor_oui, &outputTlv.value[1],
+ 3);
+ recvVsaattr->attr_len = outputTlv.length - 4;
+ if (recvVsaattr->attr_len > NAN_MAX_VSA_DATA_LEN) {
+ recvVsaattr->attr_len = NAN_MAX_VSA_DATA_LEN;
+ }
+ if (recvVsaattr->attr_len) {
+ memcpy(recvVsaattr->vsa, &outputTlv.value[4],
+ recvVsaattr->attr_len);
+ }
+ break;
+ }
+
+ case NAN_TLV_TYPE_BEACON_SDF_PAYLOAD_RECEIVE:
+ event->is_beacon_sdf_payload_received = 1;
+ event->data.frame_len = outputTlv.length;
+ if (event->data.frame_len > NAN_MAX_VSA_DATA_LEN) {
+ event->data.frame_len = NAN_MAX_VSA_DATA_LEN;
+ }
+ memcpy(&event->data.frame_data, &outputTlv.value[0],
+ event->data.frame_len);
+ break;
+
+ default:
+ ALOGI("Unhandled TLV Type:%d", outputTlv.type);
+ break;
+ }
+ remainingLen -= readLen;
+ pInputTlv += readLen;
+ memset(&outputTlv,0, sizeof(outputTlv));
+ }
+ return WIFI_SUCCESS;
+#else /* NAN_2_0 */
+ return WIFI_ERROR_INVALID_ARGS;
+#endif /* NAN_2_0 */
+}
+
+void NanCommand::getNanReceivePostConnectivityCapabilityVal(
+ const u8 *pInValue,
+ NanReceivePostConnectivityCapability *pRxCapab)
+{
+ if (pInValue && pRxCapab) {
+ pRxCapab->is_mesh_supported = (pInValue[0] && (0x01 << 5));
+ pRxCapab->is_ibss_supported = (pInValue[0] && (0x01 << 4));
+ pRxCapab->wlan_infra_field = (pInValue[0] && (0x01 << 3));
+ pRxCapab->is_tdls_supported = (pInValue[0] && (0x01 << 2));
+ pRxCapab->is_wfds_supported = (pInValue[0] && (0x01 << 1));
+ pRxCapab->is_wfd_supported = pInValue[0] && 0x01;
+ }
+}
+
+int NanCommand::getNanReceivePostDiscoveryVal(const u8 *pInValue,
+ u32 length,
+ NanReceivePostDiscovery *pRxDisc)
+{
+ int ret = 0;
+
+#ifdef NAN_2_0
+ if (length <= 8 || pInValue == NULL) {
+ ALOGE("%s: Invalid Arg TLV Len %d < 4",
+ __func__, length);
+ return -1;
+ }
+
+ pRxDisc->type = (NanConnectionType) pInValue[0];
+ pRxDisc->role = (NanDeviceRole) pInValue[1];
+ pRxDisc->duration = (NanAvailDuration) (pInValue[2] & 0x03);
+ pRxDisc->mapid = ((pInValue[2] >> 2) & 0x0F);
+ memcpy(&pRxDisc->avail_interval_bitmap,
+ &pInValue[4],
+ sizeof(pRxDisc->avail_interval_bitmap));
+
+ u8 *pInputTlv = (u8 *)&pInValue[8];
+ NanTlv outputTlv;
+ u16 readLen = 0;
+ int remainingLen = (length - 8);
+
+ //Has Mac address
+ if (remainingLen <= 0) {
+ ALOGE("%s: No TLV's present",__func__);
+ return -1;
+ }
+
+ ALOGI("%s: TLV remaining Len:%d",__func__, remainingLen);
+ while ((remainingLen > 0) &&
+ (0 != (readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv)))) {
+ ALOGI("%s: Remaining Len:%d readLen:%d type:%d length:%d",
+ __func__, remainingLen, readLen, outputTlv.type,
+ outputTlv.length);
+ switch (outputTlv.type) {
+ case NAN_TLV_TYPE_MAC_ADDRESS:
+ if (outputTlv.length > sizeof(pRxDisc->addr)) {
+ outputTlv.length = sizeof(pRxDisc->addr);
+ }
+ memcpy(pRxDisc->addr, outputTlv.value, outputTlv.length);
+ break;
+ case NAN_TLV_TYPE_WLAN_MESH_ID:
+ if (outputTlv.length > sizeof(pRxDisc->mesh_id)) {
+ outputTlv.length = sizeof(pRxDisc->mesh_id);
+ }
+ memcpy(pRxDisc->mesh_id, outputTlv.value, outputTlv.length);
+ pRxDisc->mesh_id_len = outputTlv.length;
+ break;
+ case NAN_TLV_TYPE_WLAN_INFRASTRUCTURE_SSID:
+ if (outputTlv.length > sizeof(pRxDisc->infrastructure_ssid_val)) {
+ outputTlv.length = sizeof(pRxDisc->infrastructure_ssid_val);
+ }
+ memcpy(pRxDisc->infrastructure_ssid_val, outputTlv.value,
+ outputTlv.length);
+ pRxDisc->infrastructure_ssid_len = outputTlv.length;
+ default:
+ ALOGI("Unhandled TLV Type:%d", outputTlv.type);
+ break;
+ }
+ remainingLen -= readLen;
+ pInputTlv += readLen;
+ memset(&outputTlv,0, sizeof(outputTlv));
+ }
+#endif /* NAN_2_0 */
+ return ret;
+}
+
+int NanCommand::getNanFurtherAvailabilityMap(const u8 *pInValue,
+ u32 length,
+ 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);
+ 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);
+ }
+ else {
+ memset(pFam->vendor_elements, 0,
+ sizeof(pFam->vendor_elements));
+ }
+#endif /* NAN_2_0*/
+ return 0;
+}
+
+int NanCommand::getNanStaParameter(NanStaParameter *pRsp)
+{
+ int ret = WIFI_ERROR_NONE;
+ int res = -1;
+
+ /*
+ Construct NL message to get the sync stats parameter
+ which has all the parameter required by staparameter.
+ */
+ NanStatsRequest syncStats;
+ memset(&syncStats, 0, sizeof(syncStats));
+ syncStats.header.handle = 0x0;
+ syncStats.header.transaction_id = 0x1234;
+ syncStats.stats_id = NAN_STATS_ID_DE_TIMING_SYNC;
+ syncStats.clear = 0;
+
+ mStaParam = pRsp;
+ ret = putNanStats(&syncStats);
+ if (ret != 0) {
+ ALOGE("%s: putNanStats Error:%d",__func__, ret);
+ goto cleanup;
+ }
+ ret = requestEvent();
+ if (ret != 0) {
+ ALOGE("%s: requestEvent Error:%d",__func__, ret);
+ goto cleanup;
+ }
+
+ struct timespec abstime;
+ abstime.tv_sec = 4;
+ abstime.tv_nsec = 0;
+ res = mCondition.wait(abstime);
+ if (res == ETIMEDOUT)
+ {
+ ALOGE("%s: Time out happened.", __func__);
+ ret = WIFI_ERROR_TIMED_OUT;
+ goto cleanup;
+ }
+ ALOGI("%s: NanStaparameter Master_pref:%x," \
+ " Random_factor:%x, hop_count:%x " \
+ " beacon_transmit_time:%d", __func__,
+ pRsp->master_pref, pRsp->random_factor,
+ pRsp->hop_count, pRsp->beacon_transmit_time);
+cleanup:
+ mStaParam = NULL;
+ return (int)ret;
+}
diff --git a/qcwcn/wifi_hal/nan_req.cpp b/qcwcn/wifi_hal/nan_req.cpp
new file mode 100644
index 0000000..250a5bd
--- /dev/null
+++ b/qcwcn/wifi_hal/nan_req.cpp
@@ -0,0 +1,1071 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "sync.h"
+#include <utils/Log.h>
+#include "wifi_hal.h"
+#include "nan.h"
+#include "nan_i.h"
+#include "nancommand.h"
+
+int NanCommand::putNanEnable(const NanEnableRequest *pReq)
+{
+ ALOGI("NAN_ENABLE");
+ size_t message_len = NAN_MAX_ENABLE_REQ_SIZE;
+
+ if (pReq == NULL) {
+ return WIFI_ERROR_INVALID_ARGS;
+ }
+
+#ifdef NAN_2_0
+ /* Removing the unsupported ones */
+ message_len -= \
+ (SIZEOF_TLV_HDR + sizeof(u8) /* Random Time */ + \
+ SIZEOF_TLV_HDR + sizeof(u8) /* Full Scan Int */);
+
+ message_len += \
+ (
+ pReq->config_2dot4g_support ? (SIZEOF_TLV_HDR + \
+ sizeof(pReq->support_2dot4g_val)) : 0 \
+ ) + \
+ (
+ pReq->config_2dot4g_beacons ? (SIZEOF_TLV_HDR + \
+ sizeof(pReq->beacon_2dot4g_val)) : 0 \
+ ) + \
+ (
+ pReq->config_2dot4g_discovery ? (SIZEOF_TLV_HDR + \
+ sizeof(pReq->discovery_2dot4g_val)) : 0 \
+ ) + \
+ (
+ pReq->config_5g_beacons ? (SIZEOF_TLV_HDR + \
+ sizeof(pReq->beacon_5g_val)) : 0 \
+ ) + \
+ (
+ pReq->config_5g_discovery ? (SIZEOF_TLV_HDR + \
+ sizeof(pReq->discovery_5g_val)) : 0 \
+ ) + \
+ (
+ pReq->config_5g_rssi_close ? (SIZEOF_TLV_HDR + \
+ sizeof(pReq->rssi_close_5g_val)) : 0 \
+ ) + \
+ (
+ pReq->config_5g_rssi_middle ? (SIZEOF_TLV_HDR + \
+ sizeof(pReq->rssi_middle_5g_val)) : 0 \
+ ) + \
+ (
+ pReq->config_5g_rssi_close_proximity ? (SIZEOF_TLV_HDR + \
+ sizeof(pReq->rssi_close_proximity_5g_val)) : 0 \
+ ) + \
+ (
+ pReq->config_rssi_window_size ? (SIZEOF_TLV_HDR + \
+ sizeof(pReq->rssi_window_size_val)) : 0 \
+ ) + \
+ (
+ pReq->config_oui ? (SIZEOF_TLV_HDR + \
+ sizeof(pReq->oui_val)) : 0 \
+ ) + \
+ (
+ pReq->config_intf_addr ? (SIZEOF_TLV_HDR + \
+ sizeof(pReq->intf_addr_val)) : 0 \
+ ) + \
+ (
+ pReq->config_cluster_attribute_val ? (SIZEOF_TLV_HDR + \
+ sizeof(pReq->config_cluster_attribute_val)) : 0 \
+ ) + \
+ (
+ pReq->config_scan_params ? (SIZEOF_TLV_HDR + \
+ NAN_MAX_SOCIAL_CHANNEL * sizeof(u32)) : 0 \
+ ) + \
+ (
+ pReq->config_debug_flags ? (SIZEOF_TLV_HDR + \
+ sizeof(u64)) : 0 \
+ ) + \
+ (
+ pReq->config_random_factor_force ? (SIZEOF_TLV_HDR + \
+ sizeof(pReq->random_factor_force_val)) : 0 \
+ ) + \
+ (
+ pReq->config_hop_count_force ? (SIZEOF_TLV_HDR + \
+ sizeof(pReq->hop_count_force_val)) : 0 \
+ );
+#endif /* NAN_2_0 */
+
+ pNanEnableReqMsg pFwReq = (pNanEnableReqMsg)malloc(message_len);
+ if (pFwReq == NULL) {
+ return WIFI_ERROR_OUT_OF_MEMORY;
+ }
+
+ ALOGI("Message Len %d", message_len);
+ memset (pFwReq, 0, message_len);
+ pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
+ pFwReq->fwHeader.msgId = NAN_MSG_ID_ENABLE_REQ;
+ pFwReq->fwHeader.msgLen = message_len;
+ pFwReq->fwHeader.handle = pReq->header.handle;
+ pFwReq->fwHeader.transactionId = pReq->header.transaction_id;
+
+ u8* tlvs = pFwReq->ptlv;
+
+ /* Write the TLVs to the message. */
+ tlvs = addTlv(NAN_TLV_TYPE_5G_SUPPORT, sizeof(pReq->support_5g),
+ (const u8*)&pReq->support_5g, tlvs);
+ tlvs = addTlv(NAN_TLV_TYPE_CLUSTER_ID_LOW, sizeof(pReq->cluster_low),
+ (const u8*)&pReq->cluster_low, tlvs);
+ tlvs = addTlv(NAN_TLV_TYPE_CLUSTER_ID_HIGH, sizeof(pReq->cluster_high),
+ (const u8*)&pReq->cluster_high, tlvs);
+ tlvs = addTlv(NAN_TLV_TYPE_SID_BEACON, sizeof(pReq->sid_beacon),
+ (const u8*)&pReq->sid_beacon, tlvs);
+ tlvs = addTlv(NAN_TLV_TYPE_RSSI_CLOSE, sizeof(pReq->rssi_close),
+ (const u8*)&pReq->rssi_close, tlvs);
+ tlvs = addTlv(NAN_TLV_TYPE_RSSI_MEDIUM, sizeof(pReq->rssi_middle),
+ (const u8*)&pReq->rssi_middle, tlvs);
+ tlvs = addTlv(NAN_TLV_TYPE_HOP_COUNT_LIMIT, sizeof(pReq->hop_count_limit),
+ (const u8*)&pReq->hop_count_limit, tlvs);
+#ifndef NAN_2_0
+ tlvs = addTlv(NAN_TLV_TYPE_RANDOM_UPDATE_TIME, sizeof(pReq->random_time),
+ (const u8*)&pReq->random_time, tlvs);
+#endif /* NAN_2_0 */
+ tlvs = addTlv(NAN_TLV_TYPE_MASTER_PREFERENCE, sizeof(pReq->master_pref),
+ (const u8*)&pReq->master_pref, tlvs);
+#ifndef NAN_2_0
+ tlvs = addTlv(NAN_TLV_TYPE_PERIODIC_SCAN_INTERVAL, sizeof(pReq->periodic_scan_interval),
+ (const u8*)&pReq->periodic_scan_interval, tlvs);
+#endif /* NAN_2_0 */
+
+#ifdef NAN_2_0
+ if (pReq->config_2dot4g_support) {
+ tlvs = addTlv(NAN_TLV_TYPE_2DOT4G_SUPPORT, sizeof(pReq->support_2dot4g_val),
+ (const u8*)&pReq->support_2dot4g_val, tlvs);
+ }
+ if (pReq->config_2dot4g_beacons) {
+ tlvs = addTlv(NAN_TLV_TYPE_2DOT4G_BEACONS, sizeof(pReq->beacon_2dot4g_val),
+ (const u8*)&pReq->beacon_2dot4g_val, tlvs);
+ }
+ if (pReq->config_2dot4g_discovery) {
+ tlvs = addTlv(NAN_TLV_TYPE_2DOT4G_SDF, sizeof(pReq->discovery_2dot4g_val),
+ (const u8*)&pReq->discovery_2dot4g_val, tlvs);
+ }
+ if (pReq->config_5g_beacons) {
+ tlvs = addTlv(NAN_TLV_TYPE_5G_BEACON, sizeof(pReq->beacon_5g_val),
+ (const u8*)&pReq->beacon_5g_val, tlvs);
+ }
+ if (pReq->config_5g_discovery) {
+ tlvs = addTlv(NAN_TLV_TYPE_5G_SDF, sizeof(pReq->discovery_5g_val),
+ (const u8*)&pReq->discovery_5g_val, tlvs);
+ }
+ /* Add the support of sending 5G RSSI values */
+ if (pReq->config_5g_rssi_close) {
+ tlvs = addTlv(NAN_TLV_TYPE_5G_RSSI_CLOSE, sizeof(pReq->rssi_close_5g_val),
+ (const u8*)&pReq->rssi_close_5g_val, tlvs);
+ }
+ if (pReq->config_5g_rssi_middle) {
+ tlvs = addTlv(NAN_TLV_TYPE_5G_RSSI_MEDIUM, sizeof(pReq->rssi_middle_5g_val),
+ (const u8*)&pReq->rssi_middle_5g_val, 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_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);
+ }
+ if (pReq->config_oui) {
+ tlvs = addTlv(NAN_TLV_TYPE_CLUSTER_OUI_NETWORK_ID, sizeof(pReq->oui_val),
+ (const u8*)&pReq->oui_val, tlvs);
+ }
+ if (pReq->config_intf_addr) {
+ tlvs = addTlv(NAN_TLV_TYPE_SOURCE_MAC_ADDRESS, sizeof(pReq->intf_addr_val),
+ (const u8*)&pReq->intf_addr_val[0], 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_CHANNEL];
+ /* Fill the social channel param */
+ fillNanSocialChannelParamVal(&pReq->scan_params_val,
+ socialChannelParamVal);
+ int i;
+ for (i = 0; i < NAN_MAX_SOCIAL_CHANNEL; i++) {
+ tlvs = addTlv(NAN_TLV_TYPE_SOCIAL_CHANNEL_SCAN_PARAMETERS,
+ sizeof(socialChannelParamVal[i]),
+ (const u8*)&socialChannelParamVal[i], tlvs);
+ }
+ }
+ if (pReq->config_debug_flags) {
+ tlvs = addTlv(NAN_TLV_TYPE_DEBUGGING_FLAGS,
+ sizeof(pReq->debug_flags_val),
+ (const u8*)&pReq->debug_flags_val, tlvs);
+ }
+ if (pReq->config_random_factor_force) {
+ tlvs = addTlv(NAN_TLV_TYPE_RANDOM_FACTOR_FORCE,
+ sizeof(pReq->random_factor_force_val),
+ (const u8*)&pReq->random_factor_force_val, tlvs);
+ }
+ if (pReq->config_hop_count_force) {
+ tlvs = addTlv(NAN_TLV_TYPE_HOP_COUNT_FORCE,
+ sizeof(pReq->hop_count_force_val),
+ (const u8*)&pReq->hop_count_force_val, tlvs);
+ }
+#endif /* NAN_2_0 */
+
+ mVendorData = (char*)pFwReq;
+ mDataLen = message_len;
+
+ return WIFI_SUCCESS;
+}
+
+int NanCommand::putNanDisable(const NanDisableRequest *pReq)
+{
+ ALOGI("NAN_DISABLE");
+ size_t message_len = sizeof(NanDisableReqMsg);
+
+ if (pReq == NULL) {
+ return WIFI_ERROR_INVALID_ARGS;
+ }
+
+ pNanDisableReqMsg pFwReq = (pNanDisableReqMsg)malloc(message_len);
+ if (pFwReq == NULL) {
+ return WIFI_ERROR_OUT_OF_MEMORY;
+ }
+
+ ALOGI("Message Len %d", message_len);
+ memset (pFwReq, 0, message_len);
+ pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
+ pFwReq->fwHeader.msgId = NAN_MSG_ID_DISABLE_REQ;
+ pFwReq->fwHeader.msgLen = message_len;
+ pFwReq->fwHeader.handle = pReq->header.handle;
+ pFwReq->fwHeader.transactionId = pReq->header.transaction_id;
+
+ mVendorData = (char*)pFwReq;
+ mDataLen = message_len;
+
+ return WIFI_SUCCESS;
+}
+
+int NanCommand::putNanConfig(const NanConfigRequest *pReq)
+{
+ ALOGI("NAN_CONFIG");
+ size_t message_len = NAN_MAX_CONFIGURATION_REQ_SIZE;
+
+ if (pReq == NULL) {
+ return WIFI_ERROR_INVALID_ARGS;
+ }
+
+#ifndef NAN_2_0
+ // Add additional message size for transmitting
+ // further availability attribute if
+ // additional_disc_window_slots is Non-zero value.
+ if (pReq->additional_disc_window_slots != 0) {
+ message_len += (SIZEOF_TLV_HDR + \
+ sizeof(pReq->additional_disc_window_slots));
+ }
+#endif /* NAN_2_0 */
+
+#ifdef NAN_2_0
+ message_len = sizeof(NanMsgHeader);
+
+ message_len += \
+ (
+ pReq->config_sid_beacon ? (SIZEOF_TLV_HDR + \
+ sizeof(pReq->sid_beacon)) : 0 \
+ ) + \
+ (
+ pReq->config_master_pref ? (SIZEOF_TLV_HDR + \
+ sizeof(pReq->master_pref)) : 0 \
+ ) + \
+ (
+ pReq->config_5g_rssi_close_proximity ? (SIZEOF_TLV_HDR + \
+ sizeof(pReq->rssi_close_proximity_5g_val)) : 0 \
+ ) + \
+ (
+ pReq->config_rssi_window_size ? (SIZEOF_TLV_HDR + \
+ sizeof(pReq->rssi_window_size_val)) : 0 \
+ ) + \
+ (
+ pReq->config_cluster_attribute_val ? (SIZEOF_TLV_HDR + \
+ sizeof(pReq->config_cluster_attribute_val)) : 0 \
+ ) + \
+ (
+ pReq->config_scan_params ? (SIZEOF_TLV_HDR + \
+ NAN_MAX_SOCIAL_CHANNEL * sizeof(u32)) : 0 \
+ ) + \
+ (
+ pReq->config_debug_flags ? (SIZEOF_TLV_HDR + \
+ sizeof(u64)) : 0 \
+ ) + \
+ (
+ pReq->config_random_factor_force ? (SIZEOF_TLV_HDR + \
+ sizeof(pReq->random_factor_force_val)) : 0 \
+ ) + \
+ (
+ pReq->config_hop_count_force ? (SIZEOF_TLV_HDR + \
+ sizeof(pReq->hop_count_force_val)) : 0 \
+ ) + \
+ (
+ pReq->config_conn_capability ? (SIZEOF_TLV_HDR + \
+ sizeof(u32)) : 0 \
+ ) + \
+ (
+ 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 \
+ );
+#endif /* NAN_2_0 */
+
+ pNanConfigurationReqMsg pFwReq = (pNanConfigurationReqMsg)malloc(message_len);
+ if (pFwReq == NULL) {
+ return WIFI_ERROR_OUT_OF_MEMORY;
+ }
+
+ ALOGI("Message Len %d", message_len);
+ memset (pFwReq, 0, message_len);
+ pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
+ pFwReq->fwHeader.msgId = NAN_MSG_ID_CONFIGURATION_REQ;
+ pFwReq->fwHeader.msgLen = message_len;
+ pFwReq->fwHeader.handle = pReq->header.handle;
+ pFwReq->fwHeader.transactionId = pReq->header.transaction_id;
+
+ u8* tlvs = pFwReq->ptlv;
+ if (pReq->config_sid_beacon) {
+ tlvs = addTlv(NAN_TLV_TYPE_SID_BEACON, sizeof(pReq->sid_beacon),
+ (const u8*)&pReq->sid_beacon, tlvs);
+ }
+#ifndef NAN_2_0
+ tlvs = addTlv(NAN_TLV_TYPE_RANDOM_UPDATE_TIME, sizeof(pReq->random_time),
+ (const u8*)&pReq->random_time, tlvs);
+#endif /* NAN_2_0 */
+ if (pReq->config_master_pref) {
+ tlvs = addTlv(NAN_TLV_TYPE_MASTER_PREFERENCE, sizeof(pReq->master_pref),
+ (const u8*)&pReq->master_pref, tlvs);
+ }
+#ifndef NAN_2_0
+ tlvs = addTlv(NAN_TLV_TYPE_PERIODIC_SCAN_INTERVAL, sizeof(pReq->periodic_scan_interval),
+ (const u8*)&pReq->periodic_scan_interval, tlvs);
+#endif /* NAN_2_0 */
+
+/* In 2.0 Version of NAN this parameter does not have any significance */
+#ifndef NAN_2_0
+ if (pReq->additional_disc_window_slots != 0) {
+ /*
+ Construct the value in this manner
+ Bit0 ==> 1/0 Enable/Disable FAW
+ Bit1-2 ==> reserved
+ Bit3-7 ==> FAW Slot Value.
+ */
+ u8 faw_value = 0x01; /* Enable the first bit */
+ /* Shifting the disc_window_slots by 3 and masking it with 0xf8
+ so that the Bit 3 to 7 are updated
+ */
+ faw_value |= ((pReq->additional_disc_window_slots << 3) & (0xf8));
+ tlvs = addTlv(NAN_TLV_TYPE_FURTHER_AVAILABILITY,
+ sizeof(faw_value),
+ (const u8*)&faw_value, tlvs);
+ }
+#endif /* NAN_2_0 */
+
+#ifdef NAN_2_0
+ 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);
+ }
+ if (pReq->config_scan_params) {
+ u32 socialChannelParamVal[NAN_MAX_SOCIAL_CHANNEL];
+ /* Fill the social channel param */
+ fillNanSocialChannelParamVal(&pReq->scan_params_val,
+ socialChannelParamVal);
+ int i;
+ for (i = 0; i < NAN_MAX_SOCIAL_CHANNEL; i++) {
+ tlvs = addTlv(NAN_TLV_TYPE_SOCIAL_CHANNEL_SCAN_PARAMETERS,
+ sizeof(socialChannelParamVal[i]),
+ (const u8*)&socialChannelParamVal[i], tlvs);
+ }
+ }
+ if (pReq->config_debug_flags) {
+ tlvs = addTlv(NAN_TLV_TYPE_DEBUGGING_FLAGS,
+ sizeof(pReq->debug_flags_val),
+ (const u8*)&pReq->debug_flags_val, tlvs);
+ }
+ if (pReq->config_random_factor_force) {
+ tlvs = addTlv(NAN_TLV_TYPE_RANDOM_FACTOR_FORCE,
+ sizeof(pReq->random_factor_force_val),
+ (const u8*)&pReq->random_factor_force_val, tlvs);
+ }
+ if (pReq->config_hop_count_force) {
+ tlvs = addTlv(NAN_TLV_TYPE_HOP_COUNT_FORCE,
+ sizeof(pReq->hop_count_force_val),
+ (const u8*)&pReq->hop_count_force_val, tlvs);
+ }
+ if (pReq->config_conn_capability) {
+ u32 val = \
+ getNanTransmitPostConnectivityCapabilityVal(&pReq->conn_capability_val);
+ tlvs = addTlv(NAN_TLV_TYPE_POST_NAN_CONNECTIVITY_CAPABILITIES_TRANSMIT,
+ sizeof(val), (const u8*)&val, tlvs);
+ }
+ if (pReq->config_discovery_attr) {
+ fillNanTransmitPostDiscoveryVal(&pReq->discovery_attr_val,
+ (u8*)(tlvs + SIZEOF_TLV_HDR));
+ tlvs = addTlv(NAN_TLV_TYPE_POST_NAN_DISCOVERY_ATTRIBUTE_TRANSMIT,
+ calcNanTransmitPostDiscoverySize(&pReq->discovery_attr_val),
+ (const u8*)(tlvs + SIZEOF_TLV_HDR), tlvs);
+ }
+ if (pReq->config_fam) {
+ 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),
+ (const u8*)(tlvs + SIZEOF_TLV_HDR), tlvs);
+ }
+#endif /* NAN_2_0 */
+
+ mVendorData = (char*)pFwReq;
+ mDataLen = message_len;
+
+ return WIFI_SUCCESS;
+}
+
+
+int NanCommand::putNanPublish(const NanPublishRequest *pReq)
+{
+ ALOGI("NAN_PUBLISH");
+ if (pReq == NULL) {
+ return WIFI_ERROR_INVALID_ARGS;
+ }
+
+ size_t message_len =
+ sizeof(NanMsgHeader) + sizeof(NanPublishServiceReqParams) +
+ (pReq->service_name_len ? SIZEOF_TLV_HDR + pReq->service_name_len : 0) +
+ (pReq->service_specific_info_len ? SIZEOF_TLV_HDR + pReq->service_specific_info_len : 0) +
+ (pReq->rx_match_filter_len ? SIZEOF_TLV_HDR + pReq->rx_match_filter_len : 0) +
+ (pReq->tx_match_filter_len ? SIZEOF_TLV_HDR + pReq->tx_match_filter_len : 0);
+
+ pNanPublishServiceReqMsg pFwReq = (pNanPublishServiceReqMsg)malloc(message_len);
+ if (pFwReq == NULL) {
+ return WIFI_ERROR_OUT_OF_MEMORY;
+ }
+
+ ALOGI("Message Len %d", message_len);
+ memset(pFwReq, 0, message_len);
+ pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
+ pFwReq->fwHeader.msgId = NAN_MSG_ID_PUBLISH_SERVICE_REQ;
+ pFwReq->fwHeader.msgLen = message_len;
+ pFwReq->fwHeader.handle = pReq->header.handle;
+ pFwReq->fwHeader.transactionId = pReq->header.transaction_id;
+
+ pFwReq->publishServiceReqParams.ttl = pReq->ttl;
+ pFwReq->publishServiceReqParams.period = pReq->period;
+ pFwReq->publishServiceReqParams.replyIndFlag = pReq->replied_event_flag;
+ pFwReq->publishServiceReqParams.publishType = pReq->publish_type;
+ pFwReq->publishServiceReqParams.txType = pReq->tx_type;
+#ifdef NAN_2_0
+ /* Overwriting replyIndFlag to 0 based on v17 Nan Spec */
+ pFwReq->publishServiceReqParams.replyIndFlag = 0;
+ pFwReq->publishServiceReqParams.rssiThresholdFlag = pReq->rssi_threshold_flag;
+ pFwReq->publishServiceReqParams.ota_flag = pReq->ota_flag;
+ pFwReq->publishServiceReqParams.matchAlg = pReq->publish_match;
+#endif /* NAN_2_0 */
+ pFwReq->publishServiceReqParams.count = pReq->publish_count;
+#ifdef NAN_2_0
+ pFwReq->publishServiceReqParams.connmap = pReq->connmap;
+#endif /* NAN_2_0 */
+ pFwReq->publishServiceReqParams.reserved2 = 0;
+
+ u8* tlvs = pFwReq->ptlv;
+ if (pReq->service_name_len) {
+ tlvs = addTlv(NAN_TLV_TYPE_SERVICE_NAME, pReq->service_name_len,
+ (const u8*)&pReq->service_name[0], tlvs);
+ }
+ if (pReq->service_specific_info_len) {
+ tlvs = addTlv(NAN_TLV_TYPE_SERVICE_SPECIFIC_INFO, pReq->service_specific_info_len,
+ (const u8*)&pReq->service_specific_info[0], tlvs);
+ }
+ if (pReq->rx_match_filter_len) {
+ tlvs = addTlv(NAN_TLV_TYPE_RX_MATCH_FILTER, pReq->rx_match_filter_len,
+ (const u8*)&pReq->rx_match_filter[0], tlvs);
+ }
+ if (pReq->tx_match_filter_len) {
+ tlvs = addTlv(NAN_TLV_TYPE_TX_MATCH_FILTER, pReq->tx_match_filter_len,
+ (const u8*)&pReq->tx_match_filter[0], tlvs);
+ }
+
+ mVendorData = (char *)pFwReq;
+ mDataLen = message_len;
+
+ return WIFI_SUCCESS;
+}
+
+int NanCommand::putNanPublishCancel(const NanPublishCancelRequest *pReq)
+{
+ ALOGI("NAN_PUBLISH_CANCEL");
+ if (pReq == NULL) {
+ return WIFI_ERROR_INVALID_ARGS;
+ }
+ size_t message_len = sizeof(NanPublishServiceCancelReqMsg);
+
+ pNanPublishServiceCancelReqMsg pFwReq =
+ (pNanPublishServiceCancelReqMsg)malloc(message_len);
+ if (pFwReq == NULL) {
+ return WIFI_ERROR_INVALID_ARGS;
+ }
+
+ ALOGI("Message Len %d", message_len);
+ memset(pFwReq, 0, message_len);
+ pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
+ pFwReq->fwHeader.msgId = NAN_MSG_ID_PUBLISH_SERVICE_CANCEL_REQ;
+ pFwReq->fwHeader.msgLen = message_len;
+ pFwReq->fwHeader.handle = pReq->header.handle;
+ pFwReq->fwHeader.transactionId = pReq->header.transaction_id;
+
+ mVendorData = (char *)pFwReq;
+ mDataLen = message_len;
+
+ return WIFI_SUCCESS;
+}
+
+int NanCommand::putNanSubscribe(const NanSubscribeRequest *pReq)
+{
+
+ ALOGI("NAN_SUBSCRIBE");
+ if (pReq == NULL) {
+ return WIFI_ERROR_INVALID_ARGS;
+ }
+
+ size_t message_len =
+ sizeof(NanMsgHeader) + sizeof(NanSubscribeServiceReqParams) +
+ (pReq->service_name_len ? SIZEOF_TLV_HDR + pReq->service_name_len : 0) +
+ (pReq->service_specific_info_len ? SIZEOF_TLV_HDR + pReq->service_specific_info_len : 0) +
+ (pReq->rx_match_filter_len ? SIZEOF_TLV_HDR + pReq->rx_match_filter_len : 0) +
+ (pReq->tx_match_filter_len ? SIZEOF_TLV_HDR + pReq->tx_match_filter_len : 0);
+
+#ifdef NAN_2_0
+ message_len += \
+ (pReq->num_intf_addr_present * (SIZEOF_TLV_HDR + NAN_MAC_ADDR_LEN));
+#endif /* NAN_2_0 */
+
+ pNanSubscribeServiceReqMsg pFwReq = (pNanSubscribeServiceReqMsg)malloc(message_len);
+ if (pFwReq == NULL) {
+ return WIFI_ERROR_INVALID_ARGS;
+ }
+
+ ALOGI("Message Len %d", message_len);
+ memset(pFwReq, 0, message_len);
+ pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
+ pFwReq->fwHeader.msgId = NAN_MSG_ID_SUBSCRIBE_SERVICE_REQ;
+ pFwReq->fwHeader.msgLen = message_len;
+ pFwReq->fwHeader.handle = pReq->header.handle;
+ pFwReq->fwHeader.transactionId = pReq->header.transaction_id;
+
+
+ pFwReq->subscribeServiceReqParams.ttl = pReq->ttl;
+ pFwReq->subscribeServiceReqParams.period = pReq->period;
+ pFwReq->subscribeServiceReqParams.subscribeType = pReq->subscribe_type;
+ pFwReq->subscribeServiceReqParams.srfAttr = pReq->serviceResponseFilter;
+ pFwReq->subscribeServiceReqParams.srfInclude = pReq->serviceResponseInclude;
+ pFwReq->subscribeServiceReqParams.srfSend = pReq->useServiceResponseFilter;
+ pFwReq->subscribeServiceReqParams.ssiRequired = pReq->ssiRequiredForMatchIndication;
+ pFwReq->subscribeServiceReqParams.matchAlg = pReq->subscribe_match;
+ pFwReq->subscribeServiceReqParams.count = pReq->subscribe_count;
+#ifdef NAN_2_0
+ pFwReq->subscribeServiceReqParams.rssiThresholdFlag = pReq->rssi_threshold_flag;
+ pFwReq->subscribeServiceReqParams.ota_flag = pReq->ota_flag;
+ pFwReq->subscribeServiceReqParams.connmap = pReq->connmap;
+#endif /* NAN_2_0 */
+ pFwReq->subscribeServiceReqParams.reserved = 0;
+
+ u8* tlvs = pFwReq->ptlv;
+ if (pReq->service_name_len) {
+ tlvs = addTlv(NAN_TLV_TYPE_SERVICE_NAME, pReq->service_name_len,
+ (const u8*)&pReq->service_name[0], tlvs);
+ }
+ if (pReq->service_specific_info_len) {
+ tlvs = addTlv(NAN_TLV_TYPE_SERVICE_SPECIFIC_INFO, pReq->service_specific_info_len,
+ (const u8*)&pReq->service_specific_info[0], tlvs);
+ }
+ if (pReq->rx_match_filter_len) {
+ tlvs = addTlv(NAN_TLV_TYPE_RX_MATCH_FILTER, pReq->rx_match_filter_len,
+ (const u8*)&pReq->rx_match_filter[0], tlvs);
+ }
+ if (pReq->tx_match_filter_len) {
+ tlvs = addTlv(NAN_TLV_TYPE_TX_MATCH_FILTER, pReq->tx_match_filter_len,
+ (const u8*)&pReq->tx_match_filter[0], tlvs);
+ }
+
+#ifdef NAN_2_0
+ int i = 0;
+ for (i = 0; i < pReq->num_intf_addr_present; i++)
+ {
+ tlvs = addTlv(NAN_TLV_TYPE_MAC_ADDRESS,
+ NAN_MAC_ADDR_LEN,
+ (const u8*)&pReq->intf_addr[i][0], tlvs);
+ }
+#endif /* NAN_2_0 */
+
+ mVendorData = (char *)pFwReq;
+ mDataLen = message_len;
+
+ return WIFI_SUCCESS;
+}
+
+int NanCommand::putNanSubscribeCancel(const NanSubscribeCancelRequest *pReq)
+{
+ ALOGI("NAN_SUBSCRIBE_CANCEL");
+ if (pReq == NULL) {
+ return WIFI_ERROR_INVALID_ARGS;
+ }
+ size_t message_len = sizeof(NanSubscribeServiceCancelReqMsg);
+
+ pNanSubscribeServiceCancelReqMsg pFwReq =
+ (pNanSubscribeServiceCancelReqMsg)malloc(message_len);
+ if (pFwReq == NULL) {
+ return WIFI_ERROR_INVALID_ARGS;
+ }
+
+ ALOGI("Message Len %d", message_len);
+ memset(pFwReq, 0, message_len);
+ pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
+ pFwReq->fwHeader.msgId = NAN_MSG_ID_SUBSCRIBE_SERVICE_CANCEL_REQ;
+ pFwReq->fwHeader.msgLen = message_len;
+ pFwReq->fwHeader.handle = pReq->header.handle;
+ pFwReq->fwHeader.transactionId = pReq->header.transaction_id;
+
+ mVendorData = (char *)pFwReq;
+ mDataLen = message_len;
+
+ return WIFI_SUCCESS;
+}
+
+
+int NanCommand::putNanTransmitFollowup(const NanTransmitFollowupRequest *pReq)
+{
+ ALOGI("TRANSMIT_FOLLOWUP");
+ if (pReq == NULL) {
+ return WIFI_ERROR_INVALID_ARGS;
+ }
+
+ size_t message_len =
+ sizeof(NanMsgHeader) + sizeof(NanTransmitFollowupReqParams) +
+ (pReq->service_specific_info_len ? SIZEOF_TLV_HDR +
+ pReq->service_specific_info_len : 0);
+
+#ifdef NAN_2_0
+ /* Mac address needs to be added in TLV */
+ message_len += (SIZEOF_TLV_HDR + sizeof(pReq->addr));
+#endif
+
+ pNanTransmitFollowupReqMsg pFwReq = (pNanTransmitFollowupReqMsg)malloc(message_len);
+ if (pFwReq == NULL) {
+ return WIFI_ERROR_INVALID_ARGS;
+ }
+
+ ALOGI("Message Len %d", message_len);
+ memset (pFwReq, 0, message_len);
+ pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
+ pFwReq->fwHeader.msgId = NAN_MSG_ID_TRANSMIT_FOLLOWUP_REQ;
+ pFwReq->fwHeader.msgLen = message_len;
+ pFwReq->fwHeader.handle = pReq->header.handle;
+ pFwReq->fwHeader.transactionId = pReq->header.transaction_id;
+
+
+#ifndef NAN_2_0
+ memcpy(pFwReq->transmitFollowupReqParams.macAddr, pReq->addr,
+ sizeof(pFwReq->transmitFollowupReqParams.macAddr));
+#else /* NAN_2_0 */
+ pFwReq->transmitFollowupReqParams.matchHandle = pReq->match_handle;
+#endif /* NAN_2_0 */
+ pFwReq->transmitFollowupReqParams.priority = pReq->priority;
+ pFwReq->transmitFollowupReqParams.window = pReq->dw_or_faw;
+ pFwReq->transmitFollowupReqParams.reserved = 0;
+
+ u8* tlvs = pFwReq->ptlv;
+
+#ifdef NAN_2_0
+ /* Mac address needs to be added in TLV */
+ tlvs = addTlv(NAN_TLV_TYPE_MAC_ADDRESS, sizeof(pReq->addr),
+ (const u8*)&pReq->addr[0], tlvs);
+ u16 tlv_type = NAN_TLV_TYPE_SERVICE_SPECIFIC_INFO;
+#else /* NAN_2_0 */
+ u16 tlv_type = (pReq->dw_or_faw == 0)? NAN_TLV_TYPE_SERVICE_SPECIFIC_INFO :
+ NAN_TLV_TYPE_EXT_SERVICE_SPECIFIC_INFO;
+#endif /* NAN_2_0 */
+
+ if (pReq->service_specific_info_len) {
+ tlvs = addTlv(tlv_type, pReq->service_specific_info_len,
+ (const u8*)&pReq->service_specific_info[0], tlvs);
+ }
+
+ mVendorData = (char *)pFwReq;
+ mDataLen = message_len;
+
+ return WIFI_SUCCESS;
+}
+
+int NanCommand::putNanStats(const NanStatsRequest *pReq)
+{
+ ALOGI("NAN_STATS");
+ if (pReq == NULL) {
+ return WIFI_ERROR_INVALID_ARGS;
+ }
+ size_t message_len = sizeof(NanStatsReqMsg);
+
+ pNanStatsReqMsg pFwReq =
+ (pNanStatsReqMsg)malloc(message_len);
+ if (pFwReq == NULL) {
+ return WIFI_ERROR_INVALID_ARGS;
+ }
+
+ ALOGI("Message Len %d", message_len);
+ memset(pFwReq, 0, message_len);
+ pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
+ pFwReq->fwHeader.msgId = NAN_MSG_ID_STATS_REQ;
+ pFwReq->fwHeader.msgLen = message_len;
+ pFwReq->fwHeader.handle = pReq->header.handle;
+ pFwReq->fwHeader.transactionId = pReq->header.transaction_id;
+
+ pFwReq->statsReqParams.statsId = pReq->stats_id;
+ pFwReq->statsReqParams.clear = pReq->clear;
+ pFwReq->statsReqParams.reserved = 0;
+
+ mVendorData = (char *)pFwReq;
+ mDataLen = message_len;
+
+ return WIFI_SUCCESS;
+}
+
+int NanCommand::putNanTCA(const NanTCARequest *pReq)
+{
+ ALOGI("NAN_TCA");
+ if (pReq == NULL) {
+ return WIFI_ERROR_INVALID_ARGS;
+ }
+ size_t message_len = sizeof(NanTcaReqMsg);
+
+#ifdef NAN_2_0
+ message_len += (SIZEOF_TLV_HDR + 2 * sizeof(u32));
+#endif
+
+ pNanTcaReqMsg pFwReq =
+ (pNanTcaReqMsg)malloc(message_len);
+ if (pFwReq == NULL) {
+ return WIFI_ERROR_INVALID_ARGS;
+ }
+
+ ALOGI("Message Len %d", message_len);
+ memset(pFwReq, 0, message_len);
+ pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
+ pFwReq->fwHeader.msgId = NAN_MSG_ID_TCA_REQ;
+ pFwReq->fwHeader.msgLen = message_len;
+ pFwReq->fwHeader.handle = pReq->header.handle;
+ pFwReq->fwHeader.transactionId = pReq->header.transaction_id;
+
+#ifndef NAN_2_0
+ pFwReq->tcaReqParams.tcaId = pReq->tca_id;
+ pFwReq->tcaReqParams.rising = pReq->rising_direction_evt_flag;
+ pFwReq->tcaReqParams.falling = pReq->falling_direction_evt_flag;
+ pFwReq->tcaReqParams.clear = pReq->clear;
+ pFwReq->tcaReqParams.reserved = 0;
+ pFwReq->tcaReqParams.threshold = pReq->threshold;
+#else /* NAN_2_0 */
+ u32 tcaReqParams[2];
+ memset (tcaReqParams, 0, sizeof(tcaReqParams));
+ tcaReqParams[0] = (pReq->rising_direction_evt_flag & 0x01);
+ tcaReqParams[0] |= (pReq->falling_direction_evt_flag & 0x01) << 1;
+ tcaReqParams[0] |= (pReq->clear & 0x01) << 2;
+ tcaReqParams[1] = pReq->threshold;
+
+ u8* tlvs = pFwReq->ptlv;
+
+ tlvs = addTlv(NAN_TLV_TYPE_TCA_CLUSTER_SIZE_REQ, sizeof(tcaReqParams),
+ (const u8*)&tcaReqParams[0], tlvs);
+#endif
+
+ mVendorData = (char *)pFwReq;
+ mDataLen = message_len;
+
+ return WIFI_SUCCESS;
+}
+
+int NanCommand::putNanBeaconSdfPayload(const NanBeaconSdfPayloadRequest *pReq)
+{
+ int ret = WIFI_ERROR_NOT_SUPPORTED;
+#ifdef NAN_2_0
+ ALOGI("NAN_BEACON_SDF_PAYLAOD");
+ if (pReq == NULL) {
+ return WIFI_ERROR_INVALID_ARGS;
+ }
+ size_t message_len = sizeof(NanMsgHeader) + \
+ SIZEOF_TLV_HDR + sizeof(u32) + \
+ pReq->vsa.vsa_len;
+
+ pNanBeaconSdfPayloadReqMsg pFwReq =
+ (pNanBeaconSdfPayloadReqMsg)malloc(message_len);
+ if (pFwReq == NULL) {
+ return WIFI_ERROR_INVALID_ARGS;
+ }
+
+ ALOGI("Message Len %d", message_len);
+ memset(pFwReq, 0, message_len);
+ pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
+ pFwReq->fwHeader.msgId = NAN_MSG_ID_BEACON_SDF_REQ;
+ pFwReq->fwHeader.msgLen = message_len;
+ pFwReq->fwHeader.handle = pReq->header.handle;
+ pFwReq->fwHeader.transactionId = pReq->header.transaction_id;
+
+ /* Construct First 4 bytes of NanBeaconSdfPayloadReqMsg */
+ u32 temp = 0;
+ temp = pReq->vsa.payload_transmit_flag & 0x01;
+ temp |= (pReq->vsa.tx_in_discovery_beacon & 0x01) << 1;
+ temp |= (pReq->vsa.tx_in_sync_beacon & 0x01) << 2;
+ temp |= (pReq->vsa.tx_in_service_discovery & 0x01) << 3;
+ temp |= (pReq->vsa.vendor_oui & 0x00FFFFFF) << 8;
+
+ int tlv_len = sizeof(u32) + pReq->vsa.vsa_len;
+ u8* tempBuf = (u8*)malloc(tlv_len);
+ if (tempBuf == NULL) {
+ ALOGE("%s: Malloc failed", __func__);
+ free(pFwReq);
+ return WIFI_ERROR_INVALID_ARGS;
+ }
+ memset(tempBuf, 0, tlv_len);
+ memcpy(tempBuf, &temp, sizeof(u32));
+ memcpy((tempBuf + sizeof(u32)), pReq->vsa.vsa, pReq->vsa.vsa_len);
+
+ u8* tlvs = pFwReq->ptlv;
+
+ /* Write the TLVs to the message. */
+ tlvs = addTlv(NAN_TLV_TYPE_VENDOR_SPECIFIC_ATTRIBUTE_TRANSMIT, tlv_len,
+ (const u8*)tempBuf, tlvs);
+ free(tempBuf);
+
+ mVendorData = (char *)pFwReq;
+ mDataLen = message_len;
+ ret = WIFI_SUCCESS;
+#endif /* NAN_2_0 */
+ return ret;
+}
+//callback handlers registered for nl message send
+static int error_handler_nan(struct sockaddr_nl *nla, struct nlmsgerr *err,
+ void *arg)
+{
+ struct sockaddr_nl * tmp;
+ int *ret = (int *)arg;
+ tmp = nla;
+ *ret = err->error;
+ ALOGE("%s: Error code:%d (%s)", __func__, *ret, strerror(-(*ret)));
+ return NL_STOP;
+}
+
+//callback handlers registered for nl message send
+static int ack_handler_nan(struct nl_msg *msg, void *arg)
+{
+ int *ret = (int *)arg;
+ struct nl_msg * a;
+
+ ALOGE("%s: called", __func__);
+ a = msg;
+ *ret = 0;
+ return NL_STOP;
+}
+
+//callback handlers registered for nl message send
+static int finish_handler_nan(struct nl_msg *msg, void *arg)
+{
+ int *ret = (int *)arg;
+ struct nl_msg * a;
+
+ ALOGE("%s: called", __func__);
+ a = msg;
+ *ret = 0;
+ return NL_SKIP;
+}
+
+
+//Override base class requestEvent and implement little differently here
+//This will send the request message
+//We dont wait for any response back in case of Nan as it is asynchronous
+//thus no wait for condition.
+int NanCommand::requestEvent()
+{
+ int res;
+ struct nl_cb * cb;
+
+ cb = nl_cb_alloc(NL_CB_DEFAULT);
+ if (!cb) {
+ ALOGE("%s: Callback allocation failed",__func__);
+ res = -1;
+ goto out;
+ }
+
+ /* create the message */
+ res = create();
+ if (res < 0)
+ goto out;
+
+ /* send message */
+ ALOGE("%s:Handle:%p Socket Value:%p", __func__, mInfo, mInfo->cmd_sock);
+ res = nl_send_auto_complete(mInfo->cmd_sock, mMsg.getMessage());
+ if (res < 0)
+ goto out;
+ res = 1;
+
+ nl_cb_err(cb, NL_CB_CUSTOM, error_handler_nan, &res);
+ nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler_nan, &res);
+ nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler_nan, &res);
+
+ // err is populated as part of finish_handler
+ while (res > 0)
+ nl_recvmsgs(mInfo->cmd_sock, cb);
+
+ ALOGD("%s: Command invoked return value:%d",__func__, res);
+
+out:
+ //free the VendorData
+ if (mVendorData) {
+ free(mVendorData);
+ }
+ mVendorData = NULL;
+ //cleanup the mMsg
+ mMsg.destroy();
+ return res;
+}
+
+int NanCommand::calcNanTransmitPostDiscoverySize(
+ const NanTransmitPostDiscovery *pPostDiscovery)
+{
+ /* Fixed size of u32 for Conn Type, Device Role and R flag + Dur + Rsvd*/
+ int ret = sizeof(u32);
+ /* size of availability interval bit map is 4 bytes */
+ ret += sizeof(u32);
+ /* size of mac address is 6 bytes*/
+ ret += (SIZEOF_TLV_HDR + NAN_MAC_ADDR_LEN);
+ if (pPostDiscovery &&
+ pPostDiscovery->type == NAN_CONN_WLAN_MESH) {
+ /* size of WLAN_MESH_ID */
+ ret += (SIZEOF_TLV_HDR + \
+ pPostDiscovery->mesh_id_len);
+ }
+ if (pPostDiscovery &&
+ pPostDiscovery->type == NAN_CONN_WLAN_INFRA) {
+ /* size of Infrastructure ssid */
+ ret += (SIZEOF_TLV_HDR + \
+ pPostDiscovery->infrastructure_ssid_len);
+ }
+ ALOGI("%s:size:%d", __func__, ret);
+ return ret;
+}
+
+void NanCommand::fillNanSocialChannelParamVal(
+ const NanSocialChannelScanParams *pScanParams,
+ u32* pChannelParamArr)
+{
+ int i;
+ if (pChannelParamArr) {
+ memset(pChannelParamArr, 0,
+ NAN_MAX_SOCIAL_CHANNEL * sizeof(u32));
+ for (i= 0; i < NAN_MAX_SOCIAL_CHANNEL; i++) {
+ pChannelParamArr[i] = pScanParams->scan_period[i] << 16;
+ pChannelParamArr[i] |= pScanParams->dwell_time[i] << 8;
+ }
+ pChannelParamArr[NAN_CHANNEL_6] |= 6;
+ pChannelParamArr[NAN_CHANNEL_44]|= 44;
+ pChannelParamArr[NAN_CHANNEL_149]|= 149;
+ ALOGI("%s: Filled SocialChannelParamVal", __func__);
+ hexdump((char*)pChannelParamArr, NAN_MAX_SOCIAL_CHANNEL * sizeof(u32));
+ }
+ return;
+}
+
+u32 NanCommand::getNanTransmitPostConnectivityCapabilityVal(
+ const NanTransmitPostConnectivityCapability *pCapab)
+{
+ u32 ret = 0;
+ ret |= (pCapab->payload_transmit_flag? 1:0) << 16;
+ ret |= (pCapab->is_mesh_supported? 1:0) << 5;
+ ret |= (pCapab->is_ibss_supported? 1:0) << 4;
+ ret |= (pCapab->wlan_infra_field? 1:0) << 3;
+ ret |= (pCapab->is_tdls_supported? 1:0) << 2;
+ ret |= (pCapab->is_wfds_supported? 1:0) << 1;
+ ret |= (pCapab->is_wfd_supported? 1:0);
+ ALOGI("%s: val:%d", __func__, ret);
+ return ret;
+}
+
+void NanCommand::fillNanTransmitPostDiscoveryVal(
+ const NanTransmitPostDiscovery *pTxDisc,
+ u8 *pOutValue)
+{
+#ifdef NAN_2_0
+ if (pTxDisc && pOutValue) {
+ u8 *tlvs = &pOutValue[8];
+ pOutValue[0] = pTxDisc->type;
+ pOutValue[1] = pTxDisc->role;
+ pOutValue[2] = (pTxDisc->transmit_freq? 1:0);
+ pOutValue[2] |= ((pTxDisc->duration & 0x03) << 1);
+ memcpy(&pOutValue[4], &pTxDisc->avail_interval_bitmap,
+ sizeof(pTxDisc->avail_interval_bitmap));
+ tlvs = addTlv(NAN_TLV_TYPE_MAC_ADDRESS,
+ NAN_MAC_ADDR_LEN,
+ (const u8*)&pTxDisc->addr[0],
+ tlvs);
+ if (pTxDisc->type == NAN_CONN_WLAN_MESH) {
+ tlvs = addTlv(NAN_TLV_TYPE_WLAN_MESH_ID,
+ pTxDisc->mesh_id_len,
+ (const u8*)&pTxDisc->mesh_id[0],
+ tlvs);
+ }
+ if (pTxDisc->type == NAN_CONN_WLAN_INFRA) {
+ tlvs = addTlv(NAN_TLV_TYPE_FW_WLAN_INFRASTRUCTURE_SSID,
+ pTxDisc->infrastructure_ssid_len,
+ (const u8*)&pTxDisc->infrastructure_ssid_val[0],
+ tlvs);
+ }
+ ALOGI("%s: Filled TransmitPostDiscoveryVal", __func__);
+ hexdump((char*)pOutValue, calcNanTransmitPostDiscoverySize(pTxDisc));
+ }
+#endif /* NAN_2_0 */
+ return;
+}
+
+void NanCommand::fillNanFurtherAvailabilityMapVal(
+ const NanFurtherAvailabilityMap *pFam,
+ u8 *pOutValue)
+{
+ if (pFam && pOutValue) {
+ u32 famsize = NAN_FURTHER_AVAILABILITY_MAP_SIZE + \
+ pFam->vendor_elements_len;
+ 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);
+ ALOGI("%s: Filled FurtherAvailabilityMapVal", __func__);
+ hexdump((char*)pOutValue, famsize);
+ }
+ return;
+}
+
diff --git a/qcwcn/wifi_hal/nan_rsp.cpp b/qcwcn/wifi_hal/nan_rsp.cpp
new file mode 100644
index 0000000..8dde3d6
--- /dev/null
+++ b/qcwcn/wifi_hal/nan_rsp.cpp
@@ -0,0 +1,276 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "sync.h"
+#include <utils/Log.h>
+#include "wifi_hal.h"
+#include "nan.h"
+#include "nan_i.h"
+#include "nancommand.h"
+
+
+int NanCommand::isNanResponse()
+{
+ if (mNanVendorEvent == NULL) {
+ ALOGE("NULL check failed");
+ return WIFI_ERROR_INVALID_ARGS;
+ }
+
+ NanMsgHeader *pHeader = (NanMsgHeader *)mNanVendorEvent;
+
+ switch (pHeader->msgId) {
+ case NAN_MSG_ID_ERROR_RSP:
+ case NAN_MSG_ID_CONFIGURATION_RSP:
+ case NAN_MSG_ID_PUBLISH_SERVICE_CANCEL_RSP:
+ case NAN_MSG_ID_PUBLISH_SERVICE_RSP:
+ case NAN_MSG_ID_SUBSCRIBE_SERVICE_RSP:
+ case NAN_MSG_ID_SUBSCRIBE_SERVICE_CANCEL_RSP:
+ case NAN_MSG_ID_TRANSMIT_FOLLOWUP_RSP:
+ case NAN_MSG_ID_STATS_RSP:
+ case NAN_MSG_ID_ENABLE_RSP:
+ case NAN_MSG_ID_DISABLE_RSP:
+ case NAN_MSG_ID_TCA_RSP:
+#ifdef NAN_2_0
+ case NAN_MSG_ID_BEACON_SDF_RSP:
+#endif /* NAN_2_0 */
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+
+int NanCommand::getNanResponse(NanResponseMsg *pRsp)
+{
+ if (mNanVendorEvent == NULL || pRsp == NULL) {
+ ALOGE("NULL check failed");
+ return WIFI_ERROR_INVALID_ARGS;
+ }
+
+ NanMsgHeader *pHeader = (NanMsgHeader *)mNanVendorEvent;
+
+ switch (pHeader->msgId) {
+ case NAN_MSG_ID_ERROR_RSP:
+ {
+ pNanErrorRspMsg pFwRsp = \
+ (pNanErrorRspMsg)mNanVendorEvent;
+ pRsp->header.handle = pFwRsp->fwHeader.handle;
+ pRsp->header.transaction_id = pFwRsp->fwHeader.transactionId;
+ pRsp->status = pFwRsp->status;
+ pRsp->value = pFwRsp->value;
+ pRsp->response_type = NAN_RESPONSE_ERROR;
+ break;
+ }
+ case NAN_MSG_ID_CONFIGURATION_RSP:
+ {
+ pNanConfigurationRspMsg pFwRsp = \
+ (pNanConfigurationRspMsg)mNanVendorEvent;
+ pRsp->header.handle = pFwRsp->fwHeader.handle;
+ pRsp->header.transaction_id = pFwRsp->fwHeader.transactionId;
+ pRsp->status = pFwRsp->status;
+ pRsp->value = pFwRsp->value;
+ pRsp->response_type = NAN_RESPONSE_CONFIG;
+ }
+ break;
+ case NAN_MSG_ID_PUBLISH_SERVICE_CANCEL_RSP:
+ {
+ pNanPublishServiceCancelRspMsg pFwRsp = \
+ (pNanPublishServiceCancelRspMsg)mNanVendorEvent;
+ pRsp->header.handle = pFwRsp->fwHeader.handle;
+ pRsp->header.transaction_id = pFwRsp->fwHeader.transactionId;
+ pRsp->status = pFwRsp->status;
+ pRsp->value = pFwRsp->value;
+ pRsp->response_type = NAN_RESPONSE_PUBLISH_CANCEL;
+ break;
+ }
+ case NAN_MSG_ID_PUBLISH_SERVICE_RSP:
+ {
+ pNanPublishServiceRspMsg pFwRsp = \
+ (pNanPublishServiceRspMsg)mNanVendorEvent;
+ pRsp->header.handle = pFwRsp->fwHeader.handle;
+ pRsp->header.transaction_id = pFwRsp->fwHeader.transactionId;
+ pRsp->status = pFwRsp->status;
+ pRsp->value = pFwRsp->value;
+ pRsp->response_type = NAN_RESPONSE_PUBLISH;
+ break;
+ }
+ case NAN_MSG_ID_SUBSCRIBE_SERVICE_RSP:
+ {
+ pNanSubscribeServiceRspMsg pFwRsp = \
+ (pNanSubscribeServiceRspMsg)mNanVendorEvent;
+ pRsp->header.handle = pFwRsp->fwHeader.handle;
+ pRsp->header.transaction_id = pFwRsp->fwHeader.transactionId;
+ pRsp->status = pFwRsp->status;
+ pRsp->value = pFwRsp->value;
+ pRsp->response_type = NAN_RESPONSE_SUBSCRIBE;
+ }
+ break;
+ case NAN_MSG_ID_SUBSCRIBE_SERVICE_CANCEL_RSP:
+ {
+ pNanSubscribeServiceCancelRspMsg pFwRsp = \
+ (pNanSubscribeServiceCancelRspMsg)mNanVendorEvent;
+ pRsp->header.handle = pFwRsp->fwHeader.handle;
+ pRsp->header.transaction_id = pFwRsp->fwHeader.transactionId;
+ pRsp->status = pFwRsp->status;
+ pRsp->value = pFwRsp->value;
+ pRsp->response_type = NAN_RESPONSE_SUBSCRIBE_CANCEL;
+ break;
+ }
+ case NAN_MSG_ID_TRANSMIT_FOLLOWUP_RSP:
+ {
+ pNanTransmitFollowupRspMsg pFwRsp = \
+ (pNanTransmitFollowupRspMsg)mNanVendorEvent;
+ pRsp->header.handle = pFwRsp->fwHeader.handle;
+ pRsp->header.transaction_id = pFwRsp->fwHeader.transactionId;
+ pRsp->status = pFwRsp->status;
+ pRsp->value = pFwRsp->value;
+ pRsp->response_type = NAN_RESPONSE_TRANSMIT_FOLLOWUP;
+ break;
+ }
+ case NAN_MSG_ID_STATS_RSP:
+ {
+ pNanStatsRspMsg pFwRsp = \
+ (pNanStatsRspMsg)mNanVendorEvent;
+ pRsp->header.handle = pFwRsp->fwHeader.handle;
+ pRsp->header.transaction_id = pFwRsp->fwHeader.transactionId;
+ pRsp->status = pFwRsp->statsRspParams.status;
+ pRsp->value = pFwRsp->statsRspParams.value;
+ pRsp->response_type = NAN_RESPONSE_STATS;
+ pRsp->body.stats_response.stats_id = \
+ (NanStatsId)pFwRsp->statsRspParams.statsId;
+ ALOGI("%s: stats_id:%d",__func__,
+ pRsp->body.stats_response.stats_id);
+ u8 *pInputTlv = pFwRsp->ptlv;
+ NanTlv outputTlv;
+ memset(&outputTlv, 0, sizeof(outputTlv));
+ u16 readLen = 0;
+ int remainingLen = (mNanDataLen - \
+ (sizeof(NanMsgHeader) + sizeof(NanStatsRspParams)));
+
+ if (remainingLen > 0) {
+ readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv);
+ ALOGI("%s: Remaining Len:%d readLen:%d type:%d length:%d",
+ __func__, remainingLen, readLen, outputTlv.type,
+ outputTlv.length);
+ if (outputTlv.length <= \
+ sizeof(pRsp->body.stats_response.data)) {
+ memcpy(&pRsp->body.stats_response.data, outputTlv.value,
+ outputTlv.length);
+ hexdump((char*)&pRsp->body.stats_response.data, outputTlv.length);
+ }
+ else {
+ ALOGE("%s:copying only sizeof(pRsp->body.stats_response.data):%d",
+ __func__, sizeof(pRsp->body.stats_response.data));
+ memcpy(&pRsp->body.stats_response.data, outputTlv.value,
+ sizeof(pRsp->body.stats_response.data));
+ hexdump((char*)&pRsp->body.stats_response.data,
+ sizeof(pRsp->body.stats_response.data));
+ }
+ }
+ else
+ ALOGI("%s: No TLV's present",__func__);
+ break;
+ }
+ case NAN_MSG_ID_ENABLE_RSP:
+ {
+ pNanEnableRspMsg pFwRsp = \
+ (pNanEnableRspMsg)mNanVendorEvent;
+ pRsp->header.handle = pFwRsp->fwHeader.handle;
+ pRsp->header.transaction_id = pFwRsp->fwHeader.transactionId;
+ pRsp->status = pFwRsp->status;
+ pRsp->value = pFwRsp->value;
+ pRsp->response_type = NAN_RESPONSE_ENABLED;
+ break;
+ }
+ case NAN_MSG_ID_DISABLE_RSP:
+ {
+ pNanDisableRspMsg pFwRsp = \
+ (pNanDisableRspMsg)mNanVendorEvent;
+ pRsp->header.handle = pFwRsp->fwHeader.handle;
+ pRsp->header.transaction_id = pFwRsp->fwHeader.transactionId;
+ pRsp->status = pFwRsp->status;
+ pRsp->value = 0;
+ pRsp->response_type = NAN_RESPONSE_DISABLED;
+ break;
+ }
+ case NAN_MSG_ID_TCA_RSP:
+ {
+ pNanTcaRspMsg pFwRsp = \
+ (pNanTcaRspMsg)mNanVendorEvent;
+ pRsp->header.handle = pFwRsp->fwHeader.handle;
+ pRsp->header.transaction_id = pFwRsp->fwHeader.transactionId;
+ pRsp->status = pFwRsp->status;
+ pRsp->value = pFwRsp->value;
+ pRsp->response_type = NAN_RESPONSE_TCA;
+ break;
+ }
+#ifdef NAN_2_0
+ case NAN_MSG_ID_BEACON_SDF_RSP:
+ {
+ pNanBeaconSdfPayloadRspMsg pFwRsp = \
+ (pNanBeaconSdfPayloadRspMsg)mNanVendorEvent;
+ pRsp->header.handle = pFwRsp->fwHeader.handle;
+ pRsp->header.transaction_id = pFwRsp->fwHeader.transactionId;
+ pRsp->status = pFwRsp->status;
+ pRsp->value = 0;
+ pRsp->response_type = NAN_RESPONSE_BEACON_SDF_PAYLOAD;
+ break;
+ }
+#endif /* NAN_2_0 */
+ default:
+ return -1;
+ }
+ return 0;
+}
+
+int NanCommand::handleNanResponse()
+{
+ //parse the data and call
+ //the response callback handler with the populated
+ //NanResponseMsg
+ NanResponseMsg rsp_data;
+ int ret;
+
+ ALOGV("handleNanResponse called %p", this);
+ memset(&rsp_data, 0, sizeof(rsp_data));
+ //get the rsp_data
+ ret = getNanResponse(&rsp_data);
+
+ ALOGI("handleNanResponse ret:%d status:%u value:%u response_type:%u",
+ ret, rsp_data.status, rsp_data.value, rsp_data.response_type);
+ if (ret == 0 && (rsp_data.response_type == NAN_RESPONSE_STATS) &&
+ (mStaParam != NULL) &&
+ (rsp_data.body.stats_response.stats_id == NAN_STATS_ID_DE_TIMING_SYNC)) {
+ /*
+ Fill the staParam with appropriate values and return from here.
+ No need to call NotifyResponse as the request is for getting the
+ STA response
+ */
+ NanSyncStats *pSyncStats = &rsp_data.body.stats_response.data.sync_stats;
+ mStaParam->master_rank = pSyncStats->myRank;
+ mStaParam->master_pref = (pSyncStats->myRank & 0xFF00000000000000) >> 56;
+ mStaParam->random_factor = (pSyncStats->myRank & 0x00FF000000000000) >> 48;
+ mStaParam->hop_count = pSyncStats->currAmHopCount;
+ mStaParam->beacon_transmit_time = pSyncStats->currAmBTT;
+
+ return ret;
+ }
+ //Call the NotifyResponse Handler
+ if (ret == 0 && mHandler.NotifyResponse) {
+ (*mHandler.NotifyResponse)(&rsp_data);
+ }
+ return ret;
+}
diff --git a/qcwcn/wifi_hal/nancommand.h b/qcwcn/wifi_hal/nancommand.h
new file mode 100644
index 0000000..a9929bb
--- /dev/null
+++ b/qcwcn/wifi_hal/nancommand.h
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __WIFI_HAL_NAN_COMMAND_H__
+#define __WIFH_HAL_NAN_COMMAND_H__
+
+#include "common.h"
+#include "cpp_bindings.h"
+#include "nan.h"
+
+class NanCommand : public WifiVendorCommand
+{
+private:
+ NanCallbackHandler mHandler;
+ char *mNanVendorEvent;
+ u32 mNanDataLen;
+ NanStaParameter *mStaParam;
+
+ //Function to check the initial few bytes of data to
+ //determine whether NanResponse or NanEvent
+ int isNanResponse();
+ //Function which unparses the data and calls the NotifyResponse
+ int handleNanResponse();
+ //Function which will parse the mVendorData and gets
+ // the rsp_data appropriately.
+ int getNanResponse(NanResponseMsg *pRsp);
+
+ //Function which will return the Nan Indication type based on
+ //the initial few bytes of mVendorData
+ NanIndicationType getIndicationType();
+ //Function which calls the necessaryIndication callback
+ //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 getNanUnMatch(NanUnmatchInd *event);
+ int getNanSubscribeTerminated(NanSubscribeTerminatedInd *event);
+ int getNanFollowup(NanFollowupInd *event);
+ int getNanDiscEngEvent(NanDiscEngEventInd *event);
+ int getNanDisabled(NanDisabledInd *event);
+ int getNanTca(NanTCAInd *event);
+ int getNanBeaconSdfPayload(NanBeaconSdfPayloadInd *event);
+
+ //Making the constructor private since this class is a singleton
+ NanCommand(wifi_handle handle, int id, u32 vendor_id, u32 subcmd);
+
+ static NanCommand *mNanCommandInstance;
+
+ // Other private helper functions
+ int calcNanTransmitPostDiscoverySize(
+ const NanTransmitPostDiscovery *pPostDiscovery);
+ void fillNanSocialChannelParamVal(
+ const NanSocialChannelScanParams *pScanParams,
+ u32* pChannelParamArr);
+ u32 getNanTransmitPostConnectivityCapabilityVal(
+ const NanTransmitPostConnectivityCapability *pCapab);
+ void fillNanTransmitPostDiscoveryVal(
+ const NanTransmitPostDiscovery *pTxDisc,
+ u8 *pOutValue);
+ void fillNanFurtherAvailabilityMapVal(
+ const NanFurtherAvailabilityMap *pFam,
+ u8 *pOutValue);
+
+ void getNanReceivePostConnectivityCapabilityVal(
+ const u8* pInValue,
+ NanReceivePostConnectivityCapability *pRxCapab);
+ int getNanReceivePostDiscoveryVal(const u8 *pInValue,
+ u32 length,
+ NanReceivePostDiscovery *pRxDisc);
+ int getNanFurtherAvailabilityMap(const u8 *pInValue,
+ u32 length,
+ NanFurtherAvailabilityMap *pFam);
+
+public:
+ static NanCommand* instance(wifi_handle handle);
+ virtual ~NanCommand();
+
+ // This function implements creation of NAN specific Request
+ // based on the request type
+ virtual int create();
+ virtual int requestEvent();
+ virtual int handleResponse(WifiEvent reply);
+ virtual int handleEvent(WifiEvent &event);
+ int setCallbackHandler(NanCallbackHandler nHandler);
+
+
+ //Functions to fill the vendor data appropriately
+ int putNanEnable(const NanEnableRequest *pReq);
+ int putNanDisable(const NanDisableRequest *pReq);
+ int putNanPublish(const NanPublishRequest *pReq);
+ int putNanPublishCancel(const NanPublishCancelRequest *pReq);
+ int putNanSubscribe(const NanSubscribeRequest *pReq);
+ int putNanSubscribeCancel(const NanSubscribeCancelRequest *pReq);
+ int putNanTransmitFollowup(const NanTransmitFollowupRequest *pReq);
+ int putNanStats(const NanStatsRequest *pReq);
+ int putNanConfig(const NanConfigRequest *pReq);
+ int putNanTCA(const NanTCARequest *pReq);
+ int putNanBeaconSdfPayload(const NanBeaconSdfPayloadRequest *pReq);
+ int getNanStaParameter(NanStaParameter *pRsp);
+
+ //Set the Id of the request
+ void setId(int nId);
+};
+#endif /* __WIFH_HAL_NAN_COMMAND_H__ */
+