/* Copyright (c) 2014, 2018 The Linux Foundation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted 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 The Linux Foundation nor the names of its
 *    contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER 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.

 * Changes from Qualcomm Innovation Center are provided under the following license:

 * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
 * SPDX-License-Identifier: BSD-3-Clause-Clear
 */

#include "sync.h"

#define LOG_TAG  "WifiHAL"

#include <utils/Log.h>

#include "wifi_hal.h"
#include "common.h"
#include "cpp_bindings.h"
#include "tdlsCommand.h"
#include "vendor_definitions.h"

/* Singleton Static Instance */
TdlsCommand* TdlsCommand::mTdlsCommandInstance  = NULL;
TdlsCommand::TdlsCommand(wifi_handle handle, int id, u32 vendor_id, u32 subcmd)
        : WifiVendorCommand(handle, id, vendor_id, subcmd)
{
    memset(&mHandler, 0, sizeof(mHandler));
    memset(&mTDLSgetStatusRspParams, 0, sizeof(wifi_tdls_status));
    mRequestId = 0;
    memset(&mTDLSgetCaps, 0, sizeof(wifiTdlsCapabilities));
}

TdlsCommand::~TdlsCommand()
{
    mTdlsCommandInstance = NULL;
    unregisterVendorHandler(mVendor_id, mSubcmd);
}

TdlsCommand* TdlsCommand::instance(wifi_handle handle)
{
    if (handle == NULL) {
        ALOGE("Interface Handle is invalid");
        return NULL;
    }
    if (mTdlsCommandInstance == NULL) {
        mTdlsCommandInstance = new TdlsCommand(handle, 0,
                OUI_QCA,
                QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE);
        ALOGV("TdlsCommand %p created", mTdlsCommandInstance);
        return mTdlsCommandInstance;
    }
    else
    {
        if (handle != getWifiHandle(mTdlsCommandInstance->mInfo))
        {
            /* upper layer must have cleaned up the handle and reinitialized,
               so we need to update the same */
            ALOGV("Handle different, update the handle");
            mTdlsCommandInstance->mInfo = (hal_info *)handle;
        }
    }
    ALOGV("TdlsCommand %p created already", mTdlsCommandInstance);
    return mTdlsCommandInstance;
}

void TdlsCommand::setSubCmd(u32 subcmd)
{
    mSubcmd = subcmd;
}

/* This function will be the main handler for incoming event SUBCMD_TDLS
 * Call the appropriate callback handler after parsing the vendor data.
 */
