• 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 <memory>
18 #include "halstate.h"
19 #include "info.h"
20 #include "interface.h"
21 
22 template<typename>
23 struct NotSupportedFunction;
24 
25 template<typename R, typename... Args>
26 struct NotSupportedFunction<R (*)(Args...)> {
invokeNotSupportedFunction27     static constexpr R invoke(Args...) { return WIFI_ERROR_NOT_SUPPORTED; }
28 };
29 
30 template<typename... Args>
31 struct NotSupportedFunction<void (*)(Args...)> {
invokeNotSupportedFunction32     static constexpr void invoke(Args...) { }
33 };
34 
35 template<typename T>
notSupported(T & val)36 void notSupported(T& val) {
37     val = &NotSupportedFunction<T>::invoke;
38 }
39 
asHalState(wifi_handle h)40 HalState* asHalState(wifi_handle h) {
41     return reinterpret_cast<HalState*>(h);
42 }
43 
asInfo(wifi_handle h)44 Info* asInfo(wifi_handle h) {
45     return asHalState(h)->info();
46 }
47 
asInterface(wifi_interface_handle h)48 Interface* asInterface(wifi_interface_handle h) {
49     return reinterpret_cast<Interface*>(h);
50 }
51 
wifi_initialize(wifi_handle * handle)52 wifi_error wifi_initialize(wifi_handle* handle) {
53     if (handle == nullptr) {
54         return WIFI_ERROR_INVALID_ARGS;
55     }
56 
57     // Make the HAL state static inside the function for lazy construction. When
58     // stopping we want to keep track of the current HAL state because if the
59     // HAL starts again we need to know if we're in a state where we can start
60     // or not. If we're stopping with the intention of never starting back up
61     // again we could destroy the HAL state. Unfortunately there is no
62     // distinction between these two events so the safe choice is to leak this
63     // memory and always keep track of the HAL state. This is allocated on the
64     // heap instead of the stack to prevent any destructors being called when
65     // the dynamic library is being unloaded since the program state could be
66     // unreliable at this point.
67     static HalState* sHalState = new HalState();
68 
69     if (!sHalState->init()) {
70         return WIFI_ERROR_UNKNOWN;
71     }
72     *handle = reinterpret_cast<wifi_handle>(sHalState);
73 
74     return WIFI_SUCCESS;
75 }
76 
wifi_cleanup(wifi_handle handle,wifi_cleaned_up_handler handler)77 void wifi_cleanup(wifi_handle handle, wifi_cleaned_up_handler handler) {
78     if (handle == nullptr) {
79         return;
80     }
81 
82     std::condition_variable condition;
83     std::mutex mutex;
84     std::unique_lock<std::mutex> lock(mutex);
85     bool stopped = false;
86     // This lambda will be called when the stop completes. That will notify the
87     // condition variable and this function will wake up and exit. This ensures
88     // that this function is synchronous. The boolean is to ensure that when
89     // waiting we're protected against spurious wakeups, we only exit once the
90     // callback has signaled that it's been called.
91     auto callback = [&mutex, &stopped, &condition] {
92         std::unique_lock<std::mutex> lock(mutex);
93         stopped = true;
94         condition.notify_all();
95     };
96     if (asHalState(handle)->stop(callback)) {
97         // The handler succeeded and will call our callback, wait for it. If the
98         // stop call did not succeed we can't wait for this condition since our
99         // callback will never call notify on it.
100         while (!stopped) {
101             condition.wait(lock);
102         }
103     }
104     // The HAL seems to expect this callback to happen on the same thread, or at
105     // least that's what happens in other WiFi HALs. This is why this method has
106     // to be synchronous.
107     handler(handle);
108 }
109 
wifi_event_loop(wifi_handle handle)110 void wifi_event_loop(wifi_handle handle) {
111     if (handle == nullptr) {
112         return;
113     }
114 
115     asHalState(handle)->eventLoop();
116 }
117 
wifi_get_supported_feature_set(wifi_interface_handle handle,feature_set * set)118 wifi_error wifi_get_supported_feature_set(wifi_interface_handle handle,
119                                           feature_set* set) {
120     if (handle == nullptr) {
121         return WIFI_ERROR_INVALID_ARGS;
122     }
123 
124     return asInterface(handle)->getSupportedFeatureSet(set);
125 }
126 
wifi_get_ifaces(wifi_handle handle,int * num,wifi_interface_handle ** interfaces)127 wifi_error wifi_get_ifaces(wifi_handle handle,
128                            int* num,
129                            wifi_interface_handle** interfaces) {
130     if (handle == nullptr) {
131         return WIFI_ERROR_INVALID_ARGS;
132     }
133 
134     return asInfo(handle)->getInterfaces(num, interfaces);
135 }
136 
wifi_get_iface_name(wifi_interface_handle handle,char * name,size_t size)137 wifi_error wifi_get_iface_name(wifi_interface_handle handle,
138                                char* name,
139                                size_t size) {
140     if (handle == nullptr || (name == nullptr && size > 0)) {
141         return WIFI_ERROR_INVALID_ARGS;
142     }
143 
144     return asInterface(handle)->getName(name, size);
145 }
146 
wifi_get_link_stats(wifi_request_id id,wifi_interface_handle handle,wifi_stats_result_handler handler)147 wifi_error wifi_get_link_stats(wifi_request_id id,
148                                wifi_interface_handle handle,
149                                wifi_stats_result_handler handler) {
150     if (handle == nullptr) {
151         return WIFI_ERROR_INVALID_ARGS;
152     }
153 
154     return asInterface(handle)->getLinkStats(id, handler);
155 }
156 
wifi_set_link_stats(wifi_interface_handle handle,wifi_link_layer_params params)157 wifi_error wifi_set_link_stats(wifi_interface_handle handle,
158                                wifi_link_layer_params params) {
159     if (handle == nullptr) {
160         return WIFI_ERROR_INVALID_ARGS;
161     }
162 
163     return asInterface(handle)->setLinkStats(params);
164 }
165 
wifi_set_alert_handler(wifi_request_id id,wifi_interface_handle handle,wifi_alert_handler handler)166 wifi_error wifi_set_alert_handler(wifi_request_id id,
167                                   wifi_interface_handle handle,
168                                   wifi_alert_handler handler) {
169     if (handle == nullptr) {
170         return WIFI_ERROR_INVALID_ARGS;
171     }
172 
173     return asInterface(handle)->setAlertHandler(id, handler);
174 }
175 
wifi_reset_alert_handler(wifi_request_id id,wifi_interface_handle handle)176 wifi_error wifi_reset_alert_handler(wifi_request_id id,
177                                     wifi_interface_handle handle) {
178     if (handle == nullptr) {
179         return WIFI_ERROR_INVALID_ARGS;
180     }
181 
182     return asInterface(handle)->resetAlertHandler(id);
183 }
184 
wifi_get_firmware_version(wifi_interface_handle handle,char * buffer,int buffer_size)185 wifi_error wifi_get_firmware_version(wifi_interface_handle handle,
186                                      char* buffer,
187                                      int buffer_size) {
188     if (handle == nullptr) {
189         return WIFI_ERROR_INVALID_ARGS;
190     }
191 
192     return asInterface(handle)->getFirmwareVersion(buffer, buffer_size);
193 }
194 
wifi_get_driver_version(wifi_interface_handle handle,char * buffer,int buffer_size)195 wifi_error wifi_get_driver_version(wifi_interface_handle handle,
196                                    char* buffer,
197                                    int buffer_size) {
198     if (handle == nullptr) {
199         return WIFI_ERROR_INVALID_ARGS;
200     }
201 
202     return asInterface(handle)->getDriverVersion(buffer, buffer_size);
203 }
204 
wifi_set_scanning_mac_oui(wifi_interface_handle handle,oui scan_oui)205 wifi_error wifi_set_scanning_mac_oui(wifi_interface_handle handle,
206                                      oui scan_oui) {
207     if (handle == nullptr) {
208         return WIFI_ERROR_INVALID_ARGS;
209     }
210 
211     return asInterface(handle)->setScanningMacOui(scan_oui);
212 }
213 
wifi_clear_link_stats(wifi_interface_handle handle,u32 stats_clear_req_mask,u32 * stats_clear_rsp_mask,u8 stop_req,u8 * stop_rsp)214 wifi_error wifi_clear_link_stats(wifi_interface_handle handle,
215                                  u32 stats_clear_req_mask,
216                                  u32 *stats_clear_rsp_mask,
217                                  u8 stop_req,
218                                  u8 *stop_rsp) {
219     if (handle == nullptr) {
220         return WIFI_ERROR_INVALID_ARGS;
221     }
222 
223     return asInterface(handle)->clearLinkStats(stats_clear_req_mask,
224                                                stats_clear_rsp_mask,
225                                                stop_req,
226                                                stop_rsp);
227 }
228 
wifi_get_valid_channels(wifi_interface_handle handle,int band,int max_channels,wifi_channel * channels,int * num_channels)229 wifi_error wifi_get_valid_channels(wifi_interface_handle handle,
230                                    int band,
231                                    int max_channels,
232                                    wifi_channel *channels,
233                                    int *num_channels)
234 {
235     if (handle == nullptr) {
236         return WIFI_ERROR_INVALID_ARGS;
237     }
238 
239     return asInterface(handle)->getValidChannels(band,
240                                                  max_channels,
241                                                  channels,
242                                                  num_channels);
243 }
244 
wifi_start_logging(wifi_interface_handle handle,u32 verbose_level,u32 flags,u32 max_interval_sec,u32 min_data_size,char * ring_name)245 wifi_error wifi_start_logging(wifi_interface_handle handle,
246                               u32 verbose_level,
247                               u32 flags,
248                               u32 max_interval_sec,
249                               u32 min_data_size,
250                               char *ring_name) {
251     if (handle == nullptr) {
252         return WIFI_ERROR_INVALID_ARGS;
253     }
254 
255     return asInterface(handle)->startLogging(verbose_level,
256                                              flags,
257                                              max_interval_sec,
258                                              min_data_size,
259                                              ring_name);
260 }
261 
wifi_set_country_code(wifi_interface_handle handle,const char * country_code)262 wifi_error wifi_set_country_code(wifi_interface_handle handle,
263                                  const char *country_code) {
264     if (handle == nullptr) {
265         return WIFI_ERROR_INVALID_ARGS;
266     }
267 
268     return asInterface(handle)->setCountryCode(country_code);
269 }
270 
wifi_set_log_handler(wifi_request_id id,wifi_interface_handle handle,wifi_ring_buffer_data_handler handler)271 wifi_error wifi_set_log_handler(wifi_request_id id,
272                                 wifi_interface_handle handle,
273                                 wifi_ring_buffer_data_handler handler) {
274     if (handle == nullptr) {
275         return WIFI_ERROR_INVALID_ARGS;
276     }
277 
278     return asInterface(handle)->setLogHandler(id, handler);
279 }
280 
wifi_get_ring_buffers_status(wifi_interface_handle handle,u32 * num_rings,wifi_ring_buffer_status * status)281 wifi_error wifi_get_ring_buffers_status(wifi_interface_handle handle,
282                                         u32 *num_rings,
283                                         wifi_ring_buffer_status *status) {
284     if (handle == nullptr) {
285         return WIFI_ERROR_INVALID_ARGS;
286     }
287 
288     return asInterface(handle)->getRingBuffersStatus(num_rings, status);
289 }
290 
wifi_get_logger_supported_feature_set(wifi_interface_handle handle,unsigned int * support)291 wifi_error wifi_get_logger_supported_feature_set(wifi_interface_handle handle,
292                                                  unsigned int *support) {
293     if (handle == nullptr) {
294         return WIFI_ERROR_INVALID_ARGS;
295     }
296 
297     return asInterface(handle)->getLoggerSupportedFeatureSet(support);
298 }
299 
wifi_get_ring_data(wifi_interface_handle handle,char * ring_name)300 wifi_error wifi_get_ring_data(wifi_interface_handle handle, char *ring_name) {
301     if (handle == nullptr) {
302         return WIFI_ERROR_INVALID_ARGS;
303     }
304 
305     return asInterface(handle)->getRingData(ring_name);
306 }
307 
wifi_configure_nd_offload(wifi_interface_handle handle,u8 enable)308 wifi_error wifi_configure_nd_offload(wifi_interface_handle handle, u8 enable) {
309     if (handle == nullptr) {
310         return WIFI_ERROR_INVALID_ARGS;
311     }
312 
313     return asInterface(handle)->configureNdOffload(enable);
314 }
315 
wifi_start_pkt_fate_monitoring(wifi_interface_handle handle)316 wifi_error wifi_start_pkt_fate_monitoring(wifi_interface_handle handle) {
317     if (handle == nullptr) {
318         return WIFI_ERROR_INVALID_ARGS;
319     }
320 
321     return asInterface(handle)->startPacketFateMonitoring();
322 }
323 
wifi_get_tx_pkt_fates(wifi_interface_handle handle,wifi_tx_report * tx_report_bufs,size_t n_requested_fates,size_t * n_provided_fates)324 wifi_error wifi_get_tx_pkt_fates(wifi_interface_handle handle,
325                                  wifi_tx_report *tx_report_bufs,
326                                  size_t n_requested_fates,
327                                  size_t *n_provided_fates) {
328     if (handle == nullptr) {
329         return WIFI_ERROR_INVALID_ARGS;
330     }
331 
332     return asInterface(handle)->getTxPacketFates(tx_report_bufs,
333                                                  n_requested_fates,
334                                                  n_provided_fates);
335 }
336 
wifi_get_rx_pkt_fates(wifi_interface_handle handle,wifi_rx_report * rx_report_bufs,size_t n_requested_fates,size_t * n_provided_fates)337 wifi_error wifi_get_rx_pkt_fates(wifi_interface_handle handle,
338                                  wifi_rx_report *rx_report_bufs,
339                                  size_t n_requested_fates,
340                                  size_t *n_provided_fates) {
341     if (handle == nullptr) {
342         return WIFI_ERROR_INVALID_ARGS;
343     }
344 
345     return asInterface(handle)->getRxPacketFates(rx_report_bufs,
346                                                  n_requested_fates,
347                                                  n_provided_fates);
348 }
349 
wifi_get_packet_filter_capabilities(wifi_interface_handle handle,u32 * version,u32 * max_len)350 wifi_error wifi_get_packet_filter_capabilities(wifi_interface_handle handle,
351                                                u32 *version,
352                                                u32 *max_len) {
353     if (handle == nullptr) {
354         return WIFI_ERROR_INVALID_ARGS;
355     }
356 
357     return asInterface(handle)->getPacketFilterCapabilities(version, max_len);
358 }
359 
360 wifi_error
wifi_get_wake_reason_stats(wifi_interface_handle handle,WLAN_DRIVER_WAKE_REASON_CNT * wifi_wake_reason_cnt)361 wifi_get_wake_reason_stats(wifi_interface_handle handle,
362                            WLAN_DRIVER_WAKE_REASON_CNT *wifi_wake_reason_cnt) {
363     if (handle == nullptr) {
364         return WIFI_ERROR_INVALID_ARGS;
365     }
366 
367     return asInterface(handle)->getWakeReasonStats(wifi_wake_reason_cnt);
368 }
wifi_start_sending_offloaded_packet(wifi_request_id id,wifi_interface_handle handle,u16 ether_type,u8 * ip_packet,u16 ip_packet_len,u8 * src_mac_addr,u8 * dst_mac_addr,u32 period_msec)369 wifi_error wifi_start_sending_offloaded_packet(wifi_request_id id,
370                                                wifi_interface_handle handle,
371                                                u16 ether_type,
372                                                u8 *ip_packet,
373                                                u16 ip_packet_len,
374                                                u8 *src_mac_addr,
375                                                u8 *dst_mac_addr,
376                                                u32 period_msec) {
377     if (handle == nullptr) {
378         return WIFI_ERROR_INVALID_ARGS;
379     }
380 
381     return asInterface(handle)->startSendingOffloadedPacket(id,
382                                                             ether_type,
383                                                             ip_packet,
384                                                             ip_packet_len,
385                                                             src_mac_addr,
386                                                             dst_mac_addr,
387                                                             period_msec);
388 }
389 
wifi_stop_sending_offloaded_packet(wifi_request_id id,wifi_interface_handle handle)390 wifi_error wifi_stop_sending_offloaded_packet(wifi_request_id id,
391                                               wifi_interface_handle handle) {
392     if (handle == nullptr) {
393         return WIFI_ERROR_INVALID_ARGS;
394     }
395 
396     return asInterface(handle)->stopSendingOffloadedPacket(id);
397 }
398 
init_wifi_vendor_hal_func_table(wifi_hal_fn * fn)399 wifi_error init_wifi_vendor_hal_func_table(wifi_hal_fn* fn)
400 {
401     if (fn == NULL) {
402         return WIFI_ERROR_UNKNOWN;
403     }
404     fn->wifi_initialize = wifi_initialize;
405     fn->wifi_cleanup = wifi_cleanup;
406     fn->wifi_event_loop = wifi_event_loop;
407     fn->wifi_get_supported_feature_set = wifi_get_supported_feature_set;
408 
409     fn->wifi_get_ifaces = wifi_get_ifaces;
410     fn->wifi_get_iface_name = wifi_get_iface_name;
411     fn->wifi_get_link_stats = wifi_get_link_stats;
412     fn->wifi_set_link_stats = wifi_set_link_stats;
413     fn->wifi_clear_link_stats = wifi_clear_link_stats;
414 
415     fn->wifi_set_alert_handler = wifi_set_alert_handler;
416     fn->wifi_reset_alert_handler = wifi_reset_alert_handler;
417     fn->wifi_get_firmware_version = wifi_get_firmware_version;
418     fn->wifi_get_driver_version = wifi_get_driver_version;
419 
420     fn->wifi_set_scanning_mac_oui = wifi_set_scanning_mac_oui;
421     fn->wifi_get_valid_channels = wifi_get_valid_channels;
422     fn->wifi_start_logging = wifi_start_logging;
423     fn->wifi_set_country_code = wifi_set_country_code;
424     fn->wifi_set_log_handler = wifi_set_log_handler;
425     fn->wifi_get_ring_buffers_status = wifi_get_ring_buffers_status;
426     fn->wifi_get_logger_supported_feature_set
427         = wifi_get_logger_supported_feature_set;
428     fn->wifi_get_ring_data = wifi_get_ring_data;
429     fn->wifi_configure_nd_offload = wifi_configure_nd_offload;
430     fn->wifi_start_pkt_fate_monitoring = wifi_start_pkt_fate_monitoring;
431     fn->wifi_get_tx_pkt_fates = wifi_get_tx_pkt_fates;
432     fn->wifi_get_rx_pkt_fates = wifi_get_rx_pkt_fates;
433     fn->wifi_get_packet_filter_capabilities
434         = wifi_get_packet_filter_capabilities;
435     fn->wifi_get_wake_reason_stats = wifi_get_wake_reason_stats;
436 
437     fn->wifi_start_sending_offloaded_packet
438         = wifi_start_sending_offloaded_packet;
439     fn->wifi_stop_sending_offloaded_packet = wifi_stop_sending_offloaded_packet;
440 
441     // These function will either return WIFI_ERROR_NOT_SUPPORTED or do nothing
442     notSupported(fn->wifi_set_nodfs_flag);
443     notSupported(fn->wifi_get_concurrency_matrix);
444     notSupported(fn->wifi_start_gscan);
445     notSupported(fn->wifi_stop_gscan);
446     notSupported(fn->wifi_get_cached_gscan_results);
447     notSupported(fn->wifi_set_bssid_hotlist);
448     notSupported(fn->wifi_reset_bssid_hotlist);
449     notSupported(fn->wifi_set_significant_change_handler);
450     notSupported(fn->wifi_reset_significant_change_handler);
451     notSupported(fn->wifi_get_gscan_capabilities);
452     notSupported(fn->wifi_rtt_range_request);
453     notSupported(fn->wifi_rtt_range_cancel);
454     notSupported(fn->wifi_get_rtt_capabilities);
455     notSupported(fn->wifi_rtt_get_responder_info);
456     notSupported(fn->wifi_enable_responder);
457     notSupported(fn->wifi_disable_responder);
458     notSupported(fn->wifi_set_epno_list);
459     notSupported(fn->wifi_reset_epno_list);
460     notSupported(fn->wifi_get_firmware_memory_dump);
461     notSupported(fn->wifi_reset_log_handler);
462     notSupported(fn->wifi_start_rssi_monitoring);
463     notSupported(fn->wifi_stop_rssi_monitoring);
464     notSupported(fn->wifi_set_packet_filter);
465 
466     return WIFI_SUCCESS;
467 }
468 
469