/*
 * 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.
 *
 * Changes from Qualcomm Innovation Center are provided under the following license:
 *
 * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted (subject to the limitations in the
 * disclaimer below) provided that the following conditions are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *
 *   * Neither the name of Qualcomm Innovation Center, Inc. nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
 * GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
 * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "sync.h"

#include "wifi_hal.h"
#include "nan_i.h"
#include "common.h"
#include "cpp_bindings.h"
#include <utils/Log.h>
#include <errno.h>
#include "nancommand.h"
#include "vendor_definitions.h"
#include "wificonfigcommand.h"
#include <ctype.h>
#include <openssl/sha.h>
#include <openssl/evp.h>

#ifdef __GNUC__
#define PRINTF_FORMAT(a,b) __attribute__ ((format (printf, (a), (b))))
#define STRUCT_PACKED __attribute__ ((packed))
#else
#define PRINTF_FORMAT(a,b)
#define STRUCT_PACKED
#endif

#define OUT_OF_BAND_SERVICE_INSTANCE_ID 0

//Singleton Static Instance
NanCommand* NanCommand::mNanCommandInstance  = NULL;

//Implementation of the functions exposed in nan.h
wifi_error nan_register_handler(wifi_interface_handle iface,
                                NanCallbackHandler handlers)
{
    // Obtain the singleton instance
    wifi_error ret;
    NanCommand *nanCommand = NULL;
    wifi_handle wifiHandle = getWifiHandle(iface);

    nanCommand = NanCommand::instance(wifiHandle);
    if (nanCommand == NULL) {
        ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
        return WIFI_ERROR_UNKNOWN;
    }

    ret = nanCommand->setCallbackHandler(handlers);
    return ret;
}

wifi_error nan_get_version(wifi_handle handle,
                           NanVersion* version)
{
    *version = (NAN_MAJOR_VERSION <<16 | NAN_MINOR_VERSION << 8 | NAN_MICRO_VERSION);
    return WIFI_SUCCESS;
}

/*  Function to send enable request to the wifi driver.*/
wifi_error nan_enable_request(transaction_id id,
                              wifi_interface_handle iface,
                              NanEnableRequest* msg)
{
    wifi_error ret;
    NanCommand *nanCommand = NULL;
    NanCommand *t_nanCommand = NULL;
    interface_info *ifaceInfo = getIfaceInfo(iface);
    wifi_handle wifiHandle = getWifiHandle(iface);
    hal_info *info = getHalInfo(wifiHandle);

    if (info == NULL) {
        ALOGE("%s: Error hal_info NULL", __FUNCTION__);
        return WIFI_ERROR_UNKNOWN;
    }

    nanCommand = new NanCommand(wifiHandle,
                                0,
                                OUI_QCA,
                                info->support_nan_ext_cmd?
                                QCA_NL80211_VENDOR_SUBCMD_NAN_EXT :
                                QCA_NL80211_VENDOR_SUBCMD_NAN);
    if (nanCommand == NULL) {
        ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
        return WIFI_ERROR_UNKNOWN;
    }

    ret = nanCommand->create();
    if (ret != WIFI_SUCCESS)
        goto cleanup;

    /* Set the interface Id of the message. */
    ret = nanCommand->set_iface_id(ifaceInfo->name);
    if (ret != WIFI_SUCCESS)
        goto cleanup;

    ret = nanCommand->putNanEnable(id, msg);
    if (ret != WIFI_SUCCESS) {
        ALOGE("%s: putNanEnable Error:%d", __FUNCTION__, ret);
        goto cleanup;
    }

    ret = nanCommand->requestEvent();
    if (ret != WIFI_SUCCESS)
        ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);

    if (ret == WIFI_SUCCESS) {
        t_nanCommand = NanCommand::instance(wifiHandle);
        if (t_nanCommand != NULL) {
            t_nanCommand->allocSvcParams();
        }
    }

cleanup:
    delete nanCommand;
    return ret;
}

/*  Function to send disable request to the wifi driver.*/
wifi_error nan_disable_request(transaction_id id,
                               wifi_interface_handle iface)
{
    wifi_error ret;
    NanCommand *nanCommand = NULL;
    NanCommand *t_nanCommand = NULL;
    interface_info *ifaceInfo = getIfaceInfo(iface);
    wifi_handle wifiHandle = getWifiHandle(iface);
    hal_info *info = getHalInfo(wifiHandle);

    if (info == NULL) {
        ALOGE("%s: Error hal_info NULL", __FUNCTION__);
        return WIFI_ERROR_UNKNOWN;
    }

    nanCommand = new NanCommand(wifiHandle,
                                0,
                                OUI_QCA,
                                info->support_nan_ext_cmd?
                                QCA_NL80211_VENDOR_SUBCMD_NAN_EXT :
                                QCA_NL80211_VENDOR_SUBCMD_NAN);
    if (nanCommand == NULL) {
        ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
        return WIFI_ERROR_UNKNOWN;
    }

    ret = nanCommand->create();
    if (ret != WIFI_SUCCESS)
        goto cleanup;

    /* Set the interface Id of the message. */
    ret = nanCommand->set_iface_id(ifaceInfo->name);
    if (ret != WIFI_SUCCESS)
        goto cleanup;

    ret = nanCommand->putNanDisable(id);
    if (ret != WIFI_SUCCESS) {
        ALOGE("%s: putNanDisable Error:%d",__FUNCTION__, ret);
        goto cleanup;
    }

    ret = nanCommand->requestEvent();
    if (ret != WIFI_SUCCESS)
        ALOGE("%s: requestEvent Error:%d",__FUNCTION__, ret);

    if (ret == WIFI_SUCCESS) {
        t_nanCommand = NanCommand::instance(wifiHandle);
        if (t_nanCommand != NULL) {
            t_nanCommand->deallocSvcParams();
        }
    }

cleanup:
    delete nanCommand;
    return ret;
}

/*  Function to send publish request to the wifi driver.*/
wifi_error nan_publish_request(transaction_id id,
                               wifi_interface_handle iface,
                               NanPublishRequest* msg)
{
    wifi_error ret;
    NanCommand *nanCommand = NULL;
    interface_info *ifaceInfo = getIfaceInfo(iface);
    wifi_handle wifiHandle = getWifiHandle(iface);
    hal_info *info = getHalInfo(wifiHandle);

    if (info == NULL) {
        ALOGE("%s: Error hal_info NULL", __FUNCTION__);
        return WIFI_ERROR_UNKNOWN;
    }

    nanCommand = new NanCommand(wifiHandle,
                                0,
                                OUI_QCA,
                                info->support_nan_ext_cmd?
                                QCA_NL80211_VENDOR_SUBCMD_NAN_EXT :
                                QCA_NL80211_VENDOR_SUBCMD_NAN);
    if (nanCommand == NULL) {
        ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
        return WIFI_ERROR_UNKNOWN;
    }

    ret = nanCommand->create();
    if (ret != WIFI_SUCCESS)
        goto cleanup;

    /* Set the interface Id of the message. */
    ret = nanCommand->set_iface_id(ifaceInfo->name);
    if (ret != WIFI_SUCCESS)
        goto cleanup;

    ret = nanCommand->putNanPublish(id, msg);
    if (ret != WIFI_SUCCESS) {
        ALOGE("%s: putNanPublish Error:%d",__FUNCTION__, ret);
        goto cleanup;
    }

    ret = nanCommand->requestEvent();
    if (ret != WIFI_SUCCESS)
        ALOGE("%s: requestEvent Error:%d",__FUNCTION__, ret);

cleanup:
    delete nanCommand;
    return ret;
}

/*  Function to send publish cancel to the wifi driver.*/
wifi_error nan_publish_cancel_request(transaction_id id,
                                      wifi_interface_handle iface,
                                      NanPublishCancelRequest* msg)
{
    wifi_error ret;
    NanCommand *nanCommand = NULL;
    interface_info *ifaceInfo = getIfaceInfo(iface);
    wifi_handle wifiHandle = getWifiHandle(iface);
    hal_info *info = getHalInfo(wifiHandle);

    if (info == NULL) {
        ALOGE("%s: Error hal_info NULL", __FUNCTION__);
        return WIFI_ERROR_UNKNOWN;
    }

    nanCommand = new NanCommand(wifiHandle,
                                0,
                                OUI_QCA,
                                info->support_nan_ext_cmd?
                                QCA_NL80211_VENDOR_SUBCMD_NAN_EXT :
                                QCA_NL80211_VENDOR_SUBCMD_NAN);
    if (nanCommand == NULL) {
        ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
        return WIFI_ERROR_UNKNOWN;
    }

    ret = nanCommand->create();
    if (ret != WIFI_SUCCESS)
        goto cleanup;

    /* Set the interface Id of the message. */
    ret = nanCommand->set_iface_id(ifaceInfo->name);
    if (ret != WIFI_SUCCESS)
        goto cleanup;

    ret = nanCommand->putNanPublishCancel(id, msg);
    if (ret != WIFI_SUCCESS) {
        ALOGE("%s: putNanPublishCancel Error:%d", __FUNCTION__, ret);
        goto cleanup;
    }

    ret = nanCommand->requestEvent();
    if (ret != WIFI_SUCCESS)
        ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);

cleanup:
    delete nanCommand;
    return ret;
}

