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) noexcept 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 = 0; 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