/* Copyright (c) 2015, 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.
 */

#include "sync.h"

#include "wifi_hal.h"
#include "common.h"
#include "cpp_bindings.h"
#include <errno.h>
#include <utils/Log.h>
#include "wifiloggercmd.h"
#include "rb_wrapper.h"

#define LOGGER_MEMDUMP_FILENAME "/proc/debug/fwdump"
#define LOGGER_MEMDUMP_CHUNKSIZE (4 * 1024)

char power_events_ring_name[] = "power_events_rb";
char connectivity_events_ring_name[] = "connectivity_events_rb";
char pkt_stats_ring_name[] = "pkt_stats_rb";
char driver_prints_ring_name[] = "driver_prints_rb";
char firmware_prints_ring_name[] = "firmware_prints_rb";

static int get_ring_id(hal_info *info, char *ring_name)
{
    int rb_id;

    for (rb_id = 0; rb_id < NUM_RING_BUFS; rb_id++) {
        if (is_rb_name_match(&info->rb_infos[rb_id], ring_name)) {
           return rb_id;
        }
    }
    return -1;
}

//Implementation of the functions exposed in wifi_logger.h

/* Function to intiate logging */
wifi_error wifi_start_logging(wifi_interface_handle iface,
                              u32 verbose_level, u32 flags,
                              u32 max_interval_sec, u32 min_data_size,
                              char *buffer_name)
{
    int requestId, ret = 0;
    WifiLoggerCommand *wifiLoggerCommand = NULL;
    struct nlattr *nlData;
    interface_info *ifaceInfo = getIfaceInfo(iface);
    wifi_handle wifiHandle = getWifiHandle(iface);
    hal_info *info = getHalInfo(wifiHandle);
    int ring_id = 0;

    /*
     * No request id from caller, so generate one and pass it on to the driver.
     * Generate one randomly.
     */
    requestId = rand();

    if (buffer_name == NULL) {
        ALOGE("%s: Invalid Ring Name. \n", __FUNCTION__);
        return WIFI_ERROR_UNKNOWN;
    }

    ring_id = get_ring_id(info, buffer_name);
    if (ring_id < 0) {
        ALOGE("%s: Invalid Ring Buffer Name ", __FUNCTION__);
        return WIFI_ERROR_UNKNOWN;
    }

    if ((ring_id == POWER_EVENTS_RB_ID) ||
        (ring_id == PKT_STATS_RB_ID)) {
        wifiLoggerCommand = new WifiLoggerCommand(
                                wifiHandle,
                                requestId,
                                OUI_QCA,
                                QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_START);

        if (wifiLoggerCommand == NULL) {
           ALOGE("%s: Error WifiLoggerCommand NULL", __FUNCTION__);
           return WIFI_ERROR_UNKNOWN;
        }
        /* Create the NL message. */
        ret = wifiLoggerCommand->create();

        if (ret < 0)
            goto cleanup;

        /* Set the interface Id of the message. */
        ret = wifiLoggerCommand->set_iface_id(ifaceInfo->name);

        if (ret < 0)
            goto cleanup;

        /* Add the vendor specific attributes for the NL command. */
        nlData = wifiLoggerCommand->attr_start(NL80211_ATTR_VENDOR_DATA);

        if (!nlData)
            goto cleanup;

        if (wifiLoggerCommand->put_u32(
                    QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID, ring_id))
        {
            goto cleanup;
        }
        if (wifiLoggerCommand->put_u32(
                    QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL,
                    verbose_level))
        {
            goto cleanup;
        }
        if (wifiLoggerCommand->put_u32(
                    QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS,
                    flags))
        {
            goto cleanup;
        }

        wifiLoggerCommand->attr_end(nlData);

        /* Send the msg and wait for a response. */
        ret = wifiLoggerCommand->requestResponse();
        if (ret) {
            ALOGE("%s: Error %d happened. ", __FUNCTION__, ret);
        }

    }
    ALOGI("%s: Logging Started for %s.", __FUNCTION__, buffer_name);
    rb_start_logging(&info->rb_infos[ring_id], verbose_level,
                    flags, max_interval_sec, min_data_size);
cleanup:
    if (wifiLoggerCommand)
        delete wifiLoggerCommand;
    return (wifi_error)ret;

}

