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