C++程序  |  1100行  |  38.38 KB

/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "sync.h"
#include <utils/Log.h>
#include "nan.h"
#include "wifi_hal.h"
#include "nan_i.h"
#include "nancommand.h"

int NanCommand::putNanEnable(const NanEnableRequest *pReq)
{
    ALOGI("NAN_ENABLE");
    size_t message_len = NAN_MAX_ENABLE_REQ_SIZE;

    if (pReq == NULL) {
        return WIFI_ERROR_INVALID_ARGS;
    }

#ifdef NAN_2_0
    /* Removing the unsupported ones */
    message_len -= \
        (SIZEOF_TLV_HDR + sizeof(u8)  /* Random Time   */ + \
         SIZEOF_TLV_HDR + sizeof(u8)  /* Full Scan Int */);

    message_len += \
        (
          pReq->config_2dot4g_support ? (SIZEOF_TLV_HDR + \
          sizeof(pReq->support_2dot4g_val)) : 0 \
        ) + \
        (
          pReq->config_2dot4g_beacons ? (SIZEOF_TLV_HDR + \
          sizeof(pReq->beacon_2dot4g_val)) : 0 \
        ) + \
        (
          pReq->config_2dot4g_discovery ? (SIZEOF_TLV_HDR + \
          sizeof(pReq->discovery_2dot4g_val)) : 0 \
        ) + \
        (
          pReq->config_5g_beacons ? (SIZEOF_TLV_HDR + \
          sizeof(pReq->beacon_5g_val)) : 0 \
        ) + \
        (
          pReq->config_5g_discovery ? (SIZEOF_TLV_HDR + \
          sizeof(pReq->discovery_5g_val)) : 0 \
        ) + \
        (
          pReq->config_5g_rssi_close ? (SIZEOF_TLV_HDR + \
          sizeof(pReq->rssi_close_5g_val)) : 0 \
        ) + \
        (
          pReq->config_5g_rssi_middle ? (SIZEOF_TLV_HDR + \
          sizeof(pReq->rssi_middle_5g_val)) : 0 \
        ) + \
        (
          pReq->config_5g_rssi_close_proximity ? (SIZEOF_TLV_HDR + \
          sizeof(pReq->rssi_close_proximity_5g_val)) : 0 \
        ) + \
        (
          pReq->config_rssi_window_size ? (SIZEOF_TLV_HDR + \
          sizeof(pReq->rssi_window_size_val)) : 0 \
        ) + \
        (
          pReq->config_oui ? (SIZEOF_TLV_HDR + \
          sizeof(pReq->oui_val)) : 0 \
        ) + \
        (
          pReq->config_intf_addr ? (SIZEOF_TLV_HDR + \
          sizeof(pReq->intf_addr_val)) : 0 \
        ) + \
        (
          pReq->config_cluster_attribute_val ? (SIZEOF_TLV_HDR + \
          sizeof(pReq->config_cluster_attribute_val)) : 0 \
        ) + \
        (
          pReq->config_scan_params ? (SIZEOF_TLV_HDR + \
          NAN_MAX_SOCIAL_CHANNEL * sizeof(u32)) : 0 \
        ) + \
        (
          pReq->config_debug_flags ? (SIZEOF_TLV_HDR + \
          sizeof(u64)) : 0 \
        ) + \
        (
          pReq->config_random_factor_force ? (SIZEOF_TLV_HDR + \
          sizeof(pReq->random_factor_force_val)) : 0 \
         ) + \
        (
          pReq->config_hop_count_force ? (SIZEOF_TLV_HDR + \
          sizeof(pReq->hop_count_force_val)) : 0 \
        );
#endif /* NAN_2_0 */

    pNanEnableReqMsg pFwReq = (pNanEnableReqMsg)malloc(message_len);
    if (pFwReq == NULL) {
        return WIFI_ERROR_OUT_OF_MEMORY;
    }

    ALOGI("Message Len %d", message_len);
    memset (pFwReq, 0, message_len);
    pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
    pFwReq->fwHeader.msgId = NAN_MSG_ID_ENABLE_REQ;
    pFwReq->fwHeader.msgLen = message_len;
    pFwReq->fwHeader.handle = pReq->header.handle;
    pFwReq->fwHeader.transactionId = pReq->header.transaction_id;

    u8* tlvs = pFwReq->ptlv;

    /* Write the TLVs to the message. */
    tlvs = addTlv(NAN_TLV_TYPE_5G_SUPPORT, sizeof(pReq->support_5g),
                  (const u8*)&pReq->support_5g, tlvs);
    tlvs = addTlv(NAN_TLV_TYPE_CLUSTER_ID_LOW, sizeof(pReq->cluster_low),
                  (const u8*)&pReq->cluster_low, tlvs);
    tlvs = addTlv(NAN_TLV_TYPE_CLUSTER_ID_HIGH, sizeof(pReq->cluster_high),
                  (const u8*)&pReq->cluster_high, tlvs);
    tlvs = addTlv(NAN_TLV_TYPE_SID_BEACON, sizeof(pReq->sid_beacon),
                  (const u8*)&pReq->sid_beacon, tlvs);
    tlvs = addTlv(NAN_TLV_TYPE_RSSI_CLOSE, sizeof(pReq->rssi_close),
                  (const u8*)&pReq->rssi_close, tlvs);
    tlvs = addTlv(NAN_TLV_TYPE_RSSI_MEDIUM, sizeof(pReq->rssi_middle),
                  (const u8*)&pReq->rssi_middle, tlvs);
    tlvs = addTlv(NAN_TLV_TYPE_HOP_COUNT_LIMIT, sizeof(pReq->hop_count_limit),
                  (const u8*)&pReq->hop_count_limit, tlvs);
#ifndef NAN_2_0
    tlvs = addTlv(NAN_TLV_TYPE_RANDOM_UPDATE_TIME, sizeof(pReq->random_time),
                  (const u8*)&pReq->random_time, tlvs);
#endif /* NAN_2_0 */
    tlvs = addTlv(NAN_TLV_TYPE_MASTER_PREFERENCE, sizeof(pReq->master_pref),
                  (const u8*)&pReq->master_pref, tlvs);
#ifndef NAN_2_0
    tlvs = addTlv(NAN_TLV_TYPE_PERIODIC_SCAN_INTERVAL, sizeof(pReq->periodic_scan_interval),
                  (const u8*)&pReq->periodic_scan_interval, tlvs);
#endif /* NAN_2_0 */

#ifdef NAN_2_0
    if (pReq->config_2dot4g_support) {
        tlvs = addTlv(NAN_TLV_TYPE_2DOT4G_SUPPORT, sizeof(pReq->support_2dot4g_val),
                      (const u8*)&pReq->support_2dot4g_val, tlvs);
    }
    if (pReq->config_2dot4g_beacons) {
        tlvs = addTlv(NAN_TLV_TYPE_2DOT4G_BEACONS, sizeof(pReq->beacon_2dot4g_val),
                      (const u8*)&pReq->beacon_2dot4g_val, tlvs);
    }
    if (pReq->config_2dot4g_discovery) {
        tlvs = addTlv(NAN_TLV_TYPE_2DOT4G_SDF, sizeof(pReq->discovery_2dot4g_val),
                      (const u8*)&pReq->discovery_2dot4g_val, tlvs);
    }
    if (pReq->config_5g_beacons) {
        tlvs = addTlv(NAN_TLV_TYPE_5G_BEACON, sizeof(pReq->beacon_5g_val),
                      (const u8*)&pReq->beacon_5g_val, tlvs);
    }
    if (pReq->config_5g_discovery) {
        tlvs = addTlv(NAN_TLV_TYPE_5G_SDF, sizeof(pReq->discovery_5g_val),
                      (const u8*)&pReq->discovery_5g_val, tlvs);
    }
    /* Add the support of sending 5G RSSI values */
    if (pReq->config_5g_rssi_close) {
        tlvs = addTlv(NAN_TLV_TYPE_5G_RSSI_CLOSE, sizeof(pReq->rssi_close_5g_val),
                      (const u8*)&pReq->rssi_close_5g_val, tlvs);
    }
    if (pReq->config_5g_rssi_middle) {
        tlvs = addTlv(NAN_TLV_TYPE_5G_RSSI_MEDIUM, sizeof(pReq->rssi_middle_5g_val),
                      (const u8*)&pReq->rssi_middle_5g_val, tlvs);
    }
    if (pReq->config_5g_rssi_close_proximity) {
        tlvs = addTlv(NAN_TLV_TYPE_5G_RSSI_CLOSE_PROXIMITY,
                      sizeof(pReq->rssi_close_proximity_5g_val),
                      (const u8*)&pReq->rssi_close_proximity_5g_val, tlvs);
    }
    if (pReq->config_rssi_window_size) {
        tlvs = addTlv(NAN_TLV_TYPE_RSSI_AVERAGING_WINDOW_SIZE, sizeof(pReq->rssi_window_size_val),
                      (const u8*)&pReq->rssi_window_size_val, tlvs);
    }
    if (pReq->config_oui) {
        tlvs = addTlv(NAN_TLV_TYPE_CLUSTER_OUI_NETWORK_ID, sizeof(pReq->oui_val),
                      (const u8*)&pReq->oui_val, tlvs);
    }
    if (pReq->config_intf_addr) {
        tlvs = addTlv(NAN_TLV_TYPE_SOURCE_MAC_ADDRESS, sizeof(pReq->intf_addr_val),
                      (const u8*)&pReq->intf_addr_val[0], tlvs);
    }
    if (pReq->config_cluster_attribute_val) {
        tlvs = addTlv(NAN_TLV_TYPE_CLUSTER_ATTRIBUTE_IN_SDF, sizeof(pReq->config_cluster_attribute_val),
                      (const u8*)&pReq->config_cluster_attribute_val, tlvs);
    }
    if (pReq->config_scan_params) {
        u32 socialChannelParamVal[NAN_MAX_SOCIAL_CHANNEL];
        /* Fill the social channel param */
        fillNanSocialChannelParamVal(&pReq->scan_params_val,
                                     socialChannelParamVal);
        int i;
        for (i = 0; i < NAN_MAX_SOCIAL_CHANNEL; i++) {
            tlvs = addTlv(NAN_TLV_TYPE_SOCIAL_CHANNEL_SCAN_PARAMETERS,
                          sizeof(socialChannelParamVal[i]),
                          (const u8*)&socialChannelParamVal[i], tlvs);
        }
    }
    if (pReq->config_debug_flags) {
        tlvs = addTlv(NAN_TLV_TYPE_DEBUGGING_FLAGS,
                      sizeof(pReq->debug_flags_val),
                      (const u8*)&pReq->debug_flags_val, tlvs);
    }
    if (pReq->config_random_factor_force) {
        tlvs = addTlv(NAN_TLV_TYPE_RANDOM_FACTOR_FORCE,
                      sizeof(pReq->random_factor_force_val),
                      (const u8*)&pReq->random_factor_force_val, tlvs);
    }
    if (pReq->config_hop_count_force) {
        tlvs = addTlv(NAN_TLV_TYPE_HOP_COUNT_FORCE,
                      sizeof(pReq->hop_count_force_val),
                      (const u8*)&pReq->hop_count_force_val, tlvs);
    }
#endif /* NAN_2_0 */

    mVendorData = (char*)pFwReq;
    mDataLen = message_len;

    return WIFI_SUCCESS;
}