/*  Function to get each ring related info */
wifi_error wifi_get_ring_buffers_status(wifi_interface_handle iface,
                                        u32 *num_buffers,
                                        wifi_ring_buffer_status *status)
{
    int ret = 0;
    interface_info *ifaceInfo = getIfaceInfo(iface);
    wifi_handle wifiHandle = getWifiHandle(iface);
    hal_info *info = getHalInfo(wifiHandle);
    wifi_ring_buffer_status *rbs;
    struct rb_info *rb_info;
    int rb_id;

    if ((*num_buffers) < NUM_RING_BUFS) {
        ALOGE("%s: Input num_buffers:%d cannot be accommodated, "
              "Total ring buffer num:%d", __FUNCTION__, num_buffers,
              NUM_RING_BUFS);
        *num_buffers = 0;
        return WIFI_ERROR_OUT_OF_MEMORY;
    }
    for (rb_id = 0; rb_id < NUM_RING_BUFS; rb_id++) {
        rb_info = &info->rb_infos[rb_id];
        rbs = status + rb_id;

        get_rb_status(rb_info, rbs);
    }
    *num_buffers = NUM_RING_BUFS;
    return (wifi_error)ret;
}

void push_out_all_ring_buffers(hal_info *info)
{
    int rb_id;

    for (rb_id = 0; rb_id < NUM_RING_BUFS; rb_id++) {
        push_out_rb_data(&info->rb_infos[rb_id]);
    }
}

void send_alert(hal_info *info, int reason_code)
{
    //TODO check locking
    if (info->on_alert) {
        info->on_alert(0, NULL, 0, reason_code);
    }
}

void WifiLoggerCommand::setFeatureSet(u32 *support) {
    mSupportedSet = support;
}

/*  Function to get the supported feature set for logging.*/
wifi_error wifi_get_logger_supported_feature_set(wifi_interface_handle iface,
                                                 u32 *support)
{

    int requestId, ret = 0;
    WifiLoggerCommand *wifiLoggerCommand;
    struct nlattr *nlData;
    interface_info *ifaceInfo = getIfaceInfo(iface);
    wifi_handle wifiHandle = getWifiHandle(iface);
    hal_info *info = getHalInfo(wifiHandle);

    /* No request id from caller, so generate one and pass it on to the driver.
     * Generate one randomly.
     */
    requestId = rand();

    wifiLoggerCommand = new WifiLoggerCommand(
                            wifiHandle,
                            requestId,
                            OUI_QCA,
                            QCA_NL80211_VENDOR_SUBCMD_GET_LOGGER_FEATURE_SET);

    if (wifiLoggerCommand == NULL) {
        ALOGE("%s: Error WifiLoggerCommand NULL", __FUNCTION__);
        return WIFI_ERROR_UNKNOWN;
    }
    /* Create the NL message. */
    ret = wifiLoggerCommand->create();

    if (ret < 0)
        goto cleanup;

    /* Set the interface Id of the message. */
    ret = wifiLoggerCommand->set_iface_id(ifaceInfo->name);

    if (ret < 0)
        goto cleanup;

    /* Add the vendor specific attributes for the NL command. */
    nlData = wifiLoggerCommand->attr_start(NL80211_ATTR_VENDOR_DATA);

    if (!nlData)
        goto cleanup;

    if (wifiLoggerCommand->put_u32(
                QCA_WLAN_VENDOR_ATTR_FEATURE_SET, requestId))
    {
        goto cleanup;
    }
    wifiLoggerCommand->attr_end(nlData);

    wifiLoggerCommand->setFeatureSet(support);

    /* Send the msg and wait for a response. */
    ret = wifiLoggerCommand->requestResponse();
    if (ret) {
        ALOGE("%s: Error %d happened. ", __FUNCTION__, ret);
    }

cleanup:
    delete wifiLoggerCommand;
    return (wifi_error)ret;
}

