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 close(info->cleanup_socks[1]);
630 nl_socket_free(info->cmd_sock);
631 nl_socket_free(info->event_sock);
632 info->cmd_sock = NULL;
633 info->event_sock = NULL;
634 }
635
636 if (info->interfaces) {
637 for (int i = 0; i < info->num_interfaces; i++) {
638 free(info->interfaces[i]);
639 }
640 free(info->interfaces);
641 }
642
643 DestroyResponseLock();
644 pthread_mutex_destroy(&info->cb_lock);
645 free(info);
646
647 ALOGI("Internal cleanup completed");
648 }
649
wifi_internal_module_cleanup()650 void wifi_internal_module_cleanup()
651 {
652 nan_deinit_handler();
653 twt_deinit_handler();
654 }
655
wifi_cleanup(wifi_handle handle,wifi_cleaned_up_handler cleaned_up_handler)656 void wifi_cleanup(wifi_handle handle, wifi_cleaned_up_handler cleaned_up_handler)
657 {
658 if (!handle) {
659 ALOGE("Handle is null");
660 return;
661 }
662
663 hal_info *info = getHalInfo(handle);
664 wifi_error result;
665
666 int numIfaceHandles = 0;
667 wifi_interface_handle *ifaceHandles = NULL;
668 wifi_interface_handle wlan0Handle;
669
670 wlan0Handle = wifi_get_wlan_interface((wifi_handle) info, ifaceHandles, numIfaceHandles);
671
672 if (wlan0Handle != NULL) {
673 ALOGE("Calling hal cleanup");
674 if (!get_halutil_mode()) {
675 wifi_cleanup_dynamic_ifaces(handle);
676 ALOGI("Cleaned dynamic virtual ifaces\n");
677 result = wifi_stop_hal(wlan0Handle);
678 if (result != WIFI_SUCCESS) {
679 ALOGE("wifi_stop_hal failed");
680 }
681 ALOGI("wifi_stop_hal success");
682 }
683
684 } else {
685 ALOGE("Not cleaning up hal as global_iface is NULL");
686 }
687
688 /* calling internal modules or cleanup */
689 wifi_internal_module_cleanup();
690 pthread_mutex_lock(&info->cb_lock);
691
692 int bad_commands = 0;
693
694 ALOGI("event_cb callbacks left: %d ", info->num_event_cb);
695 for (int i = 0; i < info->num_event_cb; i++) {
696 ALOGI("event_cb cleanup. index:%d", i);
697 cb_info *cbi = &(info->event_cb[i]);
698 if (!cbi) {
699 ALOGE("cbi null for index %d", i);
700 continue;
701 }
702 ALOGI("event_cb cleanup. vendor cmd:%d sub_cmd:%d", cbi->vendor_id, cbi->vendor_subcmd);
703 WifiCommand *cmd = (WifiCommand *)cbi->cb_arg;
704 if (cmd != NULL) {
705 ALOGI("Command left in event_cb %p", cmd);
706 }
707 }
708
709 ALOGI("Check bad commands: num_cmd:%d bad_commands:%d", info->num_cmd, bad_commands);
710 while (info->num_cmd > bad_commands) {
711 int num_cmd = info->num_cmd;
712 cmd_info *cmdi = &(info->cmd[bad_commands]);
713 WifiCommand *cmd = cmdi->cmd;
714 if (cmd != NULL) {
715 ALOGI("Cancelling command %p: %s", cmd, cmd->getType());
716 pthread_mutex_unlock(&info->cb_lock);
717 cmd->cancel();
718 if (num_cmd == info->num_cmd) {
719 ALOGI("Cancelling command %p: %s did not work",
720 cmd, (cmd ? cmd->getType(): ""));
721 bad_commands++;
722 }
723 /* release reference added when command is saved */
724 cmd->releaseRef();
725 pthread_mutex_lock(&info->cb_lock);
726 }
727 }
728
729 for (int i = 0; i < info->num_event_cb; i++) {
730 cb_info *cbi = &(info->event_cb[i]);
731 if (!cbi) {
732 ALOGE("cbi null for index %d", i);
733 continue;
734 }
735 WifiCommand *cmd = (WifiCommand *)cbi->cb_arg;
736 ALOGE("Leaked command %p", cmd);
737 }
738 pthread_mutex_unlock(&info->cb_lock);
739
740 info->clean_up = true;
741
742 /* global func ptr be invalidated and will not call any command from legacy hal */
743 if (cleaned_up_handler) {
744 ALOGI("cleaned_up_handler to invalidates func ptr");
745 cleaned_up_handler(handle);
746 } else {
747 ALOGI("cleaned up handler is null");
748 }
749
750 if (TEMP_FAILURE_RETRY(write(info->cleanup_socks[0], "Exit", 4)) < 1) {
751 // As a fallback set the cleanup flag to TRUE
752 ALOGE("could not write to the cleanup socket");
753 }
754 ALOGE("wifi_clean_up done");
755 }
756
internal_pollin_handler(wifi_handle handle)757 static int internal_pollin_handler(wifi_handle handle)
758 {
759 hal_info *info = getHalInfo(handle);
760 struct nl_cb *cb = nl_socket_get_cb(info->event_sock);
761 int res = nl_recvmsgs(info->event_sock, cb);
762 if (res) {
763 ALOGE("nl_recvmsgs returned %d", res);
764 }
765 nl_cb_put(cb);
766 return res;
767 }
768
769 /* Run event handler */
wifi_event_loop(wifi_handle handle)770 void wifi_event_loop(wifi_handle handle)
771 {
772 hal_info *info = getHalInfo(handle);
773 if (info->in_event_loop) {
774 return;
775 } else {
776 info->in_event_loop = true;
777 }
778
779 pollfd pfd[2];
780 memset(&pfd[0], 0, sizeof(pollfd) * 2);
781
782 pfd[0].fd = nl_socket_get_fd(info->event_sock);
783 pfd[0].events = POLLIN;
784 pfd[1].fd = info->cleanup_socks[1];
785 pfd[1].events = POLLIN;
786
787 char buf[2048];
788 /* TODO: Add support for timeouts */
789
790 do {
791 int timeout = -1; /* Infinite timeout */
792 pfd[0].revents = 0;
793 pfd[1].revents = 0;
794 // ALOGI("Polling socket");
795 int result = TEMP_FAILURE_RETRY(poll(pfd, 2, timeout));
796 if (result < 0) {
797 // ALOGE("Error polling socket");
798 } else if (pfd[0].revents & POLLERR) {
799 ALOGE("POLL Error; error no = %d (%s)", errno, strerror(errno));
800 ssize_t result2 = TEMP_FAILURE_RETRY(read(pfd[0].fd, buf, sizeof(buf)));
801 ALOGE("Read after POLL returned %zd, error no = %d (%s)", result2,
802 errno, strerror(errno));
803 if (errno == WIFI_HAL_EVENT_BUFFER_NOT_AVAILABLE) {
804 ALOGE("Exit, No buffer space");
805 break;
806 }
807 } else if (pfd[0].revents & POLLHUP) {
808 ALOGE("Remote side hung up");
809 break;
810 } else if (pfd[0].revents & POLLIN && !info->clean_up) {
811 // ALOGI("Found some events!!!");
812 internal_pollin_handler(handle);
813 } else if (pfd[1].revents & POLLIN) {
814 ALOGI("Got a signal to exit!!!");
815 } else {
816 ALOGE("Unknown event - %0x, %0x", pfd[0].revents, pfd[1].revents);
817 }
818 } while (!info->clean_up);
819
820 internal_cleaned_up_handler(handle);
821 ALOGE("Exit %s", __FUNCTION__);
822 }
823
824 ///////////////////////////////////////////////////////////////////////////////////////
825
internal_no_seq_check(struct nl_msg * msg,void * arg)826 static int internal_no_seq_check(struct nl_msg *msg, void *arg)
827 {
828 return NL_OK;
829 }
830
internal_valid_message_handler(nl_msg * msg,void * arg)831 static int internal_valid_message_handler(nl_msg *msg, void *arg)
832 {
833 // ALOGI("got an event");
834
835 wifi_handle handle = (wifi_handle)arg;
836 hal_info *info = getHalInfo(handle);
837
838 WifiEvent event(msg);
839 int res = event.parse();
840 if (res < 0) {
841 ALOGE("Failed to parse event: %d", res);
842 return NL_SKIP;
843 }
844
845 int cmd = event.get_cmd();
846 uint32_t vendor_id = 0;
847 int subcmd = 0;
848
849 if (cmd == NL80211_CMD_VENDOR) {
850 vendor_id = event.get_u32(NL80211_ATTR_VENDOR_ID);
851 subcmd = event.get_u32(NL80211_ATTR_VENDOR_SUBCMD);
852 ALOGV("event received %s, vendor_id = 0x%0x, subcmd = 0x%0x",
853 event.get_cmdString(), vendor_id, subcmd);
854 } else {
855 // ALOGV("event received %s", event.get_cmdString());
856 }
857
858 // ALOGV("event received %s, vendor_id = 0x%0x", event.get_cmdString(), vendor_id);
859 // event.log();
860
861 pthread_mutex_lock(&info->cb_lock);
862
863 for (int i = 0; i < info->num_event_cb; i++) {
864 if (cmd == info->event_cb[i].nl_cmd) {
865 if (cmd == NL80211_CMD_VENDOR
866 && ((vendor_id != info->event_cb[i].vendor_id)
867 || (subcmd != info->event_cb[i].vendor_subcmd)))
868 {
869 /* event for a different vendor, ignore it */
870 continue;
871 }
872
873 cb_info *cbi = &(info->event_cb[i]);
874 nl_recvmsg_msg_cb_t cb_func = cbi->cb_func;
875 void *cb_arg = cbi->cb_arg;
876 WifiCommand *cmd = (WifiCommand *)cbi->cb_arg;
877 if (cmd != NULL) {
878 cmd->addRef();
879 }
880 pthread_mutex_unlock(&info->cb_lock);
881 if (cb_func)
882 (*cb_func)(msg, cb_arg);
883 if (cmd != NULL) {
884 cmd->releaseRef();
885 }
886
887 return NL_OK;
888 }
889 }
890
891 pthread_mutex_unlock(&info->cb_lock);
892 return NL_OK;
893 }
894
895 ///////////////////////////////////////////////////////////////////////////////////////
896
897 class GetMulticastIdCommand : public WifiCommand
898 {
899 private:
900 const char *mName;
901 const char *mGroup;
902 int mId;
903 public:
GetMulticastIdCommand(wifi_handle handle,const char * name,const char * group)904 GetMulticastIdCommand(wifi_handle handle, const char *name, const char *group)
905 : WifiCommand("GetMulticastIdCommand", handle, 0)
906 {
907 mName = name;
908 mGroup = group;
909 mId = -1;
910 }
911
getId()912 int getId() {
913 return mId;
914 }
915
create()916 virtual int create() {
917 int nlctrlFamily = genl_ctrl_resolve(mInfo->cmd_sock, "nlctrl");
918 // ALOGI("ctrl family = %d", nlctrlFamily);
919 int ret = mMsg.create(nlctrlFamily, CTRL_CMD_GETFAMILY, 0, 0);
920 if (ret < 0) {
921 return ret;
922 }
923 ret = mMsg.put_string(CTRL_ATTR_FAMILY_NAME, mName);
924 return ret;
925 }
926
handleResponse(WifiEvent & reply)927 virtual int handleResponse(WifiEvent& reply) {
928
929 // ALOGI("handling reponse in %s", __func__);
930
931 struct nlattr **tb = reply.attributes();
932 struct nlattr *mcgrp = NULL;
933 int i;
934
935 if (!tb[CTRL_ATTR_MCAST_GROUPS]) {
936 ALOGI("No multicast groups found");
937 return NL_SKIP;
938 } else {
939 // ALOGI("Multicast groups attr size = %d", nla_len(tb[CTRL_ATTR_MCAST_GROUPS]));
940 }
941
942 for_each_attr(mcgrp, tb[CTRL_ATTR_MCAST_GROUPS], i) {
943
944 // ALOGI("Processing group");
945 struct nlattr *tb2[CTRL_ATTR_MCAST_GRP_MAX + 1];
946 nla_parse(tb2, CTRL_ATTR_MCAST_GRP_MAX, (nlattr *)nla_data(mcgrp),
947 nla_len(mcgrp), NULL);
948 if (!tb2[CTRL_ATTR_MCAST_GRP_NAME] || !tb2[CTRL_ATTR_MCAST_GRP_ID]) {
949 continue;
950 }
951
952 char *grpName = (char *)nla_data(tb2[CTRL_ATTR_MCAST_GRP_NAME]);
953 int grpNameLen = nla_len(tb2[CTRL_ATTR_MCAST_GRP_NAME]);
954
955 // ALOGI("Found group name %s", grpName);
956
957 if (strncmp(grpName, mGroup, grpNameLen) != 0)
958 continue;
959
960 mId = nla_get_u32(tb2[CTRL_ATTR_MCAST_GRP_ID]);
961 break;
962 }
963
964 return NL_SKIP;
965 }
966
967 };
968
969 class SetPnoMacAddrOuiCommand : public WifiCommand {
970
971 private:
972 byte *mOui;
973 feature_set *fset;
974 feature_set *feature_matrix;
975 int *fm_size;
976 int set_size_max;
977 public:
SetPnoMacAddrOuiCommand(wifi_interface_handle handle,oui scan_oui)978 SetPnoMacAddrOuiCommand(wifi_interface_handle handle, oui scan_oui)
979 : WifiCommand("SetPnoMacAddrOuiCommand", handle, 0)
980 {
981 mOui = scan_oui;
982 fset = NULL;
983 feature_matrix = NULL;
984 fm_size = NULL;
985 set_size_max = 0;
986 }
987
createRequest(WifiRequest & request,int subcmd,byte * scan_oui)988 int createRequest(WifiRequest& request, int subcmd, byte *scan_oui) {
989 int result = request.create(GOOGLE_OUI, subcmd);
990 if (result < 0) {
991 return result;
992 }
993
994 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
995 result = request.put(ANDR_WIFI_ATTRIBUTE_PNO_RANDOM_MAC_OUI, scan_oui, DOT11_OUI_LEN);
996 if (result < 0) {
997 return result;
998 }
999
1000 request.attr_end(data);
1001 return WIFI_SUCCESS;
1002
1003 }
1004
start()1005 int start() {
1006 ALOGD("Sending mac address OUI");
1007 WifiRequest request(familyId(), ifaceId());
1008 int result = createRequest(request, WIFI_SUBCMD_SET_PNO_RANDOM_MAC_OUI, mOui);
1009 if (result != WIFI_SUCCESS) {
1010 ALOGE("failed to create request; result = %d", result);
1011 return result;
1012 }
1013
1014 result = requestResponse(request);
1015 if (result != WIFI_SUCCESS) {
1016 ALOGE("failed to set scanning mac OUI; result = %d", result);
1017 }
1018
1019 return result;
1020 }
1021 protected:
handleResponse(WifiEvent & reply)1022 virtual int handleResponse(WifiEvent& reply) {
1023 ALOGD("Request complete!");
1024 /* Nothing to do on response! */
1025 return NL_SKIP;
1026 }
1027 };
1028
1029 class SetNodfsCommand : public WifiCommand {
1030
1031 private:
1032 u32 mNoDfs;
1033 public:
SetNodfsCommand(wifi_interface_handle handle,u32 nodfs)1034 SetNodfsCommand(wifi_interface_handle handle, u32 nodfs)
1035 : WifiCommand("SetNodfsCommand", handle, 0) {
1036 mNoDfs = nodfs;
1037 }
create()1038 virtual int create() {
1039 int ret;
1040
1041 ret = mMsg.create(GOOGLE_OUI, WIFI_SUBCMD_NODFS_SET);
1042 if (ret < 0) {
1043 ALOGE("Can't create message to send to driver - %d", ret);
1044 return ret;
1045 }
1046
1047 nlattr *data = mMsg.attr_start(NL80211_ATTR_VENDOR_DATA);
1048 ret = mMsg.put_u32(ANDR_WIFI_ATTRIBUTE_NODFS_SET, mNoDfs);
1049 if (ret < 0) {
1050 return ret;
1051 }
1052
1053 mMsg.attr_end(data);
1054 return WIFI_SUCCESS;
1055 }
1056 };
1057
1058 class SetCountryCodeCommand : public WifiCommand {
1059 private:
1060 const char *mCountryCode;
1061 public:
SetCountryCodeCommand(wifi_interface_handle handle,const char * country_code)1062 SetCountryCodeCommand(wifi_interface_handle handle, const char *country_code)
1063 : WifiCommand("SetCountryCodeCommand", handle, 0) {
1064 mCountryCode = country_code;
1065 }
create()1066 virtual int create() {
1067 int ret;
1068
1069 ret = mMsg.create(GOOGLE_OUI, WIFI_SUBCMD_SET_COUNTRY_CODE);
1070 if (ret < 0) {
1071 ALOGE("Can't create message to send to driver - %d", ret);
1072 return ret;
1073 }
1074
1075 nlattr *data = mMsg.attr_start(NL80211_ATTR_VENDOR_DATA);
1076 ret = mMsg.put_string(ANDR_WIFI_ATTRIBUTE_COUNTRY, mCountryCode);
1077 if (ret < 0) {
1078 return ret;
1079 }
1080
1081 mMsg.attr_end(data);
1082 return WIFI_SUCCESS;
1083
1084 }
1085 };
1086
1087 class SetRSSIMonitorCommand : public WifiCommand {
1088 private:
1089 s8 mMax_rssi;
1090 s8 mMin_rssi;
1091 wifi_rssi_event_handler mHandler;
1092 public:
SetRSSIMonitorCommand(wifi_request_id id,wifi_interface_handle handle,s8 max_rssi,s8 min_rssi,wifi_rssi_event_handler eh)1093 SetRSSIMonitorCommand(wifi_request_id id, wifi_interface_handle handle,
1094 s8 max_rssi, s8 min_rssi, wifi_rssi_event_handler eh)
1095 : WifiCommand("SetRSSIMonitorCommand", handle, id), mMax_rssi(max_rssi), mMin_rssi
1096 (min_rssi), mHandler(eh)
1097 {
1098 ALOGI("SetRSSIMonitorCommand %p created", this);
1099 }
1100
~SetRSSIMonitorCommand()1101 virtual ~SetRSSIMonitorCommand() {
1102 /*
1103 * Mostly, this call will be no effect. However, this could be valid
1104 * when object destroy without calling unregisterVendorHandler().
1105 * This is added to protect hal crash due to use-after-free.
1106 */
1107 ALOGI("Try to remove event handler if exist, vendor 0x%0x, subcmd 0x%x",
1108 GOOGLE_OUI, GOOGLE_RSSI_MONITOR_EVENT);
1109 unregisterVendorHandler(GOOGLE_OUI, GOOGLE_RSSI_MONITOR_EVENT);
1110 ALOGI("SetRSSIMonitorCommand %p destroyed", this);
1111 }
1112
addRef()1113 virtual void addRef() {
1114 int refs = __sync_add_and_fetch(&mRefs, 1);
1115 ALOGI("addRef: WifiCommand %p has %d references", this, refs);
1116 }
1117
releaseRef()1118 virtual void releaseRef() {
1119 int refs = __sync_sub_and_fetch(&mRefs, 1);
1120 if (refs == 0) {
1121 ALOGI("releaseRef: WifiCommand %p has deleted", this);
1122 delete this;
1123 } else {
1124 ALOGI("releaseRef: WifiCommand %p has %d references", this, refs);
1125 }
1126 }
1127
createRequest(WifiRequest & request,int enable)1128 int createRequest(WifiRequest& request, int enable) {
1129 int result = request.create(GOOGLE_OUI, WIFI_SUBCMD_SET_RSSI_MONITOR);
1130 if (result < 0) {
1131 return result;
1132 }
1133
1134 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
1135 result = request.put_u32(RSSI_MONITOR_ATTRIBUTE_MAX_RSSI, (enable ? mMax_rssi: 0));
1136 if (result < 0) {
1137 return result;
1138 }
1139 ALOGD("create request");
1140 result = request.put_u32(RSSI_MONITOR_ATTRIBUTE_MIN_RSSI, (enable? mMin_rssi: 0));
1141 if (result < 0) {
1142 return result;
1143 }
1144 result = request.put_u32(RSSI_MONITOR_ATTRIBUTE_START, enable);
1145 if (result < 0) {
1146 return result;
1147 }
1148 request.attr_end(data);
1149 return result;
1150 }
1151
start()1152 int start() {
1153 WifiRequest request(familyId(), ifaceId());
1154 int result = createRequest(request, 1);
1155 if (result != WIFI_SUCCESS) {
1156 ALOGE("Failed to create request; result = %d", result);
1157 return result;
1158 }
1159
1160 registerVendorHandler(GOOGLE_OUI, GOOGLE_RSSI_MONITOR_EVENT);
1161 ALOGI("Register GOOGLE_RSSI_MONITOR_EVENT handler");
1162
1163 result = requestResponse(request);
1164 if (result != WIFI_SUCCESS) {
1165 unregisterVendorHandler(GOOGLE_OUI, GOOGLE_RSSI_MONITOR_EVENT);
1166 ALOGE("Failed to set RSSI Monitor, result = %d", result);
1167 return result;
1168 }
1169
1170 ALOGI("Successfully set RSSI monitoring");
1171 return result;
1172 }
1173
cancel()1174 virtual int cancel() {
1175 unregisterVendorHandler(GOOGLE_OUI, GOOGLE_RSSI_MONITOR_EVENT);
1176
1177 WifiRequest request(familyId(), ifaceId());
1178 int result = createRequest(request, 0);
1179 if (result != WIFI_SUCCESS) {
1180 ALOGE("failed to create request; result = %d", result);
1181 } else {
1182 result = requestResponse(request);
1183 if (result != WIFI_SUCCESS) {
1184 ALOGE("failed to stop RSSI monitoring = %d", result);
1185 }
1186 }
1187 return WIFI_SUCCESS;
1188 }
1189
handleResponse(WifiEvent & reply)1190 virtual int handleResponse(WifiEvent& reply) {
1191 /* Nothing to do on response! */
1192 return NL_SKIP;
1193 }
1194
handleEvent(WifiEvent & event)1195 virtual int handleEvent(WifiEvent& event) {
1196 ALOGI("Got a RSSI monitor event");
1197
1198 nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA);
1199 int len = event.get_vendor_data_len();
1200
1201 if (vendor_data == NULL || len == 0) {
1202 ALOGI("RSSI monitor: No data");
1203 return NL_SKIP;
1204 }
1205 /* driver<->HAL event structure */
1206 #define RSSI_MONITOR_EVT_VERSION 1
1207 typedef struct {
1208 u8 version;
1209 s8 cur_rssi;
1210 mac_addr BSSID;
1211 } rssi_monitor_evt;
1212
1213 rssi_monitor_evt *data = (rssi_monitor_evt *)event.get_vendor_data();
1214
1215 if (data->version != RSSI_MONITOR_EVT_VERSION) {
1216 ALOGI("Event version mismatch %d, expected %d", data->version, RSSI_MONITOR_EVT_VERSION);
1217 return NL_SKIP;
1218 }
1219
1220 if (*mHandler.on_rssi_threshold_breached) {
1221 (*mHandler.on_rssi_threshold_breached)(id(), data->BSSID, data->cur_rssi);
1222 } else {
1223 ALOGW("No RSSI monitor handler registered");
1224 }
1225
1226 return NL_SKIP;
1227 }
1228
1229 };
1230
1231 class AndroidPktFilterCommand : public WifiCommand {
1232 private:
1233 const u8* mProgram;
1234 u8* mReadProgram;
1235 u32 mProgramLen;
1236 u32* mVersion;
1237 u32* mMaxLen;
1238 int mReqType;
1239 public:
AndroidPktFilterCommand(wifi_interface_handle handle,u32 * version,u32 * max_len)1240 AndroidPktFilterCommand(wifi_interface_handle handle,
1241 u32* version, u32* max_len)
1242 : WifiCommand("AndroidPktFilterCommand", handle, 0),
1243 mVersion(version), mMaxLen(max_len),
1244 mReqType(GET_APF_CAPABILITIES)
1245 {
1246 mProgram = NULL;
1247 mProgramLen = 0;
1248 mReadProgram = NULL;
1249 }
1250
AndroidPktFilterCommand(wifi_interface_handle handle,const u8 * program,u32 len)1251 AndroidPktFilterCommand(wifi_interface_handle handle,
1252 const u8* program, u32 len)
1253 : WifiCommand("AndroidPktFilterCommand", handle, 0),
1254 mProgram(program), mProgramLen(len),
1255 mReqType(SET_APF_PROGRAM)
1256 {
1257 mVersion = NULL;
1258 mMaxLen = NULL;
1259 mReadProgram = NULL;
1260 }
1261
AndroidPktFilterCommand(wifi_interface_handle handle,u8 * host_dst,u32 length)1262 AndroidPktFilterCommand(wifi_interface_handle handle,
1263 u8* host_dst, u32 length)
1264 : WifiCommand("AndroidPktFilterCommand", handle, 0),
1265 mReadProgram(host_dst), mProgramLen(length),
1266 mReqType(READ_APF_PROGRAM)
1267 {
1268 mProgram = NULL;
1269 mVersion = NULL;
1270 mMaxLen = NULL;
1271 }
1272
createRequest(WifiRequest & request)1273 int createRequest(WifiRequest& request) {
1274 if (mReqType == SET_APF_PROGRAM) {
1275 ALOGI("%s: APF set program request\n", __FUNCTION__);
1276 return createSetPktFilterRequest(request);
1277 } else if (mReqType == GET_APF_CAPABILITIES) {
1278 ALOGI("%s: APF get capabilities request\n", __FUNCTION__);
1279 return createGetPktFilterCapabilitesRequest(request);
1280 } else if (mReqType == READ_APF_PROGRAM) {
1281 ALOGI("%s: APF read packet filter request\n", __FUNCTION__);
1282 return createReadPktFilterRequest(request);
1283 } else {
1284 ALOGE("%s Unknown APF request\n", __FUNCTION__);
1285 return WIFI_ERROR_NOT_SUPPORTED;
1286 }
1287 return WIFI_SUCCESS;
1288 }
1289
createSetPktFilterRequest(WifiRequest & request)1290 int createSetPktFilterRequest(WifiRequest& request) {
1291 u8 *program = new u8[mProgramLen];
1292 int result;
1293
1294 NULL_CHECK_RETURN(program, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
1295
1296 ALOGI("mProgramLen : %d\n", mProgramLen);
1297 if (mProgramLen > NL_MSG_DEFAULT_LEN) {
1298 result = request.create_custom_len(GOOGLE_OUI, APF_SUBCMD_SET_FILTER,
1299 NL_MSG_MAX_LEN);
1300 } else {
1301 result = request.create(GOOGLE_OUI, APF_SUBCMD_SET_FILTER);
1302 }
1303 if (result < 0) {
1304 ALOGE("Failed to create cmd: %d, err %d\n", APF_SUBCMD_SET_FILTER, result);
1305 delete[] program;
1306 return result;
1307 }
1308
1309 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
1310 result = request.put_u32(APF_ATTRIBUTE_PROGRAM_LEN, mProgramLen);
1311 if (result < 0) {
1312 ALOGE("Failed to put the program_len %d, err %d\n", mProgramLen, result);
1313 goto exit;
1314 }
1315 memcpy(program, mProgram, mProgramLen);
1316 result = request.put(APF_ATTRIBUTE_PROGRAM, program, mProgramLen);
1317 if (result < 0) {
1318 ALOGE("Failed to copy program_ptr %d, err %d\n", mProgramLen, result);
1319 goto exit;
1320 }
1321 exit: request.attr_end(data);
1322 delete[] program;
1323 return result;
1324 }
1325
createGetPktFilterCapabilitesRequest(WifiRequest & request)1326 int createGetPktFilterCapabilitesRequest(WifiRequest& request) {
1327 int result = request.create(GOOGLE_OUI, APF_SUBCMD_GET_CAPABILITIES);
1328 if (result < 0) {
1329 return result;
1330 }
1331
1332 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
1333 request.attr_end(data);
1334 return result;
1335 }
1336
createReadPktFilterRequest(WifiRequest & request)1337 int createReadPktFilterRequest(WifiRequest& request) {
1338 int result = request.create(GOOGLE_OUI, APF_SUBCMD_READ_FILTER);
1339 if (result < 0) {
1340 return result;
1341 }
1342 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
1343 request.attr_end(data);
1344 return result;
1345 }
1346
start()1347 int start() {
1348 WifiRequest request(familyId(), ifaceId());
1349 int result = createRequest(request);
1350 if (result < 0) {
1351 ALOGI("CreateRequest failed for APF, result = %d", result);
1352 return result;
1353 }
1354 result = requestResponse(request);
1355 if (result < 0) {
1356 ALOGI("Request Response failed for APF, result = %d", result);
1357 return result;
1358 }
1359 return result;
1360 }
1361
cancel()1362 int cancel() {
1363 return WIFI_SUCCESS;
1364 }
1365
handleResponse(WifiEvent & reply)1366 int handleResponse(WifiEvent& reply) {
1367 ALOGE("In SetAPFCommand::handleResponse mReqType %d\n", mReqType);
1368
1369 if (reply.get_cmd() != NL80211_CMD_VENDOR) {
1370 ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
1371 return NL_SKIP;
1372 }
1373
1374 int id = reply.get_vendor_id();
1375 int subcmd = reply.get_vendor_subcmd();
1376
1377 nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA);
1378 int len = reply.get_vendor_data_len();
1379
1380 ALOGI("Id = %0x, subcmd = %d, len = %d", id, subcmd, len);
1381 if (vendor_data == NULL || len == 0) {
1382 ALOGE("no vendor data in SetAPFCommand response; ignoring it");
1383 return NL_SKIP;
1384 }
1385 if (mReqType == SET_APF_PROGRAM) {
1386 ALOGE("Response received for set packet filter command\n");
1387 } else if (mReqType == GET_APF_CAPABILITIES) {
1388 *mVersion = 0;
1389 *mMaxLen = 0;
1390 ALOGD("Response received for get packet filter capabilities command\n");
1391 for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
1392 if (it.get_type() == APF_ATTRIBUTE_VERSION) {
1393 *mVersion = it.get_u32();
1394 ALOGI("APF version is %d\n", *mVersion);
1395 } else if (it.get_type() == APF_ATTRIBUTE_MAX_LEN) {
1396 *mMaxLen = it.get_u32();
1397 ALOGI("APF max len is %d\n", *mMaxLen);
1398 } else {
1399 ALOGE("Ignoring invalid attribute type = %d, size = %d",
1400 it.get_type(), it.get_len());
1401 }
1402 }
1403 } else if (mReqType == READ_APF_PROGRAM) {
1404 ALOGD("Read packet filter, mProgramLen = %d\n", mProgramLen);
1405 for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
1406 if (it.get_type() == APF_ATTRIBUTE_PROGRAM) {
1407 u8 *buffer = NULL;
1408 buffer = (u8 *)it.get_data();
1409 memcpy(mReadProgram, buffer, mProgramLen);
1410 } else if (it.get_type() == APF_ATTRIBUTE_PROGRAM_LEN) {
1411 int apf_length = it.get_u32();
1412 ALOGD("apf program length = %d\n", apf_length);
1413 }
1414 }
1415 }
1416 return NL_OK;
1417 }
1418
handleEvent(WifiEvent & event)1419 int handleEvent(WifiEvent& event) {
1420 /* No Event to receive for APF commands */
1421 return NL_SKIP;
1422 }
1423 };
1424
1425 class SetNdoffloadCommand : public WifiCommand {
1426
1427 private:
1428 u8 mEnable;
1429 public:
SetNdoffloadCommand(wifi_interface_handle handle,u8 enable)1430 SetNdoffloadCommand(wifi_interface_handle handle, u8 enable)
1431 : WifiCommand("SetNdoffloadCommand", handle, 0) {
1432 mEnable = enable;
1433 }
create()1434 virtual int create() {
1435 int ret;
1436
1437 ret = mMsg.create(GOOGLE_OUI, WIFI_SUBCMD_CONFIG_ND_OFFLOAD);
1438 if (ret < 0) {
1439 ALOGE("Can't create message to send to driver - %d", ret);
1440 return ret;
1441 }
1442
1443 nlattr *data = mMsg.attr_start(NL80211_ATTR_VENDOR_DATA);
1444 ret = mMsg.put_u8(ANDR_WIFI_ATTRIBUTE_ND_OFFLOAD_VALUE, mEnable);
1445 if (ret < 0) {
1446 return ret;
1447 }
1448
1449 mMsg.attr_end(data);
1450 return WIFI_SUCCESS;
1451 }
1452 };
1453
1454 class GetFeatureSetCommand : public WifiCommand {
1455
1456 private:
1457 int feature_type;
1458 feature_set *fset;
1459 feature_set *feature_matrix;
1460 int *fm_size;
1461 int set_size_max;
1462 public:
GetFeatureSetCommand(wifi_interface_handle handle,int feature,feature_set * set,feature_set set_matrix[],int * size,int max_size)1463 GetFeatureSetCommand(wifi_interface_handle handle, int feature, feature_set *set,
1464 feature_set set_matrix[], int *size, int max_size)
1465 : WifiCommand("GetFeatureSetCommand", handle, 0) {
1466 feature_type = feature;
1467 fset = set;
1468 feature_matrix = set_matrix;
1469 fm_size = size;
1470 set_size_max = max_size;
1471 }
1472
create()1473 virtual int create() {
1474 int ret;
1475
1476 if(feature_type == ANDR_WIFI_ATTRIBUTE_NUM_FEATURE_SET) {
1477 ret = mMsg.create(GOOGLE_OUI, WIFI_SUBCMD_GET_FEATURE_SET);
1478 } else if (feature_type == ANDR_WIFI_ATTRIBUTE_FEATURE_SET) {
1479 ret = mMsg.create(GOOGLE_OUI, WIFI_SUBCMD_GET_FEATURE_SET_MATRIX);
1480 } else {
1481 ALOGE("Unknown feature type %d", feature_type);
1482 return -1;
1483 }
1484
1485 if (ret < 0) {
1486 ALOGE("Can't create message to send to driver - %d", ret);
1487 }
1488
1489 return ret;
1490 }
1491
1492 protected:
handleResponse(WifiEvent & reply)1493 virtual int handleResponse(WifiEvent& reply) {
1494
1495 ALOGV("In GetFeatureSetCommand::handleResponse");
1496
1497 if (reply.get_cmd() != NL80211_CMD_VENDOR) {
1498 ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
1499 return NL_SKIP;
1500 }
1501
1502 int id = reply.get_vendor_id();
1503 int subcmd = reply.get_vendor_subcmd();
1504
1505 nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA);
1506 int len = reply.get_vendor_data_len();
1507
1508 ALOGV("Id = %0x, subcmd = %d, len = %d", id, subcmd, len);
1509 if (vendor_data == NULL || len == 0) {
1510 ALOGE("no vendor data in GetFeatureSetCommand response; ignoring it");
1511 return NL_SKIP;
1512 }
1513 if(feature_type == ANDR_WIFI_ATTRIBUTE_NUM_FEATURE_SET) {
1514 void *data = reply.get_vendor_data();
1515 if(!fset) {
1516 ALOGE("Buffers pointers not set");
1517 return NL_SKIP;
1518 }
1519 memcpy(fset, data, min(len, (int) sizeof(*fset)));
1520 } else {
1521 int num_features_set = 0;
1522 int i = 0;
1523
1524 if(!feature_matrix || !fm_size) {
1525 ALOGE("Buffers pointers not set");
1526 return NL_SKIP;
1527 }
1528
1529 for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
1530 if (it.get_type() == ANDR_WIFI_ATTRIBUTE_NUM_FEATURE_SET) {
1531 num_features_set = it.get_u32();
1532 ALOGV("Got feature list with %d concurrent sets", num_features_set);
1533 if(set_size_max && (num_features_set > set_size_max))
1534 num_features_set = set_size_max;
1535 *fm_size = num_features_set;
1536 } else if ((it.get_type() == ANDR_WIFI_ATTRIBUTE_FEATURE_SET) &&
1537 i < num_features_set) {
1538 feature_matrix[i] = it.get_u32();
1539 i++;
1540 } else {
1541 ALOGW("Ignoring invalid attribute type = %d, size = %d",
1542 it.get_type(), it.get_len());
1543 }
1544 }
1545
1546 }
1547 return NL_OK;
1548 }
1549
1550 };
1551 /////////////////////////////////////////////////////////////////////
1552 class GetRadioComboCommand : public WifiCommand {
1553 private:
1554 wifi_radio_combination_matrix *rcmatrix;
1555 u32* rc_size;
1556 u32 set_size_max;
1557 int ret = 0;
1558
1559 public:
GetRadioComboCommand(wifi_interface_handle handle,u32 max_size,u32 * size,wifi_radio_combination_matrix * radio_combination_matrix)1560 GetRadioComboCommand(wifi_interface_handle handle, u32 max_size, u32* size,
1561 wifi_radio_combination_matrix *radio_combination_matrix)
1562 : WifiCommand("GetRadioComboCommand", handle, 0), rcmatrix(radio_combination_matrix),
1563 rc_size(size), set_size_max(max_size)
1564 {
1565 }
1566
createRequest(WifiRequest & mMsg)1567 virtual int createRequest(WifiRequest& mMsg) {
1568 ret = mMsg.create(GOOGLE_OUI, WIFI_SUBCMD_GET_RADIO_COMBO_MATRIX);
1569 if (ret < 0) {
1570 ALOGE("Can't create message to send to driver - %d", ret);
1571 }
1572 nlattr *data = mMsg.attr_start(NL80211_ATTR_VENDOR_DATA);
1573 mMsg.attr_end(data);
1574
1575 return ret;
1576 }
1577
start()1578 int start() {
1579 WifiRequest request(familyId(), ifaceId());
1580 ret = createRequest(request);
1581 if (ret < 0) {
1582 ALOGE("Request failed for radio_combo_matrix, result = %d", ret);
1583 return ret;
1584 }
1585 ret = requestResponse(request);
1586 if (ret < 0) {
1587 ALOGE("Request Response failed for radio_combo_matrix, result = %d", ret);
1588 return ret;
1589 }
1590 ALOGD("Done! %s", __FUNCTION__);
1591 return ret;
1592 }
1593
1594 protected:
handleResponse(WifiEvent & reply)1595 virtual int handleResponse(WifiEvent& reply) {
1596 ALOGD("In GetRadioComboCommand::handleResponse");
1597 if (reply.get_cmd() != NL80211_CMD_VENDOR) {
1598 ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
1599 return NL_SKIP;
1600 }
1601
1602 int id = reply.get_vendor_id();
1603 int subcmd = reply.get_vendor_subcmd();
1604
1605 nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA);
1606 int len = reply.get_vendor_data_len();
1607
1608 ALOGV("Id = %0x, subcmd = %d, len = %d", id, subcmd, len);
1609 if (vendor_data == NULL || len == 0) {
1610 ALOGE("no vendor data in GetRadioComboCommand response; ignoring it");
1611 return NL_SKIP;
1612 }
1613
1614 for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
1615 if (it.get_type() == ANDR_WIFI_ATTRIBUTE_RADIO_COMBO_MATRIX) {
1616 void *data = it.get_data();
1617 *rc_size = it.get_len();
1618 if (!data || !*rc_size) {
1619 ALOGE("Buffers pointers not set");
1620 return NL_SKIP;
1621 }
1622 if (set_size_max < *rc_size) {
1623 ALOGE("Unexpected buffers size");
1624 return NL_SKIP;
1625 }
1626 memcpy(rcmatrix, data, min(len, *rc_size));
1627 } else {
1628 ALOGW("Ignoring invalid attribute type = %d, size = %d",
1629 it.get_type(), it.get_len());
1630 }
1631 }
1632
1633 ALOGD("GetRadioComboCommand::Success");
1634 return NL_OK;
1635 }
1636 };
1637 /////////////////////////////////////////////////////////////////////
1638
1639 class SetLatencyModeCommand : public WifiCommand {
1640 private:
1641 u32 mLatencyMode;
1642 public:
SetLatencyModeCommand(wifi_interface_handle handle,u32 LatencyMode)1643 SetLatencyModeCommand(wifi_interface_handle handle, u32 LatencyMode)
1644 : WifiCommand("SetLatencyModeCommand", handle, 0) {
1645 mLatencyMode = LatencyMode;
1646 }
1647
create()1648 virtual int create() {
1649 int ret;
1650
1651 /* Check for invalid latency Mode */
1652 if ((mLatencyMode != WIFI_LATENCY_MODE_NORMAL) &&
1653 (mLatencyMode != WIFI_LATENCY_MODE_LOW)) {
1654 ALOGE("SetLatencyModeCommand: Invalid mode: %d", mLatencyMode);
1655 return WIFI_ERROR_UNKNOWN;
1656 }
1657
1658 ret = mMsg.create(GOOGLE_OUI, WIFI_SUBCMD_SET_LATENCY_MODE);
1659 if (ret < 0) {
1660 ALOGE("Can't create message to send to driver - %d", ret);
1661 return ret;
1662 }
1663
1664 nlattr *data = mMsg.attr_start(NL80211_ATTR_VENDOR_DATA);
1665 ret = mMsg.put_u32(ANDR_WIFI_ATTRIBUTE_LATENCY_MODE, mLatencyMode);
1666 if (ret < 0) {
1667 return ret;
1668 }
1669
1670 mMsg.attr_end(data);
1671 return WIFI_SUCCESS;
1672 }
1673 };
wifi_get_multicast_id(wifi_handle handle,const char * name,const char * group)1674 static int wifi_get_multicast_id(wifi_handle handle, const char *name, const char *group)
1675 {
1676 GetMulticastIdCommand cmd(handle, name, group);
1677 int res = cmd.requestResponse();
1678 if (res < 0)
1679 return res;
1680 else
1681 return cmd.getId();
1682 }
1683
1684 /////////////////////////////////////////////////////////////////////////
1685
is_wifi_interface(const char * name)1686 static bool is_wifi_interface(const char *name)
1687 {
1688 if (strncmp(name, "wlan", 4) != 0 && strncmp(name, "swlan", 5) != 0 &&
1689 strncmp(name, "p2p", 3) != 0 && strncmp(name, "aware", 5) != 0) {
1690 /* not a wifi interface; ignore it */
1691 return false;
1692 } else {
1693 return true;
1694 }
1695 }
1696
get_interface(const char * name,interface_info * info)1697 static int get_interface(const char *name, interface_info *info)
1698 {
1699 int size = 0;
1700 size = strlcpy(info->name, name, sizeof(info->name));
1701 if (size >= sizeof(info->name)) {
1702 return WIFI_ERROR_OUT_OF_MEMORY;
1703 }
1704 info->id = if_nametoindex(name);
1705 // ALOGI("found an interface : %s, id = %d", name, info->id);
1706 return WIFI_SUCCESS;
1707 }
1708
wifi_init_interfaces(wifi_handle handle)1709 wifi_error wifi_init_interfaces(wifi_handle handle)
1710 {
1711 hal_info *info = (hal_info *)handle;
1712
1713 struct dirent *de;
1714
1715 DIR *d = opendir("/sys/class/net");
1716 if (d == 0)
1717 return WIFI_ERROR_UNKNOWN;
1718
1719 int n = 0;
1720 while ((de = readdir(d))) {
1721 if (de->d_name[0] == '.')
1722 continue;
1723 if (is_wifi_interface(de->d_name) ) {
1724 n++;
1725 }
1726 }
1727
1728 closedir(d);
1729
1730 if (n == 0)
1731 return WIFI_ERROR_NOT_AVAILABLE;
1732
1733 d = opendir("/sys/class/net");
1734 if (d == 0)
1735 return WIFI_ERROR_UNKNOWN;
1736
1737 /* Have place holder for 3 virtual interfaces */
1738 n += MAX_VIRTUAL_IFACES;
1739 info->interfaces = (interface_info **)calloc(n, sizeof(interface_info *) * n);
1740 if (!info->interfaces) {
1741 info->num_interfaces = 0;
1742 closedir(d);
1743 return WIFI_ERROR_OUT_OF_MEMORY;
1744 }
1745
1746 int i = 0;
1747 while ((de = readdir(d))) {
1748 if (de->d_name[0] == '.')
1749 continue;
1750 if (is_wifi_interface(de->d_name)) {
1751 interface_info *ifinfo = (interface_info *)malloc(sizeof(interface_info));
1752 if (!ifinfo) {
1753 if (info->interfaces) {
1754 for (int j = 0; j < i; j++) {
1755 free(info->interfaces[j]);
1756 }
1757 }
1758 free(info->interfaces);
1759 info->num_interfaces = 0;
1760 closedir(d);
1761 return WIFI_ERROR_OUT_OF_MEMORY;
1762 }
1763 memset(ifinfo, 0, sizeof(interface_info));
1764 if (get_interface(de->d_name, ifinfo) != WIFI_SUCCESS) {
1765 free(ifinfo);
1766 continue;
1767 }
1768 /* Mark as static iface */
1769 ifinfo->is_virtual = false;
1770 ifinfo->handle = handle;
1771 info->interfaces[i] = ifinfo;
1772 i++;
1773 }
1774 }
1775
1776 closedir(d);
1777
1778 info->num_interfaces = i;
1779 info->max_num_interfaces = n;
1780 return WIFI_SUCCESS;
1781 }
1782
wifi_get_ifaces(wifi_handle handle,int * num,wifi_interface_handle ** interfaces)1783 wifi_error wifi_get_ifaces(wifi_handle handle, int *num, wifi_interface_handle **interfaces)
1784 {
1785 hal_info *info = (hal_info *)handle;
1786
1787 *interfaces = (wifi_interface_handle *)info->interfaces;
1788 *num = info->num_interfaces;
1789
1790 return WIFI_SUCCESS;
1791 }
1792
wifi_add_iface_hal_info(wifi_handle handle,const char * ifname)1793 wifi_error wifi_add_iface_hal_info(wifi_handle handle, const char* ifname)
1794 {
1795 hal_info *info = NULL;
1796 int i = 0;
1797
1798 info = (hal_info *)handle;
1799 if (info == NULL) {
1800 ALOGE("Could not find info\n");
1801 return WIFI_ERROR_UNKNOWN;
1802 }
1803
1804 ALOGI("%s: add interface_info for iface: %s\n", __FUNCTION__, ifname);
1805 if (info->num_interfaces == MAX_VIRTUAL_IFACES) {
1806 ALOGE("No space. max limit reached for virtual interfaces %d\n", info->num_interfaces);
1807 return WIFI_ERROR_OUT_OF_MEMORY;
1808 }
1809
1810 interface_info *ifinfo = (interface_info *)malloc(sizeof(interface_info));
1811 if (!ifinfo) {
1812 free(info->interfaces);
1813 info->num_interfaces = 0;
1814 return WIFI_ERROR_OUT_OF_MEMORY;
1815 }
1816
1817 ifinfo->handle = handle;
1818 while (i < info->max_num_interfaces) {
1819 if (info->interfaces[i] == NULL) {
1820 if (get_interface(ifname, ifinfo) != WIFI_SUCCESS) {
1821 continue;
1822 }
1823 ifinfo->is_virtual = true;
1824 info->interfaces[i] = ifinfo;
1825 info->num_interfaces++;
1826 ALOGI("%s: Added iface: %s at the index %d\n", __FUNCTION__, ifname, i);
1827 break;
1828 }
1829 i++;
1830 }
1831 return WIFI_SUCCESS;
1832 }
1833
wifi_clear_iface_hal_info(wifi_handle handle,const char * ifname)1834 wifi_error wifi_clear_iface_hal_info(wifi_handle handle, const char* ifname)
1835 {
1836 hal_info *info = (hal_info *)handle;
1837 int i = 0;
1838
1839 ALOGI("%s: clear hal info for iface: %s\n", __FUNCTION__, ifname);
1840 while (i < info->max_num_interfaces) {
1841 if ((info->interfaces[i] != NULL) &&
1842 strncmp(info->interfaces[i]->name, ifname,
1843 sizeof(info->interfaces[i]->name)) == 0) {
1844 free(info->interfaces[i]);
1845 info->interfaces[i] = NULL;
1846 info->num_interfaces--;
1847 ALOGI("%s: Cleared the index = %d for iface: %s\n", __FUNCTION__, i, ifname);
1848 break;
1849 }
1850 i++;
1851 }
1852 if (i < info->num_interfaces) {
1853 for (int j = i; j < info->num_interfaces; j++) {
1854 info->interfaces[j] = info->interfaces[j+1];
1855 }
1856 info->interfaces[info->num_interfaces] = NULL;
1857 }
1858 return WIFI_SUCCESS;
1859 }
1860
wifi_get_wlan_interface(wifi_handle info,wifi_interface_handle * ifaceHandles,int numIfaceHandles)1861 wifi_interface_handle wifi_get_wlan_interface(wifi_handle info, wifi_interface_handle *ifaceHandles, int numIfaceHandles)
1862 {
1863 char buf[EVENT_BUF_SIZE];
1864 wifi_interface_handle wlan0Handle;
1865 wifi_error res = wifi_get_ifaces((wifi_handle)info, &numIfaceHandles, &ifaceHandles);
1866 if (res < 0) {
1867 return NULL;
1868 }
1869 for (int i = 0; i < numIfaceHandles; i++) {
1870 if (wifi_get_iface_name(ifaceHandles[i], buf, sizeof(buf)) == WIFI_SUCCESS) {
1871 if (strncmp(buf, "wlan0", 5) == 0) {
1872 ALOGI("found interface %s\n", buf);
1873 wlan0Handle = ifaceHandles[i];
1874 return wlan0Handle;
1875 }
1876 }
1877 }
1878 return NULL;
1879 }
wifi_get_iface_name(wifi_interface_handle handle,char * name,size_t size)1880 wifi_error wifi_get_iface_name(wifi_interface_handle handle, char *name, size_t size)
1881 {
1882 interface_info *info = (interface_info *)handle;
1883 strncpy(name, info->name, (IFNAMSIZ));
1884 name[IFNAMSIZ - 1] = '\0';
1885 return WIFI_SUCCESS;
1886 }
1887
wifi_get_iface_handle(wifi_handle handle,char * name)1888 wifi_interface_handle wifi_get_iface_handle(wifi_handle handle, char *name)
1889 {
1890 char buf[EVENT_BUF_SIZE];
1891 wifi_interface_handle *ifaceHandles;
1892 int numIfaceHandles;
1893 wifi_interface_handle ifHandle;
1894
1895 wifi_error res = wifi_get_ifaces((wifi_handle)handle, &numIfaceHandles, &ifaceHandles);
1896 if (res < 0) {
1897 return NULL;
1898 }
1899 for (int i = 0; i < numIfaceHandles; i++) {
1900 if (wifi_get_iface_name(ifaceHandles[i], buf, sizeof(buf)) == WIFI_SUCCESS) {
1901 if (strcmp(buf, name) == 0) {
1902 ALOGI("found interface %s\n", buf);
1903 ifHandle = ifaceHandles[i];
1904 return ifHandle;
1905 }
1906 }
1907 }
1908 return NULL;
1909 }
1910
wifi_get_supported_feature_set(wifi_interface_handle handle,feature_set * set)1911 wifi_error wifi_get_supported_feature_set(wifi_interface_handle handle, feature_set *set)
1912 {
1913 GetFeatureSetCommand command(handle, ANDR_WIFI_ATTRIBUTE_NUM_FEATURE_SET, set, NULL, NULL, 1);
1914 return (wifi_error) command.requestResponse();
1915 }
1916
wifi_get_concurrency_matrix(wifi_interface_handle handle,int set_size_max,feature_set set[],int * set_size)1917 wifi_error wifi_get_concurrency_matrix(wifi_interface_handle handle, int set_size_max,
1918 feature_set set[], int *set_size)
1919 {
1920 GetFeatureSetCommand command(handle, ANDR_WIFI_ATTRIBUTE_FEATURE_SET, NULL,
1921 set, set_size, set_size_max);
1922 return (wifi_error) command.requestResponse();
1923 }
1924
wifi_get_supported_radio_combinations_matrix(wifi_handle handle,u32 max_size,u32 * size,wifi_radio_combination_matrix * radio_combination_matrix)1925 wifi_error wifi_get_supported_radio_combinations_matrix(wifi_handle handle,
1926 u32 max_size, u32* size, wifi_radio_combination_matrix *radio_combination_matrix)
1927 {
1928 int numIfaceHandles = 0;
1929 wifi_interface_handle *ifaceHandles = NULL;
1930 wifi_interface_handle wlan0Handle;
1931
1932 wlan0Handle = wifi_get_wlan_interface((wifi_handle)handle, ifaceHandles, numIfaceHandles);
1933 GetRadioComboCommand *cmd = new GetRadioComboCommand(wlan0Handle, max_size,
1934 size, radio_combination_matrix);
1935 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
1936 wifi_error result = (wifi_error)cmd->start();
1937 if (result == WIFI_SUCCESS) {
1938 ALOGD("Get radio combo matrix success");
1939 } else {
1940 ALOGE("Get radio combo matrix failed\n");
1941 }
1942 cmd->releaseRef();
1943 return result;
1944 }
1945
wifi_set_scanning_mac_oui(wifi_interface_handle handle,oui scan_oui)1946 wifi_error wifi_set_scanning_mac_oui(wifi_interface_handle handle, oui scan_oui)
1947 {
1948 SetPnoMacAddrOuiCommand command(handle, scan_oui);
1949 return (wifi_error)command.start();
1950
1951 }
1952
wifi_set_nodfs_flag(wifi_interface_handle handle,u32 nodfs)1953 wifi_error wifi_set_nodfs_flag(wifi_interface_handle handle, u32 nodfs)
1954 {
1955 SetNodfsCommand command(handle, nodfs);
1956 return (wifi_error) command.requestResponse();
1957 }
1958
wifi_set_country_code(wifi_interface_handle handle,const char * country_code)1959 wifi_error wifi_set_country_code(wifi_interface_handle handle, const char *country_code)
1960 {
1961 SetCountryCodeCommand command(handle, country_code);
1962 return (wifi_error) command.requestResponse();
1963 }
1964
wifi_start_rssi_monitoring(wifi_request_id id,wifi_interface_handle iface,s8 max_rssi,s8 min_rssi,wifi_rssi_event_handler eh)1965 static wifi_error wifi_start_rssi_monitoring(wifi_request_id id, wifi_interface_handle
1966 iface, s8 max_rssi, s8 min_rssi, wifi_rssi_event_handler eh)
1967 {
1968 ALOGI("Starting RSSI monitor %d", id);
1969 wifi_handle handle = getWifiHandle(iface);
1970 SetRSSIMonitorCommand *cmd = new SetRSSIMonitorCommand(id, iface, max_rssi, min_rssi, eh);
1971 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
1972 wifi_error result = wifi_register_cmd(handle, id, cmd);
1973 if (result != WIFI_SUCCESS) {
1974 ALOGI("wifi_register_cmd() is failed %d", id);
1975 cmd->releaseRef();
1976 return result;
1977 }
1978 result = (wifi_error)cmd->start();
1979 if (result != WIFI_SUCCESS) {
1980 ALOGI("start() is failed %d", id);
1981 wifi_unregister_cmd(handle, id);
1982 cmd->releaseRef();
1983 return result;
1984 }
1985 return result;
1986 }
1987
wifi_stop_rssi_monitoring(wifi_request_id id,wifi_interface_handle iface)1988 static wifi_error wifi_stop_rssi_monitoring(wifi_request_id id, wifi_interface_handle iface)
1989 {
1990 ALOGI("Stopping RSSI monitor %d", id);
1991
1992 if (id == -1) {
1993 wifi_rssi_event_handler handler;
1994 s8 max_rssi = 0, min_rssi = 0;
1995 memset(&handler, 0, sizeof(handler));
1996 SetRSSIMonitorCommand *cmd = new SetRSSIMonitorCommand(id, iface,
1997 max_rssi, min_rssi, handler);
1998 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
1999 cmd->cancel();
2000 cmd->releaseRef();
2001 return WIFI_SUCCESS;
2002 }
2003 return wifi_cancel_cmd(id, iface);
2004 }
2005
wifi_get_packet_filter_capabilities(wifi_interface_handle handle,u32 * version,u32 * max_len)2006 static wifi_error wifi_get_packet_filter_capabilities(wifi_interface_handle handle,
2007 u32 *version, u32 *max_len)
2008 {
2009 ALOGD("Getting APF capabilities, halHandle = %p\n", handle);
2010 AndroidPktFilterCommand *cmd = new AndroidPktFilterCommand(handle, version, max_len);
2011 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
2012 wifi_error result = (wifi_error)cmd->start();
2013 if (result == WIFI_SUCCESS) {
2014 ALOGD("Getting APF capability, version = %d, max_len = %d\n", *version, *max_len);
2015 }
2016 cmd->releaseRef();
2017 return result;
2018 }
2019
wifi_set_packet_filter(wifi_interface_handle handle,const u8 * program,u32 len)2020 static wifi_error wifi_set_packet_filter(wifi_interface_handle handle,
2021 const u8 *program, u32 len)
2022 {
2023 char iface_name[IFNAMSIZ];
2024
2025 ALOGE("Setting APF program, halHandle = %p\n", handle);
2026 if (wifi_get_iface_name(handle, iface_name, sizeof(iface_name)) != WIFI_SUCCESS) {
2027 ALOGE("%s : Invalid interface handle\n", __func__);
2028 return WIFI_ERROR_INVALID_ARGS;
2029 }
2030 ALOGE("Set apf filter for iface = %s\n", iface_name);
2031
2032 AndroidPktFilterCommand *cmd = new AndroidPktFilterCommand(handle, program, len);
2033 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
2034 wifi_error result = (wifi_error)cmd->start();
2035 cmd->releaseRef();
2036 return result;
2037 }
2038
wifi_read_packet_filter(wifi_interface_handle handle,u32 src_offset,u8 * host_dst,u32 length)2039 static wifi_error wifi_read_packet_filter(wifi_interface_handle handle,
2040 u32 src_offset, u8 *host_dst, u32 length)
2041 {
2042 ALOGD("Read APF program, halHandle = %p, length = %d\n", handle, length);
2043 AndroidPktFilterCommand *cmd = new AndroidPktFilterCommand(handle, host_dst, length);
2044 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
2045 wifi_error result = (wifi_error)cmd->start();
2046 if (result == WIFI_SUCCESS) {
2047 ALOGI("Read APF program success\n");
2048 }
2049 cmd->releaseRef();
2050 return result;
2051 }
wifi_configure_nd_offload(wifi_interface_handle handle,u8 enable)2052 static wifi_error wifi_configure_nd_offload(wifi_interface_handle handle, u8 enable)
2053 {
2054 SetNdoffloadCommand command(handle, enable);
2055 return (wifi_error) command.requestResponse();
2056 }
wifi_set_latency_mode(wifi_interface_handle handle,wifi_latency_mode mode)2057 wifi_error wifi_set_latency_mode(wifi_interface_handle handle, wifi_latency_mode mode)
2058 {
2059 ALOGD("Setting Wifi Latency mode, halHandle = %p LatencyMode = %d\n", handle, mode);
2060 SetLatencyModeCommand command(handle, mode);
2061 return (wifi_error) command.requestResponse();
2062 }
2063
2064 /////////////////////////////////////////////////////////////////////////
2065 class TxPowerScenario : public WifiCommand {
2066 wifi_power_scenario mScenario;
2067 public:
2068 // constructor for tx power scenario setting
TxPowerScenario(wifi_interface_handle handle,wifi_power_scenario scenario)2069 TxPowerScenario(wifi_interface_handle handle, wifi_power_scenario scenario)
2070 : WifiCommand("TxPowerScenario", handle, 0), mScenario(scenario)
2071 {
2072 mScenario = scenario;
2073 }
2074
2075 // constructor for tx power scenario resetting
TxPowerScenario(wifi_interface_handle handle)2076 TxPowerScenario(wifi_interface_handle handle)
2077 : WifiCommand("TxPowerScenario", handle, 0)
2078 {
2079 mScenario = WIFI_POWER_SCENARIO_DEFAULT;
2080 }
2081
createRequest(WifiRequest & request,int subcmd,wifi_power_scenario mScenario)2082 int createRequest(WifiRequest& request, int subcmd, wifi_power_scenario mScenario) {
2083 int result = request.create(GOOGLE_OUI, subcmd);
2084 if (result < 0) {
2085 return result;
2086 }
2087
2088 if ((mScenario <= WIFI_POWER_SCENARIO_INVALID) ||
2089 (mScenario >= SAR_CONFIG_SCENARIO_COUNT)) {
2090 ALOGE("Unsupported tx power value:%d\n", mScenario);
2091 return WIFI_ERROR_NOT_SUPPORTED;
2092 }
2093
2094 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
2095 result = request.put_s8(ANDR_WIFI_ATTRIBUTE_TX_POWER_SCENARIO, mScenario);
2096 if (result < 0) {
2097 ALOGE("Failed to put tx power scenario request; result = %d", result);
2098 return result;
2099 }
2100 request.attr_end(data);
2101 return WIFI_SUCCESS;
2102 }
2103
start(wifi_power_scenario mScenario)2104 int start(wifi_power_scenario mScenario) {
2105 WifiRequest request(familyId(), ifaceId());
2106 int result = createRequest(request, WIFI_SUBCMD_TX_POWER_SCENARIO, mScenario);
2107 if (result != WIFI_SUCCESS) {
2108 ALOGE("failed to create request; result = %d", result);
2109 return result;
2110 }
2111
2112 result = requestResponse(request);
2113 if (result != WIFI_SUCCESS) {
2114 ALOGE("failed to send tx power scenario; result = %d", result);
2115 }
2116 return result;
2117 }
2118 protected:
handleResponse(WifiEvent & reply)2119 virtual int handleResponse(WifiEvent& reply) {
2120 ALOGD("Request complete!");
2121 /* Nothing to do on response! */
2122 return NL_SKIP;
2123 }
2124 };
2125
2126
wifi_select_tx_power_scenario(wifi_interface_handle handle,wifi_power_scenario scenario)2127 wifi_error wifi_select_tx_power_scenario(wifi_interface_handle handle, wifi_power_scenario scenario)
2128 {
2129 ALOGE("wifi_select_tx_power_scenario");
2130 TxPowerScenario command(handle);
2131 return (wifi_error)command.start(scenario);
2132 }
2133
wifi_reset_tx_power_scenario(wifi_interface_handle handle)2134 wifi_error wifi_reset_tx_power_scenario(wifi_interface_handle handle)
2135 {
2136 wifi_power_scenario scenario = WIFI_POWER_SCENARIO_DEFAULT;
2137 ALOGE("wifi_reset_tx_power_scenario");
2138 TxPowerScenario command(handle);
2139 return (wifi_error)command.start(scenario);
2140 }
2141
2142 /////////////////////////////////////////////////////////////////////////////
2143
2144 class ThermalMitigation : public WifiCommand {
2145 private:
2146 wifi_thermal_mode mMitigation;
2147 u32 mCompletionWindow;
2148 public:
2149 // constructor for thermal mitigation setting
ThermalMitigation(wifi_interface_handle handle,wifi_thermal_mode mitigation,u32 completion_window)2150 ThermalMitigation(wifi_interface_handle handle,
2151 wifi_thermal_mode mitigation, u32 completion_window)
2152 : WifiCommand("ThermalMitigation", handle, 0)
2153 {
2154 mMitigation = mitigation;
2155 mCompletionWindow = completion_window;
2156 }
2157
createRequest(WifiRequest & request,int subcmd,wifi_thermal_mode mitigation,u32 completion_window)2158 int createRequest(WifiRequest& request, int subcmd,
2159 wifi_thermal_mode mitigation, u32 completion_window) {
2160 int result = request.create(GOOGLE_OUI, subcmd);
2161 if (result < 0) {
2162 return result;
2163 }
2164
2165 if ((mitigation < WIFI_MITIGATION_NONE) ||
2166 (mitigation > WIFI_MITIGATION_EMERGENCY)) {
2167 ALOGE("Unsupported tx mitigation value:%d\n", mitigation);
2168 return WIFI_ERROR_NOT_SUPPORTED;
2169 }
2170
2171 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
2172 result = request.put_s8(ANDR_WIFI_ATTRIBUTE_THERMAL_MITIGATION, mitigation);
2173 if (result < 0) {
2174 ALOGE("Failed to put tx power scenario request; result = %d", result);
2175 return result;
2176 }
2177 result = request.put_u32(ANDR_WIFI_ATTRIBUTE_THERMAL_COMPLETION_WINDOW,
2178 completion_window);
2179 if (result < 0) {
2180 ALOGE("Failed to put tx power scenario request; result = %d", result);
2181 return result;
2182 }
2183
2184 request.attr_end(data);
2185 return WIFI_SUCCESS;
2186 }
2187
start()2188 int start() {
2189 WifiRequest request(familyId(), ifaceId());
2190 int result = createRequest(request, WIFI_SUBCMD_THERMAL_MITIGATION, mMitigation,
2191 mCompletionWindow);
2192 if (result != WIFI_SUCCESS) {
2193 ALOGE("failed to create request; result = %d", result);
2194 return result;
2195 }
2196
2197 ALOGD("try to get resp; mitigation=%d, delay=%d", mMitigation, mCompletionWindow);
2198 result = requestResponse(request);
2199 if (result != WIFI_SUCCESS) {
2200 ALOGE("failed to send thermal mitigation; result = %d", result);
2201 }
2202 return result;
2203 }
2204 protected:
handleResponse(WifiEvent & reply)2205 virtual int handleResponse(WifiEvent& reply) {
2206 ALOGD("Request complete!");
2207 /* Nothing to do on response! */
2208 return NL_SKIP;
2209 }
2210 };
2211
wifi_set_thermal_mitigation_mode(wifi_handle handle,wifi_thermal_mode mode,u32 completion_window)2212 wifi_error wifi_set_thermal_mitigation_mode(wifi_handle handle,
2213 wifi_thermal_mode mode,
2214 u32 completion_window)
2215 {
2216 int numIfaceHandles = 0;
2217 wifi_interface_handle *ifaceHandles = NULL;
2218 wifi_interface_handle wlan0Handle;
2219
2220 wlan0Handle = wifi_get_wlan_interface((wifi_handle)handle, ifaceHandles, numIfaceHandles);
2221 ThermalMitigation command(wlan0Handle, mode, completion_window);
2222 return (wifi_error)command.start();
2223 }
2224
2225 /////////////////////////////////////////////////////////////////////////////
2226
2227 class ChAvoidCommand : public WifiCommand {
2228 private:
2229 u32 mNumParams;
2230 wifi_coex_unsafe_channel *chavoidParams;
2231 u32 mMandatory;
2232
2233 public:
ChAvoidCommand(wifi_interface_handle handle,u32 num,wifi_coex_unsafe_channel channels[],u32 mandatory)2234 ChAvoidCommand(wifi_interface_handle handle,
2235 u32 num, wifi_coex_unsafe_channel channels[], u32 mandatory)
2236 : WifiCommand("ChAvoidCommand", handle, 0),
2237 mNumParams(num), chavoidParams(channels), mMandatory(mandatory)
2238 {
2239 }
2240
createRequest(WifiRequest & request)2241 int createRequest(WifiRequest& request) {
2242 return createSetChAvoidRequest(request);
2243 }
2244
createSetChAvoidRequest(WifiRequest & request)2245 int createSetChAvoidRequest(WifiRequest& request) {
2246 int result = request.create(GOOGLE_OUI, CHAVOID_SUBCMD_SET_CONFIG);
2247 if (result < 0) {
2248 ALOGE("%s : Failed to create SUBCMD\n", __func__);
2249 return result;
2250 }
2251
2252 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
2253 result = request.put_u32(CHAVOID_ATTRIBUTE_CNT, mNumParams);
2254 if (result < 0) {
2255 ALOGE("%s : Failed to set cound\n", __func__);
2256 return result;
2257 }
2258 result = request.put_u32(CHAVOID_ATTRIBUTE_MANDATORY, mMandatory);
2259 if (result < 0) {
2260 ALOGE("%s : Failed to set mandatory cap\n", __func__);
2261 return result;
2262 }
2263
2264 nlattr *chavoid_config = request.attr_start(CHAVOID_ATTRIBUTE_CONFIG);
2265 for (int i = 0; i< mNumParams; i++) {
2266 nlattr *item = request.attr_start(i);
2267 if (item == NULL) {
2268 ALOGE("%s : Failed to alloc item\n", __func__);
2269 return WIFI_ERROR_OUT_OF_MEMORY;
2270 }
2271 result = request.put_u32(CHAVOID_ATTRIBUTE_BAND, chavoidParams[i].band);
2272 if (result < 0) {
2273 ALOGE("%s : Failed to set band\n", __func__);
2274 return result;
2275 }
2276 result = request.put_u32(CHAVOID_ATTRIBUTE_CHANNEL, chavoidParams[i].channel);
2277 if (result < 0) {
2278 ALOGE("%s : Failed to set channel\n", __func__);
2279 return result;
2280 }
2281 result = request.put_u32(CHAVOID_ATTRIBUTE_PWRCAP, chavoidParams[i].power_cap_dbm);
2282 if (result < 0) {
2283 ALOGE("%s : Failed to set power cap\n", __func__);
2284 return result;
2285 }
2286 request.attr_end(item);
2287 }
2288 request.attr_end(chavoid_config);
2289 request.attr_end(data);
2290 return WIFI_SUCCESS;
2291 }
2292
start()2293 int start() {
2294 WifiRequest request(familyId(), ifaceId());
2295 int result = createRequest(request);
2296 if (result < 0) {
2297 return result;
2298 }
2299 result = requestResponse(request);
2300 if (result < 0) {
2301 ALOGI("Request Response failed for ChAvoid, result = %d", result);
2302 return result;
2303 }
2304 return result;
2305 }
2306
handleResponse(WifiEvent & reply)2307 int handleResponse(WifiEvent& reply) {
2308 ALOGD("In ChAvoidCommand::handleResponse");
2309
2310 if (reply.get_cmd() != NL80211_CMD_VENDOR) {
2311 ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
2312 return NL_SKIP;
2313 }
2314
2315 nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA);
2316 int len = reply.get_vendor_data_len();
2317
2318 if (vendor_data == NULL || len == 0) {
2319 ALOGE("no vendor data in ChAvoidCommand response; ignoring it");
2320 return NL_SKIP;
2321 }
2322 ALOGD("Response received for ChAvoid command\n");
2323 return NL_OK;
2324 }
2325
handleEvent(WifiEvent & event)2326 int handleEvent(WifiEvent& event) {
2327 /* No Event to receive for ChAvoid commands */
2328 ALOGD("ChAvoid command %s\n", __FUNCTION__);
2329 return NL_SKIP;
2330 }
2331 };
2332
wifi_set_coex_unsafe_channels(wifi_handle handle,u32 num,wifi_coex_unsafe_channel channels[],u32 mandatory)2333 wifi_error wifi_set_coex_unsafe_channels(wifi_handle handle,
2334 u32 num, wifi_coex_unsafe_channel channels[], u32 mandatory)
2335 {
2336 int numIfaceHandles = 0;
2337 wifi_interface_handle *ifaceHandles = NULL;
2338 wifi_interface_handle wlan0Handle;
2339
2340 wlan0Handle = wifi_get_wlan_interface((wifi_handle)handle, ifaceHandles, numIfaceHandles);
2341
2342 ChAvoidCommand *cmd = new ChAvoidCommand(wlan0Handle, num, channels, mandatory);
2343 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
2344 wifi_error result = (wifi_error)cmd->start();
2345 if (result == WIFI_SUCCESS) {
2346 ALOGI("Setting Channel Avoidance success\n");
2347 } else {
2348 ALOGE("Setting Channel Avoidance failed\n");
2349 }
2350 cmd->releaseRef();
2351 return result;
2352 }
2353
2354 /////////////////////////////////////////////////////////////////////////////
2355
2356 class DscpCommand : public WifiCommand {
2357 private:
2358 u32 mStart;
2359 u32 mEnd;
2360 u32 mAc;
2361 int mReqType;
2362 public:
DscpCommand(wifi_interface_handle handle,u32 start,u32 end,u32 ac)2363 DscpCommand(wifi_interface_handle handle,
2364 u32 start, u32 end, u32 ac)
2365 : WifiCommand("DscpCommand", handle, 0),
2366 mStart(start), mEnd(end), mAc(ac),
2367 mReqType(SET_DSCP_TABLE)
2368 {
2369 }
2370
DscpCommand(wifi_interface_handle handle)2371 DscpCommand(wifi_interface_handle handle)
2372 : WifiCommand("DscpCommand", handle, 0),
2373 mReqType(RESET_DSCP_TABLE)
2374 {
2375 mStart = 0;
2376 mEnd = 0;
2377 mAc = 0;
2378 }
2379
createRequest(WifiRequest & request)2380 int createRequest(WifiRequest& request) {
2381 if (mReqType == SET_DSCP_TABLE) {
2382 ALOGI("\n%s: DSCP set table request\n", __FUNCTION__);
2383 return createSetDscpRequest(request);
2384 } else if (mReqType == RESET_DSCP_TABLE) {
2385 ALOGI("\n%s: DSCP reset table request\n", __FUNCTION__);
2386 return createResetDscpRequest(request);
2387 } else {
2388 ALOGE("\n%s Unknown DSCP request\n", __FUNCTION__);
2389 return WIFI_ERROR_NOT_SUPPORTED;
2390 }
2391 return WIFI_SUCCESS;
2392 }
2393
createSetDscpRequest(WifiRequest & request)2394 int createSetDscpRequest(WifiRequest& request) {
2395 int result = request.create(GOOGLE_OUI, DSCP_SUBCMD_SET_TABLE);
2396 if (result < 0) {
2397 return result;
2398 }
2399
2400 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
2401 result = request.put_u32(DSCP_ATTRIBUTE_START, mStart);
2402 if (result < 0) {
2403 goto exit;
2404 }
2405 result = request.put_u32(DSCP_ATTRIBUTE_END, mEnd);
2406 if (result < 0) {
2407 goto exit;
2408 }
2409 result = request.put_u32(DSCP_ATTRIBUTE_AC, mAc);
2410 if (result < 0) {
2411 goto exit;
2412 }
2413 request.attr_end(data);
2414 exit:
2415 return result;
2416 }
2417
createResetDscpRequest(WifiRequest & request)2418 int createResetDscpRequest(WifiRequest& request) {
2419 int result = request.create(GOOGLE_OUI, DSCP_SUBCMD_RESET_TABLE);
2420 if (result < 0) {
2421 return result;
2422 }
2423
2424 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
2425 request.attr_end(data);
2426 return result;
2427 }
2428
start()2429 int start() {
2430 WifiRequest request(familyId(), ifaceId());
2431 int result = createRequest(request);
2432 if (result < 0) {
2433 return result;
2434 }
2435 result = requestResponse(request);
2436 if (result < 0) {
2437 ALOGI("Request Response failed for DSCP, result = %d", result);
2438 return result;
2439 }
2440 return result;
2441 }
2442
handleResponse(WifiEvent & reply)2443 int handleResponse(WifiEvent& reply) {
2444 ALOGD("In DscpCommand::handleResponse");
2445
2446 if (reply.get_cmd() != NL80211_CMD_VENDOR) {
2447 ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
2448 return NL_SKIP;
2449 }
2450
2451 nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA);
2452 int len = reply.get_vendor_data_len();
2453
2454 if (vendor_data == NULL || len == 0) {
2455 ALOGE("no vendor data in DscpCommand response; ignoring it");
2456 return NL_SKIP;
2457 }
2458 if( mReqType == SET_DSCP_TABLE) {
2459 ALOGD("Response received for Set DSCP command\n");
2460 } else if (mReqType == RESET_DSCP_TABLE) {
2461 ALOGD("Response received for Reset DSCP command\n");
2462 }
2463 return NL_OK;
2464 }
2465
handleEvent(WifiEvent & event)2466 int handleEvent(WifiEvent& event) {
2467 /* No Event to receive for DSCP commands */
2468 ALOGD("DSCP command %s\n", __FUNCTION__);
2469 return NL_SKIP;
2470 }
2471 };
2472
wifi_map_dscp_access_category(wifi_handle handle,u32 start,u32 end,u32 ac)2473 wifi_error wifi_map_dscp_access_category(wifi_handle handle,
2474 u32 start, u32 end, u32 ac)
2475 {
2476 int numIfaceHandles = 0;
2477 wifi_interface_handle *ifaceHandles = NULL;
2478 wifi_interface_handle wlan0Handle;
2479
2480 wlan0Handle = wifi_get_wlan_interface((wifi_handle)handle, ifaceHandles, numIfaceHandles);
2481
2482 DscpCommand *cmd = new DscpCommand(wlan0Handle, start, end, ac);
2483 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
2484 wifi_error result = (wifi_error)cmd->start();
2485 if (result == WIFI_SUCCESS) {
2486 ALOGI("Mapping DSCP table success\n");
2487 } else {
2488 ALOGE("Mapping DSCP table fail\n");
2489 }
2490 cmd->releaseRef();
2491 return result;
2492 }
2493
wifi_reset_dscp_mapping(wifi_handle handle)2494 wifi_error wifi_reset_dscp_mapping(wifi_handle handle)
2495 {
2496 int numIfaceHandles = 0;
2497 wifi_interface_handle *ifaceHandles = NULL;
2498 wifi_interface_handle wlan0Handle;
2499
2500 wlan0Handle = wifi_get_wlan_interface((wifi_handle)handle, ifaceHandles, numIfaceHandles);
2501
2502 DscpCommand *cmd = new DscpCommand(wlan0Handle);
2503 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
2504 wifi_error result = (wifi_error)cmd->start();
2505 if (result == WIFI_SUCCESS) {
2506 ALOGI("Resetting DSCP table success\n");
2507 } else {
2508 ALOGE("Resetting DSCP table fail\n");
2509 }
2510 cmd->releaseRef();
2511 return result;
2512 }
2513
2514 class VirtualIfaceConfig : public WifiCommand {
2515 const char *mIfname;
2516 nl80211_iftype mType;
2517 u32 mwlan0_id;
2518
2519 public:
VirtualIfaceConfig(wifi_interface_handle handle,const char * ifname,nl80211_iftype iface_type,u32 wlan0_id)2520 VirtualIfaceConfig(wifi_interface_handle handle, const char* ifname,
2521 nl80211_iftype iface_type, u32 wlan0_id)
2522 : WifiCommand("VirtualIfaceConfig", handle, 0), mIfname(ifname), mType(iface_type),
2523 mwlan0_id(wlan0_id)
2524 {
2525 mIfname = ifname;
2526 mType = iface_type;
2527 mwlan0_id = wlan0_id;
2528 }
createRequest(WifiRequest & request,const char * ifname,nl80211_iftype iface_type,u32 wlan0_id)2529 int createRequest(WifiRequest& request, const char* ifname,
2530 nl80211_iftype iface_type, u32 wlan0_id) {
2531 ALOGD("add ifname = %s, iface_type = %d, wlan0_id = %d",
2532 ifname, iface_type, wlan0_id);
2533
2534 int result = request.create(NL80211_CMD_NEW_INTERFACE);
2535 if (result < 0) {
2536 ALOGE("failed to create NL80211_CMD_NEW_INTERFACE; result = %d", result);
2537 return result;
2538 }
2539
2540 result = request.put_u32(NL80211_ATTR_IFINDEX, wlan0_id);
2541 if (result < 0) {
2542 ALOGE("failed to put NL80211_ATTR_IFINDEX; result = %d", result);
2543 return result;
2544 }
2545
2546 result = request.put_string(NL80211_ATTR_IFNAME, ifname);
2547 if (result < 0) {
2548 ALOGE("failed to put NL80211_ATTR_IFNAME = %s; result = %d", ifname, result);
2549 return result;
2550 }
2551
2552 result = request.put_u32(NL80211_ATTR_IFTYPE, iface_type);
2553 if (result < 0) {
2554 ALOGE("failed to put NL80211_ATTR_IFTYPE = %d; result = %d", iface_type, result);
2555 return result;
2556 }
2557 return WIFI_SUCCESS;
2558 }
2559
deleteRequest(WifiRequest & request,const char * ifname)2560 int deleteRequest(WifiRequest& request, const char* ifname) {
2561 ALOGD("delete ifname = %s\n", ifname);
2562 int result = request.create(NL80211_CMD_DEL_INTERFACE);
2563 if (result < 0) {
2564 ALOGE("failed to create NL80211_CMD_DEL_INTERFACE; result = %d", result);
2565 return result;
2566 }
2567 result = request.put_u32(NL80211_ATTR_IFINDEX, if_nametoindex(ifname));
2568 if (result < 0) {
2569 ALOGE("failed to put NL80211_ATTR_IFINDEX = %d; result = %d",
2570 if_nametoindex(ifname), result);
2571 return result;
2572 }
2573 result = request.put_string(NL80211_ATTR_IFNAME, ifname);
2574 if (result < 0) {
2575 ALOGE("failed to put NL80211_ATTR_IFNAME = %s; result = %d", ifname, result);
2576 return result;
2577 }
2578 return WIFI_SUCCESS;
2579 }
2580
createIface()2581 int createIface() {
2582 ALOGD("Creating virtual interface");
2583 WifiRequest request(familyId(), ifaceId());
2584 int result = createRequest(request, mIfname, mType, mwlan0_id);
2585 if (result != WIFI_SUCCESS) {
2586 ALOGE("failed to create virtual iface request; result = %d\n", result);
2587 return result;
2588 }
2589
2590 result = requestResponse(request);
2591 if (result != WIFI_SUCCESS) {
2592 ALOGE("failed to get the virtual iface create response; result = %d\n", result);
2593 return result;
2594 }
2595 ALOGD("Created virtual interface");
2596 return WIFI_SUCCESS;
2597 }
2598
deleteIface()2599 int deleteIface() {
2600 ALOGD("Deleting virtual interface");
2601 WifiRequest request(familyId(), ifaceId());
2602 int result = deleteRequest(request, mIfname);
2603 if (result != WIFI_SUCCESS) {
2604 ALOGE("failed to create virtual iface delete request; result = %d\n", result);
2605 return result;
2606 }
2607
2608 result = requestResponse(request);
2609 if (result != WIFI_SUCCESS) {
2610 ALOGE("failed to get response of delete virtual interface; result = %d\n", result);
2611 return result;
2612 }
2613 ALOGD("Deleted virtual interface");
2614 return WIFI_SUCCESS;
2615 }
2616 protected:
handleResponse(WifiEvent & reply)2617 virtual int handleResponse(WifiEvent& reply) {
2618 ALOGD("Request complete!");
2619 /* Nothing to do on response! */
2620 return NL_SKIP;
2621 }
2622 };
2623
2624 static std::vector<std::string> added_ifaces;
2625
wifi_cleanup_dynamic_ifaces(wifi_handle handle)2626 static void wifi_cleanup_dynamic_ifaces(wifi_handle handle)
2627 {
2628 int len = added_ifaces.size();
2629 ALOGI("%s: virtual iface size %d\n", __FUNCTION__, len);
2630 while (len--) {
2631 wifi_virtual_interface_delete(handle, added_ifaces.front().c_str());
2632 ALOGI("%s: deleted virtual iface %s\n",
2633 __FUNCTION__, added_ifaces.front().c_str());
2634 }
2635 added_ifaces.clear();
2636 }
2637
wifi_virtual_interface_create(wifi_handle handle,const char * ifname,wifi_interface_type iface_type)2638 wifi_error wifi_virtual_interface_create(wifi_handle handle, const char* ifname,
2639 wifi_interface_type iface_type)
2640 {
2641 int numIfaceHandles = 0;
2642 wifi_error ret = WIFI_SUCCESS;
2643 wifi_interface_handle *ifaceHandles = NULL;
2644 wifi_interface_handle wlan0Handle;
2645 nl80211_iftype type = NL80211_IFTYPE_UNSPECIFIED;
2646 u32 wlan0_id = if_nametoindex("wlan0");
2647
2648 if (!handle || !wlan0_id) {
2649 ALOGE("%s: Error wifi_handle NULL or wlan0 not present\n", __FUNCTION__);
2650 return WIFI_ERROR_UNKNOWN;
2651 }
2652
2653 /* Do not create interface if already exist. */
2654 if (if_nametoindex(ifname)) {
2655 ALOGD("%s: if_nametoindex(%s) = %d already exists, skip create \n",
2656 __FUNCTION__, ifname, if_nametoindex(ifname));
2657 return WIFI_SUCCESS;
2658 }
2659
2660 ALOGD("%s: ifname name = %s, type = %s\n", __FUNCTION__, ifname,
2661 IfaceTypeToString(iface_type));
2662
2663 switch (iface_type) {
2664 case WIFI_INTERFACE_TYPE_STA:
2665 type = NL80211_IFTYPE_STATION;
2666 break;
2667 case WIFI_INTERFACE_TYPE_AP:
2668 type = NL80211_IFTYPE_AP;
2669 break;
2670 case WIFI_INTERFACE_TYPE_P2P:
2671 type = NL80211_IFTYPE_P2P_DEVICE;
2672 break;
2673 case WIFI_INTERFACE_TYPE_NAN:
2674 ALOGE("%s: Unsupported interface type %u\n", __FUNCTION__, iface_type);
2675 return WIFI_ERROR_NOT_SUPPORTED;
2676 default:
2677 ALOGE("%s: Wrong interface type %u\n", __FUNCTION__, iface_type);
2678 return WIFI_ERROR_UNKNOWN;
2679 }
2680
2681 wlan0Handle = wifi_get_wlan_interface((wifi_handle)handle, ifaceHandles, numIfaceHandles);
2682 VirtualIfaceConfig command(wlan0Handle, ifname, type, wlan0_id);
2683
2684 ret = (wifi_error)command.createIface();
2685 if (ret != WIFI_SUCCESS) {
2686 ALOGE("%s: Iface add Error:%d", __FUNCTION__,ret);
2687 return ret;
2688 }
2689 /* Update dynamic interface list */
2690 added_ifaces.push_back(std::string(ifname));
2691 ret = wifi_add_iface_hal_info((wifi_handle)handle, ifname);
2692 return ret;
2693 }
2694
wifi_virtual_interface_delete(wifi_handle handle,const char * ifname)2695 wifi_error wifi_virtual_interface_delete(wifi_handle handle, const char* ifname)
2696 {
2697 int numIfaceHandles = 0;
2698 int i = 0;
2699 wifi_error ret = WIFI_SUCCESS;
2700 wifi_interface_handle *ifaceHandles = NULL;
2701 wifi_interface_handle wlan0Handle;
2702 hal_info *info = (hal_info *)handle;
2703 u32 wlan0_id = if_nametoindex("wlan0");
2704
2705 if (!handle || !wlan0_id) {
2706 ALOGE("%s: Error wifi_handle NULL or wlan0 not present\n", __FUNCTION__);
2707 return WIFI_ERROR_UNKNOWN;
2708 }
2709
2710 /* Check if interface delete requested on valid interface */
2711 while (i < info->max_num_interfaces) {
2712 if (info->interfaces[i] != NULL &&
2713 strncmp(info->interfaces[i]->name,
2714 ifname, sizeof(info->interfaces[i]->name)) == 0) {
2715 if (!get_halutil_mode()) {
2716 if (info->interfaces[i]->is_virtual == false) {
2717 ALOGI("%s: %s is static iface, skip delete\n",
2718 __FUNCTION__, ifname);
2719 return WIFI_SUCCESS;
2720 }
2721 } else {
2722 ALOGI("%s: %s delete iface", __FUNCTION__, ifname);
2723 break;
2724 }
2725 }
2726 i++;
2727 }
2728
2729 ALOGI("%s: iface name=%s\n", __FUNCTION__, ifname);
2730 wlan0Handle = wifi_get_wlan_interface((wifi_handle)handle, ifaceHandles, numIfaceHandles);
2731 VirtualIfaceConfig command(wlan0Handle, ifname, (nl80211_iftype)0, 0);
2732 ret = (wifi_error)command.deleteIface();
2733 if (ret != WIFI_SUCCESS) {
2734 ALOGE("%s: Iface delete Error:%d", __FUNCTION__,ret);
2735 /* If lower layer returns an error, hang event is expected to do wifi reset
2736 * and hal state needs to be cleared irrespectivily. Hence fall-through.
2737 */
2738 }
2739 /* Update dynamic interface list */
2740 added_ifaces.erase(std::remove(added_ifaces.begin(), added_ifaces.end(), std::string(ifname)),
2741 added_ifaces.end());
2742 ret = wifi_clear_iface_hal_info((wifi_handle)handle, ifname);
2743 return ret;
2744 }
2745 /////////////////////////////////////////////////////////////////////////////
2746
2747 class MultiStaConfig : public WifiCommand {
2748 wifi_multi_sta_use_case mUseCase;
2749 int mReqType;
2750
2751 public:
MultiStaConfig(wifi_interface_handle handle)2752 MultiStaConfig(wifi_interface_handle handle)
2753 : WifiCommand("MultiStaConfig", handle, 0), mReqType(SET_PRIMARY_CONNECTION)
2754 {
2755 mUseCase = WIFI_DUAL_STA_TRANSIENT_PREFER_PRIMARY;
2756 }
MultiStaConfig(wifi_interface_handle handle,wifi_multi_sta_use_case use_case)2757 MultiStaConfig(wifi_interface_handle handle, wifi_multi_sta_use_case use_case)
2758 : WifiCommand("MultiStaConfig", handle, 0), mUseCase(use_case), mReqType(SET_USE_CASE)
2759 {
2760 mUseCase = use_case;
2761 }
2762
createRequest(WifiRequest & request)2763 int createRequest(WifiRequest& request) {
2764 if (mReqType == SET_PRIMARY_CONNECTION) {
2765 ALOGI("\n%s: MultiSta set primary connection\n", __FUNCTION__);
2766 return createSetPrimaryConnectionRequest(request);
2767 } else if (mReqType == SET_USE_CASE) {
2768 ALOGI("\n%s: MultiSta set use case\n", __FUNCTION__);
2769 return createSetUsecaseRequest(request);
2770 } else {
2771 ALOGE("\n%s Unknown MultiSta request\n", __FUNCTION__);
2772 return WIFI_ERROR_NOT_SUPPORTED;
2773 }
2774 return WIFI_SUCCESS;
2775 }
2776
createSetPrimaryConnectionRequest(WifiRequest & request)2777 int createSetPrimaryConnectionRequest(WifiRequest& request) {
2778 int result = request.create(GOOGLE_OUI, WIFI_SUBCMD_SET_MULTISTA_PRIMARY_CONNECTION);
2779 if (result < 0) {
2780 return result;
2781 }
2782
2783 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
2784 request.attr_end(data);
2785
2786 return result;
2787 }
2788
createSetUsecaseRequest(WifiRequest & request)2789 int createSetUsecaseRequest(WifiRequest& request) {
2790 int result = request.create(GOOGLE_OUI, WIFI_SUBCMD_SET_MULTISTA_USE_CASE);
2791 if (result < 0) {
2792 return result;
2793 }
2794
2795 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
2796 result = request.put_u32(MULTISTA_ATTRIBUTE_USE_CASE, mUseCase);
2797 if (result < 0) {
2798 ALOGE("failed to put MULTISTA_ATTRIBUTE_USE_CASE = %d; result = %d", mUseCase, result);
2799 goto exit;
2800 }
2801
2802 exit: request.attr_end(data);
2803 return result;
2804 }
2805
start()2806 int start() {
2807 WifiRequest request(familyId(), ifaceId());
2808 int result = createRequest(request);
2809 if (result < 0) {
2810 return result;
2811 }
2812 result = requestResponse(request);
2813 if (result < 0) {
2814 ALOGI("Request Response failed for MultiSta, result = %d", result);
2815 return result;
2816 }
2817 ALOGI("Done!");
2818 return result;
2819 }
2820 protected:
handleResponse(WifiEvent & reply)2821 virtual int handleResponse(WifiEvent& reply) {
2822 ALOGD("Request complete!");
2823 /* Nothing to do on response! */
2824 return NL_SKIP;
2825 }
2826 };
2827
wifi_multi_sta_set_primary_connection(wifi_handle handle,wifi_interface_handle iface)2828 wifi_error wifi_multi_sta_set_primary_connection(wifi_handle handle, wifi_interface_handle iface)
2829 {
2830 wifi_error ret = WIFI_SUCCESS;
2831 char buf[IFNAMSIZ];
2832
2833 if (!handle || !iface) {
2834 ALOGE("%s: Error wifi_handle NULL or invalid wifi interface handle\n", __FUNCTION__);
2835 return WIFI_ERROR_UNKNOWN;
2836 }
2837
2838 if (wifi_get_iface_name(iface, buf, sizeof(buf)) != WIFI_SUCCESS) {
2839 ALOGE("%s : Invalid interface handle\n", __func__);
2840 return WIFI_ERROR_INVALID_ARGS;
2841 }
2842
2843 ALOGD("Setting Multista primary connection for iface = %s\n", buf);
2844
2845 MultiStaConfig *cmd = new MultiStaConfig(iface);
2846 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
2847 ret = (wifi_error)cmd->start();
2848 cmd->releaseRef();
2849 return ret;
2850 }
2851
wifi_multi_sta_set_use_case(wifi_handle handle,wifi_multi_sta_use_case use_case)2852 wifi_error wifi_multi_sta_set_use_case(wifi_handle handle, wifi_multi_sta_use_case use_case)
2853 {
2854 int numIfaceHandles = 0;
2855 wifi_error ret = WIFI_SUCCESS;
2856 wifi_interface_handle *ifaceHandles = NULL;
2857 wifi_interface_handle wlan0Handle;
2858
2859 if (!handle) {
2860 ALOGE("%s: Error wifi_handle NULL\n", __FUNCTION__);
2861 return WIFI_ERROR_UNKNOWN;
2862 }
2863
2864 if (!(use_case >= WIFI_DUAL_STA_TRANSIENT_PREFER_PRIMARY &&
2865 use_case <= WIFI_DUAL_STA_NON_TRANSIENT_UNBIASED)) {
2866 ALOGE("%s: Invalid multi_sta usecase %d\n", __FUNCTION__, use_case);
2867 return WIFI_ERROR_INVALID_ARGS;
2868 }
2869
2870 wlan0Handle = wifi_get_wlan_interface((wifi_handle)handle, ifaceHandles, numIfaceHandles);
2871 ALOGD("Setting Multista usecase = %d\n", use_case);
2872 MultiStaConfig *cmd = new MultiStaConfig(wlan0Handle, use_case);
2873 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
2874 ret = (wifi_error)cmd->start();
2875 cmd->releaseRef();
2876 return ret;
2877 }
2878 /////////////////////////////////////////////////////////////////////////////////////////////////
2879
2880 class SetVoipModeCommand : public WifiCommand {
2881
2882 private:
2883 wifi_voip_mode mMode;
2884 public:
SetVoipModeCommand(wifi_interface_handle handle,wifi_voip_mode mode)2885 SetVoipModeCommand(wifi_interface_handle handle, wifi_voip_mode mode)
2886 : WifiCommand("SetVoipModeCommand", handle, 0) {
2887 mMode = mode;
2888 }
create()2889 virtual int create() {
2890 int ret;
2891
2892 ret = mMsg.create(GOOGLE_OUI, WIFI_SUBCMD_CONFIG_VOIP_MODE);
2893 if (ret < 0) {
2894 ALOGE("Can't create message to send to driver - %d", ret);
2895 return ret;
2896 }
2897
2898 nlattr *data = mMsg.attr_start(NL80211_ATTR_VENDOR_DATA);
2899 ret = mMsg.put_u32(ANDR_WIFI_ATTRIBUTE_VOIP_MODE, mMode);
2900 ALOGE("mMode - %d", mMode);
2901 if (ret < 0) {
2902 ALOGE("Failed to set voip mode %d\n", mMode);
2903 return ret;
2904 }
2905
2906 ALOGI("Successfully configured voip mode %d\n", mMode);
2907 mMsg.attr_end(data);
2908 return WIFI_SUCCESS;
2909 }
2910 };
2911
wifi_set_voip_mode(wifi_interface_handle handle,wifi_voip_mode mode)2912 wifi_error wifi_set_voip_mode(wifi_interface_handle handle, wifi_voip_mode mode)
2913 {
2914 ALOGD("Setting VOIP mode, halHandle = %p Mode = %d\n", handle, mode);
2915 SetVoipModeCommand command(handle, mode);
2916 return (wifi_error) command.requestResponse();
2917 }
2918
2919 /////////////////////////////////////////////////////////////////////////////////////////////////
2920 class SetDtimConfigCommand : public WifiCommand {
2921
2922 private:
2923 uint32_t multiplier;
2924 public:
SetDtimConfigCommand(wifi_interface_handle handle,u32 dtim_multiplier)2925 SetDtimConfigCommand(wifi_interface_handle handle, u32 dtim_multiplier)
2926 : WifiCommand("SetDtimConfigCommand", handle, 0) {
2927 multiplier = dtim_multiplier;
2928 }
create()2929 virtual int create() {
2930 int ret;
2931
2932 ret = mMsg.create(GOOGLE_OUI, WIFI_SUBCMD_SET_DTIM_CONFIG);
2933 if (ret < 0) {
2934 ALOGE("Can't create message to send to driver - %d", ret);
2935 return ret;
2936 }
2937
2938 nlattr *data = mMsg.attr_start(NL80211_ATTR_VENDOR_DATA);
2939 ret = mMsg.put_u32(ANDR_WIFI_ATTRIBUTE_DTIM_MULTIPLIER, multiplier);
2940 if (ret < 0) {
2941 ALOGE("Failed to set dtim mutiplier %d\n", multiplier);
2942 return ret;
2943 }
2944
2945 ALOGI("Successfully configured dtim multiplier %d\n", multiplier);
2946 mMsg.attr_end(data);
2947 return WIFI_SUCCESS;
2948 }
2949 };
2950
wifi_set_dtim_config(wifi_interface_handle handle,u32 multiplier)2951 wifi_error wifi_set_dtim_config(wifi_interface_handle handle, u32 multiplier)
2952 {
2953 ALOGD("Setting DTIM config , halHandle = %p Multiplier = %d\n", handle, multiplier);
2954 SetDtimConfigCommand command(handle, multiplier);
2955 return (wifi_error) command.requestResponse();
2956 }
2957
2958 /////////////////////////////////////////////////////////////////////////////////////////////////
2959 class UsableChannelCommand : public WifiCommand {
2960
2961 private:
2962 u32 mBandMask;
2963 u32 mIfaceModeMask;
2964 u32 mFilterMask;
2965 u32 mMaxSize;
2966 u32* mSize;
2967 wifi_usable_channel* mChannels;
2968
2969 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)2970 UsableChannelCommand(wifi_interface_handle handle, u32 band_mask, u32 iface_mode_mask,
2971 u32 filter_mask, u32 max_size, u32* size, wifi_usable_channel* channels)
2972 : WifiCommand("UsableChannelCommand", handle, 0),
2973 mBandMask(band_mask), mIfaceModeMask(iface_mode_mask),
2974 mFilterMask(filter_mask), mMaxSize(max_size),
2975 mSize(size), mChannels(channels)
2976 {
2977 }
2978
createRequest(WifiRequest & request)2979 int createRequest(WifiRequest& request) {
2980 createUsableChannelRequest(request);
2981 return WIFI_SUCCESS;
2982 }
2983
createUsableChannelRequest(WifiRequest & request)2984 int createUsableChannelRequest(WifiRequest& request) {
2985 int result = request.create(GOOGLE_OUI, WIFI_SUBCMD_USABLE_CHANNEL);
2986 if (result < 0) {
2987 ALOGE("Failed to create UsableChannel request; result = %d", result);
2988 return result;
2989 }
2990
2991 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
2992
2993 result = request.put_u32(USABLECHAN_ATTRIBUTE_BAND, mBandMask);
2994 if (result != WIFI_SUCCESS) {
2995 ALOGE("Failed to put log level; result = %d", result);
2996 return result;
2997 }
2998 result = request.put_u32(USABLECHAN_ATTRIBUTE_IFACE, mIfaceModeMask);
2999 if (result != WIFI_SUCCESS) {
3000 ALOGE("Failed to put ring flags; result = %d", result);
3001 return result;
3002 }
3003 result = request.put_u32(USABLECHAN_ATTRIBUTE_FILTER, mFilterMask);
3004 if (result != WIFI_SUCCESS) {
3005 ALOGE("Failed to put usablechan filter; result = %d", result);
3006 return result;
3007 }
3008 result = request.put_u32(USABLECHAN_ATTRIBUTE_MAX_SIZE, mMaxSize);
3009 if (result != WIFI_SUCCESS) {
3010 ALOGE("Failed to put usablechan max_size; result = %d", result);
3011 return result;
3012 }
3013 request.attr_end(data);
3014
3015 return WIFI_SUCCESS;
3016 }
3017
start()3018 int start() {
3019 WifiRequest request(familyId(), ifaceId());
3020 int result = createRequest(request);
3021 if (result != WIFI_SUCCESS) {
3022 ALOGE("failed to create request; result = %d", result);
3023 return result;
3024 }
3025
3026 result = requestResponse(request);
3027 if (result != WIFI_SUCCESS) {
3028 ALOGE("failed to set scanning mac OUI; result = %d", result);
3029 }
3030
3031 return result;
3032 }
3033
handleResponse(WifiEvent & reply)3034 virtual int handleResponse(WifiEvent& reply) {
3035 ALOGD("In DebugCommand::handleResponse");
3036
3037 if (reply.get_cmd() != NL80211_CMD_VENDOR) {
3038 ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
3039 return NL_SKIP;
3040 }
3041
3042 nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA);
3043 int len = reply.get_vendor_data_len();
3044 wifi_usable_channel *channels(mChannels);
3045
3046 if (vendor_data == NULL || len == 0) {
3047 ALOGE("No Debug data found");
3048 return NL_SKIP;
3049 }
3050
3051 nl_iterator it(vendor_data);
3052 if (it.get_type() == USABLECHAN_ATTRIBUTE_SIZE) {
3053 *mSize = it.get_u32();
3054 } else {
3055 ALOGE("Unknown attribute: %d expecting %d",
3056 it.get_type(), USABLECHAN_ATTRIBUTE_SIZE);
3057 return NL_SKIP;
3058 }
3059
3060 it.next();
3061 if (it.get_type() == USABLECHAN_ATTRIBUTE_CHANNELS) {
3062 memcpy(channels, it.get_data(), sizeof(wifi_usable_channel) * *mSize);
3063 } else {
3064 ALOGE("Unknown attribute: %d expecting %d",
3065 it.get_type(), USABLECHAN_ATTRIBUTE_SIZE);
3066 return NL_SKIP;
3067 }
3068
3069 return NL_OK;
3070 }
3071
handleEvent(WifiEvent & event)3072 virtual int handleEvent(WifiEvent& event) {
3073 /* NO events! */
3074 return NL_SKIP;
3075 }
3076 };
3077
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)3078 wifi_error wifi_get_usable_channels(wifi_handle handle, u32 band_mask, u32 iface_mode_mask,
3079 u32 filter_mask, u32 max_size, u32* size, wifi_usable_channel* channels)
3080 {
3081 int numIfaceHandles = 0;
3082 wifi_interface_handle *ifaceHandles = NULL;
3083 wifi_interface_handle wlan0Handle;
3084
3085 wlan0Handle = wifi_get_wlan_interface((wifi_handle)handle, ifaceHandles, numIfaceHandles);
3086 UsableChannelCommand command(wlan0Handle, band_mask, iface_mode_mask,
3087 filter_mask, max_size, size, channels);
3088 return (wifi_error)command.start();
3089 }
3090
3091 /////////////////////////////////////////////////////////////////////////////////////////////////
3092 class EnableTxPowerLimit : public WifiCommand {
3093 private:
3094 bool mEnableTxLimits;
3095 public:
EnableTxPowerLimit(wifi_interface_handle handle,bool enable_tx_pwr_limits)3096 EnableTxPowerLimit(wifi_interface_handle handle, bool enable_tx_pwr_limits)
3097 : WifiCommand("EnableTxPowerLimit", handle, 0)
3098 {
3099 mEnableTxLimits = enable_tx_pwr_limits;
3100 }
3101
create()3102 virtual int create() {
3103 int ret;
3104
3105 ret = mMsg.create(GOOGLE_OUI, WIFI_SUBCMD_ENABLE_TX_POWER_LIMIT);
3106 if (ret < 0) {
3107 ALOGE("Can't create message to send to driver - %d", ret);
3108 return ret;
3109 }
3110
3111 nlattr *data = mMsg.attr_start(NL80211_ATTR_VENDOR_DATA);
3112 ret = mMsg.put_u8(TX_POWER_CAP_ENABLE_ATTRIBUTE, mEnableTxLimits);
3113 if (ret < 0) {
3114 ALOGE("Failed to put enable tx power limit param %d\n", mEnableTxLimits);
3115 return ret;
3116 }
3117 mMsg.attr_end(data);
3118 return WIFI_SUCCESS;
3119 }
3120 };
3121
wifi_enable_tx_power_limits(wifi_interface_handle handle,bool isEnable)3122 wifi_error wifi_enable_tx_power_limits(wifi_interface_handle handle, bool isEnable)
3123 {
3124 ALOGD("Configuring the tx power limits , halHandle = %p\n", handle);
3125
3126 EnableTxPowerLimit command(handle, isEnable);
3127 return (wifi_error) command.requestResponse();
3128 }
3129
3130 //////////////////////////////////////////////////////
3131 class EnableStaChannel : public WifiCommand {
3132
3133 private:
3134 u32 mChannelCatEnabFlag;
3135 public:
EnableStaChannel(wifi_interface_handle handle,u32 channelCategoryEnableFlag)3136 EnableStaChannel(wifi_interface_handle handle, u32 channelCategoryEnableFlag)
3137 : WifiCommand("EnableStaChannel", handle, 0) {
3138 mChannelCatEnabFlag = channelCategoryEnableFlag;
3139 }
create()3140 virtual int create() {
3141 int ret;
3142
3143 ret = mMsg.create(GOOGLE_OUI, WIFI_SUBCMD_CHANNEL_POLICY);
3144 if (ret < 0) {
3145 ALOGE("Can't create message to send to driver - %d", ret);
3146 return ret;
3147 }
3148
3149 nlattr *data = mMsg.attr_start(NL80211_ATTR_VENDOR_DATA);
3150 ret = mMsg.put_u32(ANDR_WIFI_ATTRIBUTE_CHAN_POLICY, mChannelCatEnabFlag);
3151 if (ret < 0) {
3152 return ret;
3153 }
3154
3155 mMsg.attr_end(data);
3156 return WIFI_SUCCESS;
3157 }
3158 };
3159
3160 /* enable or disable the feature of allowing current STA-connected
3161 * channel for WFA GO, SAP and Wi-Fi Aware when the regulatory allows.
3162 */
wifi_enable_sta_channel_for_peer_network(wifi_handle handle,u32 channelCategoryEnableFlag)3163 wifi_error wifi_enable_sta_channel_for_peer_network(wifi_handle handle,
3164 u32 channelCategoryEnableFlag) {
3165 int numIfaceHandles = 0;
3166 wifi_interface_handle *ifaceHandles = NULL;
3167 wifi_interface_handle wlan0Handle;
3168
3169 wlan0Handle = wifi_get_wlan_interface((wifi_handle)handle, ifaceHandles, numIfaceHandles);
3170 EnableStaChannel command(wlan0Handle, channelCategoryEnableFlag);
3171 return (wifi_error) command.requestResponse();
3172 }
3173