int NanCommand::putNanDisable(const NanDisableRequest *pReq)
{
    ALOGI("NAN_DISABLE");
    size_t message_len = sizeof(NanDisableReqMsg);

    if (pReq == NULL) {
        return WIFI_ERROR_INVALID_ARGS;
    }

    pNanDisableReqMsg pFwReq = (pNanDisableReqMsg)malloc(message_len);
    if (pFwReq == NULL) {
        return WIFI_ERROR_OUT_OF_MEMORY;
    }

    ALOGI("Message Len %d", message_len);
    memset (pFwReq, 0, message_len);
    pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
    pFwReq->fwHeader.msgId = NAN_MSG_ID_DISABLE_REQ;
    pFwReq->fwHeader.msgLen = message_len;
    pFwReq->fwHeader.handle = pReq->header.handle;
    pFwReq->fwHeader.transactionId = pReq->header.transaction_id;

    mVendorData = (char*)pFwReq;
    mDataLen = message_len;

    return WIFI_SUCCESS;
}

int NanCommand::putNanConfig(const NanConfigRequest *pReq)
{
    ALOGI("NAN_CONFIG");
    size_t message_len = NAN_MAX_CONFIGURATION_REQ_SIZE;

    if (pReq == NULL) {
        return WIFI_ERROR_INVALID_ARGS;
    }

#ifndef NAN_2_0
    // Add additional message size for transmitting
    // further availability attribute if
    // additional_disc_window_slots is Non-zero value.
    if (pReq->additional_disc_window_slots != 0) {
        message_len += (SIZEOF_TLV_HDR + \
                        sizeof(pReq->additional_disc_window_slots));
    }
#endif /* NAN_2_0 */

#ifdef NAN_2_0
    message_len = sizeof(NanMsgHeader);

    message_len += \
         (
           pReq->config_sid_beacon ? (SIZEOF_TLV_HDR + \
           sizeof(pReq->sid_beacon)) : 0 \
         ) + \
         (
           pReq->config_master_pref ? (SIZEOF_TLV_HDR + \
           sizeof(pReq->master_pref)) : 0 \
         ) + \
         (
           pReq->config_5g_rssi_close_proximity ? (SIZEOF_TLV_HDR + \
           sizeof(pReq->rssi_close_proximity_5g_val)) : 0 \
         ) + \
         (
           pReq->config_rssi_window_size ? (SIZEOF_TLV_HDR + \
           sizeof(pReq->rssi_window_size_val)) : 0 \
         ) + \
         (
           pReq->config_cluster_attribute_val ? (SIZEOF_TLV_HDR + \
           sizeof(pReq->config_cluster_attribute_val)) : 0 \
         ) + \
         (
           pReq->config_scan_params ? (SIZEOF_TLV_HDR + \
           NAN_MAX_SOCIAL_CHANNEL * sizeof(u32)) : 0 \
         ) + \
         (
           pReq->config_debug_flags ? (SIZEOF_TLV_HDR + \
           sizeof(u64)) : 0 \
          ) + \
         (
           pReq->config_random_factor_force ? (SIZEOF_TLV_HDR + \
           sizeof(pReq->random_factor_force_val)) : 0 \
          ) + \
         (
           pReq->config_hop_count_force ? (SIZEOF_TLV_HDR + \
           sizeof(pReq->hop_count_force_val)) : 0 \
         ) + \
         (
           pReq->config_conn_capability ? (SIZEOF_TLV_HDR + \
           sizeof(u32)) : 0 \
         ) + \
         (
           pReq->config_discovery_attr ? (SIZEOF_TLV_HDR + \
           calcNanTransmitPostDiscoverySize(&pReq->discovery_attr_val)) : 0 \
         );

    if (pReq->config_fam && \
        calcNanFurtherAvailabilityMapSize(&pReq->fam_val)) {
        message_len += (SIZEOF_TLV_HDR + \
           calcNanFurtherAvailabilityMapSize(&pReq->fam_val));
    }
#endif /* NAN_2_0 */

    pNanConfigurationReqMsg pFwReq = (pNanConfigurationReqMsg)malloc(message_len);
    if (pFwReq == NULL) {
        return WIFI_ERROR_OUT_OF_MEMORY;
    }

    ALOGI("Message Len %d", message_len);
    memset (pFwReq, 0, message_len);
    pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
    pFwReq->fwHeader.msgId = NAN_MSG_ID_CONFIGURATION_REQ;
    pFwReq->fwHeader.msgLen = message_len;
    pFwReq->fwHeader.handle = pReq->header.handle;
    pFwReq->fwHeader.transactionId = pReq->header.transaction_id;

    u8* tlvs = pFwReq->ptlv;
    if (pReq->config_sid_beacon) {
        tlvs = addTlv(NAN_TLV_TYPE_SID_BEACON, sizeof(pReq->sid_beacon),
                      (const u8*)&pReq->sid_beacon, tlvs);
    }
#ifndef NAN_2_0
    tlvs = addTlv(NAN_TLV_TYPE_RANDOM_UPDATE_TIME, sizeof(pReq->random_time),
                  (const u8*)&pReq->random_time, tlvs);
#endif /* NAN_2_0 */
    if (pReq->config_master_pref) {
        tlvs = addTlv(NAN_TLV_TYPE_MASTER_PREFERENCE, sizeof(pReq->master_pref),
                      (const u8*)&pReq->master_pref, tlvs);
    }
#ifndef NAN_2_0
    tlvs = addTlv(NAN_TLV_TYPE_PERIODIC_SCAN_INTERVAL, sizeof(pReq->periodic_scan_interval),
                  (const u8*)&pReq->periodic_scan_interval, tlvs);
#endif /* NAN_2_0 */

/* In 2.0 Version of NAN this parameter does not have any significance */
#ifndef NAN_2_0
    if (pReq->additional_disc_window_slots != 0) {
        /*
        Construct the value in this manner
        Bit0 ==> 1/0 Enable/Disable FAW
        Bit1-2 ==>  reserved
        Bit3-7 ==>  FAW Slot Value.
        */
        u8 faw_value = 0x01;  /* Enable the first bit */
        /* Shifting the disc_window_slots by 3 and masking it with 0xf8
           so that the Bit 3 to 7 are updated
        */
        faw_value |= ((pReq->additional_disc_window_slots << 3) & (0xf8));
        tlvs = addTlv(NAN_TLV_TYPE_FURTHER_AVAILABILITY,
                      sizeof(faw_value),
                      (const u8*)&faw_value, tlvs);
    }
#endif /* NAN_2_0 */

#ifdef NAN_2_0
    if (pReq->config_rssi_window_size) {
        tlvs = addTlv(NAN_TLV_TYPE_RSSI_AVERAGING_WINDOW_SIZE, sizeof(pReq->rssi_window_size_val),
                      (const u8*)&pReq->rssi_window_size_val, tlvs);
    }
    if (pReq->config_scan_params) {
        u32 socialChannelParamVal[NAN_MAX_SOCIAL_CHANNEL];
        /* Fill the social channel param */
        fillNanSocialChannelParamVal(&pReq->scan_params_val,
                                 socialChannelParamVal);
        int i;
        for (i = 0; i < NAN_MAX_SOCIAL_CHANNEL; i++) {
            tlvs = addTlv(NAN_TLV_TYPE_SOCIAL_CHANNEL_SCAN_PARAMETERS,
                          sizeof(socialChannelParamVal[i]),
                          (const u8*)&socialChannelParamVal[i], tlvs);
        }
    }
    if (pReq->config_debug_flags) {
        tlvs = addTlv(NAN_TLV_TYPE_DEBUGGING_FLAGS,
                      sizeof(pReq->debug_flags_val),
                      (const u8*)&pReq->debug_flags_val, tlvs);
    }
    if (pReq->config_random_factor_force) {
        tlvs = addTlv(NAN_TLV_TYPE_RANDOM_FACTOR_FORCE,
                      sizeof(pReq->random_factor_force_val),
                      (const u8*)&pReq->random_factor_force_val, tlvs);
    }
    if (pReq->config_hop_count_force) {
        tlvs = addTlv(NAN_TLV_TYPE_HOP_COUNT_FORCE,
                      sizeof(pReq->hop_count_force_val),
                      (const u8*)&pReq->hop_count_force_val, tlvs);
    }
    if (pReq->config_conn_capability) {
        u32 val = \
        getNanTransmitPostConnectivityCapabilityVal(&pReq->conn_capability_val);
        tlvs = addTlv(NAN_TLV_TYPE_POST_NAN_CONNECTIVITY_CAPABILITIES_TRANSMIT,
                      sizeof(val), (const u8*)&val, tlvs);
    }
    if (pReq->config_discovery_attr) {
        fillNanTransmitPostDiscoveryVal(&pReq->discovery_attr_val,
                                        (u8*)(tlvs + SIZEOF_TLV_HDR));
        tlvs = addTlv(NAN_TLV_TYPE_POST_NAN_DISCOVERY_ATTRIBUTE_TRANSMIT,
                      calcNanTransmitPostDiscoverySize(&pReq->discovery_attr_val),
                      (const u8*)(tlvs + SIZEOF_TLV_HDR), tlvs);
    }
    if (pReq->config_fam && \
        calcNanFurtherAvailabilityMapSize(&pReq->fam_val)) {
        fillNanFurtherAvailabilityMapVal(&pReq->fam_val,
                                        (u8*)(tlvs + SIZEOF_TLV_HDR));
        tlvs = addTlv(NAN_TLV_TYPE_FURTHER_AVAILABILITY_MAP,
                      calcNanFurtherAvailabilityMapSize(&pReq->fam_val),
                      (const u8*)(tlvs + SIZEOF_TLV_HDR), tlvs);
    }
#endif /* NAN_2_0 */

    mVendorData = (char*)pFwReq;
    mDataLen = message_len;

    return WIFI_SUCCESS;
}