int TdlsCommand::handleEvent(WifiEvent &event)
{
    ALOGV("Got a TDLS message from Driver");
    WifiVendorCommand::handleEvent(event);

    /* Parse the vendordata and get the attribute */
    switch(mSubcmd)
    {
        case QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE:
            {
                struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX
                    + 1];
                mac_addr addr;
                wifi_tdls_status status;

                memset(&addr, 0, sizeof(mac_addr));
                memset(&status, 0, sizeof(wifi_tdls_status));
                nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX,
                        (struct nlattr *)mVendorData,
                        mDataLen, NULL);

                ALOGV("QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE Received");
                if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_TDLS_MAC_ADDR])
                {
                    ALOGE("%s: QCA_WLAN_VENDOR_ATTR_TDLS_MAC_ADDR not found",
                            __FUNCTION__);
                    return WIFI_ERROR_INVALID_ARGS;
                }
                memcpy(addr,
                  (u8 *)nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_TDLS_MAC_ADDR]),
                  nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_TDLS_MAC_ADDR]));

                ALOGV(MAC_ADDR_STR, MAC_ADDR_ARRAY(addr));

                if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_TDLS_STATE])
                {
                    ALOGE("%s: QCA_WLAN_VENDOR_ATTR_TDLS_STATE not found",
                            __FUNCTION__);
                    return WIFI_ERROR_INVALID_ARGS;
                }
                status.state = (wifi_tdls_state)
                    get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_TDLS_STATE]);
                ALOGV("TDLS: State New : %d ", status.state);

                if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_TDLS_REASON])
                {
                    ALOGE("%s: QCA_WLAN_VENDOR_ATTR_TDLS_REASON not found",
                            __FUNCTION__);
                    return WIFI_ERROR_INVALID_ARGS;
                }
                status.reason = (wifi_tdls_reason)
                    get_s32(tb_vendor[QCA_WLAN_VENDOR_ATTR_TDLS_REASON]);
                ALOGV("TDLS: Reason : %d ", status.reason);

                if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_TDLS_CHANNEL])
                {
                    ALOGE("%s: QCA_WLAN_VENDOR_ATTR_TDLS_CHANNEL not found",
                            __FUNCTION__);
                    return WIFI_ERROR_INVALID_ARGS;
                }
                status.channel =
                    get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_TDLS_CHANNEL]);
                ALOGV("TDLS: channel : %d ", status.channel);

                if (!tb_vendor[
                        QCA_WLAN_VENDOR_ATTR_TDLS_GLOBAL_OPERATING_CLASS])
                {
                    ALOGE("%s: QCA_WLAN_VENDOR_ATTR_TDLS_GLOBAL_OPERATING_CLASS"
                            " not found", __FUNCTION__);
                    return WIFI_ERROR_INVALID_ARGS;
                }
                status.global_operating_class = get_u32(
                   tb_vendor[QCA_WLAN_VENDOR_ATTR_TDLS_GLOBAL_OPERATING_CLASS]);
                ALOGV("TDLS: global_operating_class: %d ",
                        status.global_operating_class);

                if (mHandler.on_tdls_state_changed)
                    (*mHandler.on_tdls_state_changed)(addr, status);
                else
                    ALOGE("TDLS: No Callback registered: ");
            }
            break;

        default:
            /* Error case should not happen print log */
            ALOGE("%s: Wrong TDLS subcmd received %d", __FUNCTION__, mSubcmd);
    }

    return NL_SKIP;
}

