1 #include <stdint.h>
2 #include <fcntl.h>
3 #include <sys/socket.h>
4 #include <netlink/genl/genl.h>
5 #include <netlink/genl/family.h>
6 #include <netlink/genl/ctrl.h>
7 #include <linux/rtnetlink.h>
8 #include <netpacket/packet.h>
9 #include <linux/filter.h>
10 #include <linux/errqueue.h>
11 #include <errno.h>
12
13 #include <linux/pkt_sched.h>
14 #include <netlink/object-api.h>
15 #include <netlink/netlink.h>
16 #include <netlink/socket.h>
17 #include <netlink/attr.h>
18 #include <netlink/handlers.h>
19 #include <netlink/msg.h>
20
21 #include <dirent.h>
22 #include <net/if.h>
23
24 #include "sync.h"
25
26 #define LOG_TAG "WifiHAL"
27
28 #include <utils/Log.h>
29
30 #include "wifi_hal.h"
31 #include "common.h"
32 #include "cpp_bindings.h"
33 #include "rtt.h"
34 /*
35 BUGBUG: normally, libnl allocates ports for all connections it makes; but
36 being a static library, it doesn't really know how many other netlink connections
37 are made by the same process, if connections come from different shared libraries.
38 These port assignments exist to solve that problem - temporarily. We need to fix
39 libnl to try and allocate ports across the entire process.
40 */
41
42 #define WIFI_HAL_CMD_SOCK_PORT 644
43 #define WIFI_HAL_EVENT_SOCK_PORT 645
44
45 static void internal_event_handler(wifi_handle handle, int events);
46 static int internal_no_seq_check(nl_msg *msg, void *arg);
47 static int internal_valid_message_handler(nl_msg *msg, void *arg);
48 static int wifi_get_multicast_id(wifi_handle handle, const char *name, const char *group);
49 static int wifi_add_membership(wifi_handle handle, const char *group);
50 static wifi_error wifi_init_interfaces(wifi_handle handle);
51 static wifi_error wifi_start_rssi_monitoring(wifi_request_id id, wifi_interface_handle
52 iface, s8 max_rssi, s8 min_rssi, wifi_rssi_event_handler eh);
53 static wifi_error wifi_stop_rssi_monitoring(wifi_request_id id, wifi_interface_handle iface);
54 static wifi_error wifi_set_packet_filter(wifi_interface_handle handle,
55 const u8 *program, u32 len);
56 static wifi_error wifi_get_packet_filter_capabilities(wifi_interface_handle handle,
57 u32 *version, u32 *max_len);
58 static wifi_error wifi_configure_nd_offload(wifi_interface_handle iface, u8 enable);
59
60 typedef enum wifi_attr {
61 ANDR_WIFI_ATTRIBUTE_NUM_FEATURE_SET,
62 ANDR_WIFI_ATTRIBUTE_FEATURE_SET,
63 ANDR_WIFI_ATTRIBUTE_PNO_RANDOM_MAC_OUI,
64 ANDR_WIFI_ATTRIBUTE_NODFS_SET,
65 ANDR_WIFI_ATTRIBUTE_COUNTRY,
66 ANDR_WIFI_ATTRIBUTE_ND_OFFLOAD_VALUE
67 // Add more attribute here
68 } wifi_attr_t;
69
70 enum wifi_rssi_monitor_attr {
71 RSSI_MONITOR_ATTRIBUTE_MAX_RSSI,
72 RSSI_MONITOR_ATTRIBUTE_MIN_RSSI,
73 RSSI_MONITOR_ATTRIBUTE_START,
74 };
75
76 enum wifi_apf_attr {
77 APF_ATTRIBUTE_VERSION,
78 APF_ATTRIBUTE_MAX_LEN,
79 APF_ATTRIBUTE_PROGRAM,
80 APF_ATTRIBUTE_PROGRAM_LEN
81 };
82
83 enum apf_request_type {
84 GET_APF_CAPABILITIES,
85 SET_APF_PROGRAM
86 };
87
88 /* Initialize/Cleanup */
89
wifi_socket_set_local_port(struct nl_sock * sock,uint32_t port)90 void wifi_socket_set_local_port(struct nl_sock *sock, uint32_t port)
91 {
92 uint32_t pid = getpid() & 0x3FFFFF;
93 nl_socket_set_local_port(sock, pid + (port << 22));
94 }
95
wifi_create_nl_socket(int port)96 static nl_sock * wifi_create_nl_socket(int port)
97 {
98 // ALOGI("Creating socket");
99 struct nl_sock *sock = nl_socket_alloc();
100 if (sock == NULL) {
101 ALOGE("Could not create handle");
102 return NULL;
103 }
104
105 wifi_socket_set_local_port(sock, port);
106
107 struct sockaddr *addr = NULL;
108 // ALOGI("sizeof(sockaddr) = %d, sizeof(sockaddr_nl) = %d", sizeof(*addr), sizeof(*addr_nl));
109
110 // ALOGI("Connecting socket");
111 if (nl_connect(sock, NETLINK_GENERIC)) {
112 ALOGE("Could not connect handle");
113 nl_socket_free(sock);
114 return NULL;
115 }
116
117 // ALOGI("Making socket nonblocking");
118 /*
119 if (nl_socket_set_nonblocking(sock)) {
120 ALOGE("Could make socket non-blocking");
121 nl_socket_free(sock);
122 return NULL;
123 }
124 */
125
126 return sock;
127 }
128
129 /*initialize function pointer table with Broadcom HHAL API*/
init_wifi_vendor_hal_func_table(wifi_hal_fn * fn)130 wifi_error init_wifi_vendor_hal_func_table(wifi_hal_fn *fn)
131 {
132 if (fn == NULL) {
133 return WIFI_ERROR_UNKNOWN;
134 }
135 fn->wifi_initialize = wifi_initialize;
136 fn->wifi_cleanup = wifi_cleanup;
137 fn->wifi_event_loop = wifi_event_loop;
138 fn->wifi_get_supported_feature_set = wifi_get_supported_feature_set;
139 fn->wifi_get_concurrency_matrix = wifi_get_concurrency_matrix;
140 fn->wifi_set_scanning_mac_oui = wifi_set_scanning_mac_oui;
141 fn->wifi_get_ifaces = wifi_get_ifaces;
142 fn->wifi_get_iface_name = wifi_get_iface_name;
143 fn->wifi_start_gscan = wifi_start_gscan;
144 fn->wifi_stop_gscan = wifi_stop_gscan;
145 fn->wifi_get_cached_gscan_results = wifi_get_cached_gscan_results;
146 fn->wifi_set_bssid_hotlist = wifi_set_bssid_hotlist;
147 fn->wifi_reset_bssid_hotlist = wifi_reset_bssid_hotlist;
148 fn->wifi_set_significant_change_handler = wifi_set_significant_change_handler;
149 fn->wifi_reset_significant_change_handler = wifi_reset_significant_change_handler;
150 fn->wifi_get_gscan_capabilities = wifi_get_gscan_capabilities;
151 fn->wifi_get_link_stats = wifi_get_link_stats;
152 fn->wifi_set_link_stats = wifi_set_link_stats;
153 fn->wifi_clear_link_stats = wifi_clear_link_stats;
154 fn->wifi_get_valid_channels = wifi_get_valid_channels;
155 fn->wifi_rtt_range_request = wifi_rtt_range_request;
156 fn->wifi_rtt_range_cancel = wifi_rtt_range_cancel;
157 fn->wifi_get_rtt_capabilities = wifi_get_rtt_capabilities;
158 fn->wifi_rtt_get_responder_info = wifi_rtt_get_responder_info;
159 fn->wifi_enable_responder = wifi_enable_responder;
160 fn->wifi_disable_responder = wifi_disable_responder;
161 fn->wifi_set_nodfs_flag = wifi_set_nodfs_flag;
162 fn->wifi_start_logging = wifi_start_logging;
163 fn->wifi_set_epno_list = wifi_set_epno_list;
164 fn->wifi_reset_epno_list = wifi_reset_epno_list;
165 fn->wifi_set_country_code = wifi_set_country_code;
166 fn->wifi_get_firmware_memory_dump = wifi_get_firmware_memory_dump;
167 fn->wifi_set_log_handler = wifi_set_log_handler;
168 fn->wifi_reset_log_handler = wifi_reset_log_handler;
169 fn->wifi_set_alert_handler = wifi_set_alert_handler;
170 fn->wifi_reset_alert_handler = wifi_reset_alert_handler;
171 fn->wifi_get_firmware_version = wifi_get_firmware_version;
172 fn->wifi_get_ring_buffers_status = wifi_get_ring_buffers_status;
173 fn->wifi_get_logger_supported_feature_set = wifi_get_logger_supported_feature_set;
174 fn->wifi_get_ring_data = wifi_get_ring_data;
175 fn->wifi_get_driver_version = wifi_get_driver_version;
176 fn->wifi_start_rssi_monitoring = wifi_start_rssi_monitoring;
177 fn->wifi_stop_rssi_monitoring = wifi_stop_rssi_monitoring;
178 fn->wifi_configure_nd_offload = wifi_configure_nd_offload;
179 fn->wifi_start_sending_offloaded_packet = wifi_start_sending_offloaded_packet;
180 fn->wifi_stop_sending_offloaded_packet = wifi_stop_sending_offloaded_packet;
181 fn->wifi_start_pkt_fate_monitoring = wifi_start_pkt_fate_monitoring;
182 fn->wifi_get_tx_pkt_fates = wifi_get_tx_pkt_fates;
183 fn->wifi_get_rx_pkt_fates = wifi_get_rx_pkt_fates;
184 fn->wifi_get_packet_filter_capabilities = wifi_get_packet_filter_capabilities;
185 fn->wifi_set_packet_filter = wifi_set_packet_filter;
186 return WIFI_SUCCESS;
187 }
188
wifi_initialize(wifi_handle * handle)189 wifi_error wifi_initialize(wifi_handle *handle)
190 {
191 srand(getpid());
192
193 ALOGI("Initializing wifi");
194 hal_info *info = (hal_info *)malloc(sizeof(hal_info));
195 if (info == NULL) {
196 ALOGE("Could not allocate hal_info");
197 return WIFI_ERROR_UNKNOWN;
198 }
199
200 memset(info, 0, sizeof(*info));
201
202 ALOGI("Creating socket");
203 if (socketpair(AF_UNIX, SOCK_STREAM, 0, info->cleanup_socks) == -1) {
204 ALOGE("Could not create cleanup sockets");
205 free(info);
206 return WIFI_ERROR_UNKNOWN;
207 }
208
209 struct nl_sock *cmd_sock = wifi_create_nl_socket(WIFI_HAL_CMD_SOCK_PORT);
210 if (cmd_sock == NULL) {
211 ALOGE("Could not create handle");
212 free(info);
213 return WIFI_ERROR_UNKNOWN;
214 }
215
216 struct nl_sock *event_sock = wifi_create_nl_socket(WIFI_HAL_EVENT_SOCK_PORT);
217 if (event_sock == NULL) {
218 ALOGE("Could not create handle");
219 nl_socket_free(cmd_sock);
220 free(info);
221 return WIFI_ERROR_UNKNOWN;
222 }
223
224 struct nl_cb *cb = nl_socket_get_cb(event_sock);
225 if (cb == NULL) {
226 ALOGE("Could not create handle");
227 nl_socket_free(cmd_sock);
228 nl_socket_free(event_sock);
229 free(info);
230 return WIFI_ERROR_UNKNOWN;
231 }
232
233 // ALOGI("cb->refcnt = %d", cb->cb_refcnt);
234 nl_cb_set(cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, internal_no_seq_check, info);
235 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, internal_valid_message_handler, info);
236 nl_cb_put(cb);
237
238 info->cmd_sock = cmd_sock;
239 info->event_sock = event_sock;
240 info->clean_up = false;
241 info->in_event_loop = false;
242
243 info->event_cb = (cb_info *)malloc(sizeof(cb_info) * DEFAULT_EVENT_CB_SIZE);
244 info->alloc_event_cb = DEFAULT_EVENT_CB_SIZE;
245 info->num_event_cb = 0;
246
247 info->cmd = (cmd_info *)malloc(sizeof(cmd_info) * DEFAULT_CMD_SIZE);
248 info->alloc_cmd = DEFAULT_CMD_SIZE;
249 info->num_cmd = 0;
250
251 info->nl80211_family_id = genl_ctrl_resolve(cmd_sock, "nl80211");
252 if (info->nl80211_family_id < 0) {
253 ALOGE("Could not resolve nl80211 familty id");
254 nl_socket_free(cmd_sock);
255 nl_socket_free(event_sock);
256 free(info);
257 return WIFI_ERROR_UNKNOWN;
258 }
259
260 pthread_mutex_init(&info->cb_lock, NULL);
261
262 *handle = (wifi_handle) info;
263
264 if (wifi_init_interfaces(*handle) != WIFI_SUCCESS) {
265 ALOGE("No wifi interface found");
266 nl_socket_free(cmd_sock);
267 nl_socket_free(event_sock);
268 pthread_mutex_destroy(&info->cb_lock);
269 free(info);
270 return WIFI_ERROR_NOT_AVAILABLE;
271 }
272
273 if ((wifi_add_membership(*handle, "scan") < 0) ||
274 (wifi_add_membership(*handle, "mlme") < 0) ||
275 (wifi_add_membership(*handle, "regulatory") < 0) ||
276 (wifi_add_membership(*handle, "vendor") < 0)) {
277 ALOGE("Add membership failed");
278 nl_socket_free(cmd_sock);
279 nl_socket_free(event_sock);
280 pthread_mutex_destroy(&info->cb_lock);
281 free(info);
282 return WIFI_ERROR_NOT_AVAILABLE;
283 }
284
285 // ALOGI("Found %d interfaces", info->num_interfaces);
286
287 ALOGI("Initialized Wifi HAL Successfully; vendor cmd = %d", NL80211_CMD_VENDOR);
288 return WIFI_SUCCESS;
289 }
290
wifi_add_membership(wifi_handle handle,const char * group)291 static int wifi_add_membership(wifi_handle handle, const char *group)
292 {
293 hal_info *info = getHalInfo(handle);
294
295 int id = wifi_get_multicast_id(handle, "nl80211", group);
296 if (id < 0) {
297 ALOGE("Could not find group %s", group);
298 return id;
299 }
300
301 int ret = nl_socket_add_membership(info->event_sock, id);
302 if (ret < 0) {
303 ALOGE("Could not add membership to group %s", group);
304 }
305
306 // ALOGI("Successfully added membership for group %s", group);
307 return ret;
308 }
309
internal_cleaned_up_handler(wifi_handle handle)310 static void internal_cleaned_up_handler(wifi_handle handle)
311 {
312 hal_info *info = getHalInfo(handle);
313 wifi_cleaned_up_handler cleaned_up_handler = info->cleaned_up_handler;
314
315 if (info->cmd_sock != 0) {
316 close(info->cleanup_socks[0]);
317 close(info->cleanup_socks[1]);
318 nl_socket_free(info->cmd_sock);
319 nl_socket_free(info->event_sock);
320 info->cmd_sock = NULL;
321 info->event_sock = NULL;
322 }
323
324 (*cleaned_up_handler)(handle);
325 pthread_mutex_destroy(&info->cb_lock);
326 free(info);
327
328 ALOGI("Internal cleanup completed");
329 }
330
wifi_cleanup(wifi_handle handle,wifi_cleaned_up_handler handler)331 void wifi_cleanup(wifi_handle handle, wifi_cleaned_up_handler handler)
332 {
333 hal_info *info = getHalInfo(handle);
334 char buf[64];
335
336 info->cleaned_up_handler = handler;
337 if (TEMP_FAILURE_RETRY(write(info->cleanup_socks[0], "Exit", 4)) < 1) {
338 // As a fallback set the cleanup flag to TRUE
339 ALOGE("could not write to the cleanup socket");
340 } else {
341 // Listen to the response
342 // Hopefully we dont get errors or get hung up
343 // Not much can be done in that case, but assume that
344 // it has rx'ed the Exit message to exit the thread.
345 // As a fallback set the cleanup flag to TRUE
346 memset(buf, 0, sizeof(buf));
347 ssize_t result = TEMP_FAILURE_RETRY(read(info->cleanup_socks[0], buf, sizeof(buf)));
348 ALOGE("%s: Read after POLL returned %zd, error no = %d (%s)", __FUNCTION__,
349 result, errno, strerror(errno));
350 if (strncmp(buf, "Done", 4) == 0) {
351 ALOGE("Event processing terminated");
352 } else {
353 ALOGD("Rx'ed %s", buf);
354 }
355 }
356 info->clean_up = true;
357 pthread_mutex_lock(&info->cb_lock);
358
359 int bad_commands = 0;
360
361 for (int i = 0; i < info->num_event_cb; i++) {
362 cb_info *cbi = &(info->event_cb[i]);
363 WifiCommand *cmd = (WifiCommand *)cbi->cb_arg;
364 ALOGI("Command left in event_cb %p:%s", cmd, (cmd ? cmd->getType(): ""));
365 }
366
367 while (info->num_cmd > bad_commands) {
368 int num_cmd = info->num_cmd;
369 cmd_info *cmdi = &(info->cmd[bad_commands]);
370 WifiCommand *cmd = cmdi->cmd;
371 if (cmd != NULL) {
372 ALOGI("Cancelling command %p:%s", cmd, cmd->getType());
373 pthread_mutex_unlock(&info->cb_lock);
374 cmd->cancel();
375 pthread_mutex_lock(&info->cb_lock);
376 if (num_cmd == info->num_cmd) {
377 ALOGI("Cancelling command %p:%s did not work", cmd, (cmd ? cmd->getType(): ""));
378 bad_commands++;
379 }
380 /* release reference added when command is saved */
381 cmd->releaseRef();
382 }
383 }
384
385 for (int i = 0; i < info->num_event_cb; i++) {
386 cb_info *cbi = &(info->event_cb[i]);
387 WifiCommand *cmd = (WifiCommand *)cbi->cb_arg;
388 ALOGE("Leaked command %p", cmd);
389 }
390 pthread_mutex_unlock(&info->cb_lock);
391 internal_cleaned_up_handler(handle);
392 }
393
internal_pollin_handler(wifi_handle handle)394 static int internal_pollin_handler(wifi_handle handle)
395 {
396 hal_info *info = getHalInfo(handle);
397 struct nl_cb *cb = nl_socket_get_cb(info->event_sock);
398 int res = nl_recvmsgs(info->event_sock, cb);
399 // ALOGD("nl_recvmsgs returned %d", res);
400 nl_cb_put(cb);
401 return res;
402 }
403
404 /* Run event handler */
wifi_event_loop(wifi_handle handle)405 void wifi_event_loop(wifi_handle handle)
406 {
407 hal_info *info = getHalInfo(handle);
408 if (info->in_event_loop) {
409 return;
410 } else {
411 info->in_event_loop = true;
412 }
413
414 pollfd pfd[2];
415 memset(&pfd[0], 0, sizeof(pollfd) * 2);
416
417 pfd[0].fd = nl_socket_get_fd(info->event_sock);
418 pfd[0].events = POLLIN;
419 pfd[1].fd = info->cleanup_socks[1];
420 pfd[1].events = POLLIN;
421
422 char buf[2048];
423 /* TODO: Add support for timeouts */
424
425 do {
426 int timeout = -1; /* Infinite timeout */
427 pfd[0].revents = 0;
428 pfd[1].revents = 0;
429 // ALOGI("Polling socket");
430 int result = TEMP_FAILURE_RETRY(poll(pfd, 2, timeout));
431 if (result < 0) {
432 // ALOGE("Error polling socket");
433 } else if (pfd[0].revents & POLLERR) {
434 ALOGE("POLL Error; error no = %d (%s)", errno, strerror(errno));
435 ssize_t result2 = TEMP_FAILURE_RETRY(read(pfd[0].fd, buf, sizeof(buf)));
436 ALOGE("Read after POLL returned %zd, error no = %d (%s)", result2,
437 errno, strerror(errno));
438 } else if (pfd[0].revents & POLLHUP) {
439 ALOGE("Remote side hung up");
440 break;
441 } else if (pfd[0].revents & POLLIN) {
442 // ALOGI("Found some events!!!");
443 internal_pollin_handler(handle);
444 } else if (pfd[1].revents & POLLIN) {
445 memset(buf, 0, sizeof(buf));
446 ssize_t result2 = TEMP_FAILURE_RETRY(read(pfd[1].fd, buf, sizeof(buf)));
447 ALOGE("%s: Read after POLL returned %zd, error no = %d (%s)", __FUNCTION__,
448 result2, errno, strerror(errno));
449 if (strncmp(buf, "Exit", 4) == 0) {
450 ALOGD("Got a signal to exit!!!");
451 if (TEMP_FAILURE_RETRY(write(pfd[1].fd, "Done", 4)) < 1) {
452 ALOGE("could not write to the cleanup socket");
453 }
454 break;
455 } else {
456 ALOGD("Rx'ed %s on the cleanup socket\n", buf);
457 }
458 } else {
459 ALOGE("Unknown event - %0x, %0x", pfd[0].revents, pfd[1].revents);
460 }
461 } while (!info->clean_up);
462 ALOGI("Exit %s", __FUNCTION__);
463 }
464
465 ///////////////////////////////////////////////////////////////////////////////////////
466
internal_no_seq_check(struct nl_msg * msg,void * arg)467 static int internal_no_seq_check(struct nl_msg *msg, void *arg)
468 {
469 return NL_OK;
470 }
471
internal_valid_message_handler(nl_msg * msg,void * arg)472 static int internal_valid_message_handler(nl_msg *msg, void *arg)
473 {
474 // ALOGI("got an event");
475
476 wifi_handle handle = (wifi_handle)arg;
477 hal_info *info = getHalInfo(handle);
478
479 WifiEvent event(msg);
480 int res = event.parse();
481 if (res < 0) {
482 ALOGE("Failed to parse event: %d", res);
483 return NL_SKIP;
484 }
485
486 int cmd = event.get_cmd();
487 uint32_t vendor_id = 0;
488 int subcmd = 0;
489
490 if (cmd == NL80211_CMD_VENDOR) {
491 vendor_id = event.get_u32(NL80211_ATTR_VENDOR_ID);
492 subcmd = event.get_u32(NL80211_ATTR_VENDOR_SUBCMD);
493 ALOGV("event received %s, vendor_id = 0x%0x, subcmd = 0x%0x",
494 event.get_cmdString(), vendor_id, subcmd);
495 } else {
496 // ALOGV("event received %s", event.get_cmdString());
497 }
498
499 // ALOGV("event received %s, vendor_id = 0x%0x", event.get_cmdString(), vendor_id);
500 // event.log();
501
502 bool dispatched = false;
503
504 pthread_mutex_lock(&info->cb_lock);
505
506 for (int i = 0; i < info->num_event_cb; i++) {
507 if (cmd == info->event_cb[i].nl_cmd) {
508 if (cmd == NL80211_CMD_VENDOR
509 && ((vendor_id != info->event_cb[i].vendor_id)
510 || (subcmd != info->event_cb[i].vendor_subcmd)))
511 {
512 /* event for a different vendor, ignore it */
513 continue;
514 }
515
516 cb_info *cbi = &(info->event_cb[i]);
517 nl_recvmsg_msg_cb_t cb_func = cbi->cb_func;
518 void *cb_arg = cbi->cb_arg;
519 WifiCommand *cmd = (WifiCommand *)cbi->cb_arg;
520 if (cmd != NULL) {
521 cmd->addRef();
522 }
523 pthread_mutex_unlock(&info->cb_lock);
524 if (cb_func)
525 (*cb_func)(msg, cb_arg);
526 if (cmd != NULL) {
527 cmd->releaseRef();
528 }
529
530 return NL_OK;
531 }
532 }
533
534 pthread_mutex_unlock(&info->cb_lock);
535 return NL_OK;
536 }
537
538 ///////////////////////////////////////////////////////////////////////////////////////
539
540 class GetMulticastIdCommand : public WifiCommand
541 {
542 private:
543 const char *mName;
544 const char *mGroup;
545 int mId;
546 public:
GetMulticastIdCommand(wifi_handle handle,const char * name,const char * group)547 GetMulticastIdCommand(wifi_handle handle, const char *name, const char *group)
548 : WifiCommand("GetMulticastIdCommand", handle, 0)
549 {
550 mName = name;
551 mGroup = group;
552 mId = -1;
553 }
554
getId()555 int getId() {
556 return mId;
557 }
558
create()559 virtual int create() {
560 int nlctrlFamily = genl_ctrl_resolve(mInfo->cmd_sock, "nlctrl");
561 // ALOGI("ctrl family = %d", nlctrlFamily);
562 int ret = mMsg.create(nlctrlFamily, CTRL_CMD_GETFAMILY, 0, 0);
563 if (ret < 0) {
564 return ret;
565 }
566 ret = mMsg.put_string(CTRL_ATTR_FAMILY_NAME, mName);
567 return ret;
568 }
569
handleResponse(WifiEvent & reply)570 virtual int handleResponse(WifiEvent& reply) {
571
572 // ALOGI("handling reponse in %s", __func__);
573
574 struct nlattr **tb = reply.attributes();
575 struct genlmsghdr *gnlh = reply.header();
576 struct nlattr *mcgrp = NULL;
577 int i;
578
579 if (!tb[CTRL_ATTR_MCAST_GROUPS]) {
580 ALOGI("No multicast groups found");
581 return NL_SKIP;
582 } else {
583 // ALOGI("Multicast groups attr size = %d", nla_len(tb[CTRL_ATTR_MCAST_GROUPS]));
584 }
585
586 for_each_attr(mcgrp, tb[CTRL_ATTR_MCAST_GROUPS], i) {
587
588 // ALOGI("Processing group");
589 struct nlattr *tb2[CTRL_ATTR_MCAST_GRP_MAX + 1];
590 nla_parse(tb2, CTRL_ATTR_MCAST_GRP_MAX, (nlattr *)nla_data(mcgrp),
591 nla_len(mcgrp), NULL);
592 if (!tb2[CTRL_ATTR_MCAST_GRP_NAME] || !tb2[CTRL_ATTR_MCAST_GRP_ID]) {
593 continue;
594 }
595
596 char *grpName = (char *)nla_data(tb2[CTRL_ATTR_MCAST_GRP_NAME]);
597 int grpNameLen = nla_len(tb2[CTRL_ATTR_MCAST_GRP_NAME]);
598
599 // ALOGI("Found group name %s", grpName);
600
601 if (strncmp(grpName, mGroup, grpNameLen) != 0)
602 continue;
603
604 mId = nla_get_u32(tb2[CTRL_ATTR_MCAST_GRP_ID]);
605 break;
606 }
607
608 return NL_SKIP;
609 }
610
611 };
612
613 class SetPnoMacAddrOuiCommand : public WifiCommand {
614
615 private:
616 byte *mOui;
617 feature_set *fset;
618 feature_set *feature_matrix;
619 int *fm_size;
620 int set_size_max;
621 public:
SetPnoMacAddrOuiCommand(wifi_interface_handle handle,oui scan_oui)622 SetPnoMacAddrOuiCommand(wifi_interface_handle handle, oui scan_oui)
623 : WifiCommand("SetPnoMacAddrOuiCommand", handle, 0)
624 {
625 mOui = scan_oui;
626 }
627
createRequest(WifiRequest & request,int subcmd,byte * scan_oui)628 int createRequest(WifiRequest& request, int subcmd, byte *scan_oui) {
629 int result = request.create(GOOGLE_OUI, subcmd);
630 if (result < 0) {
631 return result;
632 }
633
634 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
635 result = request.put(ANDR_WIFI_ATTRIBUTE_PNO_RANDOM_MAC_OUI, scan_oui, DOT11_OUI_LEN);
636 if (result < 0) {
637 return result;
638 }
639
640 request.attr_end(data);
641 return WIFI_SUCCESS;
642
643 }
644
start()645 int start() {
646 ALOGD("Sending mac address OUI");
647 WifiRequest request(familyId(), ifaceId());
648 int result = createRequest(request, WIFI_SUBCMD_SET_PNO_RANDOM_MAC_OUI, mOui);
649 if (result != WIFI_SUCCESS) {
650 ALOGE("failed to create request; result = %d", result);
651 return result;
652 }
653
654 result = requestResponse(request);
655 if (result != WIFI_SUCCESS) {
656 ALOGE("failed to set scanning mac OUI; result = %d", result);
657 }
658
659 return result;
660 }
661 protected:
handleResponse(WifiEvent & reply)662 virtual int handleResponse(WifiEvent& reply) {
663 ALOGD("Request complete!");
664 /* Nothing to do on response! */
665 return NL_SKIP;
666 }
667 };
668
669 class SetNodfsCommand : public WifiCommand {
670
671 private:
672 u32 mNoDfs;
673 public:
SetNodfsCommand(wifi_interface_handle handle,u32 nodfs)674 SetNodfsCommand(wifi_interface_handle handle, u32 nodfs)
675 : WifiCommand("SetNodfsCommand", handle, 0) {
676 mNoDfs = nodfs;
677 }
create()678 virtual int create() {
679 int ret;
680
681 ret = mMsg.create(GOOGLE_OUI, WIFI_SUBCMD_NODFS_SET);
682 if (ret < 0) {
683 ALOGE("Can't create message to send to driver - %d", ret);
684 return ret;
685 }
686
687 nlattr *data = mMsg.attr_start(NL80211_ATTR_VENDOR_DATA);
688 ret = mMsg.put_u32(ANDR_WIFI_ATTRIBUTE_NODFS_SET, mNoDfs);
689 if (ret < 0) {
690 return ret;
691 }
692
693 mMsg.attr_end(data);
694 return WIFI_SUCCESS;
695 }
696 };
697
698 class SetCountryCodeCommand : public WifiCommand {
699 private:
700 const char *mCountryCode;
701 public:
SetCountryCodeCommand(wifi_interface_handle handle,const char * country_code)702 SetCountryCodeCommand(wifi_interface_handle handle, const char *country_code)
703 : WifiCommand("SetCountryCodeCommand", handle, 0) {
704 mCountryCode = country_code;
705 }
create()706 virtual int create() {
707 int ret;
708
709 ret = mMsg.create(GOOGLE_OUI, WIFI_SUBCMD_SET_COUNTRY_CODE);
710 if (ret < 0) {
711 ALOGE("Can't create message to send to driver - %d", ret);
712 return ret;
713 }
714
715 nlattr *data = mMsg.attr_start(NL80211_ATTR_VENDOR_DATA);
716 ret = mMsg.put_string(ANDR_WIFI_ATTRIBUTE_COUNTRY, mCountryCode);
717 if (ret < 0) {
718 return ret;
719 }
720
721 mMsg.attr_end(data);
722 return WIFI_SUCCESS;
723
724 }
725 };
726
727 class SetRSSIMonitorCommand : public WifiCommand {
728 private:
729 s8 mMax_rssi;
730 s8 mMin_rssi;
731 wifi_rssi_event_handler mHandler;
732 public:
SetRSSIMonitorCommand(wifi_request_id id,wifi_interface_handle handle,s8 max_rssi,s8 min_rssi,wifi_rssi_event_handler eh)733 SetRSSIMonitorCommand(wifi_request_id id, wifi_interface_handle handle,
734 s8 max_rssi, s8 min_rssi, wifi_rssi_event_handler eh)
735 : WifiCommand("SetRSSIMonitorCommand", handle, id), mMax_rssi(max_rssi), mMin_rssi
736 (min_rssi), mHandler(eh)
737 {
738 }
createRequest(WifiRequest & request,int enable)739 int createRequest(WifiRequest& request, int enable) {
740 int result = request.create(GOOGLE_OUI, WIFI_SUBCMD_SET_RSSI_MONITOR);
741 if (result < 0) {
742 return result;
743 }
744
745 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
746 result = request.put_u32(RSSI_MONITOR_ATTRIBUTE_MAX_RSSI, (enable ? mMax_rssi: 0));
747 if (result < 0) {
748 return result;
749 }
750 ALOGD("create request");
751 result = request.put_u32(RSSI_MONITOR_ATTRIBUTE_MIN_RSSI, (enable? mMin_rssi: 0));
752 if (result < 0) {
753 return result;
754 }
755 result = request.put_u32(RSSI_MONITOR_ATTRIBUTE_START, enable);
756 if (result < 0) {
757 return result;
758 }
759 request.attr_end(data);
760 return result;
761 }
762
start()763 int start() {
764 WifiRequest request(familyId(), ifaceId());
765 int result = createRequest(request, 1);
766 if (result < 0) {
767 return result;
768 }
769 result = requestResponse(request);
770 if (result < 0) {
771 ALOGI("Failed to set RSSI Monitor, result = %d", result);
772 return result;
773 }
774 ALOGI("Successfully set RSSI monitoring");
775 registerVendorHandler(GOOGLE_OUI, GOOGLE_RSSI_MONITOR_EVENT);
776
777
778 if (result < 0) {
779 unregisterVendorHandler(GOOGLE_OUI, GOOGLE_RSSI_MONITOR_EVENT);
780 return result;
781 }
782 ALOGI("Done!");
783 return result;
784 }
785
cancel()786 virtual int cancel() {
787
788 WifiRequest request(familyId(), ifaceId());
789 int result = createRequest(request, 0);
790 if (result != WIFI_SUCCESS) {
791 ALOGE("failed to create request; result = %d", result);
792 } else {
793 result = requestResponse(request);
794 if (result != WIFI_SUCCESS) {
795 ALOGE("failed to stop RSSI monitoring = %d", result);
796 }
797 }
798 unregisterVendorHandler(GOOGLE_OUI, GOOGLE_RSSI_MONITOR_EVENT);
799 return WIFI_SUCCESS;
800 }
801
handleResponse(WifiEvent & reply)802 virtual int handleResponse(WifiEvent& reply) {
803 /* Nothing to do on response! */
804 return NL_SKIP;
805 }
806
handleEvent(WifiEvent & event)807 virtual int handleEvent(WifiEvent& event) {
808 ALOGI("Got a RSSI monitor event");
809
810 nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA);
811 int len = event.get_vendor_data_len();
812
813 if (vendor_data == NULL || len == 0) {
814 ALOGI("RSSI monitor: No data");
815 return NL_SKIP;
816 }
817 /* driver<->HAL event structure */
818 #define RSSI_MONITOR_EVT_VERSION 1
819 typedef struct {
820 u8 version;
821 s8 cur_rssi;
822 mac_addr BSSID;
823 } rssi_monitor_evt;
824
825 rssi_monitor_evt *data = (rssi_monitor_evt *)event.get_vendor_data();
826
827 if (data->version != RSSI_MONITOR_EVT_VERSION) {
828 ALOGI("Event version mismatch %d, expected %d", data->version, RSSI_MONITOR_EVT_VERSION);
829 return NL_SKIP;
830 }
831
832 if (*mHandler.on_rssi_threshold_breached) {
833 (*mHandler.on_rssi_threshold_breached)(id(), data->BSSID, data->cur_rssi);
834 } else {
835 ALOGW("No RSSI monitor handler registered");
836 }
837
838 return NL_SKIP;
839 }
840
841 };
842
843 class AndroidPktFilterCommand : public WifiCommand {
844 private:
845 const u8* mProgram;
846 u32 mProgramLen;
847 u32* mVersion;
848 u32* mMaxLen;
849 int mReqType;
850 public:
AndroidPktFilterCommand(wifi_interface_handle handle,u32 * version,u32 * max_len)851 AndroidPktFilterCommand(wifi_interface_handle handle,
852 u32* version, u32* max_len)
853 : WifiCommand("AndroidPktFilterCommand", handle, 0),
854 mVersion(version), mMaxLen(max_len),
855 mReqType(GET_APF_CAPABILITIES)
856 {
857 }
858
AndroidPktFilterCommand(wifi_interface_handle handle,const u8 * program,u32 len)859 AndroidPktFilterCommand(wifi_interface_handle handle,
860 const u8* program, u32 len)
861 : WifiCommand("AndroidPktFilterCommand", handle, 0),
862 mProgram(program), mProgramLen(len),
863 mReqType(SET_APF_PROGRAM)
864 {
865 }
866
createRequest(WifiRequest & request)867 int createRequest(WifiRequest& request) {
868 if (mReqType == SET_APF_PROGRAM) {
869 ALOGI("\n%s: APF set program request\n", __FUNCTION__);
870 return createSetPktFilterRequest(request);
871 } else if (mReqType == GET_APF_CAPABILITIES) {
872 ALOGI("\n%s: APF get capabilities request\n", __FUNCTION__);
873 return createGetPktFilterCapabilitesRequest(request);
874 } else {
875 ALOGE("\n%s Unknown APF request\n", __FUNCTION__);
876 return WIFI_ERROR_NOT_SUPPORTED;
877 }
878 return WIFI_SUCCESS;
879 }
880
createSetPktFilterRequest(WifiRequest & request)881 int createSetPktFilterRequest(WifiRequest& request) {
882 u8 *program = new u8[mProgramLen];
883 NULL_CHECK_RETURN(program, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
884 int result = request.create(GOOGLE_OUI, APF_SUBCMD_SET_FILTER);
885 if (result < 0) {
886 return result;
887 }
888
889 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
890 result = request.put_u32(APF_ATTRIBUTE_PROGRAM_LEN, mProgramLen);
891 if (result < 0) {
892 return result;
893 }
894 memcpy(program, mProgram, mProgramLen);
895 result = request.put(APF_ATTRIBUTE_PROGRAM, program, mProgramLen);
896 if (result < 0) {
897 return result;
898 }
899 request.attr_end(data);
900 delete[] program;
901 return result;
902 }
903
createGetPktFilterCapabilitesRequest(WifiRequest & request)904 int createGetPktFilterCapabilitesRequest(WifiRequest& request) {
905 int result = request.create(GOOGLE_OUI, APF_SUBCMD_GET_CAPABILITIES);
906 if (result < 0) {
907 return result;
908 }
909
910 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
911 request.attr_end(data);
912 return result;
913 }
914
start()915 int start() {
916 WifiRequest request(familyId(), ifaceId());
917 int result = createRequest(request);
918 if (result < 0) {
919 return result;
920 }
921 result = requestResponse(request);
922 if (result < 0) {
923 ALOGI("Request Response failed for APF, result = %d", result);
924 return result;
925 }
926 ALOGI("Done!");
927 return result;
928 }
929
cancel()930 int cancel() {
931 return WIFI_SUCCESS;
932 }
933
handleResponse(WifiEvent & reply)934 int handleResponse(WifiEvent& reply) {
935 ALOGD("In SetAPFCommand::handleResponse");
936
937 if (reply.get_cmd() != NL80211_CMD_VENDOR) {
938 ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
939 return NL_SKIP;
940 }
941
942 int id = reply.get_vendor_id();
943 int subcmd = reply.get_vendor_subcmd();
944
945 nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA);
946 int len = reply.get_vendor_data_len();
947
948 ALOGD("Id = %0x, subcmd = %d, len = %d", id, subcmd, len);
949 if (vendor_data == NULL || len == 0) {
950 ALOGE("no vendor data in SetAPFCommand response; ignoring it");
951 return NL_SKIP;
952 }
953 if( mReqType == SET_APF_PROGRAM) {
954 ALOGD("Response recieved for set packet filter command\n");
955 } else if (mReqType == GET_APF_CAPABILITIES) {
956 *mVersion = 0;
957 *mMaxLen = 0;
958 ALOGD("Response recieved for get packet filter capabilities command\n");
959 for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
960 if (it.get_type() == APF_ATTRIBUTE_VERSION) {
961 *mVersion = it.get_u32();
962 ALOGI("APF version is %d\n", *mVersion);
963 } else if (it.get_type() == APF_ATTRIBUTE_MAX_LEN) {
964 *mMaxLen = it.get_u32();
965 ALOGI("APF max len is %d\n", *mMaxLen);
966 } else {
967 ALOGE("Ignoring invalid attribute type = %d, size = %d",
968 it.get_type(), it.get_len());
969 }
970 }
971 }
972 return NL_OK;
973 }
974
handleEvent(WifiEvent & event)975 int handleEvent(WifiEvent& event) {
976 /* No Event to recieve for APF commands */
977 return NL_SKIP;
978 }
979 };
980
981 class SetNdoffloadCommand : public WifiCommand {
982
983 private:
984 u8 mEnable;
985 public:
SetNdoffloadCommand(wifi_interface_handle handle,u8 enable)986 SetNdoffloadCommand(wifi_interface_handle handle, u8 enable)
987 : WifiCommand("SetNdoffloadCommand", handle, 0) {
988 mEnable = enable;
989 }
create()990 virtual int create() {
991 int ret;
992
993 ret = mMsg.create(GOOGLE_OUI, WIFI_SUBCMD_CONFIG_ND_OFFLOAD);
994 if (ret < 0) {
995 ALOGE("Can't create message to send to driver - %d", ret);
996 return ret;
997 }
998
999 nlattr *data = mMsg.attr_start(NL80211_ATTR_VENDOR_DATA);
1000 ret = mMsg.put_u8(ANDR_WIFI_ATTRIBUTE_ND_OFFLOAD_VALUE, mEnable);
1001 if (ret < 0) {
1002 return ret;
1003 }
1004
1005 mMsg.attr_end(data);
1006 return WIFI_SUCCESS;
1007 }
1008 };
1009
1010 class GetFeatureSetCommand : public WifiCommand {
1011
1012 private:
1013 int feature_type;
1014 feature_set *fset;
1015 feature_set *feature_matrix;
1016 int *fm_size;
1017 int set_size_max;
1018 public:
GetFeatureSetCommand(wifi_interface_handle handle,int feature,feature_set * set,feature_set set_matrix[],int * size,int max_size)1019 GetFeatureSetCommand(wifi_interface_handle handle, int feature, feature_set *set,
1020 feature_set set_matrix[], int *size, int max_size)
1021 : WifiCommand("GetFeatureSetCommand", handle, 0)
1022 {
1023 feature_type = feature;
1024 fset = set;
1025 feature_matrix = set_matrix;
1026 fm_size = size;
1027 set_size_max = max_size;
1028 }
1029
create()1030 virtual int create() {
1031 int ret;
1032
1033 if(feature_type == ANDR_WIFI_ATTRIBUTE_NUM_FEATURE_SET) {
1034 ret = mMsg.create(GOOGLE_OUI, WIFI_SUBCMD_GET_FEATURE_SET);
1035 } else if (feature_type == ANDR_WIFI_ATTRIBUTE_FEATURE_SET) {
1036 ret = mMsg.create(GOOGLE_OUI, WIFI_SUBCMD_GET_FEATURE_SET_MATRIX);
1037 } else {
1038 ALOGE("Unknown feature type %d", feature_type);
1039 return -1;
1040 }
1041
1042 if (ret < 0) {
1043 ALOGE("Can't create message to send to driver - %d", ret);
1044 }
1045
1046 return ret;
1047 }
1048
1049 protected:
handleResponse(WifiEvent & reply)1050 virtual int handleResponse(WifiEvent& reply) {
1051
1052 ALOGV("In GetFeatureSetCommand::handleResponse");
1053
1054 if (reply.get_cmd() != NL80211_CMD_VENDOR) {
1055 ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
1056 return NL_SKIP;
1057 }
1058
1059 int id = reply.get_vendor_id();
1060 int subcmd = reply.get_vendor_subcmd();
1061
1062 nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA);
1063 int len = reply.get_vendor_data_len();
1064
1065 ALOGV("Id = %0x, subcmd = %d, len = %d", id, subcmd, len);
1066 if (vendor_data == NULL || len == 0) {
1067 ALOGE("no vendor data in GetFeatureSetCommand response; ignoring it");
1068 return NL_SKIP;
1069 }
1070 if(feature_type == ANDR_WIFI_ATTRIBUTE_NUM_FEATURE_SET) {
1071 void *data = reply.get_vendor_data();
1072 if(!fset) {
1073 ALOGE("Buffers pointers not set");
1074 return NL_SKIP;
1075 }
1076 memcpy(fset, data, min(len, (int) sizeof(*fset)));
1077 } else {
1078 int num_features_set = 0;
1079 int i = 0;
1080
1081 if(!feature_matrix || !fm_size) {
1082 ALOGE("Buffers pointers not set");
1083 return NL_SKIP;
1084 }
1085
1086 for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
1087 if (it.get_type() == ANDR_WIFI_ATTRIBUTE_NUM_FEATURE_SET) {
1088 num_features_set = it.get_u32();
1089 ALOGV("Got feature list with %d concurrent sets", num_features_set);
1090 if(set_size_max && (num_features_set > set_size_max))
1091 num_features_set = set_size_max;
1092 *fm_size = num_features_set;
1093 } else if ((it.get_type() == ANDR_WIFI_ATTRIBUTE_FEATURE_SET) &&
1094 i < num_features_set) {
1095 feature_matrix[i] = it.get_u32();
1096 i++;
1097 } else {
1098 ALOGW("Ignoring invalid attribute type = %d, size = %d",
1099 it.get_type(), it.get_len());
1100 }
1101 }
1102
1103 }
1104 return NL_OK;
1105 }
1106
1107 };
1108
wifi_get_multicast_id(wifi_handle handle,const char * name,const char * group)1109 static int wifi_get_multicast_id(wifi_handle handle, const char *name, const char *group)
1110 {
1111 GetMulticastIdCommand cmd(handle, name, group);
1112 int res = cmd.requestResponse();
1113 if (res < 0)
1114 return res;
1115 else
1116 return cmd.getId();
1117 }
1118
1119 /////////////////////////////////////////////////////////////////////////
1120
is_wifi_interface(const char * name)1121 static bool is_wifi_interface(const char *name)
1122 {
1123 if (strncmp(name, "wlan", 4) != 0 && strncmp(name, "p2p", 3) != 0) {
1124 /* not a wifi interface; ignore it */
1125 return false;
1126 } else {
1127 return true;
1128 }
1129 }
1130
get_interface(const char * name,interface_info * info)1131 static int get_interface(const char *name, interface_info *info)
1132 {
1133 strcpy(info->name, name);
1134 info->id = if_nametoindex(name);
1135 // ALOGI("found an interface : %s, id = %d", name, info->id);
1136 return WIFI_SUCCESS;
1137 }
1138
wifi_init_interfaces(wifi_handle handle)1139 wifi_error wifi_init_interfaces(wifi_handle handle)
1140 {
1141 hal_info *info = (hal_info *)handle;
1142
1143 struct dirent *de;
1144
1145 DIR *d = opendir("/sys/class/net");
1146 if (d == 0)
1147 return WIFI_ERROR_UNKNOWN;
1148
1149 int n = 0;
1150 while ((de = readdir(d))) {
1151 if (de->d_name[0] == '.')
1152 continue;
1153 if (is_wifi_interface(de->d_name) ) {
1154 n++;
1155 }
1156 }
1157
1158 closedir(d);
1159
1160 if (n == 0)
1161 return WIFI_ERROR_NOT_AVAILABLE;
1162
1163 d = opendir("/sys/class/net");
1164 if (d == 0)
1165 return WIFI_ERROR_UNKNOWN;
1166
1167 info->interfaces = (interface_info **)malloc(sizeof(interface_info *) * n);
1168
1169 int i = 0;
1170 while ((de = readdir(d))) {
1171 if (de->d_name[0] == '.')
1172 continue;
1173 if (is_wifi_interface(de->d_name)) {
1174 interface_info *ifinfo = (interface_info *)malloc(sizeof(interface_info));
1175 if (get_interface(de->d_name, ifinfo) != WIFI_SUCCESS) {
1176 free(ifinfo);
1177 continue;
1178 }
1179 ifinfo->handle = handle;
1180 info->interfaces[i] = ifinfo;
1181 i++;
1182 }
1183 }
1184
1185 closedir(d);
1186
1187 info->num_interfaces = n;
1188 return WIFI_SUCCESS;
1189 }
1190
wifi_get_ifaces(wifi_handle handle,int * num,wifi_interface_handle ** interfaces)1191 wifi_error wifi_get_ifaces(wifi_handle handle, int *num, wifi_interface_handle **interfaces)
1192 {
1193 hal_info *info = (hal_info *)handle;
1194
1195 *interfaces = (wifi_interface_handle *)info->interfaces;
1196 *num = info->num_interfaces;
1197
1198 return WIFI_SUCCESS;
1199 }
1200
wifi_get_iface_name(wifi_interface_handle handle,char * name,size_t size)1201 wifi_error wifi_get_iface_name(wifi_interface_handle handle, char *name, size_t size)
1202 {
1203 interface_info *info = (interface_info *)handle;
1204 strcpy(name, info->name);
1205 return WIFI_SUCCESS;
1206 }
1207
wifi_get_supported_feature_set(wifi_interface_handle handle,feature_set * set)1208 wifi_error wifi_get_supported_feature_set(wifi_interface_handle handle, feature_set *set)
1209 {
1210 GetFeatureSetCommand command(handle, ANDR_WIFI_ATTRIBUTE_NUM_FEATURE_SET, set, NULL, NULL, 1);
1211 return (wifi_error) command.requestResponse();
1212 }
1213
wifi_get_concurrency_matrix(wifi_interface_handle handle,int set_size_max,feature_set set[],int * set_size)1214 wifi_error wifi_get_concurrency_matrix(wifi_interface_handle handle, int set_size_max,
1215 feature_set set[], int *set_size)
1216 {
1217 GetFeatureSetCommand command(handle, ANDR_WIFI_ATTRIBUTE_FEATURE_SET, NULL,
1218 set, set_size, set_size_max);
1219 return (wifi_error) command.requestResponse();
1220 }
1221
wifi_set_scanning_mac_oui(wifi_interface_handle handle,oui scan_oui)1222 wifi_error wifi_set_scanning_mac_oui(wifi_interface_handle handle, oui scan_oui)
1223 {
1224 SetPnoMacAddrOuiCommand command(handle, scan_oui);
1225 return (wifi_error)command.start();
1226
1227 }
1228
wifi_set_nodfs_flag(wifi_interface_handle handle,u32 nodfs)1229 wifi_error wifi_set_nodfs_flag(wifi_interface_handle handle, u32 nodfs)
1230 {
1231 SetNodfsCommand command(handle, nodfs);
1232 return (wifi_error) command.requestResponse();
1233 }
1234
wifi_set_country_code(wifi_interface_handle handle,const char * country_code)1235 wifi_error wifi_set_country_code(wifi_interface_handle handle, const char *country_code)
1236 {
1237 SetCountryCodeCommand command(handle, country_code);
1238 return (wifi_error) command.requestResponse();
1239 }
1240
wifi_start_rssi_monitoring(wifi_request_id id,wifi_interface_handle iface,s8 max_rssi,s8 min_rssi,wifi_rssi_event_handler eh)1241 static wifi_error wifi_start_rssi_monitoring(wifi_request_id id, wifi_interface_handle
1242 iface, s8 max_rssi, s8 min_rssi, wifi_rssi_event_handler eh)
1243 {
1244 ALOGD("Start RSSI monitor %d", id);
1245 wifi_handle handle = getWifiHandle(iface);
1246 SetRSSIMonitorCommand *cmd = new SetRSSIMonitorCommand(id, iface, max_rssi, min_rssi, eh);
1247 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
1248 wifi_error result = wifi_register_cmd(handle, id, cmd);
1249 if (result != WIFI_SUCCESS) {
1250 cmd->releaseRef();
1251 return result;
1252 }
1253 result = (wifi_error)cmd->start();
1254 if (result != WIFI_SUCCESS) {
1255 wifi_unregister_cmd(handle, id);
1256 cmd->releaseRef();
1257 return result;
1258 }
1259 return result;
1260 }
1261
wifi_stop_rssi_monitoring(wifi_request_id id,wifi_interface_handle iface)1262 static wifi_error wifi_stop_rssi_monitoring(wifi_request_id id, wifi_interface_handle iface)
1263 {
1264 ALOGD("Stopping RSSI monitor");
1265
1266 if(id == -1) {
1267 wifi_rssi_event_handler handler;
1268 s8 max_rssi = 0, min_rssi = 0;
1269 wifi_handle handle = getWifiHandle(iface);
1270 memset(&handler, 0, sizeof(handler));
1271 SetRSSIMonitorCommand *cmd = new SetRSSIMonitorCommand(id, iface,
1272 max_rssi, min_rssi, handler);
1273 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
1274 cmd->cancel();
1275 cmd->releaseRef();
1276 return WIFI_SUCCESS;
1277 }
1278 return wifi_cancel_cmd(id, iface);
1279 }
1280
wifi_get_packet_filter_capabilities(wifi_interface_handle handle,u32 * version,u32 * max_len)1281 static wifi_error wifi_get_packet_filter_capabilities(wifi_interface_handle handle,
1282 u32 *version, u32 *max_len)
1283 {
1284 ALOGD("Getting APF capabilities, halHandle = %p\n", handle);
1285 AndroidPktFilterCommand *cmd = new AndroidPktFilterCommand(handle, version, max_len);
1286 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
1287 wifi_error result = (wifi_error)cmd->start();
1288 if (result == WIFI_SUCCESS) {
1289 ALOGD("Getting APF capability, version = %d, max_len = %d\n", *version, *max_len);
1290 }
1291 cmd->releaseRef();
1292 return result;
1293 }
1294
wifi_set_packet_filter(wifi_interface_handle handle,const u8 * program,u32 len)1295 static wifi_error wifi_set_packet_filter(wifi_interface_handle handle,
1296 const u8 *program, u32 len)
1297 {
1298 ALOGD("Setting APF program, halHandle = %p\n", handle);
1299 AndroidPktFilterCommand *cmd = new AndroidPktFilterCommand(handle, program, len);
1300 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
1301 wifi_error result = (wifi_error)cmd->start();
1302 cmd->releaseRef();
1303 return result;
1304 }
1305
wifi_configure_nd_offload(wifi_interface_handle handle,u8 enable)1306 static wifi_error wifi_configure_nd_offload(wifi_interface_handle handle, u8 enable)
1307 {
1308 SetNdoffloadCommand command(handle, enable);
1309 return (wifi_error) command.requestResponse();
1310 }
1311
1312 /////////////////////////////////////////////////////////////////////////////
1313