int NanCommand::putNanPublish(const NanPublishRequest *pReq)
{
    ALOGI("NAN_PUBLISH");
    if (pReq == NULL) {
        return WIFI_ERROR_INVALID_ARGS;
    }

    size_t message_len =
        sizeof(NanMsgHeader) + sizeof(NanPublishServiceReqParams) +
        (pReq->service_name_len ? SIZEOF_TLV_HDR + pReq->service_name_len : 0) +
        (pReq->service_specific_info_len ? SIZEOF_TLV_HDR + pReq->service_specific_info_len : 0) +
        (pReq->rx_match_filter_len ? SIZEOF_TLV_HDR + pReq->rx_match_filter_len : 0) +
        (pReq->tx_match_filter_len ? SIZEOF_TLV_HDR + pReq->tx_match_filter_len : 0);

    pNanPublishServiceReqMsg pFwReq = (pNanPublishServiceReqMsg)malloc(message_len);
    if (pFwReq == NULL) {
        return WIFI_ERROR_OUT_OF_MEMORY;
    }

    ALOGI("Message Len %d", message_len);
    memset(pFwReq, 0, message_len);
    pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
    pFwReq->fwHeader.msgId = NAN_MSG_ID_PUBLISH_SERVICE_REQ;
    pFwReq->fwHeader.msgLen = message_len;
    pFwReq->fwHeader.handle = pReq->header.handle;
    pFwReq->fwHeader.transactionId = pReq->header.transaction_id;

    pFwReq->publishServiceReqParams.ttl = pReq->ttl;
    pFwReq->publishServiceReqParams.period = pReq->period;
    pFwReq->publishServiceReqParams.replyIndFlag = pReq->replied_event_flag;
    pFwReq->publishServiceReqParams.publishType = pReq->publish_type;
    pFwReq->publishServiceReqParams.txType = pReq->tx_type;
#ifdef NAN_2_0
    /* Overwriting replyIndFlag to 0 based on v17 Nan Spec */
    pFwReq->publishServiceReqParams.replyIndFlag = 0;
    pFwReq->publishServiceReqParams.rssiThresholdFlag = pReq->rssi_threshold_flag;
    pFwReq->publishServiceReqParams.ota_flag = pReq->ota_flag;
    pFwReq->publishServiceReqParams.matchAlg = pReq->publish_match;
#endif /* NAN_2_0 */
    pFwReq->publishServiceReqParams.count = pReq->publish_count;
#ifdef NAN_2_0
    pFwReq->publishServiceReqParams.connmap = pReq->connmap;
#endif /* NAN_2_0 */
    pFwReq->publishServiceReqParams.reserved2 = 0;

    u8* tlvs = pFwReq->ptlv;
    if (pReq->service_name_len) {
        tlvs = addTlv(NAN_TLV_TYPE_SERVICE_NAME, pReq->service_name_len,
                      (const u8*)&pReq->service_name[0], tlvs);
    }
    if (pReq->service_specific_info_len) {
        tlvs = addTlv(NAN_TLV_TYPE_SERVICE_SPECIFIC_INFO, pReq->service_specific_info_len,
                      (const u8*)&pReq->service_specific_info[0], tlvs);
    }
    if (pReq->rx_match_filter_len) {
        tlvs = addTlv(NAN_TLV_TYPE_RX_MATCH_FILTER, pReq->rx_match_filter_len,
                      (const u8*)&pReq->rx_match_filter[0], tlvs);
    }
    if (pReq->tx_match_filter_len) {
        tlvs = addTlv(NAN_TLV_TYPE_TX_MATCH_FILTER, pReq->tx_match_filter_len,
                      (const u8*)&pReq->tx_match_filter[0], tlvs);
    }

    mVendorData = (char *)pFwReq;
    mDataLen = message_len;

    return WIFI_SUCCESS;
}