int TdlsCommand::handleResponse(WifiEvent &reply)
{
    WifiVendorCommand::handleResponse(reply);

    switch(mSubcmd)
    {
        case QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS:
            {
                struct nlattr *tb_vendor[
                    QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
                nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
                        (struct nlattr *)mVendorData,
                        mDataLen, NULL);

                ALOGV("QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS Received");
                memset(&mTDLSgetStatusRspParams, 0, sizeof(wifi_tdls_status));

                if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE])
                {
                    ALOGE("%s: QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE"
                            " not found", __FUNCTION__);
                    return WIFI_ERROR_INVALID_ARGS;
                }
                mTDLSgetStatusRspParams.state = (wifi_tdls_state)get_u32(
                        tb_vendor[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE]);
                ALOGV("TDLS: State : %u ", mTDLSgetStatusRspParams.state);

                if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON])
                {
                    ALOGE("%s: QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON"
                            " not found", __FUNCTION__);
                    return WIFI_ERROR_INVALID_ARGS;
                }
                mTDLSgetStatusRspParams.reason = (wifi_tdls_reason)get_s32(
                        tb_vendor[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON]);
                ALOGV("TDLS: Reason : %d ", mTDLSgetStatusRspParams.reason);

                if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL])
                {
                    ALOGE("%s: QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL"
                            " not found", __FUNCTION__);
                    return WIFI_ERROR_INVALID_ARGS;
                }
                mTDLSgetStatusRspParams.channel = get_u32(tb_vendor[
                        QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL]);
                ALOGV("TDLS: channel : %d ", mTDLSgetStatusRspParams.channel);

                if (!tb_vendor[
                  QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS])
                {
                    ALOGE("%s:"
                   "QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS"
                    " not found", __FUNCTION__);
                    return WIFI_ERROR_INVALID_ARGS;
                }
                mTDLSgetStatusRspParams.global_operating_class =
                  get_u32(tb_vendor[
                  QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]);
                ALOGV("TDLS: global_operating_class: %d ",
                        mTDLSgetStatusRspParams.global_operating_class);
            }
            break;
        case QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_CAPABILITIES:
            {
                struct nlattr *tb_vendor[
                    QCA_WLAN_VENDOR_ATTR_TDLS_GET_CAPS_MAX + 1];
                nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_TDLS_GET_CAPS_MAX,
                        (struct nlattr *)mVendorData,
                        mDataLen, NULL);

                memset(&mTDLSgetCaps, 0, sizeof(wifiTdlsCapabilities));

                if (!tb_vendor[
                    QCA_WLAN_VENDOR_ATTR_TDLS_GET_CAPS_MAX_CONC_SESSIONS]
                   )
                {
                    ALOGE("%s: QCA_WLAN_VENDOR_ATTR_TDLS_GET_CAPS_"
                          "MAX_CONC_SESSIONS not found", __FUNCTION__);
                    return WIFI_ERROR_INVALID_ARGS;
                }
                mTDLSgetCaps.maxConcurrentTdlsSessionNum = get_u32(tb_vendor[
                        QCA_WLAN_VENDOR_ATTR_TDLS_GET_CAPS_MAX_CONC_SESSIONS]);

                if (!tb_vendor[
                    QCA_WLAN_VENDOR_ATTR_TDLS_GET_CAPS_FEATURES_SUPPORTED])
                {
                    ALOGE("%s: QCA_WLAN_VENDOR_ATTR_TDLS_GET_CAPS_"
                          "FEATURES_SUPPORTED not found", __FUNCTION__);
                    return WIFI_ERROR_INVALID_ARGS;
                }
                mTDLSgetCaps.tdlsSupportedFeatures = get_u32(tb_vendor[
                    QCA_WLAN_VENDOR_ATTR_TDLS_GET_CAPS_FEATURES_SUPPORTED]);
            }
            break;
        default :
            ALOGE("%s: Wrong TDLS subcmd response received %d",
                __FUNCTION__, mSubcmd);
    }
    return NL_SKIP;
}


