| /* |
| * 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.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, |
| void* userdata) |
| { |
| // 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, userdata); |
| 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; |
| mUserData = 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, |
| void *pUserData) |
| { |
| int res = 0; |
| mHandler = nHandler; |
| mUserData = pUserData; |
| 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 */ |
| } |