Home | History | Annotate | Download | only in wifi_hal
      1 /*
      2  * Copyright (C) 2017 The Android Open Source Project
      3  *
      4  * Portions copyright (C) 2017 Broadcom Limited
      5  *
      6  * Licensed under the Apache License, Version 2.0 (the "License");
      7  * you may not use this file except in compliance with the License.
      8  * You may obtain a copy of the License at
      9  *
     10  *     http://www.apache.org/licenses/LICENSE-2.0
     11  *
     12  * Unless required by applicable law or agreed to in writing, software
     13  * distributed under the License is distributed on an "AS IS" BASIS,
     14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     15  * See the License for the specific language governing permissions and
     16  * limitations under the License.
     17  */
     18 
     19 #include <stdint.h>
     20 #include <fcntl.h>
     21 #include <sys/socket.h>
     22 #include <netlink/genl/genl.h>
     23 #include <netlink/genl/family.h>
     24 #include <netlink/genl/ctrl.h>
     25 #include <linux/rtnetlink.h>
     26 #include <netpacket/packet.h>
     27 #include <linux/filter.h>
     28 #include <linux/errqueue.h>
     29 
     30 #include <linux/pkt_sched.h>
     31 #include <netlink/object-api.h>
     32 #include <netlink/netlink.h>
     33 #include <netlink/socket.h>
     34 #include <netlink/handlers.h>
     35 
     36 #include "sync.h"
     37 
     38 #define LOG_TAG  "WifiHAL"
     39 
     40 #include <log/log.h>
     41 
     42 #include "wifi_hal.h"
     43 #include "common.h"
     44 #include "cpp_bindings.h"
     45 
     46 enum {
     47     LSTATS_SUBCMD_GET_INFO = ANDROID_NL80211_SUBCMD_LSTATS_RANGE_START,
     48 };
     49 
     50 class GetLinkStatsCommand : public WifiCommand
     51 {
     52     wifi_stats_result_handler mHandler;
     53 public:
     54     GetLinkStatsCommand(wifi_interface_handle iface, wifi_stats_result_handler handler)
     55         : WifiCommand("GetLinkStatsCommand", iface, 0), mHandler(handler)
     56     { }
     57 
     58     virtual int create() {
     59         // ALOGI("Creating message to get link statistics; iface = %d", mIfaceInfo->id);
     60 
     61         int ret = mMsg.create(GOOGLE_OUI, LSTATS_SUBCMD_GET_INFO);
     62         if (ret < 0) {
     63             ALOGE("Failed to create %x - %d", LSTATS_SUBCMD_GET_INFO, ret);
     64             return ret;
     65         }
     66 
     67         return ret;
     68     }
     69 
     70 protected:
     71     virtual int handleResponse(WifiEvent& reply) {
     72 
     73         // ALOGI("In GetLinkStatsCommand::handleResponse");
     74 
     75         if (reply.get_cmd() != NL80211_CMD_VENDOR) {
     76             ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
     77             return NL_SKIP;
     78         }
     79 
     80         int id = reply.get_vendor_id();
     81         int subcmd = reply.get_vendor_subcmd();
     82 
     83         // ALOGI("Id = %0x, subcmd = %d", id, subcmd);
     84 
     85         void *data = reply.get_vendor_data();
     86         int len = reply.get_vendor_data_len();
     87         wifi_radio_stat *radio_stat = (wifi_radio_stat *)data;
     88         if (!radio_stat) {
     89             ALOGE("Invalid stats pointer received");
     90             return NL_SKIP;
     91         }
     92 	radio_stat->tx_time_per_levels = (u32*)((char*)data + sizeof(wifi_radio_stat) + sizeof(wifi_iface_stat));
     93         if (radio_stat->num_channels > 11) {
     94             ALOGE("Incorrect number of channels = %d", radio_stat->num_channels);
     95             // dump data before num_channels
     96             ALOGE("radio: = %d", radio_stat->radio);
     97             ALOGE("on_time: = %d", radio_stat->on_time);
     98             ALOGE("tx_time: = %d", radio_stat->tx_time);
     99             ALOGE("rx_time: = %d", radio_stat->rx_time);
    100             ALOGE("on_time_scan: = %d", radio_stat->on_time_scan);
    101             ALOGE("on_time_nbd: = %d", radio_stat->on_time_nbd);
    102             ALOGE("on_time_gscan: = %d", radio_stat->on_time_gscan);
    103             ALOGE("on_time_pno_scan: = %d", radio_stat->on_time_pno_scan);
    104             ALOGE("on_time_hs20: = %d", radio_stat->on_time_hs20);
    105             return NL_SKIP;
    106         }
    107         wifi_iface_stat *iface_stat = (wifi_iface_stat *)((char* )data + sizeof(wifi_radio_stat));
    108 
    109 	if(*mHandler.on_link_stats_results == NULL) {
    110 		ALOGE("*mHandler.on_link_stats_results is NULL");
    111 	} else {
    112         	(*mHandler.on_link_stats_results)(id, iface_stat, 1, radio_stat);
    113 	}
    114         return NL_OK;
    115     }
    116 
    117 };
    118 
    119 wifi_error wifi_get_link_stats(wifi_request_id id,
    120         wifi_interface_handle iface, wifi_stats_result_handler handler)
    121 {
    122     GetLinkStatsCommand command(iface, handler);
    123     return (wifi_error) command.requestResponse();
    124 }
    125 
    126 wifi_error wifi_set_link_stats(
    127         wifi_interface_handle /* iface */, wifi_link_layer_params /* params */)
    128 {
    129     /* Return success here since bcom HAL does not need set link stats. */
    130     return WIFI_SUCCESS;
    131 }
    132 
    133 wifi_error wifi_clear_link_stats(
    134         wifi_interface_handle /* iface */, u32 /* stats_clear_req_mask */,
    135         u32 * /* stats_clear_rsp_mask */, u8 /* stop_req */, u8 * /* stop_rsp */)
    136 {
    137     /* Return success here since bcom HAL does not support clear link stats. */
    138     return WIFI_SUCCESS;
    139 }
    140