/*  Function to send Subscribe request to the wifi driver.*/
wifi_error nan_subscribe_request(transaction_id id,
                                 wifi_interface_handle iface,
                                 NanSubscribeRequest* msg)
{
    wifi_error ret;
    NanCommand *nanCommand = NULL;
    interface_info *ifaceInfo = getIfaceInfo(iface);
    wifi_handle wifiHandle = getWifiHandle(iface);
    hal_info *info = getHalInfo(wifiHandle);

    if (info == NULL) {
        ALOGE("%s: Error hal_info NULL", __FUNCTION__);
        return WIFI_ERROR_UNKNOWN;
    }

    nanCommand = new NanCommand(wifiHandle,
                                0,
                                OUI_QCA,
                                info->support_nan_ext_cmd?
                                QCA_NL80211_VENDOR_SUBCMD_NAN_EXT :
                                QCA_NL80211_VENDOR_SUBCMD_NAN);
    if (nanCommand == NULL) {
        ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
        return WIFI_ERROR_UNKNOWN;
    }

    ret = nanCommand->create();
    if (ret != WIFI_SUCCESS)
        goto cleanup;

    /* Set the interface Id of the message. */
    ret = nanCommand->set_iface_id(ifaceInfo->name);
    if (ret != WIFI_SUCCESS)
        goto cleanup;

    ret = nanCommand->putNanSubscribe(id, msg);
    if (ret != WIFI_SUCCESS) {
        ALOGE("%s: putNanSubscribe Error:%d", __FUNCTION__, ret);
        goto cleanup;
    }

    ret = nanCommand->requestEvent();
    if (ret != WIFI_SUCCESS)
        ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);

cleanup:
    delete nanCommand;
    return ret;
}

/*  Function to cancel subscribe to the wifi driver.*/
wifi_error nan_subscribe_cancel_request(transaction_id id,
                                        wifi_interface_handle iface,
                                        NanSubscribeCancelRequest* msg)
{
    wifi_error ret;
    NanCommand *nanCommand = NULL;
    NanCommand *t_nanCommand = NULL;
    interface_info *ifaceInfo = getIfaceInfo(iface);
    wifi_handle wifiHandle = getWifiHandle(iface);
    hal_info *info = getHalInfo(wifiHandle);

    if (info == NULL) {
        ALOGE("%s: Error hal_info NULL", __FUNCTION__);
        return WIFI_ERROR_UNKNOWN;
    }

    nanCommand = new NanCommand(wifiHandle,
                                0,
                                OUI_QCA,
                                info->support_nan_ext_cmd?
                                QCA_NL80211_VENDOR_SUBCMD_NAN_EXT :
                                QCA_NL80211_VENDOR_SUBCMD_NAN);
    if (nanCommand == NULL) {
        ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
        return WIFI_ERROR_UNKNOWN;
    }

    ret = nanCommand->create();
    if (ret != WIFI_SUCCESS)
        goto cleanup;

    /* Set the interface Id of the message. */
    ret = nanCommand->set_iface_id(ifaceInfo->name);
    if (ret != WIFI_SUCCESS)
        goto cleanup;

    ret = nanCommand->putNanSubscribeCancel(id, msg);
    if (ret != WIFI_SUCCESS) {
        ALOGE("%s: putNanSubscribeCancel Error:%d", __FUNCTION__, ret);
        goto cleanup;
    }

    ret = nanCommand->requestEvent();
    if (ret != WIFI_SUCCESS)
        ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);

    if (ret == WIFI_SUCCESS) {
        t_nanCommand = NanCommand::instance(wifiHandle);
        if (t_nanCommand != NULL) {
            t_nanCommand->deleteServiceId(msg->subscribe_id,
                                          0, NAN_ROLE_SUBSCRIBER);
        }
    }

cleanup:
    delete nanCommand;
    return ret;
}

/*  Function to send NAN follow up request to the wifi driver.*/
wifi_error nan_transmit_followup_request(transaction_id id,
                                         wifi_interface_handle iface,
                                         NanTransmitFollowupRequest* msg)
{
    wifi_error ret;
    NanCommand *nanCommand = NULL;
    interface_info *ifaceInfo = getIfaceInfo(iface);
    wifi_handle wifiHandle = getWifiHandle(iface);
    hal_info *info = getHalInfo(wifiHandle);

    if (info == NULL) {
        ALOGE("%s: Error hal_info NULL", __FUNCTION__);
        return WIFI_ERROR_UNKNOWN;
    }

    nanCommand = new NanCommand(wifiHandle,
                                0,
                                OUI_QCA,
                                info->support_nan_ext_cmd?
                                QCA_NL80211_VENDOR_SUBCMD_NAN_EXT :
                                QCA_NL80211_VENDOR_SUBCMD_NAN);
    if (nanCommand == NULL) {
        ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
        return WIFI_ERROR_UNKNOWN;
    }

    ret = nanCommand->create();
    if (ret != WIFI_SUCCESS)
        goto cleanup;

    /* Set the interface Id of the message. */
    ret = nanCommand->set_iface_id(ifaceInfo->name);
    if (ret != WIFI_SUCCESS)
        goto cleanup;

    ret = nanCommand->putNanTransmitFollowup(id, msg);
    if (ret != WIFI_SUCCESS) {
        ALOGE("%s: putNanTransmitFollowup Error:%d", __FUNCTION__, ret);
        goto cleanup;
    }

    ret = nanCommand->requestEvent();
    if (ret != WIFI_SUCCESS)
        ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);

cleanup:
    delete nanCommand;
    return ret;
}

/*  Function to send NAN statistics request to the wifi driver.*/
wifi_error nan_stats_request(transaction_id id,
                             wifi_interface_handle iface,
                             NanStatsRequest* msg)
{
    wifi_error ret;
    NanCommand *nanCommand = NULL;
    interface_info *ifaceInfo = getIfaceInfo(iface);
    wifi_handle wifiHandle = getWifiHandle(iface);
    hal_info *info = getHalInfo(wifiHandle);

    if (info == NULL) {
        ALOGE("%s: Error hal_info NULL", __FUNCTION__);
        return WIFI_ERROR_UNKNOWN;
    }

    nanCommand = new NanCommand(wifiHandle,
                                0,
                                OUI_QCA,
                                info->support_nan_ext_cmd?
                                QCA_NL80211_VENDOR_SUBCMD_NAN_EXT :
                                QCA_NL80211_VENDOR_SUBCMD_NAN);
    if (nanCommand == NULL) {
        ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
        return WIFI_ERROR_UNKNOWN;
    }

    ret = nanCommand->create();
    if (ret != WIFI_SUCCESS)
        goto cleanup;

    /* Set the interface Id of the message. */
    ret = nanCommand->set_iface_id(ifaceInfo->name);
    if (ret != WIFI_SUCCESS)
        goto cleanup;

    ret = nanCommand->putNanStats(id, msg);
    if (ret != WIFI_SUCCESS) {
        ALOGE("%s: putNanStats Error:%d", __FUNCTION__, ret);
        goto cleanup;
    }

    ret = nanCommand->requestEvent();
    if (ret != WIFI_SUCCESS)
        ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);

cleanup:
    delete nanCommand;
    return ret;
}

/*  Function to send NAN configuration request to the wifi driver.*/
wifi_error nan_config_request(transaction_id id,
                              wifi_interface_handle iface,
                              NanConfigRequest* msg)
{
    wifi_error ret;
    NanCommand *nanCommand = NULL;
    interface_info *ifaceInfo = getIfaceInfo(iface);
    wifi_handle wifiHandle = getWifiHandle(iface);
    hal_info *info = getHalInfo(wifiHandle);

    if (info == NULL) {
        ALOGE("%s: Error hal_info NULL", __FUNCTION__);
        return WIFI_ERROR_UNKNOWN;
    }

    nanCommand = new NanCommand(wifiHandle,
                                0,
                                OUI_QCA,
                                info->support_nan_ext_cmd?
                                QCA_NL80211_VENDOR_SUBCMD_NAN_EXT :
                                QCA_NL80211_VENDOR_SUBCMD_NAN);
    if (nanCommand == NULL) {
        ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
        return WIFI_ERROR_UNKNOWN;
    }

    ret = nanCommand->create();
    if (ret != WIFI_SUCCESS)
        goto cleanup;

    /* Set the interface Id of the message. */
    ret = nanCommand->set_iface_id(ifaceInfo->name);
    if (ret != WIFI_SUCCESS)
        goto cleanup;

    ret = nanCommand->putNanConfig(id, msg);
    if (ret != WIFI_SUCCESS) {
        ALOGE("%s: putNanConfig Error:%d",__FUNCTION__, ret);
        goto cleanup;
    }

    ret = nanCommand->requestEvent();
    if (ret != WIFI_SUCCESS)
        ALOGE("%s: requestEvent Error:%d",__FUNCTION__, ret);

cleanup:
    delete nanCommand;
    return ret;
}

/*  Function to send NAN request to the wifi driver.*/
wifi_error nan_tca_request(transaction_id id,
                           wifi_interface_handle iface,
                           NanTCARequest* msg)
{
    wifi_error ret;
    NanCommand *nanCommand = NULL;
    interface_info *ifaceInfo = getIfaceInfo(iface);
    wifi_handle wifiHandle = getWifiHandle(iface);
    hal_info *info = getHalInfo(wifiHandle);

    if (info == NULL) {
        ALOGE("%s: Error hal_info NULL", __FUNCTION__);
        return WIFI_ERROR_UNKNOWN;
    }

    nanCommand = new NanCommand(wifiHandle,
                                0,
                                OUI_QCA,
                                info->support_nan_ext_cmd?
                                QCA_NL80211_VENDOR_SUBCMD_NAN_EXT :
                                QCA_NL80211_VENDOR_SUBCMD_NAN);
    if (nanCommand == NULL) {
        ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
        return WIFI_ERROR_UNKNOWN;
    }

    ret = nanCommand->create();
    if (ret != WIFI_SUCCESS)
        goto cleanup;

    /* Set the interface Id of the message. */
    ret = nanCommand->set_iface_id(ifaceInfo->name);
    if (ret != WIFI_SUCCESS)
        goto cleanup;

    ret = nanCommand->putNanTCA(id, msg);
    if (ret != WIFI_SUCCESS) {
        ALOGE("%s: putNanTCA Error:%d",__FUNCTION__, ret);
        goto cleanup;
    }

    ret = nanCommand->requestEvent();
    if (ret != WIFI_SUCCESS)
        ALOGE("%s: requestEvent Error:%d",__FUNCTION__, ret);

cleanup:
    delete nanCommand;
    return ret;
}

