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 "wifi_hal.h"
     20 #include "nan_i.h"
     21 #include "common.h"
     22 #include "cpp_bindings.h"
     23 #include <utils/Log.h>
     24 #include "nancommand.h"
     25 
     26 #ifdef __GNUC__
     27 #define PRINTF_FORMAT(a,b) __attribute__ ((format (printf, (a), (b))))
     28 #define STRUCT_PACKED __attribute__ ((packed))
     29 #else
     30 #define PRINTF_FORMAT(a,b)
     31 #define STRUCT_PACKED
     32 #endif
     33 
     34 #include "qca-vendor.h"
     35 
     36 //Singleton Static Instance
     37 NanCommand* NanCommand::mNanCommandInstance  = NULL;
     38 
     39 //Implementation of the functions exposed in nan.h
     40 wifi_error nan_register_handler(wifi_interface_handle iface,
     41                                 NanCallbackHandler handlers)
     42 {
     43     // Obtain the singleton instance
     44     int ret = 0;
     45     NanCommand *nanCommand = NULL;
     46     interface_info *ifaceInfo = getIfaceInfo(iface);
     47     wifi_handle wifiHandle = getWifiHandle(iface);
     48 
     49     nanCommand = NanCommand::instance(wifiHandle);
     50     if (nanCommand == NULL) {
     51         ALOGE("%s: Error NanCommand NULL", __func__);
     52         return WIFI_ERROR_UNKNOWN;
     53     }
     54 
     55     ret = nanCommand->setCallbackHandler(handlers);
     56     return (wifi_error)ret;
     57 
     58 cleanup:
     59     return (wifi_error)ret;
     60 }
     61 
     62 wifi_error nan_get_version(wifi_handle handle,
     63                            NanVersion* version)
     64 {
     65     *version = (NAN_MAJOR_VERSION <<16 | NAN_MINOR_VERSION << 8 | NAN_MICRO_VERSION);
     66     return WIFI_SUCCESS;
     67 }
     68 
     69 /*  Function to send enable request to the wifi driver.*/
     70 wifi_error nan_enable_request(transaction_id id,
     71                               wifi_interface_handle iface,
     72                               NanEnableRequest* msg)
     73 {
     74     int ret = 0;
     75     NanCommand *nanCommand = NULL;
     76     interface_info *ifaceInfo = getIfaceInfo(iface);
     77     wifi_handle wifiHandle = getWifiHandle(iface);
     78 
     79     nanCommand = new NanCommand(wifiHandle,
     80                                 0,
     81                                 OUI_QCA,
     82                                 QCA_NL80211_VENDOR_SUBCMD_NAN);
     83     if (nanCommand == NULL) {
     84         ALOGE("%s: Error NanCommand NULL", __func__);
     85         return WIFI_ERROR_UNKNOWN;
     86     }
     87 
     88     ret = nanCommand->create();
     89     if (ret < 0)
     90         goto cleanup;
     91 
     92     /* Set the interface Id of the message. */
     93     ret = nanCommand->set_iface_id(ifaceInfo->name);
     94     if (ret < 0)
     95         goto cleanup;
     96 
     97     ret = nanCommand->putNanEnable(id, msg);
     98     if (ret != 0) {
     99         ALOGE("%s: putNanEnable Error:%d",__func__, ret);
    100         goto cleanup;
    101     }
    102     ret = nanCommand->requestEvent();
    103     if (ret != 0) {
    104         ALOGE("%s: requestEvent Error:%d",__func__, ret);
    105     }
    106 cleanup:
    107     delete nanCommand;
    108     return (wifi_error)ret;
    109 }
    110 
    111 /*  Function to send disable request to the wifi driver.*/
    112 wifi_error nan_disable_request(transaction_id id,
    113                                wifi_interface_handle iface)
    114 {
    115     int ret = 0;
    116     NanCommand *nanCommand = NULL;
    117     interface_info *ifaceInfo = getIfaceInfo(iface);
    118     wifi_handle wifiHandle = getWifiHandle(iface);
    119 
    120     nanCommand = new NanCommand(wifiHandle,
    121                                 0,
    122                                 OUI_QCA,
    123                                 QCA_NL80211_VENDOR_SUBCMD_NAN);
    124     if (nanCommand == NULL) {
    125         ALOGE("%s: Error NanCommand NULL", __func__);
    126         return WIFI_ERROR_UNKNOWN;
    127     }
    128 
    129     ret = nanCommand->create();
    130     if (ret < 0)
    131         goto cleanup;
    132 
    133     /* Set the interface Id of the message. */
    134     ret = nanCommand->set_iface_id(ifaceInfo->name);
    135     if (ret < 0)
    136         goto cleanup;
    137 
    138     ret = nanCommand->putNanDisable(id);
    139     if (ret != 0) {
    140         ALOGE("%s: putNanDisable Error:%d",__func__, ret);
    141         goto cleanup;
    142     }
    143     ret = nanCommand->requestEvent();
    144     if (ret != 0) {
    145         ALOGE("%s: requestEvent Error:%d",__func__, ret);
    146     }
    147 cleanup:
    148     delete nanCommand;
    149     return (wifi_error)ret;
    150 }
    151 
    152 /*  Function to send publish request to the wifi driver.*/
    153 wifi_error nan_publish_request(transaction_id id,
    154                                wifi_interface_handle iface,
    155                                NanPublishRequest* msg)
    156 {
    157     int ret = 0;
    158     NanCommand *nanCommand = NULL;
    159     interface_info *ifaceInfo = getIfaceInfo(iface);
    160     wifi_handle wifiHandle = getWifiHandle(iface);
    161 
    162     nanCommand = new NanCommand(wifiHandle,
    163                                 0,
    164                                 OUI_QCA,
    165                                 QCA_NL80211_VENDOR_SUBCMD_NAN);
    166     if (nanCommand == NULL) {
    167         ALOGE("%s: Error NanCommand NULL", __func__);
    168         return WIFI_ERROR_UNKNOWN;
    169     }
    170 
    171     ret = nanCommand->create();
    172     if (ret < 0)
    173         goto cleanup;
    174 
    175     /* Set the interface Id of the message. */
    176     ret = nanCommand->set_iface_id(ifaceInfo->name);
    177     if (ret < 0)
    178         goto cleanup;
    179 
    180     ret = nanCommand->putNanPublish(id, msg);
    181     if (ret != 0) {
    182         ALOGE("%s: putNanPublish Error:%d",__func__, ret);
    183         goto cleanup;
    184     }
    185     ret = nanCommand->requestEvent();
    186     if (ret != 0) {
    187         ALOGE("%s: requestEvent Error:%d",__func__, ret);
    188     }
    189 cleanup:
    190     delete nanCommand;
    191     return (wifi_error)ret;
    192 }
    193 
    194 /*  Function to send publish cancel to the wifi driver.*/
    195 wifi_error nan_publish_cancel_request(transaction_id id,
    196                                       wifi_interface_handle iface,
    197                                       NanPublishCancelRequest* msg)
    198 {
    199     int ret = 0;
    200     NanCommand *nanCommand = NULL;
    201     interface_info *ifaceInfo = getIfaceInfo(iface);
    202     wifi_handle wifiHandle = getWifiHandle(iface);
    203 
    204     nanCommand = new NanCommand(wifiHandle,
    205                                 0,
    206                                 OUI_QCA,
    207                                 QCA_NL80211_VENDOR_SUBCMD_NAN);
    208     if (nanCommand == NULL) {
    209         ALOGE("%s: Error NanCommand NULL", __func__);
    210         return WIFI_ERROR_UNKNOWN;
    211     }
    212 
    213     ret = nanCommand->create();
    214     if (ret < 0)
    215         goto cleanup;
    216 
    217     /* Set the interface Id of the message. */
    218     ret = nanCommand->set_iface_id(ifaceInfo->name);
    219     if (ret < 0)
    220         goto cleanup;
    221 
    222     ret = nanCommand->putNanPublishCancel(id, msg);
    223     if (ret != 0) {
    224         ALOGE("%s: putNanPublishCancel Error:%d",__func__, ret);
    225         goto cleanup;
    226     }
    227     ret = nanCommand->requestEvent();
    228     if (ret != 0) {
    229         ALOGE("%s: requestEvent Error:%d",__func__, ret);
    230     }
    231 cleanup:
    232     delete nanCommand;
    233     return (wifi_error)ret;
    234 }
    235 
    236 /*  Function to send Subscribe request to the wifi driver.*/
    237 wifi_error nan_subscribe_request(transaction_id id,
    238                                  wifi_interface_handle iface,
    239                                  NanSubscribeRequest* msg)
    240 {
    241     int ret = 0;
    242     NanCommand *nanCommand = NULL;
    243     interface_info *ifaceInfo = getIfaceInfo(iface);
    244     wifi_handle wifiHandle = getWifiHandle(iface);
    245 
    246     nanCommand = new NanCommand(wifiHandle,
    247                                 0,
    248                                 OUI_QCA,
    249                                 QCA_NL80211_VENDOR_SUBCMD_NAN);
    250     if (nanCommand == NULL) {
    251         ALOGE("%s: Error NanCommand NULL", __func__);
    252         return WIFI_ERROR_UNKNOWN;
    253     }
    254 
    255     ret = nanCommand->create();
    256     if (ret < 0)
    257         goto cleanup;
    258 
    259     /* Set the interface Id of the message. */
    260     ret = nanCommand->set_iface_id(ifaceInfo->name);
    261     if (ret < 0)
    262         goto cleanup;
    263 
    264     ret = nanCommand->putNanSubscribe(id, msg);
    265     if (ret != 0) {
    266         ALOGE("%s: putNanSubscribe Error:%d",__func__, ret);
    267         goto cleanup;
    268     }
    269     ret = nanCommand->requestEvent();
    270     if (ret != 0) {
    271         ALOGE("%s: requestEvent Error:%d",__func__, ret);
    272     }
    273 cleanup:
    274     delete nanCommand;
    275     return (wifi_error)ret;
    276 }
    277 
    278 /*  Function to cancel subscribe to the wifi driver.*/
    279 wifi_error nan_subscribe_cancel_request(transaction_id id,
    280                                         wifi_interface_handle iface,
    281                                         NanSubscribeCancelRequest* msg)
    282 {
    283     int ret = 0;
    284     NanCommand *nanCommand = NULL;
    285     interface_info *ifaceInfo = getIfaceInfo(iface);
    286     wifi_handle wifiHandle = getWifiHandle(iface);
    287 
    288     nanCommand = new NanCommand(wifiHandle,
    289                                 0,
    290                                 OUI_QCA,
    291                                 QCA_NL80211_VENDOR_SUBCMD_NAN);
    292     if (nanCommand == NULL) {
    293         ALOGE("%s: Error NanCommand NULL", __func__);
    294         return WIFI_ERROR_UNKNOWN;
    295     }
    296 
    297     ret = nanCommand->create();
    298     if (ret < 0)
    299         goto cleanup;
    300 
    301     /* Set the interface Id of the message. */
    302     ret = nanCommand->set_iface_id(ifaceInfo->name);
    303     if (ret < 0)
    304         goto cleanup;
    305 
    306     ret = nanCommand->putNanSubscribeCancel(id, msg);
    307     if (ret != 0) {
    308         ALOGE("%s: putNanSubscribeCancel Error:%d",__func__, ret);
    309         goto cleanup;
    310     }
    311     ret = nanCommand->requestEvent();
    312     if (ret != 0) {
    313         ALOGE("%s: requestEvent Error:%d",__func__, ret);
    314     }
    315 cleanup:
    316     delete nanCommand;
    317     return (wifi_error)ret;
    318 }
    319 
    320 /*  Function to send NAN follow up request to the wifi driver.*/
    321 wifi_error nan_transmit_followup_request(transaction_id id,
    322                                          wifi_interface_handle iface,
    323                                          NanTransmitFollowupRequest* msg)
    324 {
    325     int ret = 0;
    326     NanCommand *nanCommand = NULL;
    327     interface_info *ifaceInfo = getIfaceInfo(iface);
    328     wifi_handle wifiHandle = getWifiHandle(iface);
    329 
    330     nanCommand = new NanCommand(wifiHandle,
    331                                 0,
    332                                 OUI_QCA,
    333                                 QCA_NL80211_VENDOR_SUBCMD_NAN);
    334     if (nanCommand == NULL) {
    335         ALOGE("%s: Error NanCommand NULL", __func__);
    336         return WIFI_ERROR_UNKNOWN;
    337     }
    338 
    339     ret = nanCommand->create();
    340     if (ret < 0)
    341         goto cleanup;
    342 
    343     /* Set the interface Id of the message. */
    344     ret = nanCommand->set_iface_id(ifaceInfo->name);
    345     if (ret < 0)
    346         goto cleanup;
    347 
    348     ret = nanCommand->putNanTransmitFollowup(id, msg);
    349     if (ret != 0) {
    350         ALOGE("%s: putNanTransmitFollowup Error:%d",__func__, ret);
    351         goto cleanup;
    352     }
    353     ret = nanCommand->requestEvent();
    354     if (ret != 0) {
    355         ALOGE("%s: requestEvent Error:%d",__func__, ret);
    356     }
    357 cleanup:
    358     delete nanCommand;
    359     return (wifi_error)ret;
    360 }
    361 
    362 /*  Function to send NAN statistics request to the wifi driver.*/
    363 wifi_error nan_stats_request(transaction_id id,
    364                              wifi_interface_handle iface,
    365                              NanStatsRequest* msg)
    366 {
    367     int ret = 0;
    368     NanCommand *nanCommand = NULL;
    369     interface_info *ifaceInfo = getIfaceInfo(iface);
    370     wifi_handle wifiHandle = getWifiHandle(iface);
    371 
    372     nanCommand = new NanCommand(wifiHandle,
    373                                 0,
    374                                 OUI_QCA,
    375                                 QCA_NL80211_VENDOR_SUBCMD_NAN);
    376     if (nanCommand == NULL) {
    377         ALOGE("%s: Error NanCommand NULL", __func__);
    378         return WIFI_ERROR_UNKNOWN;
    379     }
    380 
    381     ret = nanCommand->create();
    382     if (ret < 0)
    383         goto cleanup;
    384 
    385     /* Set the interface Id of the message. */
    386     ret = nanCommand->set_iface_id(ifaceInfo->name);
    387     if (ret < 0)
    388         goto cleanup;
    389 
    390     ret = nanCommand->putNanStats(id, msg);
    391     if (ret != 0) {
    392         ALOGE("%s: putNanStats Error:%d",__func__, ret);
    393         goto cleanup;
    394     }
    395     ret = nanCommand->requestEvent();
    396     if (ret != 0) {
    397         ALOGE("%s: requestEvent Error:%d",__func__, ret);
    398     }
    399 cleanup:
    400     delete nanCommand;
    401     return (wifi_error)ret;
    402 }
    403 
    404 /*  Function to send NAN configuration request to the wifi driver.*/
    405 wifi_error nan_config_request(transaction_id id,
    406                               wifi_interface_handle iface,
    407                               NanConfigRequest* msg)
    408 {
    409     int ret = 0;
    410     NanCommand *nanCommand = NULL;
    411     interface_info *ifaceInfo = getIfaceInfo(iface);
    412     wifi_handle wifiHandle = getWifiHandle(iface);
    413 
    414     nanCommand = new NanCommand(wifiHandle,
    415                                 0,
    416                                 OUI_QCA,
    417                                 QCA_NL80211_VENDOR_SUBCMD_NAN);
    418     if (nanCommand == NULL) {
    419         ALOGE("%s: Error NanCommand NULL", __func__);
    420         return WIFI_ERROR_UNKNOWN;
    421     }
    422 
    423     ret = nanCommand->create();
    424     if (ret < 0)
    425         goto cleanup;
    426 
    427     /* Set the interface Id of the message. */
    428     ret = nanCommand->set_iface_id(ifaceInfo->name);
    429     if (ret < 0)
    430         goto cleanup;
    431 
    432     ret = nanCommand->putNanConfig(id, msg);
    433     if (ret != 0) {
    434         ALOGE("%s: putNanConfig Error:%d",__func__, ret);
    435         goto cleanup;
    436     }
    437     ret = nanCommand->requestEvent();
    438     if (ret != 0) {
    439         ALOGE("%s: requestEvent Error:%d",__func__, ret);
    440     }
    441 cleanup:
    442     delete nanCommand;
    443     return (wifi_error)ret;
    444 }
    445 
    446 /*  Function to send NAN request to the wifi driver.*/
    447 wifi_error nan_tca_request(transaction_id id,
    448                            wifi_interface_handle iface,
    449                            NanTCARequest* msg)
    450 {
    451     int ret = 0;
    452     NanCommand *nanCommand = NULL;
    453     interface_info *ifaceInfo = getIfaceInfo(iface);
    454     wifi_handle wifiHandle = getWifiHandle(iface);
    455 
    456     nanCommand = new NanCommand(wifiHandle,
    457                                 0,
    458                                 OUI_QCA,
    459                                 QCA_NL80211_VENDOR_SUBCMD_NAN);
    460     if (nanCommand == NULL) {
    461         ALOGE("%s: Error NanCommand NULL", __func__);
    462         return WIFI_ERROR_UNKNOWN;
    463     }
    464 
    465     ret = nanCommand->create();
    466     if (ret < 0)
    467         goto cleanup;
    468 
    469     /* Set the interface Id of the message. */
    470     ret = nanCommand->set_iface_id(ifaceInfo->name);
    471     if (ret < 0)
    472         goto cleanup;
    473 
    474     ret = nanCommand->putNanTCA(id, msg);
    475     if (ret != 0) {
    476         ALOGE("%s: putNanTCA Error:%d",__func__, ret);
    477         goto cleanup;
    478     }
    479     ret = nanCommand->requestEvent();
    480     if (ret != 0) {
    481         ALOGE("%s: requestEvent Error:%d",__func__, ret);
    482     }
    483 cleanup:
    484     delete nanCommand;
    485     return (wifi_error)ret;
    486 }
    487 
    488 /*  Function to send NAN Beacon sdf payload to the wifi driver.
    489     This instructs the Discovery Engine to begin publishing the
    490     received payload in any Beacon or Service Discovery Frame
    491     transmitted*/
    492 wifi_error nan_beacon_sdf_payload_request(transaction_id id,
    493                                          wifi_interface_handle iface,
    494                                          NanBeaconSdfPayloadRequest* msg)
    495 {
    496     int ret = WIFI_ERROR_NOT_SUPPORTED;
    497     NanCommand *nanCommand = NULL;
    498     interface_info *ifaceInfo = getIfaceInfo(iface);
    499     wifi_handle wifiHandle = getWifiHandle(iface);
    500 
    501     nanCommand = new NanCommand(wifiHandle,
    502                                 0,
    503                                 OUI_QCA,
    504                                 QCA_NL80211_VENDOR_SUBCMD_NAN);
    505     if (nanCommand == NULL) {
    506         ALOGE("%s: Error NanCommand NULL", __func__);
    507         return WIFI_ERROR_UNKNOWN;
    508     }
    509 
    510     ret = nanCommand->create();
    511     if (ret < 0)
    512         goto cleanup;
    513 
    514     /* Set the interface Id of the message. */
    515     ret = nanCommand->set_iface_id(ifaceInfo->name);
    516     if (ret < 0)
    517         goto cleanup;
    518 
    519     ret = nanCommand->putNanBeaconSdfPayload(id, msg);
    520     if (ret != 0) {
    521         ALOGE("%s: putNanBeaconSdfPayload Error:%d",__func__, ret);
    522         goto cleanup;
    523     }
    524     ret = nanCommand->requestEvent();
    525     if (ret != 0) {
    526         ALOGE("%s: requestEvent Error:%d",__func__, ret);
    527     }
    528 
    529 cleanup:
    530     delete nanCommand;
    531     return (wifi_error)ret;
    532 }
    533 
    534 wifi_error nan_get_sta_parameter(transaction_id id,
    535                                  wifi_interface_handle iface,
    536                                  NanStaParameter* msg)
    537 {
    538     int ret = WIFI_ERROR_NOT_SUPPORTED;
    539     NanCommand *nanCommand = NULL;
    540     interface_info *ifaceInfo = getIfaceInfo(iface);
    541     wifi_handle wifiHandle = getWifiHandle(iface);
    542 
    543     nanCommand = NanCommand::instance(wifiHandle);
    544     if (nanCommand == NULL) {
    545         ALOGE("%s: Error NanCommand NULL", __func__);
    546         return WIFI_ERROR_UNKNOWN;
    547     }
    548 
    549     ret = nanCommand->getNanStaParameter(iface, msg);
    550     if (ret != 0) {
    551         ALOGE("%s: getNanStaParameter Error:%d",__func__, ret);
    552         goto cleanup;
    553     }
    554 
    555 cleanup:
    556     return (wifi_error)ret;
    557 }
    558 
    559 /*  Function to get NAN capabilities */
    560 wifi_error nan_get_capabilities(transaction_id id,
    561                                 wifi_interface_handle iface)
    562 {
    563     int ret = 0;
    564     NanCommand *nanCommand = NULL;
    565     interface_info *ifaceInfo = getIfaceInfo(iface);
    566     wifi_handle wifiHandle = getWifiHandle(iface);
    567 
    568     nanCommand = new NanCommand(wifiHandle,
    569                                 0,
    570                                 OUI_QCA,
    571                                 QCA_NL80211_VENDOR_SUBCMD_NAN);
    572     if (nanCommand == NULL) {
    573         ALOGE("%s: Error NanCommand NULL", __func__);
    574         return WIFI_ERROR_UNKNOWN;
    575     }
    576 
    577     ret = nanCommand->create();
    578     if (ret < 0)
    579         goto cleanup;
    580 
    581     /* Set the interface Id of the message. */
    582     ret = nanCommand->set_iface_id(ifaceInfo->name);
    583     if (ret < 0)
    584         goto cleanup;
    585 
    586     ret = nanCommand->putNanCapabilities(id);
    587     if (ret != 0) {
    588         ALOGE("%s: putNanCapabilities Error:%d",__func__, ret);
    589         goto cleanup;
    590     }
    591     ret = nanCommand->requestEvent();
    592     if (ret != 0) {
    593         ALOGE("%s: requestEvent Error:%d",__func__, ret);
    594     }
    595 cleanup:
    596     delete nanCommand;
    597     return (wifi_error)ret;
    598 }
    599 
    600 // Implementation related to nan class common functions
    601 // Constructor
    602 //Making the constructor private since this class is a singleton
    603 NanCommand::NanCommand(wifi_handle handle, int id, u32 vendor_id, u32 subcmd)
    604         : WifiVendorCommand(handle, id, vendor_id, subcmd)
    605 {
    606     memset(&mHandler, 0,sizeof(mHandler));
    607     mNanVendorEvent = NULL;
    608     mNanDataLen = 0;
    609     mStaParam = NULL;
    610 }
    611 
    612 NanCommand* NanCommand::instance(wifi_handle handle)
    613 {
    614     if (handle == NULL) {
    615         ALOGE("Handle is invalid");
    616         return NULL;
    617     }
    618     if (mNanCommandInstance == NULL) {
    619         mNanCommandInstance = new NanCommand(handle, 0,
    620                                              OUI_QCA,
    621                                              QCA_NL80211_VENDOR_SUBCMD_NAN);
    622         ALOGV("NanCommand %p created", mNanCommandInstance);
    623         return mNanCommandInstance;
    624     }
    625     else
    626     {
    627         if (handle != getWifiHandle(mNanCommandInstance->mInfo)) {
    628             /* upper layer must have cleaned up the handle and reinitialized,
    629                so we need to update the same */
    630             ALOGI("Handle different, update the handle");
    631             mNanCommandInstance->mInfo = (hal_info *)handle;
    632         }
    633     }
    634     ALOGV("NanCommand %p created already", mNanCommandInstance);
    635     return mNanCommandInstance;
    636 }
    637 
    638 void NanCommand::cleanup()
    639 {
    640     //free the VendorData
    641     if (mVendorData) {
    642         free(mVendorData);
    643     }
    644     mVendorData = NULL;
    645     //cleanup the mMsg
    646     mMsg.destroy();
    647 }
    648 
    649 NanCommand::~NanCommand()
    650 {
    651     ALOGV("NanCommand %p destroyed", this);
    652 }
    653 
    654 int NanCommand::handleResponse(WifiEvent &reply){
    655     return NL_SKIP;
    656 }
    657 
    658 int NanCommand::setCallbackHandler(NanCallbackHandler nHandler)
    659 {
    660     int res = 0;
    661     mHandler = nHandler;
    662     res = registerVendorHandler(mVendor_id, mSubcmd);
    663     if (res != 0) {
    664         //error case should not happen print log
    665         ALOGE("%s: Unable to register Vendor Handler Vendor Id=0x%x subcmd=%u",
    666               __func__, mVendor_id, mSubcmd);
    667     }
    668     return res;
    669 }
    670 
    671 /* This function implements creation of Vendor command */
    672 int NanCommand::create() {
    673     int ret = mMsg.create(NL80211_CMD_VENDOR, 0, 0);
    674     if (ret < 0) {
    675         goto out;
    676     }
    677 
    678     /* Insert the oui in the msg */
    679     ret = mMsg.put_u32(NL80211_ATTR_VENDOR_ID, mVendor_id);
    680     if (ret < 0)
    681         goto out;
    682     /* Insert the subcmd in the msg */
    683     ret = mMsg.put_u32(NL80211_ATTR_VENDOR_SUBCMD, mSubcmd);
    684     if (ret < 0)
    685         goto out;
    686 out:
    687     if (ret < 0) {
    688         mMsg.destroy();
    689     }
    690     return ret;
    691 }
    692 
    693 // This function will be the main handler for incoming event
    694 // QCA_NL80211_VENDOR_SUBCMD_NAN
    695 //Call the appropriate callback handler after parsing the vendor data.
    696 int NanCommand::handleEvent(WifiEvent &event)
    697 {
    698     WifiVendorCommand::handleEvent(event);
    699     ALOGV("%s: Subcmd=%u Vendor data len received:%d",
    700           __FUNCTION__, mSubcmd, mDataLen);
    701     hexdump(mVendorData, mDataLen);
    702 
    703     if (mSubcmd == QCA_NL80211_VENDOR_SUBCMD_NAN){
    704         // Parse the vendordata and get the NAN attribute
    705         struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_MAX + 1];
    706         nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_MAX,
    707                   (struct nlattr *)mVendorData,
    708                   mDataLen, NULL);
    709         // Populating the mNanVendorEvent and mNanDataLen to point to NAN data.
    710         mNanVendorEvent = (char *)nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_NAN]);
    711         mNanDataLen = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_NAN]);
    712 
    713         if (isNanResponse()) {
    714             //handleNanResponse will parse the data and call
    715             //the response callback handler with the populated
    716             //NanResponseMsg
    717             handleNanResponse();
    718         }
    719         else {
    720             //handleNanIndication will parse the data and call
    721             //the corresponding Indication callback handler
    722             //with the corresponding populated Indication event
    723             handleNanIndication();
    724         }
    725     }
    726     else {
    727         //error case should not happen print log
    728         ALOGE("%s: Wrong NAN subcmd received %d", __func__, mSubcmd);
    729     }
    730     return NL_SKIP;
    731 }
    732 
    733 /*Helper function to Write and Read TLV called in indication as well as request */
    734 u16 NANTLV_WriteTlv(pNanTlv pInTlv, u8 *pOutTlv)
    735 {
    736     u16 writeLen = 0;
    737     u16 i;
    738 
    739     if (!pInTlv)
    740     {
    741         ALOGE("NULL pInTlv");
    742         return writeLen;
    743     }
    744 
    745     if (!pOutTlv)
    746     {
    747         ALOGE("NULL pOutTlv");
    748         return writeLen;
    749     }
    750 
    751     *pOutTlv++ = pInTlv->type & 0xFF;
    752     *pOutTlv++ = (pInTlv->type & 0xFF00) >> 8;
    753     writeLen += 2;
    754 
    755     ALOGV("WRITE TLV type %u, writeLen %u", pInTlv->type, writeLen);
    756 
    757     *pOutTlv++ = pInTlv->length & 0xFF;
    758     *pOutTlv++ = (pInTlv->length & 0xFF00) >> 8;
    759     writeLen += 2;
    760 
    761     ALOGV("WRITE TLV length %u, writeLen %u", pInTlv->length, writeLen);
    762 
    763     for (i=0; i < pInTlv->length; ++i)
    764     {
    765         *pOutTlv++ = pInTlv->value[i];
    766     }
    767 
    768     writeLen += pInTlv->length;
    769     ALOGV("WRITE TLV value, writeLen %u", writeLen);
    770     return writeLen;
    771 }
    772 
    773 u16 NANTLV_ReadTlv(u8 *pInTlv, pNanTlv pOutTlv)
    774 {
    775     u16 readLen = 0;
    776 
    777     if (!pInTlv)
    778     {
    779         ALOGE("NULL pInTlv");
    780         return readLen;
    781     }
    782 
    783     if (!pOutTlv)
    784     {
    785         ALOGE("NULL pOutTlv");
    786         return readLen;
    787     }
    788 
    789     pOutTlv->type = *pInTlv++;
    790     pOutTlv->type |= *pInTlv++ << 8;
    791     readLen += 2;
    792 
    793     ALOGV("READ TLV type %u, readLen %u", pOutTlv->type, readLen);
    794 
    795     pOutTlv->length = *pInTlv++;
    796     pOutTlv->length |= *pInTlv++ << 8;
    797     readLen += 2;
    798 
    799     ALOGV("READ TLV length %u, readLen %u", pOutTlv->length, readLen);
    800 
    801     if (pOutTlv->length)
    802     {
    803         pOutTlv->value = pInTlv;
    804         readLen += pOutTlv->length;
    805     }
    806     else
    807     {
    808         pOutTlv->value = NULL;
    809     }
    810 
    811     ALOGV("READ TLV  readLen %u", readLen);
    812     return readLen;
    813 }
    814 
    815 u8* addTlv(u16 type, u16 length, const u8* value, u8* pOutTlv)
    816 {
    817    NanTlv nanTlv;
    818    u16 len;
    819 
    820    nanTlv.type = type;
    821    nanTlv.length = length;
    822    nanTlv.value = (u8*)value;
    823 
    824    len = NANTLV_WriteTlv(&nanTlv, pOutTlv);
    825    return (pOutTlv + len);
    826 }
    827