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