/* Copyright (c) 2015, 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.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted (subject to the limitations in the
 * disclaimer below) provided that the following conditions are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *
 *   * Neither the name of Qualcomm Innovation Center, Inc. nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
 * GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
 * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "sync.h"

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

#define LOGGER_MEMDUMP_FILENAME "/proc/debug/fwdump"
#define DRIVER_MEMDUMP_FILENAME "/proc/debugdriver/driverdump"
#define LOGGER_MEMDUMP_CHUNKSIZE (4 * 1024)
#define DRIVER_MEMDUMP_MAX_FILESIZE (16 * 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;
    wifi_error ret;
    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;

    /* Check Supported logger capability */
    if (!(info->supported_logger_feature_set & LOGGER_RING_BUFFER)) {
        ALOGE("%s: Ring buffer logging feature not supported %x", __FUNCTION__,
              info->supported_logger_feature_set);
        return WIFI_ERROR_NOT_SUPPORTED;
    }
    /*
     * No request id from caller, so generate one and pass it on to the driver.
     * Generate one randomly.
     */
    requestId = get_requestid();

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

    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 != WIFI_SUCCESS)
        goto cleanup;

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

    /* Add the vendor specific attributes for the NL command. */
    nlData = wifiLoggerCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
    if (!nlData){
        ret = WIFI_ERROR_UNKNOWN;
        goto cleanup;
    }

    ret = wifiLoggerCommand->put_u32(QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID,
                                     ring_id);
    if (ret != WIFI_SUCCESS)
        goto cleanup;

    ret = wifiLoggerCommand->put_u32(
                             QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL,
                             verbose_level);
    if (ret != WIFI_SUCCESS)
        goto cleanup;

    ret = wifiLoggerCommand->put_u32(QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS,
                                     flags);
    if (ret != WIFI_SUCCESS)
        goto cleanup;

    wifiLoggerCommand->attr_end(nlData);

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

    ALOGV("%s: Logging Started for %s. with verboselevel %d",
           __FUNCTION__, buffer_name,verbose_level);
    rb_start_logging(&info->rb_infos[ring_id], verbose_level,
                    flags, max_interval_sec, min_data_size);