int NanCommand::putNanPublishCancel(const NanPublishCancelRequest *pReq)
{
    ALOGI("NAN_PUBLISH_CANCEL");
    if (pReq == NULL) {
        return WIFI_ERROR_INVALID_ARGS;
    }
    size_t message_len = sizeof(NanPublishServiceCancelReqMsg);

    pNanPublishServiceCancelReqMsg pFwReq =
        (pNanPublishServiceCancelReqMsg)malloc(message_len);
    if (pFwReq == NULL) {
        return WIFI_ERROR_INVALID_ARGS;
    }

    ALOGI("Message Len %d", message_len);
    memset(pFwReq, 0, message_len);
    pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
    pFwReq->fwHeader.msgId = NAN_MSG_ID_PUBLISH_SERVICE_CANCEL_REQ;
    pFwReq->fwHeader.msgLen = message_len;
    pFwReq->fwHeader.handle = pReq->header.handle;
    pFwReq->fwHeader.transactionId = pReq->header.transaction_id;

    mVendorData = (char *)pFwReq;
    mDataLen = message_len;

    return WIFI_SUCCESS;
}

int NanCommand::putNanSubscribe(const NanSubscribeRequest *pReq)
{

    ALOGI("NAN_SUBSCRIBE");
    if (pReq == NULL) {
        return WIFI_ERROR_INVALID_ARGS;
    }

    size_t message_len =
        sizeof(NanMsgHeader) + sizeof(NanSubscribeServiceReqParams) +
        (pReq->service_name_len ? SIZEOF_TLV_HDR + pReq->service_name_len : 0) +
        (pReq->service_specific_info_len ? SIZEOF_TLV_HDR + pReq->service_specific_info_len : 0) +
        (pReq->rx_match_filter_len ? SIZEOF_TLV_HDR + pReq->rx_match_filter_len : 0) +
        (pReq->tx_match_filter_len ? SIZEOF_TLV_HDR + pReq->tx_match_filter_len : 0);

#ifdef NAN_2_0
    message_len += \
        (pReq->num_intf_addr_present * (SIZEOF_TLV_HDR + NAN_MAC_ADDR_LEN));
#endif /* NAN_2_0 */

    pNanSubscribeServiceReqMsg pFwReq = (pNanSubscribeServiceReqMsg)malloc(message_len);
    if (pFwReq == NULL) {
        return WIFI_ERROR_INVALID_ARGS;
    }

    ALOGI("Message Len %d", message_len);
    memset(pFwReq, 0, message_len);
    pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
    pFwReq->fwHeader.msgId = NAN_MSG_ID_SUBSCRIBE_SERVICE_REQ;
    pFwReq->fwHeader.msgLen = message_len;
    pFwReq->fwHeader.handle = pReq->header.handle;
    pFwReq->fwHeader.transactionId = pReq->header.transaction_id;


    pFwReq->subscribeServiceReqParams.ttl = pReq->ttl;
    pFwReq->subscribeServiceReqParams.period = pReq->period;
    pFwReq->subscribeServiceReqParams.subscribeType = pReq->subscribe_type;
    pFwReq->subscribeServiceReqParams.srfAttr = pReq->serviceResponseFilter;
    pFwReq->subscribeServiceReqParams.srfInclude = pReq->serviceResponseInclude;
    pFwReq->subscribeServiceReqParams.srfSend = pReq->useServiceResponseFilter;
    pFwReq->subscribeServiceReqParams.ssiRequired = pReq->ssiRequiredForMatchIndication;
    pFwReq->subscribeServiceReqParams.matchAlg = pReq->subscribe_match;
    pFwReq->subscribeServiceReqParams.count = pReq->subscribe_count;
#ifdef NAN_2_0
    pFwReq->subscribeServiceReqParams.rssiThresholdFlag = pReq->rssi_threshold_flag;
    pFwReq->subscribeServiceReqParams.ota_flag = pReq->ota_flag;
    pFwReq->subscribeServiceReqParams.connmap = pReq->connmap;
#endif /* NAN_2_0 */
    pFwReq->subscribeServiceReqParams.reserved = 0;

    u8* tlvs = pFwReq->ptlv;
    if (pReq->service_name_len) {
        tlvs = addTlv(NAN_TLV_TYPE_SERVICE_NAME, pReq->service_name_len,
                      (const u8*)&pReq->service_name[0], tlvs);
    }
    if (pReq->service_specific_info_len) {
        tlvs = addTlv(NAN_TLV_TYPE_SERVICE_SPECIFIC_INFO, pReq->service_specific_info_len,
                      (const u8*)&pReq->service_specific_info[0], tlvs);
    }
    if (pReq->rx_match_filter_len) {
        tlvs = addTlv(NAN_TLV_TYPE_RX_MATCH_FILTER, pReq->rx_match_filter_len,
                      (const u8*)&pReq->rx_match_filter[0], tlvs);
    }
    if (pReq->tx_match_filter_len) {
        tlvs = addTlv(NAN_TLV_TYPE_TX_MATCH_FILTER, pReq->tx_match_filter_len,
                      (const u8*)&pReq->tx_match_filter[0], tlvs);
    }

#ifdef NAN_2_0
    int i = 0;
    for (i = 0; i < pReq->num_intf_addr_present; i++)
    {
        tlvs = addTlv(NAN_TLV_TYPE_MAC_ADDRESS,
                      NAN_MAC_ADDR_LEN,
                      (const u8*)&pReq->intf_addr[i][0], tlvs);
    }
#endif /* NAN_2_0 */

    mVendorData = (char *)pFwReq;
    mDataLen = message_len;

    return WIFI_SUCCESS;
}

