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