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