Home | History | Annotate | Download | only in wifi_hal
      1 /*
      2  * Copyright (C) 2014 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *     http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "sync.h"
     18 
     19 #include "nan.h"
     20 #include "nan_i.h"
     21 #include "wifi_hal.h"
     22 #include "common.h"
     23 #include "cpp_bindings.h"
     24 #include <utils/Log.h>
     25 #include "nancommand.h"
     26 
     27 #ifdef __GNUC__
     28 #define PRINTF_FORMAT(a,b) __attribute__ ((format (printf, (a), (b))))
     29 #define STRUCT_PACKED __attribute__ ((packed))
     30 #else
     31 #define PRINTF_FORMAT(a,b)
     32 #define STRUCT_PACKED
     33 #endif
     34 
     35 #include "qca-vendor.h"
     36 
     37 //Singleton Static Instance
     38 NanCommand* NanCommand::mNanCommandInstance  = NULL;
     39 
     40 //Implementation of the functions exposed in nan.h
     41 wifi_error nan_register_handler(wifi_handle handle,
     42                                 NanCallbackHandler handlers,
     43                                 void* userdata)
     44 {
     45     // Obtain the singleton instance
     46     int ret = 0;
     47     NanCommand *nCommand;
     48 
     49     nCommand = NanCommand::instance(handle);
     50     if (nCommand == NULL) {
     51         ALOGE("%s: Error NanCommand NULL", __func__);
     52         return WIFI_ERROR_UNKNOWN;
     53     }
     54     ret = nCommand->setCallbackHandler(handlers, userdata);
     55     return (wifi_error)ret;
     56 }
     57 
     58 wifi_error nan_get_version(wifi_handle handle,
     59                            NanVersion* version)
     60 {
     61     *version = (NAN_MAJOR_VERSION <<16 | NAN_MINOR_VERSION << 8 | NAN_MICRO_VERSION);
     62     return WIFI_SUCCESS;
     63 }
     64 
     65 /*  Function to send enable request to the wifi driver.*/
     66 wifi_error nan_enable_request(wifi_request_id id,
     67                               wifi_handle handle,
     68                               NanEnableRequest* msg)
     69 {
     70     int ret = 0;
     71     NanCommand *nCommand;
     72 
     73     nCommand = NanCommand::instance(handle);
     74     if (nCommand == NULL) {
     75         ALOGE("%s: Error NanCommand NULL", __func__);
     76         return WIFI_ERROR_UNKNOWN;
     77     }
     78 
     79     ret = nCommand->putNanEnable(msg);
     80     if (ret != 0) {
     81         ALOGE("%s: putNanEnable Error:%d",__func__, ret);
     82         goto cleanup;
     83     }
     84     nCommand->setId(id);
     85     ret = nCommand->requestEvent();
     86     if (ret != 0) {
     87         ALOGE("%s: requestEvent Error:%d",__func__, ret);
     88     }
     89 cleanup:
     90     return (wifi_error)ret;
     91 }
     92 
     93 /*  Function to send disable request to the wifi driver.*/
     94 wifi_error nan_disable_request(wifi_request_id id,
     95                                wifi_handle handle,
     96                                NanDisableRequest* msg)
     97 {
     98     int ret = 0;
     99     NanCommand *nCommand;
    100 
    101     nCommand = NanCommand::instance(handle);
    102     if (nCommand == NULL) {
    103         ALOGE("%s: Error NanCommand NULL", __func__);
    104         return WIFI_ERROR_UNKNOWN;
    105     }
    106 
    107     ret = nCommand->putNanDisable(msg);
    108     if (ret != 0) {
    109         ALOGE("%s: putNanDisable Error:%d",__func__, ret);
    110         goto cleanup;
    111     }
    112     nCommand->setId(id);
    113     ret = nCommand->requestEvent();
    114     if (ret != 0) {
    115         ALOGE("%s: requestEvent Error:%d",__func__, ret);
    116     }
    117 cleanup:
    118     return (wifi_error)ret;
    119 }
    120 
    121 /*  Function to send publish request to the wifi driver.*/
    122 wifi_error nan_publish_request(wifi_request_id id,
    123                                wifi_handle handle,
    124                                NanPublishRequest* msg)
    125 {
    126     int ret = 0;
    127     NanCommand *nCommand;
    128 
    129     nCommand = NanCommand::instance(handle);
    130     if (nCommand == NULL) {
    131         ALOGE("%s: Error NanCommand NULL", __func__);
    132         return WIFI_ERROR_UNKNOWN;
    133     }
    134 
    135     ret = nCommand->putNanPublish(msg);
    136     if (ret != 0) {
    137         ALOGE("%s: putNanPublish Error:%d",__func__, ret);
    138         goto cleanup;
    139     }
    140     nCommand->setId(id);
    141     ret = nCommand->requestEvent();
    142     if (ret != 0) {
    143         ALOGE("%s: requestEvent Error:%d",__func__, ret);
    144     }
    145 cleanup:
    146     return (wifi_error)ret;
    147 }
    148 
    149 /*  Function to send publish cancel to the wifi driver.*/
    150 wifi_error nan_publish_cancel_request(wifi_request_id id,
    151                                       wifi_handle handle,
    152                                       NanPublishCancelRequest* msg)
    153 {
    154     int ret = 0;
    155     NanCommand *nCommand;
    156 
    157     nCommand = NanCommand::instance(handle);
    158     if (nCommand == NULL) {
    159         ALOGE("%s: Error NanCommand NULL", __func__);
    160         return WIFI_ERROR_UNKNOWN;
    161     }
    162 
    163     ret = nCommand->putNanPublishCancel(msg);
    164     if (ret != 0) {
    165         ALOGE("%s: putNanPublishCancel Error:%d",__func__, ret);
    166         goto cleanup;
    167     }
    168     nCommand->setId(id);
    169     ret = nCommand->requestEvent();
    170     if (ret != 0) {
    171         ALOGE("%s: requestEvent Error:%d",__func__, ret);
    172     }
    173 cleanup:
    174     return (wifi_error)ret;
    175 }
    176 
    177 /*  Function to send Subscribe request to the wifi driver.*/
    178 wifi_error nan_subscribe_request(wifi_request_id id,
    179                                  wifi_handle handle,
    180                                  NanSubscribeRequest* msg)
    181 {
    182     int ret = 0;
    183     NanCommand *nCommand;
    184 
    185     nCommand = NanCommand::instance(handle);
    186     if (nCommand == NULL) {
    187         ALOGE("%s: Error NanCommand NULL", __func__);
    188         return WIFI_ERROR_UNKNOWN;
    189     }
    190 
    191     ret = nCommand->putNanSubscribe(msg);
    192     if (ret != 0) {
    193         ALOGE("%s: putNanSubscribe Error:%d",__func__, ret);
    194         goto cleanup;
    195     }
    196     nCommand->setId(id);
    197     ret = nCommand->requestEvent();
    198     if (ret != 0) {
    199         ALOGE("%s: requestEvent Error:%d",__func__, ret);
    200     }
    201 cleanup:
    202     return (wifi_error)ret;
    203 }
    204 
    205 /*  Function to cancel subscribe to the wifi driver.*/
    206 wifi_error nan_subscribe_cancel_request(wifi_request_id id,
    207                                         wifi_handle handle,
    208                                         NanSubscribeCancelRequest* msg)
    209 {
    210     int ret = 0;
    211     NanCommand *nCommand;
    212 
    213     nCommand = NanCommand::instance(handle);
    214     if (nCommand == NULL) {
    215         ALOGE("%s: Error NanCommand NULL", __func__);
    216         return WIFI_ERROR_UNKNOWN;
    217     }
    218 
    219     ret = nCommand->putNanSubscribeCancel(msg);
    220     if (ret != 0) {
    221         ALOGE("%s: putNanSubscribeCancel Error:%d",__func__, ret);
    222         goto cleanup;
    223     }
    224     nCommand->setId(id);
    225     ret = nCommand->requestEvent();
    226     if (ret != 0) {
    227         ALOGE("%s: requestEvent Error:%d",__func__, ret);
    228     }
    229 cleanup:
    230     return (wifi_error)ret;
    231 }
    232 
    233 /*  Function to send NAN follow up request to the wifi driver.*/
    234 wifi_error nan_transmit_followup_request(wifi_request_id id,
    235                                          wifi_handle handle,
    236                                          NanTransmitFollowupRequest* msg)
    237 {
    238     int ret = 0;
    239     NanCommand *nCommand;
    240 
    241     nCommand = NanCommand::instance(handle);
    242     if (nCommand == NULL) {
    243         ALOGE("%s: Error NanCommand NULL", __func__);
    244         return WIFI_ERROR_UNKNOWN;
    245     }
    246 
    247     ret = nCommand->putNanTransmitFollowup(msg);
    248     if (ret != 0) {
    249         ALOGE("%s: putNanTransmitFollowup Error:%d",__func__, ret);
    250         goto cleanup;
    251     }
    252     nCommand->setId(id);
    253     ret = nCommand->requestEvent();
    254     if (ret != 0) {
    255         ALOGE("%s: requestEvent Error:%d",__func__, ret);
    256     }
    257 cleanup:
    258     return (wifi_error)ret;
    259 }
    260 
    261 /*  Function to send NAN statistics request to the wifi driver.*/
    262 wifi_error nan_stats_request(wifi_request_id id,
    263                              wifi_handle handle,
    264                              NanStatsRequest* msg)
    265 {
    266     int ret = 0;
    267     NanCommand *nCommand;
    268 
    269     nCommand = NanCommand::instance(handle);
    270     if (nCommand == NULL) {
    271         ALOGE("%s: Error NanCommand NULL", __func__);
    272         return WIFI_ERROR_UNKNOWN;
    273     }
    274 
    275     ret = nCommand->putNanStats(msg);
    276     if (ret != 0) {
    277         ALOGE("%s: putNanStats Error:%d",__func__, ret);
    278         goto cleanup;
    279     }
    280     nCommand->setId(id);
    281     ret = nCommand->requestEvent();
    282     if (ret != 0) {
    283         ALOGE("%s: requestEvent Error:%d",__func__, ret);
    284     }
    285 cleanup:
    286     return (wifi_error)ret;
    287 }
    288 
    289 /*  Function to send NAN configuration request to the wifi driver.*/
    290 wifi_error nan_config_request(wifi_request_id id,
    291                               wifi_handle handle,
    292                               NanConfigRequest* msg)
    293 {
    294     int ret = 0;
    295     NanCommand *nCommand;
    296 
    297     nCommand = NanCommand::instance(handle);
    298     if (nCommand == NULL) {
    299         ALOGE("%s: Error NanCommand NULL", __func__);
    300         return WIFI_ERROR_UNKNOWN;
    301     }
    302 
    303     ret = nCommand->putNanConfig(msg);
    304     if (ret != 0) {
    305         ALOGE("%s: putNanConfig Error:%d",__func__, ret);
    306         goto cleanup;
    307     }
    308     nCommand->setId(id);
    309     ret = nCommand->requestEvent();
    310     if (ret != 0) {
    311         ALOGE("%s: requestEvent Error:%d",__func__, ret);
    312     }
    313 cleanup:
    314     return (wifi_error)ret;
    315 }
    316 
    317 /*  Function to send NAN request to the wifi driver.*/
    318 wifi_error nan_tca_request(wifi_request_id id,
    319                            wifi_handle handle,
    320                            NanTCARequest* msg)
    321 {
    322     int ret = 0;
    323     NanCommand *nCommand;
    324 
    325     nCommand = NanCommand::instance(handle);
    326     if (nCommand == NULL) {
    327         ALOGE("%s: Error NanCommand NULL", __func__);
    328         return WIFI_ERROR_UNKNOWN;
    329     }
    330 
    331     ret = nCommand->putNanTCA(msg);
    332     if (ret != 0) {
    333         ALOGE("%s: putNanTCA Error:%d",__func__, ret);
    334         goto cleanup;
    335     }
    336     nCommand->setId(id);
    337     ret = nCommand->requestEvent();
    338     if (ret != 0) {
    339         ALOGE("%s: requestEvent Error:%d",__func__, ret);
    340     }
    341 cleanup:
    342     return (wifi_error)ret;
    343 }
    344 
    345 /*  Function to send NAN Beacon sdf payload to the wifi driver.
    346     This instructs the Discovery Engine to begin publishing the
    347     received payload in any Beacon or Service Discovery Frame
    348     transmitted*/
    349 wifi_error nan_beacon_sdf_payload_request(wifi_request_id id,
    350                                          wifi_handle handle,
    351                                          NanBeaconSdfPayloadRequest* msg)
    352 {
    353     int ret = WIFI_ERROR_NOT_SUPPORTED;
    354 #ifdef NAN_2_0
    355     NanCommand *nCommand;
    356 
    357     nCommand = NanCommand::instance(handle);
    358     if (nCommand == NULL) {
    359         ALOGE("%s: Error NanCommand NULL", __func__);
    360         return WIFI_ERROR_UNKNOWN;
    361     }
    362 
    363     ret = nCommand->putNanBeaconSdfPayload(msg);
    364     if (ret != 0) {
    365         ALOGE("%s: putNanBeaconSdfPayload Error:%d",__func__, ret);
    366         goto cleanup;
    367     }
    368     nCommand->setId(id);
    369     ret = nCommand->requestEvent();
    370     if (ret != 0) {
    371         ALOGE("%s: requestEvent Error:%d",__func__, ret);
    372     }
    373 #endif /* NAN_2_0 */
    374 cleanup:
    375     return (wifi_error)ret;
    376 }
    377 
    378 wifi_error nan_get_sta_parameter(wifi_request_id id,
    379                                  wifi_handle handle,
    380                                  NanStaParameter* msg)
    381 {
    382     int ret = WIFI_ERROR_NOT_SUPPORTED;
    383 #ifdef NAN_2_0
    384     NanCommand *nCommand;
    385 
    386     nCommand = NanCommand::instance(handle);
    387     if (nCommand == NULL) {
    388         ALOGE("%s: Error NanCommand NULL", __func__);
    389         return WIFI_ERROR_UNKNOWN;
    390     }
    391 
    392     nCommand->setId(id);
    393     ret = nCommand->getNanStaParameter(msg);
    394     if (ret != 0) {
    395         ALOGE("%s: getNanStaParameter Error:%d",__func__, ret);
    396         goto cleanup;
    397     }
    398 #endif /* NAN_2_0 */
    399 cleanup:
    400     return (wifi_error)ret;
    401 }
    402 
    403 // Implementation related to nan class common functions
    404 // Constructor
    405 //Making the constructor private since this class is a singleton
    406 NanCommand::NanCommand(wifi_handle handle, int id, u32 vendor_id, u32 subcmd)
    407         : WifiVendorCommand(handle, id, vendor_id, subcmd)
    408 {
    409     ALOGV("NanCommand %p constructed", this);
    410     memset(&mHandler, 0,sizeof(mHandler));
    411     mNanVendorEvent = NULL;
    412     mNanDataLen = 0;
    413     mStaParam = NULL;
    414     mUserData = NULL;
    415 }
    416 
    417 NanCommand* NanCommand::instance(wifi_handle handle)
    418 {
    419     if (handle == NULL) {
    420         ALOGE("Handle is invalid");
    421         return NULL;
    422     }
    423     if (mNanCommandInstance == NULL) {
    424         mNanCommandInstance = new NanCommand(handle, 0,
    425                                              OUI_QCA,
    426                                              QCA_NL80211_VENDOR_SUBCMD_NAN);
    427         ALOGV("NanCommand %p created", mNanCommandInstance);
    428         return mNanCommandInstance;
    429     }
    430     else
    431     {
    432         if (handle != getWifiHandle(mNanCommandInstance->mInfo)) {
    433             /* upper layer must have cleaned up the handle and reinitialized,
    434                so we need to update the same */
    435             ALOGI("Handle different, update the handle");
    436             mNanCommandInstance->mInfo = (hal_info *)handle;
    437         }
    438     }
    439     ALOGV("NanCommand %p created already", mNanCommandInstance);
    440     return mNanCommandInstance;
    441 }
    442 
    443 NanCommand::~NanCommand()
    444 {
    445     ALOGV("NanCommand %p destroyed", this);
    446     unregisterVendorHandler(mVendor_id, mSubcmd);
    447 }
    448 
    449 // This function implements creation of Vendor command
    450 // For NAN just call base Vendor command create
    451 int NanCommand::create() {
    452     return (WifiVendorCommand::create());
    453 }
    454 
    455 int NanCommand::handleResponse(WifiEvent reply){
    456     ALOGI("skipping a response");
    457     return NL_SKIP;
    458 }
    459 
    460 int NanCommand::setCallbackHandler(NanCallbackHandler nHandler,
    461                                    void *pUserData)
    462 {
    463     int res = 0;
    464     mHandler = nHandler;
    465     mUserData = pUserData;
    466     res = registerVendorHandler(mVendor_id, mSubcmd);
    467     if (res != 0) {
    468         //error case should not happen print log
    469         ALOGE("%s: Unable to register Vendor Handler Vendor Id=0x%x subcmd=%u",
    470               __func__, mVendor_id, mSubcmd);
    471     }
    472     return res;
    473 }
    474 
    475 // This function will be the main handler for incoming event
    476 // QCA_NL80211_VENDOR_SUBCMD_NAN
    477 //Call the appropriate callback handler after parsing the vendor data.
    478 int NanCommand::handleEvent(WifiEvent &event)
    479 {
    480     ALOGI("Got a NAN message from Driver");
    481     WifiVendorCommand::handleEvent(event);
    482 
    483     if (mSubcmd == QCA_NL80211_VENDOR_SUBCMD_NAN){
    484         // Parse the vendordata and get the NAN attribute
    485         struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_MAX + 1];
    486         nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_MAX,
    487                   (struct nlattr *)mVendorData,
    488                   mDataLen, NULL);
    489         // Populating the mNanVendorEvent and mNanDataLen to point to NAN data.
    490         mNanVendorEvent = (char *)nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_NAN]);
    491         mNanDataLen = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_NAN]);
    492 
    493         if (isNanResponse()) {
    494             //handleNanResponse will parse the data and call
    495             //the response callback handler with the populated
    496             //NanResponseMsg
    497             handleNanResponse();
    498         }
    499         else {
    500             //handleNanIndication will parse the data and call
    501             //the corresponding Indication callback handler
    502             //with the corresponding populated Indication event
    503             handleNanIndication();
    504         }
    505     }
    506     else {
    507         //error case should not happen print log
    508         ALOGE("%s: Wrong NAN subcmd received %d", __func__, mSubcmd);
    509     }
    510     return NL_SKIP;
    511 }
    512 
    513 /*Helper function to Write and Read TLV called in indication as well as request */
    514 u16 NANTLV_WriteTlv(pNanTlv pInTlv, u8 *pOutTlv)
    515 {
    516     u16 writeLen = 0;
    517     u16 i;
    518 
    519     if (!pInTlv)
    520     {
    521         ALOGE("NULL pInTlv");
    522         return writeLen;
    523     }
    524 
    525     if (!pOutTlv)
    526     {
    527         ALOGE("NULL pOutTlv");
    528         return writeLen;
    529     }
    530 
    531     *pOutTlv++ = pInTlv->type & 0xFF;
    532     *pOutTlv++ = (pInTlv->type & 0xFF00) >> 8;
    533     writeLen += 2;
    534 
    535     ALOGV("WRITE TLV type %u, writeLen %u", pInTlv->type, writeLen);
    536 
    537     *pOutTlv++ = pInTlv->length & 0xFF;
    538     *pOutTlv++ = (pInTlv->length & 0xFF00) >> 8;
    539     writeLen += 2;
    540 
    541     ALOGV("WRITE TLV length %u, writeLen %u", pInTlv->length, writeLen);
    542 
    543     for (i=0; i < pInTlv->length; ++i)
    544     {
    545         *pOutTlv++ = pInTlv->value[i];
    546     }
    547 
    548     writeLen += pInTlv->length;
    549     ALOGV("WRITE TLV value, writeLen %u", writeLen);
    550     return writeLen;
    551 }
    552 
    553 u16 NANTLV_ReadTlv(u8 *pInTlv, pNanTlv pOutTlv)
    554 {
    555     u16 readLen = 0;
    556     u16 tmp = 0;
    557 
    558     if (!pInTlv)
    559     {
    560         ALOGE("NULL pInTlv");
    561         return readLen;
    562     }
    563 
    564     if (!pOutTlv)
    565     {
    566         ALOGE("NULL pOutTlv");
    567         return readLen;
    568     }
    569 
    570     pOutTlv->type = *pInTlv++;
    571     pOutTlv->type |= *pInTlv++ << 8;
    572     readLen += 2;
    573 
    574     ALOGV("READ TLV type %u, readLen %u", pOutTlv->type, readLen);
    575 
    576     pOutTlv->length = *pInTlv++;
    577     pOutTlv->length |= *pInTlv++ << 8;
    578     readLen += 2;
    579 
    580     ALOGV("READ TLV length %u, readLen %u", pOutTlv->length, readLen);
    581 
    582     if (pOutTlv->length)
    583     {
    584         pOutTlv->value = pInTlv;
    585         readLen += pOutTlv->length;
    586     }
    587     else
    588     {
    589         pOutTlv->value = NULL;
    590     }
    591 
    592     ALOGV("READ TLV value %u, readLen %u", pOutTlv->value, readLen);
    593 
    594     /* Map the right TLV value based on NAN version in Firmware
    595        which the framework can understand*/
    596     tmp = pOutTlv->type;
    597     pOutTlv->type = getNanTlvtypeFromFWTlvtype(pOutTlv->type);
    598     ALOGI("%s: FWTlvtype:%d NanTlvtype:%d", __func__,
    599           tmp, pOutTlv->type);
    600     return readLen;
    601 }
    602 
    603 u8* addTlv(u16 type, u16 length, const u8* value, u8* pOutTlv)
    604 {
    605    NanTlv nanTlv;
    606    u16 len;
    607    u16 tmp =0;
    608 
    609    /* Set the right TLV based on NAN version in Firmware */
    610    tmp = type;
    611    type = getFWTlvtypeFromNanTlvtype(type);
    612    ALOGI("%s: NanTlvtype:%d FWTlvtype:%d", __func__,
    613          tmp, type);
    614 
    615    nanTlv.type = type;
    616    nanTlv.length = length;
    617    nanTlv.value = (u8*)value;
    618 
    619    len = NANTLV_WriteTlv(&nanTlv, pOutTlv);
    620    return (pOutTlv + len);
    621 }
    622 
    623 void NanCommand::setId(int nId)
    624 {
    625     mId = nId;
    626 }
    627 
    628 u16 getNanTlvtypeFromFWTlvtype(u16 fwTlvtype)
    629 {
    630 #ifndef NAN_2_0
    631     /* In case of Pronto no mapping required */
    632     return fwTlvtype;
    633 #else /* NAN_2_0 */
    634     if (fwTlvtype <= NAN_TLV_TYPE_FW_SERVICE_SPECIFIC_INFO) {
    635         /* return the TLV value as is */
    636         return fwTlvtype;
    637     }
    638     if (fwTlvtype >= NAN_TLV_TYPE_FW_TCA_LAST) {
    639         return fwTlvtype;
    640     }
    641     /* Other FW TLV values and Config types map it
    642        appropriately
    643     */
    644     switch (fwTlvtype) {
    645     case NAN_TLV_TYPE_FW_EXT_SERVICE_SPECIFIC_INFO:
    646         return NAN_TLV_TYPE_EXT_SERVICE_SPECIFIC_INFO;
    647     case NAN_TLV_TYPE_FW_VENDOR_SPECIFIC_ATTRIBUTE_TRANSMIT:
    648         return NAN_TLV_TYPE_VENDOR_SPECIFIC_ATTRIBUTE_TRANSMIT;
    649     case NAN_TLV_TYPE_FW_VENDOR_SPECIFIC_ATTRIBUTE_RECEIVE:
    650         return NAN_TLV_TYPE_VENDOR_SPECIFIC_ATTRIBUTE_RECEIVE;
    651     case NAN_TLV_TYPE_FW_POST_NAN_CONNECTIVITY_CAPABILITIES_RECEIVE:
    652         return NAN_TLV_TYPE_POST_NAN_CONNECTIVITY_CAPABILITIES_RECEIVE;
    653     case NAN_TLV_TYPE_FW_POST_NAN_DISCOVERY_ATTRIBUTE_RECEIVE:
    654         return NAN_TLV_TYPE_POST_NAN_DISCOVERY_ATTRIBUTE_RECEIVE;
    655     case NAN_TLV_TYPE_FW_BEACON_SDF_PAYLOAD_RECEIVE:
    656         return NAN_TLV_TYPE_BEACON_SDF_PAYLOAD_RECEIVE;
    657 
    658     case NAN_TLV_TYPE_FW_24G_SUPPORT:
    659         return NAN_TLV_TYPE_2DOT4G_SUPPORT;
    660     case NAN_TLV_TYPE_FW_24G_BEACON:
    661             return NAN_TLV_TYPE_2DOT4G_BEACONS;
    662     case NAN_TLV_TYPE_FW_24G_SDF:
    663         return NAN_TLV_TYPE_2DOT4G_SDF;
    664     case NAN_TLV_TYPE_FW_24G_RSSI_CLOSE:
    665         return NAN_TLV_TYPE_RSSI_CLOSE;
    666     case NAN_TLV_TYPE_FW_24G_RSSI_MIDDLE:
    667         return NAN_TLV_TYPE_RSSI_MEDIUM;
    668     case NAN_TLV_TYPE_FW_24G_RSSI_CLOSE_PROXIMITY:
    669         return NAN_TLV_TYPE_RSSI_CLOSE_PROXIMITY;
    670     case NAN_TLV_TYPE_FW_5G_SUPPORT:
    671         return NAN_TLV_TYPE_5G_SUPPORT;
    672     case NAN_TLV_TYPE_FW_5G_BEACON:
    673         return NAN_TLV_TYPE_5G_BEACON;
    674     case NAN_TLV_TYPE_FW_5G_SDF:
    675             return NAN_TLV_TYPE_5G_SDF;
    676     case NAN_TLV_TYPE_FW_5G_RSSI_CLOSE:
    677             return NAN_TLV_TYPE_5G_RSSI_CLOSE;
    678     case NAN_TLV_TYPE_FW_5G_RSSI_MIDDLE:
    679         return NAN_TLV_TYPE_5G_RSSI_MEDIUM;
    680     case NAN_TLV_TYPE_FW_5G_RSSI_CLOSE_PROXIMITY:
    681         return NAN_TLV_TYPE_5G_RSSI_CLOSE_PROXIMITY;
    682     case NAN_TLV_TYPE_FW_SID_BEACON:
    683         return NAN_TLV_TYPE_SID_BEACON;
    684     case NAN_TLV_TYPE_FW_HOP_COUNT_LIMIT:
    685         return NAN_TLV_TYPE_HOP_COUNT_LIMIT;
    686     case NAN_TLV_TYPE_FW_MASTER_PREFERENCE:
    687         return NAN_TLV_TYPE_MASTER_PREFERENCE;
    688     case NAN_TLV_TYPE_FW_CLUSTER_ID_LOW:
    689         return NAN_TLV_TYPE_CLUSTER_ID_LOW;
    690     case NAN_TLV_TYPE_FW_CLUSTER_ID_HIGH:
    691         return NAN_TLV_TYPE_CLUSTER_ID_HIGH;
    692     case NAN_TLV_TYPE_FW_RSSI_AVERAGING_WINDOW_SIZE:
    693             return NAN_TLV_TYPE_RSSI_AVERAGING_WINDOW_SIZE;
    694     case NAN_TLV_TYPE_FW_CLUSTER_OUI_NETWORK_ID:
    695         return NAN_TLV_TYPE_CLUSTER_OUI_NETWORK_ID;
    696     case NAN_TLV_TYPE_FW_SOURCE_MAC_ADDRESS:
    697             return NAN_TLV_TYPE_SOURCE_MAC_ADDRESS;
    698     case NAN_TLV_TYPE_FW_CLUSTER_ATTRIBUTE_IN_SDF:
    699         return NAN_TLV_TYPE_CLUSTER_ATTRIBUTE_IN_SDF;
    700     case NAN_TLV_TYPE_FW_SOCIAL_CHANNEL_SCAN_PARAMS:
    701         return NAN_TLV_TYPE_SOCIAL_CHANNEL_SCAN_PARAMETERS;
    702     case NAN_TLV_TYPE_FW_DEBUGGING_FLAGS:
    703         return NAN_TLV_TYPE_DEBUGGING_FLAGS;
    704     case NAN_TLV_TYPE_FW_POST_NAN_CONNECTIVITY_CAPABILITIES_TRANSMIT:
    705         return NAN_TLV_TYPE_POST_NAN_CONNECTIVITY_CAPABILITIES_TRANSMIT;
    706     case NAN_TLV_TYPE_FW_POST_NAN_DISCOVERY_ATTRIBUTE_TRANSMIT:
    707         return NAN_TLV_TYPE_POST_NAN_DISCOVERY_ATTRIBUTE_TRANSMIT;
    708     case NAN_TLV_TYPE_FW_FURTHER_AVAILABILITY_MAP:
    709         return NAN_TLV_TYPE_FURTHER_AVAILABILITY_MAP;
    710     case NAN_TLV_TYPE_FW_HOP_COUNT_FORCE:
    711         return NAN_TLV_TYPE_HOP_COUNT_FORCE;
    712     case NAN_TLV_TYPE_FW_RANDOM_FACTOR_FORCE:
    713         return NAN_TLV_TYPE_RANDOM_FACTOR_FORCE;
    714 
    715     /* Attrib types */
    716     /* Unmapped attrib types */
    717     case NAN_TLV_TYPE_FW_AVAILABILITY_INTERVALS_MAP:
    718         break;
    719     case NAN_TLV_TYPE_FW_WLAN_MESH_ID:
    720         return NAN_TLV_TYPE_WLAN_MESH_ID;
    721     case NAN_TLV_TYPE_FW_MAC_ADDRESS:
    722         return NAN_TLV_TYPE_MAC_ADDRESS;
    723     case NAN_TLV_TYPE_FW_RECEIVED_RSSI_VALUE:
    724         return NAN_TLV_TYPE_RECEIVED_RSSI_VALUE;
    725     case NAN_TLV_TYPE_FW_CLUSTER_ATTRIBUTE:
    726         return NAN_TLV_TYPE_CLUSTER_ATTIBUTE;
    727     case NAN_TLV_TYPE_FW_WLAN_INFRASTRUCTURE_SSID:
    728         return NAN_TLV_TYPE_WLAN_INFRASTRUCTURE_SSID;
    729 
    730     /* Events Type */
    731     case NAN_TLV_TYPE_FW_EVENT_SELF_STATION_MAC_ADDRESS:
    732         return NAN_EVENT_ID_STA_MAC_ADDR;
    733     case NAN_TLV_TYPE_FW_EVENT_STARTED_CLUSTER:
    734         return NAN_EVENT_ID_STARTED_CLUSTER;
    735     case NAN_TLV_TYPE_FW_EVENT_JOINED_CLUSTER:
    736         return NAN_EVENT_ID_JOINED_CLUSTER;
    737     /* unmapped Event Type */
    738     case NAN_TLV_TYPE_FW_EVENT_CLUSTER_SCAN_RESULTS:
    739         break;
    740 
    741     case NAN_TLV_TYPE_FW_TCA_CLUSTER_SIZE_REQ:
    742     case NAN_TLV_TYPE_FW_TCA_CLUSTER_SIZE_RSP:
    743         return NAN_TCA_ID_CLUSTER_SIZE;
    744 
    745     default:
    746         break;
    747     }
    748     ALOGE("%s: Unhandled FW TLV value:%d", __func__, fwTlvtype);
    749     return 0xFFFF;
    750 #endif /*NAN_2_0*/
    751 }
    752 
    753 u16 getFWTlvtypeFromNanTlvtype(u16 nanTlvtype)
    754 {
    755 #ifndef NAN_2_0
    756     /* In case of Pronto no mapping required */
    757     return nanTlvtype;
    758 #else /* NAN_2_0 */
    759     if (nanTlvtype <= NAN_TLV_TYPE_SERVICE_SPECIFIC_INFO) {
    760         /* return the TLV value as is */
    761         return nanTlvtype;
    762     }
    763     if (nanTlvtype >= NAN_TLV_TYPE_STATS_FIRST &&
    764         nanTlvtype <= NAN_TLV_TYPE_STATS_LAST) {
    765         return nanTlvtype;
    766     }
    767     /* Other NAN TLV values and Config types map it
    768        appropriately
    769     */
    770     switch (nanTlvtype) {
    771     case NAN_TLV_TYPE_EXT_SERVICE_SPECIFIC_INFO:
    772         return NAN_TLV_TYPE_FW_EXT_SERVICE_SPECIFIC_INFO;
    773     case NAN_TLV_TYPE_SDF_LAST:
    774         return NAN_TLV_TYPE_FW_SDF_LAST;
    775 
    776     /* Configuration types */
    777     case NAN_TLV_TYPE_5G_SUPPORT:
    778         return NAN_TLV_TYPE_FW_5G_SUPPORT;
    779     case NAN_TLV_TYPE_SID_BEACON:
    780         return NAN_TLV_TYPE_FW_SID_BEACON;
    781     case NAN_TLV_TYPE_5G_SYNC_DISC:
    782         break;
    783     case NAN_TLV_TYPE_RSSI_CLOSE:
    784         return NAN_TLV_TYPE_FW_24G_RSSI_CLOSE;
    785     case NAN_TLV_TYPE_RSSI_MEDIUM:
    786         return NAN_TLV_TYPE_FW_24G_RSSI_MIDDLE;
    787     case NAN_TLV_TYPE_HOP_COUNT_LIMIT:
    788         return NAN_TLV_TYPE_FW_HOP_COUNT_LIMIT;
    789     /* unmapped */
    790     case NAN_TLV_TYPE_RANDOM_UPDATE_TIME:
    791         break;
    792     case NAN_TLV_TYPE_MASTER_PREFERENCE:
    793         return NAN_TLV_TYPE_FW_MASTER_PREFERENCE;
    794     /* unmapped */
    795     case NAN_TLV_TYPE_EARLY_WAKEUP:
    796         break;
    797     case NAN_TLV_TYPE_PERIODIC_SCAN_INTERVAL:
    798         break;
    799     case NAN_TLV_TYPE_CLUSTER_ID_LOW:
    800         return NAN_TLV_TYPE_FW_CLUSTER_ID_LOW;
    801     case NAN_TLV_TYPE_CLUSTER_ID_HIGH:
    802         return NAN_TLV_TYPE_FW_CLUSTER_ID_HIGH;
    803     case NAN_TLV_TYPE_RSSI_CLOSE_PROXIMITY:
    804         return NAN_TLV_TYPE_FW_24G_RSSI_CLOSE_PROXIMITY;
    805     case NAN_TLV_TYPE_CONFIG_LAST:
    806         return NAN_TLV_TYPE_FW_CONFIG_LAST;
    807     case NAN_TLV_TYPE_FURTHER_AVAILABILITY:
    808         break;
    809 
    810     /* All Stats type are unmapped as of now */
    811 
    812     /* Attributes types */
    813     case NAN_TLV_TYPE_WLAN_MESH_ID:
    814         return NAN_TLV_TYPE_FW_WLAN_MESH_ID;
    815     case NAN_TLV_TYPE_MAC_ADDRESS:
    816         return NAN_TLV_TYPE_FW_MAC_ADDRESS;
    817     case NAN_TLV_TYPE_RECEIVED_RSSI_VALUE:
    818         return NAN_TLV_TYPE_FW_RECEIVED_RSSI_VALUE;
    819     case NAN_TLV_TYPE_TCA_CLUSTER_SIZE_REQ:
    820         return NAN_TLV_TYPE_FW_TCA_CLUSTER_SIZE_REQ;
    821     case NAN_TLV_TYPE_ATTRS_LAST:
    822         return NAN_TLV_TYPE_FW_ATTRS_LAST;
    823 
    824     case NAN_TLV_TYPE_VENDOR_SPECIFIC_ATTRIBUTE_TRANSMIT:
    825         return NAN_TLV_TYPE_FW_VENDOR_SPECIFIC_ATTRIBUTE_TRANSMIT;
    826     case NAN_TLV_TYPE_VENDOR_SPECIFIC_ATTRIBUTE_RECEIVE:
    827         return NAN_TLV_TYPE_FW_VENDOR_SPECIFIC_ATTRIBUTE_RECEIVE;
    828     case NAN_TLV_TYPE_POST_NAN_CONNECTIVITY_CAPABILITIES_TRANSMIT:
    829         return NAN_TLV_TYPE_FW_POST_NAN_CONNECTIVITY_CAPABILITIES_TRANSMIT;
    830     case NAN_TLV_TYPE_POST_NAN_CONNECTIVITY_CAPABILITIES_RECEIVE:
    831         return NAN_TLV_TYPE_FW_POST_NAN_CONNECTIVITY_CAPABILITIES_RECEIVE;
    832     case NAN_TLV_TYPE_POST_NAN_DISCOVERY_ATTRIBUTE_TRANSMIT:
    833         return NAN_TLV_TYPE_FW_POST_NAN_DISCOVERY_ATTRIBUTE_TRANSMIT;
    834     case NAN_TLV_TYPE_POST_NAN_DISCOVERY_ATTRIBUTE_RECEIVE:
    835         return NAN_TLV_TYPE_FW_POST_NAN_DISCOVERY_ATTRIBUTE_RECEIVE;
    836     case NAN_TLV_TYPE_FURTHER_AVAILABILITY_MAP:
    837         return NAN_TLV_TYPE_FW_FURTHER_AVAILABILITY_MAP;
    838     case NAN_TLV_TYPE_BEACON_SDF_PAYLOAD_RECEIVE:
    839         return NAN_TLV_TYPE_FW_BEACON_SDF_PAYLOAD_RECEIVE;
    840 
    841     case NAN_TLV_TYPE_2DOT4G_SUPPORT:
    842         return NAN_TLV_TYPE_FW_24G_SUPPORT;
    843     case NAN_TLV_TYPE_2DOT4G_BEACONS:
    844         return NAN_TLV_TYPE_FW_24G_BEACON;
    845     case NAN_TLV_TYPE_2DOT4G_SDF:
    846         return NAN_TLV_TYPE_FW_24G_SDF;
    847     case NAN_TLV_TYPE_5G_BEACON:
    848         return NAN_TLV_TYPE_FW_5G_BEACON;
    849     case NAN_TLV_TYPE_5G_SDF:
    850         return NAN_TLV_TYPE_FW_5G_SDF;
    851     case NAN_TLV_TYPE_5G_RSSI_CLOSE:
    852         return NAN_TLV_TYPE_FW_5G_RSSI_CLOSE;
    853     case NAN_TLV_TYPE_5G_RSSI_MEDIUM:
    854         return NAN_TLV_TYPE_FW_5G_RSSI_MIDDLE;
    855     case NAN_TLV_TYPE_5G_RSSI_CLOSE_PROXIMITY:
    856         return NAN_TLV_TYPE_FW_5G_RSSI_CLOSE_PROXIMITY;
    857     case NAN_TLV_TYPE_RSSI_AVERAGING_WINDOW_SIZE:
    858         return NAN_TLV_TYPE_FW_RSSI_AVERAGING_WINDOW_SIZE;
    859     case NAN_TLV_TYPE_CLUSTER_OUI_NETWORK_ID:
    860         return NAN_TLV_TYPE_FW_CLUSTER_OUI_NETWORK_ID;
    861     case NAN_TLV_TYPE_SOURCE_MAC_ADDRESS:
    862         return NAN_TLV_TYPE_FW_SOURCE_MAC_ADDRESS;
    863     case NAN_TLV_TYPE_CLUSTER_ATTRIBUTE_IN_SDF:
    864         return NAN_TLV_TYPE_FW_CLUSTER_ATTRIBUTE_IN_SDF;
    865     case NAN_TLV_TYPE_SOCIAL_CHANNEL_SCAN_PARAMETERS:
    866         return NAN_TLV_TYPE_FW_SOCIAL_CHANNEL_SCAN_PARAMS;
    867     case NAN_TLV_TYPE_DEBUGGING_FLAGS:
    868         return NAN_TLV_TYPE_FW_DEBUGGING_FLAGS;
    869     case NAN_TLV_TYPE_WLAN_INFRASTRUCTURE_SSID:
    870         return NAN_TLV_TYPE_FW_WLAN_INFRASTRUCTURE_SSID;
    871     case NAN_TLV_TYPE_RANDOM_FACTOR_FORCE:
    872         return NAN_TLV_TYPE_FW_RANDOM_FACTOR_FORCE;
    873     case NAN_TLV_TYPE_HOP_COUNT_FORCE:
    874         return NAN_TLV_TYPE_FW_HOP_COUNT_FORCE;
    875 
    876 
    877     default:
    878         break;
    879     }
    880     ALOGE("%s: Unhandled NAN TLV value:%d", __func__, nanTlvtype);
    881     return 0xFFFF;
    882 #endif /* NAN_2_0 */
    883 }
    884