/*  Function to send NAN Beacon sdf payload to the wifi driver.
    This instructs the Discovery Engine to begin publishing the
    received payload in any Beacon or Service Discovery Frame
    transmitted*/
wifi_error nan_beacon_sdf_payload_request(transaction_id id,
                                         wifi_interface_handle iface,
                                         NanBeaconSdfPayloadRequest* msg)
{
    wifi_error ret;
    NanCommand *nanCommand = NULL;
    interface_info *ifaceInfo = getIfaceInfo(iface);
    wifi_handle wifiHandle = getWifiHandle(iface);
    hal_info *info = getHalInfo(wifiHandle);

    if (info == NULL) {
        ALOGE("%s: Error hal_info NULL", __FUNCTION__);
        return WIFI_ERROR_UNKNOWN;
    }

    nanCommand = new NanCommand(wifiHandle,
                                0,
                                OUI_QCA,
                                info->support_nan_ext_cmd?
                                QCA_NL80211_VENDOR_SUBCMD_NAN_EXT :
                                QCA_NL80211_VENDOR_SUBCMD_NAN);
    if (nanCommand == NULL) {
        ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
        return WIFI_ERROR_UNKNOWN;
    }

    ret = nanCommand->create();
    if (ret != WIFI_SUCCESS)
        goto cleanup;

    /* Set the interface Id of the message. */
    ret = nanCommand->set_iface_id(ifaceInfo->name);
    if (ret != WIFI_SUCCESS)
        goto cleanup;

    ret = nanCommand->putNanBeaconSdfPayload(id, msg);
    if (ret != WIFI_SUCCESS) {
        ALOGE("%s: putNanBeaconSdfPayload Error:%d", __FUNCTION__, ret);
        goto cleanup;
    }

    ret = nanCommand->requestEvent();
    if (ret != WIFI_SUCCESS)
        ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);

cleanup:
    delete nanCommand;
    return ret;
}

wifi_error nan_get_sta_parameter(transaction_id id,
                                 wifi_interface_handle iface,
                                 NanStaParameter* msg)
{
    wifi_error ret;
    NanCommand *nanCommand = NULL;
    wifi_handle wifiHandle = getWifiHandle(iface);

    nanCommand = NanCommand::instance(wifiHandle);
    if (nanCommand == NULL) {
        ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
        return WIFI_ERROR_UNKNOWN;
    }

    ret = nanCommand->getNanStaParameter(iface, msg);
    if (ret != WIFI_SUCCESS) {
        ALOGE("%s: getNanStaParameter Error:%d", __FUNCTION__, ret);
        goto cleanup;
    }

cleanup:
    return ret;
}

/*  Function to get NAN capabilities */
wifi_error nan_get_capabilities(transaction_id id,
                                wifi_interface_handle iface)
{
    wifi_error ret;
    NanCommand *nanCommand = NULL;
    interface_info *ifaceInfo = getIfaceInfo(iface);
    wifi_handle wifiHandle = getWifiHandle(iface);
    hal_info *info = getHalInfo(wifiHandle);

    if (info == NULL) {
        ALOGE("%s: Error hal_info NULL", __FUNCTION__);
        return WIFI_ERROR_UNKNOWN;
    }

    nanCommand = new NanCommand(wifiHandle,
                                0,
                                OUI_QCA,
                                info->support_nan_ext_cmd?
                                QCA_NL80211_VENDOR_SUBCMD_NAN_EXT :
                                QCA_NL80211_VENDOR_SUBCMD_NAN);
    if (nanCommand == NULL) {
        ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
        return WIFI_ERROR_UNKNOWN;
    }

    ret = nanCommand->create();
    if (ret != WIFI_SUCCESS)
        goto cleanup;

    /* Set the interface Id of the message. */
    ret = nanCommand->set_iface_id(ifaceInfo->name);
    if (ret != WIFI_SUCCESS)
        goto cleanup;

    ret = nanCommand->putNanCapabilities(id);
    if (ret != WIFI_SUCCESS) {
        ALOGE("%s: putNanCapabilities Error:%d",__FUNCTION__, ret);
        goto cleanup;
    }

    ret = nanCommand->requestEvent();
    if (ret != WIFI_SUCCESS)
        ALOGE("%s: requestEvent Error:%d",__FUNCTION__, ret);

cleanup:
    delete nanCommand;
    return ret;
}

/*  Function to get NAN capabilities */
wifi_error nan_debug_command_config(transaction_id id,
                                   wifi_interface_handle iface,
                                   NanDebugParams debug,
                                   int debug_msg_length)
{
    wifi_error ret;
    NanCommand *nanCommand = NULL;
    interface_info *ifaceInfo = getIfaceInfo(iface);
    wifi_handle wifiHandle = getWifiHandle(iface);
    hal_info *info = getHalInfo(wifiHandle);

    if (info == NULL) {
        ALOGE("%s: Error hal_info NULL", __FUNCTION__);
        return WIFI_ERROR_UNKNOWN;
    }

    if (debug_msg_length <= 0) {
        ALOGE("%s: Invalid debug message length = %d", __FUNCTION__,
                                                       debug_msg_length);
        return WIFI_ERROR_UNKNOWN;
    }

    nanCommand = new NanCommand(wifiHandle,
                                0,
                                OUI_QCA,
                                info->support_nan_ext_cmd?
                                QCA_NL80211_VENDOR_SUBCMD_NAN_EXT :
                                QCA_NL80211_VENDOR_SUBCMD_NAN);
    if (nanCommand == NULL) {
        ALOGE("%s: Error NanCommand NULL", __FUNCTION__);
        return WIFI_ERROR_UNKNOWN;
    }

    ret = nanCommand->create();
    if (ret != WIFI_SUCCESS)
        goto cleanup;

    /* Set the interface Id of the message. */
    ret = nanCommand->set_iface_id(ifaceInfo->name);
    if (ret != WIFI_SUCCESS)
        goto cleanup;

    ret = nanCommand->putNanDebugCommand(debug, debug_msg_length);
    if (ret != WIFI_SUCCESS) {
        ALOGE("%s: putNanDebugCommand Error:%d",__FUNCTION__, ret);
        goto cleanup;
    }

    ret = nanCommand->requestEvent();
    if (ret != WIFI_SUCCESS)
        ALOGE("%s: requestEvent Error:%d",__FUNCTION__, ret);

cleanup:
    delete nanCommand;
    return ret;
}

wifi_error nan_initialize_vendor_cmd(wifi_interface_handle iface,
                                     NanCommand **nanCommand)
{
    wifi_error ret;
    interface_info *ifaceInfo = getIfaceInfo(iface);
    wifi_handle wifiHandle = getWifiHandle(iface);

    if (nanCommand == NULL) {
        ALOGE("%s: Error nanCommand NULL", __FUNCTION__);
        return WIFI_ERROR_INVALID_ARGS;
    }

    *nanCommand = new NanCommand(wifiHandle,
                                 0,
                                 OUI_QCA,
                                 QCA_NL80211_VENDOR_SUBCMD_NDP);
    if (*nanCommand == NULL) {
        ALOGE("%s: Object creation failed", __FUNCTION__);
        return WIFI_ERROR_OUT_OF_MEMORY;
    }

    /* Create the message */
    ret = (*nanCommand)->create();
    if (ret != WIFI_SUCCESS)
        goto cleanup;

    ret = (*nanCommand)->set_iface_id(ifaceInfo->name);
    if (ret != WIFI_SUCCESS)
        goto cleanup;

    return WIFI_SUCCESS;

cleanup:
    delete *nanCommand;
    return ret;
}

