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