1
2 #include <stdint.h>
3 #include <fcntl.h>
4 #include <sys/socket.h>
5 #include <netlink/genl/genl.h>
6 #include <netlink/genl/family.h>
7 #include <netlink/genl/ctrl.h>
8 #include <linux/rtnetlink.h>
9 #include <netpacket/packet.h>
10 #include <linux/filter.h>
11 #include <linux/errqueue.h>
12
13 #include <linux/pkt_sched.h>
14 #include <netlink/object-api.h>
15 #include <netlink/netlink.h>
16 #include <netlink/socket.h>
17 #include <netlink/handlers.h>
18
19 #include "sync.h"
20
21 #define LOG_TAG "WifiHAL"
22
23 #include <utils/Log.h>
24
25 #include "wifi_hal.h"
26 #include "common.h"
27 #include "cpp_bindings.h"
28
29
30 enum {
31 LSTATS_SUBCMD_GET_INFO = ANDROID_NL80211_SUBCMD_LSTATS_RANGE_START,
32 };
33
34 class GetLinkStatsCommand : public WifiCommand
35 {
36 wifi_stats_result_handler mHandler;
37 public:
GetLinkStatsCommand(wifi_interface_handle iface,wifi_stats_result_handler handler)38 GetLinkStatsCommand(wifi_interface_handle iface, wifi_stats_result_handler handler)
39 : WifiCommand(iface, 0), mHandler(handler)
40 { }
41
create()42 virtual int create() {
43 // ALOGI("Creating message to get link statistics; iface = %d", mIfaceInfo->id);
44
45 int ret = mMsg.create(GOOGLE_OUI, LSTATS_SUBCMD_GET_INFO);
46 if (ret < 0) {
47 ALOGE("Failed to create %x - %d", LSTATS_SUBCMD_GET_INFO, ret);
48 return ret;
49 }
50
51 return ret;
52 }
53
54 protected:
handleResponse(WifiEvent & reply)55 virtual int handleResponse(WifiEvent& reply) {
56
57 // ALOGI("In GetLinkStatsCommand::handleResponse");
58
59 if (reply.get_cmd() != NL80211_CMD_VENDOR) {
60 ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
61 return NL_SKIP;
62 }
63
64 int id = reply.get_vendor_id();
65 int subcmd = reply.get_vendor_subcmd();
66
67 // ALOGI("Id = %0x, subcmd = %d", id, subcmd);
68
69 void *data = reply.get_vendor_data();
70 int len = reply.get_vendor_data_len();
71 int num_chan = ((wifi_radio_stat *)data)->num_channels;
72 if (num_chan > 32) {
73 ALOGE("Incorrect number of channels = %d", num_chan);
74 return NL_SKIP;
75 }
76 (*mHandler.on_link_stats_results)(id,
77 (wifi_iface_stat *)((char *)&((wifi_radio_stat *)data)->channels
78 + num_chan*sizeof(wifi_channel_stat)),
79 1, (wifi_radio_stat *)data);
80
81 return NL_OK;
82 }
83 };
84
wifi_get_link_stats(wifi_request_id id,wifi_interface_handle iface,wifi_stats_result_handler handler)85 wifi_error wifi_get_link_stats(wifi_request_id id,
86 wifi_interface_handle iface, wifi_stats_result_handler handler)
87 {
88 GetLinkStatsCommand command(iface, handler);
89 return (wifi_error) command.requestResponse();
90 }
91
92