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 #include <utils/Log.h>
     19 #include "wifi_hal.h"
     20 #include "nan_i.h"
     21 #include "nancommand.h"
     22 
     23 wifi_error NanCommand::putNanEnable(transaction_id id, const NanEnableRequest *pReq)
     24 {
     25     wifi_error ret;
     26     ALOGV("NAN_ENABLE");
     27     size_t message_len = NAN_MAX_ENABLE_REQ_SIZE;
     28 
     29     if (pReq == NULL) {
     30         cleanup();
     31         return WIFI_ERROR_INVALID_ARGS;
     32     }
     33 
     34     message_len += \
     35         (
     36           pReq->config_support_5g ? (SIZEOF_TLV_HDR + \
     37           sizeof(pReq->support_5g_val)) : 0 \
     38         ) + \
     39         (
     40           pReq->config_sid_beacon ? (SIZEOF_TLV_HDR + \
     41           sizeof(pReq->sid_beacon_val)) : 0 \
     42         ) + \
     43         (
     44           pReq->config_2dot4g_rssi_close ? (SIZEOF_TLV_HDR + \
     45           sizeof(pReq->rssi_close_2dot4g_val)) : 0 \
     46         ) + \
     47         (
     48           pReq->config_2dot4g_rssi_middle ? (SIZEOF_TLV_HDR + \
     49           sizeof(pReq->rssi_middle_2dot4g_val)) : 0 \
     50         ) + \
     51         (
     52           pReq->config_hop_count_limit ? (SIZEOF_TLV_HDR + \
     53           sizeof(pReq->hop_count_limit_val)) : 0 \
     54         ) + \
     55         (
     56           pReq->config_2dot4g_support ? (SIZEOF_TLV_HDR + \
     57           sizeof(pReq->support_2dot4g_val)) : 0 \
     58         ) + \
     59         (
     60           pReq->config_2dot4g_beacons ? (SIZEOF_TLV_HDR + \
     61           sizeof(pReq->beacon_2dot4g_val)) : 0 \
     62         ) + \
     63         (
     64           pReq->config_2dot4g_sdf ? (SIZEOF_TLV_HDR + \
     65           sizeof(pReq->sdf_2dot4g_val)) : 0 \
     66         ) + \
     67         (
     68           pReq->config_5g_beacons ? (SIZEOF_TLV_HDR + \
     69           sizeof(pReq->beacon_5g_val)) : 0 \
     70         ) + \
     71         (
     72           pReq->config_5g_sdf ? (SIZEOF_TLV_HDR + \
     73           sizeof(pReq->sdf_5g_val)) : 0 \
     74         ) + \
     75         (
     76           pReq->config_5g_rssi_close ? (SIZEOF_TLV_HDR + \
     77           sizeof(pReq->rssi_close_5g_val)) : 0 \
     78         ) + \
     79         (
     80           pReq->config_5g_rssi_middle ? (SIZEOF_TLV_HDR + \
     81           sizeof(pReq->rssi_middle_5g_val)) : 0 \
     82         ) + \
     83         (
     84           pReq->config_2dot4g_rssi_proximity ? (SIZEOF_TLV_HDR + \
     85           sizeof(pReq->rssi_proximity_2dot4g_val)) : 0 \
     86         ) + \
     87         (
     88           pReq->config_5g_rssi_close_proximity ? (SIZEOF_TLV_HDR + \
     89           sizeof(pReq->rssi_close_proximity_5g_val)) : 0 \
     90         ) + \
     91         (
     92           pReq->config_rssi_window_size ? (SIZEOF_TLV_HDR + \
     93           sizeof(pReq->rssi_window_size_val)) : 0 \
     94         ) + \
     95         (
     96           pReq->config_oui ? (SIZEOF_TLV_HDR + \
     97           sizeof(pReq->oui_val)) : 0 \
     98         ) + \
     99         (
    100           pReq->config_intf_addr ? (SIZEOF_TLV_HDR + \
    101           sizeof(pReq->intf_addr_val)) : 0 \
    102         ) + \
    103         (
    104           pReq->config_cluster_attribute_val ? (SIZEOF_TLV_HDR + \
    105           sizeof(pReq->config_cluster_attribute_val)) : 0 \
    106         ) + \
    107         (
    108           pReq->config_scan_params ? NAN_MAX_SOCIAL_CHANNELS *
    109           (SIZEOF_TLV_HDR + sizeof(u32)) : 0 \
    110         ) + \
    111         (
    112           pReq->config_random_factor_force ? (SIZEOF_TLV_HDR + \
    113           sizeof(pReq->random_factor_force_val)) : 0 \
    114         ) + \
    115         (
    116           pReq->config_hop_count_force ? (SIZEOF_TLV_HDR + \
    117           sizeof(pReq->hop_count_force_val)) : 0 \
    118         ) + \
    119         (
    120           pReq->config_24g_channel ? (SIZEOF_TLV_HDR + \
    121           sizeof(u32)) : 0 \
    122         ) + \
    123         (
    124           pReq->config_5g_channel ? (SIZEOF_TLV_HDR + \
    125           sizeof(u32)) : 0 \
    126         ) + \
    127         (
    128            pReq->config_dw.config_2dot4g_dw_band ? (SIZEOF_TLV_HDR + \
    129            sizeof(u32)) : 0 \
    130         ) + \
    131         (
    132            pReq->config_dw.config_5g_dw_band ? (SIZEOF_TLV_HDR + \
    133            sizeof(u32)) : 0 \
    134         ) + \
    135         (
    136            pReq->config_disc_mac_addr_randomization ? (SIZEOF_TLV_HDR + \
    137            sizeof(u32)) : 0 \
    138         ) + \
    139         (
    140            /* Always include cfg discovery indication TLV */
    141            SIZEOF_TLV_HDR + sizeof(u32) \
    142         ) + \
    143         (
    144           pReq->config_subscribe_sid_beacon ? (SIZEOF_TLV_HDR + \
    145           sizeof(pReq->subscribe_sid_beacon_val)) : 0 \
    146         ) + \
    147         (
    148            pReq->config_discovery_beacon_int ? (SIZEOF_TLV_HDR + \
    149            sizeof(u32)) : 0 \
    150         ) + \
    151         (
    152            pReq->config_nss ? (SIZEOF_TLV_HDR + \
    153            sizeof(u32)) : 0 \
    154         ) + \
    155         (
    156            pReq->config_enable_ranging ? (SIZEOF_TLV_HDR + \
    157            sizeof(u32)) : 0 \
    158         ) + \
    159         (
    160            pReq->config_dw_early_termination ? (SIZEOF_TLV_HDR + \
    161            sizeof(u32)) : 0 \
    162         );
    163 
    164     pNanEnableReqMsg pFwReq = (pNanEnableReqMsg)malloc(message_len);
    165     if (pFwReq == NULL) {
    166         cleanup();
    167         return WIFI_ERROR_OUT_OF_MEMORY;
    168     }
    169 
    170     ALOGV("Message Len %zu", message_len);
    171     memset (pFwReq, 0, message_len);
    172     pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
    173     pFwReq->fwHeader.msgId = NAN_MSG_ID_ENABLE_REQ;
    174     pFwReq->fwHeader.msgLen = message_len;
    175     pFwReq->fwHeader.transactionId = id;
    176 
    177     u8* tlvs = pFwReq->ptlv;
    178 
    179     /* Write the TLVs to the message. */
    180 
    181     tlvs = addTlv(NAN_TLV_TYPE_CLUSTER_ID_LOW, sizeof(pReq->cluster_low),
    182                   (const u8*)&pReq->cluster_low, tlvs);
    183     tlvs = addTlv(NAN_TLV_TYPE_CLUSTER_ID_HIGH, sizeof(pReq->cluster_high),
    184                   (const u8*)&pReq->cluster_high, tlvs);
    185     tlvs = addTlv(NAN_TLV_TYPE_MASTER_PREFERENCE, sizeof(pReq->master_pref),
    186                   (const u8*)&pReq->master_pref, tlvs);
    187     if (pReq->config_support_5g) {
    188         tlvs = addTlv(NAN_TLV_TYPE_5G_SUPPORT, sizeof(pReq->support_5g_val),
    189                      (const u8*)&pReq->support_5g_val, tlvs);
    190     }
    191     if (pReq->config_sid_beacon) {
    192         tlvs = addTlv(NAN_TLV_TYPE_SID_BEACON, sizeof(pReq->sid_beacon_val),
    193                       (const u8*)&pReq->sid_beacon_val, tlvs);
    194     }
    195     if (pReq->config_2dot4g_rssi_close) {
    196         tlvs = addTlv(NAN_TLV_TYPE_24G_RSSI_CLOSE,
    197                       sizeof(pReq->rssi_close_2dot4g_val),
    198                       (const u8*)&pReq->rssi_close_2dot4g_val, tlvs);
    199     }
    200     if (pReq->config_2dot4g_rssi_middle) {
    201         tlvs = addTlv(NAN_TLV_TYPE_24G_RSSI_MIDDLE,
    202                       sizeof(pReq->rssi_middle_2dot4g_val),
    203                       (const u8*)&pReq->rssi_middle_2dot4g_val, tlvs);
    204     }
    205     if (pReq->config_hop_count_limit) {
    206         tlvs = addTlv(NAN_TLV_TYPE_HOP_COUNT_LIMIT,
    207                       sizeof(pReq->hop_count_limit_val),
    208                       (const u8*)&pReq->hop_count_limit_val, tlvs);
    209     }
    210     if (pReq->config_2dot4g_support) {
    211         tlvs = addTlv(NAN_TLV_TYPE_24G_SUPPORT, sizeof(pReq->support_2dot4g_val),
    212                       (const u8*)&pReq->support_2dot4g_val, tlvs);
    213     }
    214     if (pReq->config_2dot4g_beacons) {
    215         tlvs = addTlv(NAN_TLV_TYPE_24G_BEACON, sizeof(pReq->beacon_2dot4g_val),
    216                       (const u8*)&pReq->beacon_2dot4g_val, tlvs);
    217     }
    218     if (pReq->config_2dot4g_sdf) {
    219         tlvs = addTlv(NAN_TLV_TYPE_24G_SDF, sizeof(pReq->sdf_2dot4g_val),
    220                       (const u8*)&pReq->sdf_2dot4g_val, tlvs);
    221     }
    222     if (pReq->config_5g_beacons) {
    223         tlvs = addTlv(NAN_TLV_TYPE_5G_BEACON, sizeof(pReq->beacon_5g_val),
    224                       (const u8*)&pReq->beacon_5g_val, tlvs);
    225     }
    226     if (pReq->config_5g_sdf) {
    227         tlvs = addTlv(NAN_TLV_TYPE_5G_SDF, sizeof(pReq->sdf_5g_val),
    228                       (const u8*)&pReq->sdf_5g_val, tlvs);
    229     }
    230     if (pReq->config_2dot4g_rssi_proximity) {
    231         tlvs = addTlv(NAN_TLV_TYPE_24G_RSSI_CLOSE_PROXIMITY,
    232                       sizeof(pReq->rssi_proximity_2dot4g_val),
    233                       (const u8*)&pReq->rssi_proximity_2dot4g_val, tlvs);
    234     }
    235     /* Add the support of sending 5G RSSI values */
    236     if (pReq->config_5g_rssi_close) {
    237         tlvs = addTlv(NAN_TLV_TYPE_5G_RSSI_CLOSE, sizeof(pReq->rssi_close_5g_val),
    238                       (const u8*)&pReq->rssi_close_5g_val, tlvs);
    239     }
    240     if (pReq->config_5g_rssi_middle) {
    241         tlvs = addTlv(NAN_TLV_TYPE_5G_RSSI_MIDDLE, sizeof(pReq->rssi_middle_5g_val),
    242                       (const u8*)&pReq->rssi_middle_5g_val, tlvs);
    243     }
    244     if (pReq->config_5g_rssi_close_proximity) {
    245         tlvs = addTlv(NAN_TLV_TYPE_5G_RSSI_CLOSE_PROXIMITY,
    246                       sizeof(pReq->rssi_close_proximity_5g_val),
    247                       (const u8*)&pReq->rssi_close_proximity_5g_val, tlvs);
    248     }
    249     if (pReq->config_rssi_window_size) {
    250         tlvs = addTlv(NAN_TLV_TYPE_RSSI_AVERAGING_WINDOW_SIZE, sizeof(pReq->rssi_window_size_val),
    251                       (const u8*)&pReq->rssi_window_size_val, tlvs);
    252     }
    253     if (pReq->config_oui) {
    254         tlvs = addTlv(NAN_TLV_TYPE_CLUSTER_OUI_NETWORK_ID, sizeof(pReq->oui_val),
    255                       (const u8*)&pReq->oui_val, tlvs);
    256     }
    257     if (pReq->config_intf_addr) {
    258         tlvs = addTlv(NAN_TLV_TYPE_SOURCE_MAC_ADDRESS, sizeof(pReq->intf_addr_val),
    259                       (const u8*)&pReq->intf_addr_val[0], tlvs);
    260     }
    261     if (pReq->config_cluster_attribute_val) {
    262         tlvs = addTlv(NAN_TLV_TYPE_CLUSTER_ATTRIBUTE_IN_SDF, sizeof(pReq->config_cluster_attribute_val),
    263                       (const u8*)&pReq->config_cluster_attribute_val, tlvs);
    264     }
    265     if (pReq->config_scan_params) {
    266         u32 socialChannelParamVal[NAN_MAX_SOCIAL_CHANNELS];
    267         /* Fill the social channel param */
    268         fillNanSocialChannelParamVal(&pReq->scan_params_val,
    269                                      socialChannelParamVal);
    270         int i;
    271         for (i = 0; i < NAN_MAX_SOCIAL_CHANNELS; i++) {
    272             tlvs = addTlv(NAN_TLV_TYPE_SOCIAL_CHANNEL_SCAN_PARAMS,
    273                           sizeof(socialChannelParamVal[i]),
    274                           (const u8*)&socialChannelParamVal[i], tlvs);
    275         }
    276     }
    277     if (pReq->config_random_factor_force) {
    278         tlvs = addTlv(NAN_TLV_TYPE_RANDOM_FACTOR_FORCE,
    279                       sizeof(pReq->random_factor_force_val),
    280                       (const u8*)&pReq->random_factor_force_val, tlvs);
    281     }
    282     if (pReq->config_hop_count_force) {
    283         tlvs = addTlv(NAN_TLV_TYPE_HOP_COUNT_FORCE,
    284                       sizeof(pReq->hop_count_force_val),
    285                       (const u8*)&pReq->hop_count_force_val, tlvs);
    286     }
    287     if (pReq->config_24g_channel) {
    288         tlvs = addTlv(NAN_TLV_TYPE_24G_CHANNEL,
    289                       sizeof(u32),
    290                       (const u8*)&pReq->channel_24g_val, tlvs);
    291     }
    292     if (pReq->config_5g_channel) {
    293         tlvs = addTlv(NAN_TLV_TYPE_5G_CHANNEL,
    294                       sizeof(u32),
    295                       (const u8*)&pReq->channel_5g_val, tlvs);
    296     }
    297     if (pReq->config_dw.config_2dot4g_dw_band) {
    298         tlvs = addTlv(NAN_TLV_TYPE_2G_COMMITTED_DW,
    299                       sizeof(pReq->config_dw.dw_2dot4g_interval_val),
    300                       (const u8*)&pReq->config_dw.dw_2dot4g_interval_val, tlvs);
    301     }
    302     if (pReq->config_dw.config_5g_dw_band) {
    303         tlvs = addTlv(NAN_TLV_TYPE_5G_COMMITTED_DW,
    304                       sizeof(pReq->config_dw.dw_5g_interval_val),
    305                       (const u8*)&pReq->config_dw.dw_5g_interval_val, tlvs);
    306     }
    307     if (pReq->config_disc_mac_addr_randomization) {
    308         tlvs = addTlv(NAN_TLV_TYPE_DISC_MAC_ADDR_RANDOM_INTERVAL,
    309                       sizeof(u32),
    310                       (const u8*)&pReq->disc_mac_addr_rand_interval_sec, tlvs);
    311     }
    312 
    313     u32 config_discovery_indications;
    314     config_discovery_indications = (u32)pReq->discovery_indication_cfg;
    315     tlvs = addTlv(NAN_TLV_TYPE_CONFIG_DISCOVERY_INDICATIONS,
    316                   sizeof(u32),
    317                   (const u8*)&config_discovery_indications, tlvs);
    318 
    319     if (pReq->config_subscribe_sid_beacon) {
    320         tlvs = addTlv(NAN_TLV_TYPE_SUBSCRIBE_SID_BEACON,
    321                       sizeof(pReq->subscribe_sid_beacon_val),
    322                       (const u8*)&pReq->subscribe_sid_beacon_val, tlvs);
    323     }
    324     if (pReq->config_discovery_beacon_int) {
    325         tlvs = addTlv(NAN_TLV_TYPE_DB_INTERVAL, sizeof(u32),
    326                       (const u8*)&pReq->discovery_beacon_interval, tlvs);
    327     }
    328     if (pReq->config_nss) {
    329         tlvs = addTlv(NAN_TLV_TYPE_TX_RX_CHAINS, sizeof(u32),
    330                       (const u8*)&pReq->nss, tlvs);
    331     }
    332     if (pReq->config_enable_ranging) {
    333         tlvs = addTlv(NAN_TLV_TYPE_ENABLE_DEVICE_RANGING, sizeof(u32),
    334                       (const u8*)&pReq->enable_ranging, tlvs);
    335     }
    336     if (pReq->config_dw_early_termination) {
    337         tlvs = addTlv(NAN_TLV_TYPE_DW_EARLY_TERMINATION, sizeof(u32),
    338                       (const u8*)&pReq->enable_dw_termination, tlvs);
    339     }
    340 
    341     mVendorData = (char*)pFwReq;
    342     mDataLen = message_len;
    343 
    344     //Insert the vendor specific data
    345     ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
    346     if (ret != WIFI_SUCCESS) {
    347         ALOGE("%s: put_bytes Error:%d",__func__, ret);
    348         cleanup();
    349         return ret;
    350     }
    351     hexdump(mVendorData, mDataLen);
    352     return ret;
    353 }
    354 
    355 wifi_error NanCommand::putNanDisable(transaction_id id)
    356 {
    357     wifi_error ret;
    358     ALOGV("NAN_DISABLE");
    359     size_t message_len = sizeof(NanDisableReqMsg);
    360 
    361     pNanDisableReqMsg pFwReq = (pNanDisableReqMsg)malloc(message_len);
    362     if (pFwReq == NULL) {
    363         cleanup();
    364         return WIFI_ERROR_OUT_OF_MEMORY;
    365     }
    366 
    367     ALOGV("Message Len %zu", message_len);
    368     memset (pFwReq, 0, message_len);
    369     pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
    370     pFwReq->fwHeader.msgId = NAN_MSG_ID_DISABLE_REQ;
    371     pFwReq->fwHeader.msgLen = message_len;
    372     pFwReq->fwHeader.transactionId = id;
    373 
    374     mVendorData = (char*)pFwReq;
    375     mDataLen = message_len;
    376 
    377     ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
    378     if (ret != WIFI_SUCCESS) {
    379         ALOGE("%s: put_bytes Error:%d",__func__, ret);
    380         cleanup();
    381         return ret;
    382     }
    383     hexdump(mVendorData, mDataLen);
    384     return ret;
    385 }
    386 
    387 wifi_error NanCommand::putNanConfig(transaction_id id, const NanConfigRequest *pReq)
    388 {
    389     wifi_error ret;
    390     ALOGV("NAN_CONFIG");
    391     size_t message_len = 0;
    392     int idx = 0;
    393 
    394     if (pReq == NULL ||
    395         pReq->num_config_discovery_attr > NAN_MAX_POSTDISCOVERY_LEN) {
    396         cleanup();
    397         return WIFI_ERROR_INVALID_ARGS;
    398     }
    399 
    400     message_len = sizeof(NanMsgHeader);
    401 
    402     message_len += \
    403         (
    404            pReq->config_sid_beacon ? (SIZEOF_TLV_HDR + \
    405            sizeof(pReq->sid_beacon)) : 0 \
    406         ) + \
    407         (
    408            pReq->config_master_pref ? (SIZEOF_TLV_HDR + \
    409            sizeof(pReq->master_pref)) : 0 \
    410         ) + \
    411         (
    412            pReq->config_rssi_proximity ? (SIZEOF_TLV_HDR + \
    413            sizeof(pReq->rssi_proximity)) : 0 \
    414         ) + \
    415         (
    416            pReq->config_5g_rssi_close_proximity ? (SIZEOF_TLV_HDR + \
    417            sizeof(pReq->rssi_close_proximity_5g_val)) : 0 \
    418         ) + \
    419         (
    420            pReq->config_rssi_window_size ? (SIZEOF_TLV_HDR + \
    421            sizeof(pReq->rssi_window_size_val)) : 0 \
    422         ) + \
    423         (
    424            pReq->config_cluster_attribute_val ? (SIZEOF_TLV_HDR + \
    425            sizeof(pReq->config_cluster_attribute_val)) : 0 \
    426         ) + \
    427         (
    428            pReq->config_scan_params ? NAN_MAX_SOCIAL_CHANNELS *
    429            (SIZEOF_TLV_HDR + sizeof(u32)) : 0 \
    430         ) + \
    431         (
    432            pReq->config_random_factor_force ? (SIZEOF_TLV_HDR + \
    433            sizeof(pReq->random_factor_force_val)) : 0 \
    434         ) + \
    435         (
    436            pReq->config_hop_count_force ? (SIZEOF_TLV_HDR + \
    437            sizeof(pReq->hop_count_force_val)) : 0 \
    438         ) + \
    439         (
    440            pReq->config_conn_capability ? (SIZEOF_TLV_HDR + \
    441            sizeof(u32)) : 0 \
    442         ) + \
    443         (
    444            pReq->config_dw.config_2dot4g_dw_band ? (SIZEOF_TLV_HDR + \
    445            sizeof(u32)) : 0 \
    446         ) + \
    447         (
    448            pReq->config_dw.config_5g_dw_band ? (SIZEOF_TLV_HDR + \
    449            sizeof(u32)) : 0 \
    450         ) + \
    451         (
    452            pReq->config_disc_mac_addr_randomization ? (SIZEOF_TLV_HDR + \
    453            sizeof(u32)) : 0 \
    454         ) + \
    455         (
    456           pReq->config_subscribe_sid_beacon ? (SIZEOF_TLV_HDR + \
    457           sizeof(pReq->subscribe_sid_beacon_val)) : 0 \
    458         ) + \
    459         (
    460            /* Always include cfg discovery indication TLV */
    461            SIZEOF_TLV_HDR + sizeof(u32) \
    462         ) + \
    463         (
    464            pReq->config_discovery_beacon_int ? (SIZEOF_TLV_HDR + \
    465            sizeof(u32)) : 0 \
    466         ) + \
    467         (
    468            pReq->config_nss ? (SIZEOF_TLV_HDR + \
    469            sizeof(u32)) : 0 \
    470         ) + \
    471         (
    472            pReq->config_enable_ranging ? (SIZEOF_TLV_HDR + \
    473            sizeof(u32)) : 0 \
    474         ) + \
    475         (
    476            pReq->config_dw_early_termination ? (SIZEOF_TLV_HDR + \
    477            sizeof(u32)) : 0 \
    478         );
    479 
    480     if (pReq->num_config_discovery_attr) {
    481         for (idx = 0; idx < pReq->num_config_discovery_attr; idx ++) {
    482             message_len += SIZEOF_TLV_HDR +\
    483                 calcNanTransmitPostDiscoverySize(&pReq->discovery_attr_val[idx]);
    484         }
    485     }
    486 
    487     if (pReq->config_fam && \
    488         calcNanFurtherAvailabilityMapSize(&pReq->fam_val)) {
    489         message_len += (SIZEOF_TLV_HDR + \
    490            calcNanFurtherAvailabilityMapSize(&pReq->fam_val));
    491     }
    492 
    493     pNanConfigurationReqMsg pFwReq = (pNanConfigurationReqMsg)malloc(message_len);
    494     if (pFwReq == NULL) {
    495         cleanup();
    496         return WIFI_ERROR_OUT_OF_MEMORY;
    497     }
    498 
    499     ALOGV("Message Len %zu", message_len);
    500     memset (pFwReq, 0, message_len);
    501     pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
    502     pFwReq->fwHeader.msgId = NAN_MSG_ID_CONFIGURATION_REQ;
    503     pFwReq->fwHeader.msgLen = message_len;
    504     pFwReq->fwHeader.transactionId = id;
    505 
    506     u8* tlvs = pFwReq->ptlv;
    507     if (pReq->config_sid_beacon) {
    508         tlvs = addTlv(NAN_TLV_TYPE_SID_BEACON, sizeof(pReq->sid_beacon),
    509                       (const u8*)&pReq->sid_beacon, tlvs);
    510     }
    511     if (pReq->config_master_pref) {
    512         tlvs = addTlv(NAN_TLV_TYPE_MASTER_PREFERENCE, sizeof(pReq->master_pref),
    513                       (const u8*)&pReq->master_pref, tlvs);
    514     }
    515     if (pReq->config_rssi_window_size) {
    516         tlvs = addTlv(NAN_TLV_TYPE_RSSI_AVERAGING_WINDOW_SIZE, sizeof(pReq->rssi_window_size_val),
    517                       (const u8*)&pReq->rssi_window_size_val, tlvs);
    518     }
    519     if (pReq->config_rssi_proximity) {
    520         tlvs = addTlv(NAN_TLV_TYPE_24G_RSSI_CLOSE_PROXIMITY, sizeof(pReq->rssi_proximity),
    521                       (const u8*)&pReq->rssi_proximity, tlvs);
    522     }
    523     if (pReq->config_5g_rssi_close_proximity) {
    524         tlvs = addTlv(NAN_TLV_TYPE_5G_RSSI_CLOSE_PROXIMITY,
    525                       sizeof(pReq->rssi_close_proximity_5g_val),
    526                       (const u8*)&pReq->rssi_close_proximity_5g_val, tlvs);
    527     }
    528     if (pReq->config_cluster_attribute_val) {
    529         tlvs = addTlv(NAN_TLV_TYPE_CLUSTER_ATTRIBUTE_IN_SDF, sizeof(pReq->config_cluster_attribute_val),
    530                       (const u8*)&pReq->config_cluster_attribute_val, tlvs);
    531     }
    532     if (pReq->config_scan_params) {
    533         u32 socialChannelParamVal[NAN_MAX_SOCIAL_CHANNELS];
    534         /* Fill the social channel param */
    535         fillNanSocialChannelParamVal(&pReq->scan_params_val,
    536                                  socialChannelParamVal);
    537         int i;
    538         for (i = 0; i < NAN_MAX_SOCIAL_CHANNELS; i++) {
    539             tlvs = addTlv(NAN_TLV_TYPE_SOCIAL_CHANNEL_SCAN_PARAMS,
    540                           sizeof(socialChannelParamVal[i]),
    541                           (const u8*)&socialChannelParamVal[i], tlvs);
    542         }
    543     }
    544     if (pReq->config_random_factor_force) {
    545         tlvs = addTlv(NAN_TLV_TYPE_RANDOM_FACTOR_FORCE,
    546                       sizeof(pReq->random_factor_force_val),
    547                       (const u8*)&pReq->random_factor_force_val, tlvs);
    548     }
    549     if (pReq->config_hop_count_force) {
    550         tlvs = addTlv(NAN_TLV_TYPE_HOP_COUNT_FORCE,
    551                       sizeof(pReq->hop_count_force_val),
    552                       (const u8*)&pReq->hop_count_force_val, tlvs);
    553     }
    554     if (pReq->config_conn_capability) {
    555         u32 val = \
    556         getNanTransmitPostConnectivityCapabilityVal(&pReq->conn_capability_val);
    557         tlvs = addTlv(NAN_TLV_TYPE_POST_NAN_CONNECTIVITY_CAPABILITIES_TRANSMIT,
    558                       sizeof(val), (const u8*)&val, tlvs);
    559     }
    560     if (pReq->num_config_discovery_attr) {
    561         for (idx = 0; idx < pReq->num_config_discovery_attr; idx ++) {
    562             fillNanTransmitPostDiscoveryVal(&pReq->discovery_attr_val[idx],
    563                                             (u8*)(tlvs + SIZEOF_TLV_HDR));
    564             tlvs = addTlv(NAN_TLV_TYPE_POST_NAN_DISCOVERY_ATTRIBUTE_TRANSMIT,
    565                           calcNanTransmitPostDiscoverySize(
    566                               &pReq->discovery_attr_val[idx]),
    567                           (const u8*)(tlvs + SIZEOF_TLV_HDR), tlvs);
    568         }
    569     }
    570     if (pReq->config_fam && \
    571         calcNanFurtherAvailabilityMapSize(&pReq->fam_val)) {
    572         fillNanFurtherAvailabilityMapVal(&pReq->fam_val,
    573                                         (u8*)(tlvs + SIZEOF_TLV_HDR));
    574         tlvs = addTlv(NAN_TLV_TYPE_FURTHER_AVAILABILITY_MAP,
    575                       calcNanFurtherAvailabilityMapSize(&pReq->fam_val),
    576                       (const u8*)(tlvs + SIZEOF_TLV_HDR), tlvs);
    577     }
    578     if (pReq->config_dw.config_2dot4g_dw_band) {
    579         tlvs = addTlv(NAN_TLV_TYPE_2G_COMMITTED_DW,
    580                       sizeof(pReq->config_dw.dw_2dot4g_interval_val),
    581                       (const u8*)&pReq->config_dw.dw_2dot4g_interval_val, tlvs);
    582     }
    583     if (pReq->config_dw.config_5g_dw_band) {
    584         tlvs = addTlv(NAN_TLV_TYPE_5G_COMMITTED_DW,
    585                       sizeof(pReq->config_dw.dw_5g_interval_val),
    586                       (const u8*)&pReq->config_dw.dw_5g_interval_val, tlvs);
    587     }
    588     if (pReq->config_disc_mac_addr_randomization) {
    589         tlvs = addTlv(NAN_TLV_TYPE_DISC_MAC_ADDR_RANDOM_INTERVAL,
    590                       sizeof(u32),
    591                       (const u8*)&pReq->disc_mac_addr_rand_interval_sec, tlvs);
    592     }
    593     if (pReq->config_subscribe_sid_beacon) {
    594         tlvs = addTlv(NAN_TLV_TYPE_SUBSCRIBE_SID_BEACON,
    595                       sizeof(pReq->subscribe_sid_beacon_val),
    596                       (const u8*)&pReq->subscribe_sid_beacon_val, tlvs);
    597     }
    598     if (pReq->config_discovery_beacon_int) {
    599         tlvs = addTlv(NAN_TLV_TYPE_DB_INTERVAL, sizeof(u32),
    600                       (const u8*)&pReq->discovery_beacon_interval, tlvs);
    601     }
    602 
    603     u32 config_discovery_indications;
    604     config_discovery_indications = (u32)(pReq->discovery_indication_cfg);
    605     /* Always include the discovery cfg TLV as there is no cfg flag */
    606     tlvs = addTlv(NAN_TLV_TYPE_CONFIG_DISCOVERY_INDICATIONS,
    607                   sizeof(u32),
    608                   (const u8*)&config_discovery_indications, tlvs);
    609 
    610     if (pReq->config_nss) {
    611         tlvs = addTlv(NAN_TLV_TYPE_TX_RX_CHAINS, sizeof(u32),
    612                       (const u8*)&pReq->nss, tlvs);
    613     }
    614     if (pReq->config_enable_ranging) {
    615         tlvs = addTlv(NAN_TLV_TYPE_ENABLE_DEVICE_RANGING, sizeof(u32),
    616                       (const u8*)&pReq->enable_ranging, tlvs);
    617     }
    618     if (pReq->config_dw_early_termination) {
    619         tlvs = addTlv(NAN_TLV_TYPE_DW_EARLY_TERMINATION, sizeof(u32),
    620                       (const u8*)&pReq->enable_dw_termination, tlvs);
    621     }
    622 
    623     mVendorData = (char*)pFwReq;
    624     mDataLen = message_len;
    625 
    626     ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
    627     if (ret != WIFI_SUCCESS) {
    628         ALOGE("%s: put_bytes Error:%d",__func__, ret);
    629         cleanup();
    630         return ret;
    631     }
    632     hexdump(mVendorData, mDataLen);
    633     return ret;
    634 }
    635 
    636 wifi_error NanCommand::putNanPublish(transaction_id id, const NanPublishRequest *pReq)
    637 {
    638     wifi_error ret;
    639     ALOGV("NAN_PUBLISH");
    640     if (pReq == NULL) {
    641         cleanup();
    642         return WIFI_ERROR_INVALID_ARGS;
    643     }
    644 
    645     size_t message_len =
    646         sizeof(NanMsgHeader) + sizeof(NanPublishServiceReqParams) +
    647         (pReq->service_name_len ? SIZEOF_TLV_HDR + pReq->service_name_len : 0) +
    648         (pReq->service_specific_info_len ? SIZEOF_TLV_HDR + pReq->service_specific_info_len : 0) +
    649         (pReq->rx_match_filter_len ? SIZEOF_TLV_HDR + pReq->rx_match_filter_len : 0) +
    650         (pReq->tx_match_filter_len ? SIZEOF_TLV_HDR + pReq->tx_match_filter_len : 0) +
    651         (SIZEOF_TLV_HDR + sizeof(NanServiceAcceptPolicy)) +
    652         (pReq->cipher_type ? SIZEOF_TLV_HDR + sizeof(NanCsidType) : 0) +
    653         ((pReq->sdea_params.config_nan_data_path || pReq->sdea_params.security_cfg ||
    654           pReq->sdea_params.ranging_state || pReq->sdea_params.range_report ||
    655           pReq->sdea_params.qos_cfg) ?
    656           SIZEOF_TLV_HDR + sizeof(NanFWSdeaCtrlParams) : 0) +
    657         ((pReq->ranging_cfg.ranging_interval_msec || pReq->ranging_cfg.config_ranging_indications ||
    658           pReq->ranging_cfg.distance_ingress_mm || pReq->ranging_cfg.distance_egress_mm) ?
    659           SIZEOF_TLV_HDR + sizeof(NanFWRangeConfigParams) : 0) +
    660         ((pReq->range_response_cfg.publish_id ||
    661           pReq->range_response_cfg.ranging_response) ?
    662           SIZEOF_TLV_HDR + sizeof(NanFWRangeReqMsg) : 0)  +
    663         (pReq->sdea_service_specific_info_len ? SIZEOF_TLV_HDR + pReq->sdea_service_specific_info_len : 0);
    664 
    665     if ((pReq->key_info.key_type ==  NAN_SECURITY_KEY_INPUT_PMK) &&
    666         (pReq->key_info.body.pmk_info.pmk_len == NAN_PMK_INFO_LEN))
    667         message_len += SIZEOF_TLV_HDR + NAN_PMK_INFO_LEN;
    668     else if ((pReq->key_info.key_type ==  NAN_SECURITY_KEY_INPUT_PASSPHRASE) &&
    669              (pReq->key_info.body.passphrase_info.passphrase_len >=
    670               NAN_SECURITY_MIN_PASSPHRASE_LEN) &&
    671              (pReq->key_info.body.passphrase_info.passphrase_len <=
    672               NAN_SECURITY_MAX_PASSPHRASE_LEN))
    673         message_len += SIZEOF_TLV_HDR +
    674                        pReq->key_info.body.passphrase_info.passphrase_len;
    675 
    676     pNanPublishServiceReqMsg pFwReq = (pNanPublishServiceReqMsg)malloc(message_len);
    677     if (pFwReq == NULL) {
    678         cleanup();
    679         return WIFI_ERROR_OUT_OF_MEMORY;
    680     }
    681 
    682     ALOGV("Message Len %zu", message_len);
    683     memset(pFwReq, 0, message_len);
    684     pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
    685     pFwReq->fwHeader.msgId = NAN_MSG_ID_PUBLISH_SERVICE_REQ;
    686     pFwReq->fwHeader.msgLen = message_len;
    687     if (pReq->publish_id == 0) {
    688         pFwReq->fwHeader.handle = 0xFFFF;
    689     } else {
    690         pFwReq->fwHeader.handle = pReq->publish_id;
    691     }
    692     pFwReq->fwHeader.transactionId = id;
    693 
    694     pFwReq->publishServiceReqParams.ttl = pReq->ttl;
    695     pFwReq->publishServiceReqParams.period = pReq->period;
    696     pFwReq->publishServiceReqParams.replyIndFlag =
    697                                    (pReq->recv_indication_cfg & BIT_3) ? 0 : 1;
    698     pFwReq->publishServiceReqParams.publishType = pReq->publish_type;
    699     pFwReq->publishServiceReqParams.txType = pReq->tx_type;
    700 
    701     pFwReq->publishServiceReqParams.rssiThresholdFlag = pReq->rssi_threshold_flag;
    702     pFwReq->publishServiceReqParams.matchAlg = pReq->publish_match_indicator;
    703     pFwReq->publishServiceReqParams.count = pReq->publish_count;
    704     pFwReq->publishServiceReqParams.connmap = pReq->connmap;
    705     pFwReq->publishServiceReqParams.pubTerminatedIndDisableFlag =
    706                                    (pReq->recv_indication_cfg & BIT_0) ? 1 : 0;
    707     pFwReq->publishServiceReqParams.pubMatchExpiredIndDisableFlag =
    708                                    (pReq->recv_indication_cfg & BIT_1) ? 1 : 0;
    709     pFwReq->publishServiceReqParams.followupRxIndDisableFlag =
    710                                    (pReq->recv_indication_cfg & BIT_2) ? 1 : 0;
    711 
    712     pFwReq->publishServiceReqParams.reserved2 = 0;
    713 
    714     u8* tlvs = pFwReq->ptlv;
    715     if (pReq->service_name_len) {
    716         tlvs = addTlv(NAN_TLV_TYPE_SERVICE_NAME, pReq->service_name_len,
    717                       (const u8*)&pReq->service_name[0], tlvs);
    718     }
    719     if (pReq->service_specific_info_len) {
    720         tlvs = addTlv(NAN_TLV_TYPE_SERVICE_SPECIFIC_INFO, pReq->service_specific_info_len,
    721                       (const u8*)&pReq->service_specific_info[0], tlvs);
    722     }
    723     if (pReq->rx_match_filter_len) {
    724         tlvs = addTlv(NAN_TLV_TYPE_RX_MATCH_FILTER, pReq->rx_match_filter_len,
    725                       (const u8*)&pReq->rx_match_filter[0], tlvs);
    726     }
    727     if (pReq->tx_match_filter_len) {
    728         tlvs = addTlv(NAN_TLV_TYPE_TX_MATCH_FILTER, pReq->tx_match_filter_len,
    729                       (const u8*)&pReq->tx_match_filter[0], tlvs);
    730     }
    731 
    732     /* Pass the Accept policy always */
    733     tlvs = addTlv(NAN_TLV_TYPE_NAN_SERVICE_ACCEPT_POLICY, sizeof(NanServiceAcceptPolicy),
    734                   (const u8*)&pReq->service_responder_policy, tlvs);
    735 
    736     if (pReq->cipher_type) {
    737         NanCsidType pNanCsidType;
    738         pNanCsidType.csid_type = pReq->cipher_type;
    739         tlvs = addTlv(NAN_TLV_TYPE_NAN_CSID, sizeof(NanCsidType),
    740                         (const u8*)&pNanCsidType, tlvs);
    741     }
    742 
    743     if ((pReq->key_info.key_type ==  NAN_SECURITY_KEY_INPUT_PMK) &&
    744         (pReq->key_info.body.pmk_info.pmk_len == NAN_PMK_INFO_LEN)) {
    745         tlvs = addTlv(NAN_TLV_TYPE_NAN_PMK,
    746                       pReq->key_info.body.pmk_info.pmk_len,
    747                       (const u8*)&pReq->key_info.body.pmk_info.pmk[0], tlvs);
    748     } else if ((pReq->key_info.key_type == NAN_SECURITY_KEY_INPUT_PASSPHRASE) &&
    749         (pReq->key_info.body.passphrase_info.passphrase_len >=
    750          NAN_SECURITY_MIN_PASSPHRASE_LEN) &&
    751         (pReq->key_info.body.passphrase_info.passphrase_len <=
    752          NAN_SECURITY_MAX_PASSPHRASE_LEN)) {
    753         tlvs = addTlv(NAN_TLV_TYPE_NAN_PASSPHRASE,
    754                   pReq->key_info.body.passphrase_info.passphrase_len,
    755                   (const u8*)&pReq->key_info.body.passphrase_info.passphrase[0],
    756                   tlvs);
    757     }
    758 
    759     if (pReq->sdea_params.config_nan_data_path ||
    760         pReq->sdea_params.security_cfg ||
    761         pReq->sdea_params.ranging_state ||
    762         pReq->sdea_params.range_report ||
    763         pReq->sdea_params.qos_cfg) {
    764         NanFWSdeaCtrlParams pNanFWSdeaCtrlParams;
    765         memset(&pNanFWSdeaCtrlParams, 0, sizeof(NanFWSdeaCtrlParams));
    766 
    767         if (pReq->sdea_params.config_nan_data_path) {
    768             pNanFWSdeaCtrlParams.data_path_required = 1;
    769             pNanFWSdeaCtrlParams.data_path_type =
    770                                   (pReq->sdea_params.ndp_type & BIT_0) ?
    771                                   NAN_DATA_PATH_MULTICAST_MSG :
    772                                   NAN_DATA_PATH_UNICAST_MSG;
    773 
    774         }
    775         if (pReq->sdea_params.security_cfg) {
    776             pNanFWSdeaCtrlParams.security_required =
    777                                          pReq->sdea_params.security_cfg;
    778         }
    779         if (pReq->sdea_params.ranging_state) {
    780             pNanFWSdeaCtrlParams.ranging_required =
    781                                          pReq->sdea_params.ranging_state;
    782         }
    783         if (pReq->sdea_params.range_report) {
    784             pNanFWSdeaCtrlParams.range_report =
    785                 (((pReq->sdea_params.range_report & NAN_ENABLE_RANGE_REPORT) >> 1) ? 1 : 0);
    786         }
    787         if (pReq->sdea_params.qos_cfg) {
    788             pNanFWSdeaCtrlParams.qos_required = pReq->sdea_params.qos_cfg;
    789         }
    790         tlvs = addTlv(NAN_TLV_TYPE_SDEA_CTRL_PARAMS, sizeof(NanFWSdeaCtrlParams),
    791                         (const u8*)&pNanFWSdeaCtrlParams, tlvs);
    792     }
    793 
    794     if (pReq->ranging_cfg.ranging_interval_msec ||
    795         pReq->ranging_cfg.config_ranging_indications ||
    796         pReq->ranging_cfg.distance_ingress_mm ||
    797         pReq->ranging_cfg.distance_egress_mm) {
    798         NanFWRangeConfigParams pNanFWRangingCfg;
    799 
    800         memset(&pNanFWRangingCfg, 0, sizeof(NanFWRangeConfigParams));
    801         pNanFWRangingCfg.range_interval =
    802                                 pReq->ranging_cfg.ranging_interval_msec;
    803         pNanFWRangingCfg.ranging_indication_event =
    804             ((pReq->ranging_cfg.config_ranging_indications & NAN_RANGING_INDICATE_CONTINUOUS_MASK) |
    805             (pReq->ranging_cfg.config_ranging_indications & NAN_RANGING_INDICATE_INGRESS_MET_MASK) |
    806             (pReq->ranging_cfg.config_ranging_indications & NAN_RANGING_INDICATE_EGRESS_MET_MASK));
    807 
    808         pNanFWRangingCfg.ranging_indication_event = pReq->ranging_cfg.config_ranging_indications;
    809         if (pReq->ranging_cfg.config_ranging_indications & NAN_RANGING_INDICATE_INGRESS_MET_MASK)
    810             pNanFWRangingCfg.geo_fence_threshold.inner_threshold =
    811                                         pReq->ranging_cfg.distance_ingress_mm;
    812         if (pReq->ranging_cfg.config_ranging_indications & NAN_RANGING_INDICATE_EGRESS_MET_MASK)
    813             pNanFWRangingCfg.geo_fence_threshold.outer_threshold =
    814                                        pReq->ranging_cfg.distance_egress_mm;
    815         tlvs = addTlv(NAN_TLV_TYPE_NAN_RANGING_CFG, sizeof(NanFWRangeConfigParams),
    816                                                     (const u8*)&pNanFWRangingCfg, tlvs);
    817     }
    818 
    819     if (pReq->sdea_service_specific_info_len) {
    820         tlvs = addTlv(NAN_TLV_TYPE_SDEA_SERVICE_SPECIFIC_INFO, pReq->sdea_service_specific_info_len,
    821                       (const u8*)&pReq->sdea_service_specific_info[0], tlvs);
    822     }
    823 
    824     if (pReq->range_response_cfg.publish_id || pReq->range_response_cfg.ranging_response) {
    825 
    826         NanFWRangeReqMsg pNanFWRangeReqMsg;
    827         memset(&pNanFWRangeReqMsg, 0, sizeof(NanFWRangeReqMsg));
    828         pNanFWRangeReqMsg.range_id =
    829                                 (u16)pReq->range_response_cfg.publish_id;
    830         CHAR_ARRAY_TO_MAC_ADDR(pReq->range_response_cfg.peer_addr, pNanFWRangeReqMsg.range_mac_addr);
    831         pNanFWRangeReqMsg.ranging_accept =
    832             ((pReq->range_response_cfg.ranging_response == NAN_RANGE_REQUEST_ACCEPT) ? 1 : 0);
    833         pNanFWRangeReqMsg.ranging_reject =
    834             ((pReq->range_response_cfg.ranging_response == NAN_RANGE_REQUEST_REJECT) ? 1 : 0);
    835         pNanFWRangeReqMsg.ranging_cancel =
    836             ((pReq->range_response_cfg.ranging_response == NAN_RANGE_REQUEST_CANCEL) ? 1 : 0);
    837         tlvs = addTlv(NAN_TLV_TYPE_NAN20_RANGING_REQUEST, sizeof(NanFWRangeReqMsg),
    838                                                     (const u8*)&pNanFWRangeReqMsg, tlvs);
    839     }
    840 
    841     mVendorData = (char *)pFwReq;
    842     mDataLen = message_len;
    843 
    844     ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
    845     if (ret != WIFI_SUCCESS) {
    846         ALOGE("%s: put_bytes Error:%d",__func__, ret);
    847         cleanup();
    848         return ret;
    849     }
    850     hexdump(mVendorData, mDataLen);
    851     return ret;
    852 }
    853 
    854 wifi_error NanCommand::putNanPublishCancel(transaction_id id, const NanPublishCancelRequest *pReq)
    855 {
    856     wifi_error ret;
    857     ALOGV("NAN_PUBLISH_CANCEL");
    858     if (pReq == NULL) {
    859         cleanup();
    860         return WIFI_ERROR_INVALID_ARGS;
    861     }
    862     size_t message_len = sizeof(NanPublishServiceCancelReqMsg);
    863 
    864     pNanPublishServiceCancelReqMsg pFwReq =
    865         (pNanPublishServiceCancelReqMsg)malloc(message_len);
    866     if (pFwReq == NULL) {
    867         cleanup();
    868         return WIFI_ERROR_OUT_OF_MEMORY;
    869     }
    870 
    871     ALOGV("Message Len %zu", message_len);
    872     memset(pFwReq, 0, message_len);
    873     pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
    874     pFwReq->fwHeader.msgId = NAN_MSG_ID_PUBLISH_SERVICE_CANCEL_REQ;
    875     pFwReq->fwHeader.msgLen = message_len;
    876     pFwReq->fwHeader.handle = pReq->publish_id;
    877     pFwReq->fwHeader.transactionId = id;
    878 
    879     mVendorData = (char *)pFwReq;
    880     mDataLen = message_len;
    881 
    882     ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
    883     if (ret != WIFI_SUCCESS) {
    884         ALOGE("%s: put_bytes Error:%d",__func__, ret);
    885         cleanup();
    886         return ret;
    887     }
    888     hexdump(mVendorData, mDataLen);
    889     return ret;
    890 }
    891 
    892 wifi_error NanCommand::putNanSubscribe(transaction_id id,
    893                                 const NanSubscribeRequest *pReq)
    894 {
    895     wifi_error ret;
    896 
    897     ALOGV("NAN_SUBSCRIBE");
    898     if (pReq == NULL) {
    899         cleanup();
    900         return WIFI_ERROR_INVALID_ARGS;
    901     }
    902 
    903     size_t message_len =
    904         sizeof(NanMsgHeader) + sizeof(NanSubscribeServiceReqParams) +
    905         (pReq->service_name_len ? SIZEOF_TLV_HDR + pReq->service_name_len : 0) +
    906         (pReq->service_specific_info_len ? SIZEOF_TLV_HDR + pReq->service_specific_info_len : 0) +
    907         (pReq->rx_match_filter_len ? SIZEOF_TLV_HDR + pReq->rx_match_filter_len : 0) +
    908         (pReq->tx_match_filter_len ? SIZEOF_TLV_HDR + pReq->tx_match_filter_len : 0) +
    909         (pReq->cipher_type ? SIZEOF_TLV_HDR + sizeof(NanCsidType) : 0) +
    910         ((pReq->sdea_params.config_nan_data_path || pReq->sdea_params.security_cfg ||
    911           pReq->sdea_params.ranging_state || pReq->sdea_params.range_report ||
    912           pReq->sdea_params.qos_cfg) ?
    913           SIZEOF_TLV_HDR + sizeof(NanFWSdeaCtrlParams) : 0) +
    914         ((pReq->ranging_cfg.ranging_interval_msec || pReq->ranging_cfg.config_ranging_indications ||
    915           pReq->ranging_cfg.distance_ingress_mm || pReq->ranging_cfg.distance_egress_mm) ?
    916           SIZEOF_TLV_HDR + sizeof(NanFWRangeConfigParams) : 0) +
    917         ((pReq->range_response_cfg.requestor_instance_id ||
    918           pReq->range_response_cfg.ranging_response) ?
    919           SIZEOF_TLV_HDR + sizeof(NanFWRangeReqMsg) : 0) +
    920         (pReq->sdea_service_specific_info_len ? SIZEOF_TLV_HDR + pReq->sdea_service_specific_info_len : 0);
    921 
    922     message_len += \
    923         (pReq->num_intf_addr_present * (SIZEOF_TLV_HDR + NAN_MAC_ADDR_LEN));
    924 
    925 
    926     if ((pReq->key_info.key_type ==  NAN_SECURITY_KEY_INPUT_PMK) &&
    927         (pReq->key_info.body.pmk_info.pmk_len == NAN_PMK_INFO_LEN))
    928         message_len += SIZEOF_TLV_HDR + NAN_PMK_INFO_LEN;
    929     else if ((pReq->key_info.key_type ==  NAN_SECURITY_KEY_INPUT_PASSPHRASE) &&
    930              (pReq->key_info.body.passphrase_info.passphrase_len >=
    931               NAN_SECURITY_MIN_PASSPHRASE_LEN) &&
    932              (pReq->key_info.body.passphrase_info.passphrase_len <=
    933               NAN_SECURITY_MAX_PASSPHRASE_LEN))
    934         message_len += SIZEOF_TLV_HDR +
    935                        pReq->key_info.body.passphrase_info.passphrase_len;
    936 
    937 
    938     pNanSubscribeServiceReqMsg pFwReq = (pNanSubscribeServiceReqMsg)malloc(message_len);
    939     if (pFwReq == NULL) {
    940         cleanup();
    941         return WIFI_ERROR_OUT_OF_MEMORY;
    942     }
    943 
    944     ALOGV("Message Len %zu", message_len);
    945     memset(pFwReq, 0, message_len);
    946     pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
    947     pFwReq->fwHeader.msgId = NAN_MSG_ID_SUBSCRIBE_SERVICE_REQ;
    948     pFwReq->fwHeader.msgLen = message_len;
    949     if (pReq->subscribe_id == 0) {
    950         pFwReq->fwHeader.handle = 0xFFFF;
    951     } else {
    952         pFwReq->fwHeader.handle = pReq->subscribe_id;
    953     }
    954     pFwReq->fwHeader.transactionId = id;
    955 
    956     pFwReq->subscribeServiceReqParams.ttl = pReq->ttl;
    957     pFwReq->subscribeServiceReqParams.period = pReq->period;
    958     pFwReq->subscribeServiceReqParams.subscribeType = pReq->subscribe_type;
    959     pFwReq->subscribeServiceReqParams.srfAttr = pReq->serviceResponseFilter;
    960     pFwReq->subscribeServiceReqParams.srfInclude = pReq->serviceResponseInclude;
    961     pFwReq->subscribeServiceReqParams.srfSend = pReq->useServiceResponseFilter;
    962     pFwReq->subscribeServiceReqParams.ssiRequired = pReq->ssiRequiredForMatchIndication;
    963     pFwReq->subscribeServiceReqParams.matchAlg = pReq->subscribe_match_indicator;
    964     pFwReq->subscribeServiceReqParams.count = pReq->subscribe_count;
    965     pFwReq->subscribeServiceReqParams.rssiThresholdFlag = pReq->rssi_threshold_flag;
    966     pFwReq->subscribeServiceReqParams.subTerminatedIndDisableFlag =
    967                                    (pReq->recv_indication_cfg & BIT_0) ? 1 : 0;
    968     pFwReq->subscribeServiceReqParams.subMatchExpiredIndDisableFlag =
    969                                    (pReq->recv_indication_cfg & BIT_1) ? 1 : 0;
    970     pFwReq->subscribeServiceReqParams.followupRxIndDisableFlag =
    971                                    (pReq->recv_indication_cfg & BIT_2) ? 1 : 0;
    972     pFwReq->subscribeServiceReqParams.connmap = pReq->connmap;
    973     pFwReq->subscribeServiceReqParams.reserved = 0;
    974 
    975     u8* tlvs = pFwReq->ptlv;
    976     if (pReq->service_name_len) {
    977         tlvs = addTlv(NAN_TLV_TYPE_SERVICE_NAME, pReq->service_name_len,
    978                       (const u8*)&pReq->service_name[0], tlvs);
    979     }
    980     if (pReq->service_specific_info_len) {
    981         tlvs = addTlv(NAN_TLV_TYPE_SERVICE_SPECIFIC_INFO, pReq->service_specific_info_len,
    982                       (const u8*)&pReq->service_specific_info[0], tlvs);
    983     }
    984     if (pReq->rx_match_filter_len) {
    985         tlvs = addTlv(NAN_TLV_TYPE_RX_MATCH_FILTER, pReq->rx_match_filter_len,
    986                       (const u8*)&pReq->rx_match_filter[0], tlvs);
    987     }
    988     if (pReq->tx_match_filter_len) {
    989         tlvs = addTlv(NAN_TLV_TYPE_TX_MATCH_FILTER, pReq->tx_match_filter_len,
    990                       (const u8*)&pReq->tx_match_filter[0], tlvs);
    991     }
    992 
    993     int i = 0;
    994     for (i = 0; i < pReq->num_intf_addr_present; i++)
    995     {
    996         tlvs = addTlv(NAN_TLV_TYPE_MAC_ADDRESS,
    997                       NAN_MAC_ADDR_LEN,
    998                       (const u8*)&pReq->intf_addr[i][0], tlvs);
    999     }
   1000 
   1001     if (pReq->cipher_type) {
   1002         NanCsidType pNanCsidType;
   1003         pNanCsidType.csid_type = pReq->cipher_type;
   1004         tlvs = addTlv(NAN_TLV_TYPE_NAN_CSID, sizeof(NanCsidType),
   1005                         (const u8*)&pNanCsidType, tlvs);
   1006     }
   1007 
   1008     if ((pReq->key_info.key_type ==  NAN_SECURITY_KEY_INPUT_PMK) &&
   1009         (pReq->key_info.body.pmk_info.pmk_len == NAN_PMK_INFO_LEN)) {
   1010         tlvs = addTlv(NAN_TLV_TYPE_NAN_PMK,
   1011                       pReq->key_info.body.pmk_info.pmk_len,
   1012                       (const u8*)&pReq->key_info.body.pmk_info.pmk[0], tlvs);
   1013     } else if ((pReq->key_info.key_type == NAN_SECURITY_KEY_INPUT_PASSPHRASE) &&
   1014         (pReq->key_info.body.passphrase_info.passphrase_len >=
   1015          NAN_SECURITY_MIN_PASSPHRASE_LEN) &&
   1016         (pReq->key_info.body.passphrase_info.passphrase_len <=
   1017          NAN_SECURITY_MAX_PASSPHRASE_LEN)) {
   1018         tlvs = addTlv(NAN_TLV_TYPE_NAN_PASSPHRASE,
   1019                   pReq->key_info.body.passphrase_info.passphrase_len,
   1020                   (const u8*)&pReq->key_info.body.passphrase_info.passphrase[0],
   1021                   tlvs);
   1022     }
   1023 
   1024     if (pReq->sdea_params.config_nan_data_path ||
   1025         pReq->sdea_params.security_cfg ||
   1026         pReq->sdea_params.ranging_state ||
   1027         pReq->sdea_params.range_report ||
   1028         pReq->sdea_params.qos_cfg) {
   1029         NanFWSdeaCtrlParams pNanFWSdeaCtrlParams;
   1030         memset(&pNanFWSdeaCtrlParams, 0, sizeof(NanFWSdeaCtrlParams));
   1031 
   1032         if (pReq->sdea_params.config_nan_data_path) {
   1033             pNanFWSdeaCtrlParams.data_path_required = 1;
   1034             pNanFWSdeaCtrlParams.data_path_type =
   1035                                   (pReq->sdea_params.ndp_type & BIT_0) ?
   1036                                   NAN_DATA_PATH_MULTICAST_MSG :
   1037                                   NAN_DATA_PATH_UNICAST_MSG;
   1038 
   1039         }
   1040         if (pReq->sdea_params.security_cfg) {
   1041             pNanFWSdeaCtrlParams.security_required =
   1042                                          pReq->sdea_params.security_cfg;
   1043         }
   1044         if (pReq->sdea_params.ranging_state) {
   1045             pNanFWSdeaCtrlParams.ranging_required =
   1046                                          pReq->sdea_params.ranging_state;
   1047         }
   1048         if (pReq->sdea_params.range_report) {
   1049             pNanFWSdeaCtrlParams.range_report =
   1050                 ((pReq->sdea_params.range_report & NAN_ENABLE_RANGE_REPORT >> 1) ? 1 : 0);
   1051         }
   1052         if (pReq->sdea_params.qos_cfg) {
   1053             pNanFWSdeaCtrlParams.qos_required = pReq->sdea_params.qos_cfg;
   1054         }
   1055         tlvs = addTlv(NAN_TLV_TYPE_SDEA_CTRL_PARAMS, sizeof(NanFWSdeaCtrlParams),
   1056                         (const u8*)&pNanFWSdeaCtrlParams, tlvs);
   1057 
   1058     }
   1059 
   1060     if (pReq->ranging_cfg.ranging_interval_msec || pReq->ranging_cfg.config_ranging_indications || pReq->ranging_cfg.distance_ingress_mm
   1061         || pReq->ranging_cfg.distance_egress_mm) {
   1062         NanFWRangeConfigParams pNanFWRangingCfg;
   1063         memset(&pNanFWRangingCfg, 0, sizeof(NanFWRangeConfigParams));
   1064         pNanFWRangingCfg.range_interval =
   1065                                 pReq->ranging_cfg.ranging_interval_msec;
   1066         pNanFWRangingCfg.ranging_indication_event =
   1067             ((pReq->ranging_cfg.config_ranging_indications & NAN_RANGING_INDICATE_CONTINUOUS_MASK) |
   1068             (pReq->ranging_cfg.config_ranging_indications & NAN_RANGING_INDICATE_INGRESS_MET_MASK) |
   1069             (pReq->ranging_cfg.config_ranging_indications & NAN_RANGING_INDICATE_EGRESS_MET_MASK));
   1070 
   1071         pNanFWRangingCfg.ranging_indication_event =
   1072                                           pReq->ranging_cfg.config_ranging_indications;
   1073         if (pReq->ranging_cfg.config_ranging_indications & NAN_RANGING_INDICATE_INGRESS_MET_MASK)
   1074             pNanFWRangingCfg.geo_fence_threshold.inner_threshold =
   1075                                         pReq->ranging_cfg.distance_ingress_mm;
   1076         if (pReq->ranging_cfg.config_ranging_indications & NAN_RANGING_INDICATE_EGRESS_MET_MASK)
   1077             pNanFWRangingCfg.geo_fence_threshold.outer_threshold =
   1078                                        pReq->ranging_cfg.distance_egress_mm;
   1079         tlvs = addTlv(NAN_TLV_TYPE_NAN_RANGING_CFG, sizeof(NanFWRangeConfigParams),
   1080                                                     (const u8*)&pNanFWRangingCfg, tlvs);
   1081     }
   1082 
   1083     if (pReq->sdea_service_specific_info_len) {
   1084         tlvs = addTlv(NAN_TLV_TYPE_SDEA_SERVICE_SPECIFIC_INFO, pReq->sdea_service_specific_info_len,
   1085                       (const u8*)&pReq->sdea_service_specific_info[0], tlvs);
   1086     }
   1087 
   1088     if (pReq->range_response_cfg.requestor_instance_id || pReq->range_response_cfg.ranging_response) {
   1089         NanFWRangeReqMsg pNanFWRangeReqMsg;
   1090         memset(&pNanFWRangeReqMsg, 0, sizeof(NanFWRangeReqMsg));
   1091         pNanFWRangeReqMsg.range_id =
   1092                                 pReq->range_response_cfg.requestor_instance_id;
   1093         memcpy(&pNanFWRangeReqMsg.range_mac_addr, &pReq->range_response_cfg.peer_addr, NAN_MAC_ADDR_LEN);
   1094         pNanFWRangeReqMsg.ranging_accept =
   1095             ((pReq->range_response_cfg.ranging_response == NAN_RANGE_REQUEST_ACCEPT) ? 1 : 0);
   1096         pNanFWRangeReqMsg.ranging_reject =
   1097             ((pReq->range_response_cfg.ranging_response == NAN_RANGE_REQUEST_REJECT) ? 1 : 0);
   1098         pNanFWRangeReqMsg.ranging_cancel =
   1099             ((pReq->range_response_cfg.ranging_response == NAN_RANGE_REQUEST_CANCEL) ? 1 : 0);
   1100         tlvs = addTlv(NAN_TLV_TYPE_NAN20_RANGING_REQUEST, sizeof(NanFWRangeReqMsg),
   1101                                                     (const u8*)&pNanFWRangeReqMsg, tlvs);
   1102     }
   1103 
   1104     mVendorData = (char *)pFwReq;
   1105     mDataLen = message_len;
   1106     ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
   1107     if (ret != WIFI_SUCCESS) {
   1108         ALOGE("%s: put_bytes Error:%d",__func__, ret);
   1109         cleanup();
   1110         return ret;
   1111     }
   1112     hexdump(mVendorData, mDataLen);
   1113     return ret;
   1114 }
   1115 
   1116 wifi_error NanCommand::putNanSubscribeCancel(transaction_id id,
   1117                                       const NanSubscribeCancelRequest *pReq)
   1118 {
   1119     wifi_error ret;
   1120     ALOGV("NAN_SUBSCRIBE_CANCEL");
   1121     if (pReq == NULL) {
   1122         cleanup();
   1123         return WIFI_ERROR_INVALID_ARGS;
   1124     }
   1125     size_t message_len = sizeof(NanSubscribeServiceCancelReqMsg);
   1126 
   1127     pNanSubscribeServiceCancelReqMsg pFwReq =
   1128         (pNanSubscribeServiceCancelReqMsg)malloc(message_len);
   1129     if (pFwReq == NULL) {
   1130         cleanup();
   1131         return WIFI_ERROR_OUT_OF_MEMORY;
   1132     }
   1133 
   1134     ALOGV("Message Len %zu", message_len);
   1135     memset(pFwReq, 0, message_len);
   1136     pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
   1137     pFwReq->fwHeader.msgId = NAN_MSG_ID_SUBSCRIBE_SERVICE_CANCEL_REQ;
   1138     pFwReq->fwHeader.msgLen = message_len;
   1139     pFwReq->fwHeader.handle = pReq->subscribe_id;
   1140     pFwReq->fwHeader.transactionId = id;
   1141 
   1142     mVendorData = (char *)pFwReq;
   1143     mDataLen = message_len;
   1144     ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
   1145     if (ret != WIFI_SUCCESS) {
   1146         ALOGE("%s: put_bytes Error:%d",__func__, ret);
   1147         cleanup();
   1148         return ret;
   1149     }
   1150     hexdump(mVendorData, mDataLen);
   1151     return ret;
   1152 }
   1153 
   1154 wifi_error NanCommand::putNanTransmitFollowup(transaction_id id,
   1155                                        const NanTransmitFollowupRequest *pReq)
   1156 {
   1157     wifi_error ret;
   1158     ALOGV("TRANSMIT_FOLLOWUP");
   1159     if (pReq == NULL) {
   1160         cleanup();
   1161         return WIFI_ERROR_INVALID_ARGS;
   1162     }
   1163 
   1164     size_t message_len =
   1165         sizeof(NanMsgHeader) + sizeof(NanTransmitFollowupReqParams) +
   1166         (pReq->service_specific_info_len ? SIZEOF_TLV_HDR +
   1167          pReq->service_specific_info_len : 0) +
   1168         (pReq->sdea_service_specific_info_len ? SIZEOF_TLV_HDR + pReq->sdea_service_specific_info_len : 0);
   1169 
   1170     /* Mac address needs to be added in TLV */
   1171     message_len += (SIZEOF_TLV_HDR + sizeof(pReq->addr));
   1172 
   1173     pNanTransmitFollowupReqMsg pFwReq = (pNanTransmitFollowupReqMsg)malloc(message_len);
   1174     if (pFwReq == NULL) {
   1175         cleanup();
   1176         return WIFI_ERROR_OUT_OF_MEMORY;
   1177     }
   1178 
   1179     ALOGV("Message Len %zu", message_len);
   1180     memset (pFwReq, 0, message_len);
   1181     pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
   1182     pFwReq->fwHeader.msgId = NAN_MSG_ID_TRANSMIT_FOLLOWUP_REQ;
   1183     pFwReq->fwHeader.msgLen = message_len;
   1184     pFwReq->fwHeader.handle = pReq->publish_subscribe_id;
   1185     pFwReq->fwHeader.transactionId = id;
   1186 
   1187     pFwReq->transmitFollowupReqParams.matchHandle = pReq->requestor_instance_id;
   1188     if (pReq->priority != NAN_TX_PRIORITY_HIGH) {
   1189         pFwReq->transmitFollowupReqParams.priority = 1;
   1190     } else {
   1191         pFwReq->transmitFollowupReqParams.priority = 2;
   1192     }
   1193     pFwReq->transmitFollowupReqParams.window = pReq->dw_or_faw;
   1194     pFwReq->transmitFollowupReqParams.followupTxRspDisableFlag =
   1195                                    (pReq->recv_indication_cfg & BIT_0) ? 1 : 0;
   1196     pFwReq->transmitFollowupReqParams.reserved = 0;
   1197 
   1198     u8* tlvs = pFwReq->ptlv;
   1199 
   1200     /* Mac address needs to be added in TLV */
   1201     tlvs = addTlv(NAN_TLV_TYPE_MAC_ADDRESS, sizeof(pReq->addr),
   1202                   (const u8*)&pReq->addr[0], tlvs);
   1203     u16 tlv_type = NAN_TLV_TYPE_SERVICE_SPECIFIC_INFO;
   1204 
   1205     if (pReq->service_specific_info_len) {
   1206         tlvs = addTlv(tlv_type, pReq->service_specific_info_len,
   1207                       (const u8*)&pReq->service_specific_info[0], tlvs);
   1208     }
   1209 
   1210     if (pReq->sdea_service_specific_info_len) {
   1211         tlvs = addTlv(NAN_TLV_TYPE_SDEA_SERVICE_SPECIFIC_INFO, pReq->sdea_service_specific_info_len,
   1212                       (const u8*)&pReq->sdea_service_specific_info[0], tlvs);
   1213     }
   1214 
   1215     mVendorData = (char *)pFwReq;
   1216     mDataLen = message_len;
   1217 
   1218     ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
   1219     if (ret != WIFI_SUCCESS) {
   1220         ALOGE("%s: put_bytes Error:%d",__func__, ret);
   1221         cleanup();
   1222         return ret;
   1223     }
   1224     hexdump(mVendorData, mDataLen);
   1225     return ret;
   1226 }
   1227 
   1228 wifi_error NanCommand::putNanStats(transaction_id id, const NanStatsRequest *pReq)
   1229 {
   1230     wifi_error ret;
   1231     ALOGV("NAN_STATS");
   1232     if (pReq == NULL) {
   1233         cleanup();
   1234         return WIFI_ERROR_INVALID_ARGS;
   1235     }
   1236     size_t message_len = sizeof(NanStatsReqMsg);
   1237 
   1238     pNanStatsReqMsg pFwReq =
   1239         (pNanStatsReqMsg)malloc(message_len);
   1240     if (pFwReq == NULL) {
   1241         cleanup();
   1242         return WIFI_ERROR_OUT_OF_MEMORY;
   1243     }
   1244 
   1245     ALOGV("Message Len %zu", message_len);
   1246     memset(pFwReq, 0, message_len);
   1247     pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
   1248     pFwReq->fwHeader.msgId = NAN_MSG_ID_STATS_REQ;
   1249     pFwReq->fwHeader.msgLen = message_len;
   1250     pFwReq->fwHeader.transactionId = id;
   1251 
   1252     pFwReq->statsReqParams.statsType = pReq->stats_type;
   1253     pFwReq->statsReqParams.clear = pReq->clear;
   1254     pFwReq->statsReqParams.reserved = 0;
   1255 
   1256     mVendorData = (char *)pFwReq;
   1257     mDataLen = message_len;
   1258 
   1259     ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
   1260     if (ret != WIFI_SUCCESS) {
   1261         ALOGE("%s: put_bytes Error:%d",__func__, ret);
   1262         cleanup();
   1263         return ret;
   1264     }
   1265     hexdump(mVendorData, mDataLen);
   1266     return ret;
   1267 }
   1268 
   1269 wifi_error NanCommand::putNanTCA(transaction_id id, const NanTCARequest *pReq)
   1270 {
   1271     wifi_error ret;
   1272     ALOGV("NAN_TCA");
   1273     if (pReq == NULL) {
   1274         cleanup();
   1275         return WIFI_ERROR_INVALID_ARGS;
   1276     }
   1277     size_t message_len = sizeof(NanTcaReqMsg);
   1278 
   1279     message_len += (SIZEOF_TLV_HDR + 2 * sizeof(u32));
   1280     pNanTcaReqMsg pFwReq =
   1281         (pNanTcaReqMsg)malloc(message_len);
   1282     if (pFwReq == NULL) {
   1283         cleanup();
   1284         return WIFI_ERROR_OUT_OF_MEMORY;
   1285     }
   1286 
   1287     ALOGV("Message Len %zu", message_len);
   1288     memset(pFwReq, 0, message_len);
   1289     pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
   1290     pFwReq->fwHeader.msgId = NAN_MSG_ID_TCA_REQ;
   1291     pFwReq->fwHeader.msgLen = message_len;
   1292     pFwReq->fwHeader.transactionId = id;
   1293 
   1294     u32 tcaReqParams[2];
   1295     memset (tcaReqParams, 0, sizeof(tcaReqParams));
   1296     tcaReqParams[0] = (pReq->rising_direction_evt_flag & 0x01);
   1297     tcaReqParams[0] |= (pReq->falling_direction_evt_flag & 0x01) << 1;
   1298     tcaReqParams[0] |= (pReq->clear & 0x01) << 2;
   1299     tcaReqParams[1] = pReq->threshold;
   1300 
   1301     u8* tlvs = pFwReq->ptlv;
   1302 
   1303     if (pReq->tca_type == NAN_TCA_ID_CLUSTER_SIZE) {
   1304         tlvs = addTlv(NAN_TLV_TYPE_CLUSTER_SIZE_REQ, sizeof(tcaReqParams),
   1305                       (const u8*)&tcaReqParams[0], tlvs);
   1306     } else {
   1307         ALOGE("%s: Unrecognized tca_type:%u", __FUNCTION__, pReq->tca_type);
   1308         cleanup();
   1309         return WIFI_ERROR_INVALID_ARGS;
   1310     }
   1311 
   1312     mVendorData = (char *)pFwReq;
   1313     mDataLen = message_len;
   1314 
   1315     ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
   1316     if (ret != WIFI_SUCCESS) {
   1317         ALOGE("%s: put_bytes Error:%d",__func__, ret);
   1318         cleanup();
   1319         return ret;
   1320     }
   1321     hexdump(mVendorData, mDataLen);
   1322     return ret;
   1323 }
   1324 
   1325 wifi_error NanCommand::putNanBeaconSdfPayload(transaction_id id,
   1326                                        const NanBeaconSdfPayloadRequest *pReq)
   1327 {
   1328     wifi_error ret;
   1329     ALOGV("NAN_BEACON_SDF_PAYLAOD");
   1330     if (pReq == NULL) {
   1331         cleanup();
   1332         return WIFI_ERROR_INVALID_ARGS;
   1333     }
   1334     size_t message_len = sizeof(NanMsgHeader) + \
   1335         SIZEOF_TLV_HDR + sizeof(u32) + \
   1336         pReq->vsa.vsa_len;
   1337 
   1338     pNanBeaconSdfPayloadReqMsg pFwReq =
   1339         (pNanBeaconSdfPayloadReqMsg)malloc(message_len);
   1340     if (pFwReq == NULL) {
   1341         cleanup();
   1342         return WIFI_ERROR_OUT_OF_MEMORY;
   1343     }
   1344 
   1345     ALOGV("Message Len %zu", message_len);
   1346     memset(pFwReq, 0, message_len);
   1347     pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
   1348     pFwReq->fwHeader.msgId = NAN_MSG_ID_BEACON_SDF_REQ;
   1349     pFwReq->fwHeader.msgLen = message_len;
   1350     pFwReq->fwHeader.transactionId = id;
   1351 
   1352     /* Construct First 4 bytes of NanBeaconSdfPayloadReqMsg */
   1353     u32 temp = 0;
   1354     temp = pReq->vsa.payload_transmit_flag & 0x01;
   1355     temp |= (pReq->vsa.tx_in_discovery_beacon & 0x01) << 1;
   1356     temp |= (pReq->vsa.tx_in_sync_beacon & 0x01) << 2;
   1357     temp |= (pReq->vsa.tx_in_service_discovery & 0x01) << 3;
   1358     temp |= (pReq->vsa.vendor_oui & 0x00FFFFFF) << 8;
   1359 
   1360     int tlv_len = sizeof(u32) + pReq->vsa.vsa_len;
   1361     u8* tempBuf = (u8*)malloc(tlv_len);
   1362     if (tempBuf == NULL) {
   1363         ALOGE("%s: Malloc failed", __func__);
   1364         free(pFwReq);
   1365         cleanup();
   1366         return WIFI_ERROR_OUT_OF_MEMORY;
   1367     }
   1368     memset(tempBuf, 0, tlv_len);
   1369     memcpy(tempBuf, &temp, sizeof(u32));
   1370     memcpy((tempBuf + sizeof(u32)), pReq->vsa.vsa, pReq->vsa.vsa_len);
   1371 
   1372     u8* tlvs = pFwReq->ptlv;
   1373 
   1374     /* Write the TLVs to the message. */
   1375     tlvs = addTlv(NAN_TLV_TYPE_VENDOR_SPECIFIC_ATTRIBUTE_TRANSMIT, tlv_len,
   1376                   (const u8*)tempBuf, tlvs);
   1377     free(tempBuf);
   1378 
   1379     mVendorData = (char *)pFwReq;
   1380     mDataLen = message_len;
   1381 
   1382     ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
   1383     if (ret != WIFI_SUCCESS) {
   1384         ALOGE("%s: put_bytes Error:%d",__func__, ret);
   1385         cleanup();
   1386         return ret;
   1387     }
   1388     hexdump(mVendorData, mDataLen);
   1389     return ret;
   1390 }
   1391 
   1392 //callback handlers registered for nl message send
   1393 static int error_handler_nan(struct sockaddr_nl *nla, struct nlmsgerr *err,
   1394                          void *arg)
   1395 {
   1396     struct sockaddr_nl * tmp;
   1397     int *ret = (int *)arg;
   1398     tmp = nla;
   1399     *ret = err->error;
   1400     ALOGE("%s: Error code:%d (%s)", __func__, *ret, strerror(-(*ret)));
   1401     return NL_STOP;
   1402 }
   1403 
   1404 //callback handlers registered for nl message send
   1405 static int ack_handler_nan(struct nl_msg *msg, void *arg)
   1406 {
   1407     int *ret = (int *)arg;
   1408     struct nl_msg * a;
   1409 
   1410     ALOGE("%s: called", __func__);
   1411     a = msg;
   1412     *ret = 0;
   1413     return NL_STOP;
   1414 }
   1415 
   1416 //callback handlers registered for nl message send
   1417 static int finish_handler_nan(struct nl_msg *msg, void *arg)
   1418 {
   1419   int *ret = (int *)arg;
   1420   struct nl_msg * a;
   1421 
   1422   ALOGE("%s: called", __func__);
   1423   a = msg;
   1424   *ret = 0;
   1425   return NL_SKIP;
   1426 }
   1427 
   1428 
   1429 //Override base class requestEvent and implement little differently here
   1430 //This will send the request message
   1431 //We dont wait for any response back in case of Nan as it is asynchronous
   1432 //thus no wait for condition.
   1433 wifi_error NanCommand::requestEvent()
   1434 {
   1435     wifi_error res;
   1436     int status;
   1437     struct nl_cb * cb;
   1438 
   1439     cb = nl_cb_alloc(NL_CB_DEFAULT);
   1440     if (!cb) {
   1441         ALOGE("%s: Callback allocation failed",__func__);
   1442         res = WIFI_ERROR_OUT_OF_MEMORY;
   1443         goto out;
   1444     }
   1445 
   1446     if (!mInfo->cmd_sock) {
   1447         ALOGE("%s: Command socket is null",__func__);
   1448         res = WIFI_ERROR_OUT_OF_MEMORY;
   1449         goto out;
   1450     }
   1451 
   1452     /* send message */
   1453     ALOGV("%s:Handle:%p Socket Value:%p", __func__, mInfo, mInfo->cmd_sock);
   1454     status = nl_send_auto_complete(mInfo->cmd_sock, mMsg.getMessage());
   1455     if (status < 0) {
   1456         res = mapKernelErrortoWifiHalError(status);
   1457         goto out;
   1458     }
   1459 
   1460     status = 1;
   1461 
   1462     nl_cb_err(cb, NL_CB_CUSTOM, error_handler_nan, &status);
   1463     nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler_nan, &status);
   1464     nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler_nan, &status);
   1465 
   1466     // err is populated as part of finish_handler
   1467     while (status > 0)
   1468         nl_recvmsgs(mInfo->cmd_sock, cb);
   1469 
   1470     res = mapKernelErrortoWifiHalError(status);
   1471 out:
   1472     //free the VendorData
   1473     if (mVendorData) {
   1474         free(mVendorData);
   1475     }
   1476     mVendorData = NULL;
   1477     //cleanup the mMsg
   1478     mMsg.destroy();
   1479     return res;
   1480 }
   1481 
   1482 int NanCommand::calcNanTransmitPostDiscoverySize(
   1483     const NanTransmitPostDiscovery *pPostDiscovery)
   1484 {
   1485     /* Fixed size of u32 for Conn Type, Device Role and R flag + Dur + Rsvd*/
   1486     int ret = sizeof(u32);
   1487     /* size of availability interval bit map is 4 bytes */
   1488     ret += sizeof(u32);
   1489     /* size of mac address is 6 bytes*/
   1490     ret += (SIZEOF_TLV_HDR + NAN_MAC_ADDR_LEN);
   1491     if (pPostDiscovery &&
   1492         pPostDiscovery->type == NAN_CONN_WLAN_MESH) {
   1493         /* size of WLAN_MESH_ID  */
   1494         ret += (SIZEOF_TLV_HDR + \
   1495                 pPostDiscovery->mesh_id_len);
   1496     }
   1497     if (pPostDiscovery &&
   1498         pPostDiscovery->type == NAN_CONN_WLAN_INFRA) {
   1499         /* size of Infrastructure ssid  */
   1500         ret += (SIZEOF_TLV_HDR + \
   1501                 pPostDiscovery->infrastructure_ssid_len);
   1502     }
   1503     ALOGV("%s:size:%d", __func__, ret);
   1504     return ret;
   1505 }
   1506 
   1507 void NanCommand::fillNanSocialChannelParamVal(
   1508     const NanSocialChannelScanParams *pScanParams,
   1509     u32* pChannelParamArr)
   1510 {
   1511     int i;
   1512     if (pChannelParamArr) {
   1513         memset(pChannelParamArr, 0,
   1514                NAN_MAX_SOCIAL_CHANNELS * sizeof(u32));
   1515         for (i= 0; i < NAN_MAX_SOCIAL_CHANNELS; i++) {
   1516             pChannelParamArr[i] = pScanParams->scan_period[i] << 16;
   1517             pChannelParamArr[i] |= pScanParams->dwell_time[i] << 8;
   1518         }
   1519         pChannelParamArr[NAN_CHANNEL_24G_BAND] |= 6;
   1520         pChannelParamArr[NAN_CHANNEL_5G_BAND_LOW]|= 44;
   1521         pChannelParamArr[NAN_CHANNEL_5G_BAND_HIGH]|= 149;
   1522         ALOGV("%s: Filled SocialChannelParamVal", __func__);
   1523         hexdump((char*)pChannelParamArr, NAN_MAX_SOCIAL_CHANNELS * sizeof(u32));
   1524     }
   1525     return;
   1526 }
   1527 
   1528 u32 NanCommand::getNanTransmitPostConnectivityCapabilityVal(
   1529     const NanTransmitPostConnectivityCapability *pCapab)
   1530 {
   1531     u32 ret = 0;
   1532     ret |= (pCapab->payload_transmit_flag? 1:0) << 16;
   1533     ret |= (pCapab->is_mesh_supported? 1:0) << 5;
   1534     ret |= (pCapab->is_ibss_supported? 1:0) << 4;
   1535     ret |= (pCapab->wlan_infra_field? 1:0) << 3;
   1536     ret |= (pCapab->is_tdls_supported? 1:0) << 2;
   1537     ret |= (pCapab->is_wfds_supported? 1:0) << 1;
   1538     ret |= (pCapab->is_wfd_supported? 1:0);
   1539     ALOGV("%s: val:%d", __func__, ret);
   1540     return ret;
   1541 }
   1542 
   1543 void NanCommand::fillNanTransmitPostDiscoveryVal(
   1544     const NanTransmitPostDiscovery *pTxDisc,
   1545     u8 *pOutValue)
   1546 {
   1547 
   1548     if (pTxDisc && pOutValue) {
   1549         u8 *tlvs = &pOutValue[8];
   1550         pOutValue[0] = pTxDisc->type;
   1551         pOutValue[1] = pTxDisc->role;
   1552         pOutValue[2] = (pTxDisc->transmit_freq? 1:0);
   1553         pOutValue[2] |= ((pTxDisc->duration & 0x03) << 1);
   1554         memcpy(&pOutValue[4], &pTxDisc->avail_interval_bitmap,
   1555                sizeof(pTxDisc->avail_interval_bitmap));
   1556         tlvs = addTlv(NAN_TLV_TYPE_MAC_ADDRESS,
   1557                     NAN_MAC_ADDR_LEN,
   1558                     (const u8*)&pTxDisc->addr[0],
   1559                     tlvs);
   1560         if (pTxDisc->type == NAN_CONN_WLAN_MESH) {
   1561             tlvs = addTlv(NAN_TLV_TYPE_WLAN_MESH_ID,
   1562                         pTxDisc->mesh_id_len,
   1563                         (const u8*)&pTxDisc->mesh_id[0],
   1564                         tlvs);
   1565         }
   1566         if (pTxDisc->type == NAN_CONN_WLAN_INFRA) {
   1567             tlvs = addTlv(NAN_TLV_TYPE_WLAN_INFRA_SSID,
   1568                         pTxDisc->infrastructure_ssid_len,
   1569                         (const u8*)&pTxDisc->infrastructure_ssid_val[0],
   1570                         tlvs);
   1571         }
   1572         ALOGV("%s: Filled TransmitPostDiscoveryVal", __func__);
   1573         hexdump((char*)pOutValue, calcNanTransmitPostDiscoverySize(pTxDisc));
   1574     }
   1575 
   1576     return;
   1577 }
   1578 
   1579 void NanCommand::fillNanFurtherAvailabilityMapVal(
   1580     const NanFurtherAvailabilityMap *pFam,
   1581     u8 *pOutValue)
   1582 {
   1583     int idx = 0;
   1584 
   1585     if (pFam && pOutValue) {
   1586         u32 famsize = calcNanFurtherAvailabilityMapSize(pFam);
   1587         pNanFurtherAvailabilityMapAttrTlv pFwReq = \
   1588             (pNanFurtherAvailabilityMapAttrTlv)pOutValue;
   1589 
   1590         memset(pOutValue, 0, famsize);
   1591         pFwReq->numChan = pFam->numchans;
   1592         for (idx = 0; idx < pFam->numchans; idx++) {
   1593             const NanFurtherAvailabilityChannel *pFamChan =  \
   1594                 &pFam->famchan[idx];
   1595             pNanFurtherAvailabilityChan pFwFamChan = \
   1596                 (pNanFurtherAvailabilityChan)((u8*)&pFwReq->pFaChan[0] + \
   1597                 (idx * sizeof(NanFurtherAvailabilityChan)));
   1598 
   1599             pFwFamChan->entryCtrl.availIntDuration = \
   1600                 pFamChan->entry_control;
   1601             pFwFamChan->entryCtrl.mapId = \
   1602                 pFamChan->mapid;
   1603             pFwFamChan->opClass =  pFamChan->class_val;
   1604             pFwFamChan->channel = pFamChan->channel;
   1605             memcpy(&pFwFamChan->availIntBitmap,
   1606                    &pFamChan->avail_interval_bitmap,
   1607                    sizeof(pFwFamChan->availIntBitmap));
   1608         }
   1609         ALOGV("%s: Filled FurtherAvailabilityMapVal", __func__);
   1610         hexdump((char*)pOutValue, famsize);
   1611     }
   1612     return;
   1613 }
   1614 
   1615 int NanCommand::calcNanFurtherAvailabilityMapSize(
   1616     const NanFurtherAvailabilityMap *pFam)
   1617 {
   1618     int ret = 0;
   1619     if (pFam && pFam->numchans &&
   1620         pFam->numchans <= NAN_MAX_FAM_CHANNELS) {
   1621         /* Fixed size of u8 for numchans*/
   1622         ret = sizeof(u8);
   1623         /* numchans * sizeof(FamChannels) */
   1624         ret += (pFam->numchans * sizeof(NanFurtherAvailabilityChan));
   1625     }
   1626     ALOGV("%s:size:%d", __func__, ret);
   1627     return ret;
   1628 }
   1629 
   1630 wifi_error NanCommand::putNanCapabilities(transaction_id id)
   1631 {
   1632     wifi_error ret;
   1633     ALOGV("NAN_CAPABILITIES");
   1634     size_t message_len = sizeof(NanCapabilitiesReqMsg);
   1635 
   1636     pNanCapabilitiesReqMsg pFwReq = (pNanCapabilitiesReqMsg)malloc(message_len);
   1637     if (pFwReq == NULL) {
   1638         cleanup();
   1639         return WIFI_ERROR_OUT_OF_MEMORY;
   1640     }
   1641 
   1642     memset (pFwReq, 0, message_len);
   1643     pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
   1644     pFwReq->fwHeader.msgId = NAN_MSG_ID_CAPABILITIES_REQ;
   1645     pFwReq->fwHeader.msgLen = message_len;
   1646     pFwReq->fwHeader.transactionId = id;
   1647 
   1648     mVendorData = (char*)pFwReq;
   1649     mDataLen = message_len;
   1650 
   1651     ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
   1652     if (ret != WIFI_SUCCESS) {
   1653         ALOGE("%s: put_bytes Error:%d",__func__, ret);
   1654         cleanup();
   1655         return ret;
   1656     }
   1657     hexdump(mVendorData, mDataLen);
   1658     return ret;
   1659 }
   1660 
   1661 wifi_error NanCommand::putNanDebugCommand(NanDebugParams debug,
   1662                                    int debug_msg_length)
   1663 {
   1664     wifi_error ret;
   1665     ALOGV("NAN_AVAILABILITY_DEBUG");
   1666     size_t message_len = sizeof(NanTestModeReqMsg);
   1667 
   1668     message_len += (SIZEOF_TLV_HDR + debug_msg_length);
   1669     pNanTestModeReqMsg pFwReq = (pNanTestModeReqMsg)malloc(message_len);
   1670     if (pFwReq == NULL) {
   1671         cleanup();
   1672         return WIFI_ERROR_OUT_OF_MEMORY;
   1673     }
   1674 
   1675     ALOGV("Message Len %zu\n", message_len);
   1676     ALOGV("%s: Debug Command Type = 0x%x \n", __func__, debug.cmd);
   1677     ALOGV("%s: ** Debug Command Data Start **", __func__);
   1678     hexdump(debug.debug_cmd_data, debug_msg_length);
   1679     ALOGV("%s: ** Debug Command Data End **", __func__);
   1680 
   1681     memset (pFwReq, 0, message_len);
   1682     pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
   1683     pFwReq->fwHeader.msgId = NAN_MSG_ID_TESTMODE_REQ;
   1684     pFwReq->fwHeader.msgLen = message_len;
   1685     pFwReq->fwHeader.transactionId = 0;
   1686 
   1687     u8* tlvs = pFwReq->ptlv;
   1688     tlvs = addTlv(NAN_TLV_TYPE_TESTMODE_GENERIC_CMD, debug_msg_length,
   1689                   (const u8*)&debug, tlvs);
   1690 
   1691     mVendorData = (char*)pFwReq;
   1692     mDataLen = message_len;
   1693 
   1694     /* Write the TLVs to the message. */
   1695     ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
   1696     if (ret != WIFI_SUCCESS) {
   1697         ALOGE("%s: put_bytes Error:%d",__func__, ret);
   1698         cleanup();
   1699         return ret;
   1700     }
   1701     hexdump(mVendorData, mDataLen);
   1702     return ret;
   1703 }
   1704