diff options
author | Linux Build Service Account <lnxbuild@localhost> | 2018-02-17 01:17:10 -0700 |
---|---|---|
committer | Linux Build Service Account <lnxbuild@localhost> | 2018-02-17 01:17:10 -0700 |
commit | 3d79c2103caee2f6f08e9438d9abc2b4a898a01c (patch) | |
tree | 7dff0a3a8fc5dcb701e58ee5159ad03b357ad297 | |
parent | ac55dfc747f410c0a35b3973681474519dbef29b (diff) | |
parent | 450edb7d0eef06e206c924e1c003fa6466681430 (diff) | |
download | android_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.cpp | 11 | ||||
-rw-r--r-- | qcwcn/wifi_hal/cpp_bindings.h | 12 | ||||
-rw-r--r-- | qcwcn/wifi_hal/nud_stats.h | 37 | ||||
-rw-r--r-- | qcwcn/wifi_hal/qca-vendor_copy.h | 112 | ||||
-rw-r--r-- | qcwcn/wifi_hal/wifihal_vendor.cpp | 277 | ||||
-rw-r--r-- | qcwcn/wifi_hal/wifihal_vendorcommand.h | 14 |
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 |