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