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         close(info->cleanup_socks[1]);
630         nl_socket_free(info->cmd_sock);
631         nl_socket_free(info->event_sock);
632         info->cmd_sock = NULL;
633         info->event_sock = NULL;
634     }
635 
636     if (info->interfaces) {
637         for (int i = 0; i < info->num_interfaces; i++) {
638             free(info->interfaces[i]);
639         }
640         free(info->interfaces);
641     }
642 
643     DestroyResponseLock();
644     pthread_mutex_destroy(&info->cb_lock);
645     free(info);
646 
647     ALOGI("Internal cleanup completed");
648 }
649 
wifi_internal_module_cleanup()650 void wifi_internal_module_cleanup()
651 {
652     nan_deinit_handler();
653     twt_deinit_handler();
654 }
655 
wifi_cleanup(wifi_handle handle,wifi_cleaned_up_handler cleaned_up_handler)656 void wifi_cleanup(wifi_handle handle, wifi_cleaned_up_handler cleaned_up_handler)
657 {
658     if (!handle) {
659         ALOGE("Handle is null");
660         return;
661     }
662 
663     hal_info *info = getHalInfo(handle);
664     wifi_error result;
665 
666     int numIfaceHandles = 0;
667     wifi_interface_handle *ifaceHandles = NULL;
668     wifi_interface_handle wlan0Handle;
669 
670     wlan0Handle = wifi_get_wlan_interface((wifi_handle) info, ifaceHandles, numIfaceHandles);
671 
672     if (wlan0Handle != NULL) {
673         ALOGE("Calling hal cleanup");
674         if (!get_halutil_mode()) {
675             wifi_cleanup_dynamic_ifaces(handle);
676             ALOGI("Cleaned dynamic virtual ifaces\n");
677             result = wifi_stop_hal(wlan0Handle);
678             if (result != WIFI_SUCCESS) {
679                 ALOGE("wifi_stop_hal failed");
680             }
681             ALOGI("wifi_stop_hal success");
682         }
683 
684     } else {
685         ALOGE("Not cleaning up hal as global_iface is NULL");
686     }
687 
688     /* calling internal modules or cleanup */
689     wifi_internal_module_cleanup();
690     pthread_mutex_lock(&info->cb_lock);
691 
692     int bad_commands = 0;
693 
694     ALOGI("event_cb callbacks left: %d ", info->num_event_cb);
695     for (int i = 0; i < info->num_event_cb; i++) {
696         ALOGI("event_cb cleanup. index:%d", i);
697         cb_info *cbi = &(info->event_cb[i]);
698         if (!cbi) {
699             ALOGE("cbi null for index %d", i);
700             continue;
701         }
702         ALOGI("event_cb cleanup. vendor cmd:%d sub_cmd:%d", cbi->vendor_id, cbi->vendor_subcmd);
703         WifiCommand *cmd = (WifiCommand *)cbi->cb_arg;
704         if (cmd != NULL) {
705             ALOGI("Command left in event_cb %p", cmd);
706         }
707     }
708 
709     ALOGI("Check bad commands: num_cmd:%d bad_commands:%d", info->num_cmd, bad_commands);
710     while (info->num_cmd > bad_commands) {
711         int num_cmd = info->num_cmd;
712         cmd_info *cmdi = &(info->cmd[bad_commands]);
713         WifiCommand *cmd = cmdi->cmd;
714         if (cmd != NULL) {
715             ALOGI("Cancelling command %p: %s", cmd, cmd->getType());
716             pthread_mutex_unlock(&info->cb_lock);
717             cmd->cancel();
718             if (num_cmd == info->num_cmd) {
719                 ALOGI("Cancelling command %p: %s did not work",
720                     cmd, (cmd ? cmd->getType(): ""));
721                 bad_commands++;
722             }
723             /* release reference added when command is saved */
724             cmd->releaseRef();
725             pthread_mutex_lock(&info->cb_lock);
726         }
727     }
728 
729     for (int i = 0; i < info->num_event_cb; i++) {
730         cb_info *cbi = &(info->event_cb[i]);
731         if (!cbi) {
732             ALOGE("cbi null for index %d", i);
733             continue;
734         }
735         WifiCommand *cmd = (WifiCommand *)cbi->cb_arg;
736         ALOGE("Leaked command %p", cmd);
737     }
738     pthread_mutex_unlock(&info->cb_lock);
739 
740     info->clean_up = true;
741 
742     /* global func ptr be invalidated and will not call any command from legacy hal */
743     if (cleaned_up_handler) {
744         ALOGI("cleaned_up_handler to invalidates func ptr");
745         cleaned_up_handler(handle);
746     } else {
747         ALOGI("cleaned up handler is null");
748     }
749 
750     if (TEMP_FAILURE_RETRY(write(info->cleanup_socks[0], "Exit", 4)) < 1) {
751         // As a fallback set the cleanup flag to TRUE
752         ALOGE("could not write to the cleanup socket");
753     }
754     ALOGE("wifi_clean_up done");
755 }
756 
internal_pollin_handler(wifi_handle handle)757 static int internal_pollin_handler(wifi_handle handle)
758 {
759     hal_info *info = getHalInfo(handle);
760     struct nl_cb *cb = nl_socket_get_cb(info->event_sock);
761     int res = nl_recvmsgs(info->event_sock, cb);
762     if (res) {
763         ALOGE("nl_recvmsgs returned %d", res);
764     }
765     nl_cb_put(cb);
766     return res;
767 }
768 
769 /* Run event handler */
wifi_event_loop(wifi_handle handle)770 void wifi_event_loop(wifi_handle handle)
771 {
772     hal_info *info = getHalInfo(handle);
773     if (info->in_event_loop) {
774         return;
775     } else {
776         info->in_event_loop = true;
777     }
778 
779     pollfd pfd[2];
780     memset(&pfd[0], 0, sizeof(pollfd) * 2);
781 
782     pfd[0].fd = nl_socket_get_fd(info->event_sock);
783     pfd[0].events = POLLIN;
784     pfd[1].fd = info->cleanup_socks[1];
785     pfd[1].events = POLLIN;
786 
787     char buf[2048];
788     /* TODO: Add support for timeouts */
789 
790     do {
791         int timeout = -1;                   /* Infinite timeout */
792         pfd[0].revents = 0;
793         pfd[1].revents = 0;
794         // ALOGI("Polling socket");
795         int result = TEMP_FAILURE_RETRY(poll(pfd, 2, timeout));
796         if (result < 0) {
797             // ALOGE("Error polling socket");
798         } else if (pfd[0].revents & POLLERR) {
799             ALOGE("POLL Error; error no = %d (%s)", errno, strerror(errno));
800             ssize_t result2 = TEMP_FAILURE_RETRY(read(pfd[0].fd, buf, sizeof(buf)));
801             ALOGE("Read after POLL returned %zd, error no = %d (%s)", result2,
802                   errno, strerror(errno));
803             if (errno == WIFI_HAL_EVENT_BUFFER_NOT_AVAILABLE) {
804                 ALOGE("Exit, No buffer space");
805                 break;
806             }
807         } else if (pfd[0].revents & POLLHUP) {
808             ALOGE("Remote side hung up");
809             break;
810         } else if (pfd[0].revents & POLLIN && !info->clean_up) {
811             // ALOGI("Found some events!!!");
812             internal_pollin_handler(handle);
813         } else if (pfd[1].revents & POLLIN) {
814             ALOGI("Got a signal to exit!!!");
815         } else {
816             ALOGE("Unknown event - %0x, %0x", pfd[0].revents, pfd[1].revents);
817         }
818     } while (!info->clean_up);
819 
820     internal_cleaned_up_handler(handle);
821     ALOGE("Exit %s", __FUNCTION__);
822 }
823 
824 ///////////////////////////////////////////////////////////////////////////////////////
825 
internal_no_seq_check(struct nl_msg * msg,void * arg)826 static int internal_no_seq_check(struct nl_msg *msg, void *arg)
827 {
828     return NL_OK;
829 }
830 
internal_valid_message_handler(nl_msg * msg,void * arg)831 static int internal_valid_message_handler(nl_msg *msg, void *arg)
832 {
833     // ALOGI("got an event");
834 
835     wifi_handle handle = (wifi_handle)arg;
836     hal_info *info = getHalInfo(handle);
837 
838     WifiEvent event(msg);
839     int res = event.parse();
840     if (res < 0) {
841         ALOGE("Failed to parse event: %d", res);
842         return NL_SKIP;
843     }
844 
845     int cmd = event.get_cmd();
846     uint32_t vendor_id = 0;
847     int subcmd = 0;
848 
849     if (cmd == NL80211_CMD_VENDOR) {
850         vendor_id = event.get_u32(NL80211_ATTR_VENDOR_ID);
851         subcmd = event.get_u32(NL80211_ATTR_VENDOR_SUBCMD);
852         ALOGV("event received %s, vendor_id = 0x%0x, subcmd = 0x%0x",
853                 event.get_cmdString(), vendor_id, subcmd);
854     } else {
855         // ALOGV("event received %s", event.get_cmdString());
856     }
857 
858     // ALOGV("event received %s, vendor_id = 0x%0x", event.get_cmdString(), vendor_id);
859     // event.log();
860 
861     pthread_mutex_lock(&info->cb_lock);
862 
863     for (int i = 0; i < info->num_event_cb; i++) {
864         if (cmd == info->event_cb[i].nl_cmd) {
865             if (cmd == NL80211_CMD_VENDOR
866                 && ((vendor_id != info->event_cb[i].vendor_id)
867                 || (subcmd != info->event_cb[i].vendor_subcmd)))
868             {
869                 /* event for a different vendor, ignore it */
870                 continue;
871             }
872 
873             cb_info *cbi = &(info->event_cb[i]);
874             nl_recvmsg_msg_cb_t cb_func = cbi->cb_func;
875             void *cb_arg = cbi->cb_arg;
876             WifiCommand *cmd = (WifiCommand *)cbi->cb_arg;
877             if (cmd != NULL) {
878                 cmd->addRef();
879             }
880             pthread_mutex_unlock(&info->cb_lock);
881             if (cb_func)
882                 (*cb_func)(msg, cb_arg);
883             if (cmd != NULL) {
884                 cmd->releaseRef();
885             }
886 
887             return NL_OK;
888         }
889     }
890 
891     pthread_mutex_unlock(&info->cb_lock);
892     return NL_OK;
893 }
894 
895 ///////////////////////////////////////////////////////////////////////////////////////
896 
897 class GetMulticastIdCommand : public WifiCommand
898 {
899 private:
900     const char *mName;
901     const char *mGroup;
902     int   mId;
903 public:
GetMulticastIdCommand(wifi_handle handle,const char * name,const char * group)904     GetMulticastIdCommand(wifi_handle handle, const char *name, const char *group)
905         : WifiCommand("GetMulticastIdCommand", handle, 0)
906     {
907         mName = name;
908         mGroup = group;
909         mId = -1;
910     }
911 
getId()912     int getId() {
913         return mId;
914     }
915 
create()916     virtual int create() {
917         int nlctrlFamily = genl_ctrl_resolve(mInfo->cmd_sock, "nlctrl");
918         // ALOGI("ctrl family = %d", nlctrlFamily);
919         int ret = mMsg.create(nlctrlFamily, CTRL_CMD_GETFAMILY, 0, 0);
920         if (ret < 0) {
921             return ret;
922         }
923         ret = mMsg.put_string(CTRL_ATTR_FAMILY_NAME, mName);
924         return ret;
925     }
926 
handleResponse(WifiEvent & reply)927     virtual int handleResponse(WifiEvent& reply) {
928 
929         // ALOGI("handling reponse in %s", __func__);
930 
931         struct nlattr **tb = reply.attributes();
932         struct nlattr *mcgrp = NULL;
933         int i;
934 
935         if (!tb[CTRL_ATTR_MCAST_GROUPS]) {
936             ALOGI("No multicast groups found");
937             return NL_SKIP;
938         } else {
939             // ALOGI("Multicast groups attr size = %d", nla_len(tb[CTRL_ATTR_MCAST_GROUPS]));
940         }
941 
942         for_each_attr(mcgrp, tb[CTRL_ATTR_MCAST_GROUPS], i) {
943 
944             // ALOGI("Processing group");
945             struct nlattr *tb2[CTRL_ATTR_MCAST_GRP_MAX + 1];
946             nla_parse(tb2, CTRL_ATTR_MCAST_GRP_MAX, (nlattr *)nla_data(mcgrp),
947                 nla_len(mcgrp), NULL);
948             if (!tb2[CTRL_ATTR_MCAST_GRP_NAME] || !tb2[CTRL_ATTR_MCAST_GRP_ID]) {
949                 continue;
950             }
951 
952             char *grpName = (char *)nla_data(tb2[CTRL_ATTR_MCAST_GRP_NAME]);
953             int grpNameLen = nla_len(tb2[CTRL_ATTR_MCAST_GRP_NAME]);
954 
955             // ALOGI("Found group name %s", grpName);
956 
957             if (strncmp(grpName, mGroup, grpNameLen) != 0)
958                 continue;
959 
960             mId = nla_get_u32(tb2[CTRL_ATTR_MCAST_GRP_ID]);
961             break;
962         }
963 
964         return NL_SKIP;
965     }
966 
967 };
968 
969 class SetPnoMacAddrOuiCommand : public WifiCommand {
970 
971 private:
972     byte *mOui;
973     feature_set *fset;
974     feature_set *feature_matrix;
975     int *fm_size;
976     int set_size_max;
977 public:
SetPnoMacAddrOuiCommand(wifi_interface_handle handle,oui scan_oui)978     SetPnoMacAddrOuiCommand(wifi_interface_handle handle, oui scan_oui)
979         : WifiCommand("SetPnoMacAddrOuiCommand", handle, 0)
980     {
981         mOui = scan_oui;
982         fset = NULL;
983         feature_matrix = NULL;
984         fm_size = NULL;
985         set_size_max = 0;
986     }
987 
createRequest(WifiRequest & request,int subcmd,byte * scan_oui)988     int createRequest(WifiRequest& request, int subcmd, byte *scan_oui) {
989         int result = request.create(GOOGLE_OUI, subcmd);
990         if (result < 0) {
991             return result;
992         }
993 
994         nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
995         result = request.put(ANDR_WIFI_ATTRIBUTE_PNO_RANDOM_MAC_OUI, scan_oui, DOT11_OUI_LEN);
996         if (result < 0) {
997             return result;
998         }
999 
1000         request.attr_end(data);
1001         return WIFI_SUCCESS;
1002 
1003     }
1004 
start()1005     int start() {
1006         ALOGD("Sending mac address OUI");
1007         WifiRequest request(familyId(), ifaceId());
1008         int result = createRequest(request, WIFI_SUBCMD_SET_PNO_RANDOM_MAC_OUI, mOui);
1009         if (result != WIFI_SUCCESS) {
1010             ALOGE("failed to create request; result = %d", result);
1011             return result;
1012         }
1013 
1014         result = requestResponse(request);
1015         if (result != WIFI_SUCCESS) {
1016             ALOGE("failed to set scanning mac OUI; result = %d", result);
1017         }
1018 
1019         return result;
1020     }
1021 protected:
handleResponse(WifiEvent & reply)1022     virtual int handleResponse(WifiEvent& reply) {
1023          ALOGD("Request complete!");
1024         /* Nothing to do on response! */
1025         return NL_SKIP;
1026     }
1027 };
1028 
1029 class SetNodfsCommand : public WifiCommand {
1030 
1031 private:
1032     u32 mNoDfs;
1033 public:
SetNodfsCommand(wifi_interface_handle handle,u32 nodfs)1034     SetNodfsCommand(wifi_interface_handle handle, u32 nodfs)
1035         : WifiCommand("SetNodfsCommand", handle, 0) {
1036         mNoDfs = nodfs;
1037     }
create()1038     virtual int create() {
1039         int ret;
1040 
1041         ret = mMsg.create(GOOGLE_OUI, WIFI_SUBCMD_NODFS_SET);
1042         if (ret < 0) {
1043             ALOGE("Can't create message to send to driver - %d", ret);
1044             return ret;
1045         }
1046 
1047         nlattr *data = mMsg.attr_start(NL80211_ATTR_VENDOR_DATA);
1048         ret = mMsg.put_u32(ANDR_WIFI_ATTRIBUTE_NODFS_SET, mNoDfs);
1049         if (ret < 0) {
1050              return ret;
1051         }
1052 
1053         mMsg.attr_end(data);
1054         return WIFI_SUCCESS;
1055     }
1056 };
1057 
1058 class SetCountryCodeCommand : public WifiCommand {
1059 private:
1060     const char *mCountryCode;
1061 public:
SetCountryCodeCommand(wifi_interface_handle handle,const char * country_code)1062     SetCountryCodeCommand(wifi_interface_handle handle, const char *country_code)
1063         : WifiCommand("SetCountryCodeCommand", handle, 0) {
1064         mCountryCode = country_code;
1065         }
create()1066     virtual int create() {
1067         int ret;
1068 
1069         ret = mMsg.create(GOOGLE_OUI, WIFI_SUBCMD_SET_COUNTRY_CODE);
1070         if (ret < 0) {
1071              ALOGE("Can't create message to send to driver - %d", ret);
1072              return ret;
1073         }
1074 
1075         nlattr *data = mMsg.attr_start(NL80211_ATTR_VENDOR_DATA);
1076         ret = mMsg.put_string(ANDR_WIFI_ATTRIBUTE_COUNTRY, mCountryCode);
1077         if (ret < 0) {
1078             return ret;
1079         }
1080 
1081         mMsg.attr_end(data);
1082         return WIFI_SUCCESS;
1083 
1084     }
1085 };
1086 
1087 class SetRSSIMonitorCommand : public WifiCommand {
1088 private:
1089     s8 mMax_rssi;
1090     s8 mMin_rssi;
1091     wifi_rssi_event_handler mHandler;
1092 public:
SetRSSIMonitorCommand(wifi_request_id id,wifi_interface_handle handle,s8 max_rssi,s8 min_rssi,wifi_rssi_event_handler eh)1093     SetRSSIMonitorCommand(wifi_request_id id, wifi_interface_handle handle,
1094                 s8 max_rssi, s8 min_rssi, wifi_rssi_event_handler eh)
1095         : WifiCommand("SetRSSIMonitorCommand", handle, id), mMax_rssi(max_rssi), mMin_rssi
1096         (min_rssi), mHandler(eh)
1097         {
1098             ALOGI("SetRSSIMonitorCommand %p created", this);
1099         }
1100 
~SetRSSIMonitorCommand()1101    virtual ~SetRSSIMonitorCommand() {
1102         /*
1103          * Mostly, this call will be no effect. However, this could be valid
1104          * when object destroy without calling unregisterVendorHandler().
1105          * This is added to protect hal crash due to use-after-free.
1106          */
1107         ALOGI("Try to remove event handler if exist, vendor 0x%0x, subcmd 0x%x",
1108             GOOGLE_OUI, GOOGLE_RSSI_MONITOR_EVENT);
1109         unregisterVendorHandler(GOOGLE_OUI, GOOGLE_RSSI_MONITOR_EVENT);
1110         ALOGI("SetRSSIMonitorCommand %p destroyed", this);
1111    }
1112 
addRef()1113    virtual void addRef() {
1114         int refs = __sync_add_and_fetch(&mRefs, 1);
1115         ALOGI("addRef: WifiCommand %p has %d references", this, refs);
1116    }
1117 
releaseRef()1118    virtual void releaseRef() {
1119         int refs = __sync_sub_and_fetch(&mRefs, 1);
1120         if (refs == 0) {
1121             ALOGI("releaseRef: WifiCommand %p has deleted", this);
1122             delete this;
1123         } else {
1124             ALOGI("releaseRef: WifiCommand %p has %d references", this, refs);
1125         }
1126    }
1127 
createRequest(WifiRequest & request,int enable)1128    int createRequest(WifiRequest& request, int enable) {
1129         int result = request.create(GOOGLE_OUI, WIFI_SUBCMD_SET_RSSI_MONITOR);
1130         if (result < 0) {
1131             return result;
1132         }
1133 
1134         nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
1135         result = request.put_u32(RSSI_MONITOR_ATTRIBUTE_MAX_RSSI, (enable ? mMax_rssi: 0));
1136         if (result < 0) {
1137             return result;
1138         }
1139         ALOGD("create request");
1140         result = request.put_u32(RSSI_MONITOR_ATTRIBUTE_MIN_RSSI, (enable? mMin_rssi: 0));
1141         if (result < 0) {
1142             return result;
1143         }
1144         result = request.put_u32(RSSI_MONITOR_ATTRIBUTE_START, enable);
1145         if (result < 0) {
1146             return result;
1147         }
1148         request.attr_end(data);
1149         return result;
1150     }
1151 
start()1152     int start() {
1153         WifiRequest request(familyId(), ifaceId());
1154         int result = createRequest(request, 1);
1155         if (result != WIFI_SUCCESS) {
1156             ALOGE("Failed to create request; result = %d", result);
1157             return result;
1158         }
1159 
1160         registerVendorHandler(GOOGLE_OUI, GOOGLE_RSSI_MONITOR_EVENT);
1161         ALOGI("Register GOOGLE_RSSI_MONITOR_EVENT handler");
1162 
1163         result = requestResponse(request);
1164         if (result != WIFI_SUCCESS) {
1165             unregisterVendorHandler(GOOGLE_OUI, GOOGLE_RSSI_MONITOR_EVENT);
1166             ALOGE("Failed to set RSSI Monitor, result = %d", result);
1167             return result;
1168         }
1169 
1170         ALOGI("Successfully set RSSI monitoring");
1171         return result;
1172     }
1173 
cancel()1174     virtual int cancel() {
1175         unregisterVendorHandler(GOOGLE_OUI, GOOGLE_RSSI_MONITOR_EVENT);
1176 
1177         WifiRequest request(familyId(), ifaceId());
1178         int result = createRequest(request, 0);
1179         if (result != WIFI_SUCCESS) {
1180             ALOGE("failed to create request; result = %d", result);
1181         } else {
1182             result = requestResponse(request);
1183             if (result != WIFI_SUCCESS) {
1184                 ALOGE("failed to stop RSSI monitoring = %d", result);
1185             }
1186         }
1187         return WIFI_SUCCESS;
1188     }
1189 
handleResponse(WifiEvent & reply)1190     virtual int handleResponse(WifiEvent& reply) {
1191         /* Nothing to do on response! */
1192         return NL_SKIP;
1193     }
1194 
handleEvent(WifiEvent & event)1195    virtual int handleEvent(WifiEvent& event) {
1196         ALOGI("Got a RSSI monitor event");
1197 
1198         nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA);
1199         int len = event.get_vendor_data_len();
1200 
1201         if (vendor_data == NULL || len == 0) {
1202             ALOGI("RSSI monitor: No data");
1203             return NL_SKIP;
1204         }
1205         /* driver<->HAL event structure */
1206         #define RSSI_MONITOR_EVT_VERSION   1
1207         typedef struct {
1208             u8 version;
1209             s8 cur_rssi;
1210             mac_addr BSSID;
1211         } rssi_monitor_evt;
1212 
1213         rssi_monitor_evt *data = (rssi_monitor_evt *)event.get_vendor_data();
1214 
1215         if (data->version != RSSI_MONITOR_EVT_VERSION) {
1216             ALOGI("Event version mismatch %d, expected %d", data->version, RSSI_MONITOR_EVT_VERSION);
1217             return NL_SKIP;
1218         }
1219 
1220         if (*mHandler.on_rssi_threshold_breached) {
1221             (*mHandler.on_rssi_threshold_breached)(id(), data->BSSID, data->cur_rssi);
1222         } else {
1223             ALOGW("No RSSI monitor handler registered");
1224         }
1225 
1226         return NL_SKIP;
1227     }
1228 
1229 };
1230 
1231 class AndroidPktFilterCommand : public WifiCommand {
1232     private:
1233         const u8* mProgram;
1234         u8* mReadProgram;
1235         u32 mProgramLen;
1236         u32* mVersion;
1237         u32* mMaxLen;
1238         int mReqType;
1239     public:
AndroidPktFilterCommand(wifi_interface_handle handle,u32 * version,u32 * max_len)1240         AndroidPktFilterCommand(wifi_interface_handle handle,
1241                 u32* version, u32* max_len)
1242             : WifiCommand("AndroidPktFilterCommand", handle, 0),
1243                     mVersion(version), mMaxLen(max_len),
1244                     mReqType(GET_APF_CAPABILITIES)
1245         {
1246             mProgram = NULL;
1247             mProgramLen = 0;
1248             mReadProgram = NULL;
1249         }
1250 
AndroidPktFilterCommand(wifi_interface_handle handle,const u8 * program,u32 len)1251         AndroidPktFilterCommand(wifi_interface_handle handle,
1252                 const u8* program, u32 len)
1253             : WifiCommand("AndroidPktFilterCommand", handle, 0),
1254                     mProgram(program), mProgramLen(len),
1255                     mReqType(SET_APF_PROGRAM)
1256         {
1257             mVersion = NULL;
1258             mMaxLen = NULL;
1259             mReadProgram = NULL;
1260         }
1261 
AndroidPktFilterCommand(wifi_interface_handle handle,u8 * host_dst,u32 length)1262         AndroidPktFilterCommand(wifi_interface_handle handle,
1263             u8* host_dst, u32 length)
1264             : WifiCommand("AndroidPktFilterCommand", handle, 0),
1265                 mReadProgram(host_dst), mProgramLen(length),
1266                 mReqType(READ_APF_PROGRAM)
1267         {
1268             mProgram = NULL;
1269             mVersion = NULL;
1270             mMaxLen = NULL;
1271         }
1272 
createRequest(WifiRequest & request)1273     int createRequest(WifiRequest& request) {
1274         if (mReqType == SET_APF_PROGRAM) {
1275             ALOGI("%s: APF set program request\n", __FUNCTION__);
1276             return createSetPktFilterRequest(request);
1277         } else if (mReqType == GET_APF_CAPABILITIES) {
1278             ALOGI("%s: APF get capabilities request\n", __FUNCTION__);
1279 	    return createGetPktFilterCapabilitesRequest(request);
1280         } else if (mReqType == READ_APF_PROGRAM) {
1281             ALOGI("%s: APF read packet filter request\n", __FUNCTION__);
1282             return createReadPktFilterRequest(request);
1283         } else {
1284             ALOGE("%s Unknown APF request\n", __FUNCTION__);
1285             return WIFI_ERROR_NOT_SUPPORTED;
1286         }
1287         return WIFI_SUCCESS;
1288     }
1289 
createSetPktFilterRequest(WifiRequest & request)1290     int createSetPktFilterRequest(WifiRequest& request) {
1291         u8 *program = new u8[mProgramLen];
1292         int result;
1293 
1294         NULL_CHECK_RETURN(program, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
1295 
1296         ALOGI("mProgramLen : %d\n", mProgramLen);
1297         if (mProgramLen > NL_MSG_DEFAULT_LEN) {
1298             result = request.create_custom_len(GOOGLE_OUI, APF_SUBCMD_SET_FILTER,
1299                     NL_MSG_MAX_LEN);
1300         } else {
1301             result = request.create(GOOGLE_OUI, APF_SUBCMD_SET_FILTER);
1302         }
1303         if (result < 0) {
1304             ALOGE("Failed to create cmd: %d, err %d\n", APF_SUBCMD_SET_FILTER, result);
1305             delete[] program;
1306             return result;
1307         }
1308 
1309         nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
1310         result = request.put_u32(APF_ATTRIBUTE_PROGRAM_LEN, mProgramLen);
1311         if (result < 0) {
1312             ALOGE("Failed to put the program_len %d, err %d\n", mProgramLen, result);
1313             goto exit;
1314         }
1315         memcpy(program, mProgram, mProgramLen);
1316         result = request.put(APF_ATTRIBUTE_PROGRAM, program, mProgramLen);
1317         if (result < 0) {
1318             ALOGE("Failed to copy program_ptr %d, err %d\n", mProgramLen, result);
1319             goto exit;
1320         }
1321 exit:   request.attr_end(data);
1322         delete[] program;
1323         return result;
1324     }
1325 
createGetPktFilterCapabilitesRequest(WifiRequest & request)1326     int createGetPktFilterCapabilitesRequest(WifiRequest& request) {
1327         int result = request.create(GOOGLE_OUI, APF_SUBCMD_GET_CAPABILITIES);
1328         if (result < 0) {
1329             return result;
1330         }
1331 
1332         nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
1333         request.attr_end(data);
1334         return result;
1335     }
1336 
createReadPktFilterRequest(WifiRequest & request)1337     int createReadPktFilterRequest(WifiRequest& request) {
1338         int result = request.create(GOOGLE_OUI, APF_SUBCMD_READ_FILTER);
1339             if (result < 0) {
1340                 return result;
1341             }
1342             nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
1343             request.attr_end(data);
1344             return result;
1345     }
1346 
start()1347     int start() {
1348         WifiRequest request(familyId(), ifaceId());
1349         int result = createRequest(request);
1350         if (result < 0) {
1351             ALOGI("CreateRequest failed for APF, result = %d", result);
1352             return result;
1353         }
1354         result = requestResponse(request);
1355         if (result < 0) {
1356             ALOGI("Request Response failed for APF, result = %d", result);
1357             return result;
1358         }
1359         return result;
1360     }
1361 
cancel()1362     int cancel() {
1363         return WIFI_SUCCESS;
1364     }
1365 
handleResponse(WifiEvent & reply)1366     int handleResponse(WifiEvent& reply) {
1367         ALOGE("In SetAPFCommand::handleResponse mReqType %d\n", mReqType);
1368 
1369         if (reply.get_cmd() != NL80211_CMD_VENDOR) {
1370             ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
1371             return NL_SKIP;
1372         }
1373 
1374         int id = reply.get_vendor_id();
1375         int subcmd = reply.get_vendor_subcmd();
1376 
1377         nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA);
1378         int len = reply.get_vendor_data_len();
1379 
1380         ALOGI("Id = %0x, subcmd = %d, len = %d", id, subcmd, len);
1381         if (vendor_data == NULL || len == 0) {
1382             ALOGE("no vendor data in SetAPFCommand response; ignoring it");
1383             return NL_SKIP;
1384         }
1385         if (mReqType == SET_APF_PROGRAM) {
1386             ALOGE("Response received for set packet filter command\n");
1387         } else if (mReqType == GET_APF_CAPABILITIES) {
1388             *mVersion = 0;
1389             *mMaxLen = 0;
1390             ALOGD("Response received for get packet filter capabilities command\n");
1391             for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
1392                 if (it.get_type() == APF_ATTRIBUTE_VERSION) {
1393                     *mVersion = it.get_u32();
1394                     ALOGI("APF version is %d\n", *mVersion);
1395                 } else if (it.get_type() == APF_ATTRIBUTE_MAX_LEN) {
1396                     *mMaxLen = it.get_u32();
1397                     ALOGI("APF max len is %d\n", *mMaxLen);
1398                 } else {
1399                     ALOGE("Ignoring invalid attribute type = %d, size = %d",
1400                             it.get_type(), it.get_len());
1401                 }
1402             }
1403         } else if (mReqType == READ_APF_PROGRAM) {
1404             ALOGD("Read packet filter, mProgramLen = %d\n", mProgramLen);
1405             for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
1406                 if (it.get_type() == APF_ATTRIBUTE_PROGRAM) {
1407                     u8 *buffer = NULL;
1408                     buffer = (u8 *)it.get_data();
1409                     memcpy(mReadProgram, buffer, mProgramLen);
1410                 } else if (it.get_type() == APF_ATTRIBUTE_PROGRAM_LEN) {
1411                     int apf_length = it.get_u32();
1412                     ALOGD("apf program length = %d\n", apf_length);
1413                 }
1414             }
1415         }
1416         return NL_OK;
1417     }
1418 
handleEvent(WifiEvent & event)1419     int handleEvent(WifiEvent& event) {
1420         /* No Event to receive for APF commands */
1421         return NL_SKIP;
1422     }
1423 };
1424 
1425 class SetNdoffloadCommand : public WifiCommand {
1426 
1427 private:
1428     u8 mEnable;
1429 public:
SetNdoffloadCommand(wifi_interface_handle handle,u8 enable)1430     SetNdoffloadCommand(wifi_interface_handle handle, u8 enable)
1431         : WifiCommand("SetNdoffloadCommand", handle, 0) {
1432         mEnable = enable;
1433     }
create()1434     virtual int create() {
1435         int ret;
1436 
1437         ret = mMsg.create(GOOGLE_OUI, WIFI_SUBCMD_CONFIG_ND_OFFLOAD);
1438         if (ret < 0) {
1439             ALOGE("Can't create message to send to driver - %d", ret);
1440             return ret;
1441         }
1442 
1443         nlattr *data = mMsg.attr_start(NL80211_ATTR_VENDOR_DATA);
1444         ret = mMsg.put_u8(ANDR_WIFI_ATTRIBUTE_ND_OFFLOAD_VALUE, mEnable);
1445         if (ret < 0) {
1446              return ret;
1447         }
1448 
1449         mMsg.attr_end(data);
1450         return WIFI_SUCCESS;
1451     }
1452 };
1453 
1454 class GetFeatureSetCommand : public WifiCommand {
1455 
1456 private:
1457     int feature_type;
1458     feature_set *fset;
1459     feature_set *feature_matrix;
1460     int *fm_size;
1461     int set_size_max;
1462 public:
GetFeatureSetCommand(wifi_interface_handle handle,int feature,feature_set * set,feature_set set_matrix[],int * size,int max_size)1463     GetFeatureSetCommand(wifi_interface_handle handle, int feature, feature_set *set,
1464          feature_set set_matrix[], int *size, int max_size)
1465         : WifiCommand("GetFeatureSetCommand", handle, 0) {
1466         feature_type = feature;
1467         fset = set;
1468         feature_matrix = set_matrix;
1469         fm_size = size;
1470         set_size_max = max_size;
1471     }
1472 
create()1473     virtual int create() {
1474         int ret;
1475 
1476         if(feature_type == ANDR_WIFI_ATTRIBUTE_NUM_FEATURE_SET) {
1477             ret = mMsg.create(GOOGLE_OUI, WIFI_SUBCMD_GET_FEATURE_SET);
1478         } else if (feature_type == ANDR_WIFI_ATTRIBUTE_FEATURE_SET) {
1479             ret = mMsg.create(GOOGLE_OUI, WIFI_SUBCMD_GET_FEATURE_SET_MATRIX);
1480         } else {
1481             ALOGE("Unknown feature type %d", feature_type);
1482             return -1;
1483         }
1484 
1485         if (ret < 0) {
1486             ALOGE("Can't create message to send to driver - %d", ret);
1487         }
1488 
1489         return ret;
1490     }
1491 
1492 protected:
handleResponse(WifiEvent & reply)1493     virtual int handleResponse(WifiEvent& reply) {
1494 
1495         ALOGV("In GetFeatureSetCommand::handleResponse");
1496 
1497         if (reply.get_cmd() != NL80211_CMD_VENDOR) {
1498             ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
1499             return NL_SKIP;
1500         }
1501 
1502         int id = reply.get_vendor_id();
1503         int subcmd = reply.get_vendor_subcmd();
1504 
1505         nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA);
1506         int len = reply.get_vendor_data_len();
1507 
1508         ALOGV("Id = %0x, subcmd = %d, len = %d", id, subcmd, len);
1509         if (vendor_data == NULL || len == 0) {
1510             ALOGE("no vendor data in GetFeatureSetCommand response; ignoring it");
1511             return NL_SKIP;
1512         }
1513         if(feature_type == ANDR_WIFI_ATTRIBUTE_NUM_FEATURE_SET) {
1514             void *data = reply.get_vendor_data();
1515             if(!fset) {
1516                 ALOGE("Buffers pointers not set");
1517                 return NL_SKIP;
1518             }
1519             memcpy(fset, data, min(len, (int) sizeof(*fset)));
1520         } else {
1521             int num_features_set = 0;
1522             int i = 0;
1523 
1524             if(!feature_matrix || !fm_size) {
1525                 ALOGE("Buffers pointers not set");
1526                 return NL_SKIP;
1527             }
1528 
1529             for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
1530                 if (it.get_type() == ANDR_WIFI_ATTRIBUTE_NUM_FEATURE_SET) {
1531                     num_features_set = it.get_u32();
1532                     ALOGV("Got feature list with %d concurrent sets", num_features_set);
1533                     if(set_size_max && (num_features_set > set_size_max))
1534                         num_features_set = set_size_max;
1535                     *fm_size = num_features_set;
1536                 } else if ((it.get_type() == ANDR_WIFI_ATTRIBUTE_FEATURE_SET) &&
1537                              i < num_features_set) {
1538                     feature_matrix[i] = it.get_u32();
1539                     i++;
1540                 } else {
1541                     ALOGW("Ignoring invalid attribute type = %d, size = %d",
1542                             it.get_type(), it.get_len());
1543                 }
1544             }
1545 
1546         }
1547         return NL_OK;
1548     }
1549 
1550 };
1551 /////////////////////////////////////////////////////////////////////
1552 class GetRadioComboCommand : public WifiCommand {
1553 private:
1554     wifi_radio_combination_matrix *rcmatrix;
1555     u32* rc_size;
1556     u32 set_size_max;
1557     int ret = 0;
1558 
1559 public:
GetRadioComboCommand(wifi_interface_handle handle,u32 max_size,u32 * size,wifi_radio_combination_matrix * radio_combination_matrix)1560     GetRadioComboCommand(wifi_interface_handle handle, u32 max_size, u32* size,
1561         wifi_radio_combination_matrix *radio_combination_matrix)
1562         : WifiCommand("GetRadioComboCommand", handle, 0), rcmatrix(radio_combination_matrix),
1563         rc_size(size), set_size_max(max_size)
1564     {
1565     }
1566 
createRequest(WifiRequest & mMsg)1567     virtual int createRequest(WifiRequest& mMsg) {
1568         ret = mMsg.create(GOOGLE_OUI, WIFI_SUBCMD_GET_RADIO_COMBO_MATRIX);
1569         if (ret < 0) {
1570             ALOGE("Can't create message to send to driver - %d", ret);
1571         }
1572         nlattr *data = mMsg.attr_start(NL80211_ATTR_VENDOR_DATA);
1573         mMsg.attr_end(data);
1574 
1575         return ret;
1576     }
1577 
start()1578     int start() {
1579         WifiRequest request(familyId(), ifaceId());
1580         ret = createRequest(request);
1581         if (ret < 0) {
1582             ALOGE("Request failed for radio_combo_matrix, result = %d", ret);
1583             return ret;
1584         }
1585         ret = requestResponse(request);
1586         if (ret < 0) {
1587             ALOGE("Request Response failed for radio_combo_matrix, result = %d", ret);
1588             return ret;
1589         }
1590         ALOGD("Done! %s", __FUNCTION__);
1591         return ret;
1592     }
1593 
1594 protected:
handleResponse(WifiEvent & reply)1595    virtual int handleResponse(WifiEvent& reply) {
1596         ALOGD("In GetRadioComboCommand::handleResponse");
1597         if (reply.get_cmd() != NL80211_CMD_VENDOR) {
1598             ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
1599             return NL_SKIP;
1600         }
1601 
1602         int id = reply.get_vendor_id();
1603         int subcmd = reply.get_vendor_subcmd();
1604 
1605         nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA);
1606         int len = reply.get_vendor_data_len();
1607 
1608         ALOGV("Id = %0x, subcmd = %d, len = %d", id, subcmd, len);
1609         if (vendor_data == NULL || len == 0) {
1610             ALOGE("no vendor data in GetRadioComboCommand response; ignoring it");
1611             return NL_SKIP;
1612         }
1613 
1614         for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
1615             if (it.get_type() == ANDR_WIFI_ATTRIBUTE_RADIO_COMBO_MATRIX) {
1616                 void *data = it.get_data();
1617                 *rc_size = it.get_len();
1618                 if (!data || !*rc_size) {
1619                     ALOGE("Buffers pointers not set");
1620                     return NL_SKIP;
1621                 }
1622                 if (set_size_max < *rc_size) {
1623                     ALOGE("Unexpected buffers size");
1624                     return NL_SKIP;
1625                 }
1626                 memcpy(rcmatrix, data, min(len, *rc_size));
1627             } else {
1628                 ALOGW("Ignoring invalid attribute type = %d, size = %d",
1629                         it.get_type(), it.get_len());
1630             }
1631         }
1632 
1633         ALOGD("GetRadioComboCommand::Success");
1634         return NL_OK;
1635     }
1636 };
1637 /////////////////////////////////////////////////////////////////////
1638 
1639 class SetLatencyModeCommand : public WifiCommand {
1640 private:
1641     u32 mLatencyMode;
1642 public:
SetLatencyModeCommand(wifi_interface_handle handle,u32 LatencyMode)1643     SetLatencyModeCommand(wifi_interface_handle handle, u32 LatencyMode)
1644         : WifiCommand("SetLatencyModeCommand", handle, 0) {
1645             mLatencyMode = LatencyMode;
1646     }
1647 
create()1648     virtual int create() {
1649         int ret;
1650 
1651         /* Check for invalid latency Mode */
1652         if ((mLatencyMode != WIFI_LATENCY_MODE_NORMAL) &&
1653             (mLatencyMode != WIFI_LATENCY_MODE_LOW)) {
1654             ALOGE("SetLatencyModeCommand: Invalid mode: %d", mLatencyMode);
1655             return WIFI_ERROR_UNKNOWN;
1656         }
1657 
1658         ret = mMsg.create(GOOGLE_OUI, WIFI_SUBCMD_SET_LATENCY_MODE);
1659         if (ret < 0) {
1660             ALOGE("Can't create message to send to driver - %d", ret);
1661             return ret;
1662         }
1663 
1664         nlattr *data = mMsg.attr_start(NL80211_ATTR_VENDOR_DATA);
1665         ret = mMsg.put_u32(ANDR_WIFI_ATTRIBUTE_LATENCY_MODE, mLatencyMode);
1666         if (ret < 0) {
1667             return ret;
1668         }
1669 
1670         mMsg.attr_end(data);
1671         return WIFI_SUCCESS;
1672     }
1673 };
wifi_get_multicast_id(wifi_handle handle,const char * name,const char * group)1674 static int wifi_get_multicast_id(wifi_handle handle, const char *name, const char *group)
1675 {
1676     GetMulticastIdCommand cmd(handle, name, group);
1677     int res = cmd.requestResponse();
1678     if (res < 0)
1679         return res;
1680     else
1681         return cmd.getId();
1682 }
1683 
1684 /////////////////////////////////////////////////////////////////////////
1685 
is_wifi_interface(const char * name)1686 static bool is_wifi_interface(const char *name)
1687 {
1688     if (strncmp(name, "wlan", 4) != 0 && strncmp(name, "swlan", 5) != 0 &&
1689         strncmp(name, "p2p", 3) != 0 && strncmp(name, "aware", 5) != 0) {
1690         /* not a wifi interface; ignore it */
1691         return false;
1692     } else {
1693         return true;
1694     }
1695 }
1696 
get_interface(const char * name,interface_info * info)1697 static int get_interface(const char *name, interface_info *info)
1698 {
1699     int size = 0;
1700     size = strlcpy(info->name, name, sizeof(info->name));
1701     if (size >= sizeof(info->name)) {
1702         return WIFI_ERROR_OUT_OF_MEMORY;
1703     }
1704     info->id = if_nametoindex(name);
1705     // ALOGI("found an interface : %s, id = %d", name, info->id);
1706     return WIFI_SUCCESS;
1707 }
1708 
wifi_init_interfaces(wifi_handle handle)1709 wifi_error wifi_init_interfaces(wifi_handle handle)
1710 {
1711     hal_info *info = (hal_info *)handle;
1712 
1713     struct dirent *de;
1714 
1715     DIR *d = opendir("/sys/class/net");
1716     if (d == 0)
1717         return WIFI_ERROR_UNKNOWN;
1718 
1719     int n = 0;
1720     while ((de = readdir(d))) {
1721         if (de->d_name[0] == '.')
1722             continue;
1723         if (is_wifi_interface(de->d_name) ) {
1724             n++;
1725         }
1726     }
1727 
1728     closedir(d);
1729 
1730     if (n == 0)
1731         return WIFI_ERROR_NOT_AVAILABLE;
1732 
1733     d = opendir("/sys/class/net");
1734     if (d == 0)
1735         return WIFI_ERROR_UNKNOWN;
1736 
1737     /* Have place holder for 3 virtual interfaces */
1738     n += MAX_VIRTUAL_IFACES;
1739     info->interfaces = (interface_info **)calloc(n, sizeof(interface_info *) * n);
1740     if (!info->interfaces) {
1741         info->num_interfaces = 0;
1742         closedir(d);
1743         return WIFI_ERROR_OUT_OF_MEMORY;
1744     }
1745 
1746     int i = 0;
1747     while ((de = readdir(d))) {
1748         if (de->d_name[0] == '.')
1749             continue;
1750         if (is_wifi_interface(de->d_name)) {
1751             interface_info *ifinfo = (interface_info *)malloc(sizeof(interface_info));
1752             if (!ifinfo) {
1753                 if (info->interfaces) {
1754                     for (int j = 0; j < i; j++) {
1755                         free(info->interfaces[j]);
1756                     }
1757                 }
1758                 free(info->interfaces);
1759                 info->num_interfaces = 0;
1760                 closedir(d);
1761                 return WIFI_ERROR_OUT_OF_MEMORY;
1762             }
1763             memset(ifinfo, 0, sizeof(interface_info));
1764             if (get_interface(de->d_name, ifinfo) != WIFI_SUCCESS) {
1765                 free(ifinfo);
1766                 continue;
1767             }
1768             /* Mark as static iface */
1769             ifinfo->is_virtual = false;
1770             ifinfo->handle = handle;
1771             info->interfaces[i] = ifinfo;
1772             i++;
1773         }
1774     }
1775 
1776     closedir(d);
1777 
1778     info->num_interfaces = i;
1779     info->max_num_interfaces = n;
1780     return WIFI_SUCCESS;
1781 }
1782 
wifi_get_ifaces(wifi_handle handle,int * num,wifi_interface_handle ** interfaces)1783 wifi_error wifi_get_ifaces(wifi_handle handle, int *num, wifi_interface_handle **interfaces)
1784 {
1785     hal_info *info = (hal_info *)handle;
1786 
1787     *interfaces = (wifi_interface_handle *)info->interfaces;
1788     *num = info->num_interfaces;
1789 
1790     return WIFI_SUCCESS;
1791 }
1792 
wifi_add_iface_hal_info(wifi_handle handle,const char * ifname)1793 wifi_error wifi_add_iface_hal_info(wifi_handle handle, const char* ifname)
1794 {
1795     hal_info *info = NULL;
1796     int i = 0;
1797 
1798     info = (hal_info *)handle;
1799     if (info == NULL) {
1800         ALOGE("Could not find info\n");
1801         return WIFI_ERROR_UNKNOWN;
1802     }
1803 
1804     ALOGI("%s: add interface_info for iface: %s\n", __FUNCTION__, ifname);
1805     if (info->num_interfaces == MAX_VIRTUAL_IFACES) {
1806         ALOGE("No space. max limit reached for virtual interfaces %d\n", info->num_interfaces);
1807         return WIFI_ERROR_OUT_OF_MEMORY;
1808     }
1809 
1810     interface_info *ifinfo = (interface_info *)malloc(sizeof(interface_info));
1811     if (!ifinfo) {
1812         free(info->interfaces);
1813         info->num_interfaces = 0;
1814         return WIFI_ERROR_OUT_OF_MEMORY;
1815     }
1816 
1817     ifinfo->handle = handle;
1818     while (i < info->max_num_interfaces) {
1819         if (info->interfaces[i] == NULL) {
1820             if (get_interface(ifname, ifinfo) != WIFI_SUCCESS) {
1821                 continue;
1822             }
1823             ifinfo->is_virtual = true;
1824             info->interfaces[i] = ifinfo;
1825             info->num_interfaces++;
1826             ALOGI("%s: Added iface: %s at the index %d\n", __FUNCTION__, ifname, i);
1827             break;
1828         }
1829         i++;
1830     }
1831     return WIFI_SUCCESS;
1832 }
1833 
wifi_clear_iface_hal_info(wifi_handle handle,const char * ifname)1834 wifi_error wifi_clear_iface_hal_info(wifi_handle handle, const char* ifname)
1835 {
1836     hal_info *info = (hal_info *)handle;
1837     int i = 0;
1838 
1839     ALOGI("%s: clear hal info for iface: %s\n", __FUNCTION__, ifname);
1840     while (i < info->max_num_interfaces) {
1841         if ((info->interfaces[i] != NULL) &&
1842             strncmp(info->interfaces[i]->name, ifname,
1843             sizeof(info->interfaces[i]->name)) == 0) {
1844             free(info->interfaces[i]);
1845             info->interfaces[i] = NULL;
1846             info->num_interfaces--;
1847             ALOGI("%s: Cleared the index = %d for iface: %s\n", __FUNCTION__, i, ifname);
1848             break;
1849         }
1850         i++;
1851     }
1852     if (i < info->num_interfaces) {
1853         for (int j = i; j < info->num_interfaces; j++) {
1854             info->interfaces[j] = info->interfaces[j+1];
1855         }
1856         info->interfaces[info->num_interfaces] = NULL;
1857     }
1858     return WIFI_SUCCESS;
1859 }
1860 
wifi_get_wlan_interface(wifi_handle info,wifi_interface_handle * ifaceHandles,int numIfaceHandles)1861 wifi_interface_handle wifi_get_wlan_interface(wifi_handle info, wifi_interface_handle *ifaceHandles, int numIfaceHandles)
1862 {
1863     char buf[EVENT_BUF_SIZE];
1864     wifi_interface_handle wlan0Handle;
1865     wifi_error res = wifi_get_ifaces((wifi_handle)info, &numIfaceHandles, &ifaceHandles);
1866     if (res < 0) {
1867         return NULL;
1868     }
1869     for (int i = 0; i < numIfaceHandles; i++) {
1870         if (wifi_get_iface_name(ifaceHandles[i], buf, sizeof(buf)) == WIFI_SUCCESS) {
1871             if (strncmp(buf, "wlan0", 5) == 0) {
1872                 ALOGI("found interface %s\n", buf);
1873                 wlan0Handle = ifaceHandles[i];
1874                 return wlan0Handle;
1875             }
1876         }
1877     }
1878     return NULL;
1879 }
wifi_get_iface_name(wifi_interface_handle handle,char * name,size_t size)1880 wifi_error wifi_get_iface_name(wifi_interface_handle handle, char *name, size_t size)
1881 {
1882     interface_info *info = (interface_info *)handle;
1883     strncpy(name, info->name, (IFNAMSIZ));
1884     name[IFNAMSIZ - 1] = '\0';
1885     return WIFI_SUCCESS;
1886 }
1887 
wifi_get_iface_handle(wifi_handle handle,char * name)1888 wifi_interface_handle wifi_get_iface_handle(wifi_handle handle, char *name)
1889 {
1890     char buf[EVENT_BUF_SIZE];
1891     wifi_interface_handle *ifaceHandles;
1892     int numIfaceHandles;
1893     wifi_interface_handle ifHandle;
1894 
1895     wifi_error res = wifi_get_ifaces((wifi_handle)handle, &numIfaceHandles, &ifaceHandles);
1896     if (res < 0) {
1897         return NULL;
1898     }
1899     for (int i = 0; i < numIfaceHandles; i++) {
1900         if (wifi_get_iface_name(ifaceHandles[i], buf, sizeof(buf)) == WIFI_SUCCESS) {
1901             if (strcmp(buf, name) == 0) {
1902                 ALOGI("found interface %s\n", buf);
1903                 ifHandle = ifaceHandles[i];
1904                 return ifHandle;
1905             }
1906         }
1907     }
1908     return NULL;
1909 }
1910 
wifi_get_supported_feature_set(wifi_interface_handle handle,feature_set * set)1911 wifi_error wifi_get_supported_feature_set(wifi_interface_handle handle, feature_set *set)
1912 {
1913     GetFeatureSetCommand command(handle, ANDR_WIFI_ATTRIBUTE_NUM_FEATURE_SET, set, NULL, NULL, 1);
1914     return (wifi_error) command.requestResponse();
1915 }
1916 
wifi_get_concurrency_matrix(wifi_interface_handle handle,int set_size_max,feature_set set[],int * set_size)1917 wifi_error wifi_get_concurrency_matrix(wifi_interface_handle handle, int set_size_max,
1918        feature_set set[], int *set_size)
1919 {
1920     GetFeatureSetCommand command(handle, ANDR_WIFI_ATTRIBUTE_FEATURE_SET, NULL,
1921             set, set_size, set_size_max);
1922     return (wifi_error) command.requestResponse();
1923 }
1924 
wifi_get_supported_radio_combinations_matrix(wifi_handle handle,u32 max_size,u32 * size,wifi_radio_combination_matrix * radio_combination_matrix)1925 wifi_error wifi_get_supported_radio_combinations_matrix(wifi_handle handle,
1926     u32 max_size, u32* size, wifi_radio_combination_matrix *radio_combination_matrix)
1927 {
1928     int numIfaceHandles = 0;
1929     wifi_interface_handle *ifaceHandles = NULL;
1930     wifi_interface_handle wlan0Handle;
1931 
1932     wlan0Handle = wifi_get_wlan_interface((wifi_handle)handle, ifaceHandles, numIfaceHandles);
1933     GetRadioComboCommand *cmd = new GetRadioComboCommand(wlan0Handle, max_size,
1934         size, radio_combination_matrix);
1935     NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
1936     wifi_error result = (wifi_error)cmd->start();
1937     if (result == WIFI_SUCCESS) {
1938         ALOGD("Get radio combo matrix success");
1939     } else {
1940         ALOGE("Get radio combo matrix failed\n");
1941     }
1942     cmd->releaseRef();
1943     return result;
1944 }
1945 
wifi_set_scanning_mac_oui(wifi_interface_handle handle,oui scan_oui)1946 wifi_error wifi_set_scanning_mac_oui(wifi_interface_handle handle, oui scan_oui)
1947 {
1948     SetPnoMacAddrOuiCommand command(handle, scan_oui);
1949     return (wifi_error)command.start();
1950 
1951 }
1952 
wifi_set_nodfs_flag(wifi_interface_handle handle,u32 nodfs)1953 wifi_error wifi_set_nodfs_flag(wifi_interface_handle handle, u32 nodfs)
1954 {
1955     SetNodfsCommand command(handle, nodfs);
1956     return (wifi_error) command.requestResponse();
1957 }
1958 
wifi_set_country_code(wifi_interface_handle handle,const char * country_code)1959 wifi_error wifi_set_country_code(wifi_interface_handle handle, const char *country_code)
1960 {
1961     SetCountryCodeCommand command(handle, country_code);
1962     return (wifi_error) command.requestResponse();
1963 }
1964 
wifi_start_rssi_monitoring(wifi_request_id id,wifi_interface_handle iface,s8 max_rssi,s8 min_rssi,wifi_rssi_event_handler eh)1965 static wifi_error wifi_start_rssi_monitoring(wifi_request_id id, wifi_interface_handle
1966                         iface, s8 max_rssi, s8 min_rssi, wifi_rssi_event_handler eh)
1967 {
1968     ALOGI("Starting RSSI monitor %d", id);
1969     wifi_handle handle = getWifiHandle(iface);
1970     SetRSSIMonitorCommand *cmd = new SetRSSIMonitorCommand(id, iface, max_rssi, min_rssi, eh);
1971     NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
1972     wifi_error result = wifi_register_cmd(handle, id, cmd);
1973     if (result != WIFI_SUCCESS) {
1974         ALOGI("wifi_register_cmd() is failed %d", id);
1975         cmd->releaseRef();
1976         return result;
1977     }
1978     result = (wifi_error)cmd->start();
1979     if (result != WIFI_SUCCESS) {
1980         ALOGI("start() is failed %d", id);
1981         wifi_unregister_cmd(handle, id);
1982         cmd->releaseRef();
1983         return result;
1984     }
1985     return result;
1986 }
1987 
wifi_stop_rssi_monitoring(wifi_request_id id,wifi_interface_handle iface)1988 static wifi_error wifi_stop_rssi_monitoring(wifi_request_id id, wifi_interface_handle iface)
1989 {
1990     ALOGI("Stopping RSSI monitor %d", id);
1991 
1992     if (id == -1) {
1993         wifi_rssi_event_handler handler;
1994         s8 max_rssi = 0, min_rssi = 0;
1995         memset(&handler, 0, sizeof(handler));
1996         SetRSSIMonitorCommand *cmd = new SetRSSIMonitorCommand(id, iface,
1997                                                     max_rssi, min_rssi, handler);
1998         NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
1999         cmd->cancel();
2000         cmd->releaseRef();
2001         return WIFI_SUCCESS;
2002     }
2003     return wifi_cancel_cmd(id, iface);
2004 }
2005 
wifi_get_packet_filter_capabilities(wifi_interface_handle handle,u32 * version,u32 * max_len)2006 static wifi_error wifi_get_packet_filter_capabilities(wifi_interface_handle handle,
2007         u32 *version, u32 *max_len)
2008 {
2009     ALOGD("Getting APF capabilities, halHandle = %p\n", handle);
2010     AndroidPktFilterCommand *cmd = new AndroidPktFilterCommand(handle, version, max_len);
2011     NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
2012     wifi_error result = (wifi_error)cmd->start();
2013     if (result == WIFI_SUCCESS) {
2014         ALOGD("Getting APF capability, version = %d, max_len = %d\n", *version, *max_len);
2015     }
2016     cmd->releaseRef();
2017     return result;
2018 }
2019 
wifi_set_packet_filter(wifi_interface_handle handle,const u8 * program,u32 len)2020 static wifi_error wifi_set_packet_filter(wifi_interface_handle handle,
2021         const u8 *program, u32 len)
2022 {
2023     char iface_name[IFNAMSIZ];
2024 
2025     ALOGE("Setting APF program, halHandle = %p\n", handle);
2026     if (wifi_get_iface_name(handle, iface_name, sizeof(iface_name)) != WIFI_SUCCESS) {
2027        ALOGE("%s : Invalid interface handle\n", __func__);
2028        return WIFI_ERROR_INVALID_ARGS;
2029     }
2030     ALOGE("Set apf filter for iface = %s\n", iface_name);
2031 
2032     AndroidPktFilterCommand *cmd = new AndroidPktFilterCommand(handle, program, len);
2033     NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
2034     wifi_error result = (wifi_error)cmd->start();
2035     cmd->releaseRef();
2036     return result;
2037 }
2038 
wifi_read_packet_filter(wifi_interface_handle handle,u32 src_offset,u8 * host_dst,u32 length)2039 static wifi_error wifi_read_packet_filter(wifi_interface_handle handle,
2040     u32 src_offset, u8 *host_dst, u32 length)
2041 {
2042     ALOGD("Read APF program, halHandle = %p, length = %d\n", handle, length);
2043     AndroidPktFilterCommand *cmd = new AndroidPktFilterCommand(handle, host_dst, length);
2044     NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
2045     wifi_error result = (wifi_error)cmd->start();
2046     if (result == WIFI_SUCCESS) {
2047         ALOGI("Read APF program success\n");
2048     }
2049     cmd->releaseRef();
2050     return result;
2051 }
wifi_configure_nd_offload(wifi_interface_handle handle,u8 enable)2052 static wifi_error wifi_configure_nd_offload(wifi_interface_handle handle, u8 enable)
2053 {
2054     SetNdoffloadCommand command(handle, enable);
2055     return (wifi_error) command.requestResponse();
2056 }
wifi_set_latency_mode(wifi_interface_handle handle,wifi_latency_mode mode)2057 wifi_error wifi_set_latency_mode(wifi_interface_handle handle, wifi_latency_mode mode)
2058 {
2059     ALOGD("Setting Wifi Latency mode, halHandle = %p LatencyMode = %d\n", handle, mode);
2060     SetLatencyModeCommand command(handle, mode);
2061     return (wifi_error) command.requestResponse();
2062 }
2063 
2064 /////////////////////////////////////////////////////////////////////////
2065 class TxPowerScenario : public WifiCommand {
2066     wifi_power_scenario mScenario;
2067 public:
2068     // constructor for tx power scenario setting
TxPowerScenario(wifi_interface_handle handle,wifi_power_scenario scenario)2069     TxPowerScenario(wifi_interface_handle handle, wifi_power_scenario scenario)
2070     : WifiCommand("TxPowerScenario", handle, 0), mScenario(scenario)
2071     {
2072         mScenario = scenario;
2073     }
2074 
2075     // constructor for tx power scenario resetting
TxPowerScenario(wifi_interface_handle handle)2076     TxPowerScenario(wifi_interface_handle handle)
2077     : WifiCommand("TxPowerScenario", handle, 0)
2078     {
2079         mScenario = WIFI_POWER_SCENARIO_DEFAULT;
2080     }
2081 
createRequest(WifiRequest & request,int subcmd,wifi_power_scenario mScenario)2082     int createRequest(WifiRequest& request, int subcmd, wifi_power_scenario mScenario) {
2083         int result = request.create(GOOGLE_OUI, subcmd);
2084         if (result < 0) {
2085             return result;
2086         }
2087 
2088         if ((mScenario <= WIFI_POWER_SCENARIO_INVALID) ||
2089            (mScenario >= SAR_CONFIG_SCENARIO_COUNT)) {
2090             ALOGE("Unsupported tx power value:%d\n", mScenario);
2091             return WIFI_ERROR_NOT_SUPPORTED;
2092         }
2093 
2094         nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
2095         result = request.put_s8(ANDR_WIFI_ATTRIBUTE_TX_POWER_SCENARIO, mScenario);
2096         if (result < 0) {
2097             ALOGE("Failed to put tx power scenario request; result = %d", result);
2098             return result;
2099         }
2100         request.attr_end(data);
2101         return WIFI_SUCCESS;
2102     }
2103 
start(wifi_power_scenario mScenario)2104     int start(wifi_power_scenario mScenario) {
2105         WifiRequest request(familyId(), ifaceId());
2106         int result = createRequest(request, WIFI_SUBCMD_TX_POWER_SCENARIO, mScenario);
2107         if (result != WIFI_SUCCESS) {
2108             ALOGE("failed to create request; result = %d", result);
2109             return result;
2110         }
2111 
2112         result = requestResponse(request);
2113         if (result != WIFI_SUCCESS) {
2114             ALOGE("failed to send tx power scenario; result = %d", result);
2115         }
2116         return result;
2117     }
2118 protected:
handleResponse(WifiEvent & reply)2119     virtual int handleResponse(WifiEvent& reply) {
2120         ALOGD("Request complete!");
2121         /* Nothing to do on response! */
2122         return NL_SKIP;
2123     }
2124 };
2125 
2126 
wifi_select_tx_power_scenario(wifi_interface_handle handle,wifi_power_scenario scenario)2127 wifi_error wifi_select_tx_power_scenario(wifi_interface_handle handle, wifi_power_scenario scenario)
2128 {
2129     ALOGE("wifi_select_tx_power_scenario");
2130     TxPowerScenario command(handle);
2131     return (wifi_error)command.start(scenario);
2132 }
2133 
wifi_reset_tx_power_scenario(wifi_interface_handle handle)2134 wifi_error wifi_reset_tx_power_scenario(wifi_interface_handle handle)
2135 {
2136     wifi_power_scenario scenario = WIFI_POWER_SCENARIO_DEFAULT;
2137     ALOGE("wifi_reset_tx_power_scenario");
2138     TxPowerScenario command(handle);
2139     return (wifi_error)command.start(scenario);
2140 }
2141 
2142 /////////////////////////////////////////////////////////////////////////////
2143 
2144 class ThermalMitigation : public WifiCommand {
2145 private:
2146     wifi_thermal_mode mMitigation;
2147     u32 mCompletionWindow;
2148 public:
2149     // constructor for thermal mitigation setting
ThermalMitigation(wifi_interface_handle handle,wifi_thermal_mode mitigation,u32 completion_window)2150     ThermalMitigation(wifi_interface_handle handle,
2151 		    wifi_thermal_mode mitigation, u32 completion_window)
2152     : WifiCommand("ThermalMitigation", handle, 0)
2153     {
2154         mMitigation = mitigation;
2155 		mCompletionWindow = completion_window;
2156     }
2157 
createRequest(WifiRequest & request,int subcmd,wifi_thermal_mode mitigation,u32 completion_window)2158     int createRequest(WifiRequest& request, int subcmd,
2159 		    wifi_thermal_mode mitigation, u32 completion_window) {
2160         int result = request.create(GOOGLE_OUI, subcmd);
2161         if (result < 0) {
2162             return result;
2163         }
2164 
2165         if ((mitigation < WIFI_MITIGATION_NONE) ||
2166            (mitigation > WIFI_MITIGATION_EMERGENCY)) {
2167             ALOGE("Unsupported tx mitigation value:%d\n", mitigation);
2168             return WIFI_ERROR_NOT_SUPPORTED;
2169         }
2170 
2171         nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
2172         result = request.put_s8(ANDR_WIFI_ATTRIBUTE_THERMAL_MITIGATION, mitigation);
2173         if (result < 0) {
2174             ALOGE("Failed to put tx power scenario request; result = %d", result);
2175             return result;
2176         }
2177         result = request.put_u32(ANDR_WIFI_ATTRIBUTE_THERMAL_COMPLETION_WINDOW,
2178 		       	completion_window);
2179         if (result < 0) {
2180             ALOGE("Failed to put tx power scenario request; result = %d", result);
2181             return result;
2182         }
2183 
2184         request.attr_end(data);
2185         return WIFI_SUCCESS;
2186     }
2187 
start()2188     int start() {
2189         WifiRequest request(familyId(), ifaceId());
2190         int result = createRequest(request, WIFI_SUBCMD_THERMAL_MITIGATION, mMitigation,
2191 		       	mCompletionWindow);
2192         if (result != WIFI_SUCCESS) {
2193             ALOGE("failed to create request; result = %d", result);
2194             return result;
2195         }
2196 
2197         ALOGD("try to get resp; mitigation=%d, delay=%d", mMitigation, mCompletionWindow);
2198         result = requestResponse(request);
2199         if (result != WIFI_SUCCESS) {
2200             ALOGE("failed to send thermal mitigation; result = %d", result);
2201         }
2202         return result;
2203     }
2204 protected:
handleResponse(WifiEvent & reply)2205     virtual int handleResponse(WifiEvent& reply) {
2206         ALOGD("Request complete!");
2207         /* Nothing to do on response! */
2208         return NL_SKIP;
2209     }
2210 };
2211 
wifi_set_thermal_mitigation_mode(wifi_handle handle,wifi_thermal_mode mode,u32 completion_window)2212 wifi_error wifi_set_thermal_mitigation_mode(wifi_handle handle,
2213                                             wifi_thermal_mode mode,
2214                                             u32 completion_window)
2215 {
2216     int numIfaceHandles = 0;
2217     wifi_interface_handle *ifaceHandles = NULL;
2218     wifi_interface_handle wlan0Handle;
2219 
2220     wlan0Handle = wifi_get_wlan_interface((wifi_handle)handle, ifaceHandles, numIfaceHandles);
2221     ThermalMitigation command(wlan0Handle, mode, completion_window);
2222     return (wifi_error)command.start();
2223 }
2224 
2225 /////////////////////////////////////////////////////////////////////////////
2226 
2227 class ChAvoidCommand : public WifiCommand {
2228     private:
2229         u32 mNumParams;
2230         wifi_coex_unsafe_channel *chavoidParams;
2231         u32 mMandatory;
2232 
2233     public:
ChAvoidCommand(wifi_interface_handle handle,u32 num,wifi_coex_unsafe_channel channels[],u32 mandatory)2234         ChAvoidCommand(wifi_interface_handle handle,
2235             u32 num, wifi_coex_unsafe_channel channels[], u32 mandatory)
2236             : WifiCommand("ChAvoidCommand", handle, 0),
2237                 mNumParams(num), chavoidParams(channels), mMandatory(mandatory)
2238         {
2239         }
2240 
createRequest(WifiRequest & request)2241     int createRequest(WifiRequest& request) {
2242         return createSetChAvoidRequest(request);
2243     }
2244 
createSetChAvoidRequest(WifiRequest & request)2245     int createSetChAvoidRequest(WifiRequest& request) {
2246         int result = request.create(GOOGLE_OUI, CHAVOID_SUBCMD_SET_CONFIG);
2247         if (result < 0) {
2248             ALOGE("%s : Failed to create SUBCMD\n", __func__);
2249             return result;
2250         }
2251 
2252         nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
2253         result = request.put_u32(CHAVOID_ATTRIBUTE_CNT, mNumParams);
2254         if (result < 0) {
2255             ALOGE("%s : Failed to set cound\n", __func__);
2256             return result;
2257         }
2258         result = request.put_u32(CHAVOID_ATTRIBUTE_MANDATORY, mMandatory);
2259         if (result < 0) {
2260             ALOGE("%s : Failed to set mandatory cap\n", __func__);
2261             return result;
2262         }
2263 
2264         nlattr *chavoid_config = request.attr_start(CHAVOID_ATTRIBUTE_CONFIG);
2265         for (int i = 0; i< mNumParams; i++) {
2266             nlattr *item = request.attr_start(i);
2267             if (item == NULL) {
2268                 ALOGE("%s : Failed to alloc item\n", __func__);
2269                 return WIFI_ERROR_OUT_OF_MEMORY;
2270             }
2271             result = request.put_u32(CHAVOID_ATTRIBUTE_BAND, chavoidParams[i].band);
2272             if (result < 0) {
2273                 ALOGE("%s : Failed to set band\n", __func__);
2274                 return result;
2275             }
2276             result = request.put_u32(CHAVOID_ATTRIBUTE_CHANNEL, chavoidParams[i].channel);
2277             if (result < 0) {
2278                 ALOGE("%s : Failed to set channel\n", __func__);
2279                 return result;
2280             }
2281             result = request.put_u32(CHAVOID_ATTRIBUTE_PWRCAP, chavoidParams[i].power_cap_dbm);
2282             if (result < 0) {
2283                 ALOGE("%s : Failed to set power cap\n", __func__);
2284                 return result;
2285             }
2286             request.attr_end(item);
2287         }
2288         request.attr_end(chavoid_config);
2289         request.attr_end(data);
2290         return WIFI_SUCCESS;
2291     }
2292 
start()2293     int start() {
2294         WifiRequest request(familyId(), ifaceId());
2295         int result = createRequest(request);
2296         if (result < 0) {
2297             return result;
2298         }
2299         result = requestResponse(request);
2300         if (result < 0) {
2301             ALOGI("Request Response failed for ChAvoid, result = %d", result);
2302             return result;
2303         }
2304         return result;
2305     }
2306 
handleResponse(WifiEvent & reply)2307     int handleResponse(WifiEvent& reply) {
2308         ALOGD("In ChAvoidCommand::handleResponse");
2309 
2310         if (reply.get_cmd() != NL80211_CMD_VENDOR) {
2311             ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
2312             return NL_SKIP;
2313         }
2314 
2315         nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA);
2316         int len = reply.get_vendor_data_len();
2317 
2318         if (vendor_data == NULL || len == 0) {
2319             ALOGE("no vendor data in ChAvoidCommand response; ignoring it");
2320             return NL_SKIP;
2321         }
2322         ALOGD("Response received for ChAvoid command\n");
2323         return NL_OK;
2324     }
2325 
handleEvent(WifiEvent & event)2326     int handleEvent(WifiEvent& event) {
2327         /* No Event to receive for ChAvoid commands */
2328         ALOGD("ChAvoid command %s\n", __FUNCTION__);
2329         return NL_SKIP;
2330     }
2331 };
2332 
wifi_set_coex_unsafe_channels(wifi_handle handle,u32 num,wifi_coex_unsafe_channel channels[],u32 mandatory)2333 wifi_error wifi_set_coex_unsafe_channels(wifi_handle handle,
2334         u32 num, wifi_coex_unsafe_channel channels[], u32 mandatory)
2335 {
2336     int numIfaceHandles = 0;
2337     wifi_interface_handle *ifaceHandles = NULL;
2338     wifi_interface_handle wlan0Handle;
2339 
2340     wlan0Handle = wifi_get_wlan_interface((wifi_handle)handle, ifaceHandles, numIfaceHandles);
2341 
2342     ChAvoidCommand *cmd = new ChAvoidCommand(wlan0Handle, num, channels, mandatory);
2343     NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
2344     wifi_error result = (wifi_error)cmd->start();
2345     if (result == WIFI_SUCCESS) {
2346         ALOGI("Setting Channel Avoidance success\n");
2347     } else {
2348         ALOGE("Setting Channel Avoidance failed\n");
2349     }
2350     cmd->releaseRef();
2351     return result;
2352 }
2353 
2354 /////////////////////////////////////////////////////////////////////////////
2355 
2356 class DscpCommand : public WifiCommand {
2357     private:
2358 	u32 mStart;
2359 	u32 mEnd;
2360 	u32 mAc;
2361         int mReqType;
2362     public:
DscpCommand(wifi_interface_handle handle,u32 start,u32 end,u32 ac)2363         DscpCommand(wifi_interface_handle handle,
2364                 u32 start, u32 end, u32 ac)
2365             : WifiCommand("DscpCommand", handle, 0),
2366                     mStart(start), mEnd(end), mAc(ac),
2367                     mReqType(SET_DSCP_TABLE)
2368         {
2369         }
2370 
DscpCommand(wifi_interface_handle handle)2371         DscpCommand(wifi_interface_handle handle)
2372             : WifiCommand("DscpCommand", handle, 0),
2373                     mReqType(RESET_DSCP_TABLE)
2374         {
2375             mStart = 0;
2376             mEnd = 0;
2377             mAc = 0;
2378         }
2379 
createRequest(WifiRequest & request)2380     int createRequest(WifiRequest& request) {
2381         if (mReqType == SET_DSCP_TABLE) {
2382             ALOGI("\n%s: DSCP set table request\n", __FUNCTION__);
2383             return createSetDscpRequest(request);
2384         } else if (mReqType == RESET_DSCP_TABLE) {
2385             ALOGI("\n%s: DSCP reset table request\n", __FUNCTION__);
2386             return createResetDscpRequest(request);
2387         } else {
2388             ALOGE("\n%s Unknown DSCP request\n", __FUNCTION__);
2389             return WIFI_ERROR_NOT_SUPPORTED;
2390         }
2391         return WIFI_SUCCESS;
2392     }
2393 
createSetDscpRequest(WifiRequest & request)2394     int createSetDscpRequest(WifiRequest& request) {
2395         int result = request.create(GOOGLE_OUI, DSCP_SUBCMD_SET_TABLE);
2396         if (result < 0) {
2397             return result;
2398         }
2399 
2400         nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
2401         result = request.put_u32(DSCP_ATTRIBUTE_START, mStart);
2402         if (result < 0) {
2403             goto exit;
2404         }
2405         result = request.put_u32(DSCP_ATTRIBUTE_END, mEnd);
2406         if (result < 0) {
2407             goto exit;
2408         }
2409         result = request.put_u32(DSCP_ATTRIBUTE_AC, mAc);
2410         if (result < 0) {
2411             goto exit;
2412         }
2413         request.attr_end(data);
2414 exit:
2415         return result;
2416     }
2417 
createResetDscpRequest(WifiRequest & request)2418     int createResetDscpRequest(WifiRequest& request) {
2419         int result = request.create(GOOGLE_OUI, DSCP_SUBCMD_RESET_TABLE);
2420         if (result < 0) {
2421             return result;
2422         }
2423 
2424         nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
2425         request.attr_end(data);
2426         return result;
2427     }
2428 
start()2429     int start() {
2430         WifiRequest request(familyId(), ifaceId());
2431         int result = createRequest(request);
2432         if (result < 0) {
2433             return result;
2434         }
2435         result = requestResponse(request);
2436         if (result < 0) {
2437             ALOGI("Request Response failed for DSCP, result = %d", result);
2438             return result;
2439         }
2440         return result;
2441     }
2442 
handleResponse(WifiEvent & reply)2443     int handleResponse(WifiEvent& reply) {
2444         ALOGD("In DscpCommand::handleResponse");
2445 
2446         if (reply.get_cmd() != NL80211_CMD_VENDOR) {
2447             ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
2448             return NL_SKIP;
2449         }
2450 
2451         nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA);
2452         int len = reply.get_vendor_data_len();
2453 
2454         if (vendor_data == NULL || len == 0) {
2455             ALOGE("no vendor data in DscpCommand response; ignoring it");
2456             return NL_SKIP;
2457         }
2458         if( mReqType == SET_DSCP_TABLE) {
2459             ALOGD("Response received for Set DSCP command\n");
2460         } else if (mReqType == RESET_DSCP_TABLE) {
2461             ALOGD("Response received for Reset DSCP command\n");
2462         }
2463         return NL_OK;
2464     }
2465 
handleEvent(WifiEvent & event)2466     int handleEvent(WifiEvent& event) {
2467         /* No Event to receive for DSCP commands */
2468         ALOGD("DSCP command %s\n", __FUNCTION__);
2469         return NL_SKIP;
2470     }
2471 };
2472 
wifi_map_dscp_access_category(wifi_handle handle,u32 start,u32 end,u32 ac)2473 wifi_error wifi_map_dscp_access_category(wifi_handle handle,
2474         u32 start, u32 end, u32 ac)
2475 {
2476     int numIfaceHandles = 0;
2477     wifi_interface_handle *ifaceHandles = NULL;
2478     wifi_interface_handle wlan0Handle;
2479 
2480     wlan0Handle = wifi_get_wlan_interface((wifi_handle)handle, ifaceHandles, numIfaceHandles);
2481 
2482     DscpCommand *cmd = new DscpCommand(wlan0Handle, start, end, ac);
2483     NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
2484     wifi_error result = (wifi_error)cmd->start();
2485     if (result == WIFI_SUCCESS) {
2486         ALOGI("Mapping DSCP table success\n");
2487     } else {
2488         ALOGE("Mapping DSCP table fail\n");
2489     }
2490     cmd->releaseRef();
2491     return result;
2492 }
2493 
wifi_reset_dscp_mapping(wifi_handle handle)2494 wifi_error wifi_reset_dscp_mapping(wifi_handle handle)
2495 {
2496     int numIfaceHandles = 0;
2497     wifi_interface_handle *ifaceHandles = NULL;
2498     wifi_interface_handle wlan0Handle;
2499 
2500     wlan0Handle = wifi_get_wlan_interface((wifi_handle)handle, ifaceHandles, numIfaceHandles);
2501 
2502     DscpCommand *cmd = new DscpCommand(wlan0Handle);
2503     NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
2504     wifi_error result = (wifi_error)cmd->start();
2505     if (result == WIFI_SUCCESS) {
2506         ALOGI("Resetting DSCP table success\n");
2507     } else {
2508         ALOGE("Resetting DSCP table fail\n");
2509     }
2510     cmd->releaseRef();
2511     return result;
2512 }
2513 
2514 class VirtualIfaceConfig : public WifiCommand {
2515     const char *mIfname;
2516     nl80211_iftype mType;
2517     u32 mwlan0_id;
2518 
2519 public:
VirtualIfaceConfig(wifi_interface_handle handle,const char * ifname,nl80211_iftype iface_type,u32 wlan0_id)2520     VirtualIfaceConfig(wifi_interface_handle handle, const char* ifname,
2521         nl80211_iftype iface_type, u32 wlan0_id)
2522     : WifiCommand("VirtualIfaceConfig", handle, 0), mIfname(ifname), mType(iface_type),
2523         mwlan0_id(wlan0_id)
2524     {
2525         mIfname = ifname;
2526         mType = iface_type;
2527         mwlan0_id = wlan0_id;
2528     }
createRequest(WifiRequest & request,const char * ifname,nl80211_iftype iface_type,u32 wlan0_id)2529     int createRequest(WifiRequest& request, const char* ifname,
2530         nl80211_iftype iface_type, u32 wlan0_id) {
2531         ALOGD("add ifname = %s, iface_type = %d, wlan0_id = %d",
2532         ifname, iface_type, wlan0_id);
2533 
2534         int result = request.create(NL80211_CMD_NEW_INTERFACE);
2535         if (result < 0) {
2536             ALOGE("failed to create NL80211_CMD_NEW_INTERFACE; result = %d", result);
2537             return result;
2538         }
2539 
2540         result = request.put_u32(NL80211_ATTR_IFINDEX, wlan0_id);
2541         if (result < 0) {
2542             ALOGE("failed to put NL80211_ATTR_IFINDEX; result = %d", result);
2543             return result;
2544         }
2545 
2546         result = request.put_string(NL80211_ATTR_IFNAME, ifname);
2547         if (result < 0) {
2548             ALOGE("failed to put NL80211_ATTR_IFNAME = %s; result = %d", ifname, result);
2549             return result;
2550         }
2551 
2552         result = request.put_u32(NL80211_ATTR_IFTYPE, iface_type);
2553         if (result < 0) {
2554             ALOGE("failed to put NL80211_ATTR_IFTYPE = %d; result = %d", iface_type, result);
2555             return result;
2556         }
2557         return WIFI_SUCCESS;
2558     }
2559 
deleteRequest(WifiRequest & request,const char * ifname)2560     int deleteRequest(WifiRequest& request, const char* ifname) {
2561         ALOGD("delete ifname = %s\n", ifname);
2562         int result = request.create(NL80211_CMD_DEL_INTERFACE);
2563         if (result < 0) {
2564             ALOGE("failed to create NL80211_CMD_DEL_INTERFACE; result = %d", result);
2565             return result;
2566         }
2567         result = request.put_u32(NL80211_ATTR_IFINDEX, if_nametoindex(ifname));
2568         if (result < 0) {
2569             ALOGE("failed to put NL80211_ATTR_IFINDEX = %d; result = %d",
2570                 if_nametoindex(ifname), result);
2571             return result;
2572         }
2573         result = request.put_string(NL80211_ATTR_IFNAME, ifname);
2574         if (result < 0) {
2575             ALOGE("failed to put NL80211_ATTR_IFNAME = %s; result = %d", ifname, result);
2576             return result;
2577         }
2578         return WIFI_SUCCESS;
2579     }
2580 
createIface()2581     int createIface() {
2582         ALOGD("Creating virtual interface");
2583         WifiRequest request(familyId(), ifaceId());
2584         int result = createRequest(request, mIfname, mType, mwlan0_id);
2585         if (result != WIFI_SUCCESS) {
2586             ALOGE("failed to create virtual iface request; result = %d\n", result);
2587             return result;
2588         }
2589 
2590         result = requestResponse(request);
2591         if (result != WIFI_SUCCESS) {
2592             ALOGE("failed to get the virtual iface create response; result = %d\n", result);
2593             return result;
2594         }
2595         ALOGD("Created virtual interface");
2596         return WIFI_SUCCESS;
2597     }
2598 
deleteIface()2599     int deleteIface() {
2600         ALOGD("Deleting virtual interface");
2601         WifiRequest request(familyId(), ifaceId());
2602         int result = deleteRequest(request, mIfname);
2603         if (result != WIFI_SUCCESS) {
2604             ALOGE("failed to create virtual iface delete request; result = %d\n", result);
2605             return result;
2606         }
2607 
2608         result = requestResponse(request);
2609         if (result != WIFI_SUCCESS) {
2610             ALOGE("failed to get response of delete virtual interface; result = %d\n", result);
2611             return result;
2612         }
2613         ALOGD("Deleted virtual interface");
2614         return WIFI_SUCCESS;
2615     }
2616 protected:
handleResponse(WifiEvent & reply)2617     virtual int handleResponse(WifiEvent& reply) {
2618          ALOGD("Request complete!");
2619         /* Nothing to do on response! */
2620         return NL_SKIP;
2621     }
2622 };
2623 
2624 static std::vector<std::string> added_ifaces;
2625 
wifi_cleanup_dynamic_ifaces(wifi_handle handle)2626 static void wifi_cleanup_dynamic_ifaces(wifi_handle handle)
2627 {
2628     int len = added_ifaces.size();
2629     ALOGI("%s: virtual iface size %d\n", __FUNCTION__, len);
2630     while (len--) {
2631         wifi_virtual_interface_delete(handle, added_ifaces.front().c_str());
2632         ALOGI("%s: deleted virtual iface %s\n",
2633             __FUNCTION__, added_ifaces.front().c_str());
2634     }
2635     added_ifaces.clear();
2636 }
2637 
wifi_virtual_interface_create(wifi_handle handle,const char * ifname,wifi_interface_type iface_type)2638 wifi_error wifi_virtual_interface_create(wifi_handle handle, const char* ifname,
2639         wifi_interface_type iface_type)
2640 {
2641     int numIfaceHandles = 0;
2642     wifi_error ret = WIFI_SUCCESS;
2643     wifi_interface_handle *ifaceHandles = NULL;
2644     wifi_interface_handle wlan0Handle;
2645     nl80211_iftype type = NL80211_IFTYPE_UNSPECIFIED;
2646     u32 wlan0_id = if_nametoindex("wlan0");
2647 
2648     if (!handle || !wlan0_id) {
2649         ALOGE("%s: Error wifi_handle NULL or wlan0 not present\n", __FUNCTION__);
2650         return WIFI_ERROR_UNKNOWN;
2651     }
2652 
2653     /* Do not create interface if already exist. */
2654     if (if_nametoindex(ifname)) {
2655         ALOGD("%s: if_nametoindex(%s) = %d already exists, skip create \n",
2656             __FUNCTION__, ifname, if_nametoindex(ifname));
2657         return WIFI_SUCCESS;
2658     }
2659 
2660     ALOGD("%s: ifname name = %s, type = %s\n", __FUNCTION__, ifname,
2661         IfaceTypeToString(iface_type));
2662 
2663     switch (iface_type) {
2664         case WIFI_INTERFACE_TYPE_STA:
2665             type = NL80211_IFTYPE_STATION;
2666             break;
2667         case WIFI_INTERFACE_TYPE_AP:
2668             type = NL80211_IFTYPE_AP;
2669             break;
2670         case WIFI_INTERFACE_TYPE_P2P:
2671             type = NL80211_IFTYPE_P2P_DEVICE;
2672             break;
2673         case WIFI_INTERFACE_TYPE_NAN:
2674             ALOGE("%s: Unsupported interface type %u\n", __FUNCTION__, iface_type);
2675             return WIFI_ERROR_NOT_SUPPORTED;
2676         default:
2677             ALOGE("%s: Wrong interface type %u\n", __FUNCTION__, iface_type);
2678             return WIFI_ERROR_UNKNOWN;
2679     }
2680 
2681     wlan0Handle = wifi_get_wlan_interface((wifi_handle)handle, ifaceHandles, numIfaceHandles);
2682     VirtualIfaceConfig command(wlan0Handle, ifname, type, wlan0_id);
2683 
2684     ret = (wifi_error)command.createIface();
2685     if (ret != WIFI_SUCCESS) {
2686         ALOGE("%s: Iface add Error:%d", __FUNCTION__,ret);
2687         return ret;
2688     }
2689     /* Update dynamic interface list */
2690     added_ifaces.push_back(std::string(ifname));
2691     ret = wifi_add_iface_hal_info((wifi_handle)handle, ifname);
2692     return ret;
2693 }
2694 
wifi_virtual_interface_delete(wifi_handle handle,const char * ifname)2695 wifi_error wifi_virtual_interface_delete(wifi_handle handle, const char* ifname)
2696 {
2697     int numIfaceHandles = 0;
2698     int i = 0;
2699     wifi_error ret = WIFI_SUCCESS;
2700     wifi_interface_handle *ifaceHandles = NULL;
2701     wifi_interface_handle wlan0Handle;
2702     hal_info *info = (hal_info *)handle;
2703     u32 wlan0_id = if_nametoindex("wlan0");
2704 
2705     if (!handle || !wlan0_id) {
2706         ALOGE("%s: Error wifi_handle NULL or wlan0 not present\n", __FUNCTION__);
2707         return WIFI_ERROR_UNKNOWN;
2708     }
2709 
2710     /* Check if interface delete requested on valid interface */
2711     while (i < info->max_num_interfaces) {
2712         if (info->interfaces[i] != NULL &&
2713             strncmp(info->interfaces[i]->name,
2714             ifname, sizeof(info->interfaces[i]->name)) == 0) {
2715             if (!get_halutil_mode()) {
2716                 if (info->interfaces[i]->is_virtual == false) {
2717                     ALOGI("%s: %s is static iface, skip delete\n",
2718                         __FUNCTION__, ifname);
2719                         return WIFI_SUCCESS;
2720                 }
2721             } else {
2722                 ALOGI("%s: %s delete iface", __FUNCTION__, ifname);
2723                 break;
2724             }
2725         }
2726         i++;
2727     }
2728 
2729     ALOGI("%s: iface name=%s\n", __FUNCTION__, ifname);
2730     wlan0Handle = wifi_get_wlan_interface((wifi_handle)handle, ifaceHandles, numIfaceHandles);
2731     VirtualIfaceConfig command(wlan0Handle, ifname, (nl80211_iftype)0, 0);
2732     ret = (wifi_error)command.deleteIface();
2733     if (ret != WIFI_SUCCESS) {
2734         ALOGE("%s: Iface delete Error:%d", __FUNCTION__,ret);
2735         /* If lower layer returns an error, hang event is expected to do wifi reset
2736          * and hal state needs to be cleared irrespectivily. Hence fall-through.
2737          */
2738     }
2739     /* Update dynamic interface list */
2740     added_ifaces.erase(std::remove(added_ifaces.begin(), added_ifaces.end(), std::string(ifname)),
2741         added_ifaces.end());
2742     ret = wifi_clear_iface_hal_info((wifi_handle)handle, ifname);
2743     return ret;
2744 }
2745 /////////////////////////////////////////////////////////////////////////////
2746 
2747 class MultiStaConfig : public WifiCommand {
2748     wifi_multi_sta_use_case mUseCase;
2749     int mReqType;
2750 
2751 public:
MultiStaConfig(wifi_interface_handle handle)2752     MultiStaConfig(wifi_interface_handle handle)
2753     : WifiCommand("MultiStaConfig", handle, 0), mReqType(SET_PRIMARY_CONNECTION)
2754     {
2755         mUseCase = WIFI_DUAL_STA_TRANSIENT_PREFER_PRIMARY;
2756     }
MultiStaConfig(wifi_interface_handle handle,wifi_multi_sta_use_case use_case)2757     MultiStaConfig(wifi_interface_handle handle, wifi_multi_sta_use_case use_case)
2758     : WifiCommand("MultiStaConfig", handle, 0), mUseCase(use_case), mReqType(SET_USE_CASE)
2759     {
2760         mUseCase = use_case;
2761     }
2762 
createRequest(WifiRequest & request)2763     int createRequest(WifiRequest& request) {
2764         if (mReqType == SET_PRIMARY_CONNECTION) {
2765             ALOGI("\n%s: MultiSta set primary connection\n", __FUNCTION__);
2766             return createSetPrimaryConnectionRequest(request);
2767         } else if (mReqType == SET_USE_CASE) {
2768             ALOGI("\n%s: MultiSta set use case\n", __FUNCTION__);
2769             return createSetUsecaseRequest(request);
2770         } else {
2771             ALOGE("\n%s Unknown MultiSta request\n", __FUNCTION__);
2772             return WIFI_ERROR_NOT_SUPPORTED;
2773         }
2774         return WIFI_SUCCESS;
2775     }
2776 
createSetPrimaryConnectionRequest(WifiRequest & request)2777     int createSetPrimaryConnectionRequest(WifiRequest& request) {
2778         int result = request.create(GOOGLE_OUI, WIFI_SUBCMD_SET_MULTISTA_PRIMARY_CONNECTION);
2779         if (result < 0) {
2780             return result;
2781         }
2782 
2783         nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
2784         request.attr_end(data);
2785 
2786         return result;
2787     }
2788 
createSetUsecaseRequest(WifiRequest & request)2789     int createSetUsecaseRequest(WifiRequest& request) {
2790         int result = request.create(GOOGLE_OUI, WIFI_SUBCMD_SET_MULTISTA_USE_CASE);
2791         if (result < 0) {
2792             return result;
2793         }
2794 
2795         nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
2796         result = request.put_u32(MULTISTA_ATTRIBUTE_USE_CASE, mUseCase);
2797         if (result < 0) {
2798             ALOGE("failed to put MULTISTA_ATTRIBUTE_USE_CASE = %d; result = %d", mUseCase, result);
2799             goto exit;
2800         }
2801 
2802 exit:   request.attr_end(data);
2803         return result;
2804     }
2805 
start()2806     int start() {
2807         WifiRequest request(familyId(), ifaceId());
2808         int result = createRequest(request);
2809         if (result < 0) {
2810             return result;
2811         }
2812         result = requestResponse(request);
2813         if (result < 0) {
2814             ALOGI("Request Response failed for MultiSta, result = %d", result);
2815             return result;
2816         }
2817         ALOGI("Done!");
2818         return result;
2819     }
2820 protected:
handleResponse(WifiEvent & reply)2821     virtual int handleResponse(WifiEvent& reply) {
2822         ALOGD("Request complete!");
2823         /* Nothing to do on response! */
2824         return NL_SKIP;
2825     }
2826 };
2827 
wifi_multi_sta_set_primary_connection(wifi_handle handle,wifi_interface_handle iface)2828 wifi_error wifi_multi_sta_set_primary_connection(wifi_handle handle, wifi_interface_handle iface)
2829 {
2830     wifi_error ret = WIFI_SUCCESS;
2831     char buf[IFNAMSIZ];
2832 
2833     if (!handle || !iface) {
2834         ALOGE("%s: Error wifi_handle NULL or invalid wifi interface handle\n", __FUNCTION__);
2835         return WIFI_ERROR_UNKNOWN;
2836     }
2837 
2838     if (wifi_get_iface_name(iface, buf, sizeof(buf)) != WIFI_SUCCESS) {
2839         ALOGE("%s : Invalid interface handle\n", __func__);
2840         return WIFI_ERROR_INVALID_ARGS;
2841     }
2842 
2843     ALOGD("Setting Multista primary connection for iface = %s\n", buf);
2844 
2845     MultiStaConfig *cmd = new MultiStaConfig(iface);
2846     NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
2847     ret = (wifi_error)cmd->start();
2848     cmd->releaseRef();
2849     return ret;
2850 }
2851 
wifi_multi_sta_set_use_case(wifi_handle handle,wifi_multi_sta_use_case use_case)2852 wifi_error wifi_multi_sta_set_use_case(wifi_handle handle, wifi_multi_sta_use_case use_case)
2853 {
2854     int numIfaceHandles = 0;
2855     wifi_error ret = WIFI_SUCCESS;
2856     wifi_interface_handle *ifaceHandles = NULL;
2857     wifi_interface_handle wlan0Handle;
2858 
2859     if (!handle) {
2860         ALOGE("%s: Error wifi_handle NULL\n", __FUNCTION__);
2861         return WIFI_ERROR_UNKNOWN;
2862     }
2863 
2864     if (!(use_case >= WIFI_DUAL_STA_TRANSIENT_PREFER_PRIMARY &&
2865 	    use_case <= WIFI_DUAL_STA_NON_TRANSIENT_UNBIASED)) {
2866         ALOGE("%s: Invalid  multi_sta usecase %d\n", __FUNCTION__, use_case);
2867         return WIFI_ERROR_INVALID_ARGS;
2868     }
2869 
2870     wlan0Handle = wifi_get_wlan_interface((wifi_handle)handle, ifaceHandles, numIfaceHandles);
2871     ALOGD("Setting Multista usecase = %d\n", use_case);
2872     MultiStaConfig *cmd = new MultiStaConfig(wlan0Handle, use_case);
2873     NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
2874     ret = (wifi_error)cmd->start();
2875     cmd->releaseRef();
2876     return ret;
2877 }
2878 /////////////////////////////////////////////////////////////////////////////////////////////////
2879 
2880 class SetVoipModeCommand : public WifiCommand {
2881 
2882 private:
2883     wifi_voip_mode mMode;
2884 public:
SetVoipModeCommand(wifi_interface_handle handle,wifi_voip_mode mode)2885     SetVoipModeCommand(wifi_interface_handle handle, wifi_voip_mode mode)
2886         : WifiCommand("SetVoipModeCommand", handle, 0) {
2887         mMode = mode;
2888     }
create()2889     virtual int create() {
2890         int ret;
2891 
2892         ret = mMsg.create(GOOGLE_OUI, WIFI_SUBCMD_CONFIG_VOIP_MODE);
2893         if (ret < 0) {
2894             ALOGE("Can't create message to send to driver - %d", ret);
2895             return ret;
2896         }
2897 
2898         nlattr *data = mMsg.attr_start(NL80211_ATTR_VENDOR_DATA);
2899         ret = mMsg.put_u32(ANDR_WIFI_ATTRIBUTE_VOIP_MODE, mMode);
2900         ALOGE("mMode - %d", mMode);
2901         if (ret < 0) {
2902              ALOGE("Failed to set voip mode %d\n", mMode);
2903              return ret;
2904         }
2905 
2906         ALOGI("Successfully configured voip mode %d\n", mMode);
2907         mMsg.attr_end(data);
2908         return WIFI_SUCCESS;
2909     }
2910 };
2911 
wifi_set_voip_mode(wifi_interface_handle handle,wifi_voip_mode mode)2912 wifi_error wifi_set_voip_mode(wifi_interface_handle handle, wifi_voip_mode mode)
2913 {
2914     ALOGD("Setting VOIP mode, halHandle = %p Mode = %d\n", handle, mode);
2915     SetVoipModeCommand command(handle, mode);
2916     return (wifi_error) command.requestResponse();
2917 }
2918 
2919 /////////////////////////////////////////////////////////////////////////////////////////////////
2920 class SetDtimConfigCommand : public WifiCommand {
2921 
2922 private:
2923     uint32_t multiplier;
2924 public:
SetDtimConfigCommand(wifi_interface_handle handle,u32 dtim_multiplier)2925     SetDtimConfigCommand(wifi_interface_handle handle, u32 dtim_multiplier)
2926         : WifiCommand("SetDtimConfigCommand", handle, 0) {
2927         multiplier = dtim_multiplier;
2928     }
create()2929     virtual int create() {
2930         int ret;
2931 
2932         ret = mMsg.create(GOOGLE_OUI, WIFI_SUBCMD_SET_DTIM_CONFIG);
2933         if (ret < 0) {
2934             ALOGE("Can't create message to send to driver - %d", ret);
2935             return ret;
2936         }
2937 
2938         nlattr *data = mMsg.attr_start(NL80211_ATTR_VENDOR_DATA);
2939         ret = mMsg.put_u32(ANDR_WIFI_ATTRIBUTE_DTIM_MULTIPLIER, multiplier);
2940         if (ret < 0) {
2941              ALOGE("Failed to set dtim mutiplier %d\n", multiplier);
2942              return ret;
2943         }
2944 
2945         ALOGI("Successfully configured dtim multiplier %d\n", multiplier);
2946         mMsg.attr_end(data);
2947         return WIFI_SUCCESS;
2948     }
2949 };
2950 
wifi_set_dtim_config(wifi_interface_handle handle,u32 multiplier)2951 wifi_error wifi_set_dtim_config(wifi_interface_handle handle, u32 multiplier)
2952 {
2953     ALOGD("Setting DTIM config , halHandle = %p Multiplier = %d\n", handle, multiplier);
2954     SetDtimConfigCommand command(handle, multiplier);
2955     return (wifi_error) command.requestResponse();
2956 }
2957 
2958 /////////////////////////////////////////////////////////////////////////////////////////////////
2959 class UsableChannelCommand : public WifiCommand {
2960 
2961 private:
2962     u32 mBandMask;
2963     u32 mIfaceModeMask;
2964     u32 mFilterMask;
2965     u32 mMaxSize;
2966     u32* mSize;
2967     wifi_usable_channel* mChannels;
2968 
2969 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)2970     UsableChannelCommand(wifi_interface_handle handle, u32 band_mask, u32 iface_mode_mask,
2971                    u32 filter_mask, u32 max_size, u32* size, wifi_usable_channel* channels)
2972         : WifiCommand("UsableChannelCommand", handle, 0),
2973                        mBandMask(band_mask), mIfaceModeMask(iface_mode_mask),
2974                        mFilterMask(filter_mask), mMaxSize(max_size),
2975 		       mSize(size), mChannels(channels)
2976     {
2977     }
2978 
createRequest(WifiRequest & request)2979     int createRequest(WifiRequest& request) {
2980         createUsableChannelRequest(request);
2981         return WIFI_SUCCESS;
2982     }
2983 
createUsableChannelRequest(WifiRequest & request)2984     int createUsableChannelRequest(WifiRequest& request) {
2985         int result = request.create(GOOGLE_OUI, WIFI_SUBCMD_USABLE_CHANNEL);
2986         if (result < 0) {
2987             ALOGE("Failed to create UsableChannel request; result = %d", result);
2988             return result;
2989         }
2990 
2991         nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
2992 
2993         result = request.put_u32(USABLECHAN_ATTRIBUTE_BAND, mBandMask);
2994         if (result != WIFI_SUCCESS) {
2995             ALOGE("Failed to put log level; result = %d", result);
2996             return result;
2997         }
2998         result = request.put_u32(USABLECHAN_ATTRIBUTE_IFACE, mIfaceModeMask);
2999         if (result != WIFI_SUCCESS) {
3000             ALOGE("Failed to put ring flags; result = %d", result);
3001             return result;
3002         }
3003         result = request.put_u32(USABLECHAN_ATTRIBUTE_FILTER, mFilterMask);
3004         if (result != WIFI_SUCCESS) {
3005             ALOGE("Failed to put usablechan filter; result = %d", result);
3006             return result;
3007         }
3008         result = request.put_u32(USABLECHAN_ATTRIBUTE_MAX_SIZE, mMaxSize);
3009         if (result != WIFI_SUCCESS) {
3010             ALOGE("Failed to put usablechan max_size; result = %d", result);
3011             return result;
3012         }
3013         request.attr_end(data);
3014 
3015         return WIFI_SUCCESS;
3016     }
3017 
start()3018     int start() {
3019         WifiRequest request(familyId(), ifaceId());
3020         int result = createRequest(request);
3021         if (result != WIFI_SUCCESS) {
3022             ALOGE("failed to create request; result = %d", result);
3023             return result;
3024         }
3025 
3026         result = requestResponse(request);
3027         if (result != WIFI_SUCCESS) {
3028             ALOGE("failed to set scanning mac OUI; result = %d", result);
3029         }
3030 
3031         return result;
3032     }
3033 
handleResponse(WifiEvent & reply)3034     virtual int handleResponse(WifiEvent& reply) {
3035         ALOGD("In DebugCommand::handleResponse");
3036 
3037         if (reply.get_cmd() != NL80211_CMD_VENDOR) {
3038             ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
3039             return NL_SKIP;
3040         }
3041 
3042         nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA);
3043         int len = reply.get_vendor_data_len();
3044         wifi_usable_channel *channels(mChannels);
3045 
3046         if (vendor_data == NULL || len == 0) {
3047             ALOGE("No Debug data found");
3048             return NL_SKIP;
3049         }
3050 
3051         nl_iterator it(vendor_data);
3052         if (it.get_type() == USABLECHAN_ATTRIBUTE_SIZE) {
3053             *mSize = it.get_u32();
3054         } else {
3055             ALOGE("Unknown attribute: %d expecting %d",
3056                 it.get_type(), USABLECHAN_ATTRIBUTE_SIZE);
3057             return NL_SKIP;
3058         }
3059 
3060         it.next();
3061         if (it.get_type() == USABLECHAN_ATTRIBUTE_CHANNELS) {
3062             memcpy(channels, it.get_data(), sizeof(wifi_usable_channel) * *mSize);
3063         } else {
3064             ALOGE("Unknown attribute: %d expecting %d",
3065                 it.get_type(), USABLECHAN_ATTRIBUTE_SIZE);
3066             return NL_SKIP;
3067         }
3068 
3069         return NL_OK;
3070     }
3071 
handleEvent(WifiEvent & event)3072     virtual int handleEvent(WifiEvent& event) {
3073         /* NO events! */
3074         return NL_SKIP;
3075     }
3076 };
3077 
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)3078 wifi_error wifi_get_usable_channels(wifi_handle handle, u32 band_mask, u32 iface_mode_mask,
3079 		u32 filter_mask, u32 max_size, u32* size, wifi_usable_channel* channels)
3080 {
3081     int numIfaceHandles = 0;
3082     wifi_interface_handle *ifaceHandles = NULL;
3083     wifi_interface_handle wlan0Handle;
3084 
3085     wlan0Handle = wifi_get_wlan_interface((wifi_handle)handle, ifaceHandles, numIfaceHandles);
3086     UsableChannelCommand command(wlan0Handle, band_mask, iface_mode_mask,
3087                                     filter_mask, max_size, size, channels);
3088     return (wifi_error)command.start();
3089 }
3090 
3091 /////////////////////////////////////////////////////////////////////////////////////////////////
3092 class EnableTxPowerLimit : public WifiCommand {
3093 private:
3094     bool mEnableTxLimits;
3095 public:
EnableTxPowerLimit(wifi_interface_handle handle,bool enable_tx_pwr_limits)3096     EnableTxPowerLimit(wifi_interface_handle handle, bool enable_tx_pwr_limits)
3097         : WifiCommand("EnableTxPowerLimit", handle, 0)
3098     {
3099         mEnableTxLimits = enable_tx_pwr_limits;
3100     }
3101 
create()3102     virtual int create() {
3103         int ret;
3104 
3105         ret = mMsg.create(GOOGLE_OUI, WIFI_SUBCMD_ENABLE_TX_POWER_LIMIT);
3106         if (ret < 0) {
3107             ALOGE("Can't create message to send to driver - %d", ret);
3108             return ret;
3109         }
3110 
3111         nlattr *data = mMsg.attr_start(NL80211_ATTR_VENDOR_DATA);
3112         ret = mMsg.put_u8(TX_POWER_CAP_ENABLE_ATTRIBUTE, mEnableTxLimits);
3113         if (ret < 0) {
3114              ALOGE("Failed to put enable tx power limit param %d\n", mEnableTxLimits);
3115              return ret;
3116         }
3117         mMsg.attr_end(data);
3118         return WIFI_SUCCESS;
3119     }
3120 };
3121 
wifi_enable_tx_power_limits(wifi_interface_handle handle,bool isEnable)3122 wifi_error wifi_enable_tx_power_limits(wifi_interface_handle handle, bool isEnable)
3123 {
3124     ALOGD("Configuring the tx power limits , halHandle = %p\n", handle);
3125 
3126     EnableTxPowerLimit command(handle, isEnable);
3127     return (wifi_error) command.requestResponse();
3128 }
3129 
3130 //////////////////////////////////////////////////////
3131 class EnableStaChannel : public WifiCommand {
3132 
3133 private:
3134     u32 mChannelCatEnabFlag;
3135 public:
EnableStaChannel(wifi_interface_handle handle,u32 channelCategoryEnableFlag)3136     EnableStaChannel(wifi_interface_handle handle, u32 channelCategoryEnableFlag)
3137         : WifiCommand("EnableStaChannel", handle, 0) {
3138         mChannelCatEnabFlag = channelCategoryEnableFlag;
3139     }
create()3140     virtual int create() {
3141         int ret;
3142 
3143         ret = mMsg.create(GOOGLE_OUI, WIFI_SUBCMD_CHANNEL_POLICY);
3144         if (ret < 0) {
3145             ALOGE("Can't create message to send to driver - %d", ret);
3146             return ret;
3147         }
3148 
3149         nlattr *data = mMsg.attr_start(NL80211_ATTR_VENDOR_DATA);
3150         ret = mMsg.put_u32(ANDR_WIFI_ATTRIBUTE_CHAN_POLICY, mChannelCatEnabFlag);
3151         if (ret < 0) {
3152              return ret;
3153         }
3154 
3155         mMsg.attr_end(data);
3156         return WIFI_SUCCESS;
3157     }
3158 };
3159 
3160 /* enable or disable the feature of allowing current STA-connected
3161  * channel for WFA GO, SAP and Wi-Fi Aware when the regulatory allows.
3162  */
wifi_enable_sta_channel_for_peer_network(wifi_handle handle,u32 channelCategoryEnableFlag)3163 wifi_error wifi_enable_sta_channel_for_peer_network(wifi_handle handle,
3164         u32 channelCategoryEnableFlag) {
3165     int numIfaceHandles = 0;
3166     wifi_interface_handle *ifaceHandles = NULL;
3167     wifi_interface_handle wlan0Handle;
3168 
3169     wlan0Handle = wifi_get_wlan_interface((wifi_handle)handle, ifaceHandles, numIfaceHandles);
3170     EnableStaChannel command(wlan0Handle, channelCategoryEnableFlag);
3171     return (wifi_error) command.requestResponse();
3172 }
3173