Home | History | Annotate | Download | only in wifi_hal
      1 /*
      2  * Copyright (C) 2017 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "interface.h"
     18 
     19 #include "log.h"
     20 #include "netlink.h"
     21 #include "netlinkmessage.h"
     22 
     23 #include <linux/rtnetlink.h>
     24 
     25 // Provide some arbitrary firmware and driver versions for now
     26 static const char kFirmwareVersion[] = "1.0";
     27 static const char kDriverVersion[] = "1.0";
     28 
     29 // A list of supported channels in the 2.4 GHz band, values in MHz
     30 static const wifi_channel k2p4Channels[] = {
     31     2412,
     32     2417,
     33     2422,
     34     2427,
     35     2432,
     36     2437,
     37     2442,
     38     2447,
     39     2452,
     40     2457,
     41     2462,
     42     2467,
     43     2472,
     44     2484
     45 };
     46 
     47 template<typename T, size_t N>
     48 constexpr size_t arraySize(const T (&)[N]) {
     49     return N;
     50 }
     51 
     52 Interface::Interface(Netlink& netlink, const char* name)
     53     : mNetlink(netlink)
     54     , mName(name)
     55     , mInterfaceIndex(0) {
     56 }
     57 
     58 Interface::Interface(Interface&& other)
     59     : mNetlink(other.mNetlink)
     60     , mName(std::move(other.mName))
     61     , mInterfaceIndex(other.mInterfaceIndex) {
     62 }
     63 
     64 bool Interface::init() {
     65     mInterfaceIndex = if_nametoindex(mName.c_str());
     66     if (mInterfaceIndex == 0) {
     67         ALOGE("Unable to get interface index for %s", mName.c_str());
     68         return false;
     69     }
     70     return true;
     71 }
     72 
     73 wifi_error Interface::getSupportedFeatureSet(feature_set* set) {
     74     if (set == nullptr) {
     75         return WIFI_ERROR_INVALID_ARGS;
     76     }
     77     *set = WIFI_FEATURE_LINK_LAYER_STATS;
     78     return WIFI_SUCCESS;
     79 }
     80 
     81 wifi_error Interface::getName(char* name, size_t size) {
     82     if (size < mName.size() + 1) {
     83         return WIFI_ERROR_INVALID_ARGS;
     84     }
     85     strlcpy(name, mName.c_str(), size);
     86     return WIFI_SUCCESS;
     87 }
     88 
     89 wifi_error Interface::getLinkStats(wifi_request_id requestId,
     90                                    wifi_stats_result_handler handler) {
     91     NetlinkMessage message(RTM_GETLINK, mNetlink.getSequenceNumber());
     92 
     93     ifinfomsg* info = message.payload<ifinfomsg>();
     94     info->ifi_family = AF_UNSPEC;
     95     info->ifi_type = 1;
     96     info->ifi_index = mInterfaceIndex;
     97     info->ifi_flags = 0;
     98     info->ifi_change = 0xFFFFFFFF;
     99 
    100     bool success = mNetlink.sendMessage(message,
    101                                         std::bind(&Interface::onLinkStatsReply,
    102                                                   this,
    103                                                   requestId,
    104                                                   handler,
    105                                                   std::placeholders::_1));
    106     return success ? WIFI_SUCCESS : WIFI_ERROR_UNKNOWN;
    107 }
    108 
    109 wifi_error Interface::setLinkStats(wifi_link_layer_params /*params*/) {
    110     return WIFI_SUCCESS;
    111 }
    112 
    113 wifi_error Interface::setAlertHandler(wifi_request_id /*id*/,
    114                                          wifi_alert_handler /*handler*/) {
    115     return WIFI_SUCCESS;
    116 }
    117 
    118 wifi_error Interface::resetAlertHandler(wifi_request_id /*id*/) {
    119     return WIFI_SUCCESS;
    120 }
    121 
    122 wifi_error Interface::getFirmwareVersion(char* buffer, size_t size) {
    123     if (size < sizeof(kFirmwareVersion)) {
    124         return WIFI_ERROR_INVALID_ARGS;
    125     }
    126     strcpy(buffer, kFirmwareVersion);
    127     return WIFI_SUCCESS;
    128 }
    129 
    130 wifi_error Interface::getDriverVersion(char* buffer, size_t size) {
    131     if (size < sizeof(kDriverVersion)) {
    132         return WIFI_ERROR_INVALID_ARGS;
    133     }
    134     strcpy(buffer, kDriverVersion);
    135     return WIFI_SUCCESS;
    136 }
    137 
    138 wifi_error Interface::setScanningMacOui(oui /*scan_oui*/) {
    139     return WIFI_SUCCESS;
    140 }
    141 
    142 wifi_error Interface::clearLinkStats(u32 /*requestMask*/,
    143                                      u32* responseMask,
    144                                      u8 /*request*/,
    145                                      u8* response) {
    146     if (responseMask == nullptr || response == nullptr) {
    147         return WIFI_ERROR_INVALID_ARGS;
    148     }
    149     return WIFI_SUCCESS;
    150 }
    151 
    152 wifi_error Interface::getValidChannels(int band,
    153                                        int maxChannels,
    154                                        wifi_channel* channels,
    155                                        int* numChannels) {
    156     if (channels == nullptr || numChannels == nullptr || maxChannels < 0) {
    157         return WIFI_ERROR_INVALID_ARGS;
    158     }
    159     switch (band) {
    160         case WIFI_BAND_BG: // 2.4 GHz
    161             *numChannels = std::min<int>(maxChannels,
    162                                          arraySize(k2p4Channels));
    163             memcpy(channels, k2p4Channels, *numChannels);
    164 
    165             return WIFI_SUCCESS;
    166         default:
    167             return WIFI_ERROR_NOT_SUPPORTED;
    168     }
    169 }
    170 
    171 wifi_error Interface::startLogging(u32 /*verboseLevel*/,
    172                                    u32 /*flags*/,
    173                                    u32 /*maxIntervalSec*/,
    174                                    u32 /*minDataSize*/,
    175                                    char* /*ringName*/) {
    176     return WIFI_SUCCESS;
    177 }
    178 
    179 wifi_error Interface::setCountryCode(const char* /*countryCode*/) {
    180     return WIFI_SUCCESS;
    181 }
    182 
    183 wifi_error Interface::setLogHandler(wifi_request_id /*id*/,
    184                                     wifi_ring_buffer_data_handler /*handler*/) {
    185     return WIFI_SUCCESS;
    186 }
    187 
    188 wifi_error Interface::getRingBuffersStatus(u32* numRings,
    189                                            wifi_ring_buffer_status* status) {
    190     if (numRings == nullptr || status == nullptr || *numRings == 0) {
    191         return WIFI_ERROR_INVALID_ARGS;
    192     }
    193 
    194     memset(status, 0, sizeof(*status));
    195     strlcpy(reinterpret_cast<char*>(status->name),
    196             "ring0",
    197             sizeof(status->name));
    198     *numRings = 1;
    199     return WIFI_SUCCESS;
    200 }
    201 
    202 wifi_error Interface::getLoggerSupportedFeatureSet(unsigned int* support) {
    203     if (support == nullptr) {
    204         return WIFI_ERROR_INVALID_ARGS;
    205     }
    206     *support = 0;
    207     return WIFI_SUCCESS;
    208 }
    209 
    210 wifi_error Interface::getRingData(char* /*ringName*/) {
    211     return WIFI_SUCCESS;
    212 }
    213 
    214 wifi_error Interface::configureNdOffload(u8 /*enable*/) {
    215     return WIFI_SUCCESS;
    216 }
    217 
    218 wifi_error Interface::startPacketFateMonitoring() {
    219     return WIFI_SUCCESS;
    220 }
    221 
    222 wifi_error Interface::getTxPacketFates(wifi_tx_report* /*txReportBuffers*/,
    223                                        size_t /*numRequestedFates*/,
    224                                        size_t* numProvidedFates) {
    225     if (numProvidedFates == nullptr) {
    226         return WIFI_ERROR_INVALID_ARGS;
    227     }
    228     *numProvidedFates = 0;
    229     return WIFI_SUCCESS;
    230 }
    231 
    232 wifi_error Interface::getRxPacketFates(wifi_rx_report* /*rxReportBuffers*/,
    233                                        size_t /*numRequestedFates*/,
    234                                        size_t* numProvidedFates) {
    235     if (numProvidedFates == nullptr) {
    236         return WIFI_ERROR_INVALID_ARGS;
    237     }
    238     *numProvidedFates = 0;
    239     return WIFI_SUCCESS;
    240 }
    241 
    242 wifi_error Interface::getPacketFilterCapabilities(u32* version,
    243                                                   u32* maxLength) {
    244     if (version == nullptr || maxLength == nullptr) {
    245         return WIFI_ERROR_INVALID_ARGS;
    246     }
    247     *version = 0;
    248     *maxLength = 0;
    249     return WIFI_SUCCESS;
    250 }
    251 
    252 wifi_error
    253 Interface::getWakeReasonStats(WLAN_DRIVER_WAKE_REASON_CNT* wakeReasonCount) {
    254     if (wakeReasonCount == nullptr) {
    255         return WIFI_ERROR_INVALID_ARGS;
    256     }
    257     return WIFI_SUCCESS;
    258 }
    259 
    260 void Interface::onLinkStatsReply(wifi_request_id requestId,
    261                                  wifi_stats_result_handler handler,
    262                                  const NetlinkMessage& message) {
    263     if (message.size() < sizeof(nlmsghdr) + sizeof(ifinfomsg)) {
    264         ALOGE("Invalid link stats response, too small");
    265         return;
    266     }
    267     if (message.type() != RTM_NEWLINK) {
    268         ALOGE("Recieved invalid link stats reply type: %u",
    269               static_cast<unsigned int>(message.type()));
    270         return;
    271     }
    272 
    273     int numRadios = 1;
    274     wifi_radio_stat radioStats;
    275     memset(&radioStats, 0, sizeof(radioStats));
    276 
    277     wifi_iface_stat ifStats;
    278     memset(&ifStats, 0, sizeof(ifStats));
    279     ifStats.iface = reinterpret_cast<wifi_interface_handle>(this);
    280 
    281     rtnl_link_stats64 netlinkStats64;
    282     rtnl_link_stats netlinkStats;
    283     if (message.getAttribute(IFLA_STATS64, &netlinkStats64)) {
    284         ifStats.ac[WIFI_AC_BE].tx_mpdu = netlinkStats64.tx_packets;
    285         ifStats.ac[WIFI_AC_BE].rx_mpdu = netlinkStats64.rx_packets;
    286     } else if (message.getAttribute(IFLA_STATS, &netlinkStats)) {
    287         ifStats.ac[WIFI_AC_BE].tx_mpdu = netlinkStats.tx_packets;
    288         ifStats.ac[WIFI_AC_BE].rx_mpdu = netlinkStats.rx_packets;
    289     } else {
    290         return;
    291     }
    292 
    293     handler.on_link_stats_results(requestId, &ifStats, numRadios, &radioStats);
    294 }
    295