diff options
Diffstat (limited to 'MediaTek/wifi/link_layer_stats.cpp')
| -rw-r--r-- | MediaTek/wifi/link_layer_stats.cpp | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/MediaTek/wifi/link_layer_stats.cpp b/MediaTek/wifi/link_layer_stats.cpp new file mode 100644 index 0000000..ad20d92 --- /dev/null +++ b/MediaTek/wifi/link_layer_stats.cpp @@ -0,0 +1,98 @@ + +#include <stdint.h> +#include <fcntl.h> +#include <sys/socket.h> +#include <netlink/genl/genl.h> +#include <netlink/genl/family.h> +#include <netlink/genl/ctrl.h> +#include <linux/rtnetlink.h> +#include <netpacket/packet.h> +#include <linux/filter.h> +#include <linux/errqueue.h> + +#include <linux/pkt_sched.h> +#include <netlink/object-api.h> +#include <netlink/netlink.h> +#include <netlink/socket.h> +#include <netlink/handlers.h> + +#include "sync.h" + +#define LOG_TAG "WifiHAL" + +#include <utils/Log.h> + +#include "wifi_hal.h" +#include "common.h" +#include "cpp_bindings.h" + + +enum { + NL80211_ATTR_VENDOR_LLSTAT = 2, + LSTATS_SUBCMD_GET_INFO = ANDROID_NL80211_SUBCMD_LSTATS_RANGE_START, +}; + +class GetLinkStatsCommand : public WifiCommand +{ + wifi_stats_result_handler mHandler; +public: + GetLinkStatsCommand(wifi_interface_handle iface, wifi_stats_result_handler handler) + : WifiCommand(iface, 0), mHandler(handler) + { } + + virtual int create() { + //ALOGD("[WIFI HAL]Creating message to get link statistics; iface = %d", mIfaceInfo->id); + + int ret = mMsg.create(GOOGLE_OUI, LSTATS_SUBCMD_GET_INFO); + if (ret < 0) { + ALOGE("Failed to create %x - %d", LSTATS_SUBCMD_GET_INFO, ret); + return ret; + } + + return ret; + } + +protected: + virtual int handleResponse(WifiEvent& reply) { + //ALOGD("[WIFI HAL]In GetLinkStatsCommand::handleResponse"); + + if (reply.get_cmd() != NL80211_CMD_VENDOR) { + ALOGE("Ignoring reply with cmd = %d", reply.get_cmd()); + return NL_SKIP; + } + + int id = reply.get_vendor_id(); + int subcmd = reply.get_vendor_subcmd(); + + // ALOGI("Id = %0x, subcmd = %d", id, subcmd); + + struct nlattr *vendor_data = (struct nlattr *)reply.get_vendor_data(); + int len = reply.get_vendor_data_len(); + wifi_radio_stat *data; + + if(vendor_data->nla_type == NL80211_ATTR_VENDOR_LLSTAT) + data = (wifi_radio_stat *)nla_data(vendor_data); + int num_chan = data->num_channels; + if (num_chan > 32) { + ALOGE("Incorrect number of channels = %d", num_chan); + return NL_SKIP; + } + +/* + (*mHandler.on_link_stats_results)(id, + (wifi_iface_stat *)((char *)&(data)->channels + + num_chan*sizeof(wifi_channel_stat)), + 1, data); +*/ + + return NL_OK; + } +}; + +wifi_error wifi_get_link_stats(wifi_request_id id, + wifi_interface_handle iface, wifi_stats_result_handler handler) +{ + GetLinkStatsCommand command(iface, handler); + return (wifi_error) command.requestResponse(); +} + |
