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