/*  Function to get the data in each ring for the given ring ID.*/
wifi_error wifi_get_ring_data(wifi_interface_handle iface,
                              char *ring_name)
{

    int requestId, ret = 0;
    WifiLoggerCommand *wifiLoggerCommand;
    struct nlattr *nlData;
    interface_info *ifaceInfo = getIfaceInfo(iface);
    wifi_handle wifiHandle = getWifiHandle(iface);
    hal_info *info = getHalInfo(wifiHandle);
    int ring_id = 0;

    ring_id = get_ring_id(info, ring_name);
    if (ring_id < 0) {
        ALOGE("%s: Invalid Ring Buffer Name ", __FUNCTION__);
        return WIFI_ERROR_UNKNOWN;
    }

    requestId = rand();

    wifiLoggerCommand = new WifiLoggerCommand(
                                wifiHandle,
                                requestId,
                                OUI_QCA,
                                QCA_NL80211_VENDOR_SUBCMD_GET_RING_DATA);
    if (wifiLoggerCommand == NULL) {
        ALOGE("%s: Error WifiLoggerCommand NULL", __FUNCTION__);
        return WIFI_ERROR_UNKNOWN;
    }
    /* Create the NL message. */
    ret = wifiLoggerCommand->create();

    if (ret < 0)
        goto cleanup;

    /* Set the interface Id of the message. */
    ret = wifiLoggerCommand->set_iface_id(ifaceInfo->name);

    if (ret < 0)
        goto cleanup;

    /* Add the vendor specific attributes for the NL command. */
    nlData = wifiLoggerCommand->attr_start(NL80211_ATTR_VENDOR_DATA);

    if (!nlData)
        goto cleanup;

    if (wifiLoggerCommand->put_u32(
                QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID, ring_id))
    {
        goto cleanup;
    }
    wifiLoggerCommand->attr_end(nlData);

    //TBD  Is there requestResponse here
    /* Send the msg and wait for a response. */
    ret = wifiLoggerCommand->requestResponse();
    if (ret) {
        ALOGE("%s: Error %d happened. ", __FUNCTION__, ret);
    }

cleanup:
    delete wifiLoggerCommand;
    return (wifi_error)ret;
}

void WifiLoggerCommand::setVersionInfo(char *buffer, int buffer_size) {
    mVersion = buffer;
    mVersionLen = buffer_size;
}

/*  Function to send enable request to the wifi driver.*/
wifi_error wifi_get_firmware_version(wifi_interface_handle iface,
                                     char *buffer, int buffer_size)
{
    int requestId, ret = 0;
    WifiLoggerCommand *wifiLoggerCommand;
    struct nlattr *nlData;
    interface_info *ifaceInfo = getIfaceInfo(iface);
    wifi_handle wifiHandle = getWifiHandle(iface);
    hal_info *info = getHalInfo(wifiHandle);

    /* No request id from caller, so generate one and pass it on to the driver.
     * Generate one randomly.
     */
    requestId = rand();

    wifiLoggerCommand = new WifiLoggerCommand(
                                wifiHandle,
                                requestId,
                                OUI_QCA,
                                QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO);
    if (wifiLoggerCommand == NULL) {
        ALOGE("%s: Error WifiLoggerCommand NULL", __FUNCTION__);
        return WIFI_ERROR_UNKNOWN;
    }
    /* Create the NL message. */
    ret = wifiLoggerCommand->create();

    if (ret < 0)
        goto cleanup;

    /* Set the interface Id of the message. */
    ret = wifiLoggerCommand->set_iface_id(ifaceInfo->name);

    if (ret < 0)
        goto cleanup;

    /* Add the vendor specific attributes for the NL command. */
    nlData = wifiLoggerCommand->attr_start(NL80211_ATTR_VENDOR_DATA);

    if (!nlData)
        goto cleanup;

    if (wifiLoggerCommand->put_u32(
                QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION, requestId))
    {
        goto cleanup;
    }
    wifiLoggerCommand->attr_end(nlData);

    wifiLoggerCommand->setVersionInfo(buffer, buffer_size);

    /* Send the msg and wait for a response. */
    ret = wifiLoggerCommand->requestResponse();
    if (ret) {
        ALOGE("%s: Error %d happened. ", __FUNCTION__, ret);
    }
cleanup:
    delete wifiLoggerCommand;
    return (wifi_error)ret;

}