cleanup:
    delete wifiLoggerCommand;
    return 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)
{
    wifi_handle wifiHandle = getWifiHandle(iface);
    hal_info *info = getHalInfo(wifiHandle);
    wifi_ring_buffer_status *rbs;
    struct rb_info *rb_info;
    int rb_id;

    /* Check Supported logger capability */
    if (!(info->supported_logger_feature_set & LOGGER_RING_BUFFER)) {
        ALOGE("%s: Ring buffer logging feature not supported %x", __FUNCTION__,
              info->supported_logger_feature_set);
        return WIFI_ERROR_NOT_SUPPORTED;
    }

    if ((*num_buffers) < NUM_RING_BUFS) {
        ALOGE("%s: Input num_buffers:%u 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_SUCCESS;
}

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)
{
    wifi_alert_handler handler;
    char alert_msg[20] = "Fatal Event";
    pthread_mutex_lock(&info->ah_lock);
    handler.on_alert = info->on_alert;
    pthread_mutex_unlock(&info->ah_lock);

    if (handler.on_alert) {
        handler.on_alert(0, alert_msg, strlen(alert_msg), 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;
    wifi_error ret;
    WifiLoggerCommand *wifiLoggerCommand;
    struct nlattr *nlData;
    interface_info *ifaceInfo = getIfaceInfo(iface);
    wifi_handle wifiHandle = getWifiHandle(iface);

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

    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 != WIFI_SUCCESS)
        goto cleanup;

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

    /* Add the vendor specific attributes for the NL command. */
    nlData = wifiLoggerCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
    if (!nlData){
        ret = WIFI_ERROR_UNKNOWN;
        goto cleanup;
    }

    ret = wifiLoggerCommand->put_u32(QCA_WLAN_VENDOR_ATTR_LOGGER_SUPPORTED,
                                     requestId);
    if (ret != WIFI_SUCCESS)
        goto cleanup;

    wifiLoggerCommand->attr_end(nlData);

    wifiLoggerCommand->setFeatureSet(support);

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

cleanup:
    delete wifiLoggerCommand;
    return 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;
    wifi_error ret;
    WifiLoggerCommand *wifiLoggerCommand;
    struct nlattr *nlData;
    interface_info *ifaceInfo = getIfaceInfo(iface);
    wifi_handle wifiHandle = getWifiHandle(iface);
    hal_info *info = getHalInfo(wifiHandle);
    int ring_id = 0;

    /* Check Supported logger capability */
    if (!(info->supported_logger_feature_set & LOGGER_RING_BUFFER)) {
        ALOGE("%s: Ring buffer logging feature not supported %x", __FUNCTION__,
              info->supported_logger_feature_set);
        return WIFI_ERROR_NOT_SUPPORTED;
    }

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

    requestId = get_requestid();

    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 != WIFI_SUCCESS)
        goto cleanup;

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

    /* Add the vendor specific attributes for the NL command. */
    nlData = wifiLoggerCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
    if (!nlData){
        ret = WIFI_ERROR_UNKNOWN;
        goto cleanup;
    }

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

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

cleanup:
    delete wifiLoggerCommand;
    return 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;
    wifi_error ret;
    WifiLoggerCommand *wifiLoggerCommand;
    struct nlattr *nlData;
    interface_info *ifaceInfo = getIfaceInfo(iface);
    wifi_handle wifiHandle = getWifiHandle(iface);

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

    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 != WIFI_SUCCESS)
        goto cleanup;

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

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

    ret = wifiLoggerCommand->put_u8(
                QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION, requestId);
    if (ret != WIFI_SUCCESS)
        goto cleanup;

    wifiLoggerCommand->attr_end(nlData);

    wifiLoggerCommand->setVersionInfo(buffer, buffer_size);

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

cleanup:
    delete wifiLoggerCommand;
    return ret;

}

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

    int requestId;
    wifi_error ret;
    WifiLoggerCommand *wifiLoggerCommand;
    struct nlattr *nlData;
    interface_info *ifaceInfo = getIfaceInfo(iface);
    wifi_handle wifiHandle = getWifiHandle(iface);

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

    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 != WIFI_SUCCESS)
        goto cleanup;

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

    /* Add the vendor specific attributes for the NL command. */
    nlData = wifiLoggerCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
    if (!nlData){
        ret = WIFI_ERROR_UNKNOWN;
        goto cleanup;
    }

    ret = wifiLoggerCommand->put_u8(
                      QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION, requestId);
    if (ret != WIFI_SUCCESS)
        goto cleanup;

    wifiLoggerCommand->attr_end(nlData);

    wifiLoggerCommand->setVersionInfo(buffer, buffer_size);

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

cleanup:
    delete wifiLoggerCommand;
    return 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)
{
    wifi_error ret;
    int requestId;
    WifiLoggerCommand *wifiLoggerCommand;
    struct nlattr *nlData;
    interface_info *ifaceInfo = getIfaceInfo(iface);
    wifi_handle wifiHandle = getWifiHandle(iface);
    hal_info *info = getHalInfo(wifiHandle);

    /* Check Supported logger capability */
    if (!(info->supported_logger_feature_set &
          WIFI_LOGGER_MEMORY_DUMP_SUPPORTED)) {
        ALOGE("%s: Firmware memory dump logging feature not supported %x",
              __FUNCTION__, info->supported_logger_feature_set);
        return WIFI_ERROR_NOT_SUPPORTED;
    }

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

    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 != WIFI_SUCCESS)
        goto cleanup;

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

    if (ret != WIFI_SUCCESS)
        goto cleanup;

    /* Add the vendor specific attributes for the NL command. */
    nlData = wifiLoggerCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
    if (!nlData){
        ret = WIFI_ERROR_UNKNOWN;
        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 != WIFI_SUCCESS)
        goto cleanup;

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

cleanup:
    delete wifiLoggerCommand;
    return 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);

    pthread_mutex_lock(&info->lh_lock);
    info->on_ring_buffer_data = handler.on_ring_buffer_data;
    pthread_mutex_unlock(&info->lh_lock);
    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);

    pthread_mutex_lock(&info->lh_lock);
    info->on_ring_buffer_data = NULL;
    pthread_mutex_unlock(&info->lh_lock);
    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;
    }
    pthread_mutex_lock(&info->ah_lock);
    info->on_alert = handler.on_alert;
    pthread_mutex_unlock(&info->ah_lock);
    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);

    pthread_mutex_lock(&info->ah_lock);
    info->on_alert = NULL;
    pthread_mutex_unlock(&info->ah_lock);
    return WIFI_SUCCESS;
}


