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

#include "sync.h"

#include "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"

#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;
    interface_info *ifaceInfo = getIfaceInfo(iface);
    wifi_handle wifiHandle = getWifiHandle(iface);

    nanCommand = new NanCommand(wifiHandle,
                                0,
                                OUI_QCA,
                                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);

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;
    interface_info *ifaceInfo = getIfaceInfo(iface);
    wifi_handle wifiHandle = getWifiHandle(iface);

    nanCommand = new NanCommand(wifiHandle,
                                0,
                                OUI_QCA,
                                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);

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

    nanCommand = new NanCommand(wifiHandle,
                                0,
                                OUI_QCA,
                                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);

    nanCommand = new NanCommand(wifiHandle,
                                0,
                                OUI_QCA,
                                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);

    nanCommand = new NanCommand(wifiHandle,
                                0,
                                OUI_QCA,
                                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;
    interface_info *ifaceInfo = getIfaceInfo(iface);
    wifi_handle wifiHandle = getWifiHandle(iface);

    nanCommand = new NanCommand(wifiHandle,
                                0,
                                OUI_QCA,
                                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);

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

    nanCommand = new NanCommand(wifiHandle,
                                0,
                                OUI_QCA,
                                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);

    nanCommand = new NanCommand(wifiHandle,
                                0,
                                OUI_QCA,
                                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);

    nanCommand = new NanCommand(wifiHandle,
                                0,
                                OUI_QCA,
                                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);

    nanCommand = new NanCommand(wifiHandle,
                                0,
                                OUI_QCA,
                                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);

    nanCommand = new NanCommand(wifiHandle,
                                0,
                                OUI_QCA,
                                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);

    nanCommand = new NanCommand(wifiHandle,
                                0,
                                OUI_QCA,
                                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);

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

    if (iface_name == NULL) {
        ALOGE("%s: Invalid Nan Data Interface Name. \n", __FUNCTION__);
        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)
        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)) {
        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_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;

    if (iface_name == NULL) {
        ALOGE("%s: Invalid Nan Data Interface Name. \n", __FUNCTION__);
        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)
        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)) {
        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_request_initiator(transaction_id id,
                                      wifi_interface_handle iface,
                                      NanDataPathInitiatorRequest* msg)
{
    ALOGV("NAN_DP_REQUEST_INITIATOR");
    wifi_error ret;
    struct nlattr *nlData, *nlCfgSecurity, *nlCfgQos;
    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;
    }

    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)
        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)) {
        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))
            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)) {
            goto cleanup;
        }
    }
    if (msg->ndp_cfg.security_cfg == NAN_DP_CONFIG_SECURITY) {
        nlCfgSecurity =
            nanCommand->attr_start(QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_SECURITY);
        if (!nlCfgSecurity)
            goto cleanup;

        if (nanCommand->put_u32(
            QCA_WLAN_VENDOR_ATTR_NDP_SECURITY_TYPE,
            0)) {
            goto cleanup;
        }
        nanCommand->attr_end(nlCfgSecurity);
    }
    if (msg->ndp_cfg.qos_cfg == NAN_DP_CONFIG_QOS) {
        nlCfgQos =
            nanCommand->attr_start(QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS);
        if (!nlCfgQos)
            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))
            goto cleanup;
    }
    if ( msg->key_info.key_type == NAN_SECURITY_KEY_INPUT_PMK &&
         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))
            goto cleanup;
    } else if (msg->key_info.key_type == NAN_SECURITY_KEY_INPUT_PASSPHRASE &&
        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) {
        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))
            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))
            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, *nlCfgSecurity, *nlCfgQos;
    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;
    }

    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)
        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)) {
        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)) {
            goto cleanup;
        }
    }
    if (msg->ndp_cfg.security_cfg == NAN_DP_CONFIG_SECURITY) {
        nlCfgSecurity =
            nanCommand->attr_start(QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_SECURITY);
        if (!nlCfgSecurity)
            goto cleanup;
        /* Setting value to 0 for now */
        if (nanCommand->put_u32(
            QCA_WLAN_VENDOR_ATTR_NDP_SECURITY_TYPE,
            0)) {
            goto cleanup;
        }
        nanCommand->attr_end(nlCfgSecurity);
    }
    if (msg->ndp_cfg.qos_cfg == NAN_DP_CONFIG_QOS) {
        nlCfgQos =
            nanCommand->attr_start(QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS);
        if (!nlCfgQos)
            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))
            goto cleanup;
    }
    if ( msg->key_info.key_type == NAN_SECURITY_KEY_INPUT_PMK &&
         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))
            goto cleanup;
    } else if (msg->key_info.key_type == NAN_SECURITY_KEY_INPUT_PASSPHRASE &&
        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) {
        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))
            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))
            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)
        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))) {
        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;
}

NanCommand* NanCommand::instance(wifi_handle handle)
{
    if (handle == NULL) {
        ALOGE("Handle is invalid");
        return NULL;
    }
    if (mNanCommandInstance == NULL) {
        mNanCommandInstance = new NanCommand(handle, 0,
                                             OUI_QCA,
                                             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;
}

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)
{
    u16 readLen = 0;

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

    if (!pOutTlv)
    {
        ALOGE("NULL pOutTlv");
        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;

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