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 <errno.h>
     25 #include "nancommand.h"
     26 #include "vendor_definitions.h"
     27 
     28 #ifdef __GNUC__
     29 #define PRINTF_FORMAT(a,b) __attribute__ ((format (printf, (a), (b))))
     30 #define STRUCT_PACKED __attribute__ ((packed))
     31 #else
     32 #define PRINTF_FORMAT(a,b)
     33 #define STRUCT_PACKED
     34 #endif
     35 
     36 #define OUT_OF_BAND_SERVICE_INSTANCE_ID 0
     37 
     38 //Singleton Static Instance
     39 NanCommand* NanCommand::mNanCommandInstance  = NULL;
     40 
     41 //Implementation of the functions exposed in nan.h
     42 wifi_error nan_register_handler(wifi_interface_handle iface,
     43                                 NanCallbackHandler handlers)
     44 {
     45     // Obtain the singleton instance
     46     wifi_error ret;
     47     NanCommand *nanCommand = NULL;
     48     wifi_handle wifiHandle = getWifiHandle(iface);
     49 
     50     nanCommand = NanCommand::instance(wifiHandle);
     51     if (nanCommand == NULL) {
     52         ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
     53         return WIFI_ERROR_UNKNOWN;
     54     }
     55 
     56     ret = nanCommand->setCallbackHandler(handlers);
     57     return ret;
     58 }
     59 
     60 wifi_error nan_get_version(wifi_handle handle,
     61                            NanVersion* version)
     62 {
     63     *version = (NAN_MAJOR_VERSION <<16 | NAN_MINOR_VERSION << 8 | NAN_MICRO_VERSION);
     64     return WIFI_SUCCESS;
     65 }
     66 
     67 /*  Function to send enable request to the wifi driver.*/
     68 wifi_error nan_enable_request(transaction_id id,
     69                               wifi_interface_handle iface,
     70                               NanEnableRequest* msg)
     71 {
     72     wifi_error ret;
     73     NanCommand *nanCommand = NULL;
     74     interface_info *ifaceInfo = getIfaceInfo(iface);
     75     wifi_handle wifiHandle = getWifiHandle(iface);
     76 
     77     nanCommand = new NanCommand(wifiHandle,
     78                                 0,
     79                                 OUI_QCA,
     80                                 QCA_NL80211_VENDOR_SUBCMD_NAN);
     81     if (nanCommand == NULL) {
     82         ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
     83         return WIFI_ERROR_UNKNOWN;
     84     }
     85 
     86     ret = nanCommand->create();
     87     if (ret != WIFI_SUCCESS)
     88         goto cleanup;
     89 
     90     /* Set the interface Id of the message. */
     91     ret = nanCommand->set_iface_id(ifaceInfo->name);
     92     if (ret != WIFI_SUCCESS)
     93         goto cleanup;
     94 
     95     ret = nanCommand->putNanEnable(id, msg);
     96     if (ret != WIFI_SUCCESS) {
     97         ALOGE("%s: putNanEnable Error:%d", __FUNCTION__, ret);
     98         goto cleanup;
     99     }
    100 
    101     ret = nanCommand->requestEvent();
    102     if (ret != WIFI_SUCCESS)
    103         ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);
    104 
    105 cleanup:
    106     delete nanCommand;
    107     return ret;
    108 }
    109 
    110 /*  Function to send disable request to the wifi driver.*/
    111 wifi_error nan_disable_request(transaction_id id,
    112                                wifi_interface_handle iface)
    113 {
    114     wifi_error ret;
    115     NanCommand *nanCommand = NULL;
    116     interface_info *ifaceInfo = getIfaceInfo(iface);
    117     wifi_handle wifiHandle = getWifiHandle(iface);
    118 
    119     nanCommand = new NanCommand(wifiHandle,
    120                                 0,
    121                                 OUI_QCA,
    122                                 QCA_NL80211_VENDOR_SUBCMD_NAN);
    123     if (nanCommand == NULL) {
    124         ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
    125         return WIFI_ERROR_UNKNOWN;
    126     }
    127 
    128     ret = nanCommand->create();
    129     if (ret != WIFI_SUCCESS)
    130         goto cleanup;
    131 
    132     /* Set the interface Id of the message. */
    133     ret = nanCommand->set_iface_id(ifaceInfo->name);
    134     if (ret != WIFI_SUCCESS)
    135         goto cleanup;
    136 
    137     ret = nanCommand->putNanDisable(id);
    138     if (ret != WIFI_SUCCESS) {
    139         ALOGE("%s: putNanDisable Error:%d",__FUNCTION__, ret);
    140         goto cleanup;
    141     }
    142 
    143     ret = nanCommand->requestEvent();
    144     if (ret != WIFI_SUCCESS)
    145         ALOGE("%s: requestEvent Error:%d",__FUNCTION__, ret);
    146 
    147 cleanup:
    148     delete nanCommand;
    149     return 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     wifi_error ret;
    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", __FUNCTION__);
    168         return WIFI_ERROR_UNKNOWN;
    169     }
    170 
    171     ret = nanCommand->create();
    172     if (ret != WIFI_SUCCESS)
    173         goto cleanup;
    174 
    175     /* Set the interface Id of the message. */
    176     ret = nanCommand->set_iface_id(ifaceInfo->name);
    177     if (ret != WIFI_SUCCESS)
    178         goto cleanup;
    179 
    180     ret = nanCommand->putNanPublish(id, msg);
    181     if (ret != WIFI_SUCCESS) {
    182         ALOGE("%s: putNanPublish Error:%d",__FUNCTION__, ret);
    183         goto cleanup;
    184     }
    185 
    186     ret = nanCommand->requestEvent();
    187     if (ret != WIFI_SUCCESS)
    188         ALOGE("%s: requestEvent Error:%d",__FUNCTION__, ret);
    189 
    190 cleanup:
    191     delete nanCommand;
    192     return ret;
    193 }
    194 
    195 /*  Function to send publish cancel to the wifi driver.*/
    196 wifi_error nan_publish_cancel_request(transaction_id id,
    197                                       wifi_interface_handle iface,
    198                                       NanPublishCancelRequest* msg)
    199 {
    200     wifi_error ret;
    201     NanCommand *nanCommand = NULL;
    202     interface_info *ifaceInfo = getIfaceInfo(iface);
    203     wifi_handle wifiHandle = getWifiHandle(iface);
    204 
    205     nanCommand = new NanCommand(wifiHandle,
    206                                 0,
    207                                 OUI_QCA,
    208                                 QCA_NL80211_VENDOR_SUBCMD_NAN);
    209     if (nanCommand == NULL) {
    210         ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
    211         return WIFI_ERROR_UNKNOWN;
    212     }
    213 
    214     ret = nanCommand->create();
    215     if (ret != WIFI_SUCCESS)
    216         goto cleanup;
    217 
    218     /* Set the interface Id of the message. */
    219     ret = nanCommand->set_iface_id(ifaceInfo->name);
    220     if (ret != WIFI_SUCCESS)
    221         goto cleanup;
    222 
    223     ret = nanCommand->putNanPublishCancel(id, msg);
    224     if (ret != WIFI_SUCCESS) {
    225         ALOGE("%s: putNanPublishCancel Error:%d", __FUNCTION__, ret);
    226         goto cleanup;
    227     }
    228 
    229     ret = nanCommand->requestEvent();
    230     if (ret != WIFI_SUCCESS)
    231         ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);
    232 
    233 cleanup:
    234     delete nanCommand;
    235     return ret;
    236 }
    237 
    238 /*  Function to send Subscribe request to the wifi driver.*/
    239 wifi_error nan_subscribe_request(transaction_id id,
    240                                  wifi_interface_handle iface,
    241                                  NanSubscribeRequest* msg)
    242 {
    243     wifi_error ret;
    244     NanCommand *nanCommand = NULL;
    245     interface_info *ifaceInfo = getIfaceInfo(iface);
    246     wifi_handle wifiHandle = getWifiHandle(iface);
    247 
    248     nanCommand = new NanCommand(wifiHandle,
    249                                 0,
    250                                 OUI_QCA,
    251                                 QCA_NL80211_VENDOR_SUBCMD_NAN);
    252     if (nanCommand == NULL) {
    253         ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
    254         return WIFI_ERROR_UNKNOWN;
    255     }
    256 
    257     ret = nanCommand->create();
    258     if (ret != WIFI_SUCCESS)
    259         goto cleanup;
    260 
    261     /* Set the interface Id of the message. */
    262     ret = nanCommand->set_iface_id(ifaceInfo->name);
    263     if (ret != WIFI_SUCCESS)
    264         goto cleanup;
    265 
    266     ret = nanCommand->putNanSubscribe(id, msg);
    267     if (ret != WIFI_SUCCESS) {
    268         ALOGE("%s: putNanSubscribe Error:%d", __FUNCTION__, ret);
    269         goto cleanup;
    270     }
    271 
    272     ret = nanCommand->requestEvent();
    273     if (ret != WIFI_SUCCESS)
    274         ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);
    275 
    276 cleanup:
    277     delete nanCommand;
    278     return ret;
    279 }
    280 
    281 /*  Function to cancel subscribe to the wifi driver.*/
    282 wifi_error nan_subscribe_cancel_request(transaction_id id,
    283                                         wifi_interface_handle iface,
    284                                         NanSubscribeCancelRequest* msg)
    285 {
    286     wifi_error ret;
    287     NanCommand *nanCommand = NULL;
    288     interface_info *ifaceInfo = getIfaceInfo(iface);
    289     wifi_handle wifiHandle = getWifiHandle(iface);
    290 
    291     nanCommand = new NanCommand(wifiHandle,
    292                                 0,
    293                                 OUI_QCA,
    294                                 QCA_NL80211_VENDOR_SUBCMD_NAN);
    295     if (nanCommand == NULL) {
    296         ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
    297         return WIFI_ERROR_UNKNOWN;
    298     }
    299 
    300     ret = nanCommand->create();
    301     if (ret != WIFI_SUCCESS)
    302         goto cleanup;
    303 
    304     /* Set the interface Id of the message. */
    305     ret = nanCommand->set_iface_id(ifaceInfo->name);
    306     if (ret != WIFI_SUCCESS)
    307         goto cleanup;
    308 
    309     ret = nanCommand->putNanSubscribeCancel(id, msg);
    310     if (ret != WIFI_SUCCESS) {
    311         ALOGE("%s: putNanSubscribeCancel Error:%d", __FUNCTION__, ret);
    312         goto cleanup;
    313     }
    314 
    315     ret = nanCommand->requestEvent();
    316     if (ret != WIFI_SUCCESS)
    317         ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);
    318 
    319 cleanup:
    320     delete nanCommand;
    321     return ret;
    322 }
    323 
    324 /*  Function to send NAN follow up request to the wifi driver.*/
    325 wifi_error nan_transmit_followup_request(transaction_id id,
    326                                          wifi_interface_handle iface,
    327                                          NanTransmitFollowupRequest* msg)
    328 {
    329     wifi_error ret;
    330     NanCommand *nanCommand = NULL;
    331     interface_info *ifaceInfo = getIfaceInfo(iface);
    332     wifi_handle wifiHandle = getWifiHandle(iface);
    333 
    334     nanCommand = new NanCommand(wifiHandle,
    335                                 0,
    336                                 OUI_QCA,
    337                                 QCA_NL80211_VENDOR_SUBCMD_NAN);
    338     if (nanCommand == NULL) {
    339         ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
    340         return WIFI_ERROR_UNKNOWN;
    341     }
    342 
    343     ret = nanCommand->create();
    344     if (ret != WIFI_SUCCESS)
    345         goto cleanup;
    346 
    347     /* Set the interface Id of the message. */
    348     ret = nanCommand->set_iface_id(ifaceInfo->name);
    349     if (ret != WIFI_SUCCESS)
    350         goto cleanup;
    351 
    352     ret = nanCommand->putNanTransmitFollowup(id, msg);
    353     if (ret != WIFI_SUCCESS) {
    354         ALOGE("%s: putNanTransmitFollowup Error:%d", __FUNCTION__, ret);
    355         goto cleanup;
    356     }
    357 
    358     ret = nanCommand->requestEvent();
    359     if (ret != WIFI_SUCCESS)
    360         ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);
    361 
    362 cleanup:
    363     delete nanCommand;
    364     return ret;
    365 }
    366 
    367 /*  Function to send NAN statistics request to the wifi driver.*/
    368 wifi_error nan_stats_request(transaction_id id,
    369                              wifi_interface_handle iface,
    370                              NanStatsRequest* msg)
    371 {
    372     wifi_error ret;
    373     NanCommand *nanCommand = NULL;
    374     interface_info *ifaceInfo = getIfaceInfo(iface);
    375     wifi_handle wifiHandle = getWifiHandle(iface);
    376 
    377     nanCommand = new NanCommand(wifiHandle,
    378                                 0,
    379                                 OUI_QCA,
    380                                 QCA_NL80211_VENDOR_SUBCMD_NAN);
    381     if (nanCommand == NULL) {
    382         ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
    383         return WIFI_ERROR_UNKNOWN;
    384     }
    385 
    386     ret = nanCommand->create();
    387     if (ret != WIFI_SUCCESS)
    388         goto cleanup;
    389 
    390     /* Set the interface Id of the message. */
    391     ret = nanCommand->set_iface_id(ifaceInfo->name);
    392     if (ret != WIFI_SUCCESS)
    393         goto cleanup;
    394 
    395     ret = nanCommand->putNanStats(id, msg);
    396     if (ret != WIFI_SUCCESS) {
    397         ALOGE("%s: putNanStats Error:%d", __FUNCTION__, ret);
    398         goto cleanup;
    399     }
    400 
    401     ret = nanCommand->requestEvent();
    402     if (ret != WIFI_SUCCESS)
    403         ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);
    404 
    405 cleanup:
    406     delete nanCommand;
    407     return ret;
    408 }
    409 
    410 /*  Function to send NAN configuration request to the wifi driver.*/
    411 wifi_error nan_config_request(transaction_id id,
    412                               wifi_interface_handle iface,
    413                               NanConfigRequest* msg)
    414 {
    415     wifi_error ret;
    416     NanCommand *nanCommand = NULL;
    417     interface_info *ifaceInfo = getIfaceInfo(iface);
    418     wifi_handle wifiHandle = getWifiHandle(iface);
    419 
    420     nanCommand = new NanCommand(wifiHandle,
    421                                 0,
    422                                 OUI_QCA,
    423                                 QCA_NL80211_VENDOR_SUBCMD_NAN);
    424     if (nanCommand == NULL) {
    425         ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
    426         return WIFI_ERROR_UNKNOWN;
    427     }
    428 
    429     ret = nanCommand->create();
    430     if (ret != WIFI_SUCCESS)
    431         goto cleanup;
    432 
    433     /* Set the interface Id of the message. */
    434     ret = nanCommand->set_iface_id(ifaceInfo->name);
    435     if (ret != WIFI_SUCCESS)
    436         goto cleanup;
    437 
    438     ret = nanCommand->putNanConfig(id, msg);
    439     if (ret != WIFI_SUCCESS) {
    440         ALOGE("%s: putNanConfig Error:%d",__FUNCTION__, ret);
    441         goto cleanup;
    442     }
    443 
    444     ret = nanCommand->requestEvent();
    445     if (ret != WIFI_SUCCESS)
    446         ALOGE("%s: requestEvent Error:%d",__FUNCTION__, ret);
    447 
    448 cleanup:
    449     delete nanCommand;
    450     return ret;
    451 }
    452 
    453 /*  Function to send NAN request to the wifi driver.*/
    454 wifi_error nan_tca_request(transaction_id id,
    455                            wifi_interface_handle iface,
    456                            NanTCARequest* msg)
    457 {
    458     wifi_error ret;
    459     NanCommand *nanCommand = NULL;
    460     interface_info *ifaceInfo = getIfaceInfo(iface);
    461     wifi_handle wifiHandle = getWifiHandle(iface);
    462 
    463     nanCommand = new NanCommand(wifiHandle,
    464                                 0,
    465                                 OUI_QCA,
    466                                 QCA_NL80211_VENDOR_SUBCMD_NAN);
    467     if (nanCommand == NULL) {
    468         ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
    469         return WIFI_ERROR_UNKNOWN;
    470     }
    471 
    472     ret = nanCommand->create();
    473     if (ret != WIFI_SUCCESS)
    474         goto cleanup;
    475 
    476     /* Set the interface Id of the message. */
    477     ret = nanCommand->set_iface_id(ifaceInfo->name);
    478     if (ret != WIFI_SUCCESS)
    479         goto cleanup;
    480 
    481     ret = nanCommand->putNanTCA(id, msg);
    482     if (ret != WIFI_SUCCESS) {
    483         ALOGE("%s: putNanTCA Error:%d",__FUNCTION__, ret);
    484         goto cleanup;
    485     }
    486 
    487     ret = nanCommand->requestEvent();
    488     if (ret != WIFI_SUCCESS)
    489         ALOGE("%s: requestEvent Error:%d",__FUNCTION__, ret);
    490 
    491 cleanup:
    492     delete nanCommand;
    493     return ret;
    494 }
    495 
    496 /*  Function to send NAN Beacon sdf payload to the wifi driver.
    497     This instructs the Discovery Engine to begin publishing the
    498     received payload in any Beacon or Service Discovery Frame
    499     transmitted*/
    500 wifi_error nan_beacon_sdf_payload_request(transaction_id id,
    501                                          wifi_interface_handle iface,
    502                                          NanBeaconSdfPayloadRequest* msg)
    503 {
    504     wifi_error ret;
    505     NanCommand *nanCommand = NULL;
    506     interface_info *ifaceInfo = getIfaceInfo(iface);
    507     wifi_handle wifiHandle = getWifiHandle(iface);
    508 
    509     nanCommand = new NanCommand(wifiHandle,
    510                                 0,
    511                                 OUI_QCA,
    512                                 QCA_NL80211_VENDOR_SUBCMD_NAN);
    513     if (nanCommand == NULL) {
    514         ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
    515         return WIFI_ERROR_UNKNOWN;
    516     }
    517 
    518     ret = nanCommand->create();
    519     if (ret != WIFI_SUCCESS)
    520         goto cleanup;
    521 
    522     /* Set the interface Id of the message. */
    523     ret = nanCommand->set_iface_id(ifaceInfo->name);
    524     if (ret != WIFI_SUCCESS)
    525         goto cleanup;
    526 
    527     ret = nanCommand->putNanBeaconSdfPayload(id, msg);
    528     if (ret != WIFI_SUCCESS) {
    529         ALOGE("%s: putNanBeaconSdfPayload Error:%d", __FUNCTION__, ret);
    530         goto cleanup;
    531     }
    532 
    533     ret = nanCommand->requestEvent();
    534     if (ret != WIFI_SUCCESS)
    535         ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);
    536 
    537 cleanup:
    538     delete nanCommand;
    539     return ret;
    540 }
    541 
    542 wifi_error nan_get_sta_parameter(transaction_id id,
    543                                  wifi_interface_handle iface,
    544                                  NanStaParameter* msg)
    545 {
    546     wifi_error ret;
    547     NanCommand *nanCommand = NULL;
    548     wifi_handle wifiHandle = getWifiHandle(iface);
    549 
    550     nanCommand = NanCommand::instance(wifiHandle);
    551     if (nanCommand == NULL) {
    552         ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
    553         return WIFI_ERROR_UNKNOWN;
    554     }
    555 
    556     ret = nanCommand->getNanStaParameter(iface, msg);
    557     if (ret != WIFI_SUCCESS) {
    558         ALOGE("%s: getNanStaParameter Error:%d", __FUNCTION__, ret);
    559         goto cleanup;
    560     }
    561 
    562 cleanup:
    563     return ret;
    564 }
    565 
    566 /*  Function to get NAN capabilities */
    567 wifi_error nan_get_capabilities(transaction_id id,
    568                                 wifi_interface_handle iface)
    569 {
    570     wifi_error ret;
    571     NanCommand *nanCommand = NULL;
    572     interface_info *ifaceInfo = getIfaceInfo(iface);
    573     wifi_handle wifiHandle = getWifiHandle(iface);
    574 
    575     nanCommand = new NanCommand(wifiHandle,
    576                                 0,
    577                                 OUI_QCA,
    578                                 QCA_NL80211_VENDOR_SUBCMD_NAN);
    579     if (nanCommand == NULL) {
    580         ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
    581         return WIFI_ERROR_UNKNOWN;
    582     }
    583 
    584     ret = nanCommand->create();
    585     if (ret != WIFI_SUCCESS)
    586         goto cleanup;
    587 
    588     /* Set the interface Id of the message. */
    589     ret = nanCommand->set_iface_id(ifaceInfo->name);
    590     if (ret != WIFI_SUCCESS)
    591         goto cleanup;
    592 
    593     ret = nanCommand->putNanCapabilities(id);
    594     if (ret != WIFI_SUCCESS) {
    595         ALOGE("%s: putNanCapabilities Error:%d",__FUNCTION__, ret);
    596         goto cleanup;
    597     }
    598 
    599     ret = nanCommand->requestEvent();
    600     if (ret != WIFI_SUCCESS)
    601         ALOGE("%s: requestEvent Error:%d",__FUNCTION__, ret);
    602 
    603 cleanup:
    604     delete nanCommand;
    605     return ret;
    606 }
    607 
    608 /*  Function to get NAN capabilities */
    609 wifi_error nan_debug_command_config(transaction_id id,
    610                                    wifi_interface_handle iface,
    611                                    NanDebugParams debug,
    612                                    int debug_msg_length)
    613 {
    614     wifi_error ret;
    615     NanCommand *nanCommand = NULL;
    616     interface_info *ifaceInfo = getIfaceInfo(iface);
    617     wifi_handle wifiHandle = getWifiHandle(iface);
    618 
    619     if (debug_msg_length <= 0) {
    620         ALOGE("%s: Invalid debug message length = %d", __FUNCTION__,
    621                                                        debug_msg_length);
    622         return WIFI_ERROR_UNKNOWN;
    623     }
    624 
    625     nanCommand = new NanCommand(wifiHandle,
    626                                 0,
    627                                 OUI_QCA,
    628                                 QCA_NL80211_VENDOR_SUBCMD_NAN);
    629     if (nanCommand == NULL) {
    630         ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
    631         return WIFI_ERROR_UNKNOWN;
    632     }
    633 
    634     ret = nanCommand->create();
    635     if (ret != WIFI_SUCCESS)
    636         goto cleanup;
    637 
    638     /* Set the interface Id of the message. */
    639     ret = nanCommand->set_iface_id(ifaceInfo->name);
    640     if (ret != WIFI_SUCCESS)
    641         goto cleanup;
    642 
    643     ret = nanCommand->putNanDebugCommand(debug, debug_msg_length);
    644     if (ret != WIFI_SUCCESS) {
    645         ALOGE("%s: putNanDebugCommand Error:%d",__FUNCTION__, ret);
    646         goto cleanup;
    647     }
    648 
    649     ret = nanCommand->requestEvent();
    650     if (ret != WIFI_SUCCESS)
    651         ALOGE("%s: requestEvent Error:%d",__FUNCTION__, ret);
    652 
    653 cleanup:
    654     delete nanCommand;
    655     return ret;
    656 }
    657 
    658 wifi_error nan_initialize_vendor_cmd(wifi_interface_handle iface,
    659                                      NanCommand **nanCommand)
    660 {
    661     wifi_error ret;
    662     interface_info *ifaceInfo = getIfaceInfo(iface);
    663     wifi_handle wifiHandle = getWifiHandle(iface);
    664 
    665     if (nanCommand == NULL) {
    666         ALOGE("%s: Error nanCommand NULL", __FUNCTION__);
    667         return WIFI_ERROR_INVALID_ARGS;
    668     }
    669 
    670     *nanCommand = new NanCommand(wifiHandle,
    671                                  0,
    672                                  OUI_QCA,
    673                                  QCA_NL80211_VENDOR_SUBCMD_NDP);
    674     if (*nanCommand == NULL) {
    675         ALOGE("%s: Object creation failed", __FUNCTION__);
    676         return WIFI_ERROR_OUT_OF_MEMORY;
    677     }
    678 
    679     /* Create the message */
    680     ret = (*nanCommand)->create();
    681     if (ret != WIFI_SUCCESS)
    682         goto cleanup;
    683 
    684     ret = (*nanCommand)->set_iface_id(ifaceInfo->name);
    685     if (ret != WIFI_SUCCESS)
    686         goto cleanup;
    687 
    688     return WIFI_SUCCESS;
    689 
    690 cleanup:
    691     delete *nanCommand;
    692     return ret;
    693 }
    694 
    695 wifi_error nan_data_interface_create(transaction_id id,
    696                                      wifi_interface_handle iface,
    697                                      char* iface_name)
    698 {
    699     ALOGV("NAN_DP_INTERFACE_CREATE");
    700     wifi_error ret;
    701     struct nlattr *nlData;
    702     NanCommand *nanCommand = NULL;
    703 
    704     if (iface_name == NULL) {
    705         ALOGE("%s: Invalid Nan Data Interface Name. \n", __FUNCTION__);
    706         return WIFI_ERROR_INVALID_ARGS;
    707     }
    708 
    709     ret = nan_initialize_vendor_cmd(iface,
    710                                     &nanCommand);
    711     if (ret != WIFI_SUCCESS) {
    712         ALOGE("%s: Initialization failed", __FUNCTION__);
    713         return ret;
    714     }
    715 
    716     /* Add the vendor specific attributes for the NL command. */
    717     nlData = nanCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
    718     if (!nlData)
    719         goto cleanup;
    720 
    721     if (nanCommand->put_u32(
    722             QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
    723             QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE) ||
    724         nanCommand->put_u16(
    725             QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
    726             id) ||
    727         nanCommand->put_string(
    728             QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR,
    729             iface_name)) {
    730         goto cleanup;
    731     }
    732 
    733     nanCommand->attr_end(nlData);
    734 
    735     ret = nanCommand->requestEvent();
    736     if (ret != WIFI_SUCCESS)
    737         ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);
    738 
    739 cleanup:
    740     delete nanCommand;
    741     return ret;
    742 }
    743 
    744 wifi_error nan_data_interface_delete(transaction_id id,
    745                                      wifi_interface_handle iface,
    746                                      char* iface_name)
    747 {
    748     ALOGV("NAN_DP_INTERFACE_DELETE");
    749     wifi_error ret;
    750     struct nlattr *nlData;
    751     NanCommand *nanCommand = NULL;
    752 
    753     if (iface_name == NULL) {
    754         ALOGE("%s: Invalid Nan Data Interface Name. \n", __FUNCTION__);
    755         return WIFI_ERROR_INVALID_ARGS;
    756     }
    757     ret = nan_initialize_vendor_cmd(iface,
    758                                     &nanCommand);
    759     if (ret != WIFI_SUCCESS) {
    760         ALOGE("%s: Initialization failed", __FUNCTION__);
    761         return ret;
    762     }
    763 
    764     /* Add the vendor specific attributes for the NL command. */
    765     nlData = nanCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
    766     if (!nlData)
    767         goto cleanup;
    768 
    769     if (nanCommand->put_u32(
    770             QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
    771             QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE) ||
    772         nanCommand->put_u16(
    773             QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
    774             id) ||
    775         nanCommand->put_string(
    776             QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR,
    777             iface_name)) {
    778         goto cleanup;
    779     }
    780 
    781     nanCommand->attr_end(nlData);
    782 
    783     ret = nanCommand->requestEvent();
    784     if (ret != WIFI_SUCCESS)
    785         ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);
    786 
    787 cleanup:
    788     delete nanCommand;
    789     return ret;
    790 }
    791 
    792 wifi_error nan_data_request_initiator(transaction_id id,
    793                                       wifi_interface_handle iface,
    794                                       NanDataPathInitiatorRequest* msg)
    795 {
    796     ALOGV("NAN_DP_REQUEST_INITIATOR");
    797     wifi_error ret;
    798     struct nlattr *nlData, *nlCfgSecurity, *nlCfgQos;
    799     NanCommand *nanCommand = NULL;
    800 
    801     if (msg == NULL)
    802         return WIFI_ERROR_INVALID_ARGS;
    803 
    804     ret = nan_initialize_vendor_cmd(iface,
    805                                     &nanCommand);
    806     if (ret != WIFI_SUCCESS) {
    807         ALOGE("%s: Initialization failed", __FUNCTION__);
    808         return ret;
    809     }
    810 
    811     if ((msg->cipher_type != NAN_CIPHER_SUITE_SHARED_KEY_NONE) &&
    812         (msg->key_info.body.pmk_info.pmk_len == 0) &&
    813         (msg->key_info.body.passphrase_info.passphrase_len == 0)) {
    814         ALOGE("%s: Failed-Initiator req, missing pmk and passphrase",
    815                __FUNCTION__);
    816         return WIFI_ERROR_INVALID_ARGS;
    817     }
    818 
    819     if ((msg->cipher_type != NAN_CIPHER_SUITE_SHARED_KEY_NONE) &&
    820         (msg->requestor_instance_id == OUT_OF_BAND_SERVICE_INSTANCE_ID) &&
    821         (msg->service_name_len == 0)) {
    822         ALOGE("%s: Failed-Initiator req, missing service name for out of band request",
    823               __FUNCTION__);
    824         return WIFI_ERROR_INVALID_ARGS;
    825     }
    826 
    827     /* Add the vendor specific attributes for the NL command. */
    828     nlData = nanCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
    829     if (!nlData)
    830         goto cleanup;
    831 
    832     if (nanCommand->put_u32(
    833             QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
    834             QCA_WLAN_VENDOR_ATTR_NDP_INITIATOR_REQUEST) ||
    835         nanCommand->put_u16(
    836             QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
    837             id) ||
    838         nanCommand->put_u32(
    839             QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID,
    840             msg->requestor_instance_id) ||
    841         nanCommand->put_bytes(
    842             QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR,
    843             (char *)msg->peer_disc_mac_addr,
    844             NAN_MAC_ADDR_LEN) ||
    845         nanCommand->put_string(
    846             QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR,
    847             msg->ndp_iface)) {
    848         goto cleanup;
    849     }
    850 
    851     if (msg->channel_request_type != NAN_DP_CHANNEL_NOT_REQUESTED) {
    852         if (nanCommand->put_u32 (
    853                 QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_CONFIG,
    854                 msg->channel_request_type) ||
    855             nanCommand->put_u32(
    856                 QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL,
    857                 msg->channel))
    858             goto cleanup;
    859     }
    860 
    861     if (msg->app_info.ndp_app_info_len != 0) {
    862         if (nanCommand->put_bytes(
    863                 QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO,
    864                 (char *)msg->app_info.ndp_app_info,
    865                 msg->app_info.ndp_app_info_len)) {
    866             goto cleanup;
    867         }
    868     }
    869     if (msg->ndp_cfg.security_cfg == NAN_DP_CONFIG_SECURITY) {
    870         nlCfgSecurity =
    871             nanCommand->attr_start(QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_SECURITY);
    872         if (!nlCfgSecurity)
    873             goto cleanup;
    874 
    875         if (nanCommand->put_u32(
    876             QCA_WLAN_VENDOR_ATTR_NDP_SECURITY_TYPE,
    877             0)) {
    878             goto cleanup;
    879         }
    880         nanCommand->attr_end(nlCfgSecurity);
    881     }
    882     if (msg->ndp_cfg.qos_cfg == NAN_DP_CONFIG_QOS) {
    883         nlCfgQos =
    884             nanCommand->attr_start(QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS);
    885         if (!nlCfgQos)
    886             goto cleanup;
    887         /* TBD Qos Info */
    888         nanCommand->attr_end(nlCfgQos);
    889     }
    890     if (msg->cipher_type != NAN_CIPHER_SUITE_SHARED_KEY_NONE) {
    891         if (nanCommand->put_u32(QCA_WLAN_VENDOR_ATTR_NDP_CSID,
    892                 msg->cipher_type))
    893             goto cleanup;
    894     }
    895     if ( msg->key_info.key_type == NAN_SECURITY_KEY_INPUT_PMK &&
    896          msg->key_info.body.pmk_info.pmk_len == NAN_PMK_INFO_LEN) {
    897         if (nanCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_NDP_PMK,
    898             (char *)msg->key_info.body.pmk_info.pmk,
    899             msg->key_info.body.pmk_info.pmk_len))
    900             goto cleanup;
    901     } else if (msg->key_info.key_type == NAN_SECURITY_KEY_INPUT_PASSPHRASE &&
    902         msg->key_info.body.passphrase_info.passphrase_len >=
    903         NAN_SECURITY_MIN_PASSPHRASE_LEN &&
    904         msg->key_info.body.passphrase_info.passphrase_len <=
    905         NAN_SECURITY_MAX_PASSPHRASE_LEN) {
    906         if (nanCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_NDP_PASSPHRASE,
    907             (char *)msg->key_info.body.passphrase_info.passphrase,
    908             msg->key_info.body.passphrase_info.passphrase_len))
    909             goto cleanup;
    910     }
    911     if (msg->service_name_len) {
    912         if (nanCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_NAME,
    913             (char *)msg->service_name, msg->service_name_len))
    914             goto cleanup;
    915     }
    916     nanCommand->attr_end(nlData);
    917 
    918     ret = nanCommand->requestEvent();
    919     if (ret != WIFI_SUCCESS)
    920         ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);
    921 
    922 cleanup:
    923     delete nanCommand;
    924     return ret;
    925 }
    926 
    927 wifi_error nan_data_indication_response(transaction_id id,
    928                                         wifi_interface_handle iface,
    929                                         NanDataPathIndicationResponse* msg)
    930 {
    931     ALOGV("NAN_DP_INDICATION_RESPONSE");
    932     wifi_error ret;
    933     struct nlattr *nlData, *nlCfgSecurity, *nlCfgQos;
    934     NanCommand *nanCommand = NULL;
    935 
    936     if (msg == NULL)
    937         return WIFI_ERROR_INVALID_ARGS;
    938 
    939     ret = nan_initialize_vendor_cmd(iface,
    940                                     &nanCommand);
    941     if (ret != WIFI_SUCCESS) {
    942         ALOGE("%s: Initialization failed", __FUNCTION__);
    943         return ret;
    944     }
    945 
    946     if ((msg->cipher_type != NAN_CIPHER_SUITE_SHARED_KEY_NONE) &&
    947         (msg->key_info.body.pmk_info.pmk_len == 0) &&
    948         (msg->key_info.body.passphrase_info.passphrase_len == 0)) {
    949         ALOGE("%s: Failed-Initiator req, missing pmk and passphrase",
    950                __FUNCTION__);
    951         return WIFI_ERROR_INVALID_ARGS;
    952     }
    953 
    954     /* Add the vendor specific attributes for the NL command. */
    955     nlData = nanCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
    956     if (!nlData)
    957         goto cleanup;
    958 
    959     if (nanCommand->put_u32(
    960             QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
    961             QCA_WLAN_VENDOR_ATTR_NDP_RESPONDER_REQUEST) ||
    962         nanCommand->put_u16(
    963             QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
    964             id) ||
    965         nanCommand->put_u32(
    966             QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID,
    967             msg->ndp_instance_id) ||
    968         nanCommand->put_string(
    969             QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR,
    970             msg->ndp_iface) ||
    971         nanCommand->put_u32(
    972             QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE,
    973             msg->rsp_code)) {
    974         goto cleanup;
    975     }
    976     if (msg->app_info.ndp_app_info_len != 0) {
    977         if (nanCommand->put_bytes(
    978                 QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO,
    979                 (char *)msg->app_info.ndp_app_info,
    980                 msg->app_info.ndp_app_info_len)) {
    981             goto cleanup;
    982         }
    983     }
    984     if (msg->ndp_cfg.security_cfg == NAN_DP_CONFIG_SECURITY) {
    985         nlCfgSecurity =
    986             nanCommand->attr_start(QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_SECURITY);
    987         if (!nlCfgSecurity)
    988             goto cleanup;
    989         /* Setting value to 0 for now */
    990         if (nanCommand->put_u32(
    991             QCA_WLAN_VENDOR_ATTR_NDP_SECURITY_TYPE,
    992             0)) {
    993             goto cleanup;
    994         }
    995         nanCommand->attr_end(nlCfgSecurity);
    996     }
    997     if (msg->ndp_cfg.qos_cfg == NAN_DP_CONFIG_QOS) {
    998         nlCfgQos =
    999             nanCommand->attr_start(QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS);
   1000         if (!nlCfgQos)
   1001             goto cleanup;
   1002 
   1003         /* TBD Qos Info */
   1004         nanCommand->attr_end(nlCfgQos);
   1005     }
   1006     if (msg->cipher_type != NAN_CIPHER_SUITE_SHARED_KEY_NONE) {
   1007         if (nanCommand->put_u32(QCA_WLAN_VENDOR_ATTR_NDP_CSID,
   1008                 msg->cipher_type))
   1009             goto cleanup;
   1010     }
   1011     if ( msg->key_info.key_type == NAN_SECURITY_KEY_INPUT_PMK &&
   1012          msg->key_info.body.pmk_info.pmk_len == NAN_PMK_INFO_LEN) {
   1013         if (nanCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_NDP_PMK,
   1014             (char *)msg->key_info.body.pmk_info.pmk,
   1015             msg->key_info.body.pmk_info.pmk_len))
   1016             goto cleanup;
   1017     } else if (msg->key_info.key_type == NAN_SECURITY_KEY_INPUT_PASSPHRASE &&
   1018         msg->key_info.body.passphrase_info.passphrase_len >=
   1019         NAN_SECURITY_MIN_PASSPHRASE_LEN &&
   1020         msg->key_info.body.passphrase_info.passphrase_len <=
   1021         NAN_SECURITY_MAX_PASSPHRASE_LEN) {
   1022         if (nanCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_NDP_PASSPHRASE,
   1023             (char *)msg->key_info.body.passphrase_info.passphrase,
   1024             msg->key_info.body.passphrase_info.passphrase_len))
   1025             goto cleanup;
   1026     }
   1027 
   1028     if (msg->service_name_len) {
   1029         if (nanCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_NAME,
   1030             (char *)msg->service_name, msg->service_name_len))
   1031             goto cleanup;
   1032     }
   1033     nanCommand->attr_end(nlData);
   1034 
   1035     ret = nanCommand->requestEvent();
   1036     if (ret != WIFI_SUCCESS)
   1037         ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);
   1038 
   1039 cleanup:
   1040     delete nanCommand;
   1041     return ret;
   1042 }
   1043 
   1044 wifi_error nan_data_end(transaction_id id,
   1045                         wifi_interface_handle iface,
   1046                         NanDataPathEndRequest* msg)
   1047 {
   1048     wifi_error ret;
   1049     ALOGV("NAN_DP_END");
   1050     struct nlattr *nlData;
   1051     NanCommand *nanCommand = NULL;
   1052 
   1053     if (msg == NULL)
   1054         return WIFI_ERROR_INVALID_ARGS;
   1055 
   1056     ret = nan_initialize_vendor_cmd(iface,
   1057                                     &nanCommand);
   1058     if (ret != WIFI_SUCCESS) {
   1059         ALOGE("%s: Initialization failed", __FUNCTION__);
   1060         return ret;
   1061     }
   1062 
   1063     /* Add the vendor specific attributes for the NL command. */
   1064     nlData = nanCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
   1065     if (!nlData)
   1066         goto cleanup;
   1067 
   1068     if (nanCommand->put_u32(
   1069             QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
   1070             QCA_WLAN_VENDOR_ATTR_NDP_END_REQUEST) ||
   1071         nanCommand->put_u16(
   1072             QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
   1073             id) ||
   1074         nanCommand->put_bytes(
   1075             QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY,
   1076             (char *)msg->ndp_instance_id,
   1077             msg->num_ndp_instances * sizeof(u32))) {
   1078         goto cleanup;
   1079     }
   1080     nanCommand->attr_end(nlData);
   1081 
   1082     ret = nanCommand->requestEvent();
   1083     if (ret != WIFI_SUCCESS)
   1084         ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);
   1085 
   1086 cleanup:
   1087     delete nanCommand;
   1088     return ret;
   1089 }
   1090 
   1091 // Implementation related to nan class common functions
   1092 // Constructor
   1093 //Making the constructor private since this class is a singleton
   1094 NanCommand::NanCommand(wifi_handle handle, int id, u32 vendor_id, u32 subcmd)
   1095         : WifiVendorCommand(handle, id, vendor_id, subcmd)
   1096 {
   1097     memset(&mHandler, 0,sizeof(mHandler));
   1098     mNanVendorEvent = NULL;
   1099     mNanDataLen = 0;
   1100     mStaParam = NULL;
   1101 }
   1102 
   1103 NanCommand* NanCommand::instance(wifi_handle handle)
   1104 {
   1105     if (handle == NULL) {
   1106         ALOGE("Handle is invalid");
   1107         return NULL;
   1108     }
   1109     if (mNanCommandInstance == NULL) {
   1110         mNanCommandInstance = new NanCommand(handle, 0,
   1111                                              OUI_QCA,
   1112                                              QCA_NL80211_VENDOR_SUBCMD_NAN);
   1113         ALOGV("NanCommand %p created", mNanCommandInstance);
   1114         return mNanCommandInstance;
   1115     } else {
   1116         if (handle != getWifiHandle(mNanCommandInstance->mInfo)) {
   1117             /* upper layer must have cleaned up the handle and reinitialized,
   1118                so we need to update the same */
   1119             ALOGI("Handle different, update the handle");
   1120             mNanCommandInstance->mInfo = (hal_info *)handle;
   1121         }
   1122     }
   1123     ALOGV("NanCommand %p created already", mNanCommandInstance);
   1124     return mNanCommandInstance;
   1125 }
   1126 
   1127 void NanCommand::cleanup()
   1128 {
   1129     //free the VendorData
   1130     if (mVendorData) {
   1131         free(mVendorData);
   1132     }
   1133     mVendorData = NULL;
   1134     //cleanup the mMsg
   1135     mMsg.destroy();
   1136 }
   1137 
   1138 NanCommand::~NanCommand()
   1139 {
   1140     ALOGV("NanCommand %p destroyed", this);
   1141 }
   1142 
   1143 int NanCommand::handleResponse(WifiEvent &reply){
   1144     return NL_SKIP;
   1145 }
   1146 
   1147 wifi_error NanCommand::setCallbackHandler(NanCallbackHandler nHandler)
   1148 {
   1149     wifi_error res;
   1150     mHandler = nHandler;
   1151     res = registerVendorHandler(mVendor_id, QCA_NL80211_VENDOR_SUBCMD_NAN);
   1152     if (res != WIFI_SUCCESS) {
   1153         //error case should not happen print log
   1154         ALOGE("%s: Unable to register Vendor Handler Vendor Id=0x%x"
   1155               "subcmd=QCA_NL80211_VENDOR_SUBCMD_NAN", __FUNCTION__, mVendor_id);
   1156         return res;
   1157     }
   1158 
   1159     res = registerVendorHandler(mVendor_id, QCA_NL80211_VENDOR_SUBCMD_NDP);
   1160     if (res != WIFI_SUCCESS) {
   1161         //error case should not happen print log
   1162         ALOGE("%s: Unable to register Vendor Handler Vendor Id=0x%x"
   1163               "subcmd=QCA_NL80211_VENDOR_SUBCMD_NDP", __FUNCTION__, mVendor_id);
   1164         return res;
   1165     }
   1166     return res;
   1167 }
   1168 
   1169 /* This function implements creation of Vendor command */
   1170 wifi_error NanCommand::create() {
   1171     wifi_error ret = mMsg.create(NL80211_CMD_VENDOR, 0, 0);
   1172     if (ret != WIFI_SUCCESS)
   1173         goto out;
   1174 
   1175     /* Insert the oui in the msg */
   1176     ret = mMsg.put_u32(NL80211_ATTR_VENDOR_ID, mVendor_id);
   1177     if (ret != WIFI_SUCCESS)
   1178         goto out;
   1179     /* Insert the subcmd in the msg */
   1180     ret = mMsg.put_u32(NL80211_ATTR_VENDOR_SUBCMD, mSubcmd);
   1181 
   1182 out:
   1183     if (ret != WIFI_SUCCESS)
   1184         mMsg.destroy();
   1185     return ret;
   1186 }
   1187 
   1188 // This function will be the main handler for incoming event
   1189 // QCA_NL80211_VENDOR_SUBCMD_NAN
   1190 //Call the appropriate callback handler after parsing the vendor data.
   1191 int NanCommand::handleEvent(WifiEvent &event)
   1192 {
   1193     WifiVendorCommand::handleEvent(event);
   1194     ALOGV("%s: Subcmd=%u Vendor data len received:%d",
   1195           __FUNCTION__, mSubcmd, mDataLen);
   1196     hexdump(mVendorData, mDataLen);
   1197 
   1198     if (mSubcmd == QCA_NL80211_VENDOR_SUBCMD_NAN){
   1199         // Parse the vendordata and get the NAN attribute
   1200         struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_MAX + 1];
   1201         nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_MAX,
   1202                   (struct nlattr *)mVendorData,
   1203                   mDataLen, NULL);
   1204         // Populating the mNanVendorEvent and mNanDataLen to point to NAN data.
   1205         mNanVendorEvent = (char *)nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_NAN]);
   1206         mNanDataLen = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_NAN]);
   1207 
   1208         if (isNanResponse()) {
   1209             //handleNanResponse will parse the data and call
   1210             //the response callback handler with the populated
   1211             //NanResponseMsg
   1212             handleNanResponse();
   1213         } else {
   1214             //handleNanIndication will parse the data and call
   1215             //the corresponding Indication callback handler
   1216             //with the corresponding populated Indication event
   1217             handleNanIndication();
   1218         }
   1219     } else if (mSubcmd == QCA_NL80211_VENDOR_SUBCMD_NDP) {
   1220         // Parse the vendordata and get the NAN attribute
   1221         u32 ndpCmdType;
   1222         struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_AFTER_LAST + 1];
   1223         nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_NDP_MAX,
   1224                   (struct nlattr *)mVendorData,
   1225                   mDataLen, NULL);
   1226 
   1227         if (tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD]) {
   1228             ndpCmdType =
   1229                 nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD]);
   1230                 ALOGD("%s: NDP Cmd Type : val 0x%x",
   1231                       __FUNCTION__, ndpCmdType);
   1232                 switch (ndpCmdType) {
   1233                 case QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE:
   1234                     handleNdpResponse(NAN_DP_INTERFACE_CREATE, tb_vendor);
   1235                     break;
   1236                 case QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE:
   1237                     handleNdpResponse(NAN_DP_INTERFACE_DELETE, tb_vendor);
   1238                     break;
   1239                 case QCA_WLAN_VENDOR_ATTR_NDP_INITIATOR_RESPONSE:
   1240                     handleNdpResponse(NAN_DP_INITIATOR_RESPONSE, tb_vendor);
   1241                     break;
   1242                 case QCA_WLAN_VENDOR_ATTR_NDP_RESPONDER_RESPONSE:
   1243                     handleNdpResponse(NAN_DP_RESPONDER_RESPONSE, tb_vendor);
   1244                     break;
   1245                 case QCA_WLAN_VENDOR_ATTR_NDP_END_RESPONSE:
   1246                     handleNdpResponse(NAN_DP_END, tb_vendor);
   1247                     break;
   1248                 case QCA_WLAN_VENDOR_ATTR_NDP_DATA_REQUEST_IND:
   1249                 case QCA_WLAN_VENDOR_ATTR_NDP_CONFIRM_IND:
   1250                 case QCA_WLAN_VENDOR_ATTR_NDP_END_IND:
   1251                 case QCA_WLAN_VENDOR_ATTR_NDP_SCHEDULE_UPDATE_IND:
   1252                     handleNdpIndication(ndpCmdType, tb_vendor);
   1253                     break;
   1254                 default:
   1255                     ALOGE("%s: Invalid NDP subcmd response received %d",
   1256                           __FUNCTION__, ndpCmdType);
   1257                 }
   1258         }
   1259     } else {
   1260         //error case should not happen print log
   1261         ALOGE("%s: Wrong NAN subcmd received %d", __FUNCTION__, mSubcmd);
   1262     }
   1263     return NL_SKIP;
   1264 }
   1265 
   1266 /*Helper function to Write and Read TLV called in indication as well as request */
   1267 u16 NANTLV_WriteTlv(pNanTlv pInTlv, u8 *pOutTlv)
   1268 {
   1269     u16 writeLen = 0;
   1270     u16 i;
   1271 
   1272     if (!pInTlv)
   1273     {
   1274         ALOGE("NULL pInTlv");
   1275         return writeLen;
   1276     }
   1277 
   1278     if (!pOutTlv)
   1279     {
   1280         ALOGE("NULL pOutTlv");
   1281         return writeLen;
   1282     }
   1283 
   1284     *pOutTlv++ = pInTlv->type & 0xFF;
   1285     *pOutTlv++ = (pInTlv->type & 0xFF00) >> 8;
   1286     writeLen += 2;
   1287 
   1288     ALOGV("WRITE TLV type %u, writeLen %u", pInTlv->type, writeLen);
   1289 
   1290     *pOutTlv++ = pInTlv->length & 0xFF;
   1291     *pOutTlv++ = (pInTlv->length & 0xFF00) >> 8;
   1292     writeLen += 2;
   1293 
   1294     ALOGV("WRITE TLV length %u, writeLen %u", pInTlv->length, writeLen);
   1295 
   1296     for (i=0; i < pInTlv->length; ++i)
   1297     {
   1298         *pOutTlv++ = pInTlv->value[i];
   1299     }
   1300 
   1301     writeLen += pInTlv->length;
   1302     ALOGV("WRITE TLV value, writeLen %u", writeLen);
   1303     return writeLen;
   1304 }
   1305 
   1306 u16 NANTLV_ReadTlv(u8 *pInTlv, pNanTlv pOutTlv)
   1307 {
   1308     u16 readLen = 0;
   1309 
   1310     if (!pInTlv)
   1311     {
   1312         ALOGE("NULL pInTlv");
   1313         return readLen;
   1314     }
   1315 
   1316     if (!pOutTlv)
   1317     {
   1318         ALOGE("NULL pOutTlv");
   1319         return readLen;
   1320     }
   1321 
   1322     pOutTlv->type = *pInTlv++;
   1323     pOutTlv->type |= *pInTlv++ << 8;
   1324     readLen += 2;
   1325 
   1326     ALOGV("READ TLV type %u, readLen %u", pOutTlv->type, readLen);
   1327 
   1328     pOutTlv->length = *pInTlv++;
   1329     pOutTlv->length |= *pInTlv++ << 8;
   1330     readLen += 2;
   1331 
   1332     ALOGV("READ TLV length %u, readLen %u", pOutTlv->length, readLen);
   1333 
   1334     if (pOutTlv->length) {
   1335         pOutTlv->value = pInTlv;
   1336         readLen += pOutTlv->length;
   1337     } else {
   1338         pOutTlv->value = NULL;
   1339     }
   1340 
   1341     ALOGV("READ TLV  readLen %u", readLen);
   1342     return readLen;
   1343 }
   1344 
   1345 u8* addTlv(u16 type, u16 length, const u8* value, u8* pOutTlv)
   1346 {
   1347    NanTlv nanTlv;
   1348    u16 len;
   1349 
   1350    nanTlv.type = type;
   1351    nanTlv.length = length;
   1352    nanTlv.value = (u8*)value;
   1353 
   1354    len = NANTLV_WriteTlv(&nanTlv, pOutTlv);
   1355    return (pOutTlv + len);
   1356 }
   1357