• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include <future>
26 
27 // Provide some arbitrary firmware and driver versions for now
28 static const char kFirmwareVersion[] = "1.0";
29 static const char kDriverVersion[] = "1.0";
30 
31 // A list of supported channels in the 2.4 GHz band, values in MHz
32 static const wifi_channel k2p4Channels[] = {
33     2412,
34     2417,
35     2422,
36     2427,
37     2432,
38     2437,
39     2442,
40     2447,
41     2452,
42     2457,
43     2462,
44     2467,
45     2472,
46     2484
47 };
48 
49 template<typename T, size_t N>
arraySize(const T (&)[N])50 constexpr size_t arraySize(const T (&)[N]) {
51     return N;
52 }
53 
Interface(Netlink & netlink,const char * name)54 Interface::Interface(Netlink& netlink, const char* name)
55     : mNetlink(netlink)
56     , mName(name)
57     , mInterfaceIndex(0) {
58 }
59 
Interface(Interface && other)60 Interface::Interface(Interface&& other) noexcept
61     : mNetlink(other.mNetlink)
62     , mName(std::move(other.mName))
63     , mInterfaceIndex(other.mInterfaceIndex) {
64 }
65 
init()66 bool Interface::init() {
67     mInterfaceIndex = if_nametoindex(mName.c_str());
68     if (mInterfaceIndex == 0) {
69         ALOGE("Unable to get interface index for %s", mName.c_str());
70         return false;
71     }
72     return true;
73 }
74 
getSupportedFeatureSet(feature_set * set)75 wifi_error Interface::getSupportedFeatureSet(feature_set* set) {
76     if (set == nullptr) {
77         return WIFI_ERROR_INVALID_ARGS;
78     }
79     *set = 0;
80     return WIFI_SUCCESS;
81 }
82 
getName(char * name,size_t size)83 wifi_error Interface::getName(char* name, size_t size) {
84     if (size < mName.size() + 1) {
85         return WIFI_ERROR_INVALID_ARGS;
86     }
87     strlcpy(name, mName.c_str(), size);
88     return WIFI_SUCCESS;
89 }
90 
91 // Wifi legacy HAL implicitly assumes getLinkStats is blocking and
92 // handler will be set to nullptr immediately after invocation.
93 // Therefore, this function will wait until onLinkStatsReply is called.
getLinkStats(wifi_request_id requestId,wifi_stats_result_handler handler)94 wifi_error Interface::getLinkStats(wifi_request_id requestId,
95                                    wifi_stats_result_handler handler) {
96     NetlinkMessage message(RTM_GETLINK, mNetlink.getSequenceNumber());
97 
98     ifinfomsg* info = message.payload<ifinfomsg>();
99     info->ifi_family = AF_UNSPEC;
100     info->ifi_type = 1;
101     info->ifi_index = mInterfaceIndex;
102     info->ifi_flags = 0;
103     info->ifi_change = 0xFFFFFFFF;
104 
105     std::promise<void> p;
106 
107     auto callback = [this, requestId, &handler,
108         &p] (const NetlinkMessage& message) {
109         onLinkStatsReply(requestId, handler, message);
110         p.set_value();
111     };
112 
113     bool success = mNetlink.sendMessage(message, callback);
114     // Only wait when callback will be invoked. Therefore, test if the message
115     // is sent successfully first.
116     if (success) {
117         p.get_future().wait();
118     }
119     return success ? WIFI_SUCCESS : WIFI_ERROR_UNKNOWN;
120 }
121 
setLinkStats(wifi_link_layer_params)122 wifi_error Interface::setLinkStats(wifi_link_layer_params /*params*/) {
123     return WIFI_SUCCESS;
124 }
125 
setAlertHandler(wifi_request_id,wifi_alert_handler)126 wifi_error Interface::setAlertHandler(wifi_request_id /*id*/,
127                                          wifi_alert_handler /*handler*/) {
128     return WIFI_SUCCESS;
129 }
130 
resetAlertHandler(wifi_request_id)131 wifi_error Interface::resetAlertHandler(wifi_request_id /*id*/) {
132     return WIFI_SUCCESS;
133 }
134 
getFirmwareVersion(char * buffer,size_t size)135 wifi_error Interface::getFirmwareVersion(char* buffer, size_t size) {
136     if (size < sizeof(kFirmwareVersion)) {
137         return WIFI_ERROR_INVALID_ARGS;
138     }
139     strcpy(buffer, kFirmwareVersion);
140     return WIFI_SUCCESS;
141 }
142 
getDriverVersion(char * buffer,size_t size)143 wifi_error Interface::getDriverVersion(char* buffer, size_t size) {
144     if (size < sizeof(kDriverVersion)) {
145         return WIFI_ERROR_INVALID_ARGS;
146     }
147     strcpy(buffer, kDriverVersion);
148     return WIFI_SUCCESS;
149 }
150 
setScanningMacOui(oui)151 wifi_error Interface::setScanningMacOui(oui /*scan_oui*/) {
152     return WIFI_SUCCESS;
153 }
154 
clearLinkStats(u32,u32 * responseMask,u8,u8 * response)155 wifi_error Interface::clearLinkStats(u32 /*requestMask*/,
156                                      u32* responseMask,
157                                      u8 /*request*/,
158                                      u8* response) {
159     if (responseMask == nullptr || response == nullptr) {
160         return WIFI_ERROR_INVALID_ARGS;
161     }
162     return WIFI_SUCCESS;
163 }
164 
getValidChannels(int band,int maxChannels,wifi_channel * channels,int * numChannels)165 wifi_error Interface::getValidChannels(int band,
166                                        int maxChannels,
167                                        wifi_channel* channels,
168                                        int* numChannels) {
169     if (channels == nullptr || numChannels == nullptr || maxChannels < 0) {
170         return WIFI_ERROR_INVALID_ARGS;
171     }
172     switch (band) {
173         case WIFI_BAND_BG: // 2.4 GHz
174             *numChannels = std::min<int>(maxChannels,
175                                          arraySize(k2p4Channels));
176             memcpy(channels, k2p4Channels, *numChannels);
177 
178             return WIFI_SUCCESS;
179         default:
180             return WIFI_ERROR_NOT_SUPPORTED;
181     }
182 }
183 
startLogging(u32,u32,u32,u32,char *)184 wifi_error Interface::startLogging(u32 /*verboseLevel*/,
185                                    u32 /*flags*/,
186                                    u32 /*maxIntervalSec*/,
187                                    u32 /*minDataSize*/,
188                                    char* /*ringName*/) {
189     return WIFI_SUCCESS;
190 }
191 
setCountryCode(const char *)192 wifi_error Interface::setCountryCode(const char* /*countryCode*/) {
193     return WIFI_SUCCESS;
194 }
195 
setLogHandler(wifi_request_id,wifi_ring_buffer_data_handler)196 wifi_error Interface::setLogHandler(wifi_request_id /*id*/,
197                                     wifi_ring_buffer_data_handler /*handler*/) {
198     return WIFI_SUCCESS;
199 }
200 
getRingBuffersStatus(u32 * numRings,wifi_ring_buffer_status * status)201 wifi_error Interface::getRingBuffersStatus(u32* numRings,
202                                            wifi_ring_buffer_status* status) {
203     if (numRings == nullptr || status == nullptr || *numRings == 0) {
204         return WIFI_ERROR_INVALID_ARGS;
205     }
206 
207     memset(status, 0, sizeof(*status));
208     strlcpy(reinterpret_cast<char*>(status->name),
209             "ring0",
210             sizeof(status->name));
211     *numRings = 1;
212     return WIFI_SUCCESS;
213 }
214 
getLoggerSupportedFeatureSet(unsigned int * support)215 wifi_error Interface::getLoggerSupportedFeatureSet(unsigned int* support) {
216     if (support == nullptr) {
217         return WIFI_ERROR_INVALID_ARGS;
218     }
219     *support = 0;
220     return WIFI_SUCCESS;
221 }
222 
getRingData(char *)223 wifi_error Interface::getRingData(char* /*ringName*/) {
224     return WIFI_SUCCESS;
225 }
226 
configureNdOffload(u8)227 wifi_error Interface::configureNdOffload(u8 /*enable*/) {
228     return WIFI_SUCCESS;
229 }
230 
startPacketFateMonitoring()231 wifi_error Interface::startPacketFateMonitoring() {
232     return WIFI_SUCCESS;
233 }
234 
getTxPacketFates(wifi_tx_report *,size_t,size_t * numProvidedFates)235 wifi_error Interface::getTxPacketFates(wifi_tx_report* /*txReportBuffers*/,
236                                        size_t /*numRequestedFates*/,
237                                        size_t* numProvidedFates) {
238     if (numProvidedFates == nullptr) {
239         return WIFI_ERROR_INVALID_ARGS;
240     }
241     *numProvidedFates = 0;
242     return WIFI_SUCCESS;
243 }
244 
getRxPacketFates(wifi_rx_report *,size_t,size_t * numProvidedFates)245 wifi_error Interface::getRxPacketFates(wifi_rx_report* /*rxReportBuffers*/,
246                                        size_t /*numRequestedFates*/,
247                                        size_t* numProvidedFates) {
248     if (numProvidedFates == nullptr) {
249         return WIFI_ERROR_INVALID_ARGS;
250     }
251     *numProvidedFates = 0;
252     return WIFI_SUCCESS;
253 }
254 
getPacketFilterCapabilities(u32 * version,u32 * maxLength)255 wifi_error Interface::getPacketFilterCapabilities(u32* version,
256                                                   u32* maxLength) {
257     if (version == nullptr || maxLength == nullptr) {
258         return WIFI_ERROR_INVALID_ARGS;
259     }
260     *version = 0;
261     *maxLength = 0;
262     return WIFI_SUCCESS;
263 }
264 
265 wifi_error
getWakeReasonStats(WLAN_DRIVER_WAKE_REASON_CNT * wakeReasonCount)266 Interface::getWakeReasonStats(WLAN_DRIVER_WAKE_REASON_CNT* wakeReasonCount) {
267     if (wakeReasonCount == nullptr) {
268         return WIFI_ERROR_INVALID_ARGS;
269     }
270     return WIFI_SUCCESS;
271 }
272 
startSendingOffloadedPacket(wifi_request_id,u16,u8 *,u16,u8 *,u8 *,u32)273 wifi_error Interface::startSendingOffloadedPacket(wifi_request_id /*id*/,
274                                                   u16 /*ether_type*/,
275                                                   u8 * /*ip_packet*/,
276                                                   u16 /*ip_packet_len*/,
277                                                   u8 * /*src_mac_addr*/,
278                                                   u8 * /*dst_mac_addr*/,
279                                                   u32 /*period_msec*/) {
280     // Drop the packet and pretend everything is fine. Currentlty this is only
281     // used for keepalive packets to allow the CPU to go to sleep and let the
282     // hardware send keepalive packets on its own. By dropping this we lose the
283     // keepalive packets but networking will still be fine.
284     return WIFI_SUCCESS;
285 }
286 
stopSendingOffloadedPacket(wifi_request_id)287 wifi_error Interface::stopSendingOffloadedPacket(wifi_request_id /*id*/) {
288     return WIFI_SUCCESS;
289 }
290 
onLinkStatsReply(wifi_request_id requestId,wifi_stats_result_handler handler,const NetlinkMessage & message)291 void Interface::onLinkStatsReply(wifi_request_id requestId,
292                                  wifi_stats_result_handler handler,
293                                  const NetlinkMessage& message) {
294     if (message.size() < sizeof(nlmsghdr) + sizeof(ifinfomsg)) {
295         ALOGE("Invalid link stats response, too small");
296         return;
297     }
298     if (message.type() != RTM_NEWLINK) {
299         ALOGE("Recieved invalid link stats reply type: %u",
300               static_cast<unsigned int>(message.type()));
301         return;
302     }
303 
304     int numRadios = 1;
305     wifi_radio_stat radioStats;
306     memset(&radioStats, 0, sizeof(radioStats));
307 
308     wifi_iface_stat ifStats;
309     memset(&ifStats, 0, sizeof(ifStats));
310     ifStats.iface = reinterpret_cast<wifi_interface_handle>(this);
311 
312     rtnl_link_stats64 netlinkStats64;
313     rtnl_link_stats netlinkStats;
314     if (message.getAttribute(IFLA_STATS64, &netlinkStats64)) {
315         ifStats.ac[WIFI_AC_BE].tx_mpdu = netlinkStats64.tx_packets;
316         ifStats.ac[WIFI_AC_BE].rx_mpdu = netlinkStats64.rx_packets;
317     } else if (message.getAttribute(IFLA_STATS, &netlinkStats)) {
318         ifStats.ac[WIFI_AC_BE].tx_mpdu = netlinkStats.tx_packets;
319         ifStats.ac[WIFI_AC_BE].rx_mpdu = netlinkStats.rx_packets;
320     } else {
321         return;
322     }
323 
324     handler.on_link_stats_results(requestId, &ifStats, numRadios, &radioStats);
325 }
326