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>
arraySize(const T (&)[N])48 constexpr size_t arraySize(const T (&)[N]) {
49 return N;
50 }
51
Interface(Netlink & netlink,const char * name)52 Interface::Interface(Netlink& netlink, const char* name)
53 : mNetlink(netlink)
54 , mName(name)
55 , mInterfaceIndex(0) {
56 }
57
Interface(Interface && other)58 Interface::Interface(Interface&& other) noexcept
59 : mNetlink(other.mNetlink)
60 , mName(std::move(other.mName))
61 , mInterfaceIndex(other.mInterfaceIndex) {
62 }
63
init()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
getSupportedFeatureSet(feature_set * set)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
getName(char * name,size_t size)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
getLinkStats(wifi_request_id requestId,wifi_stats_result_handler handler)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
setLinkStats(wifi_link_layer_params)109 wifi_error Interface::setLinkStats(wifi_link_layer_params /*params*/) {
110 return WIFI_SUCCESS;
111 }
112
setAlertHandler(wifi_request_id,wifi_alert_handler)113 wifi_error Interface::setAlertHandler(wifi_request_id /*id*/,
114 wifi_alert_handler /*handler*/) {
115 return WIFI_SUCCESS;
116 }
117
resetAlertHandler(wifi_request_id)118 wifi_error Interface::resetAlertHandler(wifi_request_id /*id*/) {
119 return WIFI_SUCCESS;
120 }
121
getFirmwareVersion(char * buffer,size_t size)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
getDriverVersion(char * buffer,size_t size)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
setScanningMacOui(oui)138 wifi_error Interface::setScanningMacOui(oui /*scan_oui*/) {
139 return WIFI_SUCCESS;
140 }
141
clearLinkStats(u32,u32 * responseMask,u8,u8 * response)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
getValidChannels(int band,int maxChannels,wifi_channel * channels,int * numChannels)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
startLogging(u32,u32,u32,u32,char *)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
setCountryCode(const char *)179 wifi_error Interface::setCountryCode(const char* /*countryCode*/) {
180 return WIFI_SUCCESS;
181 }
182
setLogHandler(wifi_request_id,wifi_ring_buffer_data_handler)183 wifi_error Interface::setLogHandler(wifi_request_id /*id*/,
184 wifi_ring_buffer_data_handler /*handler*/) {
185 return WIFI_SUCCESS;
186 }
187
getRingBuffersStatus(u32 * numRings,wifi_ring_buffer_status * status)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
getLoggerSupportedFeatureSet(unsigned int * support)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
getRingData(char *)210 wifi_error Interface::getRingData(char* /*ringName*/) {
211 return WIFI_SUCCESS;
212 }
213
configureNdOffload(u8)214 wifi_error Interface::configureNdOffload(u8 /*enable*/) {
215 return WIFI_SUCCESS;
216 }
217
startPacketFateMonitoring()218 wifi_error Interface::startPacketFateMonitoring() {
219 return WIFI_SUCCESS;
220 }
221
getTxPacketFates(wifi_tx_report *,size_t,size_t * numProvidedFates)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
getRxPacketFates(wifi_rx_report *,size_t,size_t * numProvidedFates)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
getPacketFilterCapabilities(u32 * version,u32 * maxLength)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
getWakeReasonStats(WLAN_DRIVER_WAKE_REASON_CNT * wakeReasonCount)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
onLinkStatsReply(wifi_request_id requestId,wifi_stats_result_handler handler,const NetlinkMessage & message)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