wifi_error nan_data_interface_create(transaction_id id,
                                     wifi_interface_handle iface,
                                     char* iface_name)
{
    ALOGV("NAN_DP_INTERFACE_CREATE");
    wifi_error ret;
    struct nlattr *nlData;
    NanCommand *nanCommand = NULL;
    WiFiConfigCommand *wifiConfigCommand;
    wifi_handle handle = getWifiHandle(iface);
    hal_info *info = getHalInfo(handle);
    bool ndi_created = false;

    if (iface_name == NULL) {
        ALOGE("%s: Invalid Nan Data Interface Name. \n", __FUNCTION__);
        return WIFI_ERROR_INVALID_ARGS;
    }

    if (!info || info->num_interfaces < 1) {
        ALOGE("%s: Error wifi_handle NULL or base wlan interface not present",
              __FUNCTION__);
        return WIFI_ERROR_UNKNOWN;
    }

    if (check_feature(QCA_WLAN_VENDOR_FEATURE_USE_ADD_DEL_VIRTUAL_INTF_FOR_NDI,
                      &info->driver_supported_features)) {
        wifiConfigCommand = new WiFiConfigCommand(handle,
                                                  get_requestid(), 0, 0);
        if (wifiConfigCommand == NULL) {
            ALOGE("%s: Error wifiConfigCommand NULL", __FUNCTION__);
            return WIFI_ERROR_UNKNOWN;
        }
        wifiConfigCommand->create_generic(NL80211_CMD_NEW_INTERFACE);
        wifiConfigCommand->put_u32(NL80211_ATTR_IFINDEX,
                                   info->interfaces[0]->id);
        wifiConfigCommand->put_string(NL80211_ATTR_IFNAME, iface_name);
        wifiConfigCommand->put_u32(NL80211_ATTR_IFTYPE,
                                   NL80211_IFTYPE_STATION);
        /* Send the NL msg. */
        wifiConfigCommand->waitForRsp(false);
        ret = wifiConfigCommand->requestEvent();
        if (ret != WIFI_SUCCESS) {
            ALOGE("%s: Create intf failed, Error:%d", __FUNCTION__, ret);
            delete wifiConfigCommand;
            return ret;
        }
        ndi_created = true;
        delete wifiConfigCommand;
    }

    ret = nan_initialize_vendor_cmd(iface, &nanCommand);
    if (ret != WIFI_SUCCESS) {
        ALOGE("%s: Initialization failed", __FUNCTION__);
        goto delete_ndi;
    }

    /* Add the vendor specific attributes for the NL command. */
    nlData = nanCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
    if (!nlData) {
        ret = WIFI_ERROR_UNKNOWN;
        goto cleanup;
    }

    if (nanCommand->put_u32(
            QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
            QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE) ||
        nanCommand->put_u16(
            QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
            id) ||
        nanCommand->put_string(
            QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR,
            iface_name)) {
        ret = WIFI_ERROR_UNKNOWN;
        goto cleanup;
    }

    nanCommand->attr_end(nlData);

    ret = nanCommand->requestEvent();
    if (ret != WIFI_SUCCESS)
        ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);

cleanup:
    delete nanCommand;

delete_ndi:
    if (ndi_created && ret != WIFI_SUCCESS) {
        wifiConfigCommand = new WiFiConfigCommand(handle,
                                                  get_requestid(), 0, 0);
        if (wifiConfigCommand == NULL) {
            ALOGE("%s: Error wifiConfigCommand NULL", __FUNCTION__);
            return ret;
        }
        wifiConfigCommand->create_generic(NL80211_CMD_DEL_INTERFACE);
        wifiConfigCommand->put_u32(NL80211_ATTR_IFINDEX,
                                   if_nametoindex(iface_name));
        /* Send the NL msg. */
        wifiConfigCommand->waitForRsp(false);
        if (wifiConfigCommand->requestEvent() != WIFI_SUCCESS)
            ALOGE("%s: Delete intf failed", __FUNCTION__);

        delete wifiConfigCommand;
    }
    return ret;
}

wifi_error nan_data_interface_delete(transaction_id id,
                                     wifi_interface_handle iface,
                                     char* iface_name)
{
    ALOGV("NAN_DP_INTERFACE_DELETE");
    wifi_error ret;
    struct nlattr *nlData;
    NanCommand *nanCommand = NULL;
    WiFiConfigCommand *wifiConfigCommand;
    wifi_handle handle = getWifiHandle(iface);
    hal_info *info = getHalInfo(handle);

    if (iface_name == NULL || if_nametoindex(iface_name) == 0) {
        ALOGE("%s: Invalid/Unknown Nan Data Interface Name. \n", __FUNCTION__);
        return WIFI_ERROR_INVALID_ARGS;
    }

    if (!info || info->num_interfaces < 1) {
        ALOGE("%s: Error wifi_handle NULL or base wlan interface not present",
          __FUNCTION__);
        return WIFI_ERROR_UNKNOWN;
    }

    // NL80211_CMD_DEL_INTERFACE internally takes care of NDP cleanup.
    if ((check_feature(QCA_WLAN_VENDOR_FEATURE_USE_ADD_DEL_VIRTUAL_INTF_FOR_NDI,
                       &info->driver_supported_features)) &&
        if_nametoindex(iface_name)) {
        wifiConfigCommand = new WiFiConfigCommand(handle,
                                                  get_requestid(), 0, 0);
        if (wifiConfigCommand == NULL) {
            ALOGE("%s: Error wifiConfigCommand NULL", __FUNCTION__);
            return WIFI_ERROR_UNKNOWN;
        }
        wifiConfigCommand->create_generic(NL80211_CMD_DEL_INTERFACE);
        wifiConfigCommand->put_u32(NL80211_ATTR_IFINDEX,
                                   if_nametoindex(iface_name));
        /* Send the NL msg. */
        wifiConfigCommand->waitForRsp(false);
        if (wifiConfigCommand->requestEvent() != WIFI_SUCCESS) {
            ALOGE("%s: Delete intf failed", __FUNCTION__);
        }
        delete wifiConfigCommand;
        return WIFI_SUCCESS;
    }

    ret = nan_initialize_vendor_cmd(iface,
                                    &nanCommand);
    if (ret != WIFI_SUCCESS) {
        ALOGE("%s: Initialization failed", __FUNCTION__);
        return ret;
    }

    /* Add the vendor specific attributes for the NL command. */
    nlData = nanCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
    if (!nlData) {
        ret = WIFI_ERROR_UNKNOWN;
        goto cleanup;
    }

    if (nanCommand->put_u32(
            QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
            QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE) ||
        nanCommand->put_u16(
            QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
            id) ||
        nanCommand->put_string(
            QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR,
            iface_name)) {
        ret = WIFI_ERROR_UNKNOWN;
        goto cleanup;
    }

    nanCommand->attr_end(nlData);

    ret = nanCommand->requestEvent();
    if (ret != WIFI_SUCCESS)
        ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);

cleanup:
    delete nanCommand;
    return ret;
}

/* Service ID using SHA256 */
static bool
ndp_create_service_id(const u8 *service_name,
                      u32 service_name_len, u8 *service_id)
{
    u8 out_service_id[NAN_SVC_HASH_SIZE] = {0};
    u8 *mod_service_name;
    unsigned char prop_oob_service_name[NAN_DEF_SVC_NAME_LEN + 1] =
                                                        "Wi-Fi Aware Data Path";
    unsigned char prop_oob_service_name_lowercase[NAN_DEF_SVC_NAME_LEN + 1] =
                                                        "wi-fi aware data path";
    bool is_default = false;
    int i;

    if (!service_name) {
        ALOGE("%s: NULL service name", __FUNCTION__);
        return false;
    }

    if (!service_name_len) {
        ALOGE("%s: Zero service name length", __FUNCTION__);
        return false;
    }

    if (!service_id) {
        ALOGE("%s: NULL service ID", __FUNCTION__);
        return false;
    }

    mod_service_name = (u8 *)malloc(service_name_len);
    if (!mod_service_name) {
        ALOGE("%s: malloc failed", __FUNCTION__);
        return false;
    }

    memset(mod_service_name, 0, service_name_len);
    memcpy(mod_service_name, service_name, service_name_len);
    if ((service_name_len == NAN_DEF_SVC_NAME_LEN) &&
        (!memcmp(mod_service_name, prop_oob_service_name, service_name_len)
         || !memcmp(mod_service_name,
                    prop_oob_service_name_lowercase, service_name_len)))
        is_default = true;

    for (i = 0; i < service_name_len; i++) {
    /*
     * As per NAN spec, the only acceptable singlebyte UTF-8 symbols for a
     * Service Name are alphanumeric values (A-Z, a-z, 0-9), the hyphen ('-'),
     * the underscore ('_'), and the period ('.').
     * These checks are added for all service names except the above defined
     * default service name.
     */
        if (!is_default && !isalnum(mod_service_name[i]) &&
            (mod_service_name[i] != '_') && (mod_service_name[i] != '-') &&
            (mod_service_name[i] != '.')) {
             free(mod_service_name);
             return false;
        }

        if ((mod_service_name[i] == ' ') && (is_default))
             goto end;

        /*
         * The service_name hash SHALL always be done on a lower-case
         * version of service_name which was passed down. Therefore,
         * before passing the service_name to the SHA256 function first
         * run through the string and call tolower on each byte.
         */
        mod_service_name[i] = tolower(mod_service_name[i]);
    }

end:
    SHA256(mod_service_name, service_name_len, out_service_id);
    /*
     * As per NAN spec, Service ID is the first 48 bits of the SHA-256 hash
     * of the Service Name
     */
    memcpy(service_id, out_service_id, NAN_SVC_ID_SIZE);

    free(mod_service_name);
    return true;
}

/*
 * PMK = PBKDF2(<pass phrase>, <Salt Version>||<Cipher Suite ID>||<Service ID>||
 *              <Publisher NMI>, 4096, 32)
 * ndp_passphrase_to_pmk: API to calculate the service ID and PMK.
 * @pmk: output value of Hash
 * @passphrase: secret key
 * @salt_version: 00
 * @csid: cipher suite ID: 01
 * As per NAN spec, below are the values defined for CSID attribute:
 *     1 - NCS-SK-128 Cipher Suite
 *     2 - NCS-SK-256 Cipher Suite
 *     3 - NCS-PK-2WDH-128 Cipher Suite
 *     4 - NCS-PK-2WDH-256 Cipher Suite
 *     Other values are reserved
 * @service_id: Hash value of SHA256 on service_name
 * @peer_mac: Publisher NAN Management Interface address
 * @iterations: 4096
 * @pmk_len: 32
 */
