diff options
author | Linux Build Service Account <lnxbuild@localhost> | 2014-10-14 18:32:47 -0700 |
---|---|---|
committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2014-10-14 18:32:47 -0700 |
commit | 7a861371f6f8fc61c342ec0fa17892e9796091fa (patch) | |
tree | caf3e393d00b1603cd1ba77f3e7e265d01ac91ba | |
parent | 8bc8d61f47b31c12b3e858febca6c62f1e93fef5 (diff) | |
parent | 647566496b620f6f9b604271f6d7faa5e8d391ef (diff) | |
download | android_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.mk | 18 | ||||
-rw-r--r-- | qcwcn/wifi_hal/nan.cpp | 876 | ||||
-rw-r--r-- | qcwcn/wifi_hal/nan.h | 1764 | ||||
-rw-r--r-- | qcwcn/wifi_hal/nan_i.h | 875 | ||||
-rw-r--r-- | qcwcn/wifi_hal/nan_ind.cpp | 956 | ||||
-rw-r--r-- | qcwcn/wifi_hal/nan_req.cpp | 1071 | ||||
-rw-r--r-- | qcwcn/wifi_hal/nan_rsp.cpp | 276 | ||||
-rw-r--r-- | qcwcn/wifi_hal/nancommand.h | 120 |
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__ */ + |