/**
    API to start packet fate monitoring.
    - Once stared, monitoring should remain active until HAL is unloaded.
    - When HAL is unloaded, all packet fate buffers should be cleared.
*/
wifi_error wifi_start_pkt_fate_monitoring(wifi_interface_handle iface)
{
    wifi_handle wifiHandle = getWifiHandle(iface);
    hal_info *info = getHalInfo(wifiHandle);

    /* Check Supported logger capability */
    if (!(info->supported_logger_feature_set &
          WIFI_LOGGER_PACKET_FATE_SUPPORTED)) {
        ALOGE("%s: packet fate logging feature not supported %x",
              __FUNCTION__, info->supported_logger_feature_set);
        return WIFI_ERROR_NOT_SUPPORTED;
    }

    if (info->fate_monitoring_enabled == true) {
        ALOGV("Packet monitoring is already enabled");
        return WIFI_SUCCESS;
    }

    info->pkt_fate_stats = (packet_fate_monitor_info *) malloc (
                                              sizeof(packet_fate_monitor_info));
    if (info->pkt_fate_stats == NULL) {
        ALOGE("Failed to allocate memory for : %zu bytes",
              sizeof(packet_fate_monitor_info));
        return WIFI_ERROR_OUT_OF_MEMORY;
    }
    memset(info->pkt_fate_stats, 0, sizeof(packet_fate_monitor_info));

    pthread_mutex_lock(&info->pkt_fate_stats_lock);
    info->fate_monitoring_enabled = true;
    pthread_mutex_unlock(&info->pkt_fate_stats_lock);

    return WIFI_SUCCESS;
}


/**
    API to retrieve fates of outbound packets.
    - HAL implementation should fill |tx_report_bufs| with fates of
      _first_ min(n_requested_fates, actual packets) frames
      transmitted for the most recent association. The fate reports
      should follow the same order as their respective packets.
    - Packets reported by firmware, but not recognized by driver
      should be included.  However, the ordering of the corresponding
      reports is at the discretion of HAL implementation.
    - Framework may call this API multiple times for the same association.
    - Framework will ensure |n_requested_fates <= MAX_FATE_LOG_LEN|.
    - Framework will allocate and free the referenced storage.
*/
wifi_error wifi_get_tx_pkt_fates(wifi_interface_handle iface,
                                 wifi_tx_report *tx_report_bufs,
                                 size_t n_requested_fates,
                                 size_t *n_provided_fates)
{
    wifi_handle wifiHandle = getWifiHandle(iface);
    hal_info *info = getHalInfo(wifiHandle);
    wifi_tx_report_i *tx_fate_stats;
    size_t i;

    if (info->fate_monitoring_enabled != true) {
        ALOGE("Packet monitoring is not yet triggered");
        return WIFI_ERROR_UNINITIALIZED;
    }
    pthread_mutex_lock(&info->pkt_fate_stats_lock);

    tx_fate_stats = &info->pkt_fate_stats->tx_fate_stats[0];

    *n_provided_fates = min(n_requested_fates,
                            info->pkt_fate_stats->n_tx_stats_collected);

    for (i=0; i < *n_provided_fates; i++) {
        memcpy(tx_report_bufs[i].md5_prefix,
                    tx_fate_stats[i].md5_prefix, MD5_PREFIX_LEN);
        tx_report_bufs[i].fate = tx_fate_stats[i].fate;
        tx_report_bufs[i].frame_inf.payload_type =
            tx_fate_stats[i].frame_inf.payload_type;
        tx_report_bufs[i].frame_inf.driver_timestamp_usec =
            tx_fate_stats[i].frame_inf.driver_timestamp_usec;
        tx_report_bufs[i].frame_inf.firmware_timestamp_usec =
            tx_fate_stats[i].frame_inf.firmware_timestamp_usec;
        tx_report_bufs[i].frame_inf.frame_len =
            tx_fate_stats[i].frame_inf.frame_len;

        if (tx_report_bufs[i].frame_inf.payload_type == FRAME_TYPE_ETHERNET_II)
            memcpy(tx_report_bufs[i].frame_inf.frame_content.ethernet_ii_bytes,
                   tx_fate_stats[i].frame_inf.frame_content,
                   min(tx_fate_stats[i].frame_inf.frame_len,
                       MAX_FRAME_LEN_ETHERNET));
        else if (tx_report_bufs[i].frame_inf.payload_type ==
                                                         FRAME_TYPE_80211_MGMT)
            memcpy(
                tx_report_bufs[i].frame_inf.frame_content.ieee_80211_mgmt_bytes,
                tx_fate_stats[i].frame_inf.frame_content,
                min(tx_fate_stats[i].frame_inf.frame_len,
                    MAX_FRAME_LEN_80211_MGMT));
        else
            /* Currently framework is interested only two types(
             * FRAME_TYPE_ETHERNET_II and FRAME_TYPE_80211_MGMT) of packets, so
             * ignore the all other types of packets received from driver */
            ALOGI("Unknown format packet");
    }
    pthread_mutex_unlock(&info->pkt_fate_stats_lock);

    return WIFI_SUCCESS;
}