static int
ndp_passphrase_to_pmk(u32 cipher_type, u8 *pmk, u8 *passphrase,
                      u32 passphrase_len, u8 *service_name,
                      u32 service_name_len, u8 *svc_id, u8 *peer_mac)
{
    int result = 0;
    u8 pmk_hex[NAN_PMK_INFO_LEN] = {0};
    u8 salt[NAN_SECURITY_SALT_SIZE] = {0};
    u8 service_id[NAN_SVC_ID_SIZE] = {0};
    unsigned char *pos = NULL;
    unsigned char salt_version = 0;
    u8 csid;
    /* We read only first 3-bits, as only 1-4 values are expected currently */
    csid = (u8)(cipher_type & 0x7);
    if (csid == 0)
        csid = NAN_DEFAULT_NCS_SK;

    if (svc_id != NULL) {
        ALOGV("Service ID received from the pool");
        memcpy(service_id, svc_id, NAN_SVC_ID_SIZE);
    } else if (ndp_create_service_id((const u8 *)service_name,
                                     service_name_len, service_id) == false) {
        ALOGE("Failed to create service ID");
        return result;
    }

    pos = salt;
    /* salt version */
    *pos++ = salt_version;
    /* CSID */
    *pos++ = csid;
    /* Service ID */
    memcpy(pos, service_id, NAN_SVC_ID_SIZE);
    pos += NAN_SVC_ID_SIZE;
    /* Publisher NMI */
    memcpy(pos, peer_mac, NAN_MAC_ADDR_LEN);
    pos += NAN_MAC_ADDR_LEN;

    ALOGV("salt dump");
    hexdump(salt, NAN_SECURITY_SALT_SIZE);

    result = PKCS5_PBKDF2_HMAC((const char *)passphrase, passphrase_len, salt,
                               sizeof(salt), NAN_PMK_ITERATIONS,
                               (const EVP_MD *) EVP_sha256(),
                               NAN_PMK_INFO_LEN, pmk_hex);
    if (result)
        memcpy(pmk, pmk_hex, NAN_PMK_INFO_LEN);

    return result;
}

wifi_error nan_data_request_initiator(transaction_id id,
                                      wifi_interface_handle iface,
                                      NanDataPathInitiatorRequest* msg)
{
    ALOGV("NAN_DP_REQUEST_INITIATOR");
    wifi_error ret;
    struct nlattr *nlData, *nlCfgQos;
    NanCommand *nanCommand = NULL;
    NanCommand *t_nanCommand = NULL;
    wifi_handle wifiHandle = getWifiHandle(iface);

    if (msg == NULL)
        return WIFI_ERROR_INVALID_ARGS;

    ret = nan_initialize_vendor_cmd(iface,
                                    &nanCommand);
    if (ret != WIFI_SUCCESS) {
        ALOGE("%s: Initialization failed", __FUNCTION__);
        return ret;
    }

    t_nanCommand = NanCommand::instance(wifiHandle);
    if (t_nanCommand == NULL)
        ALOGE("%s: Error NanCommand NULL", __FUNCTION__);

    if ((msg->cipher_type != NAN_CIPHER_SUITE_SHARED_KEY_NONE) &&
        (msg->key_info.body.pmk_info.pmk_len == 0) &&
        (msg->key_info.body.passphrase_info.passphrase_len == 0)) {
        ALOGE("%s: Failed-Initiator req, missing pmk and passphrase",
               __FUNCTION__);
        return WIFI_ERROR_INVALID_ARGS;
    }

    if ((msg->cipher_type != NAN_CIPHER_SUITE_SHARED_KEY_NONE) &&
        (msg->requestor_instance_id == OUT_OF_BAND_SERVICE_INSTANCE_ID) &&
        (msg->service_name_len == 0)) {
        ALOGE("%s: Failed-Initiator req, missing service name for out of band request",
              __FUNCTION__);
        return WIFI_ERROR_INVALID_ARGS;
    }

    /* Add the vendor specific attributes for the NL command. */
    nlData = nanCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
    if (!nlData){
        ret = WIFI_ERROR_UNKNOWN;
        goto cleanup;
    }

    if (nanCommand->put_u32(
            QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
            QCA_WLAN_VENDOR_ATTR_NDP_INITIATOR_REQUEST) ||
        nanCommand->put_u16(
            QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
            id) ||
        nanCommand->put_u32(
            QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID,
            msg->requestor_instance_id) ||
        nanCommand->put_bytes(
            QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR,
            (char *)msg->peer_disc_mac_addr,
            NAN_MAC_ADDR_LEN) ||
        nanCommand->put_string(
            QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR,
            msg->ndp_iface)) {
        ret = WIFI_ERROR_UNKNOWN;
        goto cleanup;
    }

    if (msg->channel_request_type != NAN_DP_CHANNEL_NOT_REQUESTED) {
        if (nanCommand->put_u32 (
                QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_CONFIG,
                msg->channel_request_type) ||
            nanCommand->put_u32(
                QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL,
                msg->channel)){
            ret = WIFI_ERROR_UNKNOWN;
            goto cleanup;
        }
    }

    if (msg->app_info.ndp_app_info_len != 0) {
        if (nanCommand->put_bytes(
                QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO,
                (char *)msg->app_info.ndp_app_info,
                msg->app_info.ndp_app_info_len)) {
            ret = WIFI_ERROR_UNKNOWN;
            goto cleanup;
        }
    }

    if (msg->ndp_cfg.qos_cfg == NAN_DP_CONFIG_QOS) {
        nlCfgQos =
            nanCommand->attr_start(QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS);
        if (!nlCfgQos){
            ret = WIFI_ERROR_UNKNOWN;
            goto cleanup;
        }
        /* TBD Qos Info */
        nanCommand->attr_end(nlCfgQos);
    }
    if (msg->cipher_type != NAN_CIPHER_SUITE_SHARED_KEY_NONE) {
        if (nanCommand->put_u32(QCA_WLAN_VENDOR_ATTR_NDP_CSID,
                msg->cipher_type)){
            ret = WIFI_ERROR_UNKNOWN;
            goto cleanup;
        }
    }
    if (msg->key_info.key_type == NAN_SECURITY_KEY_INPUT_PMK) {
        if (msg->key_info.body.pmk_info.pmk_len != NAN_PMK_INFO_LEN) {
            ret = WIFI_ERROR_UNKNOWN;
            ALOGE("%s: Invalid pmk len:%d", __FUNCTION__,
                  msg->key_info.body.pmk_info.pmk_len);
            goto cleanup;
        }
        if (nanCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_NDP_PMK,
            (char *)msg->key_info.body.pmk_info.pmk,
            msg->key_info.body.pmk_info.pmk_len)){
            ret = WIFI_ERROR_UNKNOWN;
            goto cleanup;
        }
    } else if (msg->key_info.key_type == NAN_SECURITY_KEY_INPUT_PASSPHRASE) {
        if (msg->key_info.body.passphrase_info.passphrase_len <
            NAN_SECURITY_MIN_PASSPHRASE_LEN ||
            msg->key_info.body.passphrase_info.passphrase_len >
            NAN_SECURITY_MAX_PASSPHRASE_LEN) {
            ret = WIFI_ERROR_UNKNOWN;
            ALOGE("%s: Invalid passphrase len:%d", __FUNCTION__,
                  msg->key_info.body.passphrase_info.passphrase_len);
            goto cleanup;
        }
        u8 *service_id = NULL;

        if (t_nanCommand != NULL)
            service_id = t_nanCommand->getServiceId(msg->requestor_instance_id,
                                                    NAN_ROLE_SUBSCRIBER);
        if (service_id == NULL)
            ALOGE("%s: Entry not found for Instance ID:%d",
                  __FUNCTION__, msg->requestor_instance_id);
        if (((service_id != NULL) || (msg->service_name_len)) &&
            ndp_passphrase_to_pmk(msg->cipher_type,
                                  msg->key_info.body.pmk_info.pmk,
                                  msg->key_info.body.passphrase_info.passphrase,
                                  msg->key_info.body.passphrase_info.passphrase_len,
                                  msg->service_name, msg->service_name_len,
                                  service_id, msg->peer_disc_mac_addr)) {
            msg->key_info.body.pmk_info.pmk_len = NAN_PMK_INFO_LEN;
            if (nanCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_NDP_PMK,
                (char *)msg->key_info.body.pmk_info.pmk,
                msg->key_info.body.pmk_info.pmk_len)){
                if (nanCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_NDP_PASSPHRASE,
                    (char *)msg->key_info.body.passphrase_info.passphrase,
                    msg->key_info.body.passphrase_info.passphrase_len)){
                    ret = WIFI_ERROR_UNKNOWN;
                    goto cleanup;
                }
            }
        } else if (nanCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_NDP_PASSPHRASE,
                   (char *)msg->key_info.body.passphrase_info.passphrase,
                   msg->key_info.body.passphrase_info.passphrase_len)) {
            ret = WIFI_ERROR_UNKNOWN;
            goto cleanup;
        }
    }
    if (msg->service_name_len) {
        if (nanCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_NAME,
            (char *)msg->service_name, msg->service_name_len)){
            ret = WIFI_ERROR_UNKNOWN;
            goto cleanup;
        }
    }
    nanCommand->attr_end(nlData);

    ret = nanCommand->requestEvent();
    if (ret != WIFI_SUCCESS)
        ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);

cleanup:
    delete nanCommand;
    return ret;
}

