• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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