/* * 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)) { /* upper layer must have cleaned up the handle and reinitialized, so we need to update the same */ ALOGI("Handle different, update the handle"); mNanCommandInstance->mInfo = (hal_info *)handle; } } 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 */ }