int NanCommand::putNanSubscribeCancel(const NanSubscribeCancelRequest *pReq)
{
    ALOGI("NAN_SUBSCRIBE_CANCEL");
    if (pReq == NULL) {
        return WIFI_ERROR_INVALID_ARGS;
    }
    size_t message_len = sizeof(NanSubscribeServiceCancelReqMsg);

    pNanSubscribeServiceCancelReqMsg pFwReq =
        (pNanSubscribeServiceCancelReqMsg)malloc(message_len);
    if (pFwReq == NULL) {
        return WIFI_ERROR_INVALID_ARGS;
    }

    ALOGI("Message Len %d", message_len);
    memset(pFwReq, 0, message_len);
    pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
    pFwReq->fwHeader.msgId = NAN_MSG_ID_SUBSCRIBE_SERVICE_CANCEL_REQ;
    pFwReq->fwHeader.msgLen = message_len;
    pFwReq->fwHeader.handle = pReq->header.handle;
    pFwReq->fwHeader.transactionId = pReq->header.transaction_id;

    mVendorData = (char *)pFwReq;
    mDataLen = message_len;

    return WIFI_SUCCESS;
}


int NanCommand::putNanTransmitFollowup(const NanTransmitFollowupRequest *pReq)
{
    ALOGI("TRANSMIT_FOLLOWUP");
    if (pReq == NULL) {
        return WIFI_ERROR_INVALID_ARGS;
    }

    size_t message_len =
        sizeof(NanMsgHeader) + sizeof(NanTransmitFollowupReqParams) +
        (pReq->service_specific_info_len ? SIZEOF_TLV_HDR +
         pReq->service_specific_info_len : 0);

#ifdef NAN_2_0
    /* Mac address needs to be added in TLV */
    message_len += (SIZEOF_TLV_HDR + sizeof(pReq->addr));
#endif

    pNanTransmitFollowupReqMsg pFwReq = (pNanTransmitFollowupReqMsg)malloc(message_len);
    if (pFwReq == NULL) {
        return WIFI_ERROR_INVALID_ARGS;
    }

    ALOGI("Message Len %d", message_len);
    memset (pFwReq, 0, message_len);
    pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
    pFwReq->fwHeader.msgId = NAN_MSG_ID_TRANSMIT_FOLLOWUP_REQ;
    pFwReq->fwHeader.msgLen = message_len;
    pFwReq->fwHeader.handle = pReq->header.handle;
    pFwReq->fwHeader.transactionId = pReq->header.transaction_id;


#ifndef NAN_2_0
    memcpy(pFwReq->transmitFollowupReqParams.macAddr, pReq->addr,
           sizeof(pFwReq->transmitFollowupReqParams.macAddr));
#else /* NAN_2_0 */
    pFwReq->transmitFollowupReqParams.matchHandle = pReq->match_handle;
#endif /* NAN_2_0 */
    pFwReq->transmitFollowupReqParams.priority = pReq->priority;
    pFwReq->transmitFollowupReqParams.window = pReq->dw_or_faw;
    pFwReq->transmitFollowupReqParams.reserved = 0;

    u8* tlvs = pFwReq->ptlv;

#ifdef NAN_2_0
    /* Mac address needs to be added in TLV */
    tlvs = addTlv(NAN_TLV_TYPE_MAC_ADDRESS, sizeof(pReq->addr),
                  (const u8*)&pReq->addr[0], tlvs);
    u16 tlv_type = NAN_TLV_TYPE_SERVICE_SPECIFIC_INFO;
#else /* NAN_2_0 */
    u16 tlv_type = (pReq->dw_or_faw == 0)? NAN_TLV_TYPE_SERVICE_SPECIFIC_INFO :
        NAN_TLV_TYPE_EXT_SERVICE_SPECIFIC_INFO;
#endif /* NAN_2_0 */

    if (pReq->service_specific_info_len) {
        tlvs = addTlv(tlv_type, pReq->service_specific_info_len,
                      (const u8*)&pReq->service_specific_info[0], tlvs);
    }

    mVendorData = (char *)pFwReq;
    mDataLen = message_len;

    return WIFI_SUCCESS;
}

