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