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