/*  Function to get wlan driver version.*/
wifi_error wifi_get_driver_version(wifi_interface_handle iface,
                                   char *buffer, int buffer_size)
{

    int requestId, ret = 0;
    WifiLoggerCommand *wifiLoggerCommand;
    struct nlattr *nlData;
    interface_info *ifaceInfo = getIfaceInfo(iface);
    wifi_handle wifiHandle = getWifiHandle(iface);
    hal_info *info = getHalInfo(wifiHandle);

    /* No request id from caller, so generate one and pass it on to the driver.
     * Generate one randomly.
     */
    requestId = rand();

    wifiLoggerCommand = new WifiLoggerCommand(
                            wifiHandle,
                            requestId,
                            OUI_QCA,
                            QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO);
    if (wifiLoggerCommand == NULL) {
        ALOGE("%s: Error WifiLoggerCommand NULL", __FUNCTION__);
        return WIFI_ERROR_UNKNOWN;
    }
    /* Create the NL message. */
    ret = wifiLoggerCommand->create();

    if (ret < 0)
        goto cleanup;

    /* Set the interface Id of the message. */
    ret = wifiLoggerCommand->set_iface_id(ifaceInfo->name);

    if (ret < 0)
        goto cleanup;

    /* Add the vendor specific attributes for the NL command. */
    nlData = wifiLoggerCommand->attr_start(NL80211_ATTR_VENDOR_DATA);

    if (!nlData)
        goto cleanup;

    if (wifiLoggerCommand->put_u32(
            QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION, requestId))
    {
        goto cleanup;
    }
    wifiLoggerCommand->attr_end(nlData);

    wifiLoggerCommand->setVersionInfo(buffer, buffer_size);

    /* Send the msg and wait for a response. */
    ret = wifiLoggerCommand->requestResponse();
    if (ret) {
        ALOGE("%s: Error %d happened. ", __FUNCTION__, ret);
    }
cleanup:
    delete wifiLoggerCommand;
    return (wifi_error)ret;
}


/* Function to get the Firmware memory dump. */
wifi_error wifi_get_firmware_memory_dump(wifi_interface_handle iface,
                                wifi_firmware_memory_dump_handler handler)
{
    int requestId, ret = 0;
    WifiLoggerCommand *wifiLoggerCommand;
    struct nlattr *nlData;
    interface_info *ifaceInfo = getIfaceInfo(iface);
    wifi_handle wifiHandle = getWifiHandle(iface);
    hal_info *info = getHalInfo(wifiHandle);

    /* No request id from caller, so generate one and pass it on to the driver.
     * Generate one randomly.
     */
    requestId = rand();

    wifiLoggerCommand = new WifiLoggerCommand(
                            wifiHandle,
                            requestId,
                            OUI_QCA,
                            QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP);
    if (wifiLoggerCommand == NULL) {
        ALOGE("%s: Error WifiLoggerCommand NULL", __FUNCTION__);
        return WIFI_ERROR_UNKNOWN;
    }
    /* Create the NL message. */
    ret = wifiLoggerCommand->create();

    if (ret < 0)
        goto cleanup;

    /* Set the interface Id of the message. */
    ret = wifiLoggerCommand->set_iface_id(ifaceInfo->name);

    if (ret < 0)
        goto cleanup;

    /* Add the vendor specific attributes for the NL command. */
    nlData = wifiLoggerCommand->attr_start(NL80211_ATTR_VENDOR_DATA);

    if (!nlData)
        goto cleanup;

    wifiLoggerCommand->attr_end(nlData);

    /* copy the callback into callback handler */
    WifiLoggerCallbackHandler callbackHandler;
    memset(&callbackHandler, 0, sizeof(callbackHandler));
    callbackHandler.on_firmware_memory_dump = \
        handler.on_firmware_memory_dump;

    ret = wifiLoggerCommand->setCallbackHandler(callbackHandler);
    if (ret < 0)
        goto cleanup;

    /* Send the msg and wait for the memory dump event */
    wifiLoggerCommand->waitForRsp(true);
    ret = wifiLoggerCommand->requestEvent();
    if (ret) {
        ALOGE("%s: Error %d happened. ", __FUNCTION__, ret);
    }

cleanup:
    delete wifiLoggerCommand;
    return (wifi_error)ret;
}