int NanCommand::putNanStats(const NanStatsRequest *pReq)
{
    ALOGI("NAN_STATS");
    if (pReq == NULL) {
        return WIFI_ERROR_INVALID_ARGS;
    }
    size_t message_len = sizeof(NanStatsReqMsg);

    pNanStatsReqMsg pFwReq =
        (pNanStatsReqMsg)malloc(message_len);
    if (pFwReq == NULL) {
        return WIFI_ERROR_INVALID_ARGS;
    }

    ALOGI("Message Len %d", message_len);
    memset(pFwReq, 0, message_len);
    pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
    pFwReq->fwHeader.msgId = NAN_MSG_ID_STATS_REQ;
    pFwReq->fwHeader.msgLen = message_len;
    pFwReq->fwHeader.handle = pReq->header.handle;
    pFwReq->fwHeader.transactionId = pReq->header.transaction_id;

    pFwReq->statsReqParams.statsId = pReq->stats_id;
    pFwReq->statsReqParams.clear = pReq->clear;
    pFwReq->statsReqParams.reserved = 0;

    mVendorData = (char *)pFwReq;
    mDataLen = message_len;

    return WIFI_SUCCESS;
}

int NanCommand::putNanTCA(const NanTCARequest *pReq)
{
    ALOGI("NAN_TCA");
    if (pReq == NULL) {
        return WIFI_ERROR_INVALID_ARGS;
    }
    size_t message_len = sizeof(NanTcaReqMsg);

#ifdef NAN_2_0
    message_len += (SIZEOF_TLV_HDR + 2 * sizeof(u32));
#endif

    pNanTcaReqMsg pFwReq =
        (pNanTcaReqMsg)malloc(message_len);
    if (pFwReq == NULL) {
        return WIFI_ERROR_INVALID_ARGS;
    }

    ALOGI("Message Len %d", message_len);
    memset(pFwReq, 0, message_len);
    pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
    pFwReq->fwHeader.msgId = NAN_MSG_ID_TCA_REQ;
    pFwReq->fwHeader.msgLen = message_len;
    pFwReq->fwHeader.handle = pReq->header.handle;
    pFwReq->fwHeader.transactionId = pReq->header.transaction_id;

#ifndef NAN_2_0
    pFwReq->tcaReqParams.tcaId = pReq->tca_id;
    pFwReq->tcaReqParams.rising = pReq->rising_direction_evt_flag;
    pFwReq->tcaReqParams.falling = pReq->falling_direction_evt_flag;
    pFwReq->tcaReqParams.clear = pReq->clear;
    pFwReq->tcaReqParams.reserved = 0;
    pFwReq->tcaReqParams.threshold = pReq->threshold;
#else /* NAN_2_0 */
    u32 tcaReqParams[2];
    memset (tcaReqParams, 0, sizeof(tcaReqParams));
    tcaReqParams[0] = (pReq->rising_direction_evt_flag & 0x01);
    tcaReqParams[0] |= (pReq->falling_direction_evt_flag & 0x01) << 1;
    tcaReqParams[0] |= (pReq->clear & 0x01) << 2;
    tcaReqParams[1] = pReq->threshold;

    u8* tlvs = pFwReq->ptlv;

    tlvs = addTlv(NAN_TLV_TYPE_TCA_CLUSTER_SIZE_REQ, sizeof(tcaReqParams),
                  (const u8*)&tcaReqParams[0], tlvs);
#endif

    mVendorData = (char *)pFwReq;
    mDataLen = message_len;

    return WIFI_SUCCESS;
}

