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 "nan.h"
     20 #include "wifi_hal.h"
     21 #include "nan_i.h"
     22 #include "nancommand.h"
     23 
     24 int NanCommand::putNanEnable(const NanEnableRequest *pReq)
     25 {
     26     ALOGI("NAN_ENABLE");
     27     size_t message_len = NAN_MAX_ENABLE_REQ_SIZE;
     28 
     29     if (pReq == NULL) {
     30         return WIFI_ERROR_INVALID_ARGS;
     31     }
     32 
     33 #ifdef NAN_2_0
     34     /* Removing the unsupported ones */
     35     message_len -= \
     36         (SIZEOF_TLV_HDR + sizeof(u8)  /* Random Time   */ + \
     37          SIZEOF_TLV_HDR + sizeof(u8)  /* Full Scan Int */);
     38 
     39     message_len += \
     40         (
     41           pReq->config_2dot4g_support ? (SIZEOF_TLV_HDR + \
     42           sizeof(pReq->support_2dot4g_val)) : 0 \
     43         ) + \
     44         (
     45           pReq->config_2dot4g_beacons ? (SIZEOF_TLV_HDR + \
     46           sizeof(pReq->beacon_2dot4g_val)) : 0 \
     47         ) + \
     48         (
     49           pReq->config_2dot4g_discovery ? (SIZEOF_TLV_HDR + \
     50           sizeof(pReq->discovery_2dot4g_val)) : 0 \
     51         ) + \
     52         (
     53           pReq->config_5g_beacons ? (SIZEOF_TLV_HDR + \
     54           sizeof(pReq->beacon_5g_val)) : 0 \
     55         ) + \
     56         (
     57           pReq->config_5g_discovery ? (SIZEOF_TLV_HDR + \
     58           sizeof(pReq->discovery_5g_val)) : 0 \
     59         ) + \
     60         (
     61           pReq->config_5g_rssi_close ? (SIZEOF_TLV_HDR + \
     62           sizeof(pReq->rssi_close_5g_val)) : 0 \
     63         ) + \
     64         (
     65           pReq->config_5g_rssi_middle ? (SIZEOF_TLV_HDR + \
     66           sizeof(pReq->rssi_middle_5g_val)) : 0 \
     67         ) + \
     68         (
     69           pReq->config_5g_rssi_close_proximity ? (SIZEOF_TLV_HDR + \
     70           sizeof(pReq->rssi_close_proximity_5g_val)) : 0 \
     71         ) + \
     72         (
     73           pReq->config_rssi_window_size ? (SIZEOF_TLV_HDR + \
     74           sizeof(pReq->rssi_window_size_val)) : 0 \
     75         ) + \
     76         (
     77           pReq->config_oui ? (SIZEOF_TLV_HDR + \
     78           sizeof(pReq->oui_val)) : 0 \
     79         ) + \
     80         (
     81           pReq->config_intf_addr ? (SIZEOF_TLV_HDR + \
     82           sizeof(pReq->intf_addr_val)) : 0 \
     83         ) + \
     84         (
     85           pReq->config_cluster_attribute_val ? (SIZEOF_TLV_HDR + \
     86           sizeof(pReq->config_cluster_attribute_val)) : 0 \
     87         ) + \
     88         (
     89           pReq->config_scan_params ? (SIZEOF_TLV_HDR + \
     90           NAN_MAX_SOCIAL_CHANNEL * sizeof(u32)) : 0 \
     91         ) + \
     92         (
     93           pReq->config_debug_flags ? (SIZEOF_TLV_HDR + \
     94           sizeof(u64)) : 0 \
     95         ) + \
     96         (
     97           pReq->config_random_factor_force ? (SIZEOF_TLV_HDR + \
     98           sizeof(pReq->random_factor_force_val)) : 0 \
     99          ) + \
    100         (
    101           pReq->config_hop_count_force ? (SIZEOF_TLV_HDR + \
    102           sizeof(pReq->hop_count_force_val)) : 0 \
    103         );
    104 #endif /* NAN_2_0 */
    105 
    106     pNanEnableReqMsg pFwReq = (pNanEnableReqMsg)malloc(message_len);
    107     if (pFwReq == NULL) {
    108         return WIFI_ERROR_OUT_OF_MEMORY;
    109     }
    110 
    111     ALOGI("Message Len %d", message_len);
    112     memset (pFwReq, 0, message_len);
    113     pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
    114     pFwReq->fwHeader.msgId = NAN_MSG_ID_ENABLE_REQ;
    115     pFwReq->fwHeader.msgLen = message_len;
    116     pFwReq->fwHeader.handle = pReq->header.handle;
    117     pFwReq->fwHeader.transactionId = pReq->header.transaction_id;
    118 
    119     u8* tlvs = pFwReq->ptlv;
    120 
    121     /* Write the TLVs to the message. */
    122     tlvs = addTlv(NAN_TLV_TYPE_5G_SUPPORT, sizeof(pReq->support_5g),
    123                   (const u8*)&pReq->support_5g, tlvs);
    124     tlvs = addTlv(NAN_TLV_TYPE_CLUSTER_ID_LOW, sizeof(pReq->cluster_low),
    125                   (const u8*)&pReq->cluster_low, tlvs);
    126     tlvs = addTlv(NAN_TLV_TYPE_CLUSTER_ID_HIGH, sizeof(pReq->cluster_high),
    127                   (const u8*)&pReq->cluster_high, tlvs);
    128     tlvs = addTlv(NAN_TLV_TYPE_SID_BEACON, sizeof(pReq->sid_beacon),
    129                   (const u8*)&pReq->sid_beacon, tlvs);
    130     tlvs = addTlv(NAN_TLV_TYPE_RSSI_CLOSE, sizeof(pReq->rssi_close),
    131                   (const u8*)&pReq->rssi_close, tlvs);
    132     tlvs = addTlv(NAN_TLV_TYPE_RSSI_MEDIUM, sizeof(pReq->rssi_middle),
    133                   (const u8*)&pReq->rssi_middle, tlvs);
    134     tlvs = addTlv(NAN_TLV_TYPE_HOP_COUNT_LIMIT, sizeof(pReq->hop_count_limit),
    135                   (const u8*)&pReq->hop_count_limit, tlvs);
    136 #ifndef NAN_2_0
    137     tlvs = addTlv(NAN_TLV_TYPE_RANDOM_UPDATE_TIME, sizeof(pReq->random_time),
    138                   (const u8*)&pReq->random_time, tlvs);
    139 #endif /* NAN_2_0 */
    140     tlvs = addTlv(NAN_TLV_TYPE_MASTER_PREFERENCE, sizeof(pReq->master_pref),
    141                   (const u8*)&pReq->master_pref, tlvs);
    142 #ifndef NAN_2_0
    143     tlvs = addTlv(NAN_TLV_TYPE_PERIODIC_SCAN_INTERVAL, sizeof(pReq->periodic_scan_interval),
    144                   (const u8*)&pReq->periodic_scan_interval, tlvs);
    145 #endif /* NAN_2_0 */
    146 
    147 #ifdef NAN_2_0
    148     if (pReq->config_2dot4g_support) {
    149         tlvs = addTlv(NAN_TLV_TYPE_2DOT4G_SUPPORT, sizeof(pReq->support_2dot4g_val),
    150                       (const u8*)&pReq->support_2dot4g_val, tlvs);
    151     }
    152     if (pReq->config_2dot4g_beacons) {
    153         tlvs = addTlv(NAN_TLV_TYPE_2DOT4G_BEACONS, sizeof(pReq->beacon_2dot4g_val),
    154                       (const u8*)&pReq->beacon_2dot4g_val, tlvs);
    155     }
    156     if (pReq->config_2dot4g_discovery) {
    157         tlvs = addTlv(NAN_TLV_TYPE_2DOT4G_SDF, sizeof(pReq->discovery_2dot4g_val),
    158                       (const u8*)&pReq->discovery_2dot4g_val, tlvs);
    159     }
    160     if (pReq->config_5g_beacons) {
    161         tlvs = addTlv(NAN_TLV_TYPE_5G_BEACON, sizeof(pReq->beacon_5g_val),
    162                       (const u8*)&pReq->beacon_5g_val, tlvs);
    163     }
    164     if (pReq->config_5g_discovery) {
    165         tlvs = addTlv(NAN_TLV_TYPE_5G_SDF, sizeof(pReq->discovery_5g_val),
    166                       (const u8*)&pReq->discovery_5g_val, tlvs);
    167     }
    168     /* Add the support of sending 5G RSSI values */
    169     if (pReq->config_5g_rssi_close) {
    170         tlvs = addTlv(NAN_TLV_TYPE_5G_RSSI_CLOSE, sizeof(pReq->rssi_close_5g_val),
    171                       (const u8*)&pReq->rssi_close_5g_val, tlvs);
    172     }
    173     if (pReq->config_5g_rssi_middle) {
    174         tlvs = addTlv(NAN_TLV_TYPE_5G_RSSI_MEDIUM, sizeof(pReq->rssi_middle_5g_val),
    175                       (const u8*)&pReq->rssi_middle_5g_val, tlvs);
    176     }
    177     if (pReq->config_5g_rssi_close_proximity) {
    178         tlvs = addTlv(NAN_TLV_TYPE_5G_RSSI_CLOSE_PROXIMITY,
    179                       sizeof(pReq->rssi_close_proximity_5g_val),
    180                       (const u8*)&pReq->rssi_close_proximity_5g_val, tlvs);
    181     }
    182     if (pReq->config_rssi_window_size) {
    183         tlvs = addTlv(NAN_TLV_TYPE_RSSI_AVERAGING_WINDOW_SIZE, sizeof(pReq->rssi_window_size_val),
    184                       (const u8*)&pReq->rssi_window_size_val, tlvs);
    185     }
    186     if (pReq->config_oui) {
    187         tlvs = addTlv(NAN_TLV_TYPE_CLUSTER_OUI_NETWORK_ID, sizeof(pReq->oui_val),
    188                       (const u8*)&pReq->oui_val, tlvs);
    189     }
    190     if (pReq->config_intf_addr) {
    191         tlvs = addTlv(NAN_TLV_TYPE_SOURCE_MAC_ADDRESS, sizeof(pReq->intf_addr_val),
    192                       (const u8*)&pReq->intf_addr_val[0], tlvs);
    193     }
    194     if (pReq->config_cluster_attribute_val) {
    195         tlvs = addTlv(NAN_TLV_TYPE_CLUSTER_ATTRIBUTE_IN_SDF, sizeof(pReq->config_cluster_attribute_val),
    196                       (const u8*)&pReq->config_cluster_attribute_val, tlvs);
    197     }
    198     if (pReq->config_scan_params) {
    199         u32 socialChannelParamVal[NAN_MAX_SOCIAL_CHANNEL];
    200         /* Fill the social channel param */
    201         fillNanSocialChannelParamVal(&pReq->scan_params_val,
    202                                      socialChannelParamVal);
    203         int i;
    204         for (i = 0; i < NAN_MAX_SOCIAL_CHANNEL; i++) {
    205             tlvs = addTlv(NAN_TLV_TYPE_SOCIAL_CHANNEL_SCAN_PARAMETERS,
    206                           sizeof(socialChannelParamVal[i]),
    207                           (const u8*)&socialChannelParamVal[i], tlvs);
    208         }
    209     }
    210     if (pReq->config_debug_flags) {
    211         tlvs = addTlv(NAN_TLV_TYPE_DEBUGGING_FLAGS,
    212                       sizeof(pReq->debug_flags_val),
    213                       (const u8*)&pReq->debug_flags_val, tlvs);
    214     }
    215     if (pReq->config_random_factor_force) {
    216         tlvs = addTlv(NAN_TLV_TYPE_RANDOM_FACTOR_FORCE,
    217                       sizeof(pReq->random_factor_force_val),
    218                       (const u8*)&pReq->random_factor_force_val, tlvs);
    219     }
    220     if (pReq->config_hop_count_force) {
    221         tlvs = addTlv(NAN_TLV_TYPE_HOP_COUNT_FORCE,
    222                       sizeof(pReq->hop_count_force_val),
    223                       (const u8*)&pReq->hop_count_force_val, tlvs);
    224     }
    225 #endif /* NAN_2_0 */
    226 
    227     mVendorData = (char*)pFwReq;
    228     mDataLen = message_len;
    229 
    230     return WIFI_SUCCESS;
    231 }
    232 
    233 int NanCommand::putNanDisable(const NanDisableRequest *pReq)
    234 {
    235     ALOGI("NAN_DISABLE");
    236     size_t message_len = sizeof(NanDisableReqMsg);
    237 
    238     if (pReq == NULL) {
    239         return WIFI_ERROR_INVALID_ARGS;
    240     }
    241 
    242     pNanDisableReqMsg pFwReq = (pNanDisableReqMsg)malloc(message_len);
    243     if (pFwReq == NULL) {
    244         return WIFI_ERROR_OUT_OF_MEMORY;
    245     }
    246 
    247     ALOGI("Message Len %d", message_len);
    248     memset (pFwReq, 0, message_len);
    249     pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
    250     pFwReq->fwHeader.msgId = NAN_MSG_ID_DISABLE_REQ;
    251     pFwReq->fwHeader.msgLen = message_len;
    252     pFwReq->fwHeader.handle = pReq->header.handle;
    253     pFwReq->fwHeader.transactionId = pReq->header.transaction_id;
    254 
    255     mVendorData = (char*)pFwReq;
    256     mDataLen = message_len;
    257 
    258     return WIFI_SUCCESS;
    259 }
    260 
    261 int NanCommand::putNanConfig(const NanConfigRequest *pReq)
    262 {
    263     ALOGI("NAN_CONFIG");
    264     size_t message_len = NAN_MAX_CONFIGURATION_REQ_SIZE;
    265 
    266     if (pReq == NULL) {
    267         return WIFI_ERROR_INVALID_ARGS;
    268     }
    269 
    270 #ifndef NAN_2_0
    271     // Add additional message size for transmitting
    272     // further availability attribute if
    273     // additional_disc_window_slots is Non-zero value.
    274     if (pReq->additional_disc_window_slots != 0) {
    275         message_len += (SIZEOF_TLV_HDR + \
    276                         sizeof(pReq->additional_disc_window_slots));
    277     }
    278 #endif /* NAN_2_0 */
    279 
    280 #ifdef NAN_2_0
    281     message_len = sizeof(NanMsgHeader);
    282 
    283     message_len += \
    284          (
    285            pReq->config_sid_beacon ? (SIZEOF_TLV_HDR + \
    286            sizeof(pReq->sid_beacon)) : 0 \
    287          ) + \
    288          (
    289            pReq->config_master_pref ? (SIZEOF_TLV_HDR + \
    290            sizeof(pReq->master_pref)) : 0 \
    291          ) + \
    292          (
    293            pReq->config_5g_rssi_close_proximity ? (SIZEOF_TLV_HDR + \
    294            sizeof(pReq->rssi_close_proximity_5g_val)) : 0 \
    295          ) + \
    296          (
    297            pReq->config_rssi_window_size ? (SIZEOF_TLV_HDR + \
    298            sizeof(pReq->rssi_window_size_val)) : 0 \
    299          ) + \
    300          (
    301            pReq->config_cluster_attribute_val ? (SIZEOF_TLV_HDR + \
    302            sizeof(pReq->config_cluster_attribute_val)) : 0 \
    303          ) + \
    304          (
    305            pReq->config_scan_params ? (SIZEOF_TLV_HDR + \
    306            NAN_MAX_SOCIAL_CHANNEL * sizeof(u32)) : 0 \
    307          ) + \
    308          (
    309            pReq->config_debug_flags ? (SIZEOF_TLV_HDR + \
    310            sizeof(u64)) : 0 \
    311           ) + \
    312          (
    313            pReq->config_random_factor_force ? (SIZEOF_TLV_HDR + \
    314            sizeof(pReq->random_factor_force_val)) : 0 \
    315           ) + \
    316          (
    317            pReq->config_hop_count_force ? (SIZEOF_TLV_HDR + \
    318            sizeof(pReq->hop_count_force_val)) : 0 \
    319          ) + \
    320          (
    321            pReq->config_conn_capability ? (SIZEOF_TLV_HDR + \
    322            sizeof(u32)) : 0 \
    323          ) + \
    324          (
    325            pReq->config_discovery_attr ? (SIZEOF_TLV_HDR + \
    326            calcNanTransmitPostDiscoverySize(&pReq->discovery_attr_val)) : 0 \
    327          );
    328 
    329     if (pReq->config_fam && \
    330         calcNanFurtherAvailabilityMapSize(&pReq->fam_val)) {
    331         message_len += (SIZEOF_TLV_HDR + \
    332            calcNanFurtherAvailabilityMapSize(&pReq->fam_val));
    333     }
    334 #endif /* NAN_2_0 */
    335 
    336     pNanConfigurationReqMsg pFwReq = (pNanConfigurationReqMsg)malloc(message_len);
    337     if (pFwReq == NULL) {
    338         return WIFI_ERROR_OUT_OF_MEMORY;
    339     }
    340 
    341     ALOGI("Message Len %d", message_len);
    342     memset (pFwReq, 0, message_len);
    343     pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
    344     pFwReq->fwHeader.msgId = NAN_MSG_ID_CONFIGURATION_REQ;
    345     pFwReq->fwHeader.msgLen = message_len;
    346     pFwReq->fwHeader.handle = pReq->header.handle;
    347     pFwReq->fwHeader.transactionId = pReq->header.transaction_id;
    348 
    349     u8* tlvs = pFwReq->ptlv;
    350     if (pReq->config_sid_beacon) {
    351         tlvs = addTlv(NAN_TLV_TYPE_SID_BEACON, sizeof(pReq->sid_beacon),
    352                       (const u8*)&pReq->sid_beacon, tlvs);
    353     }
    354 #ifndef NAN_2_0
    355     tlvs = addTlv(NAN_TLV_TYPE_RANDOM_UPDATE_TIME, sizeof(pReq->random_time),
    356                   (const u8*)&pReq->random_time, tlvs);
    357 #endif /* NAN_2_0 */
    358     if (pReq->config_master_pref) {
    359         tlvs = addTlv(NAN_TLV_TYPE_MASTER_PREFERENCE, sizeof(pReq->master_pref),
    360                       (const u8*)&pReq->master_pref, tlvs);
    361     }
    362 #ifndef NAN_2_0
    363     tlvs = addTlv(NAN_TLV_TYPE_PERIODIC_SCAN_INTERVAL, sizeof(pReq->periodic_scan_interval),
    364                   (const u8*)&pReq->periodic_scan_interval, tlvs);
    365 #endif /* NAN_2_0 */
    366 
    367 /* In 2.0 Version of NAN this parameter does not have any significance */
    368 #ifndef NAN_2_0
    369     if (pReq->additional_disc_window_slots != 0) {
    370         /*
    371         Construct the value in this manner
    372         Bit0 ==> 1/0 Enable/Disable FAW
    373         Bit1-2 ==>  reserved
    374         Bit3-7 ==>  FAW Slot Value.
    375         */
    376         u8 faw_value = 0x01;  /* Enable the first bit */
    377         /* Shifting the disc_window_slots by 3 and masking it with 0xf8
    378            so that the Bit 3 to 7 are updated
    379         */
    380         faw_value |= ((pReq->additional_disc_window_slots << 3) & (0xf8));
    381         tlvs = addTlv(NAN_TLV_TYPE_FURTHER_AVAILABILITY,
    382                       sizeof(faw_value),
    383                       (const u8*)&faw_value, tlvs);
    384     }
    385 #endif /* NAN_2_0 */
    386 
    387 #ifdef NAN_2_0
    388     if (pReq->config_rssi_window_size) {
    389         tlvs = addTlv(NAN_TLV_TYPE_RSSI_AVERAGING_WINDOW_SIZE, sizeof(pReq->rssi_window_size_val),
    390                       (const u8*)&pReq->rssi_window_size_val, tlvs);
    391     }
    392     if (pReq->config_scan_params) {
    393         u32 socialChannelParamVal[NAN_MAX_SOCIAL_CHANNEL];
    394         /* Fill the social channel param */
    395         fillNanSocialChannelParamVal(&pReq->scan_params_val,
    396                                  socialChannelParamVal);
    397         int i;
    398         for (i = 0; i < NAN_MAX_SOCIAL_CHANNEL; i++) {
    399             tlvs = addTlv(NAN_TLV_TYPE_SOCIAL_CHANNEL_SCAN_PARAMETERS,
    400                           sizeof(socialChannelParamVal[i]),
    401                           (const u8*)&socialChannelParamVal[i], tlvs);
    402         }
    403     }
    404     if (pReq->config_debug_flags) {
    405         tlvs = addTlv(NAN_TLV_TYPE_DEBUGGING_FLAGS,
    406                       sizeof(pReq->debug_flags_val),
    407                       (const u8*)&pReq->debug_flags_val, tlvs);
    408     }
    409     if (pReq->config_random_factor_force) {
    410         tlvs = addTlv(NAN_TLV_TYPE_RANDOM_FACTOR_FORCE,
    411                       sizeof(pReq->random_factor_force_val),
    412                       (const u8*)&pReq->random_factor_force_val, tlvs);
    413     }
    414     if (pReq->config_hop_count_force) {
    415         tlvs = addTlv(NAN_TLV_TYPE_HOP_COUNT_FORCE,
    416                       sizeof(pReq->hop_count_force_val),
    417                       (const u8*)&pReq->hop_count_force_val, tlvs);
    418     }
    419     if (pReq->config_conn_capability) {
    420         u32 val = \
    421         getNanTransmitPostConnectivityCapabilityVal(&pReq->conn_capability_val);
    422         tlvs = addTlv(NAN_TLV_TYPE_POST_NAN_CONNECTIVITY_CAPABILITIES_TRANSMIT,
    423                       sizeof(val), (const u8*)&val, tlvs);
    424     }
    425     if (pReq->config_discovery_attr) {
    426         fillNanTransmitPostDiscoveryVal(&pReq->discovery_attr_val,
    427                                         (u8*)(tlvs + SIZEOF_TLV_HDR));
    428         tlvs = addTlv(NAN_TLV_TYPE_POST_NAN_DISCOVERY_ATTRIBUTE_TRANSMIT,
    429                       calcNanTransmitPostDiscoverySize(&pReq->discovery_attr_val),
    430                       (const u8*)(tlvs + SIZEOF_TLV_HDR), tlvs);
    431     }
    432     if (pReq->config_fam && \
    433         calcNanFurtherAvailabilityMapSize(&pReq->fam_val)) {
    434         fillNanFurtherAvailabilityMapVal(&pReq->fam_val,
    435                                         (u8*)(tlvs + SIZEOF_TLV_HDR));
    436         tlvs = addTlv(NAN_TLV_TYPE_FURTHER_AVAILABILITY_MAP,
    437                       calcNanFurtherAvailabilityMapSize(&pReq->fam_val),
    438                       (const u8*)(tlvs + SIZEOF_TLV_HDR), tlvs);
    439     }
    440 #endif /* NAN_2_0 */
    441 
    442     mVendorData = (char*)pFwReq;
    443     mDataLen = message_len;
    444 
    445     return WIFI_SUCCESS;
    446 }
    447 
    448 
    449 int NanCommand::putNanPublish(const NanPublishRequest *pReq)
    450 {
    451     ALOGI("NAN_PUBLISH");
    452     if (pReq == NULL) {
    453         return WIFI_ERROR_INVALID_ARGS;
    454     }
    455 
    456     size_t message_len =
    457         sizeof(NanMsgHeader) + sizeof(NanPublishServiceReqParams) +
    458         (pReq->service_name_len ? SIZEOF_TLV_HDR + pReq->service_name_len : 0) +
    459         (pReq->service_specific_info_len ? SIZEOF_TLV_HDR + pReq->service_specific_info_len : 0) +
    460         (pReq->rx_match_filter_len ? SIZEOF_TLV_HDR + pReq->rx_match_filter_len : 0) +
    461         (pReq->tx_match_filter_len ? SIZEOF_TLV_HDR + pReq->tx_match_filter_len : 0);
    462 
    463     pNanPublishServiceReqMsg pFwReq = (pNanPublishServiceReqMsg)malloc(message_len);
    464     if (pFwReq == NULL) {
    465         return WIFI_ERROR_OUT_OF_MEMORY;
    466     }
    467 
    468     ALOGI("Message Len %d", message_len);
    469     memset(pFwReq, 0, message_len);
    470     pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
    471     pFwReq->fwHeader.msgId = NAN_MSG_ID_PUBLISH_SERVICE_REQ;
    472     pFwReq->fwHeader.msgLen = message_len;
    473     pFwReq->fwHeader.handle = pReq->header.handle;
    474     pFwReq->fwHeader.transactionId = pReq->header.transaction_id;
    475 
    476     pFwReq->publishServiceReqParams.ttl = pReq->ttl;
    477     pFwReq->publishServiceReqParams.period = pReq->period;
    478     pFwReq->publishServiceReqParams.replyIndFlag = pReq->replied_event_flag;
    479     pFwReq->publishServiceReqParams.publishType = pReq->publish_type;
    480     pFwReq->publishServiceReqParams.txType = pReq->tx_type;
    481 #ifdef NAN_2_0
    482     /* Overwriting replyIndFlag to 0 based on v17 Nan Spec */
    483     pFwReq->publishServiceReqParams.replyIndFlag = 0;
    484     pFwReq->publishServiceReqParams.rssiThresholdFlag = pReq->rssi_threshold_flag;
    485     pFwReq->publishServiceReqParams.ota_flag = pReq->ota_flag;
    486     pFwReq->publishServiceReqParams.matchAlg = pReq->publish_match;
    487 #endif /* NAN_2_0 */
    488     pFwReq->publishServiceReqParams.count = pReq->publish_count;
    489 #ifdef NAN_2_0
    490     pFwReq->publishServiceReqParams.connmap = pReq->connmap;
    491 #endif /* NAN_2_0 */
    492     pFwReq->publishServiceReqParams.reserved2 = 0;
    493 
    494     u8* tlvs = pFwReq->ptlv;
    495     if (pReq->service_name_len) {
    496         tlvs = addTlv(NAN_TLV_TYPE_SERVICE_NAME, pReq->service_name_len,
    497                       (const u8*)&pReq->service_name[0], tlvs);
    498     }
    499     if (pReq->service_specific_info_len) {
    500         tlvs = addTlv(NAN_TLV_TYPE_SERVICE_SPECIFIC_INFO, pReq->service_specific_info_len,
    501                       (const u8*)&pReq->service_specific_info[0], tlvs);
    502     }
    503     if (pReq->rx_match_filter_len) {
    504         tlvs = addTlv(NAN_TLV_TYPE_RX_MATCH_FILTER, pReq->rx_match_filter_len,
    505                       (const u8*)&pReq->rx_match_filter[0], tlvs);
    506     }
    507     if (pReq->tx_match_filter_len) {
    508         tlvs = addTlv(NAN_TLV_TYPE_TX_MATCH_FILTER, pReq->tx_match_filter_len,
    509                       (const u8*)&pReq->tx_match_filter[0], tlvs);
    510     }
    511 
    512     mVendorData = (char *)pFwReq;
    513     mDataLen = message_len;
    514 
    515     return WIFI_SUCCESS;
    516 }
    517 
    518 int NanCommand::putNanPublishCancel(const NanPublishCancelRequest *pReq)
    519 {
    520     ALOGI("NAN_PUBLISH_CANCEL");
    521     if (pReq == NULL) {
    522         return WIFI_ERROR_INVALID_ARGS;
    523     }
    524     size_t message_len = sizeof(NanPublishServiceCancelReqMsg);
    525 
    526     pNanPublishServiceCancelReqMsg pFwReq =
    527         (pNanPublishServiceCancelReqMsg)malloc(message_len);
    528     if (pFwReq == NULL) {
    529         return WIFI_ERROR_INVALID_ARGS;
    530     }
    531 
    532     ALOGI("Message Len %d", message_len);
    533     memset(pFwReq, 0, message_len);
    534     pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
    535     pFwReq->fwHeader.msgId = NAN_MSG_ID_PUBLISH_SERVICE_CANCEL_REQ;
    536     pFwReq->fwHeader.msgLen = message_len;
    537     pFwReq->fwHeader.handle = pReq->header.handle;
    538     pFwReq->fwHeader.transactionId = pReq->header.transaction_id;
    539 
    540     mVendorData = (char *)pFwReq;
    541     mDataLen = message_len;
    542 
    543     return WIFI_SUCCESS;
    544 }
    545 
    546 int NanCommand::putNanSubscribe(const NanSubscribeRequest *pReq)
    547 {
    548 
    549     ALOGI("NAN_SUBSCRIBE");
    550     if (pReq == NULL) {
    551         return WIFI_ERROR_INVALID_ARGS;
    552     }
    553 
    554     size_t message_len =
    555         sizeof(NanMsgHeader) + sizeof(NanSubscribeServiceReqParams) +
    556         (pReq->service_name_len ? SIZEOF_TLV_HDR + pReq->service_name_len : 0) +
    557         (pReq->service_specific_info_len ? SIZEOF_TLV_HDR + pReq->service_specific_info_len : 0) +
    558         (pReq->rx_match_filter_len ? SIZEOF_TLV_HDR + pReq->rx_match_filter_len : 0) +
    559         (pReq->tx_match_filter_len ? SIZEOF_TLV_HDR + pReq->tx_match_filter_len : 0);
    560 
    561 #ifdef NAN_2_0
    562     message_len += \
    563         (pReq->num_intf_addr_present * (SIZEOF_TLV_HDR + NAN_MAC_ADDR_LEN));
    564 #endif /* NAN_2_0 */
    565 
    566     pNanSubscribeServiceReqMsg pFwReq = (pNanSubscribeServiceReqMsg)malloc(message_len);
    567     if (pFwReq == NULL) {
    568         return WIFI_ERROR_INVALID_ARGS;
    569     }
    570 
    571     ALOGI("Message Len %d", message_len);
    572     memset(pFwReq, 0, message_len);
    573     pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
    574     pFwReq->fwHeader.msgId = NAN_MSG_ID_SUBSCRIBE_SERVICE_REQ;
    575     pFwReq->fwHeader.msgLen = message_len;
    576     pFwReq->fwHeader.handle = pReq->header.handle;
    577     pFwReq->fwHeader.transactionId = pReq->header.transaction_id;
    578 
    579 
    580     pFwReq->subscribeServiceReqParams.ttl = pReq->ttl;
    581     pFwReq->subscribeServiceReqParams.period = pReq->period;
    582     pFwReq->subscribeServiceReqParams.subscribeType = pReq->subscribe_type;
    583     pFwReq->subscribeServiceReqParams.srfAttr = pReq->serviceResponseFilter;
    584     pFwReq->subscribeServiceReqParams.srfInclude = pReq->serviceResponseInclude;
    585     pFwReq->subscribeServiceReqParams.srfSend = pReq->useServiceResponseFilter;
    586     pFwReq->subscribeServiceReqParams.ssiRequired = pReq->ssiRequiredForMatchIndication;
    587     pFwReq->subscribeServiceReqParams.matchAlg = pReq->subscribe_match;
    588     pFwReq->subscribeServiceReqParams.count = pReq->subscribe_count;
    589 #ifdef NAN_2_0
    590     pFwReq->subscribeServiceReqParams.rssiThresholdFlag = pReq->rssi_threshold_flag;
    591     pFwReq->subscribeServiceReqParams.ota_flag = pReq->ota_flag;
    592     pFwReq->subscribeServiceReqParams.connmap = pReq->connmap;
    593 #endif /* NAN_2_0 */
    594     pFwReq->subscribeServiceReqParams.reserved = 0;
    595 
    596     u8* tlvs = pFwReq->ptlv;
    597     if (pReq->service_name_len) {
    598         tlvs = addTlv(NAN_TLV_TYPE_SERVICE_NAME, pReq->service_name_len,
    599                       (const u8*)&pReq->service_name[0], tlvs);
    600     }
    601     if (pReq->service_specific_info_len) {
    602         tlvs = addTlv(NAN_TLV_TYPE_SERVICE_SPECIFIC_INFO, pReq->service_specific_info_len,
    603                       (const u8*)&pReq->service_specific_info[0], tlvs);
    604     }
    605     if (pReq->rx_match_filter_len) {
    606         tlvs = addTlv(NAN_TLV_TYPE_RX_MATCH_FILTER, pReq->rx_match_filter_len,
    607                       (const u8*)&pReq->rx_match_filter[0], tlvs);
    608     }
    609     if (pReq->tx_match_filter_len) {
    610         tlvs = addTlv(NAN_TLV_TYPE_TX_MATCH_FILTER, pReq->tx_match_filter_len,
    611                       (const u8*)&pReq->tx_match_filter[0], tlvs);
    612     }
    613 
    614 #ifdef NAN_2_0
    615     int i = 0;
    616     for (i = 0; i < pReq->num_intf_addr_present; i++)
    617     {
    618         tlvs = addTlv(NAN_TLV_TYPE_MAC_ADDRESS,
    619                       NAN_MAC_ADDR_LEN,
    620                       (const u8*)&pReq->intf_addr[i][0], tlvs);
    621     }
    622 #endif /* NAN_2_0 */
    623 
    624     mVendorData = (char *)pFwReq;
    625     mDataLen = message_len;
    626 
    627     return WIFI_SUCCESS;
    628 }
    629 
    630 int NanCommand::putNanSubscribeCancel(const NanSubscribeCancelRequest *pReq)
    631 {
    632     ALOGI("NAN_SUBSCRIBE_CANCEL");
    633     if (pReq == NULL) {
    634         return WIFI_ERROR_INVALID_ARGS;
    635     }
    636     size_t message_len = sizeof(NanSubscribeServiceCancelReqMsg);
    637 
    638     pNanSubscribeServiceCancelReqMsg pFwReq =
    639         (pNanSubscribeServiceCancelReqMsg)malloc(message_len);
    640     if (pFwReq == NULL) {
    641         return WIFI_ERROR_INVALID_ARGS;
    642     }
    643 
    644     ALOGI("Message Len %d", message_len);
    645     memset(pFwReq, 0, message_len);
    646     pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
    647     pFwReq->fwHeader.msgId = NAN_MSG_ID_SUBSCRIBE_SERVICE_CANCEL_REQ;
    648     pFwReq->fwHeader.msgLen = message_len;
    649     pFwReq->fwHeader.handle = pReq->header.handle;
    650     pFwReq->fwHeader.transactionId = pReq->header.transaction_id;
    651 
    652     mVendorData = (char *)pFwReq;
    653     mDataLen = message_len;
    654 
    655     return WIFI_SUCCESS;
    656 }
    657 
    658 
    659 int NanCommand::putNanTransmitFollowup(const NanTransmitFollowupRequest *pReq)
    660 {
    661     ALOGI("TRANSMIT_FOLLOWUP");
    662     if (pReq == NULL) {
    663         return WIFI_ERROR_INVALID_ARGS;
    664     }
    665 
    666     size_t message_len =
    667         sizeof(NanMsgHeader) + sizeof(NanTransmitFollowupReqParams) +
    668         (pReq->service_specific_info_len ? SIZEOF_TLV_HDR +
    669          pReq->service_specific_info_len : 0);
    670 
    671 #ifdef NAN_2_0
    672     /* Mac address needs to be added in TLV */
    673     message_len += (SIZEOF_TLV_HDR + sizeof(pReq->addr));
    674 #endif
    675 
    676     pNanTransmitFollowupReqMsg pFwReq = (pNanTransmitFollowupReqMsg)malloc(message_len);
    677     if (pFwReq == NULL) {
    678         return WIFI_ERROR_INVALID_ARGS;
    679     }
    680 
    681     ALOGI("Message Len %d", message_len);
    682     memset (pFwReq, 0, message_len);
    683     pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
    684     pFwReq->fwHeader.msgId = NAN_MSG_ID_TRANSMIT_FOLLOWUP_REQ;
    685     pFwReq->fwHeader.msgLen = message_len;
    686     pFwReq->fwHeader.handle = pReq->header.handle;
    687     pFwReq->fwHeader.transactionId = pReq->header.transaction_id;
    688 
    689 
    690 #ifndef NAN_2_0
    691     memcpy(pFwReq->transmitFollowupReqParams.macAddr, pReq->addr,
    692            sizeof(pFwReq->transmitFollowupReqParams.macAddr));
    693 #else /* NAN_2_0 */
    694     pFwReq->transmitFollowupReqParams.matchHandle = pReq->match_handle;
    695 #endif /* NAN_2_0 */
    696     pFwReq->transmitFollowupReqParams.priority = pReq->priority;
    697     pFwReq->transmitFollowupReqParams.window = pReq->dw_or_faw;
    698     pFwReq->transmitFollowupReqParams.reserved = 0;
    699 
    700     u8* tlvs = pFwReq->ptlv;
    701 
    702 #ifdef NAN_2_0
    703     /* Mac address needs to be added in TLV */
    704     tlvs = addTlv(NAN_TLV_TYPE_MAC_ADDRESS, sizeof(pReq->addr),
    705                   (const u8*)&pReq->addr[0], tlvs);
    706     u16 tlv_type = NAN_TLV_TYPE_SERVICE_SPECIFIC_INFO;
    707 #else /* NAN_2_0 */
    708     u16 tlv_type = (pReq->dw_or_faw == 0)? NAN_TLV_TYPE_SERVICE_SPECIFIC_INFO :
    709         NAN_TLV_TYPE_EXT_SERVICE_SPECIFIC_INFO;
    710 #endif /* NAN_2_0 */
    711 
    712     if (pReq->service_specific_info_len) {
    713         tlvs = addTlv(tlv_type, pReq->service_specific_info_len,
    714                       (const u8*)&pReq->service_specific_info[0], tlvs);
    715     }
    716 
    717     mVendorData = (char *)pFwReq;
    718     mDataLen = message_len;
    719 
    720     return WIFI_SUCCESS;
    721 }
    722 
    723 int NanCommand::putNanStats(const NanStatsRequest *pReq)
    724 {
    725     ALOGI("NAN_STATS");
    726     if (pReq == NULL) {
    727         return WIFI_ERROR_INVALID_ARGS;
    728     }
    729     size_t message_len = sizeof(NanStatsReqMsg);
    730 
    731     pNanStatsReqMsg pFwReq =
    732         (pNanStatsReqMsg)malloc(message_len);
    733     if (pFwReq == NULL) {
    734         return WIFI_ERROR_INVALID_ARGS;
    735     }
    736 
    737     ALOGI("Message Len %d", message_len);
    738     memset(pFwReq, 0, message_len);
    739     pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
    740     pFwReq->fwHeader.msgId = NAN_MSG_ID_STATS_REQ;
    741     pFwReq->fwHeader.msgLen = message_len;
    742     pFwReq->fwHeader.handle = pReq->header.handle;
    743     pFwReq->fwHeader.transactionId = pReq->header.transaction_id;
    744 
    745     pFwReq->statsReqParams.statsId = pReq->stats_id;
    746     pFwReq->statsReqParams.clear = pReq->clear;
    747     pFwReq->statsReqParams.reserved = 0;
    748 
    749     mVendorData = (char *)pFwReq;
    750     mDataLen = message_len;
    751 
    752     return WIFI_SUCCESS;
    753 }
    754 
    755 int NanCommand::putNanTCA(const NanTCARequest *pReq)
    756 {
    757     ALOGI("NAN_TCA");
    758     if (pReq == NULL) {
    759         return WIFI_ERROR_INVALID_ARGS;
    760     }
    761     size_t message_len = sizeof(NanTcaReqMsg);
    762 
    763 #ifdef NAN_2_0
    764     message_len += (SIZEOF_TLV_HDR + 2 * sizeof(u32));
    765 #endif
    766 
    767     pNanTcaReqMsg pFwReq =
    768         (pNanTcaReqMsg)malloc(message_len);
    769     if (pFwReq == NULL) {
    770         return WIFI_ERROR_INVALID_ARGS;
    771     }
    772 
    773     ALOGI("Message Len %d", message_len);
    774     memset(pFwReq, 0, message_len);
    775     pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
    776     pFwReq->fwHeader.msgId = NAN_MSG_ID_TCA_REQ;
    777     pFwReq->fwHeader.msgLen = message_len;
    778     pFwReq->fwHeader.handle = pReq->header.handle;
    779     pFwReq->fwHeader.transactionId = pReq->header.transaction_id;
    780 
    781 #ifndef NAN_2_0
    782     pFwReq->tcaReqParams.tcaId = pReq->tca_id;
    783     pFwReq->tcaReqParams.rising = pReq->rising_direction_evt_flag;
    784     pFwReq->tcaReqParams.falling = pReq->falling_direction_evt_flag;
    785     pFwReq->tcaReqParams.clear = pReq->clear;
    786     pFwReq->tcaReqParams.reserved = 0;
    787     pFwReq->tcaReqParams.threshold = pReq->threshold;
    788 #else /* NAN_2_0 */
    789     u32 tcaReqParams[2];
    790     memset (tcaReqParams, 0, sizeof(tcaReqParams));
    791     tcaReqParams[0] = (pReq->rising_direction_evt_flag & 0x01);
    792     tcaReqParams[0] |= (pReq->falling_direction_evt_flag & 0x01) << 1;
    793     tcaReqParams[0] |= (pReq->clear & 0x01) << 2;
    794     tcaReqParams[1] = pReq->threshold;
    795 
    796     u8* tlvs = pFwReq->ptlv;
    797 
    798     tlvs = addTlv(NAN_TLV_TYPE_TCA_CLUSTER_SIZE_REQ, sizeof(tcaReqParams),
    799                   (const u8*)&tcaReqParams[0], tlvs);
    800 #endif
    801 
    802     mVendorData = (char *)pFwReq;
    803     mDataLen = message_len;
    804 
    805     return WIFI_SUCCESS;
    806 }
    807 
    808 int NanCommand::putNanBeaconSdfPayload(const NanBeaconSdfPayloadRequest *pReq)
    809 {
    810     int ret = WIFI_ERROR_NOT_SUPPORTED;
    811 #ifdef NAN_2_0
    812     ALOGI("NAN_BEACON_SDF_PAYLAOD");
    813     if (pReq == NULL) {
    814         return WIFI_ERROR_INVALID_ARGS;
    815     }
    816     size_t message_len = sizeof(NanMsgHeader) + \
    817         SIZEOF_TLV_HDR + sizeof(u32) + \
    818         pReq->vsa.vsa_len;
    819 
    820     pNanBeaconSdfPayloadReqMsg pFwReq =
    821         (pNanBeaconSdfPayloadReqMsg)malloc(message_len);
    822     if (pFwReq == NULL) {
    823         return WIFI_ERROR_INVALID_ARGS;
    824     }
    825 
    826     ALOGI("Message Len %d", message_len);
    827     memset(pFwReq, 0, message_len);
    828     pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
    829     pFwReq->fwHeader.msgId = NAN_MSG_ID_BEACON_SDF_REQ;
    830     pFwReq->fwHeader.msgLen = message_len;
    831     pFwReq->fwHeader.handle = pReq->header.handle;
    832     pFwReq->fwHeader.transactionId = pReq->header.transaction_id;
    833 
    834     /* Construct First 4 bytes of NanBeaconSdfPayloadReqMsg */
    835     u32 temp = 0;
    836     temp = pReq->vsa.payload_transmit_flag & 0x01;
    837     temp |= (pReq->vsa.tx_in_discovery_beacon & 0x01) << 1;
    838     temp |= (pReq->vsa.tx_in_sync_beacon & 0x01) << 2;
    839     temp |= (pReq->vsa.tx_in_service_discovery & 0x01) << 3;
    840     temp |= (pReq->vsa.vendor_oui & 0x00FFFFFF) << 8;
    841 
    842     int tlv_len = sizeof(u32) + pReq->vsa.vsa_len;
    843     u8* tempBuf = (u8*)malloc(tlv_len);
    844     if (tempBuf == NULL) {
    845         ALOGE("%s: Malloc failed", __func__);
    846         free(pFwReq);
    847         return WIFI_ERROR_INVALID_ARGS;
    848     }
    849     memset(tempBuf, 0, tlv_len);
    850     memcpy(tempBuf, &temp, sizeof(u32));
    851     memcpy((tempBuf + sizeof(u32)), pReq->vsa.vsa, pReq->vsa.vsa_len);
    852 
    853     u8* tlvs = pFwReq->ptlv;
    854 
    855     /* Write the TLVs to the message. */
    856     tlvs = addTlv(NAN_TLV_TYPE_VENDOR_SPECIFIC_ATTRIBUTE_TRANSMIT, tlv_len,
    857                   (const u8*)tempBuf, tlvs);
    858     free(tempBuf);
    859 
    860     mVendorData = (char *)pFwReq;
    861     mDataLen = message_len;
    862     ret = WIFI_SUCCESS;
    863 #endif /* NAN_2_0 */
    864     return ret;
    865 }
    866 //callback handlers registered for nl message send
    867 static int error_handler_nan(struct sockaddr_nl *nla, struct nlmsgerr *err,
    868                          void *arg)
    869 {
    870     struct sockaddr_nl * tmp;
    871     int *ret = (int *)arg;
    872     tmp = nla;
    873     *ret = err->error;
    874     ALOGE("%s: Error code:%d (%s)", __func__, *ret, strerror(-(*ret)));
    875     return NL_STOP;
    876 }
    877 
    878 //callback handlers registered for nl message send
    879 static int ack_handler_nan(struct nl_msg *msg, void *arg)
    880 {
    881     int *ret = (int *)arg;
    882     struct nl_msg * a;
    883 
    884     ALOGE("%s: called", __func__);
    885     a = msg;
    886     *ret = 0;
    887     return NL_STOP;
    888 }
    889 
    890 //callback handlers registered for nl message send
    891 static int finish_handler_nan(struct nl_msg *msg, void *arg)
    892 {
    893   int *ret = (int *)arg;
    894   struct nl_msg * a;
    895 
    896   ALOGE("%s: called", __func__);
    897   a = msg;
    898   *ret = 0;
    899   return NL_SKIP;
    900 }
    901 
    902 
    903 //Override base class requestEvent and implement little differently here
    904 //This will send the request message
    905 //We dont wait for any response back in case of Nan as it is asynchronous
    906 //thus no wait for condition.
    907 int NanCommand::requestEvent()
    908 {
    909     int res;
    910     struct nl_cb * cb;
    911 
    912     cb = nl_cb_alloc(NL_CB_DEFAULT);
    913     if (!cb) {
    914         ALOGE("%s: Callback allocation failed",__func__);
    915         res = -1;
    916         goto out;
    917     }
    918 
    919     /* create the message */
    920     res = create();
    921     if (res < 0)
    922         goto out;
    923 
    924     /* send message */
    925     ALOGE("%s:Handle:%p Socket Value:%p", __func__, mInfo, mInfo->cmd_sock);
    926     res = nl_send_auto_complete(mInfo->cmd_sock, mMsg.getMessage());
    927     if (res < 0)
    928         goto out;
    929     res = 1;
    930 
    931     nl_cb_err(cb, NL_CB_CUSTOM, error_handler_nan, &res);
    932     nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler_nan, &res);
    933     nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler_nan, &res);
    934 
    935     // err is populated as part of finish_handler
    936     while (res > 0)
    937         nl_recvmsgs(mInfo->cmd_sock, cb);
    938 
    939     ALOGD("%s: Command invoked return value:%d",__func__, res);
    940 
    941 out:
    942     //free the VendorData
    943     if (mVendorData) {
    944         free(mVendorData);
    945     }
    946     mVendorData = NULL;
    947     //cleanup the mMsg
    948     mMsg.destroy();
    949     return res;
    950 }
    951 
    952 int NanCommand::calcNanTransmitPostDiscoverySize(
    953     const NanTransmitPostDiscovery *pPostDiscovery)
    954 {
    955     /* Fixed size of u32 for Conn Type, Device Role and R flag + Dur + Rsvd*/
    956     int ret = sizeof(u32);
    957     /* size of availability interval bit map is 4 bytes */
    958     ret += sizeof(u32);
    959     /* size of mac address is 6 bytes*/
    960     ret += (SIZEOF_TLV_HDR + NAN_MAC_ADDR_LEN);
    961     if (pPostDiscovery &&
    962         pPostDiscovery->type == NAN_CONN_WLAN_MESH) {
    963         /* size of WLAN_MESH_ID  */
    964         ret += (SIZEOF_TLV_HDR + \
    965                 pPostDiscovery->mesh_id_len);
    966     }
    967     if (pPostDiscovery &&
    968         pPostDiscovery->type == NAN_CONN_WLAN_INFRA) {
    969         /* size of Infrastructure ssid  */
    970         ret += (SIZEOF_TLV_HDR + \
    971                 pPostDiscovery->infrastructure_ssid_len);
    972     }
    973     ALOGI("%s:size:%d", __func__, ret);
    974     return ret;
    975 }
    976 
    977 void NanCommand::fillNanSocialChannelParamVal(
    978     const NanSocialChannelScanParams *pScanParams,
    979     u32* pChannelParamArr)
    980 {
    981     int i;
    982     if (pChannelParamArr) {
    983         memset(pChannelParamArr, 0,
    984                NAN_MAX_SOCIAL_CHANNEL * sizeof(u32));
    985         for (i= 0; i < NAN_MAX_SOCIAL_CHANNEL; i++) {
    986             pChannelParamArr[i] = pScanParams->scan_period[i] << 16;
    987             pChannelParamArr[i] |= pScanParams->dwell_time[i] << 8;
    988         }
    989         pChannelParamArr[NAN_CHANNEL_6] |= 6;
    990         pChannelParamArr[NAN_CHANNEL_44]|= 44;
    991         pChannelParamArr[NAN_CHANNEL_149]|= 149;
    992         ALOGI("%s: Filled SocialChannelParamVal", __func__);
    993         hexdump((char*)pChannelParamArr, NAN_MAX_SOCIAL_CHANNEL * sizeof(u32));
    994     }
    995     return;
    996 }
    997 
    998 u32 NanCommand::getNanTransmitPostConnectivityCapabilityVal(
    999     const NanTransmitPostConnectivityCapability *pCapab)
   1000 {
   1001     u32 ret = 0;
   1002     ret |= (pCapab->payload_transmit_flag? 1:0) << 16;
   1003     ret |= (pCapab->is_mesh_supported? 1:0) << 5;
   1004     ret |= (pCapab->is_ibss_supported? 1:0) << 4;
   1005     ret |= (pCapab->wlan_infra_field? 1:0) << 3;
   1006     ret |= (pCapab->is_tdls_supported? 1:0) << 2;
   1007     ret |= (pCapab->is_wfds_supported? 1:0) << 1;
   1008     ret |= (pCapab->is_wfd_supported? 1:0);
   1009     ALOGI("%s: val:%d", __func__, ret);
   1010     return ret;
   1011 }
   1012 
   1013 void NanCommand::fillNanTransmitPostDiscoveryVal(
   1014     const NanTransmitPostDiscovery *pTxDisc,
   1015     u8 *pOutValue)
   1016 {
   1017 #ifdef NAN_2_0
   1018     if (pTxDisc && pOutValue) {
   1019         u8 *tlvs = &pOutValue[8];
   1020         pOutValue[0] = pTxDisc->type;
   1021         pOutValue[1] = pTxDisc->role;
   1022         pOutValue[2] = (pTxDisc->transmit_freq? 1:0);
   1023         pOutValue[2] |= ((pTxDisc->duration & 0x03) << 1);
   1024         memcpy(&pOutValue[4], &pTxDisc->avail_interval_bitmap,
   1025                sizeof(pTxDisc->avail_interval_bitmap));
   1026         tlvs = addTlv(NAN_TLV_TYPE_MAC_ADDRESS,
   1027                     NAN_MAC_ADDR_LEN,
   1028                     (const u8*)&pTxDisc->addr[0],
   1029                     tlvs);
   1030         if (pTxDisc->type == NAN_CONN_WLAN_MESH) {
   1031             tlvs = addTlv(NAN_TLV_TYPE_WLAN_MESH_ID,
   1032                         pTxDisc->mesh_id_len,
   1033                         (const u8*)&pTxDisc->mesh_id[0],
   1034                         tlvs);
   1035         }
   1036         if (pTxDisc->type == NAN_CONN_WLAN_INFRA) {
   1037             tlvs = addTlv(NAN_TLV_TYPE_FW_WLAN_INFRASTRUCTURE_SSID,
   1038                         pTxDisc->infrastructure_ssid_len,
   1039                         (const u8*)&pTxDisc->infrastructure_ssid_val[0],
   1040                         tlvs);
   1041         }
   1042         ALOGI("%s: Filled TransmitPostDiscoveryVal", __func__);
   1043         hexdump((char*)pOutValue, calcNanTransmitPostDiscoverySize(pTxDisc));
   1044     }
   1045 #endif /* NAN_2_0 */
   1046     return;
   1047 }
   1048 
   1049 void NanCommand::fillNanFurtherAvailabilityMapVal(
   1050     const NanFurtherAvailabilityMap *pFam,
   1051     u8 *pOutValue)
   1052 {
   1053 //ToDo: Fixme - build issue
   1054 #if 0
   1055     int idx = 0;
   1056     if (pFam && pOutValue) {
   1057         u32 famsize = calcNanFurtherAvailabilityMapSize(pFam);
   1058         pNanFurtherAvailabilityMapAttrTlv pFwReq = \
   1059             (pNanFurtherAvailabilityMapAttrTlv)pOutValue;
   1060 
   1061         memset(pOutValue, 0, famsize);
   1062         pFwReq->numChan = pFam->numchans;
   1063         for (idx = 0; idx < pFam->numchans; idx++) {
   1064             const NanFurtherAvailabilityChannel *pFamChan =  \
   1065                 &pFam->famchan[idx];
   1066             pNanFurtherAvailabilityChan pFwFamChan = \
   1067                 (pNanFurtherAvailabilityChan)((u8*)&pFwReq->pFaChan[0] + \
   1068                 (idx * sizeof(NanFurtherAvailabilityChan)));
   1069 
   1070             pFwFamChan->entryCtrl.availIntDuration = \
   1071                 pFamChan->entry_control;
   1072             pFwFamChan->entryCtrl.mapId = \
   1073                 pFamChan->mapid;
   1074             pFwFamChan->opClass =  pFamChan->class_val;
   1075             pFwFamChan->channel = pFamChan->channel;
   1076             memcpy(&pFwFamChan->availIntBitmap,
   1077                    &pFamChan->avail_interval_bitmap,
   1078                    sizeof(pFwFamChan->availIntBitmap));
   1079         }
   1080         ALOGI("%s: Filled FurtherAvailabilityMapVal", __func__);
   1081         hexdump((char*)pOutValue, famsize);
   1082     }
   1083 #endif
   1084     return;
   1085 }
   1086 
   1087 int NanCommand::calcNanFurtherAvailabilityMapSize(
   1088     const NanFurtherAvailabilityMap *pFam)
   1089 {
   1090     int ret = 0;
   1091     if (pFam && pFam->numchans &&
   1092         pFam->numchans <= NAN_MAX_FAM_CHANNELS) {
   1093         /* Fixed size of u8 for numchans*/
   1094         ret = sizeof(u8);
   1095         /* numchans * sizeof(FamChannels) */
   1096         //ToDo: Fix build
   1097         //ret += (pFam->numchans * sizeof(NanFurtherAvailabilityChan));
   1098     }
   1099     ALOGI("%s:size:%d", __func__, ret);
   1100     return ret;
   1101 }
   1102 
   1103