/*
 * 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) {
        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;
    }

    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_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;

delete_ndi:
    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 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);
}