wifi_error nan_data_indication_response(transaction_id id,
                                        wifi_interface_handle iface,
                                        NanDataPathIndicationResponse* msg)
{
    ALOGV("NAN_DP_INDICATION_RESPONSE");
    wifi_error ret;
    struct nlattr *nlData, *nlCfgQos;
    NanCommand *nanCommand = NULL;
    NanCommand *t_nanCommand = NULL;
    wifi_handle wifiHandle = getWifiHandle(iface);

    if (msg == NULL)
        return WIFI_ERROR_INVALID_ARGS;

    ret = nan_initialize_vendor_cmd(iface,
                                    &nanCommand);
    if (ret != WIFI_SUCCESS) {
        ALOGE("%s: Initialization failed", __FUNCTION__);
        return ret;
    }

    t_nanCommand = NanCommand::instance(wifiHandle);
    if (t_nanCommand == NULL)
        ALOGE("%s: Error NanCommand NULL", __FUNCTION__);

    if ((msg->cipher_type != NAN_CIPHER_SUITE_SHARED_KEY_NONE) &&
        (msg->key_info.body.pmk_info.pmk_len == 0) &&
        (msg->key_info.body.passphrase_info.passphrase_len == 0)) {
        ALOGE("%s: Failed-Initiator req, missing pmk and passphrase",
               __FUNCTION__);
        return WIFI_ERROR_INVALID_ARGS;
    }

    /* Add the vendor specific attributes for the NL command. */
    nlData = nanCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
    if (!nlData){
        ret = WIFI_ERROR_UNKNOWN;
        goto cleanup;
    }

    if (nanCommand->put_u32(
            QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
            QCA_WLAN_VENDOR_ATTR_NDP_RESPONDER_REQUEST) ||
        nanCommand->put_u16(
            QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
            id) ||
        nanCommand->put_u32(
            QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID,
            msg->ndp_instance_id) ||
        nanCommand->put_string(
            QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR,
            msg->ndp_iface) ||
        nanCommand->put_u32(
            QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE,
            msg->rsp_code)) {
        ret = WIFI_ERROR_UNKNOWN;
        goto cleanup;
    }
    if (msg->app_info.ndp_app_info_len != 0) {
        if (nanCommand->put_bytes(
                QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO,
                (char *)msg->app_info.ndp_app_info,
                msg->app_info.ndp_app_info_len)) {
            ret = WIFI_ERROR_UNKNOWN;
            goto cleanup;
        }
    }
    if (msg->ndp_cfg.qos_cfg == NAN_DP_CONFIG_QOS) {
        nlCfgQos =
            nanCommand->attr_start(QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS);
        if (!nlCfgQos){
            ret = WIFI_ERROR_UNKNOWN;
            goto cleanup;
        }

        /* TBD Qos Info */
        nanCommand->attr_end(nlCfgQos);
    }
    if (msg->cipher_type != NAN_CIPHER_SUITE_SHARED_KEY_NONE) {
        if (nanCommand->put_u32(QCA_WLAN_VENDOR_ATTR_NDP_CSID,
                msg->cipher_type)){
            ret = WIFI_ERROR_UNKNOWN;
            goto cleanup;
        }
    }
    if (msg->key_info.key_type == NAN_SECURITY_KEY_INPUT_PMK) {
        if (msg->key_info.body.pmk_info.pmk_len != NAN_PMK_INFO_LEN) {
            ret = WIFI_ERROR_UNKNOWN;
            ALOGE("%s: Invalid pmk len:%d", __FUNCTION__,
                  msg->key_info.body.pmk_info.pmk_len);
            goto cleanup;
        }
        if (nanCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_NDP_PMK,
            (char *)msg->key_info.body.pmk_info.pmk,
            msg->key_info.body.pmk_info.pmk_len)){
            ret = WIFI_ERROR_UNKNOWN;
            goto cleanup;
        }
    } else if (msg->key_info.key_type == NAN_SECURITY_KEY_INPUT_PASSPHRASE) {
        if (msg->key_info.body.passphrase_info.passphrase_len <
            NAN_SECURITY_MIN_PASSPHRASE_LEN ||
            msg->key_info.body.passphrase_info.passphrase_len >
            NAN_SECURITY_MAX_PASSPHRASE_LEN) {
            ret = WIFI_ERROR_UNKNOWN;
            ALOGE("%s: Invalid passphrase len:%d", __FUNCTION__,
                  msg->key_info.body.passphrase_info.passphrase_len);
            goto cleanup;
        }
        u8 *service_id = NULL;

        if (t_nanCommand != NULL)
            service_id = t_nanCommand->getServiceId(msg->ndp_instance_id,
                                                    NAN_ROLE_PUBLISHER);
        if (service_id == NULL)
            ALOGE("%s: Entry not found for Instance ID:%d",
                  __FUNCTION__, msg->ndp_instance_id);
        if (((service_id != NULL) || (msg->service_name_len)) &&
            (t_nanCommand != NULL) &&
            ndp_passphrase_to_pmk(msg->cipher_type,
                                  msg->key_info.body.pmk_info.pmk,
                                  msg->key_info.body.passphrase_info.passphrase,
                                  msg->key_info.body.passphrase_info.passphrase_len,
                                  msg->service_name, msg->service_name_len,
                                  service_id, t_nanCommand->getNmi())) {
            msg->key_info.body.pmk_info.pmk_len = NAN_PMK_INFO_LEN;
            if (nanCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_NDP_PMK,
                (char *)msg->key_info.body.pmk_info.pmk,
                msg->key_info.body.pmk_info.pmk_len))
                if (nanCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_NDP_PASSPHRASE,
                    (char *)msg->key_info.body.passphrase_info.passphrase,
                    msg->key_info.body.passphrase_info.passphrase_len)){
                    ret = WIFI_ERROR_UNKNOWN;
                    goto cleanup;
                }
        } else if (nanCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_NDP_PASSPHRASE,
                   (char *)msg->key_info.body.passphrase_info.passphrase,
                   msg->key_info.body.passphrase_info.passphrase_len)) {
            ret = WIFI_ERROR_UNKNOWN;
            goto cleanup;
        }
    }

    if (msg->service_name_len) {
        if (nanCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_NAME,
            (char *)msg->service_name, msg->service_name_len)){
            ret = WIFI_ERROR_UNKNOWN;
            goto cleanup;
        }
    }
    nanCommand->attr_end(nlData);

    ret = nanCommand->requestEvent();
    if (ret != WIFI_SUCCESS)
        ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);

cleanup:
    delete nanCommand;
    return ret;
}

wifi_error nan_data_end(transaction_id id,
                        wifi_interface_handle iface,
                        NanDataPathEndRequest* msg)
{
    wifi_error ret;
    ALOGV("NAN_DP_END");
    struct nlattr *nlData;
    NanCommand *nanCommand = NULL;

    if (msg == NULL)
        return WIFI_ERROR_INVALID_ARGS;

    ret = nan_initialize_vendor_cmd(iface,
                                    &nanCommand);
    if (ret != WIFI_SUCCESS) {
        ALOGE("%s: Initialization failed", __FUNCTION__);
        return ret;
    }

    /* Add the vendor specific attributes for the NL command. */
    nlData = nanCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
    if (!nlData){
        ret = WIFI_ERROR_UNKNOWN;
        goto cleanup;
    }

    if (nanCommand->put_u32(
            QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
            QCA_WLAN_VENDOR_ATTR_NDP_END_REQUEST) ||
        nanCommand->put_u16(
            QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
            id) ||
        nanCommand->put_bytes(
            QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY,
            (char *)msg->ndp_instance_id,
            msg->num_ndp_instances * sizeof(u32))) {
        ret = WIFI_ERROR_UNKNOWN;
        goto cleanup;
    }
    nanCommand->attr_end(nlData);

    ret = nanCommand->requestEvent();
    if (ret != WIFI_SUCCESS)
        ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret);

cleanup:
    delete nanCommand;
    return ret;
}

// Implementation related to nan class common functions
// Constructor
//Making the constructor private since this class is a singleton
NanCommand::NanCommand(wifi_handle handle, int id, u32 vendor_id, u32 subcmd)
        : WifiVendorCommand(handle, id, vendor_id, subcmd)
{
    memset(&mHandler, 0,sizeof(mHandler));
    mNanVendorEvent = NULL;
    mNanDataLen = 0;
    mStaParam = NULL;
    memset(mNmiMac, 0, sizeof(mNmiMac));
    mStorePubParams = NULL;
    mStoreSubParams = NULL;
    mNanMaxPublishes = 0;
    mNanMaxSubscribes = 0;
    mNanDiscAddrIndDisabled = false;
}

NanCommand* NanCommand::instance(wifi_handle handle)
{
    hal_info *info;

    if (handle == NULL) {
        ALOGE("Handle is invalid");
        return NULL;
    }
    info = getHalInfo(handle);
    if (info == NULL) {
        ALOGE("%s: Error hal_info NULL", __FUNCTION__);
        return NULL;
    }

    if (mNanCommandInstance == NULL) {
        mNanCommandInstance = new NanCommand(handle, 0,
                                             OUI_QCA,
                                             info->support_nan_ext_cmd?
                                             QCA_NL80211_VENDOR_SUBCMD_NAN_EXT :
                                             QCA_NL80211_VENDOR_SUBCMD_NAN);
        ALOGV("NanCommand %p created", mNanCommandInstance);
        return mNanCommandInstance;
    } else {
        if (handle != getWifiHandle(mNanCommandInstance->mInfo)) {
            /* upper layer must have cleaned up the handle and reinitialized,
               so we need to update the same */
            ALOGI("Handle different, update the handle");
            mNanCommandInstance->mInfo = (hal_info *)handle;
        }
    }
    ALOGV("NanCommand %p created already", mNanCommandInstance);
    return mNanCommandInstance;
}

void NanCommand::cleanup()
{
    //free the VendorData
    if (mVendorData) {
        free(mVendorData);
    }
    mVendorData = NULL;
    //cleanup the mMsg
    mMsg.destroy();
}

