Home | History | Annotate | Download | only in wifi_hal
      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:
     38     GetLinkStatsCommand(wifi_interface_handle iface, wifi_stats_result_handler handler)
     39         : WifiCommand("GetLinkStatsCommand", iface, 0), mHandler(handler)
     40     { }
     41 
     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:
     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 	unsigned int num_chan = ((wifi_radio_stat *)data)->num_channels;
     72         if (num_chan > 11) {
     73            ALOGE("Incorrect number of channels = %d", num_chan);
     74            // dump data before num_channels
     75            ALOGE("radio: = %d", ((wifi_radio_stat *)data)->radio);
     76            ALOGE("on_time: = %d", ((wifi_radio_stat *)data)->on_time);
     77            ALOGE("tx_time: = %d", ((wifi_radio_stat *)data)->tx_time);
     78            ALOGE("rx_time: = %d", ((wifi_radio_stat *)data)->rx_time);
     79            ALOGE("on_time_scan: = %d", ((wifi_radio_stat *)data)->on_time_scan);
     80            ALOGE("on_time_nbd: = %d", ((wifi_radio_stat *)data)->on_time_nbd);
     81            ALOGE("on_time_gscan: = %d", ((wifi_radio_stat *)data)->on_time_gscan);
     82            ALOGE("on_time_pno_scan: = %d", ((wifi_radio_stat *)data)->on_time_pno_scan);
     83            ALOGE("on_time_hs20: = %d", ((wifi_radio_stat *)data)->on_time_hs20);
     84            return NL_SKIP;
     85         }
     86 	(*mHandler.on_link_stats_results)(id,
     87 		(wifi_iface_stat *)((char *)&((wifi_radio_stat *)data)->channels
     88 		+ num_chan*sizeof(wifi_channel_stat)),
     89 		1, (wifi_radio_stat *)data);
     90 
     91         return NL_OK;
     92     }
     93 };
     94 
     95 wifi_error wifi_get_link_stats(wifi_request_id id,
     96         wifi_interface_handle iface, wifi_stats_result_handler handler)
     97 {
     98     GetLinkStatsCommand command(iface, handler);
     99     return (wifi_error) command.requestResponse();
    100 }
    101 
    102