/**
    API to retrieve fates of inbound packets.
    - HAL implementation should fill |rx_report_bufs| with fates of
      _first_ min(n_requested_fates, actual packets) frames
      received for the most recent association. The fate reports
      should follow the same order as their respective packets.
    - Packets reported by firmware, but not recognized by driver
      should be included.  However, the ordering of the corresponding
      reports is at the discretion of HAL implementation.
    - Framework may call this API multiple times for the same association.
    - Framework will ensure |n_requested_fates <= MAX_FATE_LOG_LEN|.
    - Framework will allocate and free the referenced storage.
*/
wifi_error wifi_get_rx_pkt_fates(wifi_interface_handle iface,
                                 wifi_rx_report *rx_report_bufs,
                                 size_t n_requested_fates,
                                 size_t *n_provided_fates)
{
    wifi_handle wifiHandle = getWifiHandle(iface);
    hal_info *info = getHalInfo(wifiHandle);
    wifi_rx_report_i *rx_fate_stats;
    size_t i;

    if (info->fate_monitoring_enabled != true) {
        ALOGE("Packet monitoring is not yet triggered");
        return WIFI_ERROR_UNINITIALIZED;
    }
    pthread_mutex_lock(&info->pkt_fate_stats_lock);

    rx_fate_stats = &info->pkt_fate_stats->rx_fate_stats[0];

    *n_provided_fates = min(n_requested_fates,
                            info->pkt_fate_stats->n_rx_stats_collected);

    for (i=0; i < *n_provided_fates; i++) {
        memcpy(rx_report_bufs[i].md5_prefix,
                    rx_fate_stats[i].md5_prefix, MD5_PREFIX_LEN);
        rx_report_bufs[i].fate = rx_fate_stats[i].fate;
        rx_report_bufs[i].frame_inf.payload_type =
            rx_fate_stats[i].frame_inf.payload_type;
        rx_report_bufs[i].frame_inf.driver_timestamp_usec =
            rx_fate_stats[i].frame_inf.driver_timestamp_usec;
        rx_report_bufs[i].frame_inf.firmware_timestamp_usec =
            rx_fate_stats[i].frame_inf.firmware_timestamp_usec;
        rx_report_bufs[i].frame_inf.frame_len =
            rx_fate_stats[i].frame_inf.frame_len;

        if (rx_report_bufs[i].frame_inf.payload_type == FRAME_TYPE_ETHERNET_II)
            memcpy(rx_report_bufs[i].frame_inf.frame_content.ethernet_ii_bytes,
                   rx_fate_stats[i].frame_inf.frame_content,
                   min(rx_fate_stats[i].frame_inf.frame_len,
                   MAX_FRAME_LEN_ETHERNET));
        else if (rx_report_bufs[i].frame_inf.payload_type ==
                                                         FRAME_TYPE_80211_MGMT)
            memcpy(
                rx_report_bufs[i].frame_inf.frame_content.ieee_80211_mgmt_bytes,
                rx_fate_stats[i].frame_inf.frame_content,
                min(rx_fate_stats[i].frame_inf.frame_len,
                    MAX_FRAME_LEN_80211_MGMT));
        else
            /* Currently framework is interested only two types(
             * FRAME_TYPE_ETHERNET_II and FRAME_TYPE_80211_MGMT) of packets, so
             * ignore the all other types of packets received from driver */
            ALOGI("Unknown format packet");
    }
    pthread_mutex_unlock(&info->pkt_fate_stats_lock);

    return WIFI_SUCCESS;
}

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