NanCommand::~NanCommand()
{
    ALOGV("NanCommand %p destroyed", this);
}

int NanCommand::handleResponse(WifiEvent &reply){
    return NL_SKIP;
}

/* Save NAN Management Interface address */
void NanCommand::saveNmi(u8 *mac)
{
    memcpy(mNmiMac, mac, NAN_MAC_ADDR_LEN);
}

/* Get NAN Management Interface address */
u8 *NanCommand::getNmi()
{
    return mNmiMac;
}

/*
 * Save the service ID along with Subscribe/Publish ID and Instance ID, which
 * will be used later for Passphrase to PMK calculation.
 *
 * service_id - Service ID received from Firmware either in NAN/NDP Indication
 * sub_pub_handle - Subscribe/Publish ID received in NAN/NDP Indication
 * instance_id - Service/NDP instance ID received in NAN/NDP Indication
 * pool - Subscriber/Publisher entry based on NAN/NDP Indication
 */
void NanCommand::saveServiceId(u8 *service_id, u16 sub_pub_handle,
                               u32 instance_id, NanRole pool)
{
    int i;

    if ((service_id == NULL) || (!sub_pub_handle) || (!instance_id)) {
        ALOGE("%s: Null Parameter received, sub_pub_handle=%d instance_id=%d",
              __FUNCTION__, sub_pub_handle, instance_id);
        return;
    }
    switch(pool) {
    case NAN_ROLE_PUBLISHER:
        if ((mStorePubParams == NULL) || !mNanMaxPublishes)
            return;
        for (i = 0; i < mNanMaxPublishes; i++) {
            /* In 1:n case there can be multiple publish entries with same
             * publish ID, hence save the new entry if instance ID doesn't match
             * with the existing entries in the pool
             */
            if ((mStorePubParams[i].subscriber_publisher_id) &&
                (mStorePubParams[i].instance_id != instance_id))
                continue;

            memset(&mStorePubParams[i], 0, sizeof(mStorePubParams));
            memcpy(mStorePubParams[i].service_id, service_id, NAN_SVC_ID_SIZE);
            mStorePubParams[i].subscriber_publisher_id = sub_pub_handle;
            mStorePubParams[i].instance_id = instance_id;
            ALOGV("Added new entry in Publisher pool at index=%d with "
                  "Publish ID=%d and Instance ID=%d", i,
                  mStorePubParams[i].subscriber_publisher_id,
                  mStorePubParams[i].instance_id);
            return;
        }
        if (i == mNanMaxPublishes)
            ALOGV("No empty slot found in publisher pool, entry not saved");
    break;
    case NAN_ROLE_SUBSCRIBER:
        if ((mStoreSubParams == NULL) || !mNanMaxSubscribes)
            return;
        for (i = 0; i < mNanMaxSubscribes; i++) {
            /* In 1:n case there can be multiple subscribe entries with same
             * subscribe ID, hence save new entry if instance ID doesn't match
             * with the existing entries in the pool
             */
            if ((mStoreSubParams[i].subscriber_publisher_id) &&
                (mStoreSubParams[i].instance_id != instance_id))
                continue;

            memset(&mStoreSubParams[i], 0, sizeof(mStoreSubParams));
            memcpy(mStoreSubParams[i].service_id, service_id, NAN_SVC_ID_SIZE);
            mStoreSubParams[i].subscriber_publisher_id = sub_pub_handle;
            mStoreSubParams[i].instance_id = instance_id;
            ALOGV("Added new entry in Subscriber pool at index=%d with "
                  "Subscribe ID=%d and Instance ID=%d", i,
                  mStoreSubParams[i].subscriber_publisher_id,
                  mStoreSubParams[i].instance_id);
            return;
        }
        if (i == mNanMaxSubscribes)
            ALOGV("No empty slot found in subscriber pool, entry not saved");
    break;
    default:
        ALOGE("Invalid Pool: %d", pool);
    break;
    }
}

/*
 * Get the Service ID from the pool based on the Service/NDP instance ID that
 * will be used for Passphrase to PMK calculation in Initiator/Responder request
 *
 * instance_id - Service/NDP instance ID received in NAN/NDP Indication
 * pool - Subscriber/Publisher role based on the Initiator/Responder
 */
u8 *NanCommand::getServiceId(u32 instance_id, NanRole pool)
{
    int i;

    switch(pool) {
    case NAN_ROLE_PUBLISHER:
        if ((mStorePubParams == NULL) || (!instance_id) || !mNanMaxPublishes)
            return NULL;
        ALOGV("Getting Service ID from publisher pool for instance ID=%d", instance_id);
        for (i = 0; i < mNanMaxPublishes; i++) {
            if (mStorePubParams[i].instance_id == instance_id)
                return mStorePubParams[i].service_id;
        }
    break;
    case NAN_ROLE_SUBSCRIBER:
        if ((mStoreSubParams == NULL )|| (!instance_id) || !mNanMaxSubscribes)
            return NULL;
        ALOGV("Getting Service ID from subscriber pool for instance ID=%d", instance_id);
        for (i = 0; i < mNanMaxSubscribes; i++) {
            if (mStoreSubParams[i].instance_id == instance_id)
                return mStoreSubParams[i].service_id;
        }
    break;
    default:
        ALOGE("Invalid Pool: %d", pool);
    break;
    }
    return NULL;
}

/*
 * Delete service ID entry from the pool based on the subscriber/Instance ID
 *
 * sub_handle - Subscriber ID received from the Subscribe Cancel
 * instance_id - NDP Instance ID received from the NDP End Indication
 */
void NanCommand::deleteServiceId(u16 sub_handle,
                                 u32 instance_id, NanRole pool)
{
    int i;

    switch(pool) {
    case NAN_ROLE_PUBLISHER:
        if ((mStorePubParams == NULL) || (!instance_id) || !mNanMaxPublishes)
            return;
        for (i = 0; i < mNanMaxPublishes; i++) {
            /* Delete all the entries that has the matching Instance ID */
            if (mStorePubParams[i].instance_id == instance_id) {
                ALOGV("Deleted entry at index=%d from publisher pool "
                      "with publish ID=%d and instance ID=%d", i,
                      mStorePubParams[i].subscriber_publisher_id,
                      mStorePubParams[i].instance_id);
                memset(&mStorePubParams[i], 0, sizeof(mStorePubParams));
            }
        }
    break;
    case NAN_ROLE_SUBSCRIBER:
        if ((mStoreSubParams == NULL) || (!sub_handle) || !mNanMaxSubscribes)
            return;
        for (i = 0; i < mNanMaxSubscribes; i++) {
            /* Delete all the entries that has the matching subscribe ID */
            if (mStoreSubParams[i].subscriber_publisher_id == sub_handle) {
                ALOGV("Deleted entry at index=%d from subsriber pool "
                      "with subscribe ID=%d and instance ID=%d", i,
                      mStoreSubParams[i].subscriber_publisher_id,
                      mStoreSubParams[i].instance_id);
                memset(&mStoreSubParams[i], 0, sizeof(mStoreSubParams));
            }
        }
    break;
    default:
        ALOGE("Invalid Pool: %d", pool);
    break;
    }
}

/*
 * Allocate the memory for the Subscribe and Publish pools using the Max values
 * mStorePubParams - Points the Publish pool
 * mStoreSubParams - Points the Subscribe pool
 */
void NanCommand::allocSvcParams()
{
    if (mNanMaxPublishes < NAN_DEF_PUB_SUB)
        mNanMaxPublishes = NAN_DEF_PUB_SUB;
    if (mNanMaxSubscribes < NAN_DEF_PUB_SUB)
        mNanMaxSubscribes = NAN_DEF_PUB_SUB;

    if ((mStorePubParams == NULL) && mNanMaxPublishes) {
        mStorePubParams =
        (NanStoreSvcParams *)malloc(mNanMaxPublishes*sizeof(NanStoreSvcParams));
        if (mStorePubParams == NULL) {
            ALOGE("%s: Publish pool malloc failed", __FUNCTION__);
            deallocSvcParams();
            return;
        }
        ALOGV("%s: Allocated the Publish pool for max %d entries",
              __FUNCTION__, mNanMaxPublishes);
    }
    if ((mStoreSubParams == NULL) && mNanMaxSubscribes) {
        mStoreSubParams =
        (NanStoreSvcParams *)malloc(mNanMaxSubscribes*sizeof(NanStoreSvcParams));
        if (mStoreSubParams == NULL) {
            ALOGE("%s: Subscribe pool malloc failed", __FUNCTION__);
            deallocSvcParams();
            return;
        }
        ALOGV("%s: Allocated the Subscribe pool for max %d entries",
              __FUNCTION__, mNanMaxSubscribes);
    }
}

/*
 * Reallocate the memory for Subscribe and Publish pools using the Max values
 * mStorePubParams - Points the Publish pool
 * mStoreSubParams - Points the Subscribe pool
 */
