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