WifiLoggerCommand::~WifiLoggerCommand()
{
    unregisterVendorHandler(mVendor_id, mSubcmd);
}

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

    /* 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);
    if (ret != WIFI_SUCCESS)
        goto out;

     ALOGV("%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;

    /* Check Supported logger capability */
    if (!(info->supported_logger_feature_set & LOGGER_RING_BUFFER)) {
        ALOGE("%s: Ring buffer logging feature not supported %x", __FUNCTION__,
              info->supported_logger_feature_set);
        return WIFI_ERROR_NOT_SUPPORTED;
    }

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

    pthread_mutex_init(&info->lh_lock, NULL);
    pthread_mutex_init(&info->ah_lock, NULL);

    return ret;

cleanup:
    wifi_logger_ring_buffers_deinit(info);
    return ret;
}

void wifi_logger_ring_buffers_deinit(hal_info *info)
{
    int i;

    if (!(info->supported_logger_feature_set & LOGGER_RING_BUFFER))
        return;

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


/* 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;

    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;

  a = msg;
  *ret = 0;
  return NL_SKIP;
}

wifi_error WifiLoggerCommand::requestEvent()
{
    int status;
    wifi_error res = WIFI_SUCCESS;
    struct nl_cb *cb = NULL;

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

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

    status = 1;

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

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

    ALOGV("%s: Msg sent, status=%d, mWaitForRsp=%d", __FUNCTION__, status, mWaitforRsp);
    /* Only wait for the asynchronous event if HDD returns success, res=0 */
    if (!status && (mWaitforRsp == true)) {
        struct timespec abstime;
        abstime.tv_sec = 4;
        abstime.tv_nsec = 0;
        res = mCondition.wait(abstime);
        if (res == WIFI_ERROR_TIMED_OUT)
            ALOGE("%s: Time out happened.", __FUNCTION__);

        ALOGV("%s: Command invoked return value:%d, mWaitForRsp=%d",
            __FUNCTION__, res, mWaitforRsp);
    }
out:
    nl_cb_put(cb);
    /* Cleanup the mMsg */
    mMsg.destroy();
    return res;
}

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

int WifiLoggerCommand::handleResponse(WifiEvent &reply) {
    int len = 0, version;
    char version_type[20];
    char* memBuffer = NULL;
    FILE* memDumpFilePtr = NULL;
    WifiVendorCommand::handleResponse(reply);

    memset(version_type, 0, 20);
    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);
                ALOGV("%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_LOGGER_MAX + 1];

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

            if (tb_vendor[QCA_WLAN_VENDOR_ATTR_LOGGER_SUPPORTED]) {
                *mSupportedSet =
                nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LOGGER_SUPPORTED]);
#ifdef QC_HAL_DEBUG
                ALOGV("%s: Supported Feature Set : val 0x%x",
                      __FUNCTION__, *mSupportedSet);
