1 /*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Portions copyright (C) 2017 Broadcom Limited
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19 #include <stdint.h>
20 #include <fcntl.h>
21 #include <sys/socket.h>
22 #include <netlink/genl/genl.h>
23 #include <netlink/genl/family.h>
24 #include <netlink/genl/ctrl.h>
25 #include <linux/rtnetlink.h>
26 #include <netpacket/packet.h>
27 #include <linux/filter.h>
28 #include <linux/errqueue.h>
29 #include <errno.h>
30
31 #include <linux/pkt_sched.h>
32 #include <netlink/object-api.h>
33 #include <netlink/netlink.h>
34 #include <netlink/socket.h>
35 #include <netlink/attr.h>
36 #include <netlink/handlers.h>
37 #include <netlink/msg.h>
38
39 #include <dirent.h>
40 #include <net/if.h>
41
42 #include <sys/types.h>
43 #include <unistd.h>
44
45 #include "sync.h"
46
47 #define LOG_TAG "WifiHAL"
48 #include <log/log.h>
49
50 #include "wifi_hal.h"
51 #include "common.h"
52 #include "cpp_bindings.h"
53 #include "rtt.h"
54 #include "brcm_version.h"
55 #include <stdio.h>
56 /*
57 BUGBUG: normally, libnl allocates ports for all connections it makes; but
58 being a static library, it doesn't really know how many other netlink connections
59 are made by the same process, if connections come from different shared libraries.
60 These port assignments exist to solve that problem - temporarily. We need to fix
61 libnl to try and allocate ports across the entire process.
62 */
63
64 #define WIFI_HAL_CMD_SOCK_PORT 644
65 #define WIFI_HAL_EVENT_SOCK_PORT 645
66
67 /*
68 * Defines for wifi_wait_for_driver_ready()
69 * Specify durations between polls and max wait time
70 */
71 #define POLL_DRIVER_DURATION_US (100000)
72 #define POLL_DRIVER_MAX_TIME_MS (10000)
73 #define EVENT_BUF_SIZE 2048
74
75 static void internal_event_handler(wifi_handle handle, int events);
76 static int internal_no_seq_check(nl_msg *msg, void *arg);
77 static int internal_valid_message_handler(nl_msg *msg, void *arg);
78 static int wifi_get_multicast_id(wifi_handle handle, const char *name, const char *group);
79 static int wifi_add_membership(wifi_handle handle, const char *group);
80 static wifi_error wifi_init_interfaces(wifi_handle handle);
81 static wifi_error wifi_start_rssi_monitoring(wifi_request_id id, wifi_interface_handle
82 iface, s8 max_rssi, s8 min_rssi, wifi_rssi_event_handler eh);
83 static wifi_error wifi_stop_rssi_monitoring(wifi_request_id id, wifi_interface_handle iface);
84 static wifi_error wifi_set_packet_filter(wifi_interface_handle handle,
85 const u8 *program, u32 len);
86 static wifi_error wifi_get_packet_filter_capabilities(wifi_interface_handle handle,
87 u32 *version, u32 *max_len);
88 static wifi_error wifi_configure_nd_offload(wifi_interface_handle iface, u8 enable);
89
90 typedef enum wifi_attr {
91 ANDR_WIFI_ATTRIBUTE_NUM_FEATURE_SET,
92 ANDR_WIFI_ATTRIBUTE_FEATURE_SET,
93 ANDR_WIFI_ATTRIBUTE_PNO_RANDOM_MAC_OUI,
94 ANDR_WIFI_ATTRIBUTE_NODFS_SET,
95 ANDR_WIFI_ATTRIBUTE_COUNTRY,
96 ANDR_WIFI_ATTRIBUTE_ND_OFFLOAD_VALUE,
97 ANDR_WIFI_ATTRIBUTE_TCPACK_SUP_VALUE,
98 ANDR_WIFI_ATTRIBUTE_LATENCY_MODE,
99 ANDR_WIFI_ATTRIBUTE_RANDOM_MAC,
100 ANDR_WIFI_ATTRIBUTE_TX_POWER_SCENARIO
101 // Add more attribute here
102 } wifi_attr_t;
103
104 enum wifi_rssi_monitor_attr {
105 RSSI_MONITOR_ATTRIBUTE_MAX_RSSI,
106 RSSI_MONITOR_ATTRIBUTE_MIN_RSSI,
107 RSSI_MONITOR_ATTRIBUTE_START,
108 };
109
110 enum wifi_apf_attr {
111 APF_ATTRIBUTE_VERSION,
112 APF_ATTRIBUTE_MAX_LEN,
113 APF_ATTRIBUTE_PROGRAM,
114 APF_ATTRIBUTE_PROGRAM_LEN
115 };
116
117 enum apf_request_type {
118 GET_APF_CAPABILITIES,
119 SET_APF_PROGRAM
120 };
121
122 /* Initialize/Cleanup */
123
wifi_socket_set_local_port(struct nl_sock * sock,uint32_t port)124 void wifi_socket_set_local_port(struct nl_sock *sock, uint32_t port)
125 {
126 uint32_t pid = getpid() & 0x3FFFFF;
127 nl_socket_set_local_port(sock, pid + (port << 22));
128 }
129
wifi_create_nl_socket(int port)130 static nl_sock * wifi_create_nl_socket(int port)
131 {
132 // ALOGI("Creating socket");
133 struct nl_sock *sock = nl_socket_alloc();
134 if (sock == NULL) {
135 ALOGE("Could not create handle");
136 return NULL;
137 }
138
139 wifi_socket_set_local_port(sock, port);
140
141 struct sockaddr *addr = NULL;
142 // ALOGI("sizeof(sockaddr) = %d, sizeof(sockaddr_nl) = %d", sizeof(*addr), sizeof(*addr_nl));
143
144 // ALOGI("Connecting socket");
145 if (nl_connect(sock, NETLINK_GENERIC)) {
146 ALOGE("Could not connect handle");
147 nl_socket_free(sock);
148 return NULL;
149 }
150
151 // ALOGI("Making socket nonblocking");
152 /*
153 if (nl_socket_set_nonblocking(sock)) {
154 ALOGE("Could make socket non-blocking");
155 nl_socket_free(sock);
156 return NULL;
157 }
158 */
159
160 return sock;
161 }
162
163 /*initialize function pointer table with Broadcom HHAL API*/
init_wifi_vendor_hal_func_table(wifi_hal_fn * fn)164 wifi_error init_wifi_vendor_hal_func_table(wifi_hal_fn *fn)
165 {
166 if (fn == NULL) {
167 return WIFI_ERROR_UNKNOWN;
168 }
169 fn->wifi_initialize = wifi_initialize;
170 fn->wifi_wait_for_driver_ready = wifi_wait_for_driver_ready;
171 fn->wifi_cleanup = wifi_cleanup;
172 fn->wifi_event_loop = wifi_event_loop;
173 fn->wifi_get_supported_feature_set = wifi_get_supported_feature_set;
174 fn->wifi_get_concurrency_matrix = wifi_get_concurrency_matrix;
175 fn->wifi_set_scanning_mac_oui = wifi_set_scanning_mac_oui;
176 fn->wifi_get_ifaces = wifi_get_ifaces;
177 fn->wifi_get_iface_name = wifi_get_iface_name;
178 fn->wifi_start_gscan = wifi_start_gscan;
179 fn->wifi_stop_gscan = wifi_stop_gscan;
180 fn->wifi_get_cached_gscan_results = wifi_get_cached_gscan_results;
181 fn->wifi_set_bssid_hotlist = wifi_set_bssid_hotlist;
182 fn->wifi_reset_bssid_hotlist = wifi_reset_bssid_hotlist;
183 fn->wifi_set_significant_change_handler = wifi_set_significant_change_handler;
184 fn->wifi_reset_significant_change_handler = wifi_reset_significant_change_handler;
185 fn->wifi_get_gscan_capabilities = wifi_get_gscan_capabilities;
186 fn->wifi_get_link_stats = wifi_get_link_stats;
187 fn->wifi_set_link_stats = wifi_set_link_stats;
188 fn->wifi_clear_link_stats = wifi_clear_link_stats;
189 fn->wifi_get_valid_channels = wifi_get_valid_channels;
190 fn->wifi_rtt_range_request = wifi_rtt_range_request;
191 fn->wifi_rtt_range_cancel = wifi_rtt_range_cancel;
192 fn->wifi_get_rtt_capabilities = wifi_get_rtt_capabilities;
193 fn->wifi_rtt_get_responder_info = wifi_rtt_get_responder_info;
194 fn->wifi_enable_responder = wifi_enable_responder;
195 fn->wifi_disable_responder = wifi_disable_responder;
196 fn->wifi_set_nodfs_flag = wifi_set_nodfs_flag;
197 fn->wifi_start_logging = wifi_start_logging;
198 fn->wifi_set_epno_list = wifi_set_epno_list;
199 fn->wifi_reset_epno_list = wifi_reset_epno_list;
200 fn->wifi_set_country_code = wifi_set_country_code;
201 fn->wifi_get_firmware_memory_dump = wifi_get_firmware_memory_dump;
202 fn->wifi_set_log_handler = wifi_set_log_handler;
203 fn->wifi_reset_log_handler = wifi_reset_log_handler;
204 fn->wifi_set_alert_handler = wifi_set_alert_handler;
205 fn->wifi_reset_alert_handler = wifi_reset_alert_handler;
206 fn->wifi_get_firmware_version = wifi_get_firmware_version;
207 fn->wifi_get_ring_buffers_status = wifi_get_ring_buffers_status;
208 fn->wifi_get_logger_supported_feature_set = wifi_get_logger_supported_feature_set;
209 fn->wifi_get_ring_data = wifi_get_ring_data;
210 fn->wifi_get_driver_version = wifi_get_driver_version;
211 fn->wifi_start_rssi_monitoring = wifi_start_rssi_monitoring;
212 fn->wifi_stop_rssi_monitoring = wifi_stop_rssi_monitoring;
213 fn->wifi_configure_nd_offload = wifi_configure_nd_offload;
214 fn->wifi_start_sending_offloaded_packet = wifi_start_sending_offloaded_packet;
215 fn->wifi_stop_sending_offloaded_packet = wifi_stop_sending_offloaded_packet;
216 fn->wifi_start_pkt_fate_monitoring = wifi_start_pkt_fate_monitoring;
217 fn->wifi_get_tx_pkt_fates = wifi_get_tx_pkt_fates;
218 fn->wifi_get_rx_pkt_fates = wifi_get_rx_pkt_fates;
219 fn->wifi_get_packet_filter_capabilities = wifi_get_packet_filter_capabilities;
220 fn->wifi_get_wake_reason_stats = wifi_get_wake_reason_stats;
221 fn->wifi_set_packet_filter = wifi_set_packet_filter;
222 fn->wifi_enable_firmware_roaming = wifi_enable_firmware_roaming;
223 fn->wifi_get_roaming_capabilities = wifi_get_roaming_capabilities;
224 fn->wifi_configure_roaming = wifi_configure_roaming;
225 fn->wifi_nan_register_handler = nan_register_handler;
226 fn->wifi_nan_enable_request = nan_enable_request;
227 fn->wifi_nan_disable_request = nan_disable_request;
228 fn->wifi_nan_publish_request = nan_publish_request;
229 fn->wifi_nan_publish_cancel_request = nan_publish_cancel_request;
230 fn->wifi_nan_subscribe_request = nan_subscribe_request;
231 fn->wifi_nan_subscribe_cancel_request = nan_subscribe_cancel_request;
232 fn->wifi_nan_transmit_followup_request = nan_transmit_followup_request;
233 fn->wifi_nan_stats_request = nan_stats_request;
234 fn->wifi_nan_config_request = nan_config_request;
235 fn->wifi_nan_tca_request = nan_tca_request;
236 fn->wifi_nan_beacon_sdf_payload_request = nan_beacon_sdf_payload_request;
237 fn->wifi_nan_get_version = nan_get_version;
238 fn->wifi_nan_get_capabilities = nan_get_capabilities;
239 fn->wifi_nan_data_interface_create = nan_data_interface_create;
240 fn->wifi_nan_data_interface_delete = nan_data_interface_delete;
241 fn->wifi_nan_data_request_initiator = nan_data_request_initiator;
242 fn->wifi_nan_data_indication_response = nan_data_indication_response;
243 fn->wifi_nan_data_end = nan_data_end;
244 fn->wifi_set_latency_mode = wifi_set_latency_mode;
245 #ifdef NAN_CLUSTER_MERGE
246 fn->wifi_nan_enable_merge_request = nan_enable_cluster_merge_request;
247 #endif /* NAN_CLUSTER_MERGE */
248 fn->wifi_select_tx_power_scenario = wifi_select_tx_power_scenario;
249 fn->wifi_reset_tx_power_scenario = wifi_reset_tx_power_scenario;
250
251 return WIFI_SUCCESS;
252 }
253
254 hal_info *halInfo = NULL;
wifi_pre_initialize(void)255 wifi_error wifi_pre_initialize(void)
256 {
257 srand(getpid());
258
259 int numIfaceHandles = 0;
260 wifi_interface_handle *ifaceHandles = NULL;
261 wifi_interface_handle wlan0Handle;
262 wifi_error result = WIFI_SUCCESS;
263 wifi_handle handle;
264
265 ALOGE("wifi_pre_initialize");
266 ALOGE("--- HAL version: %s ---\n", HAL_VERSION);
267 halInfo = (hal_info *)malloc(sizeof(hal_info));
268 if (halInfo == NULL) {
269 ALOGE("Could not allocate hal_info");
270 return WIFI_ERROR_UNKNOWN;
271 }
272
273 memset(halInfo, 0, sizeof(*halInfo));
274
275 ALOGI("Creating socket");
276 if (socketpair(AF_UNIX, SOCK_STREAM, 0, halInfo->cleanup_socks) == -1) {
277 ALOGE("Could not create cleanup sockets");
278 free(halInfo);
279 return WIFI_ERROR_UNKNOWN;
280 }
281
282 struct nl_sock *cmd_sock = wifi_create_nl_socket(WIFI_HAL_CMD_SOCK_PORT);
283 if (cmd_sock == NULL) {
284 ALOGE("Could not create handle");
285 free(halInfo);
286 return WIFI_ERROR_UNKNOWN;
287 }
288
289 /* Set the socket buffer size */
290 if (nl_socket_set_buffer_size(cmd_sock, (256*1024), 0) < 0) {
291 ALOGE("Could not set size for cmd_sock: %s",
292 strerror(errno));
293 } else {
294 ALOGV("nl_socket_set_buffer_size successful for cmd_sock");
295 }
296 struct nl_sock *event_sock = wifi_create_nl_socket(WIFI_HAL_EVENT_SOCK_PORT);
297 if (event_sock == NULL) {
298 ALOGE("Could not create handle");
299 nl_socket_free(cmd_sock);
300 free(halInfo);
301 return WIFI_ERROR_UNKNOWN;
302 }
303
304 /* Set the socket buffer size */
305 if (nl_socket_set_buffer_size(event_sock, (512*1024), 0) < 0) {
306 ALOGE("Could not set size for event_sock: %s",
307 strerror(errno));
308 } else {
309 ALOGV("nl_socket_set_buffer_size successful for event_sock");
310 }
311
312 struct nl_cb *cb = nl_socket_get_cb(event_sock);
313 if (cb == NULL) {
314 ALOGE("Could not create handle");
315 nl_socket_free(cmd_sock);
316 nl_socket_free(event_sock);
317 free(halInfo);
318 return WIFI_ERROR_UNKNOWN;
319 }
320
321 nl_cb_set(cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, internal_no_seq_check, halInfo);
322 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, internal_valid_message_handler, halInfo);
323 nl_cb_put(cb);
324
325 halInfo->cmd_sock = cmd_sock;
326 halInfo->event_sock = event_sock;
327 halInfo->clean_up = false;
328 halInfo->in_event_loop = false;
329
330 halInfo->event_cb = (cb_info *)malloc(sizeof(cb_info) * DEFAULT_EVENT_CB_SIZE);
331 halInfo->alloc_event_cb = DEFAULT_EVENT_CB_SIZE;
332 halInfo->num_event_cb = 0;
333
334 halInfo->cmd = (cmd_info *)malloc(sizeof(cmd_info) * DEFAULT_CMD_SIZE);
335 halInfo->alloc_cmd = DEFAULT_CMD_SIZE;
336 halInfo->num_cmd = 0;
337
338 halInfo->nl80211_family_id = genl_ctrl_resolve(cmd_sock, "nl80211");
339 if (halInfo->nl80211_family_id < 0) {
340 ALOGE("Could not resolve nl80211 familty id");
341 nl_socket_free(cmd_sock);
342 nl_socket_free(event_sock);
343 free(halInfo);
344 return WIFI_ERROR_UNKNOWN;
345 }
346
347 pthread_mutex_init(&halInfo->cb_lock, NULL);
348 InitResponseLock();
349
350 handle = (wifi_handle) halInfo;
351
352 if (wifi_init_interfaces(handle) != WIFI_SUCCESS) {
353 ALOGE("No wifi interface found");
354 nl_socket_free(cmd_sock);
355 nl_socket_free(event_sock);
356 pthread_mutex_destroy(&halInfo->cb_lock);
357 free(halInfo);
358 return WIFI_ERROR_NOT_AVAILABLE;
359 }
360
361 if ((wifi_add_membership(handle, "scan") < 0) ||
362 (wifi_add_membership(handle, "mlme") < 0) ||
363 (wifi_add_membership(handle, "regulatory") < 0) ||
364 (wifi_add_membership(handle, "vendor") < 0)) {
365 ALOGE("Add membership failed");
366 nl_socket_free(cmd_sock);
367 nl_socket_free(event_sock);
368 pthread_mutex_destroy(&halInfo->cb_lock);
369 free(halInfo);
370 return WIFI_ERROR_NOT_AVAILABLE;
371 }
372
373 ALOGI("Initialized Wifi HAL Successfully; vendor cmd = %d", NL80211_CMD_VENDOR);
374 wlan0Handle = wifi_get_wlan_interface((wifi_handle)halInfo, ifaceHandles, numIfaceHandles);
375
376 if (wlan0Handle != NULL) {
377 ALOGE("Calling preInit");
378 if (!get_halutil_mode()) {
379 result = wifi_hal_preInit(wlan0Handle);
380 if (result != WIFI_SUCCESS) {
381 ALOGE("wifi_hal_preInit failed");
382 }
383 }
384 }
385
386 return WIFI_SUCCESS;
387 }
388
wifi_initialize(wifi_handle * handle)389 wifi_error wifi_initialize(wifi_handle *handle)
390 {
391
392 int numIfaceHandles = 0;
393 wifi_interface_handle *ifaceHandles = NULL;
394 wifi_interface_handle wlan0Handle;
395 wifi_error result = WIFI_SUCCESS;
396
397 ALOGE("wifi_initialize");
398
399 if (halInfo == NULL) {
400 result = wifi_pre_initialize();
401 if (result != WIFI_SUCCESS) {
402 ALOGE("wifi_initialize wifi_pre_initialize failed");
403 return result;
404 } else {
405 ALOGE("wifi_initialize wifi_pre_initialize succeeded");
406 }
407 }
408
409 *handle = (wifi_handle) halInfo;
410 wlan0Handle = wifi_get_wlan_interface((wifi_handle)halInfo, ifaceHandles, numIfaceHandles);
411
412 if (wlan0Handle != NULL) {
413 ALOGE("Calling Hal_init");
414 if (!get_halutil_mode()) {
415 result = wifi_start_hal(wlan0Handle);
416 if (result != WIFI_SUCCESS) {
417 ALOGE("wifi_start_hal failed");
418 }
419 #ifdef FILE_DUMP
420 else {
421 ALOGE("Calling start file dump");
422 result = wifi_start_file_dump(wlan0Handle);
423 if (result != WIFI_SUCCESS) {
424 ALOGE("wifi_start_file_dump failed");
425 }
426 }
427 #endif /* FILE_DUMP */
428 }
429 } else {
430 ALOGI("Not Calling set alert handler as global_iface is NULL");
431 }
432 return WIFI_SUCCESS;
433 }
434
wifi_wait_for_driver_ready(void)435 wifi_error wifi_wait_for_driver_ready(void)
436 {
437 // This function will wait to make sure basic client netdev is created
438 // Function times out after 10 seconds
439 int count = (POLL_DRIVER_MAX_TIME_MS * 1000) / POLL_DRIVER_DURATION_US;
440 FILE *fd;
441
442 do {
443 if ((fd = fopen("/sys/class/net/wlan0", "r")) != NULL) {
444 fclose(fd);
445 wifi_pre_initialize();
446 return WIFI_SUCCESS;
447 }
448 usleep(POLL_DRIVER_DURATION_US);
449 } while(--count > 0);
450
451 ALOGE("Timed out waiting on Driver ready ... ");
452 return WIFI_ERROR_TIMED_OUT;
453 }
454
wifi_add_membership(wifi_handle handle,const char * group)455 static int wifi_add_membership(wifi_handle handle, const char *group)
456 {
457 hal_info *info = getHalInfo(handle);
458
459 int id = wifi_get_multicast_id(handle, "nl80211", group);
460 if (id < 0) {
461 ALOGE("Could not find group %s", group);
462 return id;
463 }
464
465 int ret = nl_socket_add_membership(info->event_sock, id);
466 if (ret < 0) {
467 ALOGE("Could not add membership to group %s", group);
468 }
469
470 // ALOGI("Successfully added membership for group %s", group);
471 return ret;
472 }
473
internal_cleaned_up_handler(wifi_handle handle)474 static void internal_cleaned_up_handler(wifi_handle handle)
475 {
476 hal_info *info = getHalInfo(handle);
477 wifi_cleaned_up_handler cleaned_up_handler = info->cleaned_up_handler;
478
479 ALOGI("internal clean up");
480
481 if (info->cmd_sock != 0) {
482 ALOGI("cmd_sock non null. clean up");
483 close(info->cleanup_socks[0]);
484 close(info->cleanup_socks[1]);
485 nl_socket_free(info->cmd_sock);
486 nl_socket_free(info->event_sock);
487 info->cmd_sock = NULL;
488 info->event_sock = NULL;
489 }
490
491 if (cleaned_up_handler) {
492 ALOGI("cleanup_handler cb");
493 (*cleaned_up_handler)(handle);
494 } else {
495 ALOGI("!! clean up handler is null!!");
496 }
497 DestroyResponseLock();
498 pthread_mutex_destroy(&info->cb_lock);
499 free(info);
500
501 ALOGI("Internal cleanup completed");
502 }
wifi_internal_module_cleanup()503 void wifi_internal_module_cleanup()
504 {
505 nan_deinit_handler();
506 }
507
wifi_cleanup(wifi_handle handle,wifi_cleaned_up_handler handler)508 void wifi_cleanup(wifi_handle handle, wifi_cleaned_up_handler handler)
509 {
510 hal_info *info = getHalInfo(handle);
511 char buf[64];
512 wifi_error result;
513
514 int numIfaceHandles = 0;
515 wifi_interface_handle *ifaceHandles = NULL;
516 wifi_interface_handle wlan0Handle;
517
518 info->cleaned_up_handler = handler;
519
520 wlan0Handle = wifi_get_wlan_interface((wifi_handle) info, ifaceHandles, numIfaceHandles);
521
522 if (wlan0Handle != NULL) {
523 ALOGE("Calling hal cleanup");
524 if (!get_halutil_mode()) {
525 result = wifi_stop_hal(wlan0Handle);
526 if (result != WIFI_SUCCESS) {
527 ALOGE("wifi_stop_hal failed");
528 }
529 }
530
531 #ifdef FILE_DUMP
532 ALOGE("Calling stop file dump");
533 result = wifi_stop_file_dump(wlan0Handle);
534 if (result != WIFI_SUCCESS) {
535 ALOGE("wifi_stop_file_dump failed");
536 }
537 #endif /* FILE_DUMP */
538 } else {
539 ALOGE("Not cleaning up hal as global_iface is NULL");
540 }
541
542 if (TEMP_FAILURE_RETRY(write(info->cleanup_socks[0], "Exit", 4)) < 1) {
543 // As a fallback set the cleanup flag to TRUE
544 ALOGE("could not write to the cleanup socket");
545 } else {
546 // Listen to the response
547 // Hopefully we dont get errors or get hung up
548 // Not much can be done in that case, but assume that
549 // it has rx'ed the Exit message to exit the thread.
550 // As a fallback set the cleanup flag to TRUE
551 memset(buf, 0, sizeof(buf));
552 ssize_t result = TEMP_FAILURE_RETRY(read(info->cleanup_socks[0], buf, sizeof(buf)));
553 ALOGE("%s: Read after POLL returned %zd, error no = %d (%s)", __FUNCTION__,
554 result, errno, strerror(errno));
555 if (strncmp(buf, "Done", 4) == 0) {
556 ALOGE("Event processing terminated");
557 } else {
558 ALOGD("Rx'ed %s", buf);
559 }
560 }
561 info->clean_up = true;
562 wifi_internal_module_cleanup();
563 ALOGI("wifi nan internal clean up done");
564 pthread_mutex_lock(&info->cb_lock);
565
566 int bad_commands = 0;
567
568 ALOGI("event_cb callbacks left: %d ", info->num_event_cb);
569 for (int i = 0; i < info->num_event_cb; i++) {
570 ALOGI("event_cb cleanup. index:%d", i);
571 cb_info *cbi = &(info->event_cb[i]);
572 if (!cbi) {
573 ALOGE("cbi null for index %d", i);
574 continue;
575 }
576 ALOGI("event_cb cleanup. vendor cmd:%d sub_cmd:%d", cbi->vendor_id, cbi->vendor_subcmd);
577 WifiCommand *cmd = (WifiCommand *)cbi->cb_arg;
578 if (cmd != NULL) {
579 ALOGI("Command left in event_cb %p", cmd);
580 }
581 }
582
583 ALOGI("Check bad commands: num_cmd:%d bad_commands:%d", info->num_cmd, bad_commands);
584 while (info->num_cmd > bad_commands) {
585 int num_cmd = info->num_cmd;
586 cmd_info *cmdi = &(info->cmd[bad_commands]);
587 WifiCommand *cmd = cmdi->cmd;
588 if (cmd != NULL) {
589 ALOGI("Cancelling command %p:%s", cmd, cmd->getType());
590 pthread_mutex_unlock(&info->cb_lock);
591 cmd->cancel();
592 pthread_mutex_lock(&info->cb_lock);
593 if (num_cmd == info->num_cmd) {
594 ALOGI("Cancelling command %p:%s did not work", cmd, (cmd ? cmd->getType(): ""));
595 bad_commands++;
596 }
597 /* release reference added when command is saved */
598 cmd->releaseRef();
599 }
600 }
601
602 for (int i = 0; i < info->num_event_cb; i++) {
603 cb_info *cbi = &(info->event_cb[i]);
604 if (!cbi) {
605 ALOGE("cbi null for index %d", i);
606 continue;
607 }
608 WifiCommand *cmd = (WifiCommand *)cbi->cb_arg;
609 ALOGE("Leaked command %p", cmd);
610 }
611 pthread_mutex_unlock(&info->cb_lock);
612 internal_cleaned_up_handler(handle);
613 ALOGE("wifi_clean_up done");
614 }
615
internal_pollin_handler(wifi_handle handle)616 static int internal_pollin_handler(wifi_handle handle)
617 {
618 hal_info *info = getHalInfo(handle);
619 struct nl_cb *cb = nl_socket_get_cb(info->event_sock);
620 int res = nl_recvmsgs(info->event_sock, cb);
621 // ALOGD("nl_recvmsgs returned %d", res);
622 nl_cb_put(cb);
623 return res;
624 }
625
626 /* Run event handler */
wifi_event_loop(wifi_handle handle)627 void wifi_event_loop(wifi_handle handle)
628 {
629 hal_info *info = getHalInfo(handle);
630 if (info->in_event_loop) {
631 return;
632 } else {
633 info->in_event_loop = true;
634 }
635
636 pollfd pfd[2];
637 memset(&pfd[0], 0, sizeof(pollfd) * 2);
638
639 pfd[0].fd = nl_socket_get_fd(info->event_sock);
640 pfd[0].events = POLLIN;
641 pfd[1].fd = info->cleanup_socks[1];
642 pfd[1].events = POLLIN;
643
644 char buf[2048];
645 /* TODO: Add support for timeouts */
646
647 do {
648 int timeout = -1; /* Infinite timeout */
649 pfd[0].revents = 0;
650 pfd[1].revents = 0;
651 // ALOGI("Polling socket");
652 int result = TEMP_FAILURE_RETRY(poll(pfd, 2, timeout));
653 if (result < 0) {
654 // ALOGE("Error polling socket");
655 } else if (pfd[0].revents & POLLERR) {
656 ALOGE("POLL Error; error no = %d (%s)", errno, strerror(errno));
657 ssize_t result2 = TEMP_FAILURE_RETRY(read(pfd[0].fd, buf, sizeof(buf)));
658 ALOGE("Read after POLL returned %zd, error no = %d (%s)", result2,
659 errno, strerror(errno));
660 } else if (pfd[0].revents & POLLHUP) {
661 ALOGE("Remote side hung up");
662 break;
663 } else if (pfd[0].revents & POLLIN) {
664 // ALOGI("Found some events!!!");
665 internal_pollin_handler(handle);
666 } else if (pfd[1].revents & POLLIN) {
667 memset(buf, 0, sizeof(buf));
668 ssize_t result2 = TEMP_FAILURE_RETRY(read(pfd[1].fd, buf, sizeof(buf)));
669 ALOGE("%s: Read after POLL returned %zd, error no = %d (%s)", __FUNCTION__,
670 result2, errno, strerror(errno));
671 if (strncmp(buf, "Exit", 4) == 0) {
672 ALOGD("Got a signal to exit!!!");
673 if (TEMP_FAILURE_RETRY(write(pfd[1].fd, "Done", 4)) < 1) {
674 ALOGE("could not write to the cleanup socket");
675 }
676 break;
677 } else {
678 ALOGD("Rx'ed %s on the cleanup socket\n", buf);
679 }
680 } else {
681 ALOGE("Unknown event - %0x, %0x", pfd[0].revents, pfd[1].revents);
682 }
683 } while (!info->clean_up);
684 ALOGI("Exit %s", __FUNCTION__);
685 }
686
687 ///////////////////////////////////////////////////////////////////////////////////////
688
internal_no_seq_check(struct nl_msg * msg,void * arg)689 static int internal_no_seq_check(struct nl_msg *msg, void *arg)
690 {
691 return NL_OK;
692 }
693
internal_valid_message_handler(nl_msg * msg,void * arg)694 static int internal_valid_message_handler(nl_msg *msg, void *arg)
695 {
696 // ALOGI("got an event");
697
698 wifi_handle handle = (wifi_handle)arg;
699 hal_info *info = getHalInfo(handle);
700
701 WifiEvent event(msg);
702 int res = event.parse();
703 if (res < 0) {
704 ALOGE("Failed to parse event: %d", res);
705 return NL_SKIP;
706 }
707
708 int cmd = event.get_cmd();
709 uint32_t vendor_id = 0;
710 int subcmd = 0;
711
712 if (cmd == NL80211_CMD_VENDOR) {
713 vendor_id = event.get_u32(NL80211_ATTR_VENDOR_ID);
714 subcmd = event.get_u32(NL80211_ATTR_VENDOR_SUBCMD);
715 ALOGV("event received %s, vendor_id = 0x%0x, subcmd = 0x%0x",
716 event.get_cmdString(), vendor_id, subcmd);
717 } else {
718 // ALOGV("event received %s", event.get_cmdString());
719 }
720
721 // ALOGV("event received %s, vendor_id = 0x%0x", event.get_cmdString(), vendor_id);
722 // event.log();
723
724 bool dispatched = false;
725
726 pthread_mutex_lock(&info->cb_lock);
727
728 for (int i = 0; i < info->num_event_cb; i++) {
729 if (cmd == info->event_cb[i].nl_cmd) {
730 if (cmd == NL80211_CMD_VENDOR
731 && ((vendor_id != info->event_cb[i].vendor_id)
732 || (subcmd != info->event_cb[i].vendor_subcmd)))
733 {
734 /* event for a different vendor, ignore it */
735 continue;
736 }
737
738 cb_info *cbi = &(info->event_cb[i]);
739 nl_recvmsg_msg_cb_t cb_func = cbi->cb_func;
740 void *cb_arg = cbi->cb_arg;
741 WifiCommand *cmd = (WifiCommand *)cbi->cb_arg;
742 if (cmd != NULL) {
743 cmd->addRef();
744 }
745 pthread_mutex_unlock(&info->cb_lock);
746 if (cb_func)
747 (*cb_func)(msg, cb_arg);
748 if (cmd != NULL) {
749 cmd->releaseRef();
750 }
751
752 return NL_OK;
753 }
754 }
755
756 pthread_mutex_unlock(&info->cb_lock);
757 return NL_OK;
758 }
759
760 ///////////////////////////////////////////////////////////////////////////////////////
761
762 class GetMulticastIdCommand : public WifiCommand
763 {
764 private:
765 const char *mName;
766 const char *mGroup;
767 int mId;
768 public:
GetMulticastIdCommand(wifi_handle handle,const char * name,const char * group)769 GetMulticastIdCommand(wifi_handle handle, const char *name, const char *group)
770 : WifiCommand("GetMulticastIdCommand", handle, 0)
771 {
772 mName = name;
773 mGroup = group;
774 mId = -1;
775 }
776
getId()777 int getId() {
778 return mId;
779 }
780
create()781 virtual int create() {
782 int nlctrlFamily = genl_ctrl_resolve(mInfo->cmd_sock, "nlctrl");
783 // ALOGI("ctrl family = %d", nlctrlFamily);
784 int ret = mMsg.create(nlctrlFamily, CTRL_CMD_GETFAMILY, 0, 0);
785 if (ret < 0) {
786 return ret;
787 }
788 ret = mMsg.put_string(CTRL_ATTR_FAMILY_NAME, mName);
789 return ret;
790 }
791
handleResponse(WifiEvent & reply)792 virtual int handleResponse(WifiEvent& reply) {
793
794 // ALOGI("handling reponse in %s", __func__);
795
796 struct nlattr **tb = reply.attributes();
797 struct genlmsghdr *gnlh = reply.header();
798 struct nlattr *mcgrp = NULL;
799 int i;
800
801 if (!tb[CTRL_ATTR_MCAST_GROUPS]) {
802 ALOGI("No multicast groups found");
803 return NL_SKIP;
804 } else {
805 // ALOGI("Multicast groups attr size = %d", nla_len(tb[CTRL_ATTR_MCAST_GROUPS]));
806 }
807
808 for_each_attr(mcgrp, tb[CTRL_ATTR_MCAST_GROUPS], i) {
809
810 // ALOGI("Processing group");
811 struct nlattr *tb2[CTRL_ATTR_MCAST_GRP_MAX + 1];
812 nla_parse(tb2, CTRL_ATTR_MCAST_GRP_MAX, (nlattr *)nla_data(mcgrp),
813 nla_len(mcgrp), NULL);
814 if (!tb2[CTRL_ATTR_MCAST_GRP_NAME] || !tb2[CTRL_ATTR_MCAST_GRP_ID]) {
815 continue;
816 }
817
818 char *grpName = (char *)nla_data(tb2[CTRL_ATTR_MCAST_GRP_NAME]);
819 int grpNameLen = nla_len(tb2[CTRL_ATTR_MCAST_GRP_NAME]);
820
821 // ALOGI("Found group name %s", grpName);
822
823 if (strncmp(grpName, mGroup, grpNameLen) != 0)
824 continue;
825
826 mId = nla_get_u32(tb2[CTRL_ATTR_MCAST_GRP_ID]);
827 break;
828 }
829
830 return NL_SKIP;
831 }
832
833 };
834
835 class SetPnoMacAddrOuiCommand : public WifiCommand {
836
837 private:
838 byte *mOui;
839 feature_set *fset;
840 feature_set *feature_matrix;
841 int *fm_size;
842 int set_size_max;
843 public:
SetPnoMacAddrOuiCommand(wifi_interface_handle handle,oui scan_oui)844 SetPnoMacAddrOuiCommand(wifi_interface_handle handle, oui scan_oui)
845 : WifiCommand("SetPnoMacAddrOuiCommand", handle, 0)
846 {
847 mOui = scan_oui;
848 fset = NULL;
849 feature_matrix = NULL;
850 fm_size = NULL;
851 set_size_max = 0;
852 }
853
createRequest(WifiRequest & request,int subcmd,byte * scan_oui)854 int createRequest(WifiRequest& request, int subcmd, byte *scan_oui) {
855 int result = request.create(GOOGLE_OUI, subcmd);
856 if (result < 0) {
857 return result;
858 }
859
860 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
861 result = request.put(ANDR_WIFI_ATTRIBUTE_PNO_RANDOM_MAC_OUI, scan_oui, DOT11_OUI_LEN);
862 if (result < 0) {
863 return result;
864 }
865
866 request.attr_end(data);
867 return WIFI_SUCCESS;
868
869 }
870
start()871 int start() {
872 ALOGD("Sending mac address OUI");
873 WifiRequest request(familyId(), ifaceId());
874 int result = createRequest(request, WIFI_SUBCMD_SET_PNO_RANDOM_MAC_OUI, mOui);
875 if (result != WIFI_SUCCESS) {
876 ALOGE("failed to create request; result = %d", result);
877 return result;
878 }
879
880 result = requestResponse(request);
881 if (result != WIFI_SUCCESS) {
882 ALOGE("failed to set scanning mac OUI; result = %d", result);
883 }
884
885 return result;
886 }
887 protected:
handleResponse(WifiEvent & reply)888 virtual int handleResponse(WifiEvent& reply) {
889 ALOGD("Request complete!");
890 /* Nothing to do on response! */
891 return NL_SKIP;
892 }
893 };
894
895 class SetNodfsCommand : public WifiCommand {
896
897 private:
898 u32 mNoDfs;
899 public:
SetNodfsCommand(wifi_interface_handle handle,u32 nodfs)900 SetNodfsCommand(wifi_interface_handle handle, u32 nodfs)
901 : WifiCommand("SetNodfsCommand", handle, 0) {
902 mNoDfs = nodfs;
903 }
create()904 virtual int create() {
905 int ret;
906
907 ret = mMsg.create(GOOGLE_OUI, WIFI_SUBCMD_NODFS_SET);
908 if (ret < 0) {
909 ALOGE("Can't create message to send to driver - %d", ret);
910 return ret;
911 }
912
913 nlattr *data = mMsg.attr_start(NL80211_ATTR_VENDOR_DATA);
914 ret = mMsg.put_u32(ANDR_WIFI_ATTRIBUTE_NODFS_SET, mNoDfs);
915 if (ret < 0) {
916 return ret;
917 }
918
919 mMsg.attr_end(data);
920 return WIFI_SUCCESS;
921 }
922 };
923
924 class SetCountryCodeCommand : public WifiCommand {
925 private:
926 const char *mCountryCode;
927 public:
SetCountryCodeCommand(wifi_interface_handle handle,const char * country_code)928 SetCountryCodeCommand(wifi_interface_handle handle, const char *country_code)
929 : WifiCommand("SetCountryCodeCommand", handle, 0) {
930 mCountryCode = country_code;
931 }
create()932 virtual int create() {
933 int ret;
934
935 ret = mMsg.create(GOOGLE_OUI, WIFI_SUBCMD_SET_COUNTRY_CODE);
936 if (ret < 0) {
937 ALOGE("Can't create message to send to driver - %d", ret);
938 return ret;
939 }
940
941 nlattr *data = mMsg.attr_start(NL80211_ATTR_VENDOR_DATA);
942 ret = mMsg.put_string(ANDR_WIFI_ATTRIBUTE_COUNTRY, mCountryCode);
943 if (ret < 0) {
944 return ret;
945 }
946
947 mMsg.attr_end(data);
948 return WIFI_SUCCESS;
949
950 }
951 };
952
953 class SetRSSIMonitorCommand : public WifiCommand {
954 private:
955 s8 mMax_rssi;
956 s8 mMin_rssi;
957 wifi_rssi_event_handler mHandler;
958 public:
SetRSSIMonitorCommand(wifi_request_id id,wifi_interface_handle handle,s8 max_rssi,s8 min_rssi,wifi_rssi_event_handler eh)959 SetRSSIMonitorCommand(wifi_request_id id, wifi_interface_handle handle,
960 s8 max_rssi, s8 min_rssi, wifi_rssi_event_handler eh)
961 : WifiCommand("SetRSSIMonitorCommand", handle, id), mMax_rssi(max_rssi), mMin_rssi
962 (min_rssi), mHandler(eh)
963 {
964 }
createRequest(WifiRequest & request,int enable)965 int createRequest(WifiRequest& request, int enable) {
966 int result = request.create(GOOGLE_OUI, WIFI_SUBCMD_SET_RSSI_MONITOR);
967 if (result < 0) {
968 return result;
969 }
970
971 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
972 result = request.put_u32(RSSI_MONITOR_ATTRIBUTE_MAX_RSSI, (enable ? mMax_rssi: 0));
973 if (result < 0) {
974 return result;
975 }
976 ALOGD("create request");
977 result = request.put_u32(RSSI_MONITOR_ATTRIBUTE_MIN_RSSI, (enable? mMin_rssi: 0));
978 if (result < 0) {
979 return result;
980 }
981 result = request.put_u32(RSSI_MONITOR_ATTRIBUTE_START, enable);
982 if (result < 0) {
983 return result;
984 }
985 request.attr_end(data);
986 return result;
987 }
988
start()989 int start() {
990 WifiRequest request(familyId(), ifaceId());
991 int result = createRequest(request, 1);
992 if (result < 0) {
993 return result;
994 }
995 result = requestResponse(request);
996 if (result < 0) {
997 ALOGI("Failed to set RSSI Monitor, result = %d", result);
998 return result;
999 }
1000 ALOGI("Successfully set RSSI monitoring");
1001 result = registerVendorHandler(GOOGLE_OUI, GOOGLE_RSSI_MONITOR_EVENT);
1002
1003
1004 if (result < 0) {
1005 unregisterVendorHandler(GOOGLE_OUI, GOOGLE_RSSI_MONITOR_EVENT);
1006 return result;
1007 }
1008 ALOGI("Done!");
1009 return result;
1010 }
1011
cancel()1012 virtual int cancel() {
1013
1014 WifiRequest request(familyId(), ifaceId());
1015 int result = createRequest(request, 0);
1016 if (result != WIFI_SUCCESS) {
1017 ALOGE("failed to create request; result = %d", result);
1018 } else {
1019 result = requestResponse(request);
1020 if (result != WIFI_SUCCESS) {
1021 ALOGE("failed to stop RSSI monitoring = %d", result);
1022 }
1023 }
1024 unregisterVendorHandler(GOOGLE_OUI, GOOGLE_RSSI_MONITOR_EVENT);
1025 return WIFI_SUCCESS;
1026 }
1027
handleResponse(WifiEvent & reply)1028 virtual int handleResponse(WifiEvent& reply) {
1029 /* Nothing to do on response! */
1030 return NL_SKIP;
1031 }
1032
handleEvent(WifiEvent & event)1033 virtual int handleEvent(WifiEvent& event) {
1034 ALOGI("Got a RSSI monitor event");
1035
1036 nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA);
1037 int len = event.get_vendor_data_len();
1038
1039 if (vendor_data == NULL || len == 0) {
1040 ALOGI("RSSI monitor: No data");
1041 return NL_SKIP;
1042 }
1043 /* driver<->HAL event structure */
1044 #define RSSI_MONITOR_EVT_VERSION 1
1045 typedef struct {
1046 u8 version;
1047 s8 cur_rssi;
1048 mac_addr BSSID;
1049 } rssi_monitor_evt;
1050
1051 rssi_monitor_evt *data = (rssi_monitor_evt *)event.get_vendor_data();
1052
1053 if (data->version != RSSI_MONITOR_EVT_VERSION) {
1054 ALOGI("Event version mismatch %d, expected %d", data->version, RSSI_MONITOR_EVT_VERSION);
1055 return NL_SKIP;
1056 }
1057
1058 if (*mHandler.on_rssi_threshold_breached) {
1059 (*mHandler.on_rssi_threshold_breached)(id(), data->BSSID, data->cur_rssi);
1060 } else {
1061 ALOGW("No RSSI monitor handler registered");
1062 }
1063
1064 return NL_SKIP;
1065 }
1066
1067 };
1068
1069 class AndroidPktFilterCommand : public WifiCommand {
1070 private:
1071 const u8* mProgram;
1072 u32 mProgramLen;
1073 u32* mVersion;
1074 u32* mMaxLen;
1075 int mReqType;
1076 public:
AndroidPktFilterCommand(wifi_interface_handle handle,u32 * version,u32 * max_len)1077 AndroidPktFilterCommand(wifi_interface_handle handle,
1078 u32* version, u32* max_len)
1079 : WifiCommand("AndroidPktFilterCommand", handle, 0),
1080 mVersion(version), mMaxLen(max_len),
1081 mReqType(GET_APF_CAPABILITIES)
1082 {
1083 mProgram = NULL;
1084 mProgramLen = 0;
1085 }
1086
AndroidPktFilterCommand(wifi_interface_handle handle,const u8 * program,u32 len)1087 AndroidPktFilterCommand(wifi_interface_handle handle,
1088 const u8* program, u32 len)
1089 : WifiCommand("AndroidPktFilterCommand", handle, 0),
1090 mProgram(program), mProgramLen(len),
1091 mReqType(SET_APF_PROGRAM)
1092 {
1093 mVersion = NULL;
1094 mMaxLen = NULL;
1095 }
1096
createRequest(WifiRequest & request)1097 int createRequest(WifiRequest& request) {
1098 if (mReqType == SET_APF_PROGRAM) {
1099 ALOGI("\n%s: APF set program request\n", __FUNCTION__);
1100 return createSetPktFilterRequest(request);
1101 } else if (mReqType == GET_APF_CAPABILITIES) {
1102 ALOGI("\n%s: APF get capabilities request\n", __FUNCTION__);
1103 return createGetPktFilterCapabilitesRequest(request);
1104 } else {
1105 ALOGE("\n%s Unknown APF request\n", __FUNCTION__);
1106 return WIFI_ERROR_NOT_SUPPORTED;
1107 }
1108 return WIFI_SUCCESS;
1109 }
1110
createSetPktFilterRequest(WifiRequest & request)1111 int createSetPktFilterRequest(WifiRequest& request) {
1112 u8 *program = new u8[mProgramLen];
1113 NULL_CHECK_RETURN(program, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
1114 int result = request.create(GOOGLE_OUI, APF_SUBCMD_SET_FILTER);
1115 if (result < 0) {
1116 delete[] program;
1117 return result;
1118 }
1119
1120 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
1121 result = request.put_u32(APF_ATTRIBUTE_PROGRAM_LEN, mProgramLen);
1122 if (result < 0) {
1123 goto exit;
1124 }
1125 memcpy(program, mProgram, mProgramLen);
1126 result = request.put(APF_ATTRIBUTE_PROGRAM, program, mProgramLen);
1127 if (result < 0) {
1128 goto exit;
1129 }
1130 exit: request.attr_end(data);
1131 delete[] program;
1132 return result;
1133 }
1134
createGetPktFilterCapabilitesRequest(WifiRequest & request)1135 int createGetPktFilterCapabilitesRequest(WifiRequest& request) {
1136 int result = request.create(GOOGLE_OUI, APF_SUBCMD_GET_CAPABILITIES);
1137 if (result < 0) {
1138 return result;
1139 }
1140
1141 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
1142 request.attr_end(data);
1143 return result;
1144 }
1145
start()1146 int start() {
1147 WifiRequest request(familyId(), ifaceId());
1148 int result = createRequest(request);
1149 if (result < 0) {
1150 return result;
1151 }
1152 result = requestResponse(request);
1153 if (result < 0) {
1154 ALOGI("Request Response failed for APF, result = %d", result);
1155 return result;
1156 }
1157 ALOGI("Done!");
1158 return result;
1159 }
1160
cancel()1161 int cancel() {
1162 return WIFI_SUCCESS;
1163 }
1164
handleResponse(WifiEvent & reply)1165 int handleResponse(WifiEvent& reply) {
1166 ALOGD("In SetAPFCommand::handleResponse");
1167
1168 if (reply.get_cmd() != NL80211_CMD_VENDOR) {
1169 ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
1170 return NL_SKIP;
1171 }
1172
1173 int id = reply.get_vendor_id();
1174 int subcmd = reply.get_vendor_subcmd();
1175
1176 nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA);
1177 int len = reply.get_vendor_data_len();
1178
1179 ALOGD("Id = %0x, subcmd = %d, len = %d", id, subcmd, len);
1180 if (vendor_data == NULL || len == 0) {
1181 ALOGE("no vendor data in SetAPFCommand response; ignoring it");
1182 return NL_SKIP;
1183 }
1184 if( mReqType == SET_APF_PROGRAM) {
1185 ALOGD("Response recieved for set packet filter command\n");
1186 } else if (mReqType == GET_APF_CAPABILITIES) {
1187 *mVersion = 0;
1188 *mMaxLen = 0;
1189 ALOGD("Response recieved for get packet filter capabilities command\n");
1190 for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
1191 if (it.get_type() == APF_ATTRIBUTE_VERSION) {
1192 *mVersion = it.get_u32();
1193 ALOGI("APF version is %d\n", *mVersion);
1194 } else if (it.get_type() == APF_ATTRIBUTE_MAX_LEN) {
1195 *mMaxLen = it.get_u32();
1196 ALOGI("APF max len is %d\n", *mMaxLen);
1197 } else {
1198 ALOGE("Ignoring invalid attribute type = %d, size = %d",
1199 it.get_type(), it.get_len());
1200 }
1201 }
1202 }
1203 return NL_OK;
1204 }
1205
handleEvent(WifiEvent & event)1206 int handleEvent(WifiEvent& event) {
1207 /* No Event to recieve for APF commands */
1208 return NL_SKIP;
1209 }
1210 };
1211
1212 class SetNdoffloadCommand : public WifiCommand {
1213
1214 private:
1215 u8 mEnable;
1216 public:
SetNdoffloadCommand(wifi_interface_handle handle,u8 enable)1217 SetNdoffloadCommand(wifi_interface_handle handle, u8 enable)
1218 : WifiCommand("SetNdoffloadCommand", handle, 0) {
1219 mEnable = enable;
1220 }
create()1221 virtual int create() {
1222 int ret;
1223
1224 ret = mMsg.create(GOOGLE_OUI, WIFI_SUBCMD_CONFIG_ND_OFFLOAD);
1225 if (ret < 0) {
1226 ALOGE("Can't create message to send to driver - %d", ret);
1227 return ret;
1228 }
1229
1230 nlattr *data = mMsg.attr_start(NL80211_ATTR_VENDOR_DATA);
1231 ret = mMsg.put_u8(ANDR_WIFI_ATTRIBUTE_ND_OFFLOAD_VALUE, mEnable);
1232 if (ret < 0) {
1233 return ret;
1234 }
1235
1236 mMsg.attr_end(data);
1237 return WIFI_SUCCESS;
1238 }
1239 };
1240
1241 class GetFeatureSetCommand : public WifiCommand {
1242
1243 private:
1244 int feature_type;
1245 feature_set *fset;
1246 feature_set *feature_matrix;
1247 int *fm_size;
1248 int set_size_max;
1249 public:
GetFeatureSetCommand(wifi_interface_handle handle,int feature,feature_set * set,feature_set set_matrix[],int * size,int max_size)1250 GetFeatureSetCommand(wifi_interface_handle handle, int feature, feature_set *set,
1251 feature_set set_matrix[], int *size, int max_size)
1252 : WifiCommand("GetFeatureSetCommand", handle, 0) {
1253 feature_type = feature;
1254 fset = set;
1255 feature_matrix = set_matrix;
1256 fm_size = size;
1257 set_size_max = max_size;
1258 }
1259
create()1260 virtual int create() {
1261 int ret;
1262
1263 if(feature_type == ANDR_WIFI_ATTRIBUTE_NUM_FEATURE_SET) {
1264 ret = mMsg.create(GOOGLE_OUI, WIFI_SUBCMD_GET_FEATURE_SET);
1265 } else if (feature_type == ANDR_WIFI_ATTRIBUTE_FEATURE_SET) {
1266 ret = mMsg.create(GOOGLE_OUI, WIFI_SUBCMD_GET_FEATURE_SET_MATRIX);
1267 } else {
1268 ALOGE("Unknown feature type %d", feature_type);
1269 return -1;
1270 }
1271
1272 if (ret < 0) {
1273 ALOGE("Can't create message to send to driver - %d", ret);
1274 }
1275
1276 return ret;
1277 }
1278
1279 protected:
handleResponse(WifiEvent & reply)1280 virtual int handleResponse(WifiEvent& reply) {
1281
1282 ALOGV("In GetFeatureSetCommand::handleResponse");
1283
1284 if (reply.get_cmd() != NL80211_CMD_VENDOR) {
1285 ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
1286 return NL_SKIP;
1287 }
1288
1289 int id = reply.get_vendor_id();
1290 int subcmd = reply.get_vendor_subcmd();
1291
1292 nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA);
1293 int len = reply.get_vendor_data_len();
1294
1295 ALOGV("Id = %0x, subcmd = %d, len = %d", id, subcmd, len);
1296 if (vendor_data == NULL || len == 0) {
1297 ALOGE("no vendor data in GetFeatureSetCommand response; ignoring it");
1298 return NL_SKIP;
1299 }
1300 if(feature_type == ANDR_WIFI_ATTRIBUTE_NUM_FEATURE_SET) {
1301 void *data = reply.get_vendor_data();
1302 if(!fset) {
1303 ALOGE("Buffers pointers not set");
1304 return NL_SKIP;
1305 }
1306 memcpy(fset, data, min(len, (int) sizeof(*fset)));
1307 } else {
1308 int num_features_set = 0;
1309 int i = 0;
1310
1311 if(!feature_matrix || !fm_size) {
1312 ALOGE("Buffers pointers not set");
1313 return NL_SKIP;
1314 }
1315
1316 for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
1317 if (it.get_type() == ANDR_WIFI_ATTRIBUTE_NUM_FEATURE_SET) {
1318 num_features_set = it.get_u32();
1319 ALOGV("Got feature list with %d concurrent sets", num_features_set);
1320 if(set_size_max && (num_features_set > set_size_max))
1321 num_features_set = set_size_max;
1322 *fm_size = num_features_set;
1323 } else if ((it.get_type() == ANDR_WIFI_ATTRIBUTE_FEATURE_SET) &&
1324 i < num_features_set) {
1325 feature_matrix[i] = it.get_u32();
1326 i++;
1327 } else {
1328 ALOGW("Ignoring invalid attribute type = %d, size = %d",
1329 it.get_type(), it.get_len());
1330 }
1331 }
1332
1333 }
1334 return NL_OK;
1335 }
1336
1337 };
1338
1339 class SetLatencyModeCommand : public WifiCommand {
1340 private:
1341 u32 mLatencyMode;
1342 public:
SetLatencyModeCommand(wifi_interface_handle handle,u32 LatencyMode)1343 SetLatencyModeCommand(wifi_interface_handle handle, u32 LatencyMode)
1344 : WifiCommand("SetLatencyModeCommand", handle, 0) {
1345 mLatencyMode = LatencyMode;
1346 }
1347
create()1348 virtual int create() {
1349 int ret;
1350
1351 /* Check for invalid latency Mode */
1352 if ((mLatencyMode != WIFI_LATENCY_MODE_NORMAL) &&
1353 (mLatencyMode != WIFI_LATENCY_MODE_LOW)) {
1354 ALOGE("SetLatencyModeCommand: Invalid mode: %d", mLatencyMode);
1355 return WIFI_ERROR_UNKNOWN;
1356 }
1357
1358 ret = mMsg.create(GOOGLE_OUI, WIFI_SUBCMD_SET_LATENCY_MODE);
1359 if (ret < 0) {
1360 ALOGE("Can't create message to send to driver - %d", ret);
1361 return ret;
1362 }
1363
1364 nlattr *data = mMsg.attr_start(NL80211_ATTR_VENDOR_DATA);
1365 ret = mMsg.put_u32(ANDR_WIFI_ATTRIBUTE_LATENCY_MODE, mLatencyMode);
1366 if (ret < 0) {
1367 return ret;
1368 }
1369
1370 mMsg.attr_end(data);
1371 return WIFI_SUCCESS;
1372 }
1373 };
wifi_get_multicast_id(wifi_handle handle,const char * name,const char * group)1374 static int wifi_get_multicast_id(wifi_handle handle, const char *name, const char *group)
1375 {
1376 GetMulticastIdCommand cmd(handle, name, group);
1377 int res = cmd.requestResponse();
1378 if (res < 0)
1379 return res;
1380 else
1381 return cmd.getId();
1382 }
1383
1384 /////////////////////////////////////////////////////////////////////////
1385
is_wifi_interface(const char * name)1386 static bool is_wifi_interface(const char *name)
1387 {
1388 if (strncmp(name, "wlan", 4) != 0 && strncmp(name, "swlan", 5) != 0 && strncmp(name, "p2p", 3) != 0) {
1389 /* not a wifi interface; ignore it */
1390 return false;
1391 } else {
1392 return true;
1393 }
1394 }
1395
get_interface(const char * name,interface_info * info)1396 static int get_interface(const char *name, interface_info *info)
1397 {
1398 strlcpy(info->name, name, sizeof(info->name));
1399 info->id = if_nametoindex(name);
1400 // ALOGI("found an interface : %s, id = %d", name, info->id);
1401 return WIFI_SUCCESS;
1402 }
1403
wifi_init_interfaces(wifi_handle handle)1404 wifi_error wifi_init_interfaces(wifi_handle handle)
1405 {
1406 hal_info *info = (hal_info *)handle;
1407
1408 struct dirent *de;
1409
1410 DIR *d = opendir("/sys/class/net");
1411 if (d == 0)
1412 return WIFI_ERROR_UNKNOWN;
1413
1414 int n = 0;
1415 while ((de = readdir(d))) {
1416 if (de->d_name[0] == '.')
1417 continue;
1418 if (is_wifi_interface(de->d_name) ) {
1419 n++;
1420 }
1421 }
1422
1423 closedir(d);
1424
1425 if (n == 0)
1426 return WIFI_ERROR_NOT_AVAILABLE;
1427
1428 d = opendir("/sys/class/net");
1429 if (d == 0)
1430 return WIFI_ERROR_UNKNOWN;
1431
1432 info->interfaces = (interface_info **)malloc(sizeof(interface_info *) * n);
1433 if (!info->interfaces) {
1434 info->num_interfaces = 0;
1435 closedir(d);
1436 return WIFI_ERROR_OUT_OF_MEMORY;
1437 }
1438
1439 int i = 0;
1440 while ((de = readdir(d))) {
1441 if (de->d_name[0] == '.')
1442 continue;
1443 if (is_wifi_interface(de->d_name)) {
1444 interface_info *ifinfo = (interface_info *)malloc(sizeof(interface_info));
1445 if (!ifinfo) {
1446 free(info->interfaces);
1447 info->num_interfaces = 0;
1448 closedir(d);
1449 return WIFI_ERROR_OUT_OF_MEMORY;
1450 }
1451 if (get_interface(de->d_name, ifinfo) != WIFI_SUCCESS) {
1452 free(ifinfo);
1453 continue;
1454 }
1455 ifinfo->handle = handle;
1456 info->interfaces[i] = ifinfo;
1457 i++;
1458 }
1459 }
1460
1461 closedir(d);
1462
1463 info->num_interfaces = n;
1464 return WIFI_SUCCESS;
1465 }
1466
wifi_get_ifaces(wifi_handle handle,int * num,wifi_interface_handle ** interfaces)1467 wifi_error wifi_get_ifaces(wifi_handle handle, int *num, wifi_interface_handle **interfaces)
1468 {
1469 hal_info *info = (hal_info *)handle;
1470
1471 *interfaces = (wifi_interface_handle *)info->interfaces;
1472 *num = info->num_interfaces;
1473
1474 return WIFI_SUCCESS;
1475 }
1476
wifi_get_wlan_interface(wifi_handle info,wifi_interface_handle * ifaceHandles,int numIfaceHandles)1477 wifi_interface_handle wifi_get_wlan_interface(wifi_handle info, wifi_interface_handle *ifaceHandles, int numIfaceHandles)
1478 {
1479 char buf[EVENT_BUF_SIZE];
1480 wifi_interface_handle wlan0Handle;
1481 wifi_error res = wifi_get_ifaces((wifi_handle)info, &numIfaceHandles, &ifaceHandles);
1482 if (res < 0) {
1483 return NULL;
1484 }
1485 for (int i = 0; i < numIfaceHandles; i++) {
1486 if (wifi_get_iface_name(ifaceHandles[i], buf, sizeof(buf)) == WIFI_SUCCESS) {
1487 if (strcmp(buf, "wlan0") == 0) {
1488 ALOGI("found interface %s\n", buf);
1489 wlan0Handle = ifaceHandles[i];
1490 return wlan0Handle;
1491 }
1492 }
1493 }
1494 return NULL;
1495 }
wifi_get_iface_name(wifi_interface_handle handle,char * name,size_t size)1496 wifi_error wifi_get_iface_name(wifi_interface_handle handle, char *name, size_t size)
1497 {
1498 interface_info *info = (interface_info *)handle;
1499 strncpy(name, info->name, (IFNAMSIZ));
1500 name[IFNAMSIZ - 1] = '\0';
1501 return WIFI_SUCCESS;
1502 }
1503
wifi_get_supported_feature_set(wifi_interface_handle handle,feature_set * set)1504 wifi_error wifi_get_supported_feature_set(wifi_interface_handle handle, feature_set *set)
1505 {
1506 GetFeatureSetCommand command(handle, ANDR_WIFI_ATTRIBUTE_NUM_FEATURE_SET, set, NULL, NULL, 1);
1507 return (wifi_error) command.requestResponse();
1508 }
1509
wifi_get_concurrency_matrix(wifi_interface_handle handle,int set_size_max,feature_set set[],int * set_size)1510 wifi_error wifi_get_concurrency_matrix(wifi_interface_handle handle, int set_size_max,
1511 feature_set set[], int *set_size)
1512 {
1513 GetFeatureSetCommand command(handle, ANDR_WIFI_ATTRIBUTE_FEATURE_SET, NULL,
1514 set, set_size, set_size_max);
1515 return (wifi_error) command.requestResponse();
1516 }
1517
wifi_set_scanning_mac_oui(wifi_interface_handle handle,oui scan_oui)1518 wifi_error wifi_set_scanning_mac_oui(wifi_interface_handle handle, oui scan_oui)
1519 {
1520 SetPnoMacAddrOuiCommand command(handle, scan_oui);
1521 return (wifi_error)command.start();
1522
1523 }
1524
wifi_set_nodfs_flag(wifi_interface_handle handle,u32 nodfs)1525 wifi_error wifi_set_nodfs_flag(wifi_interface_handle handle, u32 nodfs)
1526 {
1527 SetNodfsCommand command(handle, nodfs);
1528 return (wifi_error) command.requestResponse();
1529 }
1530
wifi_set_country_code(wifi_interface_handle handle,const char * country_code)1531 wifi_error wifi_set_country_code(wifi_interface_handle handle, const char *country_code)
1532 {
1533 SetCountryCodeCommand command(handle, country_code);
1534 return (wifi_error) command.requestResponse();
1535 }
1536
wifi_start_rssi_monitoring(wifi_request_id id,wifi_interface_handle iface,s8 max_rssi,s8 min_rssi,wifi_rssi_event_handler eh)1537 static wifi_error wifi_start_rssi_monitoring(wifi_request_id id, wifi_interface_handle
1538 iface, s8 max_rssi, s8 min_rssi, wifi_rssi_event_handler eh)
1539 {
1540 ALOGD("Start RSSI monitor %d", id);
1541 wifi_handle handle = getWifiHandle(iface);
1542 SetRSSIMonitorCommand *cmd = new SetRSSIMonitorCommand(id, iface, max_rssi, min_rssi, eh);
1543 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
1544 wifi_error result = wifi_register_cmd(handle, id, cmd);
1545 if (result != WIFI_SUCCESS) {
1546 cmd->releaseRef();
1547 return result;
1548 }
1549 result = (wifi_error)cmd->start();
1550 if (result != WIFI_SUCCESS) {
1551 wifi_unregister_cmd(handle, id);
1552 cmd->releaseRef();
1553 return result;
1554 }
1555 return result;
1556 }
1557
wifi_stop_rssi_monitoring(wifi_request_id id,wifi_interface_handle iface)1558 static wifi_error wifi_stop_rssi_monitoring(wifi_request_id id, wifi_interface_handle iface)
1559 {
1560 ALOGD("Stopping RSSI monitor");
1561
1562 if(id == -1) {
1563 wifi_rssi_event_handler handler;
1564 s8 max_rssi = 0, min_rssi = 0;
1565 wifi_handle handle = getWifiHandle(iface);
1566 memset(&handler, 0, sizeof(handler));
1567 SetRSSIMonitorCommand *cmd = new SetRSSIMonitorCommand(id, iface,
1568 max_rssi, min_rssi, handler);
1569 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
1570 cmd->cancel();
1571 cmd->releaseRef();
1572 return WIFI_SUCCESS;
1573 }
1574 return wifi_cancel_cmd(id, iface);
1575 }
1576
wifi_get_packet_filter_capabilities(wifi_interface_handle handle,u32 * version,u32 * max_len)1577 static wifi_error wifi_get_packet_filter_capabilities(wifi_interface_handle handle,
1578 u32 *version, u32 *max_len)
1579 {
1580 ALOGD("Getting APF capabilities, halHandle = %p\n", handle);
1581 AndroidPktFilterCommand *cmd = new AndroidPktFilterCommand(handle, version, max_len);
1582 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
1583 wifi_error result = (wifi_error)cmd->start();
1584 if (result == WIFI_SUCCESS) {
1585 ALOGD("Getting APF capability, version = %d, max_len = %d\n", *version, *max_len);
1586 }
1587 cmd->releaseRef();
1588 return result;
1589 }
1590
wifi_set_packet_filter(wifi_interface_handle handle,const u8 * program,u32 len)1591 static wifi_error wifi_set_packet_filter(wifi_interface_handle handle,
1592 const u8 *program, u32 len)
1593 {
1594 ALOGD("Setting APF program, halHandle = %p\n", handle);
1595 AndroidPktFilterCommand *cmd = new AndroidPktFilterCommand(handle, program, len);
1596 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
1597 wifi_error result = (wifi_error)cmd->start();
1598 cmd->releaseRef();
1599 return result;
1600 }
1601
wifi_configure_nd_offload(wifi_interface_handle handle,u8 enable)1602 static wifi_error wifi_configure_nd_offload(wifi_interface_handle handle, u8 enable)
1603 {
1604 SetNdoffloadCommand command(handle, enable);
1605 return (wifi_error) command.requestResponse();
1606 }
wifi_set_latency_mode(wifi_interface_handle handle,wifi_latency_mode mode)1607 wifi_error wifi_set_latency_mode(wifi_interface_handle handle, wifi_latency_mode mode)
1608 {
1609 ALOGD("Setting Wifi Latency mode, halHandle = %p LatencyMode = %d\n", handle, mode);
1610 SetLatencyModeCommand command(handle, mode);
1611 return (wifi_error) command.requestResponse();
1612 }
1613
1614 /////////////////////////////////////////////////////////////////////////
1615 class TxPowerScenario : public WifiCommand {
1616 wifi_power_scenario mScenario;
1617 public:
1618 // constructor for tx power scenario setting
TxPowerScenario(wifi_interface_handle handle,wifi_power_scenario scenario)1619 TxPowerScenario(wifi_interface_handle handle, wifi_power_scenario scenario)
1620 : WifiCommand("TxPowerScenario", handle, 0), mScenario(scenario)
1621 {
1622 mScenario = scenario;
1623 }
1624
1625 // constructor for tx power scenario resetting
TxPowerScenario(wifi_interface_handle handle)1626 TxPowerScenario(wifi_interface_handle handle)
1627 : WifiCommand("TxPowerScenario", handle, 0)
1628 {
1629 mScenario = WIFI_POWER_SCENARIO_DEFAULT;
1630 }
1631
createRequest(WifiRequest & request,int subcmd,wifi_power_scenario mScenario)1632 int createRequest(WifiRequest& request, int subcmd, wifi_power_scenario mScenario) {
1633 int result = request.create(GOOGLE_OUI, subcmd);
1634 if (result < 0) {
1635 return result;
1636 }
1637
1638 if ((mScenario <= WIFI_POWER_SCENARIO_INVALID) ||
1639 (mScenario > WIFI_POWER_SCENARIO_ON_BODY_BT)) {
1640 ALOGE("Unsupported tx power value:%d\n", mScenario);
1641 return WIFI_ERROR_NOT_SUPPORTED;
1642 }
1643
1644 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
1645 result = request.put_s8(ANDR_WIFI_ATTRIBUTE_TX_POWER_SCENARIO, mScenario);
1646 if (result < 0) {
1647 ALOGE("Failed to put tx power scenario request; result = %d", result);
1648 return result;
1649 }
1650 request.attr_end(data);
1651 return WIFI_SUCCESS;
1652 }
1653
start(wifi_power_scenario mScenario)1654 int start(wifi_power_scenario mScenario) {
1655 WifiRequest request(familyId(), ifaceId());
1656 int result = createRequest(request, WIFI_SUBCMD_TX_POWER_SCENARIO, mScenario);
1657 if (result != WIFI_SUCCESS) {
1658 ALOGE("failed to create request; result = %d", result);
1659 return result;
1660 }
1661
1662 result = requestResponse(request);
1663 if (result != WIFI_SUCCESS) {
1664 ALOGE("failed to send tx power scenario; result = %d", result);
1665 }
1666 return result;
1667 }
1668 protected:
handleResponse(WifiEvent & reply)1669 virtual int handleResponse(WifiEvent& reply) {
1670 ALOGD("Request complete!");
1671 /* Nothing to do on response! */
1672 return NL_SKIP;
1673 }
1674 };
1675
1676
wifi_select_tx_power_scenario(wifi_interface_handle handle,wifi_power_scenario scenario)1677 wifi_error wifi_select_tx_power_scenario(wifi_interface_handle handle, wifi_power_scenario scenario)
1678 {
1679 ALOGE("wifi_select_tx_power_scenario");
1680 TxPowerScenario command(handle);
1681 return (wifi_error)command.start(scenario);
1682 }
1683
wifi_reset_tx_power_scenario(wifi_interface_handle handle)1684 wifi_error wifi_reset_tx_power_scenario(wifi_interface_handle handle)
1685 {
1686 wifi_power_scenario scenario = WIFI_POWER_SCENARIO_DEFAULT;
1687 ALOGE("wifi_reset_tx_power_scenario");
1688 TxPowerScenario command(handle);
1689 return (wifi_error)command.start(scenario);
1690 }
1691
1692 /////////////////////////////////////////////////////////////////////////////
1693