wifi_error wifi_set_log_handler(wifi_request_id id,
                                wifi_interface_handle iface,
                                wifi_ring_buffer_data_handler handler)
{
    wifi_handle wifiHandle = getWifiHandle(iface);
    hal_info *info = getHalInfo(wifiHandle);

    info->on_ring_buffer_data = handler.on_ring_buffer_data;
    if (handler.on_ring_buffer_data == NULL) {
        ALOGE("Set log handler is NULL");
        return WIFI_ERROR_UNKNOWN;
    }
    return WIFI_SUCCESS;
}

wifi_error wifi_reset_log_handler(wifi_request_id id,
                                  wifi_interface_handle iface)
{
    wifi_handle wifiHandle = getWifiHandle(iface);
    hal_info *info = getHalInfo(wifiHandle);

    /* Some locking needs to be introduced here */
    info->on_ring_buffer_data = NULL;
    return WIFI_SUCCESS;
}

wifi_error wifi_set_alert_handler(wifi_request_id id,
                                  wifi_interface_handle iface,
                                  wifi_alert_handler handler)
{
    wifi_handle wifiHandle = getWifiHandle(iface);
    hal_info *info = getHalInfo(wifiHandle);

    if (handler.on_alert == NULL) {
        ALOGE("Set alert handler is NULL");
        return WIFI_ERROR_UNKNOWN;
    }
    //TODO check locking
    info->on_alert = handler.on_alert;
    return WIFI_SUCCESS;
}

wifi_error wifi_reset_alert_handler(wifi_request_id id,
                                    wifi_interface_handle iface)
{
    wifi_handle wifiHandle = getWifiHandle(iface);
    hal_info *info = getHalInfo(wifiHandle);

    /* Some locking needs to be introduced here */
    info->on_alert = NULL;
    return WIFI_SUCCESS;
}

WifiLoggerCommand::WifiLoggerCommand(wifi_handle handle, int id, u32 vendor_id, u32 subcmd)
        : WifiVendorCommand(handle, id, vendor_id, subcmd)
{
    ALOGV("WifiLoggerCommand %p constructed", this);
    mVersion = NULL;
    mVersionLen = 0;
    mRequestId = id;
    memset(&mHandler, 0,sizeof(mHandler));
    mWaitforRsp = false;
    mMoreData = false;
    mSupportedSet = NULL;
}

WifiLoggerCommand::~WifiLoggerCommand()
{
    ALOGD("WifiLoggerCommand %p destructor", this);
    unregisterVendorHandler(mVendor_id, mSubcmd);
}

/* This function implements creation of Vendor command */
int WifiLoggerCommand::create() {
    int ret = mMsg.create(NL80211_CMD_VENDOR, 0, 0);
    if (ret < 0) {
        return ret;
    }

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

     ALOGI("%s: mVendor_id = %d, Subcmd = %d.",
        __FUNCTION__, mVendor_id, mSubcmd);

out:
    return ret;
}

void rb_timerhandler(hal_info *info)
{
   struct timeval now;
   int rb_id;

   gettimeofday(&now,NULL);
   for (rb_id = 0; rb_id < NUM_RING_BUFS; rb_id++) {
       rb_check_for_timeout(&info->rb_infos[rb_id], &now);
   }
}