wifi_error TdlsCommand::setCallbackHandler(wifi_tdls_handler nHandler, u32 event)
{
    wifi_error res;
    mHandler = nHandler;

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

void TdlsCommand::unregisterHandler(u32 subCmd)
{
    unregisterVendorHandler(mVendor_id, subCmd);
}

void TdlsCommand::getStatusRspParams(wifi_tdls_status *status)
{
    status->channel = mTDLSgetStatusRspParams.channel;
    status->global_operating_class =
        mTDLSgetStatusRspParams.global_operating_class;
    status->state = mTDLSgetStatusRspParams.state;
    status->reason = mTDLSgetStatusRspParams.reason;
}

wifi_error TdlsCommand::requestResponse()
{
    return WifiCommand::requestResponse(mMsg);
}

void TdlsCommand::getCapsRspParams(wifi_tdls_capabilities *caps)
{
    caps->max_concurrent_tdls_session_num =
        mTDLSgetCaps.maxConcurrentTdlsSessionNum;
    caps->is_global_tdls_supported =
        !!(mTDLSgetCaps.tdlsSupportedFeatures & IS_GLOBAL_TDLS_SUPPORTED);
    caps->is_per_mac_tdls_supported =
        !!(mTDLSgetCaps.tdlsSupportedFeatures & IS_PER_MAC_TDLS_SUPPORTED);
    caps->is_off_channel_tdls_supported =
        !!(mTDLSgetCaps.tdlsSupportedFeatures & IS_OFF_CHANNEL_TDLS_SUPPORTED);
    ALOGV("TDLS capabilities:");
    ALOGV("max_concurrent_tdls_session_numChannel : %d\n",
            caps->max_concurrent_tdls_session_num);
    ALOGV("is_global_tdls_supported : %d\n",
            caps->is_global_tdls_supported);
    ALOGV("is_per_mac_tdls_supported : %d\n",
            caps->is_per_mac_tdls_supported);
    ALOGV("is_off_channel_tdls_supported : %d \n",
            caps->is_off_channel_tdls_supported);
}

/* wifi_enable_tdls - enables TDLS-auto mode for a specific route
 *
 * params specifies hints, which provide more information about
 * why TDLS is being sought. The firmware should do its best to
 * honor the hints before downgrading regular AP link
 *
 * On successful completion, must fire on_tdls_state_changed event
 * to indicate the status of TDLS operation.
 */
wifi_error wifi_enable_tdls(wifi_interface_handle iface,
                            mac_addr addr,
                            wifi_tdls_params *params,
                            wifi_tdls_handler handler)
{
    wifi_error ret;
    TdlsCommand *pTdlsCommand;
    struct nlattr *nl_data;
    interface_info *iinfo = getIfaceInfo(iface);
    wifi_handle handle = getWifiHandle(iface);
    pTdlsCommand = TdlsCommand::instance(handle);

    if (pTdlsCommand == NULL) {
        ALOGE("%s: Error TdlsCommand NULL", __FUNCTION__);
        return WIFI_ERROR_UNKNOWN;
    }
    pTdlsCommand->setSubCmd(QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE);

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

    ret = pTdlsCommand->set_iface_id(iinfo->name);
    if (ret != WIFI_SUCCESS)
        goto cleanup;

    /* Add the attributes */
    nl_data = pTdlsCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
    if (!nl_data){
        ret = WIFI_ERROR_UNKNOWN;
        goto cleanup;
    }
    ALOGV("%s: MAC_ADDR: " MAC_ADDR_STR, __FUNCTION__, MAC_ADDR_ARRAY(addr));
    ret = pTdlsCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR,
                                  (char *)addr, 6);
    if (ret != WIFI_SUCCESS)
        goto cleanup;

    if (params != NULL) {
        ALOGV("%s: Channel: %d, Global operating class: %d, "
            "Max Latency: %dms, Min Bandwidth: %dKbps",
            __FUNCTION__, params->channel, params->global_operating_class,
            params->max_latency_ms, params->min_bandwidth_kbps);
        ret = pTdlsCommand->put_u32(
                            QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL,
                            params->channel);
        if (ret != WIFI_SUCCESS)
                goto cleanup;
        ret = pTdlsCommand->put_u32(
                            QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS,
                            params->global_operating_class);
        if (ret != WIFI_SUCCESS)
                goto cleanup;
        ret = pTdlsCommand->put_u32(
                            QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS,
                            params->max_latency_ms);
        if (ret != WIFI_SUCCESS)
                goto cleanup;
        ret = pTdlsCommand->put_u32(
                            QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS,
                            params->min_bandwidth_kbps);
        if (ret != WIFI_SUCCESS)
                goto cleanup;
    }

    pTdlsCommand->attr_end(nl_data);

    ret = pTdlsCommand->setCallbackHandler(handler,
                        QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE);
    if (ret != WIFI_SUCCESS)
        goto cleanup;

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

cleanup:
    return ret;
}

/* wifi_disable_tdls - disables TDLS-auto mode for a specific route
 *
 * This terminates any existing TDLS with addr device, and frees the
 * device resources to make TDLS connections on new routes.
 *
 * DON'T fire any more events on 'handler' specified in earlier call to
 * wifi_enable_tdls after this action.
 */