int NanCommand::putNanBeaconSdfPayload(const NanBeaconSdfPayloadRequest *pReq)
{
    int ret = WIFI_ERROR_NOT_SUPPORTED;
#ifdef NAN_2_0
    ALOGI("NAN_BEACON_SDF_PAYLAOD");
    if (pReq == NULL) {
        return WIFI_ERROR_INVALID_ARGS;
    }
    size_t message_len = sizeof(NanMsgHeader) + \
        SIZEOF_TLV_HDR + sizeof(u32) + \
        pReq->vsa.vsa_len;

    pNanBeaconSdfPayloadReqMsg pFwReq =
        (pNanBeaconSdfPayloadReqMsg)malloc(message_len);
    if (pFwReq == NULL) {
        return WIFI_ERROR_INVALID_ARGS;
    }

    ALOGI("Message Len %d", message_len);
    memset(pFwReq, 0, message_len);
    pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
    pFwReq->fwHeader.msgId = NAN_MSG_ID_BEACON_SDF_REQ;
    pFwReq->fwHeader.msgLen = message_len;
    pFwReq->fwHeader.handle = pReq->header.handle;
    pFwReq->fwHeader.transactionId = pReq->header.transaction_id;

    /* Construct First 4 bytes of NanBeaconSdfPayloadReqMsg */
    u32 temp = 0;
    temp = pReq->vsa.payload_transmit_flag & 0x01;
    temp |= (pReq->vsa.tx_in_discovery_beacon & 0x01) << 1;
    temp |= (pReq->vsa.tx_in_sync_beacon & 0x01) << 2;
    temp |= (pReq->vsa.tx_in_service_discovery & 0x01) << 3;
    temp |= (pReq->vsa.vendor_oui & 0x00FFFFFF) << 8;

    int tlv_len = sizeof(u32) + pReq->vsa.vsa_len;
    u8* tempBuf = (u8*)malloc(tlv_len);
    if (tempBuf == NULL) {
        ALOGE("%s: Malloc failed", __func__);
        free(pFwReq);
        return WIFI_ERROR_INVALID_ARGS;
    }
    memset(tempBuf, 0, tlv_len);
    memcpy(tempBuf, &temp, sizeof(u32));
    memcpy((tempBuf + sizeof(u32)), pReq->vsa.vsa, pReq->vsa.vsa_len);

    u8* tlvs = pFwReq->ptlv;

    /* Write the TLVs to the message. */
    tlvs = addTlv(NAN_TLV_TYPE_VENDOR_SPECIFIC_ATTRIBUTE_TRANSMIT, tlv_len,
                  (const u8*)tempBuf, tlvs);
    free(tempBuf);

    mVendorData = (char *)pFwReq;
    mDataLen = message_len;
    ret = WIFI_SUCCESS;
#endif /* NAN_2_0 */
    return ret;
}
//callback handlers registered for nl message send
static int error_handler_nan(struct sockaddr_nl *nla, struct nlmsgerr *err,
                         void *arg)
{
    struct sockaddr_nl * tmp;
    int *ret = (int *)arg;
    tmp = nla;
    *ret = err->error;
    ALOGE("%s: Error code:%d (%s)", __func__, *ret, strerror(-(*ret)));
    return NL_STOP;
}

//callback handlers registered for nl message send
static int ack_handler_nan(struct nl_msg *msg, void *arg)
{
    int *ret = (int *)arg;
    struct nl_msg * a;

    ALOGE("%s: called", __func__);
    a = msg;
    *ret = 0;
    return NL_STOP;
}

//callback handlers registered for nl message send
static int finish_handler_nan(struct nl_msg *msg, void *arg)
{
  int *ret = (int *)arg;
  struct nl_msg * a;

  ALOGE("%s: called", __func__);
  a = msg;
  *ret = 0;
  return NL_SKIP;
}


//Override base class requestEvent and implement little differently here
//This will send the request message
//We dont wait for any response back in case of Nan as it is asynchronous
//thus no wait for condition.
int NanCommand::requestEvent()
{
    int res;
    struct nl_cb * cb;

    cb = nl_cb_alloc(NL_CB_DEFAULT);
    if (!cb) {
        ALOGE("%s: Callback allocation failed",__func__);
        res = -1;
        goto out;
    }

    /* create the message */
    res = create();
    if (res < 0)
        goto out;

    /* send message */
    ALOGE("%s:Handle:%p Socket Value:%p", __func__, mInfo, mInfo->cmd_sock);
    res = nl_send_auto_complete(mInfo->cmd_sock, mMsg.getMessage());
    if (res < 0)
        goto out;
    res = 1;

    nl_cb_err(cb, NL_CB_CUSTOM, error_handler_nan, &res);
    nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler_nan, &res);
    nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler_nan, &res);

    // err is populated as part of finish_handler
    while (res > 0)
        nl_recvmsgs(mInfo->cmd_sock, cb);

    ALOGD("%s: Command invoked return value:%d",__func__, res);

out:
    //free the VendorData
    if (mVendorData) {
        free(mVendorData);
    }
    mVendorData = NULL;
    //cleanup the mMsg
    mMsg.destroy();
    return res;
}