wifi_error wifi_logger_ring_buffers_init(hal_info *info)
{
    wifi_error ret;

    ret = rb_init(info, &info->rb_infos[POWER_EVENTS_RB_ID],
                  POWER_EVENTS_RB_ID,
                  POWER_EVENTS_RB_BUF_SIZE,
                  POWER_EVENTS_NUM_BUFS,
                  power_events_ring_name);
    if (ret != WIFI_SUCCESS) {
        ALOGE("Failed to initialize power events ring buffer");
        goto cleanup;
    }

    ret = rb_init(info, &info->rb_infos[CONNECTIVITY_EVENTS_RB_ID],
                  CONNECTIVITY_EVENTS_RB_ID,
                  CONNECTIVITY_EVENTS_RB_BUF_SIZE,
                  CONNECTIVITY_EVENTS_NUM_BUFS,
                  connectivity_events_ring_name);
    if (ret != WIFI_SUCCESS) {
        ALOGE("Failed to initialize connectivity events ring buffer");
        goto cleanup;
    }

    ret = rb_init(info, &info->rb_infos[PKT_STATS_RB_ID],
                  PKT_STATS_RB_ID,
                  PKT_STATS_RB_BUF_SIZE,
                  PKT_STATS_NUM_BUFS,
                  pkt_stats_ring_name);
    if (ret != WIFI_SUCCESS) {
        ALOGE("Failed to initialize per packet stats ring buffer");
        goto cleanup;
    }

    ret = rb_init(info, &info->rb_infos[DRIVER_PRINTS_RB_ID],
                  DRIVER_PRINTS_RB_ID,
                  DRIVER_PRINTS_RB_BUF_SIZE,
                  DRIVER_PRINTS_NUM_BUFS,
                  driver_prints_ring_name);
    if (ret != WIFI_SUCCESS) {
        ALOGE("Failed to initialize driver prints ring buffer");
        goto cleanup;
    }

    ret = rb_init(info, &info->rb_infos[FIRMWARE_PRINTS_RB_ID],
                  FIRMWARE_PRINTS_RB_ID,
                  FIRMWARE_PRINTS_RB_BUF_SIZE,
                  FIRMWARE_PRINTS_NUM_BUFS,
                  firmware_prints_ring_name);
    if (ret != WIFI_SUCCESS) {
        ALOGE("Failed to initialize firmware prints ring buffer");
        goto cleanup;
    }

    return ret;

cleanup:
    wifi_logger_ring_buffers_deinit(info);
    return ret;
}

void wifi_logger_ring_buffers_deinit(hal_info *info)
{
    int i;

    for (i = 0; i < NUM_RING_BUFS; i++) {
        rb_deinit(&info->rb_infos[i]);
    }
}


/* Callback handlers registered for nl message send */
static int error_handler_wifi_logger(struct sockaddr_nl *nla,
                                     struct nlmsgerr *err,
                                     void *arg)
{
    struct sockaddr_nl *tmp;
    int *ret = (int *)arg;
    tmp = nla;
    *ret = err->error;
    ALOGE("%s: Error code:%d (%s)", __FUNCTION__, *ret, strerror(-(*ret)));
    return NL_STOP;
}

/* Callback handlers registered for nl message send */
static int ack_handler_wifi_logger(struct nl_msg *msg, void *arg)
{
    int *ret = (int *)arg;
    struct nl_msg * a;

    ALOGE("%s: called", __FUNCTION__);
    a = msg;
    *ret = 0;
    return NL_STOP;
}

/* Callback handlers registered for nl message send */
static int finish_handler_wifi_logger(struct nl_msg *msg, void *arg)
{
  int *ret = (int *)arg;
  struct nl_msg * a;

  ALOGE("%s: called", __FUNCTION__);
  a = msg;
  *ret = 0;
  return NL_SKIP;
}

int WifiLoggerCommand::requestEvent()
{
    int res = -1;
    struct nl_cb *cb;

    ALOGD("%s: Entry.", __FUNCTION__);

    cb = nl_cb_alloc(NL_CB_DEFAULT);
    if (!cb) {
        ALOGE("%s: Callback allocation failed",__FUNCTION__);
        res = -1;
        goto out;
    }

    /* Send message */
    res = nl_send_auto_complete(mInfo->cmd_sock, mMsg.getMessage());
    if (res < 0)
        goto out;
    res = 1;

    nl_cb_err(cb, NL_CB_CUSTOM, error_handler_wifi_logger, &res);
    nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler_wifi_logger, &res);
    nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler_wifi_logger, &res);

    /* Err is populated as part of finish_handler. */
    while (res > 0){
         nl_recvmsgs(mInfo->cmd_sock, cb);
    }

    ALOGD("%s: Msg sent, res=%d, mWaitForRsp=%d", __FUNCTION__, res, mWaitforRsp);
    /* Only wait for the asynchronous event if HDD returns success, res=0 */
    if (!res && (mWaitforRsp == true)) {
        struct timespec abstime;
        abstime.tv_sec = 4;
        abstime.tv_nsec = 0;
        res = mCondition.wait(abstime);
        if (res == ETIMEDOUT)
        {
            ALOGE("%s: Time out happened.", __FUNCTION__);
        }
        ALOGD("%s: Command invoked return value:%d, mWaitForRsp=%d",
            __FUNCTION__, res, mWaitforRsp);
    }