void NanCommand::reallocSvcParams(NanRole pool)
{
    switch(pool) {
    case NAN_ROLE_PUBLISHER:
        if ((mStorePubParams != NULL) && mNanMaxPublishes) {
            mStorePubParams =
            (NanStoreSvcParams *)realloc(mStorePubParams,
                                         mNanMaxPublishes*sizeof(NanStoreSvcParams));
            if (mStorePubParams == NULL) {
                ALOGE("%s: Publish pool realloc failed", __FUNCTION__);
                deallocSvcParams();
                return;
            }
            ALOGV("%s: Reallocated the Publish pool for max %d entries",
                   __FUNCTION__, mNanMaxPublishes);
        }
    break;
    case NAN_ROLE_SUBSCRIBER:
        if ((mStoreSubParams != NULL) && mNanMaxSubscribes) {
            mStoreSubParams =
            (NanStoreSvcParams *)realloc(mStoreSubParams,
                                         mNanMaxSubscribes*sizeof(NanStoreSvcParams));
            if (mStoreSubParams == NULL) {
                ALOGE("%s: Subscribe pool realloc failed", __FUNCTION__);
                deallocSvcParams();
                return;
            }
            ALOGV("%s: Reallocated the Subscribe pool for max %d entries",
                  __FUNCTION__, mNanMaxSubscribes);
        }
    break;
    default:
        ALOGE("Invalid Pool: %d", pool);
    break;
    }
}

/*
 * Deallocate the Subscribe and Publish pools
 * mStorePubParams - Points the Publish pool
 * mStoreSubParams - Points the Subscribe pool
 */
void NanCommand::deallocSvcParams()
{
    if (mStorePubParams != NULL) {
        free(mStorePubParams);
        mStorePubParams = NULL;
        ALOGV("%s: Deallocated Publish pool", __FUNCTION__);
    }
    if (mStoreSubParams != NULL) {
        free(mStoreSubParams);
        mStoreSubParams = NULL;
        ALOGV("%s: Deallocated Subscribe pool", __FUNCTION__);
    }
}

wifi_error NanCommand::setCallbackHandler(NanCallbackHandler nHandler)
{
    wifi_error res;
    mHandler = nHandler;
    res = registerVendorHandler(mVendor_id, QCA_NL80211_VENDOR_SUBCMD_NAN);
    if (res != WIFI_SUCCESS) {
        //error case should not happen print log
        ALOGE("%s: Unable to register Vendor Handler Vendor Id=0x%x"
              "subcmd=QCA_NL80211_VENDOR_SUBCMD_NAN", __FUNCTION__, mVendor_id);
        return res;
    }

    res = registerVendorHandler(mVendor_id, QCA_NL80211_VENDOR_SUBCMD_NDP);
    if (res != WIFI_SUCCESS) {
        //error case should not happen print log
        ALOGE("%s: Unable to register Vendor Handler Vendor Id=0x%x"
              "subcmd=QCA_NL80211_VENDOR_SUBCMD_NDP", __FUNCTION__, mVendor_id);
        return res;
    }
    return res;
}

/* This function implements creation of Vendor command */
wifi_error NanCommand::create() {
    wifi_error ret = mMsg.create(NL80211_CMD_VENDOR, 0, 0);
    if (ret != WIFI_SUCCESS)
        goto out;

    /* Insert the oui in the msg */
    ret = mMsg.put_u32(NL80211_ATTR_VENDOR_ID, mVendor_id);
    if (ret != WIFI_SUCCESS)
        goto out;
    /* Insert the subcmd in the msg */
    ret = mMsg.put_u32(NL80211_ATTR_VENDOR_SUBCMD, mSubcmd);

out:
    if (ret != WIFI_SUCCESS)
        mMsg.destroy();
    return ret;
}

// This function will be the main handler for incoming event
// QCA_NL80211_VENDOR_SUBCMD_NAN
//Call the appropriate callback handler after parsing the vendor data.
int NanCommand::handleEvent(WifiEvent &event)
{
    WifiVendorCommand::handleEvent(event);
    ALOGV("%s: Subcmd=%u Vendor data len received:%d",
          __FUNCTION__, mSubcmd, mDataLen);
    hexdump(mVendorData, mDataLen);

    if (mSubcmd == QCA_NL80211_VENDOR_SUBCMD_NAN){
        // Parse the vendordata and get the NAN attribute
        struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_MAX + 1];
        nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_MAX,
                  (struct nlattr *)mVendorData,
                  mDataLen, NULL);
        // Populating the mNanVendorEvent and mNanDataLen to point to NAN data.
        mNanVendorEvent = (char *)nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_NAN]);
        mNanDataLen = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_NAN]);

        if (isNanResponse()) {
            //handleNanResponse will parse the data and call
            //the response callback handler with the populated
            //NanResponseMsg
            handleNanResponse();
        } else {
            //handleNanIndication will parse the data and call
            //the corresponding Indication callback handler
            //with the corresponding populated Indication event
            handleNanIndication();
        }
    } else if (mSubcmd == QCA_NL80211_VENDOR_SUBCMD_NDP) {
        // Parse the vendordata and get the NAN attribute
        u32 ndpCmdType;
        struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX + 1];
        nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX,
                  (struct nlattr *)mVendorData,
                  mDataLen, NULL);

        if (tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD]) {
            ndpCmdType =
                nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD]);
                ALOGD("%s: NDP Cmd Type : val 0x%x",
                      __FUNCTION__, ndpCmdType);
                switch (ndpCmdType) {
                case QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE:
                    handleNdpResponse(NAN_DP_INTERFACE_CREATE, tb_vendor);
                    break;
                case QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE:
                    handleNdpResponse(NAN_DP_INTERFACE_DELETE, tb_vendor);
                    break;
                case QCA_WLAN_VENDOR_ATTR_NDP_INITIATOR_RESPONSE:
                    handleNdpResponse(NAN_DP_INITIATOR_RESPONSE, tb_vendor);
                    break;
                case QCA_WLAN_VENDOR_ATTR_NDP_RESPONDER_RESPONSE:
                    handleNdpResponse(NAN_DP_RESPONDER_RESPONSE, tb_vendor);
                    break;
                case QCA_WLAN_VENDOR_ATTR_NDP_END_RESPONSE:
                    handleNdpResponse(NAN_DP_END, tb_vendor);
                    break;
                case QCA_WLAN_VENDOR_ATTR_NDP_REQUEST_IND:
                case QCA_WLAN_VENDOR_ATTR_NDP_CONFIRM_IND:
                case QCA_WLAN_VENDOR_ATTR_NDP_END_IND:
                case QCA_WLAN_VENDOR_ATTR_NDP_SCHEDULE_UPDATE_IND:
                    handleNdpIndication(ndpCmdType, tb_vendor);
                    break;
                default:
                    ALOGE("%s: Invalid NDP subcmd response received %d",
                          __FUNCTION__, ndpCmdType);
                }
        }
    } else {
        //error case should not happen print log
        ALOGE("%s: Wrong NAN subcmd received %d", __FUNCTION__, mSubcmd);
    }
    mNanVendorEvent = NULL;
    return NL_SKIP;
}

/*Helper function to Write and Read TLV called in indication as well as request */
u16 NANTLV_WriteTlv(pNanTlv pInTlv, u8 *pOutTlv)
{
    u16 writeLen = 0;
    u16 i;

    if (!pInTlv)
    {
        ALOGE("NULL pInTlv");
        return writeLen;
    }

    if (!pOutTlv)
    {
        ALOGE("NULL pOutTlv");
        return writeLen;
    }

    *pOutTlv++ = pInTlv->type & 0xFF;
    *pOutTlv++ = (pInTlv->type & 0xFF00) >> 8;
    writeLen += 2;

    ALOGV("WRITE TLV type %u, writeLen %u", pInTlv->type, writeLen);

    *pOutTlv++ = pInTlv->length & 0xFF;
    *pOutTlv++ = (pInTlv->length & 0xFF00) >> 8;
    writeLen += 2;

    ALOGV("WRITE TLV length %u, writeLen %u", pInTlv->length, writeLen);

    for (i=0; i < pInTlv->length; ++i)
    {
        *pOutTlv++ = pInTlv->value[i];
    }

    writeLen += pInTlv->length;
    ALOGV("WRITE TLV value, writeLen %u", writeLen);
    return writeLen;
}

u16 NANTLV_ReadTlv(u8 *pInTlv, pNanTlv pOutTlv, int inBufferSize)
{
    u16 readLen = 0;

    if (!pInTlv)
    {
        ALOGE("NULL pInTlv");
        return readLen;
    }

    if (!pOutTlv)
    {
        ALOGE("NULL pOutTlv");
        return readLen;
    }

    if(inBufferSize < NAN_TLV_HEADER_SIZE) {
        ALOGE("Insufficient length to process TLV header, inBufferSize = %d",
              inBufferSize);
        return readLen;
    }

    pOutTlv->type = *pInTlv++;
    pOutTlv->type |= *pInTlv++ << 8;
    readLen += 2;

    ALOGV("READ TLV type %u, readLen %u", pOutTlv->type, readLen);

    pOutTlv->length = *pInTlv++;
    pOutTlv->length |= *pInTlv++ << 8;
    readLen += 2;

    if(pOutTlv->length > (u16)(inBufferSize - NAN_TLV_HEADER_SIZE)) {
        ALOGE("Insufficient length to process TLV header, inBufferSize = %d",
              inBufferSize);
        return readLen;
    }

    ALOGV("READ TLV length %u, readLen %u", pOutTlv->length, readLen);

    if (pOutTlv->length) {
        pOutTlv->value = pInTlv;
        readLen += pOutTlv->length;
    } else {
        pOutTlv->value = NULL;
    }

    ALOGV("READ TLV  readLen %u", readLen);
    return readLen;
}

u8* addTlv(u16 type, u16 length, const u8* value, u8* pOutTlv)
{
   NanTlv nanTlv;
   u16 len;

   nanTlv.type = type;
   nanTlv.length = length;
   nanTlv.value = (u8*)value;

   len = NANTLV_WriteTlv(&nanTlv, pOutTlv);
   return (pOutTlv + len);
}