int NanCommand::calcNanTransmitPostDiscoverySize(
    const NanTransmitPostDiscovery *pPostDiscovery)
{
    /* Fixed size of u32 for Conn Type, Device Role and R flag + Dur + Rsvd*/
    int ret = sizeof(u32);
    /* size of availability interval bit map is 4 bytes */
    ret += sizeof(u32);
    /* size of mac address is 6 bytes*/
    ret += (SIZEOF_TLV_HDR + NAN_MAC_ADDR_LEN);
    if (pPostDiscovery &&
        pPostDiscovery->type == NAN_CONN_WLAN_MESH) {
        /* size of WLAN_MESH_ID  */
        ret += (SIZEOF_TLV_HDR + \
                pPostDiscovery->mesh_id_len);
    }
    if (pPostDiscovery &&
        pPostDiscovery->type == NAN_CONN_WLAN_INFRA) {
        /* size of Infrastructure ssid  */
        ret += (SIZEOF_TLV_HDR + \
                pPostDiscovery->infrastructure_ssid_len);
    }
    ALOGI("%s:size:%d", __func__, ret);
    return ret;
}

void NanCommand::fillNanSocialChannelParamVal(
    const NanSocialChannelScanParams *pScanParams,
    u32* pChannelParamArr)
{
    int i;
    if (pChannelParamArr) {
        memset(pChannelParamArr, 0,
               NAN_MAX_SOCIAL_CHANNEL * sizeof(u32));
        for (i= 0; i < NAN_MAX_SOCIAL_CHANNEL; i++) {
            pChannelParamArr[i] = pScanParams->scan_period[i] << 16;
            pChannelParamArr[i] |= pScanParams->dwell_time[i] << 8;
        }
        pChannelParamArr[NAN_CHANNEL_6] |= 6;
        pChannelParamArr[NAN_CHANNEL_44]|= 44;
        pChannelParamArr[NAN_CHANNEL_149]|= 149;
        ALOGI("%s: Filled SocialChannelParamVal", __func__);
        hexdump((char*)pChannelParamArr, NAN_MAX_SOCIAL_CHANNEL * sizeof(u32));
    }
    return;
}

u32 NanCommand::getNanTransmitPostConnectivityCapabilityVal(
    const NanTransmitPostConnectivityCapability *pCapab)
{
    u32 ret = 0;
    ret |= (pCapab->payload_transmit_flag? 1:0) << 16;
    ret |= (pCapab->is_mesh_supported? 1:0) << 5;
    ret |= (pCapab->is_ibss_supported? 1:0) << 4;
    ret |= (pCapab->wlan_infra_field? 1:0) << 3;
    ret |= (pCapab->is_tdls_supported? 1:0) << 2;
    ret |= (pCapab->is_wfds_supported? 1:0) << 1;
    ret |= (pCapab->is_wfd_supported? 1:0);
    ALOGI("%s: val:%d", __func__, ret);
    return ret;
}

void NanCommand::fillNanTransmitPostDiscoveryVal(
    const NanTransmitPostDiscovery *pTxDisc,
    u8 *pOutValue)
{
#ifdef NAN_2_0
    if (pTxDisc && pOutValue) {
        u8 *tlvs = &pOutValue[8];
        pOutValue[0] = pTxDisc->type;
        pOutValue[1] = pTxDisc->role;
        pOutValue[2] = (pTxDisc->transmit_freq? 1:0);
        pOutValue[2] |= ((pTxDisc->duration & 0x03) << 1);
        memcpy(&pOutValue[4], &pTxDisc->avail_interval_bitmap,
               sizeof(pTxDisc->avail_interval_bitmap));
        tlvs = addTlv(NAN_TLV_TYPE_MAC_ADDRESS,
                    NAN_MAC_ADDR_LEN,
                    (const u8*)&pTxDisc->addr[0],
                    tlvs);
        if (pTxDisc->type == NAN_CONN_WLAN_MESH) {
            tlvs = addTlv(NAN_TLV_TYPE_WLAN_MESH_ID,
                        pTxDisc->mesh_id_len,
                        (const u8*)&pTxDisc->mesh_id[0],
                        tlvs);
        }
        if (pTxDisc->type == NAN_CONN_WLAN_INFRA) {
            tlvs = addTlv(NAN_TLV_TYPE_FW_WLAN_INFRASTRUCTURE_SSID,
                        pTxDisc->infrastructure_ssid_len,
                        (const u8*)&pTxDisc->infrastructure_ssid_val[0],
                        tlvs);
        }
        ALOGI("%s: Filled TransmitPostDiscoveryVal", __func__);
        hexdump((char*)pOutValue, calcNanTransmitPostDiscoverySize(pTxDisc));
    }
#endif /* NAN_2_0 */
    return;
}

void NanCommand::fillNanFurtherAvailabilityMapVal(
    const NanFurtherAvailabilityMap *pFam,
    u8 *pOutValue)
{
    int idx = 0;

    if (pFam && pOutValue) {
        u32 famsize = calcNanFurtherAvailabilityMapSize(pFam);
        pNanFurtherAvailabilityMapAttrTlv pFwReq = \
            (pNanFurtherAvailabilityMapAttrTlv)pOutValue;

        memset(pOutValue, 0, famsize);
        pFwReq->numChan = pFam->numchans;
        for (idx = 0; idx < pFam->numchans; idx++) {
            const NanFurtherAvailabilityChannel *pFamChan =  \
                &pFam->famchan[idx];
            pNanFurtherAvailabilityChan pFwFamChan = \
                (pNanFurtherAvailabilityChan)((u8*)&pFwReq->pFaChan[0] + \
                (idx * sizeof(NanFurtherAvailabilityChan)));

            pFwFamChan->entryCtrl.availIntDuration = \
                pFamChan->entry_control;
            pFwFamChan->entryCtrl.mapId = \
                pFamChan->mapid;
            pFwFamChan->opClass =  pFamChan->class_val;
            pFwFamChan->channel = pFamChan->channel;
            memcpy(&pFwFamChan->availIntBitmap,
                   &pFamChan->avail_interval_bitmap,
                   sizeof(pFwFamChan->availIntBitmap));
        }
        ALOGI("%s: Filled FurtherAvailabilityMapVal", __func__);
        hexdump((char*)pOutValue, famsize);
    }
    return;
}

int NanCommand::calcNanFurtherAvailabilityMapSize(
    const NanFurtherAvailabilityMap *pFam)
{
    int ret = 0;
    if (pFam && pFam->numchans &&
        pFam->numchans <= NAN_MAX_FAM_CHANNELS) {
        /* Fixed size of u8 for numchans*/
        ret = sizeof(u8);
        /* numchans * sizeof(FamChannels) */
        ret += (pFam->numchans * sizeof(NanFurtherAvailabilityChan));
    }
    ALOGI("%s:size:%d", __func__, ret);
    return ret;
}