out:
    /* Cleanup the mMsg */
    mMsg.destroy();
    return res;
}

int WifiLoggerCommand::requestResponse()
{
    return WifiCommand::requestResponse(mMsg);
}

int WifiLoggerCommand::handleResponse(WifiEvent &reply) {
    ALOGD("Received a WifiLogger response message from Driver");
    u32 status;
    int ret = WIFI_SUCCESS;
    int i = 0;
    int len = 0, version;
    char version_type[20];
    WifiVendorCommand::handleResponse(reply);

    switch(mSubcmd)
    {
        case QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO:
        {
            struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX + 1];

            nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX,
                            (struct nlattr *)mVendorData, mDataLen, NULL);

            if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION]) {
                len = nla_len(tb_vendor[
                        QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION]);
                memcpy(version_type, "Driver", strlen("Driver"));
                version = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION;
            } else if (
                tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION]) {
                len = nla_len(
                        tb_vendor[
                        QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION]);
                memcpy(version_type, "Firmware", strlen("Firmware"));
                version = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION;
            }
            if (len && mVersion && mVersionLen) {
                memset(mVersion, 0, mVersionLen);
                /* if len is greater than the incoming length then
                   accommodate 1 lesser than mVersionLen to have the
                   string terminated with '\0' */
                len = (len > mVersionLen)? (mVersionLen - 1) : len;
                memcpy(mVersion, nla_data(tb_vendor[version]), len);
                ALOGD("%s: WLAN version len : %d", __FUNCTION__, len);
                ALOGD("%s: WLAN %s version : %s ", __FUNCTION__,
                      version_type, mVersion);
            }
        }
        break;
        case QCA_NL80211_VENDOR_SUBCMD_GET_LOGGER_FEATURE_SET:
        {
            struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_FEATURE_SET_MAX + 1];

            nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_FEATURE_SET_MAX,
                            (struct nlattr *)mVendorData, mDataLen, NULL);

            if (tb_vendor[QCA_WLAN_VENDOR_ATTR_FEATURE_SET]) {
                *mSupportedSet =
                nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_FEATURE_SET]);
                ALOGD("%s: Supported Feature Set : val 0x%x",
                      __FUNCTION__, *mSupportedSet);
            }
        }
        break;
        default :
            ALOGE("%s: Wrong Wifi Logger subcmd response received %d",
                __FUNCTION__, mSubcmd);
    }

    return NL_SKIP;
}

/* This function will be the main handler for incoming (from driver)
 * WIFI_LOGGER_SUBCMD.
 * Calls the appropriate callback handler after parsing the vendor data.
 */
