summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2018-02-17 01:17:10 -0700
committerLinux Build Service Account <lnxbuild@localhost>2018-02-17 01:17:10 -0700
commit3d79c2103caee2f6f08e9438d9abc2b4a898a01c (patch)
tree7dff0a3a8fc5dcb701e58ee5159ad03b357ad297
parentac55dfc747f410c0a35b3973681474519dbef29b (diff)
parent450edb7d0eef06e206c924e1c003fa6466681430 (diff)
downloadandroid_hardware_qcom_wlan-3d79c2103caee2f6f08e9438d9abc2b4a898a01c.tar.gz
android_hardware_qcom_wlan-3d79c2103caee2f6f08e9438d9abc2b4a898a01c.tar.bz2
android_hardware_qcom_wlan-3d79c2103caee2f6f08e9438d9abc2b4a898a01c.zip
Merge 450edb7d0eef06e206c924e1c003fa6466681430 on remote branch
Change-Id: Icb32d77daa07f409bdf5221dbae3e61147610ee1
-rw-r--r--qcwcn/wifi_hal/cpp_bindings.cpp11
-rw-r--r--qcwcn/wifi_hal/cpp_bindings.h12
-rw-r--r--qcwcn/wifi_hal/nud_stats.h37
-rw-r--r--qcwcn/wifi_hal/qca-vendor_copy.h112
-rw-r--r--qcwcn/wifi_hal/wifihal_vendor.cpp277
-rw-r--r--qcwcn/wifi_hal/wifihal_vendorcommand.h14
6 files changed, 441 insertions, 22 deletions
diff --git a/qcwcn/wifi_hal/cpp_bindings.cpp b/qcwcn/wifi_hal/cpp_bindings.cpp
index cbb865a..199cd3c 100644
--- a/qcwcn/wifi_hal/cpp_bindings.cpp
+++ b/qcwcn/wifi_hal/cpp_bindings.cpp
@@ -1,4 +1,10 @@
/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * Not a Contribution
+ */
+
+/*
* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -924,6 +930,11 @@ s64 WifiVendorCommand::get_s64(const struct nlattr *nla)
return mMsg.get_s64(nla);
}
+wifi_error WifiVendorCommand::put_ipv6_addr(int attribute, uint8_t value[16])
+{
+ return mMsg.put_ipv6_addr(attribute, value);
+}
+
wifi_error WifiVendorCommand::put_string(int attribute, const char *value)
{
return mMsg.put_string(attribute, value);
diff --git a/qcwcn/wifi_hal/cpp_bindings.h b/qcwcn/wifi_hal/cpp_bindings.h
index 42705c3..b2f7c7b 100644
--- a/qcwcn/wifi_hal/cpp_bindings.h
+++ b/qcwcn/wifi_hal/cpp_bindings.h
@@ -1,4 +1,10 @@
/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * Not a Contribution
+ */
+
+/*
* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -275,6 +281,10 @@ public:
return *(s64 *) nla_data(nla);
}
+ wifi_error put_ipv6_addr(int attribute, uint8_t *value) {
+ return wifi_nla_put(mMsg, attribute, 16, value);
+ }
+
wifi_error put_string(int attribute, const char *value) {
return wifi_nla_put(mMsg, attribute, strlen(value) + 1, value);
}
@@ -459,6 +469,8 @@ public:
virtual s32 get_s32(const struct nlattr *nla);
virtual s64 get_s64(const struct nlattr *nla);
+ virtual wifi_error put_ipv6_addr(int attribute, uint8_t value[16]);
+
virtual wifi_error put_string(int attribute, const char *value);
virtual wifi_error put_addr(int attribute, mac_addr value);
diff --git a/qcwcn/wifi_hal/nud_stats.h b/qcwcn/wifi_hal/nud_stats.h
index d6f7ecd..c1db343 100644
--- a/qcwcn/wifi_hal/nud_stats.h
+++ b/qcwcn/wifi_hal/nud_stats.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-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
@@ -44,6 +44,7 @@
#include <netlink/netlink.h>
#include <netlink/socket.h>
#include "wifi_hal.h"
+#include <arpa/inet.h>
typedef struct {
uint16_t arp_req_count_from_netdev;
@@ -58,8 +59,36 @@ typedef struct {
uint8_t is_duplicate_addr_detection;
} nud_stats;
+typedef struct {
+ uint16_t pkt_req_count_from_netdev;
+ uint16_t pkt_req_count_to_lower_mac;
+ uint16_t pkt_req_rx_count_by_lower_mac;
+ uint16_t pkt_req_count_tx_success;
+ uint16_t pkt_rsp_rx_count_by_lower_mac;
+ uint16_t pkt_rsp_rx_count_by_upper_mac;
+ uint16_t pkt_rsp_count_to_netdev;
+ uint16_t pkt_rsp_count_out_of_order_drop;
+} pkt_stats;
+
+typedef struct{
+ u32 pkt_Type;
+ char* domain_name;
+ u32 src_port;
+ u32 dst_port;
+ struct in_addr ipv4_addr;
+ u8 ipv6_addr[16];
+ pkt_stats stats;
+} cmdData;
+
+/* callback for get NUD stats */
+typedef struct {
+ void (*on_pkt_stats_results) (nud_stats *stats,
+ int mnumStats, cmdData *pkt_stats);
+} pkt_stats_result_handler;
-wifi_error wifi_set_nud_stats(wifi_interface_handle iface, u32 gw_addr);
+wifi_error wifi_set_nud_stats(wifi_interface_handle iface, u32 gw_addr,
+ cmdData set_data);
wifi_error wifi_get_nud_stats(wifi_interface_handle iface,
- nud_stats *stats);
-wifi_error wifi_clear_nud_stats(wifi_interface_handle iface);
+ pkt_stats_result_handler handler);
+wifi_error wifi_clear_nud_stats(wifi_interface_handle iface,
+ cmdData set_data);
diff --git a/qcwcn/wifi_hal/qca-vendor_copy.h b/qcwcn/wifi_hal/qca-vendor_copy.h
index 0a7a086..ae51393 100644
--- a/qcwcn/wifi_hal/qca-vendor_copy.h
+++ b/qcwcn/wifi_hal/qca-vendor_copy.h
@@ -1,4 +1,8 @@
/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ */
+
+/*
* Qualcomm Atheros OUI and vendor specific assignments
* Copyright (c) 2014-2015, Qualcomm Atheros, Inc.
*
@@ -2924,6 +2928,56 @@ enum qca_wlan_vendor_attr_pno_config_params {
};
/**
+ * qca_wlan_vendor_nud_stats_data_pkt_flags: Flag representing the various
+ * data types for which the stats have to get collected.
+ */
+enum qca_wlan_vendor_nud_stats_data_pkt_flags {
+ QCA_WLAN_VENDOR_NUD_STATS_DATA_ARP = 1 << 0,
+ QCA_WLAN_VENDOR_NUD_STATS_DATA_DNS = 1 << 1,
+ QCA_WLAN_VENDOR_NUD_STATS_DATA_TCP_HANDSHAKE = 1 << 2,
+ QCA_WLAN_VENDOR_NUD_STATS_DATA_ICMPV4 = 1 << 3,
+ QCA_WLAN_VENDOR_NUD_STATS_DATA_ICMPV6 = 1 << 4,
+ /* Used by QCA_ATTR_NUD_STATS_PKT_TYPE only in nud stats get
+ * to represent the stats of respective data type.
+ */
+ QCA_WLAN_VENDOR_NUD_STATS_DATA_TCP_SYN = 1 << 5,
+ QCA_WLAN_VENDOR_NUD_STATS_DATA_TCP_SYN_ACK = 1 << 6,
+ QCA_WLAN_VENDOR_NUD_STATS_DATA_TCP_ACK = 1 << 7,
+};
+
+enum qca_wlan_vendor_nud_stats_set_data_pkt_info {
+ QCA_ATTR_NUD_STATS_DATA_PKT_INFO_INVALID = 0,
+ /* Represents the data packet type to be monitored.
+ * Host driver tracks the stats corresponding to each data frame
+ * represented by these flags.
+ * These data packets are represented by
+ * enum qca_wlan_vendor_nud_stats_data_pkt_flags
+ */
+ QCA_ATTR_NUD_STATS_DATA_PKT_INFO_TYPE = 1,
+ /* Name corresponding to the DNS frame for which the respective DNS stats
+ * have to get monitored (sring).
+ */
+ QCA_ATTR_NUD_STATS_DATA_PKT_INFO_DNS_DOMAIN_NAME = 2,
+ /* source / destination port on which the respective proto stats have
+ * to get collected (u32).
+ */
+ QCA_ATTR_NUD_STATS_DATA_PKT_INFO_SRC_PORT = 3,
+ QCA_ATTR_NUD_STATS_DATA_PKT_INFO_DEST_PORT = 4,
+ /* IPv4 address for which the destined data packets have to be
+ * monitored. (in network byte order), u32.
+ */
+ QCA_ATTR_NUD_STATS_DATA_PKT_INFO_DEST_IPV4 = 5,
+ /* IPv4 address for which the destined data packets have to be
+ * monitored. (in network byte order), 16 bytes array.
+ */
+ QCA_ATTR_NUD_STATS_DATA_PKT_INFO_DEST_IPV6 = 6,
+
+ QCA_ATTR_NUD_STATS_DATA_PKT_INFO_LAST,
+ QCA_ATTR_NUD_STATS_DATA_PKT_INFO_MAX =
+ QCA_ATTR_NUD_STATS_DATA_PKT_INFO_LAST - 1,
+};
+
+/**
* qca_wlan_vendor_attr_nud_stats_set: attribute to vendor subcmd
* QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_SET. This carry the requisite
* information to start / stop the NUD stats collection.
@@ -2938,12 +2992,65 @@ enum qca_attr_nud_stats_set {
/* IPv4 address of Default Gateway (in network byte order) */
QCA_ATTR_NUD_STATS_GW_IPV4 = 2,
+ /* Represents the list of data packet types to be monitored.
+ * Host driver tracks the stats corresponding to each data frame
+ * represented by these flags.
+ * These data packets are represented by
+ * enum qca_wlan_vendor_nud_stats_set_data_pkt_info
+ */
+ QCA_ATTR_NUD_STATS_SET_DATA_PKT_INFO = 3,
/* keep last */
QCA_ATTR_NUD_STATS_SET_LAST,
QCA_ATTR_NUD_STATS_SET_MAX =
QCA_ATTR_NUD_STATS_SET_LAST - 1,
};
+enum qca_attr_nud_data_stats {
+ QCA_ATTR_NUD_DATA_STATS_INVALID = 0,
+ /* Data packet type for which the stats are collected.
+ * Represented by enum qca_wlan_vendor_nud_stats_data_pkt_flags
+ */
+ QCA_ATTR_NUD_STATS_PKT_TYPE = 1,
+ /* Name corresponding to the DNS frame for which the respective DNS stats
+ * are monitored (string).
+ */
+ QCA_ATTR_NUD_STATS_PKT_DNS_DOMAIN_NAME = 2,
+ /* source / destination port on which the respective proto stats are
+ * collected (u32).
+ */
+ QCA_ATTR_NUD_STATS_PKT_SRC_PORT = 3,
+ QCA_ATTR_NUD_STATS_PKT_DEST_PORT = 4,
+ /* IPv4 address for which the destined data packets have to be
+ * monitored. (in network byte order), u32.
+ */
+ QCA_ATTR_NUD_STATS_PKT_DEST_IPV4 = 5,
+ /* IPv6 address for which the destined data packets have to be
+ * monitored. (in network byte order), 16 bytes array.
+ */
+ QCA_ATTR_NUD_STATS_PKT_DEST_IPV6 = 6,
+ /* Data packet Request count received from netdev */
+ QCA_ATTR_NUD_STATS_PKT_REQ_COUNT_FROM_NETDEV = 7,
+ /* Data packet Request count sent to lower MAC from upper MAC */
+ QCA_ATTR_NUD_STATS_PKT_REQ_COUNT_TO_LOWER_MAC = 8,
+ /* Data packet Request count received by lower MAC from upper MAC */
+ QCA_ATTR_NUD_STATS_PKT_REQ_RX_COUNT_BY_LOWER_MAC = 9,
+ /* Data packet Request count successfully transmitted by the device */
+ QCA_ATTR_NUD_STATS_PKT_REQ_COUNT_TX_SUCCESS = 10,
+ /* Data packet Response count received by lower MAC */
+ QCA_ATTR_NUD_STATS_PKT_RSP_RX_COUNT_BY_LOWER_MAC = 11,
+ /* Data packet Response count received by upper MAC */
+ QCA_ATTR_NUD_STATS_PKT_RSP_RX_COUNT_BY_UPPER_MAC = 12,
+ /* Data packet Response count delivered to netdev */
+ QCA_ATTR_NUD_STATS_PKT_RSP_COUNT_TO_NETDEV = 13,
+ /* Data Packet Response count that are dropped out of order */
+ QCA_ATTR_NUD_STATS_PKT_RSP_COUNT_OUT_OF_ORDER_DROP = 14,
+
+ /* keep last */
+ QCA_ATTR_NUD_DATA_STATS_LAST,
+ QCA_ATTR_NUD_DATA_STATS_MAX =
+ QCA_ATTR_NUD_DATA_STATS_LAST - 1,
+};
+
/**
* qca_attr_nud_stats_get: attribute to vendor subcmd
* QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET. This carry the requisite
@@ -2976,6 +3083,11 @@ enum qca_attr_nud_stats_get {
*/
QCA_ATTR_NUD_STATS_IS_DAD = 10,
+ /* List of Data types for which the stats are requested.
+ * This list does not carry ARP stats as they are done by the
+ * above attributes. Represented by enum qca_attr_nud_data_stats.
+ */
+ QCA_ATTR_NUD_STATS_DATA_PKT_STATS = 11,
/* keep last */
QCA_ATTR_NUD_STATS_GET_LAST,
QCA_ATTR_NUD_STATS_GET_MAX =
diff --git a/qcwcn/wifi_hal/wifihal_vendor.cpp b/qcwcn/wifi_hal/wifihal_vendor.cpp
index 33842f2..52860d4 100644
--- a/qcwcn/wifi_hal/wifihal_vendor.cpp
+++ b/qcwcn/wifi_hal/wifihal_vendor.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-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
@@ -39,6 +39,7 @@
#include "wifihal_vendorcommand.h"
#include "vendor_definitions.h"
+#define MAX_INFO 1
//Singleton Static Instance
NUDStatsCommand* NUDStatsCommand::mNUDStatsCommandInstance = NULL;
@@ -67,6 +68,8 @@ NUDStatsCommand::NUDStatsCommand(wifi_handle handle, int id, u32 vendor_id, u32
: WifiVendorCommand(handle, id, vendor_id, subcmd)
{
memset(&mStats, 0,sizeof(nud_stats));
+ mpktInfo = NULL;
+ mnumStats = 0;
}
NUDStatsCommand::~NUDStatsCommand()
@@ -104,14 +107,32 @@ void NUDStatsCommand::setSubCmd(u32 subcmd)
mSubcmd = subcmd;
}
+void NUDStatsCommand::setHandler(pkt_stats_result_handler handler)
+{
+ mHandler = handler;
+}
+
wifi_error NUDStatsCommand::requestResponse()
{
return WifiCommand::requestResponse(mMsg);
}
+wifi_error NUDStatsCommand::notifyResponse()
+{
+ wifi_error ret = WIFI_SUCCESS;
+
+ if (mHandler.on_pkt_stats_results) {
+ mHandler.on_pkt_stats_results(&mStats, mnumStats,
+ mpktInfo);
+ } else {
+ ret = WIFI_ERROR_INVALID_ARGS;
+ }
+ return ret;
+}
+
int NUDStatsCommand::handleResponse(WifiEvent &reply)
{
- int status = WIFI_ERROR_NONE;
+ wifi_error status = WIFI_ERROR_NONE;
WifiVendorCommand::handleResponse(reply);
// Parse the vendordata and get the attribute
@@ -229,27 +250,172 @@ int NUDStatsCommand::handleResponse(WifiEvent &reply)
stats->arp_rsp_count_out_of_order_drop,
stats->ap_link_active,
stats->is_duplicate_addr_detection);
+
+ if (tb_vendor[QCA_ATTR_NUD_STATS_DATA_PKT_STATS]) {
+ mNUDStatsCommandInstance->GetPktInfo(tb_vendor);
+ }
}
}
cleanup:
if (status == WIFI_ERROR_INVALID_ARGS)
memset(&mStats,0,sizeof(nud_stats));
+ if(mpktInfo != NULL)
+ free(mpktInfo);
return status;
}
-void NUDStatsCommand::copyStats(nud_stats *stats)
+void NUDStatsCommand::GetPktInfo(struct nlattr **tbvendor)
+{
+ struct nlattr *tb;
+ int rem;
+ cmdData *pkt_stats;
+ char ipv6_address[INET6_ADDRSTRLEN];
+ cmdData pktstats;
+ int nbuff = 0;
+
+ for (tb = (struct nlattr *) nla_data(tbvendor[QCA_ATTR_NUD_STATS_DATA_PKT_STATS]),
+ rem = nla_len(tbvendor[QCA_ATTR_NUD_STATS_DATA_PKT_STATS]);
+ nla_ok(tb, rem); tb = nla_next(tb, &(rem)))
+ {
+ struct nlattr *tb2[QCA_ATTR_NUD_DATA_STATS_MAX + 1];
+ nla_parse(tb2, QCA_ATTR_NUD_DATA_STATS_MAX,
+ (struct nlattr *) nla_data(tb), nla_len(tb), NULL);
+
+ memset(&pktstats, 0, sizeof(cmdData));
+
+ if (tb2[QCA_ATTR_NUD_STATS_PKT_TYPE])
+ {
+ pktstats.pkt_Type = nla_get_u32(tb2[QCA_ATTR_NUD_STATS_PKT_TYPE]);
+ }
+
+ if (tb2[QCA_ATTR_NUD_STATS_PKT_DNS_DOMAIN_NAME])
+ {
+ pktstats.domain_name = nla_get_string(tb2[QCA_ATTR_NUD_STATS_PKT_DNS_DOMAIN_NAME]);
+ }
+
+ if (tb2[QCA_ATTR_NUD_STATS_PKT_SRC_PORT])
+ {
+ pktstats.src_port = nla_get_u32(tb2[QCA_ATTR_NUD_STATS_PKT_SRC_PORT]);
+ }
+
+ if (tb2[QCA_ATTR_NUD_STATS_PKT_DEST_PORT])
+ {
+ pktstats.dst_port = nla_get_u32(tb2[QCA_ATTR_NUD_STATS_PKT_DEST_PORT]);
+ }
+
+ if (tb2[QCA_ATTR_NUD_STATS_PKT_DEST_IPV4])
+ {
+ pktstats.ipv4_addr.s_addr = nla_get_u32(tb2[QCA_ATTR_NUD_STATS_PKT_DEST_IPV4]);
+ }
+
+ if (tb2[QCA_ATTR_NUD_STATS_PKT_DEST_IPV6])
+ {
+ memcpy(pktstats.ipv6_addr, nla_data(tb2[QCA_ATTR_NUD_STATS_PKT_DEST_IPV6]),
+ sizeof(pktstats.ipv6_addr));
+ }
+
+ if (tb2[QCA_ATTR_NUD_STATS_PKT_REQ_COUNT_FROM_NETDEV])
+ {
+ pktstats.stats.pkt_req_count_from_netdev = nla_get_u16(tb2[
+ QCA_ATTR_NUD_STATS_PKT_REQ_COUNT_FROM_NETDEV]);
+ }
+
+ if (tb2[QCA_ATTR_NUD_STATS_PKT_REQ_COUNT_TO_LOWER_MAC])
+ {
+ pktstats.stats.pkt_req_count_to_lower_mac = nla_get_u16(tb2[
+ QCA_ATTR_NUD_STATS_PKT_REQ_COUNT_TO_LOWER_MAC]);
+ }
+
+ if (tb2[QCA_ATTR_NUD_STATS_PKT_REQ_RX_COUNT_BY_LOWER_MAC])
+ {
+ pktstats.stats.pkt_req_rx_count_by_lower_mac = nla_get_u16(tb2[
+ QCA_ATTR_NUD_STATS_PKT_REQ_RX_COUNT_BY_LOWER_MAC]);
+ }
+
+ if (tb2[QCA_ATTR_NUD_STATS_PKT_REQ_COUNT_TX_SUCCESS])
+ {
+ pktstats.stats.pkt_req_count_tx_success = nla_get_u16(tb2[
+ QCA_ATTR_NUD_STATS_PKT_REQ_COUNT_TX_SUCCESS]);
+ }
+
+ if (tb2[QCA_ATTR_NUD_STATS_PKT_RSP_RX_COUNT_BY_LOWER_MAC])
+ {
+ pktstats.stats.pkt_rsp_rx_count_by_lower_mac = nla_get_u16(tb2[
+ QCA_ATTR_NUD_STATS_PKT_RSP_RX_COUNT_BY_LOWER_MAC]);
+ }
+
+ if (tb2[QCA_ATTR_NUD_STATS_PKT_RSP_RX_COUNT_BY_UPPER_MAC])
+ {
+ pktstats.stats.pkt_rsp_rx_count_by_upper_mac = nla_get_u16(tb2[
+ QCA_ATTR_NUD_STATS_PKT_RSP_RX_COUNT_BY_UPPER_MAC]);
+ }
+
+ if (tb2[QCA_ATTR_NUD_STATS_PKT_RSP_COUNT_TO_NETDEV])
+ {
+ pktstats.stats.pkt_rsp_count_to_netdev = nla_get_u16(tb2[
+ QCA_ATTR_NUD_STATS_PKT_RSP_COUNT_TO_NETDEV]);
+ }
+
+ if (tb2[QCA_ATTR_NUD_STATS_PKT_RSP_COUNT_OUT_OF_ORDER_DROP])
+ {
+ pktstats.stats.pkt_rsp_count_out_of_order_drop = nla_get_u16(tb2[
+ QCA_ATTR_NUD_STATS_PKT_RSP_COUNT_OUT_OF_ORDER_DROP]);
+ }
+
+ if (inet_ntop(AF_INET6, pktstats.ipv6_addr, ipv6_address,
+ INET6_ADDRSTRLEN) == NULL) {
+ ALOGE("%s: failed to convert ipv6 address format", __FUNCTION__);
+ }
+
+ ALOGV(" pkt_type %d domain_name :%s"
+ " src_port %d dst_port :%d"
+ " ipv4_address :%x ipv6_address %s"
+ " req_from_netdev %d count_to_lower :%d"
+ " count_by_lower :%d"
+ " count_tx_succ :%d rsp_count_lower :%d"
+ " rsp_count_upper :%d rsp_count_netdev :%d"
+ " out_of_order_drop :%d ",
+ pktstats.pkt_Type, pktstats.domain_name,
+ pktstats.src_port, pktstats.dst_port,
+ pktstats.ipv4_addr.s_addr, ipv6_address,
+ pktstats.stats.pkt_req_count_from_netdev,
+ pktstats.stats.pkt_req_count_to_lower_mac,
+ pktstats.stats.pkt_req_rx_count_by_lower_mac,
+ pktstats.stats.pkt_req_count_tx_success,
+ pktstats.stats.pkt_rsp_rx_count_by_lower_mac,
+ pktstats.stats.pkt_rsp_rx_count_by_upper_mac,
+ pktstats.stats.pkt_rsp_count_to_netdev,
+ pktstats.stats.pkt_rsp_count_out_of_order_drop);
+
+ if (nbuff == 0)
+ pkt_stats = (cmdData *)malloc(sizeof(cmdData));
+ else
+ pkt_stats = (cmdData *)realloc(pkt_stats,sizeof(cmdData) * (nbuff + 1));
+
+ mpktInfo = pkt_stats;
+ memcpy(&pkt_stats[nbuff], &pktstats,sizeof(cmdData));
+ nbuff++;
+ mnumStats = nbuff;
+ }
+}
+
+void NUDStatsCommand::copyStats(nud_stats *stats, cmdData *pktstats)
{
memcpy(stats, &mStats, sizeof(nud_stats));
+ pktstats = mpktInfo;
}
-wifi_error wifi_set_nud_stats(wifi_interface_handle iface, u32 gw_addr)
+wifi_error wifi_set_nud_stats(wifi_interface_handle iface,
+ u32 gw_addr, cmdData Data)
{
wifi_error ret;
NUDStatsCommand *NUDCommand;
- struct nlattr *nl_data;
+ struct nlattr *nl_data,*nl_pktInfo;
interface_info *iinfo = getIfaceInfo(iface);
wifi_handle handle = getWifiHandle(iface);
+ cmdData mData = Data;
+ cmdData pktstats = Data;
ALOGV("gw_addr : %x", gw_addr);
NUDCommand = NUDStatsCommand::instance(handle);
@@ -278,7 +444,60 @@ wifi_error wifi_set_nud_stats(wifi_interface_handle iface, u32 gw_addr)
ret = NUDCommand->put_u32(QCA_ATTR_NUD_STATS_GW_IPV4, gw_addr);
if (ret != WIFI_SUCCESS)
goto cleanup;
- /**/
+ /*start the packet info attributes in nested*/
+ nl_pktInfo = NUDCommand->attr_start(QCA_ATTR_NUD_STATS_SET_DATA_PKT_INFO);
+ if (!nl_pktInfo)
+ goto cleanup;
+ else {
+ ALOGV(" pkt_type %d domain_name :%s"
+ " src_port %d dst_port :%d"
+ " ipv4_address :%x ipv6_address %s",
+ pktstats.pkt_Type, pktstats.domain_name,
+ pktstats.src_port, pktstats.dst_port,
+ pktstats.ipv4_addr.s_addr,pktstats.ipv6_addr);
+
+ for (int i=0; i < MAX_INFO ; i++) {
+ /*add the packet type attributes*/
+ struct nlattr *tb_tmp;
+ tb_tmp = NUDCommand->attr_start(i);
+
+ ret = NUDCommand->put_u32(QCA_ATTR_NUD_STATS_DATA_PKT_INFO_TYPE,mData.pkt_Type);
+ if (ret != WIFI_SUCCESS)
+ goto cleanup;
+
+ /*add the domain name attributes*/
+ ret = NUDCommand->put_string(QCA_ATTR_NUD_STATS_DATA_PKT_INFO_DNS_DOMAIN_NAME,
+ mData.domain_name);
+ if (ret != WIFI_SUCCESS)
+ goto cleanup;
+
+ /*add the source port attributes*/
+ ret = NUDCommand->put_u32(QCA_ATTR_NUD_STATS_DATA_PKT_INFO_SRC_PORT,
+ mData.src_port);
+ if (ret != WIFI_SUCCESS)
+ goto cleanup;
+
+ /*add the dest port attributes*/
+ ret = NUDCommand->put_u32(QCA_ATTR_NUD_STATS_DATA_PKT_INFO_DEST_PORT,
+ mData.dst_port);
+ if (ret != WIFI_SUCCESS)
+ goto cleanup;
+
+ /*add the ipv4 address attributes*/
+ ret = NUDCommand->put_u32(QCA_ATTR_NUD_STATS_DATA_PKT_INFO_DEST_IPV4,
+ mData.ipv4_addr.s_addr);
+ if (ret != WIFI_SUCCESS)
+ goto cleanup;
+
+ /*add the ipv6 address attributes*/
+ ret = NUDCommand->put_ipv6_addr(QCA_ATTR_NUD_STATS_DATA_PKT_INFO_DEST_IPV6,
+ mData.ipv6_addr);
+ if (ret != WIFI_SUCCESS)
+ goto cleanup;
+ NUDCommand->attr_end(tb_tmp);
+ }
+ }
+ NUDCommand->attr_end(nl_pktInfo);
NUDCommand->attr_end(nl_data);
ret = NUDCommand->requestResponse();
@@ -292,7 +511,7 @@ cleanup:
wifi_error wifi_get_nud_stats(wifi_interface_handle iface,
- nud_stats *stats)
+ pkt_stats_result_handler handler)
{
wifi_error ret;
NUDStatsCommand *NUDCommand;
@@ -300,11 +519,6 @@ wifi_error wifi_get_nud_stats(wifi_interface_handle iface,
interface_info *iinfo = getIfaceInfo(iface);
wifi_handle handle = getWifiHandle(iface);
- if (stats == NULL) {
- ALOGE("%s: Error stats is NULL", __FUNCTION__);
- return WIFI_ERROR_INVALID_ARGS;
- }
-
NUDCommand = NUDStatsCommand::instance(handle);
if (NUDCommand == NULL) {
ALOGE("%s: Error NUDStatsCommand NULL", __FUNCTION__);
@@ -312,6 +526,8 @@ wifi_error wifi_get_nud_stats(wifi_interface_handle iface,
}
NUDCommand->setSubCmd(QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET);
+ NUDCommand->setHandler(handler);
+
/* create the message */
ret = NUDCommand->create();
if (ret != WIFI_SUCCESS)
@@ -333,20 +549,26 @@ wifi_error wifi_get_nud_stats(wifi_interface_handle iface,
goto cleanup;
}
- NUDCommand->copyStats(stats);
+ ret = NUDCommand->notifyResponse();
+ if (ret != WIFI_SUCCESS) {
+ ALOGE("%s: requestResponse Error:%d",__FUNCTION__, ret);
+ goto cleanup;
+ }
cleanup:
return ret;
}
-wifi_error wifi_clear_nud_stats(wifi_interface_handle iface)
+wifi_error wifi_clear_nud_stats(wifi_interface_handle iface,
+ cmdData Data)
{
wifi_error ret;
NUDStatsCommand *NUDCommand;
- struct nlattr *nl_data;
+ struct nlattr *nl_data,*nl_pktInfo;
interface_info *iinfo = getIfaceInfo(iface);
wifi_handle handle = getWifiHandle(iface);
+ cmdData mData = Data;
NUDCommand = NUDStatsCommand::instance(handle);
if (NUDCommand == NULL) {
@@ -368,6 +590,31 @@ wifi_error wifi_clear_nud_stats(wifi_interface_handle iface)
nl_data = NUDCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
if (!nl_data)
goto cleanup;
+ /*set the packet info attributes in nested*/
+ nl_pktInfo = NUDCommand->attr_start(QCA_ATTR_NUD_STATS_SET_DATA_PKT_INFO);
+ if (!nl_pktInfo)
+ goto cleanup;
+ else {
+ ALOGV(" %s: pkt_type %d domain_name :%s"
+ " src_port %d dst_port :%d"
+ " ipv4_address :%x ipv6_address %s",
+ __FUNCTION__,mData.pkt_Type, mData.domain_name,
+ mData.src_port, mData.dst_port,
+ mData.ipv4_addr.s_addr,mData.ipv6_addr);
+
+ for (int i=0; i < MAX_INFO ; i++) {
+ /*add the packet type attributes*/
+ struct nlattr *tb_tmp;
+ tb_tmp = NUDCommand->attr_start(i);
+
+ ret = NUDCommand->put_u32(QCA_ATTR_NUD_STATS_DATA_PKT_INFO_TYPE,mData.pkt_Type);
+ if (ret != WIFI_SUCCESS)
+ goto cleanup;
+
+ NUDCommand->attr_end(tb_tmp);
+ }
+ }
+ NUDCommand->attr_end(nl_pktInfo);
NUDCommand->attr_end(nl_data);
diff --git a/qcwcn/wifi_hal/wifihal_vendorcommand.h b/qcwcn/wifi_hal/wifihal_vendorcommand.h
index 2a73902..123fe1e 100644
--- a/qcwcn/wifi_hal/wifihal_vendorcommand.h
+++ b/qcwcn/wifi_hal/wifihal_vendorcommand.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-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
@@ -42,8 +42,10 @@ class NUDStatsCommand: public WifiVendorCommand
private:
static NUDStatsCommand *mNUDStatsCommandInstance;
+ pkt_stats_result_handler mHandler;
nud_stats mStats;
-
+ cmdData *mpktInfo;
+ int mnumStats;
NUDStatsCommand(wifi_handle handle, int id, u32 vendor_id, u32 subcmd);
public:
@@ -59,9 +61,15 @@ public:
virtual wifi_error requestResponse();
+ virtual wifi_error notifyResponse();
+
virtual int handleResponse(WifiEvent &reply);
- void copyStats(nud_stats *stats);
+ virtual void setHandler(pkt_stats_result_handler handler);
+
+ void copyStats(nud_stats *stats, cmdData *pktdstats);
+
+ void GetPktInfo(struct nlattr **tbvendor);
};
#ifdef __cplusplus