/* 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;
                }
                if (nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_TDLS_MAC_ADDR]) != sizeof(mac_addr))
                {
                    ALOGE("%s: QCA_WLAN_VENDOR_ATTR_TDLS_MAC_ADDR Invalid mac addr lenght",
                            __FUNCTION__);
                    return WIFI_ERROR_INVALID_ARGS;
                }
                memcpy(addr,
                  (u8 *)nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_TDLS_MAC_ADDR]),
                  sizeof(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;
}