int WifiLoggerCommand::handleEvent(WifiEvent &event)
{
    unsigned i = 0;
    u32 status;
    int ret = WIFI_SUCCESS;
    char* memBuffer = NULL;
    FILE* memDumpFilePtr = NULL;

    WifiVendorCommand::handleEvent(event);

    struct nlattr *tbVendor[
        QCA_WLAN_VENDOR_ATTR_LOGGER_RESULTS_MAX + 1];
    nla_parse(tbVendor, QCA_WLAN_VENDOR_ATTR_LOGGER_RESULTS_MAX,
            (struct nlattr *)mVendorData,
            mDataLen, NULL);

    switch(mSubcmd)
    {
        case QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP:
        {
            int id = 0;
            u32 memDumpSize = 0;
            int numRecordsRead = 0;
            u32 remaining = 0;
            char* buffer = NULL;

            if (!tbVendor[
                QCA_WLAN_VENDOR_ATTR_LOGGER_RESULTS_REQUEST_ID]) {
                ALOGE("%s: LOGGER_RESULTS_REQUEST_ID not"
                    "found, continuing...", __func__);
            }
            else {
                id = nla_get_u32(tbVendor[
                          QCA_WLAN_VENDOR_ATTR_LOGGER_RESULTS_REQUEST_ID]
                      );
                ALOGI("%s: Event has Req. ID:%d, ours:%d",
                    __func__, id, mRequestId);
            }

            if (!tbVendor[
                QCA_WLAN_VENDOR_ATTR_LOGGER_RESULTS_MEMDUMP_SIZE]) {
                ALOGE("%s: LOGGER_RESULTS_MEMDUMP_SIZE not"
                    "found", __func__);
                break;
            }

            memDumpSize = nla_get_u32(
                tbVendor[QCA_WLAN_VENDOR_ATTR_LOGGER_RESULTS_MEMDUMP_SIZE]
                );

            /* Allocate the memory indicated in memDumpSize */
            memBuffer = (char*) malloc(sizeof(char) * memDumpSize);
            if (memBuffer == NULL) {
                ALOGE("%s: No Memory for allocating Buffer ",
                      "size of %d", __func__, memDumpSize);
                break;
            }
            memset(memBuffer, 0, sizeof(char) * memDumpSize);

            ALOGI("%s: Memory Dump size: %u", __func__,
                  memDumpSize);

            /* Open the proc or debugfs filesystem */
            memDumpFilePtr = fopen(LOGGER_MEMDUMP_FILENAME, "r");
            if (memDumpFilePtr == NULL) {
                ALOGE("Failed to open %s file", LOGGER_MEMDUMP_FILENAME);
                break;
            }

            /* Read the memDumpSize value at once */
            numRecordsRead = fread(memBuffer, 1, memDumpSize,
                                   memDumpFilePtr);
            if (numRecordsRead <= 0 ||
                numRecordsRead != (int) memDumpSize) {
                ALOGE("%s: Read %d failed for reading at once.",
                      __func__, numRecordsRead);
                /* Lets try to read in chunks */
                rewind(memDumpFilePtr);
                remaining = memDumpSize;
                buffer = memBuffer;
                while (remaining) {
                    u32 readSize = 0;
                    if (remaining >= LOGGER_MEMDUMP_CHUNKSIZE) {
                        readSize = LOGGER_MEMDUMP_CHUNKSIZE;
                    }
                    else {
                        readSize = remaining;
                    }
                    numRecordsRead = fread(buffer, 1,
                                           readSize, memDumpFilePtr);
                    if (numRecordsRead) {
                        remaining -= readSize;
                        buffer += readSize;
                        ALOGI("%s: Read successful for size:%u "
                              "remaining:%u", __func__, readSize,
                              remaining);
                    }
                    else {
                        ALOGE("%s: Chunk read failed for size:%u",
                              __func__, readSize);
                        break;
                    }
                }
            }

            /* After successful read, call the callback handler*/
            if (mHandler.on_firmware_memory_dump) {
                mHandler.on_firmware_memory_dump(memBuffer,
                                                 memDumpSize);

            }
        }
        break;

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

cleanup:
    /* free the allocated memory */
    if (memBuffer) {
        free(memBuffer);
    }
    return NL_SKIP;
}

int WifiLoggerCommand::setCallbackHandler(WifiLoggerCallbackHandler nHandler)
{
    int res = 0;
    mHandler = nHandler;
    res = registerVendorHandler(mVendor_id, mSubcmd);
    if (res != 0) {
        ALOGE("%s: Unable to register Vendor Handler Vendor Id=0x%x subcmd=%u",
              __FUNCTION__, mVendor_id, mSubcmd);
    }
    return res;
}

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

int WifiLoggerCommand::timed_wait(u16 wait_time)
{
    struct timespec absTime;
    int res;
    absTime.tv_sec = wait_time;
    absTime.tv_nsec = 0;
    return mCondition.wait(absTime);
}

void WifiLoggerCommand::waitForRsp(bool wait)
{
    mWaitforRsp = wait;
}