#endif
            }
        }
        break;

        case QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP:
        {
            u32 memDumpSize = 0;
            int numRecordsRead = 0;
            u32 remaining = 0;
            char* buffer = NULL;
            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);

            if (!tbVendor[
                QCA_WLAN_VENDOR_ATTR_LOGGER_RESULTS_MEMDUMP_SIZE]) {
                ALOGE("%s: LOGGER_RESULTS_MEMDUMP_SIZE not"
                      "found", __FUNCTION__);
                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;
                        ALOGV("%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;
        case QCA_NL80211_VENDOR_SUBCMD_GET_WAKE_REASON_STATS:
        {
            struct nlattr *tbVendor[QCA_WLAN_VENDOR_GET_WAKE_STATS_MAX+1];

            /* parse and extract wake reason stats */
            nla_parse(tbVendor, QCA_WLAN_VENDOR_GET_WAKE_STATS_MAX,
                      (struct nlattr *)mVendorData,
                      mDataLen, NULL);

            mGetWakeStats->cmd_event_wake_cnt_used = 0;

            mGetWakeStats->driver_fw_local_wake_cnt_used = 0;

            if (!tbVendor[QCA_WLAN_VENDOR_ATTR_WAKE_STATS_TOTAL_RX_DATA_WAKE]) {
                ALOGE("%s: TOTAL_RX_DATA_WAKE not found", __FUNCTION__);
                break;
            }
            mGetWakeStats->total_rx_data_wake = nla_get_u32(tbVendor[
                        QCA_WLAN_VENDOR_ATTR_WAKE_STATS_TOTAL_RX_DATA_WAKE]);

            if (!tbVendor[QCA_WLAN_VENDOR_ATTR_WAKE_STATS_RX_UNICAST_CNT]) {
                ALOGE("%s: RX_UNICAST_CNT not found", __FUNCTION__);
                break;
            }
            mGetWakeStats->rx_wake_details.rx_unicast_cnt = nla_get_u32(
                    tbVendor[QCA_WLAN_VENDOR_ATTR_WAKE_STATS_RX_UNICAST_CNT]);

            if (!tbVendor[QCA_WLAN_VENDOR_ATTR_WAKE_STATS_RX_MULTICAST_CNT]) {
                ALOGE("%s: RX_MULTICAST_CNT not found", __FUNCTION__);
                break;
            }
            mGetWakeStats->rx_wake_details.rx_multicast_cnt = nla_get_u32(
                    tbVendor[QCA_WLAN_VENDOR_ATTR_WAKE_STATS_RX_MULTICAST_CNT]);

            if (!tbVendor[QCA_WLAN_VENDOR_ATTR_WAKE_STATS_RX_BROADCAST_CNT]) {
                ALOGE("%s: RX_BROADCAST_CNT not found", __FUNCTION__);
                break;
            }
            mGetWakeStats->rx_wake_details.rx_broadcast_cnt = nla_get_u32(
                    tbVendor[QCA_WLAN_VENDOR_ATTR_WAKE_STATS_RX_BROADCAST_CNT]);

            if (!tbVendor[QCA_WLAN_VENDOR_ATTR_WAKE_STATS_ICMP_PKT]) {
                ALOGE("%s: ICMP_PKT not found", __FUNCTION__);
                break;
            }
            mGetWakeStats->rx_wake_pkt_classification_info.icmp_pkt =
                nla_get_u32(tbVendor[QCA_WLAN_VENDOR_ATTR_WAKE_STATS_ICMP_PKT]);

            if (!tbVendor[QCA_WLAN_VENDOR_ATTR_WAKE_STATS_ICMP6_PKT]) {
                ALOGE("%s: ICMP6_PKT not found", __FUNCTION__);
                break;
            }
            mGetWakeStats->rx_wake_pkt_classification_info.icmp6_pkt =
                nla_get_u32(tbVendor[QCA_WLAN_VENDOR_ATTR_WAKE_STATS_ICMP6_PKT]);

            if (!tbVendor[QCA_WLAN_VENDOR_ATTR_WAKE_STATS_ICMP6_RA]) {
                ALOGE("%s: ICMP6_RA not found", __FUNCTION__);
                break;
            }
            mGetWakeStats->rx_wake_pkt_classification_info.icmp6_ra =
                nla_get_u32(tbVendor[QCA_WLAN_VENDOR_ATTR_WAKE_STATS_ICMP6_RA]);

            if (!tbVendor[QCA_WLAN_VENDOR_ATTR_WAKE_STATS_ICMP6_NA]) {
                ALOGE("%s: ICMP6_NA not found", __FUNCTION__);
                break;
            }
            mGetWakeStats->rx_wake_pkt_classification_info.icmp6_na =
                nla_get_u32(tbVendor[QCA_WLAN_VENDOR_ATTR_WAKE_STATS_ICMP6_NA]);

            if (!tbVendor[QCA_WLAN_VENDOR_ATTR_WAKE_STATS_ICMP6_NS]) {
                ALOGE("%s: ICMP6_NS not found", __FUNCTION__);
                break;
            }
            mGetWakeStats->rx_wake_pkt_classification_info.icmp6_ns =
                nla_get_u32(tbVendor[QCA_WLAN_VENDOR_ATTR_WAKE_STATS_ICMP6_NS]);

            if (!tbVendor[
                    QCA_WLAN_VENDOR_ATTR_WAKE_STATS_ICMP4_RX_MULTICAST_CNT]) {
                ALOGE("%s: ICMP4_RX_MULTICAST_CNT not found", __FUNCTION__);
                break;
            }
            mGetWakeStats->rx_multicast_wake_pkt_info.ipv4_rx_multicast_addr_cnt =
                nla_get_u32(tbVendor[
                    QCA_WLAN_VENDOR_ATTR_WAKE_STATS_ICMP4_RX_MULTICAST_CNT]);

            if (!tbVendor[
                    QCA_WLAN_VENDOR_ATTR_WAKE_STATS_ICMP6_RX_MULTICAST_CNT]) {
                ALOGE("%s: ICMP6_RX_MULTICAST_CNT not found", __FUNCTION__);
                break;
            }
            mGetWakeStats->rx_multicast_wake_pkt_info.ipv6_rx_multicast_addr_cnt =
                nla_get_u32(tbVendor[
                    QCA_WLAN_VENDOR_ATTR_WAKE_STATS_ICMP6_RX_MULTICAST_CNT]);

            if (!tbVendor[
                    QCA_WLAN_VENDOR_ATTR_WAKE_STATS_OTHER_RX_MULTICAST_CNT]) {
                ALOGE("%s: OTHER_RX_MULTICAST_CNT not found", __FUNCTION__);
                break;
            }
            mGetWakeStats->rx_multicast_wake_pkt_info.other_rx_multicast_addr_cnt =
                nla_get_u32(tbVendor[
                    QCA_WLAN_VENDOR_ATTR_WAKE_STATS_OTHER_RX_MULTICAST_CNT]);

        }
        break;

        default :
            ALOGE("%s: Wrong Wifi Logger subcmd response received %d",
                __FUNCTION__, mSubcmd);
    }

    /* free the allocated memory */
    if (memBuffer) {
        free(memBuffer);
    }
    if (memDumpFilePtr) {
        fclose(memDumpFilePtr);
    }
    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)
{
    WifiVendorCommand::handleEvent(event);

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

    return NL_SKIP;
}