wifi_error wifi_disable_tdls(wifi_interface_handle iface, mac_addr addr)
{
    wifi_error ret;
    TdlsCommand *pTdlsCommand;
    struct nlattr *nl_data;
    interface_info *iinfo = getIfaceInfo(iface);
    wifi_handle handle = getWifiHandle(iface);
    pTdlsCommand = TdlsCommand::instance(handle);

    if (pTdlsCommand == NULL) {
        ALOGE("%s: Error TdlsCommand NULL", __FUNCTION__);
        return WIFI_ERROR_UNKNOWN;
    }
    pTdlsCommand->setSubCmd(QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE);

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

    ret = pTdlsCommand->set_iface_id(iinfo->name);
    if (ret != WIFI_SUCCESS)
        goto cleanup;
    ALOGV("%s: ifindex obtained:%d", __FUNCTION__, ret);
    ALOGV("%s: MAC_ADDR: " MAC_ADDR_STR, __FUNCTION__, MAC_ADDR_ARRAY(addr));

    /* Add the attributes */
    nl_data = pTdlsCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
    if (!nl_data){
        ret = WIFI_ERROR_UNKNOWN;
        goto cleanup;
    }
    ret = pTdlsCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR,
                                  (char *)addr, 6);
    if (ret != WIFI_SUCCESS)
        goto cleanup;
    pTdlsCommand->attr_end(nl_data);

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

cleanup:
    delete pTdlsCommand;
    return ret;
}

/* wifi_get_tdls_status - allows getting the status of TDLS for a specific
 * route
 */
wifi_error wifi_get_tdls_status(wifi_interface_handle iface, mac_addr addr,
                                wifi_tdls_status *status)
{
    wifi_error ret;
    TdlsCommand *pTdlsCommand;
    struct nlattr *nl_data;
    interface_info *iinfo = getIfaceInfo(iface);
    wifi_handle handle = getWifiHandle(iface);
    pTdlsCommand = TdlsCommand::instance(handle);

    if (pTdlsCommand == NULL) {
        ALOGE("%s: Error TdlsCommand NULL", __FUNCTION__);
        return WIFI_ERROR_UNKNOWN;
    }
    pTdlsCommand->setSubCmd(QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS);

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

    ret = pTdlsCommand->set_iface_id(iinfo->name);
    if (ret != WIFI_SUCCESS)
        goto cleanup;
    ALOGV("%s: ifindex obtained:%d", __FUNCTION__, ret);

    /* Add the attributes */
    nl_data = pTdlsCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
    if (!nl_data){
        ret = WIFI_ERROR_UNKNOWN;
        goto cleanup;
    }
    ret = pTdlsCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR,
                                  (char *)addr, 6);
    if (ret != WIFI_SUCCESS)
        goto cleanup;
    pTdlsCommand->attr_end(nl_data);

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

    pTdlsCommand->getStatusRspParams(status);

cleanup:
    return ret;
}

/* return the current HW + Firmware combination's TDLS capabilities */
wifi_error wifi_get_tdls_capabilities(wifi_interface_handle iface,
                                      wifi_tdls_capabilities *capabilities)
{
    wifi_error ret;
    TdlsCommand *pTdlsCommand;

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

    interface_info *iinfo = getIfaceInfo(iface);
    wifi_handle handle = getWifiHandle(iface);
    pTdlsCommand = TdlsCommand::instance(handle);

    if (pTdlsCommand == NULL) {
        ALOGE("%s: Error TdlsCommand NULL", __FUNCTION__);
        return WIFI_ERROR_UNKNOWN;
    }
    pTdlsCommand->setSubCmd(QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_CAPABILITIES);

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

    ret = pTdlsCommand->set_iface_id(iinfo->name);
    if (ret != WIFI_SUCCESS)
        goto cleanup;

    ret = pTdlsCommand->requestResponse();
    if (ret != WIFI_SUCCESS) {
        ALOGE("%s: requestResponse Error:%d", __FUNCTION__, ret);
        goto cleanup;
    }
    pTdlsCommand->getCapsRspParams(capabilities);

cleanup:
    if (ret != WIFI_SUCCESS)
        memset(capabilities, 0, sizeof(wifi_tdls_capabilities));
    delete pTdlsCommand;
    return ret;
}
