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