wifi_error WifiLoggerCommand::setCallbackHandler(WifiLoggerCallbackHandler nHandler)
{
    wifi_error res;
    mHandler = nHandler;
    res = registerVendorHandler(mVendor_id, mSubcmd);
    if (res != WIFI_SUCCESS) {
        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);
}

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

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

/* Function to get Driver memory dump */
wifi_error wifi_get_driver_memory_dump(wifi_interface_handle iface,
                                    wifi_driver_memory_dump_callbacks callback)
{
    FILE *fp;
    size_t fileSize, remaining, readSize;
    size_t numRecordsRead;
    char *memBuffer = NULL, *buffer = NULL;
    wifi_handle wifiHandle = getWifiHandle(iface);
    hal_info *info = getHalInfo(wifiHandle);

    /* Check Supported logger capability */
    if (!(info->supported_logger_feature_set &
          WIFI_LOGGER_DRIVER_DUMP_SUPPORTED)) {
        ALOGE("%s: Driver memory dump logging feature not supported %x",
              __FUNCTION__, info->supported_logger_feature_set);
        return WIFI_ERROR_NOT_SUPPORTED;
    }
    /* Open File */
    fp = fopen(DRIVER_MEMDUMP_FILENAME, "r");
    if (fp == NULL) {
        ALOGE("Failed to open %s file", DRIVER_MEMDUMP_FILENAME);
        return WIFI_ERROR_UNKNOWN;
    }

    memBuffer = (char *) malloc(DRIVER_MEMDUMP_MAX_FILESIZE);
    if (memBuffer == NULL) {
        ALOGE("%s: malloc failed for size %d", __FUNCTION__,
                    DRIVER_MEMDUMP_MAX_FILESIZE);
        fclose(fp);
        return WIFI_ERROR_OUT_OF_MEMORY;
    }

    /* Read the DRIVER_MEMDUMP_MAX_FILESIZE value at once */
    numRecordsRead = fread(memBuffer, 1, DRIVER_MEMDUMP_MAX_FILESIZE, fp);
    if (feof(fp))
        fileSize = numRecordsRead;
    else if (numRecordsRead == DRIVER_MEMDUMP_MAX_FILESIZE) {
        ALOGE("%s: Reading only first %zu bytes from file", __FUNCTION__,
                numRecordsRead);
        fileSize = numRecordsRead;
    } else {
        ALOGE("%s: Read failed for reading at once, ret: %zu. Trying to read in"
                "chunks", __FUNCTION__, numRecordsRead);
        /* Lets try to read in chunks */
        rewind(fp);
        remaining = DRIVER_MEMDUMP_MAX_FILESIZE;
        buffer = memBuffer;
        fileSize = 0;
        while (remaining) {
            readSize = 0;
            if (remaining >= LOGGER_MEMDUMP_CHUNKSIZE)
                readSize = LOGGER_MEMDUMP_CHUNKSIZE;
            else
                readSize = remaining;

            numRecordsRead = fread(buffer, 1, readSize, fp);
            fileSize += numRecordsRead;
            if (feof(fp))
                break;
            else if (numRecordsRead == readSize) {
                remaining -= readSize;
                buffer += readSize;
                ALOGV("%s: Read successful for size:%zu remaining:%zu",
                         __FUNCTION__, readSize, remaining);
            } else {
                ALOGE("%s: Chunk read failed for size:%zu", __FUNCTION__,
                        readSize);
                free(memBuffer);
                memBuffer = NULL;
                fclose(fp);
                return WIFI_ERROR_UNKNOWN;
            }
        }
    }
    ALOGV("%s filename: %s fileSize: %zu", __FUNCTION__, DRIVER_MEMDUMP_FILENAME,
            fileSize);
    /* After successful read, call the callback function*/
    callback.on_driver_memory_dump(memBuffer, fileSize);

    /* free the allocated memory */
    free(memBuffer);
    fclose(fp);
    return WIFI_SUCCESS;
}

