1 /*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Portions copyright (C) 2017 Broadcom Limited
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19 #include <stdint.h>
20 #include <fcntl.h>
21 #include <sys/socket.h>
22 #include <netlink/genl/genl.h>
23 #include <netlink/genl/family.h>
24 #include <netlink/genl/ctrl.h>
25 #include <linux/rtnetlink.h>
26 #include <netpacket/packet.h>
27 #include <linux/filter.h>
28 #include <linux/errqueue.h>
29 #include <errno.h>
30
31 #include <linux/pkt_sched.h>
32 #include <netlink/object-api.h>
33 #include <netlink/netlink.h>
34 #include <netlink/socket.h>
35 #include <netlink/attr.h>
36 #include <netlink/handlers.h>
37 #include <netlink/msg.h>
38
39 #include <dirent.h>
40 #include <net/if.h>
41
42 #include <sys/types.h>
43 #include <unistd.h>
44
45 #include "sync.h"
46
47 #define LOG_TAG "WifiHAL"
48 #include <log/log.h>
49
50 #include "wifi_hal.h"
51 #include "common.h"
52 #include "cpp_bindings.h"
53 #include "rtt.h"
54 #include "brcm_version.h"
55 #include <stdio.h>
56 #include <string>
57 #include <vector>
58 /*
59 BUGBUG: normally, libnl allocates ports for all connections it makes; but
60 being a static library, it doesn't really know how many other netlink connections
61 are made by the same process, if connections come from different shared libraries.
62 These port assignments exist to solve that problem - temporarily. We need to fix
63 libnl to try and allocate ports across the entire process.
64 */
65
66 #define WIFI_HAL_CMD_SOCK_PORT 644
67 #define WIFI_HAL_EVENT_SOCK_PORT 645
68 #define MAX_VIRTUAL_IFACES 5
69
70 /*
71 * Defines for wifi_wait_for_driver_ready()
72 * Specify durations between polls and max wait time
73 */
74 #define POLL_DRIVER_DURATION_US (100000)
75 #define POLL_DRIVER_MAX_TIME_MS (10000)
76 #define EVENT_BUF_SIZE 2048
77 #define C2S(x) case x: return #x;
78
79 static int internal_no_seq_check(nl_msg *msg, void *arg);
80 static int internal_valid_message_handler(nl_msg *msg, void *arg);
81 static int wifi_get_multicast_id(wifi_handle handle, const char *name, const char *group);
82 static int wifi_add_membership(wifi_handle handle, const char *group);
83 static wifi_error wifi_init_interfaces(wifi_handle handle);
84 static wifi_error wifi_start_rssi_monitoring(wifi_request_id id, wifi_interface_handle
85 iface, s8 max_rssi, s8 min_rssi, wifi_rssi_event_handler eh);
86 static wifi_error wifi_stop_rssi_monitoring(wifi_request_id id, wifi_interface_handle iface);
87 static wifi_error wifi_set_packet_filter(wifi_interface_handle handle,
88 const u8 *program, u32 len);
89 static wifi_error wifi_read_packet_filter(wifi_interface_handle handle, u32 src_offset,
90 u8 *host_dst, u32 length);
91 static wifi_error wifi_get_packet_filter_capabilities(wifi_interface_handle handle,
92 u32 *version, u32 *max_len);
93 static wifi_error wifi_configure_nd_offload(wifi_interface_handle iface, u8 enable);
94 static wifi_error wifi_get_usable_channels(wifi_handle handle, u32 band_mask, u32 iface_mode_mask,
95 u32 filter_mask, u32 max_size, u32* size, wifi_usable_channel* channels);
96
97 static void wifi_cleanup_dynamic_ifaces(wifi_handle handle);
98 typedef enum wifi_attr {
99 ANDR_WIFI_ATTRIBUTE_INVALID = 0,
100 ANDR_WIFI_ATTRIBUTE_NUM_FEATURE_SET = 1,
101 ANDR_WIFI_ATTRIBUTE_FEATURE_SET = 2,
102 ANDR_WIFI_ATTRIBUTE_PNO_RANDOM_MAC_OUI = 3,
103 ANDR_WIFI_ATTRIBUTE_NODFS_SET = 4,
104 ANDR_WIFI_ATTRIBUTE_COUNTRY = 5,
105 ANDR_WIFI_ATTRIBUTE_ND_OFFLOAD_VALUE = 6,
106 ANDR_WIFI_ATTRIBUTE_TCPACK_SUP_VALUE = 7,
107 ANDR_WIFI_ATTRIBUTE_LATENCY_MODE = 8,
108 ANDR_WIFI_ATTRIBUTE_RANDOM_MAC = 9,
109 ANDR_WIFI_ATTRIBUTE_TX_POWER_SCENARIO = 10,
110 ANDR_WIFI_ATTRIBUTE_THERMAL_MITIGATION = 11,
111 ANDR_WIFI_ATTRIBUTE_THERMAL_COMPLETION_WINDOW = 12,
112 ANDR_WIFI_ATTRIBUTE_VOIP_MODE = 13,
113 ANDR_WIFI_ATTRIBUTE_DTIM_MULTIPLIER = 14,
114 // Add more attribute here
115 ANDR_WIFI_ATTRIBUTE_MAX
116 } wifi_attr_t;
117
118 enum wifi_rssi_monitor_attr {
119 RSSI_MONITOR_ATTRIBUTE_INVALID = 0,
120 RSSI_MONITOR_ATTRIBUTE_MAX_RSSI = 1,
121 RSSI_MONITOR_ATTRIBUTE_MIN_RSSI = 2,
122 RSSI_MONITOR_ATTRIBUTE_START = 3,
123 // Add more attribute here
124 RSSI_MONITOR_ATTRIBUTE_MAX
125 };
126
127 enum wifi_apf_attr {
128 APF_ATTRIBUTE_VERSION,
129 APF_ATTRIBUTE_MAX_LEN,
130 APF_ATTRIBUTE_PROGRAM,
131 APF_ATTRIBUTE_PROGRAM_LEN
132 };
133
134 enum apf_request_type {
135 GET_APF_CAPABILITIES,
136 SET_APF_PROGRAM,
137 READ_APF_PROGRAM
138 };
139
140 enum wifi_dscp_attr {
141 DSCP_ATTRIBUTE_INVALID = 0,
142 DSCP_ATTRIBUTE_START = 1,
143 DSCP_ATTRIBUTE_END = 2,
144 DSCP_ATTRIBUTE_AC = 3,
145 /* Add more attributes here */
146 DSCP_ATTRIBUTE_MAX
147 };
148
149 enum wifi_dscp_request_type {
150 SET_DSCP_TABLE,
151 RESET_DSCP_TABLE
152 };
153
154 enum wifi_chavoid_attr {
155 CHAVOID_ATTRIBUTE_INVALID = 0,
156 CHAVOID_ATTRIBUTE_CNT = 1,
157 CHAVOID_ATTRIBUTE_CONFIG = 2,
158 CHAVOID_ATTRIBUTE_BAND = 3,
159 CHAVOID_ATTRIBUTE_CHANNEL = 4,
160 CHAVOID_ATTRIBUTE_PWRCAP = 5,
161 CHAVOID_ATTRIBUTE_MANDATORY = 6,
162 /* Add more attributes here */
163 CHAVOID_ATTRIBUTE_MAX
164 };
165
166 enum wifi_usable_channel_attributes {
167 USABLECHAN_ATTRIBUTE_INVALID = 0,
168 USABLECHAN_ATTRIBUTE_BAND = 1,
169 USABLECHAN_ATTRIBUTE_IFACE = 2,
170 USABLECHAN_ATTRIBUTE_FILTER = 3,
171 USABLECHAN_ATTRIBUTE_MAX_SIZE = 4,
172 USABLECHAN_ATTRIBUTE_SIZE = 5,
173 USABLECHAN_ATTRIBUTE_CHANNELS = 6,
174 USABLECHAN_ATTRIBUTE_MAX
175 };
176
177 enum wifi_multista_attr {
178 MULTISTA_ATTRIBUTE_PRIM_CONN_IFACE,
179 MULTISTA_ATTRIBUTE_USE_CASE,
180 /* Add more attributes here */
181 MULTISTA_ATTRIBUTE_MAX
182 };
183
184 enum multista_request_type {
185 SET_PRIMARY_CONNECTION,
186 SET_USE_CASE
187 };
188
189 /* Initialize/Cleanup */
190
wifi_socket_set_local_port(struct nl_sock * sock,uint32_t port)191 void wifi_socket_set_local_port(struct nl_sock *sock, uint32_t port)
192 {
193 uint32_t pid = getpid() & 0x3FFFFF;
194 nl_socket_set_local_port(sock, pid + (port << 22));
195 }
196
wifi_create_nl_socket(int port)197 static nl_sock * wifi_create_nl_socket(int port)
198 {
199 // ALOGI("Creating socket");
200 struct nl_sock *sock = nl_socket_alloc();
201 if (sock == NULL) {
202 ALOGE("Could not create handle");
203 return NULL;
204 }
205
206 wifi_socket_set_local_port(sock, port);
207
208 if (nl_connect(sock, NETLINK_GENERIC)) {
209 ALOGE("Could not connect handle");
210 nl_socket_free(sock);
211 return NULL;
212 }
213 return sock;
214 }
215
IfaceTypeToString(wifi_interface_type iface_type)216 static const char *IfaceTypeToString(wifi_interface_type iface_type)
217 {
218 switch (iface_type) {
219 C2S(WIFI_INTERFACE_TYPE_STA)
220 C2S(WIFI_INTERFACE_TYPE_AP)
221 C2S(WIFI_INTERFACE_TYPE_P2P)
222 C2S(WIFI_INTERFACE_TYPE_NAN)
223 default:
224 return "UNKNOWN_WIFI_INTERFACE_TYPE";
225 }
226 }
227
228 /*initialize function pointer table with Broadcom HHAL API*/
init_wifi_vendor_hal_func_table(wifi_hal_fn * fn)229 wifi_error init_wifi_vendor_hal_func_table(wifi_hal_fn *fn)
230 {
231 if (fn == NULL) {
232 return WIFI_ERROR_UNKNOWN;
233 }
234 fn->wifi_initialize = wifi_initialize;
235 fn->wifi_wait_for_driver_ready = wifi_wait_for_driver_ready;
236 fn->wifi_cleanup = wifi_cleanup;
237 fn->wifi_event_loop = wifi_event_loop;
238 fn->wifi_get_supported_feature_set = wifi_get_supported_feature_set;
239 fn->wifi_get_concurrency_matrix = wifi_get_concurrency_matrix;
240 fn->wifi_set_scanning_mac_oui = wifi_set_scanning_mac_oui;
241 fn->wifi_get_ifaces = wifi_get_ifaces;
242 fn->wifi_get_iface_name = wifi_get_iface_name;
243 fn->wifi_start_gscan = wifi_start_gscan;
244 fn->wifi_stop_gscan = wifi_stop_gscan;
245 fn->wifi_get_cached_gscan_results = wifi_get_cached_gscan_results;
246 fn->wifi_set_bssid_hotlist = wifi_set_bssid_hotlist;
247 fn->wifi_reset_bssid_hotlist = wifi_reset_bssid_hotlist;
248 fn->wifi_set_significant_change_handler = wifi_set_significant_change_handler;
249 fn->wifi_reset_significant_change_handler = wifi_reset_significant_change_handler;
250 fn->wifi_get_gscan_capabilities = wifi_get_gscan_capabilities;
251 fn->wifi_get_link_stats = wifi_get_link_stats;
252 fn->wifi_set_link_stats = wifi_set_link_stats;
253 fn->wifi_clear_link_stats = wifi_clear_link_stats;
254 fn->wifi_get_valid_channels = wifi_get_valid_channels;
255 fn->wifi_rtt_range_request = wifi_rtt_range_request;
256 fn->wifi_rtt_range_cancel = wifi_rtt_range_cancel;
257 fn->wifi_get_rtt_capabilities = wifi_get_rtt_capabilities;
258 fn->wifi_rtt_get_responder_info = wifi_rtt_get_responder_info;
259 fn->wifi_enable_responder = wifi_enable_responder;
260 fn->wifi_disable_responder = wifi_disable_responder;
261 fn->wifi_set_nodfs_flag = wifi_set_nodfs_flag;
262 fn->wifi_start_logging = wifi_start_logging;
263 fn->wifi_set_epno_list = wifi_set_epno_list;
264 fn->wifi_reset_epno_list = wifi_reset_epno_list;
265 fn->wifi_set_country_code = wifi_set_country_code;
266 fn->wifi_get_firmware_memory_dump = wifi_get_firmware_memory_dump;
267 fn->wifi_set_log_handler = wifi_set_log_handler;
268 fn->wifi_reset_log_handler = wifi_reset_log_handler;
269 fn->wifi_set_alert_handler = wifi_set_alert_handler;
270 fn->wifi_reset_alert_handler = wifi_reset_alert_handler;
271 fn->wifi_get_firmware_version = wifi_get_firmware_version;
272 fn->wifi_get_ring_buffers_status = wifi_get_ring_buffers_status;
273 fn->wifi_get_logger_supported_feature_set = wifi_get_logger_supported_feature_set;
274 fn->wifi_get_ring_data = wifi_get_ring_data;
275 fn->wifi_get_driver_version = wifi_get_driver_version;
276 fn->wifi_start_rssi_monitoring = wifi_start_rssi_monitoring;
277 fn->wifi_stop_rssi_monitoring = wifi_stop_rssi_monitoring;
278 fn->wifi_configure_nd_offload = wifi_configure_nd_offload;
279 fn->wifi_start_sending_offloaded_packet = wifi_start_sending_offloaded_packet;
280 fn->wifi_stop_sending_offloaded_packet = wifi_stop_sending_offloaded_packet;
281 fn->wifi_start_pkt_fate_monitoring = wifi_start_pkt_fate_monitoring;
282 fn->wifi_get_tx_pkt_fates = wifi_get_tx_pkt_fates;
283 fn->wifi_get_rx_pkt_fates = wifi_get_rx_pkt_fates;
284 fn->wifi_get_packet_filter_capabilities = wifi_get_packet_filter_capabilities;
285 fn->wifi_get_wake_reason_stats = wifi_get_wake_reason_stats;
286 fn->wifi_set_packet_filter = wifi_set_packet_filter;
287 fn->wifi_enable_firmware_roaming = wifi_enable_firmware_roaming;
288 fn->wifi_get_roaming_capabilities = wifi_get_roaming_capabilities;
289 fn->wifi_configure_roaming = wifi_configure_roaming;
290 fn->wifi_nan_register_handler = nan_register_handler;
291 fn->wifi_nan_enable_request = nan_enable_request;
292 fn->wifi_nan_disable_request = nan_disable_request;
293 fn->wifi_nan_publish_request = nan_publish_request;
294 fn->wifi_nan_publish_cancel_request = nan_publish_cancel_request;
295 fn->wifi_nan_subscribe_request = nan_subscribe_request;
296 fn->wifi_nan_subscribe_cancel_request = nan_subscribe_cancel_request;
297 fn->wifi_nan_transmit_followup_request = nan_transmit_followup_request;
298 fn->wifi_nan_stats_request = nan_stats_request;
299 fn->wifi_nan_config_request = nan_config_request;
300 fn->wifi_nan_tca_request = nan_tca_request;
301 fn->wifi_nan_beacon_sdf_payload_request = nan_beacon_sdf_payload_request;
302 fn->wifi_nan_get_version = nan_get_version;
303 fn->wifi_nan_get_capabilities = nan_get_capabilities;
304 fn->wifi_nan_data_interface_create = nan_data_interface_create;
305 fn->wifi_nan_data_interface_delete = nan_data_interface_delete;
306 fn->wifi_nan_data_request_initiator = nan_data_request_initiator;
307 fn->wifi_nan_data_indication_response = nan_data_indication_response;
308 fn->wifi_nan_data_end = nan_data_end;
309 fn->wifi_set_latency_mode = wifi_set_latency_mode;
310 fn->wifi_select_tx_power_scenario = wifi_select_tx_power_scenario;
311 fn->wifi_reset_tx_power_scenario = wifi_reset_tx_power_scenario;
312 fn->wifi_read_packet_filter = wifi_read_packet_filter;
313 fn->wifi_set_subsystem_restart_handler = wifi_set_subsystem_restart_handler;
314 fn->wifi_set_thermal_mitigation_mode = wifi_set_thermal_mitigation_mode;
315 fn->wifi_map_dscp_access_category = wifi_map_dscp_access_category;
316 fn->wifi_reset_dscp_mapping = wifi_reset_dscp_mapping;
317 fn->wifi_virtual_interface_create = wifi_virtual_interface_create;
318 fn->wifi_virtual_interface_delete = wifi_virtual_interface_delete;
319 fn->wifi_set_coex_unsafe_channels = wifi_set_coex_unsafe_channels;
320 fn->wifi_twt_get_capability = twt_get_capability;
321 fn->wifi_twt_register_handler = twt_register_handler;
322 fn->wifi_twt_setup_request = twt_setup_request;
323 fn->wifi_twt_teardown_request = twt_teardown_request;
324 fn->wifi_twt_info_frame_request = twt_info_frame_request;
325 fn->wifi_twt_get_stats = twt_get_stats;
326 fn->wifi_twt_clear_stats = twt_clear_stats;
327 fn->wifi_multi_sta_set_primary_connection = wifi_multi_sta_set_primary_connection;
328 fn->wifi_multi_sta_set_use_case = wifi_multi_sta_set_use_case;
329 fn->wifi_set_voip_mode = wifi_set_voip_mode;
330 fn->wifi_set_dtim_config = wifi_set_dtim_config;
331 fn->wifi_get_usable_channels = wifi_get_usable_channels;
332 fn->wifi_trigger_subsystem_restart = wifi_trigger_subsystem_restart;
333
334 return WIFI_SUCCESS;
335 }
336 #ifdef GOOGLE_WIFI_FW_CONFIG_VERSION_C_WRAPPER
337 #include <google_wifi_firmware_config_version_info.h>
338
339 static void
wifi_check_valid_ota_version(wifi_interface_handle handle)340 wifi_check_valid_ota_version(wifi_interface_handle handle)
341 {
342 bool valid = false;
343 int32_t default_ver = get_google_default_vendor_wifi_config_version();
344 int32_t ota_ver = get_google_ota_updated_wifi_config_version();
345 ALOGE("default_ver %d, ota_ver %d", default_ver, ota_ver);
346
347 if (ota_ver > default_ver) {
348 valid = verify_google_ota_updated_wifi_config_integrity();
349 }
350
351 if (valid) {
352 ALOGE("Valid config files of OTA.");
353 wifi_hal_ota_update(handle, ota_ver);
354 }
355 else {
356 ALOGE("Do not valid config files of OTA.");
357 }
358 }
359 #endif // GOOGLE_WIFI_FW_CONFIG_VERSION_C_WRAPPER
360
361 hal_info *halInfo = NULL;
wifi_pre_initialize(void)362 wifi_error wifi_pre_initialize(void)
363 {
364 srand(getpid());
365
366 int numIfaceHandles = 0;
367 wifi_interface_handle *ifaceHandles = NULL;
368 wifi_interface_handle wlan0Handle;
369 wifi_error result = WIFI_SUCCESS;
370 wifi_handle handle;
371
372 ALOGE("wifi_pre_initialize");
373 ALOGE("--- HAL version: %s ---\n", HAL_VERSION);
374 halInfo = (hal_info *)malloc(sizeof(hal_info));
375 if (halInfo == NULL) {
376 ALOGE("Could not allocate hal_info");
377 return WIFI_ERROR_UNKNOWN;
378 }
379
380 memset(halInfo, 0, sizeof(*halInfo));
381
382 ALOGI("Creating socket");
383 if (socketpair(AF_UNIX, SOCK_STREAM, 0, halInfo->cleanup_socks) == -1) {
384 ALOGE("Could not create cleanup sockets");
385 free(halInfo);
386 return WIFI_ERROR_UNKNOWN;
387 }
388
389 struct nl_sock *cmd_sock = wifi_create_nl_socket(WIFI_HAL_CMD_SOCK_PORT);
390 if (cmd_sock == NULL) {
391 ALOGE("Could not create handle");
392 free(halInfo);
393 return WIFI_ERROR_UNKNOWN;
394 }
395
396 /* Set the socket buffer size */
397 if (nl_socket_set_buffer_size(cmd_sock, (256*1024), 0) < 0) {
398 ALOGE("Could not set size for cmd_sock: %s",
399 strerror(errno));
400 } else {
401 ALOGV("nl_socket_set_buffer_size successful for cmd_sock");
402 }
403 struct nl_sock *event_sock = wifi_create_nl_socket(WIFI_HAL_EVENT_SOCK_PORT);
404 if (event_sock == NULL) {
405 ALOGE("Could not create handle");
406 nl_socket_free(cmd_sock);
407 free(halInfo);
408 return WIFI_ERROR_UNKNOWN;
409 }
410
411 /* Set the socket buffer size */
412 if (nl_socket_set_buffer_size(event_sock, (4*1024*1024), 0) < 0) {
413 ALOGE("Could not set size for event_sock: %s",
414 strerror(errno));
415 } else {
416 ALOGV("nl_socket_set_buffer_size successful for event_sock");
417 }
418
419 struct nl_cb *cb = nl_socket_get_cb(event_sock);
420 if (cb == NULL) {
421 ALOGE("Could not create handle");
422 nl_socket_free(cmd_sock);
423 nl_socket_free(event_sock);
424 free(halInfo);
425 return WIFI_ERROR_UNKNOWN;
426 }
427
428 nl_cb_set(cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, internal_no_seq_check, halInfo);
429 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, internal_valid_message_handler, halInfo);
430 nl_cb_put(cb);
431
432 halInfo->cmd_sock = cmd_sock;
433 halInfo->event_sock = event_sock;
434 halInfo->clean_up = false;
435 halInfo->in_event_loop = false;
436
437 halInfo->event_cb = (cb_info *)malloc(sizeof(cb_info) * DEFAULT_EVENT_CB_SIZE);
438 halInfo->alloc_event_cb = DEFAULT_EVENT_CB_SIZE;
439 halInfo->num_event_cb = 0;
440
441 halInfo->cmd = (cmd_info *)malloc(sizeof(cmd_info) * DEFAULT_CMD_SIZE);
442 halInfo->alloc_cmd = DEFAULT_CMD_SIZE;
443 halInfo->num_cmd = 0;
444
445 halInfo->nl80211_family_id = genl_ctrl_resolve(cmd_sock, "nl80211");
446 if (halInfo->nl80211_family_id < 0) {
447 ALOGE("Could not resolve nl80211 familty id");
448 nl_socket_free(cmd_sock);
449 nl_socket_free(event_sock);
450 free(halInfo);
451 return WIFI_ERROR_UNKNOWN;
452 }
453
454 pthread_mutex_init(&halInfo->cb_lock, NULL);
455 InitResponseLock();
456
457 handle = (wifi_handle) halInfo;
458
459 if (wifi_init_interfaces(handle) != WIFI_SUCCESS) {
460 ALOGE("No wifi interface found");
461 nl_socket_free(cmd_sock);
462 nl_socket_free(event_sock);
463 pthread_mutex_destroy(&halInfo->cb_lock);
464 free(halInfo);
465 return WIFI_ERROR_NOT_AVAILABLE;
466 }
467
468 if ((wifi_add_membership(handle, "scan") < 0) ||
469 (wifi_add_membership(handle, "mlme") < 0) ||
470 (wifi_add_membership(handle, "regulatory") < 0) ||
471 (wifi_add_membership(handle, "vendor") < 0)) {
472 ALOGE("Add membership failed");
473 nl_socket_free(cmd_sock);
474 nl_socket_free(event_sock);
475 pthread_mutex_destroy(&halInfo->cb_lock);
476 free(halInfo);
477 return WIFI_ERROR_NOT_AVAILABLE;
478 }
479
480 ALOGI("Initialized Wifi HAL Successfully; vendor cmd = %d", NL80211_CMD_VENDOR);
481 wlan0Handle = wifi_get_wlan_interface((wifi_handle)halInfo, ifaceHandles, numIfaceHandles);
482
483 if (wlan0Handle != NULL) {
484 ALOGE("Calling preInit");
485 if (!get_halutil_mode()) {
486 #ifdef GOOGLE_WIFI_FW_CONFIG_VERSION_C_WRAPPER
487 (void) wifi_check_valid_ota_version(wlan0Handle);
488 #endif // GOOGLE_WIFI_FW_CONFIG_VERSION_C_WRAPPER
489 result = wifi_hal_preInit(wlan0Handle);
490 if (result != WIFI_SUCCESS) {
491 ALOGE("wifi_hal_preInit failed");
492 }
493 }
494 }
495
496 return WIFI_SUCCESS;
497 }
498
wifi_initialize(wifi_handle * handle)499 wifi_error wifi_initialize(wifi_handle *handle)
500 {
501
502 int numIfaceHandles = 0;
503 wifi_interface_handle *ifaceHandles = NULL;
504 wifi_interface_handle wlan0Handle;
505 wifi_error result = WIFI_SUCCESS;
506
507 ALOGE("wifi_initialize");
508
509 if (halInfo == NULL) {
510 result = wifi_pre_initialize();
511 if (result != WIFI_SUCCESS) {
512 ALOGE("wifi_initialize wifi_pre_initialize failed");
513 return result;
514 } else {
515 ALOGE("wifi_initialize wifi_pre_initialize succeeded");
516 }
517 }
518
519 *handle = (wifi_handle) halInfo;
520 wlan0Handle = wifi_get_wlan_interface((wifi_handle)halInfo, ifaceHandles, numIfaceHandles);
521
522 if (wlan0Handle != NULL) {
523 ALOGE("Calling Hal_init");
524 if (!get_halutil_mode()) {
525 result = wifi_start_hal(wlan0Handle);
526 if (result != WIFI_SUCCESS) {
527 ALOGE("wifi_start_hal failed");
528 }
529 }
530 } else {
531 ALOGI("Not Calling set alert handler as global_iface is NULL");
532 }
533 return WIFI_SUCCESS;
534 }
535
wifi_wait_for_driver_ready(void)536 wifi_error wifi_wait_for_driver_ready(void)
537 {
538 // This function will wait to make sure basic client netdev is created
539 // Function times out after 10 seconds
540 int count = (POLL_DRIVER_MAX_TIME_MS * 1000) / POLL_DRIVER_DURATION_US;
541 FILE *fd;
542
543 do {
544 if ((fd = fopen("/sys/class/net/wlan0", "r")) != NULL) {
545 fclose(fd);
546 wifi_pre_initialize();
547 return WIFI_SUCCESS;
548 }
549 usleep(POLL_DRIVER_DURATION_US);
550 } while(--count > 0);
551
552 ALOGE("Timed out waiting on Driver ready ... ");
553 return WIFI_ERROR_TIMED_OUT;
554 }
555
wifi_add_membership(wifi_handle handle,const char * group)556 static int wifi_add_membership(wifi_handle handle, const char *group)
557 {
558 hal_info *info = getHalInfo(handle);
559
560 int id = wifi_get_multicast_id(handle, "nl80211", group);
561 if (id < 0) {
562 ALOGE("Could not find group %s", group);
563 return id;
564 }
565
566 int ret = nl_socket_add_membership(info->event_sock, id);
567 if (ret < 0) {
568 ALOGE("Could not add membership to group %s", group);
569 }
570
571 // ALOGI("Successfully added membership for group %s", group);
572 return ret;
573 }
574
internal_cleaned_up_handler(wifi_handle handle)575 static void internal_cleaned_up_handler(wifi_handle handle)
576 {
577 hal_info *info = getHalInfo(handle);
578 wifi_cleaned_up_handler cleaned_up_handler = info->cleaned_up_handler;
579
580 ALOGI("internal clean up");
581
582 if (info->cmd_sock != 0) {
583 ALOGI("cmd_sock non null. clean up");
584 close(info->cleanup_socks[0]);
585 close(info->cleanup_socks[1]);
586 nl_socket_free(info->cmd_sock);
587 nl_socket_free(info->event_sock);
588 info->cmd_sock = NULL;
589 info->event_sock = NULL;
590 }
591
592 if (cleaned_up_handler) {
593 ALOGI("cleanup_handler cb");
594 (*cleaned_up_handler)(handle);
595 } else {
596 ALOGI("!! clean up handler is null!!");
597 }
598 DestroyResponseLock();
599 pthread_mutex_destroy(&info->cb_lock);
600 free(info);
601
602 ALOGI("Internal cleanup completed");
603 }
604
wifi_internal_module_cleanup()605 void wifi_internal_module_cleanup()
606 {
607 nan_deinit_handler();
608 twt_deinit_handler();
609 }
610
wifi_cleanup(wifi_handle handle,wifi_cleaned_up_handler handler)611 void wifi_cleanup(wifi_handle handle, wifi_cleaned_up_handler handler)
612 {
613 if (!handle) {
614 ALOGE("Handle is null");
615 return;
616 }
617
618 hal_info *info = getHalInfo(handle);
619 char buf[64];
620 wifi_error result;
621
622 int numIfaceHandles = 0;
623 wifi_interface_handle *ifaceHandles = NULL;
624 wifi_interface_handle wlan0Handle;
625
626 info->cleaned_up_handler = handler;
627
628 wlan0Handle = wifi_get_wlan_interface((wifi_handle) info, ifaceHandles, numIfaceHandles);
629
630 if (wlan0Handle != NULL) {
631 ALOGE("Calling hal cleanup");
632 if (!get_halutil_mode()) {
633 result = wifi_stop_hal(wlan0Handle);
634 if (result != WIFI_SUCCESS) {
635 ALOGE("wifi_stop_hal failed");
636 }
637 }
638
639 } else {
640 ALOGE("Not cleaning up hal as global_iface is NULL");
641 }
642
643 /* calling internal modules or cleanup */
644 wifi_internal_module_cleanup();
645 pthread_mutex_lock(&info->cb_lock);
646
647 int bad_commands = 0;
648
649 ALOGI("event_cb callbacks left: %d ", info->num_event_cb);
650 for (int i = 0; i < info->num_event_cb; i++) {
651 ALOGI("event_cb cleanup. index:%d", i);
652 cb_info *cbi = &(info->event_cb[i]);
653 if (!cbi) {
654 ALOGE("cbi null for index %d", i);
655 continue;
656 }
657 ALOGI("event_cb cleanup. vendor cmd:%d sub_cmd:%d", cbi->vendor_id, cbi->vendor_subcmd);
658 WifiCommand *cmd = (WifiCommand *)cbi->cb_arg;
659 if (cmd != NULL) {
660 ALOGI("Command left in event_cb %p", cmd);
661 }
662 }
663
664 ALOGI("Check bad commands: num_cmd:%d bad_commands:%d", info->num_cmd, bad_commands);
665 while (info->num_cmd > bad_commands) {
666 int num_cmd = info->num_cmd;
667 cmd_info *cmdi = &(info->cmd[bad_commands]);
668 WifiCommand *cmd = cmdi->cmd;
669 if (cmd != NULL) {
670 ALOGI("Cancelling command %p:%s", cmd, cmd->getType());
671 pthread_mutex_unlock(&info->cb_lock);
672 cmd->cancel();
673 pthread_mutex_lock(&info->cb_lock);
674 if (num_cmd == info->num_cmd) {
675 ALOGI("Cancelling command %p:%s did not work", cmd, (cmd ? cmd->getType(): ""));
676 bad_commands++;
677 }
678 /* release reference added when command is saved */
679 cmd->releaseRef();
680 }
681 }
682
683 for (int i = 0; i < info->num_event_cb; i++) {
684 cb_info *cbi = &(info->event_cb[i]);
685 if (!cbi) {
686 ALOGE("cbi null for index %d", i);
687 continue;
688 }
689 WifiCommand *cmd = (WifiCommand *)cbi->cb_arg;
690 ALOGE("Leaked command %p", cmd);
691 }
692 if (!get_halutil_mode()) {
693 wifi_cleanup_dynamic_ifaces(handle);
694 }
695 pthread_mutex_unlock(&info->cb_lock);
696
697 info->clean_up = true;
698
699 if (TEMP_FAILURE_RETRY(write(info->cleanup_socks[0], "Exit", 4)) < 1) {
700 // As a fallback set the cleanup flag to TRUE
701 ALOGE("could not write to the cleanup socket");
702 }
703 ALOGE("wifi_clean_up done");
704 }
705
internal_pollin_handler(wifi_handle handle)706 static int internal_pollin_handler(wifi_handle handle)
707 {
708 hal_info *info = getHalInfo(handle);
709 struct nl_cb *cb = nl_socket_get_cb(info->event_sock);
710 int res = nl_recvmsgs(info->event_sock, cb);
711 // ALOGD("nl_recvmsgs returned %d", res);
712 nl_cb_put(cb);
713 return res;
714 }
715
716 /* Run event handler */
wifi_event_loop(wifi_handle handle)717 void wifi_event_loop(wifi_handle handle)
718 {
719 hal_info *info = getHalInfo(handle);
720 if (info->in_event_loop) {
721 return;
722 } else {
723 info->in_event_loop = true;
724 }
725
726 pollfd pfd[2];
727 memset(&pfd[0], 0, sizeof(pollfd) * 2);
728
729 pfd[0].fd = nl_socket_get_fd(info->event_sock);
730 pfd[0].events = POLLIN;
731 pfd[1].fd = info->cleanup_socks[1];
732 pfd[1].events = POLLIN;
733
734 char buf[2048];
735 /* TODO: Add support for timeouts */
736
737 do {
738 int timeout = -1; /* Infinite timeout */
739 pfd[0].revents = 0;
740 pfd[1].revents = 0;
741 // ALOGI("Polling socket");
742 int result = TEMP_FAILURE_RETRY(poll(pfd, 2, timeout));
743 if (result < 0) {
744 // ALOGE("Error polling socket");
745 } else if (pfd[0].revents & POLLERR) {
746 ALOGE("POLL Error; error no = %d (%s)", errno, strerror(errno));
747 ssize_t result2 = TEMP_FAILURE_RETRY(read(pfd[0].fd, buf, sizeof(buf)));
748 ALOGE("Read after POLL returned %zd, error no = %d (%s)", result2,
749 errno, strerror(errno));
750 } else if (pfd[0].revents & POLLHUP) {
751 ALOGE("Remote side hung up");
752 break;
753 } else if (pfd[0].revents & POLLIN && !info->clean_up) {
754 // ALOGI("Found some events!!!");
755 internal_pollin_handler(handle);
756 } else if (pfd[1].revents & POLLIN) {
757 ALOGI("Got a signal to exit!!!");
758 } else {
759 ALOGE("Unknown event - %0x, %0x", pfd[0].revents, pfd[1].revents);
760 }
761 } while (!info->clean_up);
762
763 internal_cleaned_up_handler(handle);
764 ALOGE("Exit %s", __FUNCTION__);
765 }
766
767 ///////////////////////////////////////////////////////////////////////////////////////
768
internal_no_seq_check(struct nl_msg * msg,void * arg)769 static int internal_no_seq_check(struct nl_msg *msg, void *arg)
770 {
771 return NL_OK;
772 }
773
internal_valid_message_handler(nl_msg * msg,void * arg)774 static int internal_valid_message_handler(nl_msg *msg, void *arg)
775 {
776 // ALOGI("got an event");
777
778 wifi_handle handle = (wifi_handle)arg;
779 hal_info *info = getHalInfo(handle);
780
781 WifiEvent event(msg);
782 int res = event.parse();
783 if (res < 0) {
784 ALOGE("Failed to parse event: %d", res);
785 return NL_SKIP;
786 }
787
788 int cmd = event.get_cmd();
789 uint32_t vendor_id = 0;
790 int subcmd = 0;
791
792 if (cmd == NL80211_CMD_VENDOR) {
793 vendor_id = event.get_u32(NL80211_ATTR_VENDOR_ID);
794 subcmd = event.get_u32(NL80211_ATTR_VENDOR_SUBCMD);
795 ALOGV("event received %s, vendor_id = 0x%0x, subcmd = 0x%0x",
796 event.get_cmdString(), vendor_id, subcmd);
797 } else {
798 // ALOGV("event received %s", event.get_cmdString());
799 }
800
801 // ALOGV("event received %s, vendor_id = 0x%0x", event.get_cmdString(), vendor_id);
802 // event.log();
803
804 pthread_mutex_lock(&info->cb_lock);
805
806 for (int i = 0; i < info->num_event_cb; i++) {
807 if (cmd == info->event_cb[i].nl_cmd) {
808 if (cmd == NL80211_CMD_VENDOR
809 && ((vendor_id != info->event_cb[i].vendor_id)
810 || (subcmd != info->event_cb[i].vendor_subcmd)))
811 {
812 /* event for a different vendor, ignore it */
813 continue;
814 }
815
816 cb_info *cbi = &(info->event_cb[i]);
817 nl_recvmsg_msg_cb_t cb_func = cbi->cb_func;
818 void *cb_arg = cbi->cb_arg;
819 WifiCommand *cmd = (WifiCommand *)cbi->cb_arg;
820 if (cmd != NULL) {
821 cmd->addRef();
822 }
823 pthread_mutex_unlock(&info->cb_lock);
824 if (cb_func)
825 (*cb_func)(msg, cb_arg);
826 if (cmd != NULL) {
827 cmd->releaseRef();
828 }
829
830 return NL_OK;
831 }
832 }
833
834 pthread_mutex_unlock(&info->cb_lock);
835 return NL_OK;
836 }
837
838 ///////////////////////////////////////////////////////////////////////////////////////
839
840 class GetMulticastIdCommand : public WifiCommand
841 {
842 private:
843 const char *mName;
844 const char *mGroup;
845 int mId;
846 public:
GetMulticastIdCommand(wifi_handle handle,const char * name,const char * group)847 GetMulticastIdCommand(wifi_handle handle, const char *name, const char *group)
848 : WifiCommand("GetMulticastIdCommand", handle, 0)
849 {
850 mName = name;
851 mGroup = group;
852 mId = -1;
853 }
854
getId()855 int getId() {
856 return mId;
857 }
858
create()859 virtual int create() {
860 int nlctrlFamily = genl_ctrl_resolve(mInfo->cmd_sock, "nlctrl");
861 // ALOGI("ctrl family = %d", nlctrlFamily);
862 int ret = mMsg.create(nlctrlFamily, CTRL_CMD_GETFAMILY, 0, 0);
863 if (ret < 0) {
864 return ret;
865 }
866 ret = mMsg.put_string(CTRL_ATTR_FAMILY_NAME, mName);
867 return ret;
868 }
869
handleResponse(WifiEvent & reply)870 virtual int handleResponse(WifiEvent& reply) {
871
872 // ALOGI("handling reponse in %s", __func__);
873
874 struct nlattr **tb = reply.attributes();
875 struct nlattr *mcgrp = NULL;
876 int i;
877
878 if (!tb[CTRL_ATTR_MCAST_GROUPS]) {
879 ALOGI("No multicast groups found");
880 return NL_SKIP;
881 } else {
882 // ALOGI("Multicast groups attr size = %d", nla_len(tb[CTRL_ATTR_MCAST_GROUPS]));
883 }
884
885 for_each_attr(mcgrp, tb[CTRL_ATTR_MCAST_GROUPS], i) {
886
887 // ALOGI("Processing group");
888 struct nlattr *tb2[CTRL_ATTR_MCAST_GRP_MAX + 1];
889 nla_parse(tb2, CTRL_ATTR_MCAST_GRP_MAX, (nlattr *)nla_data(mcgrp),
890 nla_len(mcgrp), NULL);
891 if (!tb2[CTRL_ATTR_MCAST_GRP_NAME] || !tb2[CTRL_ATTR_MCAST_GRP_ID]) {
892 continue;
893 }
894
895 char *grpName = (char *)nla_data(tb2[CTRL_ATTR_MCAST_GRP_NAME]);
896 int grpNameLen = nla_len(tb2[CTRL_ATTR_MCAST_GRP_NAME]);
897
898 // ALOGI("Found group name %s", grpName);
899
900 if (strncmp(grpName, mGroup, grpNameLen) != 0)
901 continue;
902
903 mId = nla_get_u32(tb2[CTRL_ATTR_MCAST_GRP_ID]);
904 break;
905 }
906
907 return NL_SKIP;
908 }
909
910 };
911
912 class SetPnoMacAddrOuiCommand : public WifiCommand {
913
914 private:
915 byte *mOui;
916 feature_set *fset;
917 feature_set *feature_matrix;
918 int *fm_size;
919 int set_size_max;
920 public:
SetPnoMacAddrOuiCommand(wifi_interface_handle handle,oui scan_oui)921 SetPnoMacAddrOuiCommand(wifi_interface_handle handle, oui scan_oui)
922 : WifiCommand("SetPnoMacAddrOuiCommand", handle, 0)
923 {
924 mOui = scan_oui;
925 fset = NULL;
926 feature_matrix = NULL;
927 fm_size = NULL;
928 set_size_max = 0;
929 }
930
createRequest(WifiRequest & request,int subcmd,byte * scan_oui)931 int createRequest(WifiRequest& request, int subcmd, byte *scan_oui) {
932 int result = request.create(GOOGLE_OUI, subcmd);
933 if (result < 0) {
934 return result;
935 }
936
937 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
938 result = request.put(ANDR_WIFI_ATTRIBUTE_PNO_RANDOM_MAC_OUI, scan_oui, DOT11_OUI_LEN);
939 if (result < 0) {
940 return result;
941 }
942
943 request.attr_end(data);
944 return WIFI_SUCCESS;
945
946 }
947
start()948 int start() {
949 ALOGD("Sending mac address OUI");
950 WifiRequest request(familyId(), ifaceId());
951 int result = createRequest(request, WIFI_SUBCMD_SET_PNO_RANDOM_MAC_OUI, mOui);
952 if (result != WIFI_SUCCESS) {
953 ALOGE("failed to create request; result = %d", result);
954 return result;
955 }
956
957 result = requestResponse(request);
958 if (result != WIFI_SUCCESS) {
959 ALOGE("failed to set scanning mac OUI; result = %d", result);
960 }
961
962 return result;
963 }
964 protected:
handleResponse(WifiEvent & reply)965 virtual int handleResponse(WifiEvent& reply) {
966 ALOGD("Request complete!");
967 /* Nothing to do on response! */
968 return NL_SKIP;
969 }
970 };
971
972 class SetNodfsCommand : public WifiCommand {
973
974 private:
975 u32 mNoDfs;
976 public:
SetNodfsCommand(wifi_interface_handle handle,u32 nodfs)977 SetNodfsCommand(wifi_interface_handle handle, u32 nodfs)
978 : WifiCommand("SetNodfsCommand", handle, 0) {
979 mNoDfs = nodfs;
980 }
create()981 virtual int create() {
982 int ret;
983
984 ret = mMsg.create(GOOGLE_OUI, WIFI_SUBCMD_NODFS_SET);
985 if (ret < 0) {
986 ALOGE("Can't create message to send to driver - %d", ret);
987 return ret;
988 }
989
990 nlattr *data = mMsg.attr_start(NL80211_ATTR_VENDOR_DATA);
991 ret = mMsg.put_u32(ANDR_WIFI_ATTRIBUTE_NODFS_SET, mNoDfs);
992 if (ret < 0) {
993 return ret;
994 }
995
996 mMsg.attr_end(data);
997 return WIFI_SUCCESS;
998 }
999 };
1000
1001 class SetCountryCodeCommand : public WifiCommand {
1002 private:
1003 const char *mCountryCode;
1004 public:
SetCountryCodeCommand(wifi_interface_handle handle,const char * country_code)1005 SetCountryCodeCommand(wifi_interface_handle handle, const char *country_code)
1006 : WifiCommand("SetCountryCodeCommand", handle, 0) {
1007 mCountryCode = country_code;
1008 }
create()1009 virtual int create() {
1010 int ret;
1011
1012 ret = mMsg.create(GOOGLE_OUI, WIFI_SUBCMD_SET_COUNTRY_CODE);
1013 if (ret < 0) {
1014 ALOGE("Can't create message to send to driver - %d", ret);
1015 return ret;
1016 }
1017
1018 nlattr *data = mMsg.attr_start(NL80211_ATTR_VENDOR_DATA);
1019 ret = mMsg.put_string(ANDR_WIFI_ATTRIBUTE_COUNTRY, mCountryCode);
1020 if (ret < 0) {
1021 return ret;
1022 }
1023
1024 mMsg.attr_end(data);
1025 return WIFI_SUCCESS;
1026
1027 }
1028 };
1029
1030 class SetRSSIMonitorCommand : public WifiCommand {
1031 private:
1032 s8 mMax_rssi;
1033 s8 mMin_rssi;
1034 wifi_rssi_event_handler mHandler;
1035 public:
SetRSSIMonitorCommand(wifi_request_id id,wifi_interface_handle handle,s8 max_rssi,s8 min_rssi,wifi_rssi_event_handler eh)1036 SetRSSIMonitorCommand(wifi_request_id id, wifi_interface_handle handle,
1037 s8 max_rssi, s8 min_rssi, wifi_rssi_event_handler eh)
1038 : WifiCommand("SetRSSIMonitorCommand", handle, id), mMax_rssi(max_rssi), mMin_rssi
1039 (min_rssi), mHandler(eh)
1040 {
1041 }
createRequest(WifiRequest & request,int enable)1042 int createRequest(WifiRequest& request, int enable) {
1043 int result = request.create(GOOGLE_OUI, WIFI_SUBCMD_SET_RSSI_MONITOR);
1044 if (result < 0) {
1045 return result;
1046 }
1047
1048 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
1049 result = request.put_u32(RSSI_MONITOR_ATTRIBUTE_MAX_RSSI, (enable ? mMax_rssi: 0));
1050 if (result < 0) {
1051 return result;
1052 }
1053 ALOGD("create request");
1054 result = request.put_u32(RSSI_MONITOR_ATTRIBUTE_MIN_RSSI, (enable? mMin_rssi: 0));
1055 if (result < 0) {
1056 return result;
1057 }
1058 result = request.put_u32(RSSI_MONITOR_ATTRIBUTE_START, enable);
1059 if (result < 0) {
1060 return result;
1061 }
1062 request.attr_end(data);
1063 return result;
1064 }
1065
start()1066 int start() {
1067 WifiRequest request(familyId(), ifaceId());
1068 int result = createRequest(request, 1);
1069 if (result != WIFI_SUCCESS) {
1070 ALOGE("Failed to create request; result = %d", result);
1071 return result;
1072 }
1073
1074 registerVendorHandler(GOOGLE_OUI, GOOGLE_RSSI_MONITOR_EVENT);
1075 ALOGI("Register GOOGLE_RSSI_MONITOR_EVENT handler");
1076
1077 result = requestResponse(request);
1078 if (result != WIFI_SUCCESS) {
1079 unregisterVendorHandler(GOOGLE_OUI, GOOGLE_RSSI_MONITOR_EVENT);
1080 ALOGE("Failed to set RSSI Monitor, result = %d", result);
1081 return result;
1082 }
1083
1084 ALOGI("Successfully set RSSI monitoring");
1085 return result;
1086 }
1087
cancel()1088 virtual int cancel() {
1089 unregisterVendorHandler(GOOGLE_OUI, GOOGLE_RSSI_MONITOR_EVENT);
1090
1091 WifiRequest request(familyId(), ifaceId());
1092 int result = createRequest(request, 0);
1093 if (result != WIFI_SUCCESS) {
1094 ALOGE("failed to create request; result = %d", result);
1095 } else {
1096 result = requestResponse(request);
1097 if (result != WIFI_SUCCESS) {
1098 ALOGE("failed to stop RSSI monitoring = %d", result);
1099 }
1100 }
1101 return WIFI_SUCCESS;
1102 }
1103
handleResponse(WifiEvent & reply)1104 virtual int handleResponse(WifiEvent& reply) {
1105 /* Nothing to do on response! */
1106 return NL_SKIP;
1107 }
1108
handleEvent(WifiEvent & event)1109 virtual int handleEvent(WifiEvent& event) {
1110 ALOGI("Got a RSSI monitor event");
1111
1112 nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA);
1113 int len = event.get_vendor_data_len();
1114
1115 if (vendor_data == NULL || len == 0) {
1116 ALOGI("RSSI monitor: No data");
1117 return NL_SKIP;
1118 }
1119 /* driver<->HAL event structure */
1120 #define RSSI_MONITOR_EVT_VERSION 1
1121 typedef struct {
1122 u8 version;
1123 s8 cur_rssi;
1124 mac_addr BSSID;
1125 } rssi_monitor_evt;
1126
1127 rssi_monitor_evt *data = (rssi_monitor_evt *)event.get_vendor_data();
1128
1129 if (data->version != RSSI_MONITOR_EVT_VERSION) {
1130 ALOGI("Event version mismatch %d, expected %d", data->version, RSSI_MONITOR_EVT_VERSION);
1131 return NL_SKIP;
1132 }
1133
1134 if (*mHandler.on_rssi_threshold_breached) {
1135 (*mHandler.on_rssi_threshold_breached)(id(), data->BSSID, data->cur_rssi);
1136 } else {
1137 ALOGW("No RSSI monitor handler registered");
1138 }
1139
1140 return NL_SKIP;
1141 }
1142
1143 };
1144
1145 class AndroidPktFilterCommand : public WifiCommand {
1146 private:
1147 const u8* mProgram;
1148 u8* mReadProgram;
1149 u32 mProgramLen;
1150 u32* mVersion;
1151 u32* mMaxLen;
1152 int mReqType;
1153 public:
AndroidPktFilterCommand(wifi_interface_handle handle,u32 * version,u32 * max_len)1154 AndroidPktFilterCommand(wifi_interface_handle handle,
1155 u32* version, u32* max_len)
1156 : WifiCommand("AndroidPktFilterCommand", handle, 0),
1157 mVersion(version), mMaxLen(max_len),
1158 mReqType(GET_APF_CAPABILITIES)
1159 {
1160 mProgram = NULL;
1161 mProgramLen = 0;
1162 }
1163
AndroidPktFilterCommand(wifi_interface_handle handle,const u8 * program,u32 len)1164 AndroidPktFilterCommand(wifi_interface_handle handle,
1165 const u8* program, u32 len)
1166 : WifiCommand("AndroidPktFilterCommand", handle, 0),
1167 mProgram(program), mProgramLen(len),
1168 mReqType(SET_APF_PROGRAM)
1169 {
1170 mVersion = NULL;
1171 mMaxLen = NULL;
1172 }
1173
AndroidPktFilterCommand(wifi_interface_handle handle,u8 * host_dst,u32 length)1174 AndroidPktFilterCommand(wifi_interface_handle handle,
1175 u8* host_dst, u32 length)
1176 : WifiCommand("AndroidPktFilterCommand", handle, 0),
1177 mReadProgram(host_dst), mProgramLen(length),
1178 mReqType(READ_APF_PROGRAM)
1179 {
1180 }
1181
createRequest(WifiRequest & request)1182 int createRequest(WifiRequest& request) {
1183 if (mReqType == SET_APF_PROGRAM) {
1184 ALOGI("\n%s: APF set program request\n", __FUNCTION__);
1185 return createSetPktFilterRequest(request);
1186 } else if (mReqType == GET_APF_CAPABILITIES) {
1187 ALOGI("\n%s: APF get capabilities request\n", __FUNCTION__);
1188 return createGetPktFilterCapabilitesRequest(request);
1189 } else if (mReqType == READ_APF_PROGRAM) {
1190 ALOGI("\n%s: APF read packet filter request\n", __FUNCTION__);
1191 return createReadPktFilterRequest(request);
1192 } else {
1193 ALOGE("\n%s Unknown APF request\n", __FUNCTION__);
1194 return WIFI_ERROR_NOT_SUPPORTED;
1195 }
1196 return WIFI_SUCCESS;
1197 }
1198
createSetPktFilterRequest(WifiRequest & request)1199 int createSetPktFilterRequest(WifiRequest& request) {
1200 u8 *program = new u8[mProgramLen];
1201 NULL_CHECK_RETURN(program, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
1202 int result = request.create(GOOGLE_OUI, APF_SUBCMD_SET_FILTER);
1203 if (result < 0) {
1204 delete[] program;
1205 return result;
1206 }
1207
1208 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
1209 result = request.put_u32(APF_ATTRIBUTE_PROGRAM_LEN, mProgramLen);
1210 if (result < 0) {
1211 goto exit;
1212 }
1213 memcpy(program, mProgram, mProgramLen);
1214 result = request.put(APF_ATTRIBUTE_PROGRAM, program, mProgramLen);
1215 if (result < 0) {
1216 goto exit;
1217 }
1218 exit: request.attr_end(data);
1219 delete[] program;
1220 return result;
1221 }
1222
createGetPktFilterCapabilitesRequest(WifiRequest & request)1223 int createGetPktFilterCapabilitesRequest(WifiRequest& request) {
1224 int result = request.create(GOOGLE_OUI, APF_SUBCMD_GET_CAPABILITIES);
1225 if (result < 0) {
1226 return result;
1227 }
1228
1229 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
1230 request.attr_end(data);
1231 return result;
1232 }
1233
createReadPktFilterRequest(WifiRequest & request)1234 int createReadPktFilterRequest(WifiRequest& request) {
1235 int result = request.create(GOOGLE_OUI, APF_SUBCMD_READ_FILTER);
1236 if (result < 0) {
1237 return result;
1238 }
1239 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
1240 request.attr_end(data);
1241 return result;
1242 }
1243
start()1244 int start() {
1245 WifiRequest request(familyId(), ifaceId());
1246 int result = createRequest(request);
1247 if (result < 0) {
1248 return result;
1249 }
1250 result = requestResponse(request);
1251 if (result < 0) {
1252 ALOGI("Request Response failed for APF, result = %d", result);
1253 return result;
1254 }
1255 ALOGI("Done!");
1256 return result;
1257 }
1258
cancel()1259 int cancel() {
1260 return WIFI_SUCCESS;
1261 }
1262
handleResponse(WifiEvent & reply)1263 int handleResponse(WifiEvent& reply) {
1264 ALOGD("In SetAPFCommand::handleResponse");
1265
1266 if (reply.get_cmd() != NL80211_CMD_VENDOR) {
1267 ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
1268 return NL_SKIP;
1269 }
1270
1271 int id = reply.get_vendor_id();
1272 int subcmd = reply.get_vendor_subcmd();
1273
1274 nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA);
1275 int len = reply.get_vendor_data_len();
1276
1277 ALOGD("Id = %0x, subcmd = %d, len = %d", id, subcmd, len);
1278 if (vendor_data == NULL || len == 0) {
1279 ALOGE("no vendor data in SetAPFCommand response; ignoring it");
1280 return NL_SKIP;
1281 }
1282 if( mReqType == SET_APF_PROGRAM) {
1283 ALOGD("Response received for set packet filter command\n");
1284 } else if (mReqType == GET_APF_CAPABILITIES) {
1285 *mVersion = 0;
1286 *mMaxLen = 0;
1287 ALOGD("Response received for get packet filter capabilities command\n");
1288 for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
1289 if (it.get_type() == APF_ATTRIBUTE_VERSION) {
1290 *mVersion = it.get_u32();
1291 ALOGI("APF version is %d\n", *mVersion);
1292 } else if (it.get_type() == APF_ATTRIBUTE_MAX_LEN) {
1293 *mMaxLen = it.get_u32();
1294 ALOGI("APF max len is %d\n", *mMaxLen);
1295 } else {
1296 ALOGE("Ignoring invalid attribute type = %d, size = %d",
1297 it.get_type(), it.get_len());
1298 }
1299 }
1300 } else if (mReqType == READ_APF_PROGRAM) {
1301 ALOGD("Read packet filter, mProgramLen = %d\n", mProgramLen);
1302 for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
1303 if (it.get_type() == APF_ATTRIBUTE_PROGRAM) {
1304 u8 *buffer = NULL;
1305 buffer = (u8 *)it.get_data();
1306 memcpy(mReadProgram, buffer, mProgramLen);
1307 } else if (it.get_type() == APF_ATTRIBUTE_PROGRAM_LEN) {
1308 int apf_length = it.get_u32();
1309 ALOGD("apf program length = %d\n", apf_length);
1310 }
1311 }
1312 }
1313 return NL_OK;
1314 }
1315
handleEvent(WifiEvent & event)1316 int handleEvent(WifiEvent& event) {
1317 /* No Event to receive for APF commands */
1318 return NL_SKIP;
1319 }
1320 };
1321
1322 class SetNdoffloadCommand : public WifiCommand {
1323
1324 private:
1325 u8 mEnable;
1326 public:
SetNdoffloadCommand(wifi_interface_handle handle,u8 enable)1327 SetNdoffloadCommand(wifi_interface_handle handle, u8 enable)
1328 : WifiCommand("SetNdoffloadCommand", handle, 0) {
1329 mEnable = enable;
1330 }
create()1331 virtual int create() {
1332 int ret;
1333
1334 ret = mMsg.create(GOOGLE_OUI, WIFI_SUBCMD_CONFIG_ND_OFFLOAD);
1335 if (ret < 0) {
1336 ALOGE("Can't create message to send to driver - %d", ret);
1337 return ret;
1338 }
1339
1340 nlattr *data = mMsg.attr_start(NL80211_ATTR_VENDOR_DATA);
1341 ret = mMsg.put_u8(ANDR_WIFI_ATTRIBUTE_ND_OFFLOAD_VALUE, mEnable);
1342 if (ret < 0) {
1343 return ret;
1344 }
1345
1346 mMsg.attr_end(data);
1347 return WIFI_SUCCESS;
1348 }
1349 };
1350
1351 class GetFeatureSetCommand : public WifiCommand {
1352
1353 private:
1354 int feature_type;
1355 feature_set *fset;
1356 feature_set *feature_matrix;
1357 int *fm_size;
1358 int set_size_max;
1359 public:
GetFeatureSetCommand(wifi_interface_handle handle,int feature,feature_set * set,feature_set set_matrix[],int * size,int max_size)1360 GetFeatureSetCommand(wifi_interface_handle handle, int feature, feature_set *set,
1361 feature_set set_matrix[], int *size, int max_size)
1362 : WifiCommand("GetFeatureSetCommand", handle, 0) {
1363 feature_type = feature;
1364 fset = set;
1365 feature_matrix = set_matrix;
1366 fm_size = size;
1367 set_size_max = max_size;
1368 }
1369
create()1370 virtual int create() {
1371 int ret;
1372
1373 if(feature_type == ANDR_WIFI_ATTRIBUTE_NUM_FEATURE_SET) {
1374 ret = mMsg.create(GOOGLE_OUI, WIFI_SUBCMD_GET_FEATURE_SET);
1375 } else if (feature_type == ANDR_WIFI_ATTRIBUTE_FEATURE_SET) {
1376 ret = mMsg.create(GOOGLE_OUI, WIFI_SUBCMD_GET_FEATURE_SET_MATRIX);
1377 } else {
1378 ALOGE("Unknown feature type %d", feature_type);
1379 return -1;
1380 }
1381
1382 if (ret < 0) {
1383 ALOGE("Can't create message to send to driver - %d", ret);
1384 }
1385
1386 return ret;
1387 }
1388
1389 protected:
handleResponse(WifiEvent & reply)1390 virtual int handleResponse(WifiEvent& reply) {
1391
1392 ALOGV("In GetFeatureSetCommand::handleResponse");
1393
1394 if (reply.get_cmd() != NL80211_CMD_VENDOR) {
1395 ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
1396 return NL_SKIP;
1397 }
1398
1399 int id = reply.get_vendor_id();
1400 int subcmd = reply.get_vendor_subcmd();
1401
1402 nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA);
1403 int len = reply.get_vendor_data_len();
1404
1405 ALOGV("Id = %0x, subcmd = %d, len = %d", id, subcmd, len);
1406 if (vendor_data == NULL || len == 0) {
1407 ALOGE("no vendor data in GetFeatureSetCommand response; ignoring it");
1408 return NL_SKIP;
1409 }
1410 if(feature_type == ANDR_WIFI_ATTRIBUTE_NUM_FEATURE_SET) {
1411 void *data = reply.get_vendor_data();
1412 if(!fset) {
1413 ALOGE("Buffers pointers not set");
1414 return NL_SKIP;
1415 }
1416 memcpy(fset, data, min(len, (int) sizeof(*fset)));
1417 } else {
1418 int num_features_set = 0;
1419 int i = 0;
1420
1421 if(!feature_matrix || !fm_size) {
1422 ALOGE("Buffers pointers not set");
1423 return NL_SKIP;
1424 }
1425
1426 for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
1427 if (it.get_type() == ANDR_WIFI_ATTRIBUTE_NUM_FEATURE_SET) {
1428 num_features_set = it.get_u32();
1429 ALOGV("Got feature list with %d concurrent sets", num_features_set);
1430 if(set_size_max && (num_features_set > set_size_max))
1431 num_features_set = set_size_max;
1432 *fm_size = num_features_set;
1433 } else if ((it.get_type() == ANDR_WIFI_ATTRIBUTE_FEATURE_SET) &&
1434 i < num_features_set) {
1435 feature_matrix[i] = it.get_u32();
1436 i++;
1437 } else {
1438 ALOGW("Ignoring invalid attribute type = %d, size = %d",
1439 it.get_type(), it.get_len());
1440 }
1441 }
1442
1443 }
1444 return NL_OK;
1445 }
1446
1447 };
1448
1449 class SetLatencyModeCommand : public WifiCommand {
1450 private:
1451 u32 mLatencyMode;
1452 public:
SetLatencyModeCommand(wifi_interface_handle handle,u32 LatencyMode)1453 SetLatencyModeCommand(wifi_interface_handle handle, u32 LatencyMode)
1454 : WifiCommand("SetLatencyModeCommand", handle, 0) {
1455 mLatencyMode = LatencyMode;
1456 }
1457
create()1458 virtual int create() {
1459 int ret;
1460
1461 /* Check for invalid latency Mode */
1462 if ((mLatencyMode != WIFI_LATENCY_MODE_NORMAL) &&
1463 (mLatencyMode != WIFI_LATENCY_MODE_LOW)) {
1464 ALOGE("SetLatencyModeCommand: Invalid mode: %d", mLatencyMode);
1465 return WIFI_ERROR_UNKNOWN;
1466 }
1467
1468 ret = mMsg.create(GOOGLE_OUI, WIFI_SUBCMD_SET_LATENCY_MODE);
1469 if (ret < 0) {
1470 ALOGE("Can't create message to send to driver - %d", ret);
1471 return ret;
1472 }
1473
1474 nlattr *data = mMsg.attr_start(NL80211_ATTR_VENDOR_DATA);
1475 ret = mMsg.put_u32(ANDR_WIFI_ATTRIBUTE_LATENCY_MODE, mLatencyMode);
1476 if (ret < 0) {
1477 return ret;
1478 }
1479
1480 mMsg.attr_end(data);
1481 return WIFI_SUCCESS;
1482 }
1483 };
wifi_get_multicast_id(wifi_handle handle,const char * name,const char * group)1484 static int wifi_get_multicast_id(wifi_handle handle, const char *name, const char *group)
1485 {
1486 GetMulticastIdCommand cmd(handle, name, group);
1487 int res = cmd.requestResponse();
1488 if (res < 0)
1489 return res;
1490 else
1491 return cmd.getId();
1492 }
1493
1494 /////////////////////////////////////////////////////////////////////////
1495
is_wifi_interface(const char * name)1496 static bool is_wifi_interface(const char *name)
1497 {
1498 if (strncmp(name, "wlan", 4) != 0 && strncmp(name, "swlan", 5) != 0 &&
1499 strncmp(name, "p2p", 3) != 0 && strncmp(name, "aware", 5) != 0) {
1500 /* not a wifi interface; ignore it */
1501 return false;
1502 } else {
1503 return true;
1504 }
1505 }
1506
get_interface(const char * name,interface_info * info)1507 static int get_interface(const char *name, interface_info *info)
1508 {
1509 int size = 0;
1510 size = strlcpy(info->name, name, sizeof(info->name));
1511 if (size >= sizeof(info->name)) {
1512 return WIFI_ERROR_OUT_OF_MEMORY;
1513 }
1514 info->id = if_nametoindex(name);
1515 // ALOGI("found an interface : %s, id = %d", name, info->id);
1516 return WIFI_SUCCESS;
1517 }
1518
wifi_init_interfaces(wifi_handle handle)1519 wifi_error wifi_init_interfaces(wifi_handle handle)
1520 {
1521 hal_info *info = (hal_info *)handle;
1522
1523 struct dirent *de;
1524
1525 DIR *d = opendir("/sys/class/net");
1526 if (d == 0)
1527 return WIFI_ERROR_UNKNOWN;
1528
1529 int n = 0;
1530 while ((de = readdir(d))) {
1531 if (de->d_name[0] == '.')
1532 continue;
1533 if (is_wifi_interface(de->d_name) ) {
1534 n++;
1535 }
1536 }
1537
1538 closedir(d);
1539
1540 if (n == 0)
1541 return WIFI_ERROR_NOT_AVAILABLE;
1542
1543 d = opendir("/sys/class/net");
1544 if (d == 0)
1545 return WIFI_ERROR_UNKNOWN;
1546
1547 /* Have place holder for 3 virtual interfaces */
1548 n += MAX_VIRTUAL_IFACES;
1549 info->interfaces = (interface_info **)calloc(n, sizeof(interface_info *) * n);
1550 if (!info->interfaces) {
1551 info->num_interfaces = 0;
1552 closedir(d);
1553 return WIFI_ERROR_OUT_OF_MEMORY;
1554 }
1555
1556 int i = 0;
1557 while ((de = readdir(d))) {
1558 if (de->d_name[0] == '.')
1559 continue;
1560 if (is_wifi_interface(de->d_name)) {
1561 interface_info *ifinfo = (interface_info *)malloc(sizeof(interface_info));
1562 if (!ifinfo) {
1563 free(info->interfaces);
1564 info->num_interfaces = 0;
1565 closedir(d);
1566 return WIFI_ERROR_OUT_OF_MEMORY;
1567 }
1568 memset(ifinfo, 0, sizeof(interface_info));
1569 if (get_interface(de->d_name, ifinfo) != WIFI_SUCCESS) {
1570 continue;
1571 }
1572 /* Mark as static iface */
1573 ifinfo->is_virtual = false;
1574 ifinfo->handle = handle;
1575 info->interfaces[i] = ifinfo;
1576 i++;
1577 }
1578 }
1579
1580 closedir(d);
1581
1582 info->num_interfaces = i;
1583 info->max_num_interfaces = n;
1584 return WIFI_SUCCESS;
1585 }
1586
wifi_get_ifaces(wifi_handle handle,int * num,wifi_interface_handle ** interfaces)1587 wifi_error wifi_get_ifaces(wifi_handle handle, int *num, wifi_interface_handle **interfaces)
1588 {
1589 hal_info *info = (hal_info *)handle;
1590
1591 *interfaces = (wifi_interface_handle *)info->interfaces;
1592 *num = info->num_interfaces;
1593
1594 return WIFI_SUCCESS;
1595 }
1596
wifi_add_iface_hal_info(wifi_handle handle,const char * ifname)1597 wifi_error wifi_add_iface_hal_info(wifi_handle handle, const char* ifname)
1598 {
1599 hal_info *info = NULL;
1600 int i = 0;
1601
1602 info = (hal_info *)handle;
1603 if (info == NULL) {
1604 ALOGE("Could not find info\n");
1605 return WIFI_ERROR_UNKNOWN;
1606 }
1607
1608 ALOGI("%s: add interface_info for iface: %s\n", __FUNCTION__, ifname);
1609 if (info->num_interfaces == MAX_VIRTUAL_IFACES) {
1610 ALOGE("No space. max limit reached for virtual interfaces %d\n", info->num_interfaces);
1611 return WIFI_ERROR_OUT_OF_MEMORY;
1612 }
1613
1614 interface_info *ifinfo = (interface_info *)malloc(sizeof(interface_info));
1615 if (!ifinfo) {
1616 free(info->interfaces);
1617 info->num_interfaces = 0;
1618 return WIFI_ERROR_OUT_OF_MEMORY;
1619 }
1620
1621 ifinfo->handle = handle;
1622 while (i < info->max_num_interfaces) {
1623 if (info->interfaces[i] == NULL) {
1624 if (get_interface(ifname, ifinfo) != WIFI_SUCCESS) {
1625 continue;
1626 }
1627 ifinfo->is_virtual = true;
1628 info->interfaces[i] = ifinfo;
1629 info->num_interfaces++;
1630 ALOGI("%s: Added iface: %s at the index %d\n", __FUNCTION__, ifname, i);
1631 break;
1632 }
1633 i++;
1634 }
1635 return WIFI_SUCCESS;
1636 }
1637
wifi_clear_iface_hal_info(wifi_handle handle,const char * ifname)1638 wifi_error wifi_clear_iface_hal_info(wifi_handle handle, const char* ifname)
1639 {
1640 hal_info *info = (hal_info *)handle;
1641 int i = 0;
1642
1643 ALOGI("%s: clear hal info for iface: %s\n", __FUNCTION__, ifname);
1644 while (i < info->max_num_interfaces) {
1645 if ((info->interfaces[i] != NULL) &&
1646 strncmp(info->interfaces[i]->name, ifname,
1647 sizeof(info->interfaces[i]->name)) == 0) {
1648 free(info->interfaces[i]);
1649 info->interfaces[i] = NULL;
1650 info->num_interfaces--;
1651 ALOGI("%s: Cleared the index = %d for iface: %s\n", __FUNCTION__, i, ifname);
1652 break;
1653 }
1654 i++;
1655 }
1656 if (i < info->num_interfaces) {
1657 for (int j = i; j < info->num_interfaces; j++) {
1658 info->interfaces[j] = info->interfaces[j+1];
1659 }
1660 info->interfaces[info->num_interfaces] = NULL;
1661 }
1662 return WIFI_SUCCESS;
1663 }
1664
wifi_get_wlan_interface(wifi_handle info,wifi_interface_handle * ifaceHandles,int numIfaceHandles)1665 wifi_interface_handle wifi_get_wlan_interface(wifi_handle info, wifi_interface_handle *ifaceHandles, int numIfaceHandles)
1666 {
1667 char buf[EVENT_BUF_SIZE];
1668 wifi_interface_handle wlan0Handle;
1669 wifi_error res = wifi_get_ifaces((wifi_handle)info, &numIfaceHandles, &ifaceHandles);
1670 if (res < 0) {
1671 return NULL;
1672 }
1673 for (int i = 0; i < numIfaceHandles; i++) {
1674 if (wifi_get_iface_name(ifaceHandles[i], buf, sizeof(buf)) == WIFI_SUCCESS) {
1675 if (strncmp(buf, "wlan0", 5) == 0) {
1676 ALOGI("found interface %s\n", buf);
1677 wlan0Handle = ifaceHandles[i];
1678 return wlan0Handle;
1679 }
1680 }
1681 }
1682 return NULL;
1683 }
wifi_get_iface_name(wifi_interface_handle handle,char * name,size_t size)1684 wifi_error wifi_get_iface_name(wifi_interface_handle handle, char *name, size_t size)
1685 {
1686 interface_info *info = (interface_info *)handle;
1687 strncpy(name, info->name, (IFNAMSIZ));
1688 name[IFNAMSIZ - 1] = '\0';
1689 return WIFI_SUCCESS;
1690 }
1691
wifi_get_iface_handle(wifi_handle handle,char * name)1692 wifi_interface_handle wifi_get_iface_handle(wifi_handle handle, char *name)
1693 {
1694 char buf[EVENT_BUF_SIZE];
1695 wifi_interface_handle *ifaceHandles;
1696 int numIfaceHandles;
1697 wifi_interface_handle ifHandle;
1698
1699 wifi_error res = wifi_get_ifaces((wifi_handle)handle, &numIfaceHandles, &ifaceHandles);
1700 if (res < 0) {
1701 return NULL;
1702 }
1703 for (int i = 0; i < numIfaceHandles; i++) {
1704 if (wifi_get_iface_name(ifaceHandles[i], buf, sizeof(buf)) == WIFI_SUCCESS) {
1705 if (strcmp(buf, name) == 0) {
1706 ALOGI("found interface %s\n", buf);
1707 ifHandle = ifaceHandles[i];
1708 return ifHandle;
1709 }
1710 }
1711 }
1712 return NULL;
1713 }
1714
wifi_get_supported_feature_set(wifi_interface_handle handle,feature_set * set)1715 wifi_error wifi_get_supported_feature_set(wifi_interface_handle handle, feature_set *set)
1716 {
1717 GetFeatureSetCommand command(handle, ANDR_WIFI_ATTRIBUTE_NUM_FEATURE_SET, set, NULL, NULL, 1);
1718 return (wifi_error) command.requestResponse();
1719 }
1720
wifi_get_concurrency_matrix(wifi_interface_handle handle,int set_size_max,feature_set set[],int * set_size)1721 wifi_error wifi_get_concurrency_matrix(wifi_interface_handle handle, int set_size_max,
1722 feature_set set[], int *set_size)
1723 {
1724 GetFeatureSetCommand command(handle, ANDR_WIFI_ATTRIBUTE_FEATURE_SET, NULL,
1725 set, set_size, set_size_max);
1726 return (wifi_error) command.requestResponse();
1727 }
1728
wifi_set_scanning_mac_oui(wifi_interface_handle handle,oui scan_oui)1729 wifi_error wifi_set_scanning_mac_oui(wifi_interface_handle handle, oui scan_oui)
1730 {
1731 SetPnoMacAddrOuiCommand command(handle, scan_oui);
1732 return (wifi_error)command.start();
1733
1734 }
1735
wifi_set_nodfs_flag(wifi_interface_handle handle,u32 nodfs)1736 wifi_error wifi_set_nodfs_flag(wifi_interface_handle handle, u32 nodfs)
1737 {
1738 SetNodfsCommand command(handle, nodfs);
1739 return (wifi_error) command.requestResponse();
1740 }
1741
wifi_set_country_code(wifi_interface_handle handle,const char * country_code)1742 wifi_error wifi_set_country_code(wifi_interface_handle handle, const char *country_code)
1743 {
1744 SetCountryCodeCommand command(handle, country_code);
1745 return (wifi_error) command.requestResponse();
1746 }
1747
wifi_start_rssi_monitoring(wifi_request_id id,wifi_interface_handle iface,s8 max_rssi,s8 min_rssi,wifi_rssi_event_handler eh)1748 static wifi_error wifi_start_rssi_monitoring(wifi_request_id id, wifi_interface_handle
1749 iface, s8 max_rssi, s8 min_rssi, wifi_rssi_event_handler eh)
1750 {
1751 ALOGI("Starting RSSI monitor %d", id);
1752 wifi_handle handle = getWifiHandle(iface);
1753 SetRSSIMonitorCommand *cmd = new SetRSSIMonitorCommand(id, iface, max_rssi, min_rssi, eh);
1754 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
1755 wifi_error result = wifi_register_cmd(handle, id, cmd);
1756 if (result != WIFI_SUCCESS) {
1757 cmd->releaseRef();
1758 return result;
1759 }
1760 result = (wifi_error)cmd->start();
1761 if (result != WIFI_SUCCESS) {
1762 wifi_unregister_cmd(handle, id);
1763 cmd->releaseRef();
1764 return result;
1765 }
1766 return result;
1767 }
1768
wifi_stop_rssi_monitoring(wifi_request_id id,wifi_interface_handle iface)1769 static wifi_error wifi_stop_rssi_monitoring(wifi_request_id id, wifi_interface_handle iface)
1770 {
1771 ALOGI("Stopping RSSI monitor %d", id);
1772
1773 if(id == -1) {
1774 wifi_rssi_event_handler handler;
1775 s8 max_rssi = 0, min_rssi = 0;
1776 memset(&handler, 0, sizeof(handler));
1777 SetRSSIMonitorCommand *cmd = new SetRSSIMonitorCommand(id, iface,
1778 max_rssi, min_rssi, handler);
1779 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
1780 cmd->cancel();
1781 cmd->releaseRef();
1782 return WIFI_SUCCESS;
1783 }
1784 return wifi_cancel_cmd(id, iface);
1785 }
1786
wifi_get_packet_filter_capabilities(wifi_interface_handle handle,u32 * version,u32 * max_len)1787 static wifi_error wifi_get_packet_filter_capabilities(wifi_interface_handle handle,
1788 u32 *version, u32 *max_len)
1789 {
1790 ALOGD("Getting APF capabilities, halHandle = %p\n", handle);
1791 AndroidPktFilterCommand *cmd = new AndroidPktFilterCommand(handle, version, max_len);
1792 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
1793 wifi_error result = (wifi_error)cmd->start();
1794 if (result == WIFI_SUCCESS) {
1795 ALOGD("Getting APF capability, version = %d, max_len = %d\n", *version, *max_len);
1796 }
1797 cmd->releaseRef();
1798 return result;
1799 }
1800
wifi_set_packet_filter(wifi_interface_handle handle,const u8 * program,u32 len)1801 static wifi_error wifi_set_packet_filter(wifi_interface_handle handle,
1802 const u8 *program, u32 len)
1803 {
1804 ALOGD("Setting APF program, halHandle = %p\n", handle);
1805 AndroidPktFilterCommand *cmd = new AndroidPktFilterCommand(handle, program, len);
1806 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
1807 wifi_error result = (wifi_error)cmd->start();
1808 cmd->releaseRef();
1809 return result;
1810 }
1811
wifi_read_packet_filter(wifi_interface_handle handle,u32 src_offset,u8 * host_dst,u32 length)1812 static wifi_error wifi_read_packet_filter(wifi_interface_handle handle,
1813 u32 src_offset, u8 *host_dst, u32 length)
1814 {
1815 ALOGD("Read APF program, halHandle = %p, length = %d\n", handle, length);
1816 AndroidPktFilterCommand *cmd = new AndroidPktFilterCommand(handle, host_dst, length);
1817 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
1818 wifi_error result = (wifi_error)cmd->start();
1819 if (result == WIFI_SUCCESS) {
1820 ALOGI("Read APF program success\n");
1821 }
1822 cmd->releaseRef();
1823 return result;
1824 }
wifi_configure_nd_offload(wifi_interface_handle handle,u8 enable)1825 static wifi_error wifi_configure_nd_offload(wifi_interface_handle handle, u8 enable)
1826 {
1827 SetNdoffloadCommand command(handle, enable);
1828 return (wifi_error) command.requestResponse();
1829 }
wifi_set_latency_mode(wifi_interface_handle handle,wifi_latency_mode mode)1830 wifi_error wifi_set_latency_mode(wifi_interface_handle handle, wifi_latency_mode mode)
1831 {
1832 ALOGD("Setting Wifi Latency mode, halHandle = %p LatencyMode = %d\n", handle, mode);
1833 SetLatencyModeCommand command(handle, mode);
1834 return (wifi_error) command.requestResponse();
1835 }
1836
1837 /////////////////////////////////////////////////////////////////////////
1838 class TxPowerScenario : public WifiCommand {
1839 wifi_power_scenario mScenario;
1840 public:
1841 // constructor for tx power scenario setting
TxPowerScenario(wifi_interface_handle handle,wifi_power_scenario scenario)1842 TxPowerScenario(wifi_interface_handle handle, wifi_power_scenario scenario)
1843 : WifiCommand("TxPowerScenario", handle, 0), mScenario(scenario)
1844 {
1845 mScenario = scenario;
1846 }
1847
1848 // constructor for tx power scenario resetting
TxPowerScenario(wifi_interface_handle handle)1849 TxPowerScenario(wifi_interface_handle handle)
1850 : WifiCommand("TxPowerScenario", handle, 0)
1851 {
1852 mScenario = WIFI_POWER_SCENARIO_DEFAULT;
1853 }
1854
createRequest(WifiRequest & request,int subcmd,wifi_power_scenario mScenario)1855 int createRequest(WifiRequest& request, int subcmd, wifi_power_scenario mScenario) {
1856 int result = request.create(GOOGLE_OUI, subcmd);
1857 if (result < 0) {
1858 return result;
1859 }
1860
1861 if ((mScenario <= WIFI_POWER_SCENARIO_INVALID) ||
1862 (mScenario >= SAR_CONFIG_SCENARIO_COUNT)) {
1863 ALOGE("Unsupported tx power value:%d\n", mScenario);
1864 return WIFI_ERROR_NOT_SUPPORTED;
1865 }
1866
1867 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
1868 result = request.put_s8(ANDR_WIFI_ATTRIBUTE_TX_POWER_SCENARIO, mScenario);
1869 if (result < 0) {
1870 ALOGE("Failed to put tx power scenario request; result = %d", result);
1871 return result;
1872 }
1873 request.attr_end(data);
1874 return WIFI_SUCCESS;
1875 }
1876
start(wifi_power_scenario mScenario)1877 int start(wifi_power_scenario mScenario) {
1878 WifiRequest request(familyId(), ifaceId());
1879 int result = createRequest(request, WIFI_SUBCMD_TX_POWER_SCENARIO, mScenario);
1880 if (result != WIFI_SUCCESS) {
1881 ALOGE("failed to create request; result = %d", result);
1882 return result;
1883 }
1884
1885 result = requestResponse(request);
1886 if (result != WIFI_SUCCESS) {
1887 ALOGE("failed to send tx power scenario; result = %d", result);
1888 }
1889 return result;
1890 }
1891 protected:
handleResponse(WifiEvent & reply)1892 virtual int handleResponse(WifiEvent& reply) {
1893 ALOGD("Request complete!");
1894 /* Nothing to do on response! */
1895 return NL_SKIP;
1896 }
1897 };
1898
1899
wifi_select_tx_power_scenario(wifi_interface_handle handle,wifi_power_scenario scenario)1900 wifi_error wifi_select_tx_power_scenario(wifi_interface_handle handle, wifi_power_scenario scenario)
1901 {
1902 ALOGE("wifi_select_tx_power_scenario");
1903 TxPowerScenario command(handle);
1904 return (wifi_error)command.start(scenario);
1905 }
1906
wifi_reset_tx_power_scenario(wifi_interface_handle handle)1907 wifi_error wifi_reset_tx_power_scenario(wifi_interface_handle handle)
1908 {
1909 wifi_power_scenario scenario = WIFI_POWER_SCENARIO_DEFAULT;
1910 ALOGE("wifi_reset_tx_power_scenario");
1911 TxPowerScenario command(handle);
1912 return (wifi_error)command.start(scenario);
1913 }
1914
1915 /////////////////////////////////////////////////////////////////////////////
1916
1917 class ThermalMitigation : public WifiCommand {
1918 private:
1919 wifi_thermal_mode mMitigation;
1920 u32 mCompletionWindow;
1921 public:
1922 // constructor for thermal mitigation setting
ThermalMitigation(wifi_interface_handle handle,wifi_thermal_mode mitigation,u32 completion_window)1923 ThermalMitigation(wifi_interface_handle handle,
1924 wifi_thermal_mode mitigation, u32 completion_window)
1925 : WifiCommand("ThermalMitigation", handle, 0)
1926 {
1927 mMitigation = mitigation;
1928 mCompletionWindow = completion_window;
1929 }
1930
createRequest(WifiRequest & request,int subcmd,wifi_thermal_mode mitigation,u32 completion_window)1931 int createRequest(WifiRequest& request, int subcmd,
1932 wifi_thermal_mode mitigation, u32 completion_window) {
1933 int result = request.create(GOOGLE_OUI, subcmd);
1934 if (result < 0) {
1935 return result;
1936 }
1937
1938 if ((mitigation < WIFI_MITIGATION_NONE) ||
1939 (mitigation > WIFI_MITIGATION_EMERGENCY)) {
1940 ALOGE("Unsupported tx mitigation value:%d\n", mitigation);
1941 return WIFI_ERROR_NOT_SUPPORTED;
1942 }
1943
1944 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
1945 result = request.put_s8(ANDR_WIFI_ATTRIBUTE_THERMAL_MITIGATION, mitigation);
1946 if (result < 0) {
1947 ALOGE("Failed to put tx power scenario request; result = %d", result);
1948 return result;
1949 }
1950 result = request.put_u32(ANDR_WIFI_ATTRIBUTE_THERMAL_COMPLETION_WINDOW,
1951 completion_window);
1952 if (result < 0) {
1953 ALOGE("Failed to put tx power scenario request; result = %d", result);
1954 return result;
1955 }
1956
1957 request.attr_end(data);
1958 return WIFI_SUCCESS;
1959 }
1960
start()1961 int start() {
1962 WifiRequest request(familyId(), ifaceId());
1963 int result = createRequest(request, WIFI_SUBCMD_THERMAL_MITIGATION, mMitigation,
1964 mCompletionWindow);
1965 if (result != WIFI_SUCCESS) {
1966 ALOGE("failed to create request; result = %d", result);
1967 return result;
1968 }
1969
1970 ALOGD("try to get resp; mitigation=%d, delay=%d", mMitigation, mCompletionWindow);
1971 result = requestResponse(request);
1972 if (result != WIFI_SUCCESS) {
1973 ALOGE("failed to send thermal mitigation; result = %d", result);
1974 }
1975 return result;
1976 }
1977 protected:
handleResponse(WifiEvent & reply)1978 virtual int handleResponse(WifiEvent& reply) {
1979 ALOGD("Request complete!");
1980 /* Nothing to do on response! */
1981 return NL_SKIP;
1982 }
1983 };
1984
wifi_set_thermal_mitigation_mode(wifi_handle handle,wifi_thermal_mode mode,u32 completion_window)1985 wifi_error wifi_set_thermal_mitigation_mode(wifi_handle handle,
1986 wifi_thermal_mode mode,
1987 u32 completion_window)
1988 {
1989 int numIfaceHandles = 0;
1990 wifi_interface_handle *ifaceHandles = NULL;
1991 wifi_interface_handle wlan0Handle;
1992
1993 wlan0Handle = wifi_get_wlan_interface((wifi_handle)handle, ifaceHandles, numIfaceHandles);
1994 ThermalMitigation command(wlan0Handle, mode, completion_window);
1995 return (wifi_error)command.start();
1996 }
1997
1998 /////////////////////////////////////////////////////////////////////////////
1999
2000 class ChAvoidCommand : public WifiCommand {
2001 private:
2002 u32 mNumParams;
2003 wifi_coex_unsafe_channel *chavoidParams;
2004 u32 mMandatory;
2005
2006 public:
ChAvoidCommand(wifi_interface_handle handle,u32 num,wifi_coex_unsafe_channel channels[],u32 mandatory)2007 ChAvoidCommand(wifi_interface_handle handle,
2008 u32 num, wifi_coex_unsafe_channel channels[], u32 mandatory)
2009 : WifiCommand("ChAvoidCommand", handle, 0),
2010 mNumParams(num), chavoidParams(channels), mMandatory(mandatory)
2011 {
2012 }
2013
createRequest(WifiRequest & request)2014 int createRequest(WifiRequest& request) {
2015 return createSetChAvoidRequest(request);
2016 }
2017
createSetChAvoidRequest(WifiRequest & request)2018 int createSetChAvoidRequest(WifiRequest& request) {
2019 int result = request.create(GOOGLE_OUI, CHAVOID_SUBCMD_SET_CONFIG);
2020 if (result < 0) {
2021 ALOGE("%s : Failed to create SUBCMD\n", __func__);
2022 return result;
2023 }
2024
2025 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
2026 result = request.put_u32(CHAVOID_ATTRIBUTE_CNT, mNumParams);
2027 if (result < 0) {
2028 ALOGE("%s : Failed to set cound\n", __func__);
2029 return result;
2030 }
2031 result = request.put_u32(CHAVOID_ATTRIBUTE_MANDATORY, mMandatory);
2032 if (result < 0) {
2033 ALOGE("%s : Failed to set mandatory cap\n", __func__);
2034 return result;
2035 }
2036
2037 nlattr *chavoid_config = request.attr_start(CHAVOID_ATTRIBUTE_CONFIG);
2038 for (int i = 0; i< mNumParams; i++) {
2039 nlattr *item = request.attr_start(i);
2040 if (item == NULL) {
2041 ALOGE("%s : Failed to alloc item\n", __func__);
2042 return WIFI_ERROR_OUT_OF_MEMORY;
2043 }
2044 result = request.put_u32(CHAVOID_ATTRIBUTE_BAND, chavoidParams[i].band);
2045 if (result < 0) {
2046 ALOGE("%s : Failed to set band\n", __func__);
2047 return result;
2048 }
2049 result = request.put_u32(CHAVOID_ATTRIBUTE_CHANNEL, chavoidParams[i].channel);
2050 if (result < 0) {
2051 ALOGE("%s : Failed to set channel\n", __func__);
2052 return result;
2053 }
2054 result = request.put_u32(CHAVOID_ATTRIBUTE_PWRCAP, chavoidParams[i].power_cap_dbm);
2055 if (result < 0) {
2056 ALOGE("%s : Failed to set power cap\n", __func__);
2057 return result;
2058 }
2059 request.attr_end(item);
2060 }
2061 request.attr_end(chavoid_config);
2062 request.attr_end(data);
2063 return WIFI_SUCCESS;
2064 }
2065
start()2066 int start() {
2067 WifiRequest request(familyId(), ifaceId());
2068 int result = createRequest(request);
2069 if (result < 0) {
2070 return result;
2071 }
2072 result = requestResponse(request);
2073 if (result < 0) {
2074 ALOGI("Request Response failed for ChAvoid, result = %d", result);
2075 return result;
2076 }
2077 return result;
2078 }
2079
handleResponse(WifiEvent & reply)2080 int handleResponse(WifiEvent& reply) {
2081 ALOGD("In ChAvoidCommand::handleResponse");
2082
2083 if (reply.get_cmd() != NL80211_CMD_VENDOR) {
2084 ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
2085 return NL_SKIP;
2086 }
2087
2088 nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA);
2089 int len = reply.get_vendor_data_len();
2090
2091 if (vendor_data == NULL || len == 0) {
2092 ALOGE("no vendor data in ChAvoidCommand response; ignoring it");
2093 return NL_SKIP;
2094 }
2095 ALOGD("Response received for ChAvoid command\n");
2096 return NL_OK;
2097 }
2098
handleEvent(WifiEvent & event)2099 int handleEvent(WifiEvent& event) {
2100 /* No Event to receive for ChAvoid commands */
2101 ALOGD("ChAvoid command %s\n", __FUNCTION__);
2102 return NL_SKIP;
2103 }
2104 };
2105
wifi_set_coex_unsafe_channels(wifi_handle handle,u32 num,wifi_coex_unsafe_channel channels[],u32 mandatory)2106 wifi_error wifi_set_coex_unsafe_channels(wifi_handle handle,
2107 u32 num, wifi_coex_unsafe_channel channels[], u32 mandatory)
2108 {
2109 int numIfaceHandles = 0;
2110 wifi_interface_handle *ifaceHandles = NULL;
2111 wifi_interface_handle wlan0Handle;
2112
2113 wlan0Handle = wifi_get_wlan_interface((wifi_handle)handle, ifaceHandles, numIfaceHandles);
2114
2115 ChAvoidCommand *cmd = new ChAvoidCommand(wlan0Handle, num, channels, mandatory);
2116 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
2117 wifi_error result = (wifi_error)cmd->start();
2118 if (result == WIFI_SUCCESS) {
2119 ALOGI("Setting Channel Avoidance success\n");
2120 } else {
2121 ALOGE("Setting Channel Avoidance failed\n");
2122 }
2123 cmd->releaseRef();
2124 return result;
2125 }
2126
2127 /////////////////////////////////////////////////////////////////////////////
2128
2129 class DscpCommand : public WifiCommand {
2130 private:
2131 u32 mStart;
2132 u32 mEnd;
2133 u32 mAc;
2134 int mReqType;
2135 public:
DscpCommand(wifi_interface_handle handle,u32 start,u32 end,u32 ac)2136 DscpCommand(wifi_interface_handle handle,
2137 u32 start, u32 end, u32 ac)
2138 : WifiCommand("DscpCommand", handle, 0),
2139 mStart(start), mEnd(end), mAc(ac),
2140 mReqType(SET_DSCP_TABLE)
2141 {
2142 }
2143
DscpCommand(wifi_interface_handle handle)2144 DscpCommand(wifi_interface_handle handle)
2145 : WifiCommand("DscpCommand", handle, 0),
2146 mReqType(RESET_DSCP_TABLE)
2147 {
2148 }
2149
createRequest(WifiRequest & request)2150 int createRequest(WifiRequest& request) {
2151 if (mReqType == SET_DSCP_TABLE) {
2152 ALOGI("\n%s: DSCP set table request\n", __FUNCTION__);
2153 return createSetDscpRequest(request);
2154 } else if (mReqType == RESET_DSCP_TABLE) {
2155 ALOGI("\n%s: DSCP reset table request\n", __FUNCTION__);
2156 return createResetDscpRequest(request);
2157 } else {
2158 ALOGE("\n%s Unknown DSCP request\n", __FUNCTION__);
2159 return WIFI_ERROR_NOT_SUPPORTED;
2160 }
2161 return WIFI_SUCCESS;
2162 }
2163
createSetDscpRequest(WifiRequest & request)2164 int createSetDscpRequest(WifiRequest& request) {
2165 int result = request.create(GOOGLE_OUI, DSCP_SUBCMD_SET_TABLE);
2166 if (result < 0) {
2167 return result;
2168 }
2169
2170 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
2171 result = request.put_u32(DSCP_ATTRIBUTE_START, mStart);
2172 if (result < 0) {
2173 goto exit;
2174 }
2175 result = request.put_u32(DSCP_ATTRIBUTE_END, mEnd);
2176 if (result < 0) {
2177 goto exit;
2178 }
2179 result = request.put_u32(DSCP_ATTRIBUTE_AC, mAc);
2180 if (result < 0) {
2181 goto exit;
2182 }
2183 request.attr_end(data);
2184 exit:
2185 return result;
2186 }
2187
createResetDscpRequest(WifiRequest & request)2188 int createResetDscpRequest(WifiRequest& request) {
2189 int result = request.create(GOOGLE_OUI, DSCP_SUBCMD_RESET_TABLE);
2190 if (result < 0) {
2191 return result;
2192 }
2193
2194 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
2195 request.attr_end(data);
2196 return result;
2197 }
2198
start()2199 int start() {
2200 WifiRequest request(familyId(), ifaceId());
2201 int result = createRequest(request);
2202 if (result < 0) {
2203 return result;
2204 }
2205 result = requestResponse(request);
2206 if (result < 0) {
2207 ALOGI("Request Response failed for DSCP, result = %d", result);
2208 return result;
2209 }
2210 return result;
2211 }
2212
handleResponse(WifiEvent & reply)2213 int handleResponse(WifiEvent& reply) {
2214 ALOGD("In DscpCommand::handleResponse");
2215
2216 if (reply.get_cmd() != NL80211_CMD_VENDOR) {
2217 ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
2218 return NL_SKIP;
2219 }
2220
2221 nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA);
2222 int len = reply.get_vendor_data_len();
2223
2224 if (vendor_data == NULL || len == 0) {
2225 ALOGE("no vendor data in DscpCommand response; ignoring it");
2226 return NL_SKIP;
2227 }
2228 if( mReqType == SET_DSCP_TABLE) {
2229 ALOGD("Response received for Set DSCP command\n");
2230 } else if (mReqType == RESET_DSCP_TABLE) {
2231 ALOGD("Response received for Reset DSCP command\n");
2232 }
2233 return NL_OK;
2234 }
2235
handleEvent(WifiEvent & event)2236 int handleEvent(WifiEvent& event) {
2237 /* No Event to receive for DSCP commands */
2238 ALOGD("DSCP command %s\n", __FUNCTION__);
2239 return NL_SKIP;
2240 }
2241 };
2242
wifi_map_dscp_access_category(wifi_handle handle,u32 start,u32 end,u32 ac)2243 wifi_error wifi_map_dscp_access_category(wifi_handle handle,
2244 u32 start, u32 end, u32 ac)
2245 {
2246 int numIfaceHandles = 0;
2247 wifi_interface_handle *ifaceHandles = NULL;
2248 wifi_interface_handle wlan0Handle;
2249
2250 wlan0Handle = wifi_get_wlan_interface((wifi_handle)handle, ifaceHandles, numIfaceHandles);
2251
2252 DscpCommand *cmd = new DscpCommand(wlan0Handle, start, end, ac);
2253 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
2254 wifi_error result = (wifi_error)cmd->start();
2255 if (result == WIFI_SUCCESS) {
2256 ALOGI("Mapping DSCP table success\n");
2257 } else {
2258 ALOGE("Mapping DSCP table fail\n");
2259 }
2260 cmd->releaseRef();
2261 return result;
2262 }
2263
wifi_reset_dscp_mapping(wifi_handle handle)2264 wifi_error wifi_reset_dscp_mapping(wifi_handle handle)
2265 {
2266 int numIfaceHandles = 0;
2267 wifi_interface_handle *ifaceHandles = NULL;
2268 wifi_interface_handle wlan0Handle;
2269
2270 wlan0Handle = wifi_get_wlan_interface((wifi_handle)handle, ifaceHandles, numIfaceHandles);
2271
2272 DscpCommand *cmd = new DscpCommand(wlan0Handle);
2273 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
2274 wifi_error result = (wifi_error)cmd->start();
2275 if (result == WIFI_SUCCESS) {
2276 ALOGI("Resetting DSCP table success\n");
2277 } else {
2278 ALOGE("Resetting DSCP table fail\n");
2279 }
2280 cmd->releaseRef();
2281 return result;
2282 }
2283
2284 class VirtualIfaceConfig : public WifiCommand {
2285 const char *mIfname;
2286 nl80211_iftype mType;
2287 u32 mwlan0_id;
2288
2289 public:
VirtualIfaceConfig(wifi_interface_handle handle,const char * ifname,nl80211_iftype iface_type,u32 wlan0_id)2290 VirtualIfaceConfig(wifi_interface_handle handle, const char* ifname,
2291 nl80211_iftype iface_type, u32 wlan0_id)
2292 : WifiCommand("VirtualIfaceConfig", handle, 0), mIfname(ifname), mType(iface_type),
2293 mwlan0_id(wlan0_id)
2294 {
2295 mIfname = ifname;
2296 mType = iface_type;
2297 mwlan0_id = wlan0_id;
2298 }
createRequest(WifiRequest & request,const char * ifname,nl80211_iftype iface_type,u32 wlan0_id)2299 int createRequest(WifiRequest& request, const char* ifname,
2300 nl80211_iftype iface_type, u32 wlan0_id) {
2301 ALOGD("add ifname = %s, iface_type = %d, wlan0_id = %d",
2302 ifname, iface_type, wlan0_id);
2303
2304 int result = request.create(NL80211_CMD_NEW_INTERFACE);
2305 if (result < 0) {
2306 ALOGE("failed to create NL80211_CMD_NEW_INTERFACE; result = %d", result);
2307 return result;
2308 }
2309
2310 result = request.put_u32(NL80211_ATTR_IFINDEX, wlan0_id);
2311 if (result < 0) {
2312 ALOGE("failed to put NL80211_ATTR_IFINDEX; result = %d", result);
2313 return result;
2314 }
2315
2316 result = request.put_string(NL80211_ATTR_IFNAME, ifname);
2317 if (result < 0) {
2318 ALOGE("failed to put NL80211_ATTR_IFNAME = %s; result = %d", ifname, result);
2319 return result;
2320 }
2321
2322 result = request.put_u32(NL80211_ATTR_IFTYPE, iface_type);
2323 if (result < 0) {
2324 ALOGE("failed to put NL80211_ATTR_IFTYPE = %d; result = %d", iface_type, result);
2325 return result;
2326 }
2327 return WIFI_SUCCESS;
2328 }
2329
deleteRequest(WifiRequest & request,const char * ifname)2330 int deleteRequest(WifiRequest& request, const char* ifname) {
2331 ALOGD("delete ifname = %s\n", ifname);
2332 int result = request.create(NL80211_CMD_DEL_INTERFACE);
2333 if (result < 0) {
2334 ALOGE("failed to create NL80211_CMD_DEL_INTERFACE; result = %d", result);
2335 return result;
2336 }
2337 result = request.put_u32(NL80211_ATTR_IFINDEX, if_nametoindex(ifname));
2338 if (result < 0) {
2339 ALOGE("failed to put NL80211_ATTR_IFINDEX = %d; result = %d",
2340 if_nametoindex(ifname), result);
2341 return result;
2342 }
2343 result = request.put_string(NL80211_ATTR_IFNAME, ifname);
2344 if (result < 0) {
2345 ALOGE("failed to put NL80211_ATTR_IFNAME = %s; result = %d", ifname, result);
2346 return result;
2347 }
2348 return WIFI_SUCCESS;
2349 }
2350
createIface()2351 int createIface() {
2352 ALOGE("Creating virtual interface");
2353 WifiRequest request(familyId(), ifaceId());
2354 int result = createRequest(request, mIfname, mType, mwlan0_id);
2355 if (result != WIFI_SUCCESS) {
2356 ALOGE("failed to create virtual iface request; result = %d\n", result);
2357 return result;
2358 }
2359
2360 result = requestResponse(request);
2361 if (result != WIFI_SUCCESS) {
2362 ALOGE("failed to get the virtual iface create response; result = %d\n", result);
2363 return result;
2364 }
2365 ALOGE("Created virtual interface");
2366 return WIFI_SUCCESS;
2367 }
2368
deleteIface()2369 int deleteIface() {
2370 ALOGD("Deleting virtual interface");
2371 WifiRequest request(familyId(), ifaceId());
2372 int result = deleteRequest(request, mIfname);
2373 if (result != WIFI_SUCCESS) {
2374 ALOGE("failed to create virtual iface delete request; result = %d\n", result);
2375 return result;
2376 }
2377
2378 result = requestResponse(request);
2379 if (result != WIFI_SUCCESS) {
2380 ALOGE("failed to get response of delete virtual interface; result = %d\n", result);
2381 return result;
2382 }
2383 return WIFI_SUCCESS;
2384 }
2385 protected:
handleResponse(WifiEvent & reply)2386 virtual int handleResponse(WifiEvent& reply) {
2387 ALOGD("Request complete!");
2388 /* Nothing to do on response! */
2389 return NL_SKIP;
2390 }
2391 };
2392
2393 static std::vector<std::string> added_ifaces;
2394
wifi_cleanup_dynamic_ifaces(wifi_handle handle)2395 static void wifi_cleanup_dynamic_ifaces(wifi_handle handle)
2396 {
2397 int len = added_ifaces.size();
2398 while (len--) {
2399 wifi_virtual_interface_delete(handle, added_ifaces.front().c_str());
2400 }
2401 added_ifaces.clear();
2402 }
2403
wifi_virtual_interface_create(wifi_handle handle,const char * ifname,wifi_interface_type iface_type)2404 wifi_error wifi_virtual_interface_create(wifi_handle handle, const char* ifname,
2405 wifi_interface_type iface_type)
2406 {
2407 int numIfaceHandles = 0;
2408 wifi_error ret = WIFI_SUCCESS;
2409 wifi_interface_handle *ifaceHandles = NULL;
2410 wifi_interface_handle wlan0Handle;
2411 nl80211_iftype type = NL80211_IFTYPE_UNSPECIFIED;
2412 u32 wlan0_id = if_nametoindex("wlan0");
2413
2414 if (!handle || !wlan0_id) {
2415 ALOGE("%s: Error wifi_handle NULL or wlan0 not present\n", __FUNCTION__);
2416 return WIFI_ERROR_UNKNOWN;
2417 }
2418
2419 /* Do not create interface if already exist. */
2420 if (if_nametoindex(ifname)) {
2421 ALOGD("%s: if_nametoindex(%s) = %d already exists, skip create \n",
2422 __FUNCTION__, ifname, if_nametoindex(ifname));
2423 return WIFI_SUCCESS;
2424 }
2425
2426 ALOGD("%s: ifname name = %s, type = %s\n", __FUNCTION__, ifname,
2427 IfaceTypeToString(iface_type));
2428
2429 switch (iface_type) {
2430 case WIFI_INTERFACE_TYPE_STA:
2431 type = NL80211_IFTYPE_STATION;
2432 break;
2433 case WIFI_INTERFACE_TYPE_AP:
2434 type = NL80211_IFTYPE_AP;
2435 break;
2436 case WIFI_INTERFACE_TYPE_P2P:
2437 type = NL80211_IFTYPE_P2P_DEVICE;
2438 break;
2439 case WIFI_INTERFACE_TYPE_NAN:
2440 type = NL80211_IFTYPE_NAN;
2441 break;
2442 default:
2443 ALOGE("%s: Wrong interface type %u\n", __FUNCTION__, iface_type);
2444 return WIFI_ERROR_UNKNOWN;
2445 }
2446
2447 wlan0Handle = wifi_get_wlan_interface((wifi_handle)handle, ifaceHandles, numIfaceHandles);
2448 VirtualIfaceConfig command(wlan0Handle, ifname, type, wlan0_id);
2449
2450 ret = (wifi_error)command.createIface();
2451 if (ret != WIFI_SUCCESS) {
2452 ALOGE("%s: Iface add Error:%d", __FUNCTION__,ret);
2453 return ret;
2454 }
2455 /* Update dynamic interface list */
2456 added_ifaces.push_back(std::string(ifname));
2457 ret = wifi_add_iface_hal_info((wifi_handle)handle, ifname);
2458 return ret;
2459 }
2460
wifi_virtual_interface_delete(wifi_handle handle,const char * ifname)2461 wifi_error wifi_virtual_interface_delete(wifi_handle handle, const char* ifname)
2462 {
2463 int numIfaceHandles = 0;
2464 int i = 0;
2465 wifi_error ret = WIFI_SUCCESS;
2466 wifi_interface_handle *ifaceHandles = NULL;
2467 wifi_interface_handle wlan0Handle;
2468 hal_info *info = (hal_info *)handle;
2469 u32 wlan0_id = if_nametoindex("wlan0");
2470
2471 if (!handle || !wlan0_id) {
2472 ALOGE("%s: Error wifi_handle NULL or wlan0 not present\n", __FUNCTION__);
2473 return WIFI_ERROR_UNKNOWN;
2474 }
2475
2476 while (i < info->max_num_interfaces) {
2477 if (info->interfaces[i] != NULL &&
2478 strncmp(info->interfaces[i]->name,
2479 ifname, sizeof(info->interfaces[i]->name)) == 0) {
2480 if (info->interfaces[i]->is_virtual == false) {
2481 ALOGI("%s: %s is static iface, skip delete\n",
2482 __FUNCTION__, ifname);
2483 return WIFI_SUCCESS;
2484 }
2485 }
2486 i++;
2487 }
2488
2489 ALOGD("%s: iface name=%s\n", __FUNCTION__, ifname);
2490 wlan0Handle = wifi_get_wlan_interface((wifi_handle)handle, ifaceHandles, numIfaceHandles);
2491 VirtualIfaceConfig command(wlan0Handle, ifname, (nl80211_iftype)0, 0);
2492 ret = (wifi_error)command.deleteIface();
2493 if (ret != WIFI_SUCCESS) {
2494 ALOGE("%s: Iface delete Error:%d", __FUNCTION__,ret);
2495 return ret;
2496 }
2497 /* Update dynamic interface list */
2498 added_ifaces.erase(std::remove(added_ifaces.begin(), added_ifaces.end(), std::string(ifname)),
2499 added_ifaces.end());
2500 ret = wifi_clear_iface_hal_info((wifi_handle)handle, ifname);
2501 return ret;
2502 }
2503 /////////////////////////////////////////////////////////////////////////////
2504
2505 class MultiStaConfig : public WifiCommand {
2506 wifi_multi_sta_use_case mUseCase;
2507 int mReqType;
2508
2509 public:
MultiStaConfig(wifi_interface_handle handle)2510 MultiStaConfig(wifi_interface_handle handle)
2511 : WifiCommand("MultiStaConfig", handle, 0), mReqType(SET_PRIMARY_CONNECTION)
2512 {
2513 }
MultiStaConfig(wifi_interface_handle handle,wifi_multi_sta_use_case use_case)2514 MultiStaConfig(wifi_interface_handle handle, wifi_multi_sta_use_case use_case)
2515 : WifiCommand("MultiStaConfig", handle, 0), mUseCase(use_case), mReqType(SET_USE_CASE)
2516 {
2517 mUseCase = use_case;
2518 }
2519
createRequest(WifiRequest & request)2520 int createRequest(WifiRequest& request) {
2521 if (mReqType == SET_PRIMARY_CONNECTION) {
2522 ALOGI("\n%s: MultiSta set primary connection\n", __FUNCTION__);
2523 return createSetPrimaryConnectionRequest(request);
2524 } else if (mReqType == SET_USE_CASE) {
2525 ALOGI("\n%s: MultiSta set use case\n", __FUNCTION__);
2526 return createSetUsecaseRequest(request);
2527 } else {
2528 ALOGE("\n%s Unknown MultiSta request\n", __FUNCTION__);
2529 return WIFI_ERROR_NOT_SUPPORTED;
2530 }
2531 return WIFI_SUCCESS;
2532 }
2533
createSetPrimaryConnectionRequest(WifiRequest & request)2534 int createSetPrimaryConnectionRequest(WifiRequest& request) {
2535 int result = request.create(GOOGLE_OUI, WIFI_SUBCMD_SET_MULTISTA_PRIMARY_CONNECTION);
2536 if (result < 0) {
2537 return result;
2538 }
2539
2540 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
2541 request.attr_end(data);
2542
2543 return result;
2544 }
2545
createSetUsecaseRequest(WifiRequest & request)2546 int createSetUsecaseRequest(WifiRequest& request) {
2547 int result = request.create(GOOGLE_OUI, WIFI_SUBCMD_SET_MULTISTA_USE_CASE);
2548 if (result < 0) {
2549 return result;
2550 }
2551
2552 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
2553 result = request.put_u32(MULTISTA_ATTRIBUTE_USE_CASE, mUseCase);
2554 if (result < 0) {
2555 ALOGE("failed to put MULTISTA_ATTRIBUTE_USE_CASE = %d; result = %d", mUseCase, result);
2556 goto exit;
2557 }
2558
2559 exit: request.attr_end(data);
2560 return result;
2561 }
2562
start()2563 int start() {
2564 WifiRequest request(familyId(), ifaceId());
2565 int result = createRequest(request);
2566 if (result < 0) {
2567 return result;
2568 }
2569 result = requestResponse(request);
2570 if (result < 0) {
2571 ALOGI("Request Response failed for MultiSta, result = %d", result);
2572 return result;
2573 }
2574 ALOGI("Done!");
2575 return result;
2576 }
2577 protected:
handleResponse(WifiEvent & reply)2578 virtual int handleResponse(WifiEvent& reply) {
2579 ALOGD("Request complete!");
2580 /* Nothing to do on response! */
2581 return NL_SKIP;
2582 }
2583 };
2584
wifi_multi_sta_set_primary_connection(wifi_handle handle,wifi_interface_handle iface)2585 wifi_error wifi_multi_sta_set_primary_connection(wifi_handle handle, wifi_interface_handle iface)
2586 {
2587 wifi_error ret = WIFI_SUCCESS;
2588 char buf[IFNAMSIZ];
2589
2590 if (!handle || !iface) {
2591 ALOGE("%s: Error wifi_handle NULL or invalid wifi interface handle\n", __FUNCTION__);
2592 return WIFI_ERROR_UNKNOWN;
2593 }
2594
2595 if (wifi_get_iface_name(iface, buf, sizeof(buf)) != WIFI_SUCCESS) {
2596 ALOGE("%s : Invalid interface handle\n", __func__);
2597 return WIFI_ERROR_INVALID_ARGS;
2598 }
2599
2600 ALOGD("Setting Multista primary connection for iface = %s\n", buf);
2601
2602 MultiStaConfig *cmd = new MultiStaConfig(iface);
2603 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
2604 ret = (wifi_error)cmd->start();
2605 cmd->releaseRef();
2606 return ret;
2607 }
2608
wifi_multi_sta_set_use_case(wifi_handle handle,wifi_multi_sta_use_case use_case)2609 wifi_error wifi_multi_sta_set_use_case(wifi_handle handle, wifi_multi_sta_use_case use_case)
2610 {
2611 int numIfaceHandles = 0;
2612 wifi_error ret = WIFI_SUCCESS;
2613 wifi_interface_handle *ifaceHandles = NULL;
2614 wifi_interface_handle wlan0Handle;
2615
2616 if (!handle) {
2617 ALOGE("%s: Error wifi_handle NULL\n", __FUNCTION__);
2618 return WIFI_ERROR_UNKNOWN;
2619 }
2620
2621 if (!(use_case >= WIFI_DUAL_STA_TRANSIENT_PREFER_PRIMARY &&
2622 use_case <= WIFI_DUAL_STA_NON_TRANSIENT_UNBIASED)) {
2623 ALOGE("%s: Invalid multi_sta usecase %d\n", __FUNCTION__, use_case);
2624 return WIFI_ERROR_INVALID_ARGS;
2625 }
2626
2627 wlan0Handle = wifi_get_wlan_interface((wifi_handle)handle, ifaceHandles, numIfaceHandles);
2628 ALOGD("Setting Multista usecase = %d\n", use_case);
2629 MultiStaConfig *cmd = new MultiStaConfig(wlan0Handle, use_case);
2630 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
2631 ret = (wifi_error)cmd->start();
2632 cmd->releaseRef();
2633 return ret;
2634 }
2635 /////////////////////////////////////////////////////////////////////////////////////////////////
2636
2637 class SetVoipModeCommand : public WifiCommand {
2638
2639 private:
2640 wifi_voip_mode mMode;
2641 public:
SetVoipModeCommand(wifi_interface_handle handle,wifi_voip_mode mode)2642 SetVoipModeCommand(wifi_interface_handle handle, wifi_voip_mode mode)
2643 : WifiCommand("SetVoipModeCommand", handle, 0) {
2644 mMode = mode;
2645 }
create()2646 virtual int create() {
2647 int ret;
2648
2649 ret = mMsg.create(GOOGLE_OUI, WIFI_SUBCMD_CONFIG_VOIP_MODE);
2650 if (ret < 0) {
2651 ALOGE("Can't create message to send to driver - %d", ret);
2652 return ret;
2653 }
2654
2655 nlattr *data = mMsg.attr_start(NL80211_ATTR_VENDOR_DATA);
2656 ret = mMsg.put_u32(ANDR_WIFI_ATTRIBUTE_VOIP_MODE, mMode);
2657 ALOGE("mMode - %d", mMode);
2658 if (ret < 0) {
2659 ALOGE("Failed to set voip mode %d\n", mMode);
2660 return ret;
2661 }
2662
2663 ALOGI("Successfully configured voip mode %d\n", mMode);
2664 mMsg.attr_end(data);
2665 return WIFI_SUCCESS;
2666 }
2667 };
2668
wifi_set_voip_mode(wifi_interface_handle handle,wifi_voip_mode mode)2669 wifi_error wifi_set_voip_mode(wifi_interface_handle handle, wifi_voip_mode mode)
2670 {
2671 ALOGD("Setting VOIP mode, halHandle = %p Mode = %d\n", handle, mode);
2672 SetVoipModeCommand command(handle, mode);
2673 return (wifi_error) command.requestResponse();
2674 }
2675
2676 /////////////////////////////////////////////////////////////////////////////////////////////////
2677 class SetDtimConfigCommand : public WifiCommand {
2678
2679 private:
2680 uint32_t multiplier;
2681 public:
SetDtimConfigCommand(wifi_interface_handle handle,u32 dtim_multiplier)2682 SetDtimConfigCommand(wifi_interface_handle handle, u32 dtim_multiplier)
2683 : WifiCommand("SetDtimConfigCommand", handle, 0) {
2684 multiplier = dtim_multiplier;
2685 }
create()2686 virtual int create() {
2687 int ret;
2688
2689 ret = mMsg.create(GOOGLE_OUI, WIFI_SUBCMD_SET_DTIM_CONFIG);
2690 if (ret < 0) {
2691 ALOGE("Can't create message to send to driver - %d", ret);
2692 return ret;
2693 }
2694
2695 nlattr *data = mMsg.attr_start(NL80211_ATTR_VENDOR_DATA);
2696 ret = mMsg.put_u32(ANDR_WIFI_ATTRIBUTE_DTIM_MULTIPLIER, multiplier);
2697 if (ret < 0) {
2698 ALOGE("Failed to set dtim mutiplier %d\n", multiplier);
2699 return ret;
2700 }
2701
2702 ALOGI("Successfully configured dtim multiplier %d\n", multiplier);
2703 mMsg.attr_end(data);
2704 return WIFI_SUCCESS;
2705 }
2706 };
2707
wifi_set_dtim_config(wifi_interface_handle handle,u32 multiplier)2708 wifi_error wifi_set_dtim_config(wifi_interface_handle handle, u32 multiplier)
2709 {
2710 ALOGD("Setting DTIM config , halHandle = %p Multiplier = %d\n", handle, multiplier);
2711 SetDtimConfigCommand command(handle, multiplier);
2712 return (wifi_error) command.requestResponse();
2713 }
2714
2715 /////////////////////////////////////////////////////////////////////////////////////////////////
2716 class UsableChannelCommand : public WifiCommand {
2717
2718 private:
2719 u32 mBandMask;
2720 u32 mIfaceModeMask;
2721 u32 mFilterMask;
2722 u32 mMaxSize;
2723 u32* mSize;
2724 wifi_usable_channel* mChannels;
2725
2726 public:
UsableChannelCommand(wifi_interface_handle handle,u32 band_mask,u32 iface_mode_mask,u32 filter_mask,u32 max_size,u32 * size,wifi_usable_channel * channels)2727 UsableChannelCommand(wifi_interface_handle handle, u32 band_mask, u32 iface_mode_mask,
2728 u32 filter_mask, u32 max_size, u32* size, wifi_usable_channel* channels)
2729 : WifiCommand("UsableChannelCommand", handle, 0),
2730 mBandMask(band_mask), mIfaceModeMask(iface_mode_mask),
2731 mFilterMask(filter_mask), mMaxSize(max_size),
2732 mSize(size), mChannels(channels)
2733 {
2734 }
2735
createRequest(WifiRequest & request)2736 int createRequest(WifiRequest& request) {
2737 createUsableChannelRequest(request);
2738 return WIFI_SUCCESS;
2739 }
2740
createUsableChannelRequest(WifiRequest & request)2741 int createUsableChannelRequest(WifiRequest& request) {
2742 int result = request.create(GOOGLE_OUI, WIFI_SUBCMD_USABLE_CHANNEL);
2743 if (result < 0) {
2744 ALOGE("Failed to create UsableChannel request; result = %d", result);
2745 return result;
2746 }
2747
2748 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
2749
2750 result = request.put_u32(USABLECHAN_ATTRIBUTE_BAND, mBandMask);
2751 if (result != WIFI_SUCCESS) {
2752 ALOGE("Failed to put log level; result = %d", result);
2753 return result;
2754 }
2755 result = request.put_u32(USABLECHAN_ATTRIBUTE_IFACE, mIfaceModeMask);
2756 if (result != WIFI_SUCCESS) {
2757 ALOGE("Failed to put ring flags; result = %d", result);
2758 return result;
2759 }
2760 result = request.put_u32(USABLECHAN_ATTRIBUTE_FILTER, mFilterMask);
2761 if (result != WIFI_SUCCESS) {
2762 ALOGE("Failed to put usablechan filter; result = %d", result);
2763 return result;
2764 }
2765 result = request.put_u32(USABLECHAN_ATTRIBUTE_MAX_SIZE, mMaxSize);
2766 if (result != WIFI_SUCCESS) {
2767 ALOGE("Failed to put usablechan max_size; result = %d", result);
2768 return result;
2769 }
2770 request.attr_end(data);
2771
2772 return WIFI_SUCCESS;
2773 }
2774
start()2775 int start() {
2776 WifiRequest request(familyId(), ifaceId());
2777 int result = createRequest(request);
2778 if (result != WIFI_SUCCESS) {
2779 ALOGE("failed to create request; result = %d", result);
2780 return result;
2781 }
2782
2783 result = requestResponse(request);
2784 if (result != WIFI_SUCCESS) {
2785 ALOGE("failed to set scanning mac OUI; result = %d", result);
2786 }
2787
2788 return result;
2789 }
2790
handleResponse(WifiEvent & reply)2791 virtual int handleResponse(WifiEvent& reply) {
2792 ALOGD("In DebugCommand::handleResponse");
2793
2794 if (reply.get_cmd() != NL80211_CMD_VENDOR) {
2795 ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
2796 return NL_SKIP;
2797 }
2798
2799 nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA);
2800 int len = reply.get_vendor_data_len();
2801 wifi_usable_channel *channels(mChannels);
2802
2803 if (vendor_data == NULL || len == 0) {
2804 ALOGE("No Debug data found");
2805 return NL_SKIP;
2806 }
2807
2808 nl_iterator it(vendor_data);
2809 if (it.get_type() == USABLECHAN_ATTRIBUTE_SIZE) {
2810 *mSize = it.get_u32();
2811 } else {
2812 ALOGE("Unknown attribute: %d expecting %d",
2813 it.get_type(), USABLECHAN_ATTRIBUTE_SIZE);
2814 return NL_SKIP;
2815 }
2816
2817 it.next();
2818 if (it.get_type() == USABLECHAN_ATTRIBUTE_CHANNELS) {
2819 memcpy(channels, it.get_data(), sizeof(wifi_usable_channel) * *mSize);
2820 } else {
2821 ALOGE("Unknown attribute: %d expecting %d",
2822 it.get_type(), USABLECHAN_ATTRIBUTE_SIZE);
2823 return NL_SKIP;
2824 }
2825
2826 return NL_OK;
2827 }
2828
handleEvent(WifiEvent & event)2829 virtual int handleEvent(WifiEvent& event) {
2830 /* NO events! */
2831 return NL_SKIP;
2832 }
2833 };
2834
wifi_get_usable_channels(wifi_handle handle,u32 band_mask,u32 iface_mode_mask,u32 filter_mask,u32 max_size,u32 * size,wifi_usable_channel * channels)2835 wifi_error wifi_get_usable_channels(wifi_handle handle, u32 band_mask, u32 iface_mode_mask,
2836 u32 filter_mask, u32 max_size, u32* size, wifi_usable_channel* channels)
2837 {
2838 int numIfaceHandles = 0;
2839 wifi_interface_handle *ifaceHandles = NULL;
2840 wifi_interface_handle wlan0Handle;
2841
2842 wlan0Handle = wifi_get_wlan_interface((wifi_handle)handle, ifaceHandles, numIfaceHandles);
2843 UsableChannelCommand command(wlan0Handle, band_mask, iface_mode_mask,
2844 filter_mask, max_size, size, channels);
2845 return (wifi_error)command.start();
2846 }
2847