/* Function to get wake lock stats */
wifi_error wifi_get_wake_reason_stats(wifi_interface_handle iface,
                             WLAN_DRIVER_WAKE_REASON_CNT *wifi_wake_reason_cnt)
{
    int requestId;
    wifi_error ret;
    WifiLoggerCommand *wifiLoggerCommand;
    interface_info *ifaceInfo = getIfaceInfo(iface);
    wifi_handle wifiHandle = getWifiHandle(iface);
    hal_info *info = getHalInfo(wifiHandle);

    /* Check Supported logger capability */
    if (!(info->supported_logger_feature_set &
          WIFI_LOGGER_WAKE_LOCK_SUPPORTED)) {
        ALOGE("%s: Wake lock logging feature not supported %x",
              __FUNCTION__, info->supported_logger_feature_set);
        return WIFI_ERROR_NOT_SUPPORTED;
    }

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

    if (!wifi_wake_reason_cnt) {
        ALOGE("%s: Invalid buffer provided. Exit.",
            __FUNCTION__);
        return WIFI_ERROR_INVALID_ARGS;
    }

    wifiLoggerCommand = new WifiLoggerCommand(
                                wifiHandle,
                                requestId,
                                OUI_QCA,
                                QCA_NL80211_VENDOR_SUBCMD_GET_WAKE_REASON_STATS);
    if (wifiLoggerCommand == NULL) {
        ALOGE("%s: Error WifiLoggerCommand NULL", __FUNCTION__);
        return WIFI_ERROR_UNKNOWN;
    }

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

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

    wifiLoggerCommand->getWakeStatsRspParams(wifi_wake_reason_cnt);

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

cleanup:
    delete wifiLoggerCommand;
    return ret;
}

void WifiLoggerCommand::getWakeStatsRspParams(
                            WLAN_DRIVER_WAKE_REASON_CNT *wifi_wake_reason_cnt)
{
    mGetWakeStats = wifi_wake_reason_cnt;
}
