11a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde#include <stdint.h> 21a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde#include <fcntl.h> 31a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde#include <sys/socket.h> 41a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde#include <netlink/genl/genl.h> 51a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde#include <netlink/genl/family.h> 61a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde#include <netlink/genl/ctrl.h> 71a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde#include <linux/rtnetlink.h> 81a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde#include <netpacket/packet.h> 91a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde#include <linux/filter.h> 101a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde#include <linux/errqueue.h> 11508ee337afdefb09b15a8de9f7a61660269b39e8Prerepa Viswanadham#include <errno.h> 121a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 131a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde#include <linux/pkt_sched.h> 141a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde#include <netlink/object-api.h> 151a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde#include <netlink/netlink.h> 161a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde#include <netlink/socket.h> 17642bfbe829f5438db3d99ce4678bcb770359a632Vinit Deshpande#include <netlink/attr.h> 18642bfbe829f5438db3d99ce4678bcb770359a632Vinit Deshpande#include <netlink/handlers.h> 19642bfbe829f5438db3d99ce4678bcb770359a632Vinit Deshpande#include <netlink/msg.h> 201a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 211a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde#include <dirent.h> 221a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde#include <net/if.h> 231a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 241a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde#include "sync.h" 251a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 261a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde#define LOG_TAG "WifiHAL" 271a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 281a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde#include <utils/Log.h> 291a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 301a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde#include "wifi_hal.h" 311a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde#include "common.h" 321a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde#include "cpp_bindings.h" 33cbbc31d5d0d387068be5b84251f53d6b74bfc6f5xinhe#include "rtt.h" 341a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde/* 351a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde BUGBUG: normally, libnl allocates ports for all connections it makes; but 361a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde being a static library, it doesn't really know how many other netlink connections 371a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde are made by the same process, if connections come from different shared libraries. 381a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde These port assignments exist to solve that problem - temporarily. We need to fix 391a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde libnl to try and allocate ports across the entire process. 401a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde */ 411a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 421a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde#define WIFI_HAL_CMD_SOCK_PORT 644 431a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde#define WIFI_HAL_EVENT_SOCK_PORT 645 441a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 451a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapndestatic void internal_event_handler(wifi_handle handle, int events); 46642bfbe829f5438db3d99ce4678bcb770359a632Vinit Deshpandestatic int internal_no_seq_check(nl_msg *msg, void *arg); 471a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapndestatic int internal_valid_message_handler(nl_msg *msg, void *arg); 481a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapndestatic int wifi_get_multicast_id(wifi_handle handle, const char *name, const char *group); 491a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapndestatic int wifi_add_membership(wifi_handle handle, const char *group); 501a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapndestatic wifi_error wifi_init_interfaces(wifi_handle handle); 51fef13c11034313585be68c32322b9a53c43a37b2Ashwinstatic wifi_error wifi_start_rssi_monitoring(wifi_request_id id, wifi_interface_handle 52fef13c11034313585be68c32322b9a53c43a37b2Ashwin iface, s8 max_rssi, s8 min_rssi, wifi_rssi_event_handler eh); 53fef13c11034313585be68c32322b9a53c43a37b2Ashwinstatic wifi_error wifi_stop_rssi_monitoring(wifi_request_id id, wifi_interface_handle iface); 54dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharmastatic wifi_error wifi_set_packet_filter(wifi_interface_handle handle, 55dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma const u8 *program, u32 len); 56dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharmastatic wifi_error wifi_get_packet_filter_capabilities(wifi_interface_handle handle, 57dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma u32 *version, u32 *max_len); 5865f9c6fbd929be309642cdaf255e8394aad2b0caJun Limstatic wifi_error wifi_configure_nd_offload(wifi_interface_handle iface, u8 enable); 591a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 60f0d5070a931327e6356d765478069b9e66452a5bAshwintypedef enum wifi_attr { 619a23388d5a9f58f106169700bb179de0a4af7840Ashwin ANDR_WIFI_ATTRIBUTE_NUM_FEATURE_SET, 62f0d5070a931327e6356d765478069b9e66452a5bAshwin ANDR_WIFI_ATTRIBUTE_FEATURE_SET, 6365f9c6fbd929be309642cdaf255e8394aad2b0caJun Lim ANDR_WIFI_ATTRIBUTE_PNO_RANDOM_MAC_OUI, 6465f9c6fbd929be309642cdaf255e8394aad2b0caJun Lim ANDR_WIFI_ATTRIBUTE_NODFS_SET, 6565f9c6fbd929be309642cdaf255e8394aad2b0caJun Lim ANDR_WIFI_ATTRIBUTE_COUNTRY, 6665f9c6fbd929be309642cdaf255e8394aad2b0caJun Lim ANDR_WIFI_ATTRIBUTE_ND_OFFLOAD_VALUE 6765f9c6fbd929be309642cdaf255e8394aad2b0caJun Lim // Add more attribute here 68f0d5070a931327e6356d765478069b9e66452a5bAshwin} wifi_attr_t; 699a23388d5a9f58f106169700bb179de0a4af7840Ashwin 70fef13c11034313585be68c32322b9a53c43a37b2Ashwinenum wifi_rssi_monitor_attr { 71fef13c11034313585be68c32322b9a53c43a37b2Ashwin RSSI_MONITOR_ATTRIBUTE_MAX_RSSI, 72fef13c11034313585be68c32322b9a53c43a37b2Ashwin RSSI_MONITOR_ATTRIBUTE_MIN_RSSI, 73fef13c11034313585be68c32322b9a53c43a37b2Ashwin RSSI_MONITOR_ATTRIBUTE_START, 74fef13c11034313585be68c32322b9a53c43a37b2Ashwin}; 75fef13c11034313585be68c32322b9a53c43a37b2Ashwin 76dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharmaenum wifi_apf_attr { 77dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma APF_ATTRIBUTE_VERSION, 78dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma APF_ATTRIBUTE_MAX_LEN, 79dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma APF_ATTRIBUTE_PROGRAM, 80dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma APF_ATTRIBUTE_PROGRAM_LEN 81dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma}; 82dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma 83dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharmaenum apf_request_type { 84dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma GET_APF_CAPABILITIES, 85dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma SET_APF_PROGRAM 86dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma}; 87dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma 881a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde/* Initialize/Cleanup */ 891a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 901a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapndevoid wifi_socket_set_local_port(struct nl_sock *sock, uint32_t port) 911a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde{ 92642bfbe829f5438db3d99ce4678bcb770359a632Vinit Deshpande uint32_t pid = getpid() & 0x3FFFFF; 93642bfbe829f5438db3d99ce4678bcb770359a632Vinit Deshpande nl_socket_set_local_port(sock, pid + (port << 22)); 941a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde} 951a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 961a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapndestatic nl_sock * wifi_create_nl_socket(int port) 971a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde{ 981a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde // ALOGI("Creating socket"); 991a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde struct nl_sock *sock = nl_socket_alloc(); 1001a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (sock == NULL) { 1011a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGE("Could not create handle"); 1021a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return NULL; 1031a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 1041a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 1051a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde wifi_socket_set_local_port(sock, port); 1061a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 1071a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde struct sockaddr *addr = NULL; 1081a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde // ALOGI("sizeof(sockaddr) = %d, sizeof(sockaddr_nl) = %d", sizeof(*addr), sizeof(*addr_nl)); 1091a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 1101a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde // ALOGI("Connecting socket"); 1111a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (nl_connect(sock, NETLINK_GENERIC)) { 1121a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGE("Could not connect handle"); 1131a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde nl_socket_free(sock); 1141a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return NULL; 1151a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 1161a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 1171a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde // ALOGI("Making socket nonblocking"); 1181a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde /* 1191a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (nl_socket_set_nonblocking(sock)) { 1201a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGE("Could make socket non-blocking"); 1211a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde nl_socket_free(sock); 1221a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return NULL; 1231a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 1241a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde */ 1251a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 1261a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return sock; 1271a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde} 1281a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 129cbbc31d5d0d387068be5b84251f53d6b74bfc6f5xinhe/*initialize function pointer table with Broadcom HHAL API*/ 130cbbc31d5d0d387068be5b84251f53d6b74bfc6f5xinhewifi_error init_wifi_vendor_hal_func_table(wifi_hal_fn *fn) 131cbbc31d5d0d387068be5b84251f53d6b74bfc6f5xinhe{ 132cbbc31d5d0d387068be5b84251f53d6b74bfc6f5xinhe if (fn == NULL) { 133cbbc31d5d0d387068be5b84251f53d6b74bfc6f5xinhe return WIFI_ERROR_UNKNOWN; 134cbbc31d5d0d387068be5b84251f53d6b74bfc6f5xinhe } 135cbbc31d5d0d387068be5b84251f53d6b74bfc6f5xinhe fn->wifi_initialize = wifi_initialize; 136cbbc31d5d0d387068be5b84251f53d6b74bfc6f5xinhe fn->wifi_cleanup = wifi_cleanup; 137cbbc31d5d0d387068be5b84251f53d6b74bfc6f5xinhe fn->wifi_event_loop = wifi_event_loop; 138cbbc31d5d0d387068be5b84251f53d6b74bfc6f5xinhe fn->wifi_get_supported_feature_set = wifi_get_supported_feature_set; 139cbbc31d5d0d387068be5b84251f53d6b74bfc6f5xinhe fn->wifi_get_concurrency_matrix = wifi_get_concurrency_matrix; 140cbbc31d5d0d387068be5b84251f53d6b74bfc6f5xinhe fn->wifi_set_scanning_mac_oui = wifi_set_scanning_mac_oui; 141cbbc31d5d0d387068be5b84251f53d6b74bfc6f5xinhe fn->wifi_get_ifaces = wifi_get_ifaces; 142cbbc31d5d0d387068be5b84251f53d6b74bfc6f5xinhe fn->wifi_get_iface_name = wifi_get_iface_name; 143cbbc31d5d0d387068be5b84251f53d6b74bfc6f5xinhe fn->wifi_start_gscan = wifi_start_gscan; 144cbbc31d5d0d387068be5b84251f53d6b74bfc6f5xinhe fn->wifi_stop_gscan = wifi_stop_gscan; 145cbbc31d5d0d387068be5b84251f53d6b74bfc6f5xinhe fn->wifi_get_cached_gscan_results = wifi_get_cached_gscan_results; 146cbbc31d5d0d387068be5b84251f53d6b74bfc6f5xinhe fn->wifi_set_bssid_hotlist = wifi_set_bssid_hotlist; 147cbbc31d5d0d387068be5b84251f53d6b74bfc6f5xinhe fn->wifi_reset_bssid_hotlist = wifi_reset_bssid_hotlist; 148cbbc31d5d0d387068be5b84251f53d6b74bfc6f5xinhe fn->wifi_set_significant_change_handler = wifi_set_significant_change_handler; 149cbbc31d5d0d387068be5b84251f53d6b74bfc6f5xinhe fn->wifi_reset_significant_change_handler = wifi_reset_significant_change_handler; 150cbbc31d5d0d387068be5b84251f53d6b74bfc6f5xinhe fn->wifi_get_gscan_capabilities = wifi_get_gscan_capabilities; 151cbbc31d5d0d387068be5b84251f53d6b74bfc6f5xinhe fn->wifi_get_link_stats = wifi_get_link_stats; 152cbbc31d5d0d387068be5b84251f53d6b74bfc6f5xinhe fn->wifi_get_valid_channels = wifi_get_valid_channels; 153cbbc31d5d0d387068be5b84251f53d6b74bfc6f5xinhe fn->wifi_rtt_range_request = wifi_rtt_range_request; 154cbbc31d5d0d387068be5b84251f53d6b74bfc6f5xinhe fn->wifi_rtt_range_cancel = wifi_rtt_range_cancel; 155cbbc31d5d0d387068be5b84251f53d6b74bfc6f5xinhe fn->wifi_get_rtt_capabilities = wifi_get_rtt_capabilities; 156d122c5c4cbdb8fdee2576789733e42ea0ecb9d9cgautam fn->wifi_rtt_get_responder_info = wifi_rtt_get_responder_info; 15789b86262c90552a05a6177944d0ced6b01f27d80gautam fn->wifi_enable_responder = wifi_enable_responder; 15889b86262c90552a05a6177944d0ced6b01f27d80gautam fn->wifi_disable_responder = wifi_disable_responder; 159cbbc31d5d0d387068be5b84251f53d6b74bfc6f5xinhe fn->wifi_set_nodfs_flag = wifi_set_nodfs_flag; 160cbbc31d5d0d387068be5b84251f53d6b74bfc6f5xinhe fn->wifi_start_logging = wifi_start_logging; 161cbbc31d5d0d387068be5b84251f53d6b74bfc6f5xinhe fn->wifi_set_epno_list = wifi_set_epno_list; 16289296a7fc953e68649cdb1366d22376c034ace05Mitchell Wills fn->wifi_reset_epno_list = wifi_reset_epno_list; 163cbbc31d5d0d387068be5b84251f53d6b74bfc6f5xinhe fn->wifi_set_country_code = wifi_set_country_code; 164cab099c7be6490bad1e0402b630840f8d0fcc99bxinhe fn->wifi_get_firmware_memory_dump = wifi_get_firmware_memory_dump; 165cab099c7be6490bad1e0402b630840f8d0fcc99bxinhe fn->wifi_set_log_handler = wifi_set_log_handler; 166c604b53461cfea0a1e6f6f5ad84b0a35be69b8e0JerryLee fn->wifi_reset_log_handler = wifi_reset_log_handler; 167cab099c7be6490bad1e0402b630840f8d0fcc99bxinhe fn->wifi_set_alert_handler = wifi_set_alert_handler; 16856deba26a624507fc2e0e6b134f8bd88d091a141Jerry Lee fn->wifi_reset_alert_handler = wifi_reset_alert_handler; 169cab099c7be6490bad1e0402b630840f8d0fcc99bxinhe fn->wifi_get_firmware_version = wifi_get_firmware_version; 170cab099c7be6490bad1e0402b630840f8d0fcc99bxinhe fn->wifi_get_ring_buffers_status = wifi_get_ring_buffers_status; 171cab099c7be6490bad1e0402b630840f8d0fcc99bxinhe fn->wifi_get_logger_supported_feature_set = wifi_get_logger_supported_feature_set; 172cab099c7be6490bad1e0402b630840f8d0fcc99bxinhe fn->wifi_get_ring_data = wifi_get_ring_data; 173cab099c7be6490bad1e0402b630840f8d0fcc99bxinhe fn->wifi_get_driver_version = wifi_get_driver_version; 174f060fbe12899e67fc4c491af52718ef5e5f1e3eePierre Vandwalle fn->wifi_set_bssid_blacklist = wifi_set_bssid_blacklist; 175fef13c11034313585be68c32322b9a53c43a37b2Ashwin fn->wifi_start_rssi_monitoring = wifi_start_rssi_monitoring; 176fef13c11034313585be68c32322b9a53c43a37b2Ashwin fn->wifi_stop_rssi_monitoring = wifi_stop_rssi_monitoring; 17765f9c6fbd929be309642cdaf255e8394aad2b0caJun Lim fn->wifi_configure_nd_offload = wifi_configure_nd_offload; 1788f1ec7e8e43ec37e94806764b2873c93368cf137Ecco Park fn->wifi_start_sending_offloaded_packet = wifi_start_sending_offloaded_packet; 1798f1ec7e8e43ec37e94806764b2873c93368cf137Ecco Park fn->wifi_stop_sending_offloaded_packet = wifi_stop_sending_offloaded_packet; 1807e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma fn->wifi_start_pkt_fate_monitoring = wifi_start_pkt_fate_monitoring; 1817e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma fn->wifi_get_tx_pkt_fates = wifi_get_tx_pkt_fates; 1827e8b4497898f0de16faa50d0b65fcd7d09085e24Sreenath Sharma fn->wifi_get_rx_pkt_fates = wifi_get_rx_pkt_fates; 183dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma fn->wifi_get_packet_filter_capabilities = wifi_get_packet_filter_capabilities; 184dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma fn->wifi_set_packet_filter = wifi_set_packet_filter; 185cbbc31d5d0d387068be5b84251f53d6b74bfc6f5xinhe return WIFI_SUCCESS; 186cbbc31d5d0d387068be5b84251f53d6b74bfc6f5xinhe} 187cbbc31d5d0d387068be5b84251f53d6b74bfc6f5xinhe 1881a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapndewifi_error wifi_initialize(wifi_handle *handle) 1891a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde{ 1901a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde srand(getpid()); 1911a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 1921a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGI("Initializing wifi"); 1931a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde hal_info *info = (hal_info *)malloc(sizeof(hal_info)); 1941a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (info == NULL) { 1951a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGE("Could not allocate hal_info"); 1969a23388d5a9f58f106169700bb179de0a4af7840Ashwin return WIFI_ERROR_UNKNOWN; 1971a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 1981a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 1991a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde memset(info, 0, sizeof(*info)); 2001a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 2011a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGI("Creating socket"); 20205e31d445f52da4746ff0cc0703d83814cea98d0Vinit Deshpande if (socketpair(AF_UNIX, SOCK_STREAM, 0, info->cleanup_socks) == -1) { 20305e31d445f52da4746ff0cc0703d83814cea98d0Vinit Deshpande ALOGE("Could not create cleanup sockets"); 20456c89ca266b11be506192f3a13a1dba3f109c2cfAshwin free(info); 20505e31d445f52da4746ff0cc0703d83814cea98d0Vinit Deshpande return WIFI_ERROR_UNKNOWN; 20605e31d445f52da4746ff0cc0703d83814cea98d0Vinit Deshpande } 20705e31d445f52da4746ff0cc0703d83814cea98d0Vinit Deshpande 2081a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde struct nl_sock *cmd_sock = wifi_create_nl_socket(WIFI_HAL_CMD_SOCK_PORT); 2091a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (cmd_sock == NULL) { 2101a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGE("Could not create handle"); 21156c89ca266b11be506192f3a13a1dba3f109c2cfAshwin free(info); 2121a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return WIFI_ERROR_UNKNOWN; 2131a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 2141a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 2151a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde struct nl_sock *event_sock = wifi_create_nl_socket(WIFI_HAL_EVENT_SOCK_PORT); 2161a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (event_sock == NULL) { 2171a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGE("Could not create handle"); 2181a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde nl_socket_free(cmd_sock); 21956c89ca266b11be506192f3a13a1dba3f109c2cfAshwin free(info); 2201a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return WIFI_ERROR_UNKNOWN; 2211a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 2221a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 2231a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde struct nl_cb *cb = nl_socket_get_cb(event_sock); 2241a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (cb == NULL) { 2251a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGE("Could not create handle"); 22656c89ca266b11be506192f3a13a1dba3f109c2cfAshwin nl_socket_free(cmd_sock); 22756c89ca266b11be506192f3a13a1dba3f109c2cfAshwin nl_socket_free(event_sock); 22856c89ca266b11be506192f3a13a1dba3f109c2cfAshwin free(info); 2291a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return WIFI_ERROR_UNKNOWN; 2301a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 2311a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 2321a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde // ALOGI("cb->refcnt = %d", cb->cb_refcnt); 233642bfbe829f5438db3d99ce4678bcb770359a632Vinit Deshpande nl_cb_set(cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, internal_no_seq_check, info); 2341a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, internal_valid_message_handler, info); 2351a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde nl_cb_put(cb); 2361a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 2371a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde info->cmd_sock = cmd_sock; 2381a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde info->event_sock = event_sock; 2391a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde info->clean_up = false; 2401a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde info->in_event_loop = false; 2411a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 2421a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde info->event_cb = (cb_info *)malloc(sizeof(cb_info) * DEFAULT_EVENT_CB_SIZE); 2431a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde info->alloc_event_cb = DEFAULT_EVENT_CB_SIZE; 2441a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde info->num_event_cb = 0; 2451a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 2461a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde info->cmd = (cmd_info *)malloc(sizeof(cmd_info) * DEFAULT_CMD_SIZE); 2471a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde info->alloc_cmd = DEFAULT_CMD_SIZE; 2481a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde info->num_cmd = 0; 2491a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 2501a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde info->nl80211_family_id = genl_ctrl_resolve(cmd_sock, "nl80211"); 2511a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (info->nl80211_family_id < 0) { 2521a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGE("Could not resolve nl80211 familty id"); 2531a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde nl_socket_free(cmd_sock); 2541a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde nl_socket_free(event_sock); 2551a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde free(info); 2569a23388d5a9f58f106169700bb179de0a4af7840Ashwin return WIFI_ERROR_UNKNOWN; 2571a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 2581a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 259bb8a4d506769d7dc8b33445c6725a40b7523063cVinit Deshpande pthread_mutex_init(&info->cb_lock, NULL); 260bb8a4d506769d7dc8b33445c6725a40b7523063cVinit Deshpande 2611a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde *handle = (wifi_handle) info; 2621a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 2631a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde wifi_add_membership(*handle, "scan"); 2641a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde wifi_add_membership(*handle, "mlme"); 2651a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde wifi_add_membership(*handle, "regulatory"); 2661a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde wifi_add_membership(*handle, "vendor"); 2671a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 2681a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde wifi_init_interfaces(*handle); 2691a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde // ALOGI("Found %d interfaces", info->num_interfaces); 2701a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 271bb8a4d506769d7dc8b33445c6725a40b7523063cVinit Deshpande 2721a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGI("Initialized Wifi HAL Successfully; vendor cmd = %d", NL80211_CMD_VENDOR); 2731a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return WIFI_SUCCESS; 2741a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde} 2751a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 2761a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapndestatic int wifi_add_membership(wifi_handle handle, const char *group) 2771a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde{ 2781a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde hal_info *info = getHalInfo(handle); 2791a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 2801a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int id = wifi_get_multicast_id(handle, "nl80211", group); 2811a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (id < 0) { 2821a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGE("Could not find group %s", group); 2831a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return id; 2841a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 2851a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 2861a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int ret = nl_socket_add_membership(info->event_sock, id); 2871a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (ret < 0) { 2881a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGE("Could not add membership to group %s", group); 2891a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 2901a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 2911a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde // ALOGI("Successfully added membership for group %s", group); 2921a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return ret; 2931a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde} 2941a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 2951a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapndestatic void internal_cleaned_up_handler(wifi_handle handle) 2961a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde{ 2971a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde hal_info *info = getHalInfo(handle); 2981a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde wifi_cleaned_up_handler cleaned_up_handler = info->cleaned_up_handler; 2991a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 3001a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (info->cmd_sock != 0) { 30105e31d445f52da4746ff0cc0703d83814cea98d0Vinit Deshpande close(info->cleanup_socks[0]); 30205e31d445f52da4746ff0cc0703d83814cea98d0Vinit Deshpande close(info->cleanup_socks[1]); 3031a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde nl_socket_free(info->cmd_sock); 3041a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde nl_socket_free(info->event_sock); 3051a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde info->cmd_sock = NULL; 3061a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde info->event_sock = NULL; 3071a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 3081a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 3091a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde (*cleaned_up_handler)(handle); 310bb8a4d506769d7dc8b33445c6725a40b7523063cVinit Deshpande pthread_mutex_destroy(&info->cb_lock); 3111a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde free(info); 3121a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 3131a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGI("Internal cleanup completed"); 3141a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde} 3151a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 3161a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapndevoid wifi_cleanup(wifi_handle handle, wifi_cleaned_up_handler handler) 3171a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde{ 3181a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde hal_info *info = getHalInfo(handle); 31956c89ca266b11be506192f3a13a1dba3f109c2cfAshwin char buf[64]; 32056c89ca266b11be506192f3a13a1dba3f109c2cfAshwin 3211a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde info->cleaned_up_handler = handler; 32256c89ca266b11be506192f3a13a1dba3f109c2cfAshwin if (write(info->cleanup_socks[0], "Exit", 4) < 1) { 32356c89ca266b11be506192f3a13a1dba3f109c2cfAshwin // As a fallback set the cleanup flag to TRUE 32456c89ca266b11be506192f3a13a1dba3f109c2cfAshwin ALOGE("could not write to the cleanup socket"); 32556c89ca266b11be506192f3a13a1dba3f109c2cfAshwin } else { 32656c89ca266b11be506192f3a13a1dba3f109c2cfAshwin // Listen to the response 32756c89ca266b11be506192f3a13a1dba3f109c2cfAshwin // Hopefully we dont get errors or get hung up 32856c89ca266b11be506192f3a13a1dba3f109c2cfAshwin // Not much can be done in that case, but assume that 32956c89ca266b11be506192f3a13a1dba3f109c2cfAshwin // it has rx'ed the Exit message to exit the thread. 33056c89ca266b11be506192f3a13a1dba3f109c2cfAshwin // As a fallback set the cleanup flag to TRUE 33156c89ca266b11be506192f3a13a1dba3f109c2cfAshwin memset(buf, 0, sizeof(buf)); 33256c89ca266b11be506192f3a13a1dba3f109c2cfAshwin int result = read(info->cleanup_socks[0], buf, sizeof(buf)); 33356c89ca266b11be506192f3a13a1dba3f109c2cfAshwin ALOGE("%s: Read after POLL returned %d, error no = %d", __FUNCTION__, result, errno); 33456c89ca266b11be506192f3a13a1dba3f109c2cfAshwin if (strncmp(buf, "Done", 4) == 0) { 33556c89ca266b11be506192f3a13a1dba3f109c2cfAshwin ALOGE("Event processing terminated"); 33656c89ca266b11be506192f3a13a1dba3f109c2cfAshwin } else { 33756c89ca266b11be506192f3a13a1dba3f109c2cfAshwin ALOGD("Rx'ed %s", buf); 33856c89ca266b11be506192f3a13a1dba3f109c2cfAshwin } 33956c89ca266b11be506192f3a13a1dba3f109c2cfAshwin } 3401a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde info->clean_up = true; 34105e31d445f52da4746ff0cc0703d83814cea98d0Vinit Deshpande pthread_mutex_lock(&info->cb_lock); 34205e31d445f52da4746ff0cc0703d83814cea98d0Vinit Deshpande 343d4f6adc737f93d75d3a1be8427a144f907a4dde6Vinit Deshpande int bad_commands = 0; 344d4f6adc737f93d75d3a1be8427a144f907a4dde6Vinit Deshpande 3456d9f23bf01b35074e29c6319c4009a1295cb4aa6Vinit Deshpande for (int i = 0; i < info->num_event_cb; i++) { 3466d9f23bf01b35074e29c6319c4009a1295cb4aa6Vinit Deshpande cb_info *cbi = &(info->event_cb[i]); 3476d9f23bf01b35074e29c6319c4009a1295cb4aa6Vinit Deshpande WifiCommand *cmd = (WifiCommand *)cbi->cb_arg; 3485cbe0dca22a31ea90201e47989df44b124f6f13eAshwin ALOGI("Command left in event_cb %p:%s", cmd, (cmd ? cmd->getType(): "")); 3496d9f23bf01b35074e29c6319c4009a1295cb4aa6Vinit Deshpande } 3506d9f23bf01b35074e29c6319c4009a1295cb4aa6Vinit Deshpande 351d4f6adc737f93d75d3a1be8427a144f907a4dde6Vinit Deshpande while (info->num_cmd > bad_commands) { 352d4f6adc737f93d75d3a1be8427a144f907a4dde6Vinit Deshpande int num_cmd = info->num_cmd; 353d4f6adc737f93d75d3a1be8427a144f907a4dde6Vinit Deshpande cmd_info *cmdi = &(info->cmd[bad_commands]); 354d4f6adc737f93d75d3a1be8427a144f907a4dde6Vinit Deshpande WifiCommand *cmd = cmdi->cmd; 35505e31d445f52da4746ff0cc0703d83814cea98d0Vinit Deshpande if (cmd != NULL) { 3565cbe0dca22a31ea90201e47989df44b124f6f13eAshwin ALOGI("Cancelling command %p:%s", cmd, cmd->getType()); 357974df1c535fa4aa5c191d47877aa27c79fad0263Vinit Deshpande pthread_mutex_unlock(&info->cb_lock); 35805e31d445f52da4746ff0cc0703d83814cea98d0Vinit Deshpande cmd->cancel(); 359974df1c535fa4aa5c191d47877aa27c79fad0263Vinit Deshpande pthread_mutex_lock(&info->cb_lock); 360d4f6adc737f93d75d3a1be8427a144f907a4dde6Vinit Deshpande if (num_cmd == info->num_cmd) { 3615cbe0dca22a31ea90201e47989df44b124f6f13eAshwin ALOGI("Cancelling command %p:%s did not work", cmd, (cmd ? cmd->getType(): "")); 362d4f6adc737f93d75d3a1be8427a144f907a4dde6Vinit Deshpande bad_commands++; 363d4f6adc737f93d75d3a1be8427a144f907a4dde6Vinit Deshpande } 364d7f3cb9915d9ac514393d0ad7767662958054b8fPaul Stewart /* release reference added when command is saved */ 365d7f3cb9915d9ac514393d0ad7767662958054b8fPaul Stewart cmd->releaseRef(); 36605e31d445f52da4746ff0cc0703d83814cea98d0Vinit Deshpande } 36705e31d445f52da4746ff0cc0703d83814cea98d0Vinit Deshpande } 36805e31d445f52da4746ff0cc0703d83814cea98d0Vinit Deshpande 369d4f6adc737f93d75d3a1be8427a144f907a4dde6Vinit Deshpande for (int i = 0; i < info->num_event_cb; i++) { 370d4f6adc737f93d75d3a1be8427a144f907a4dde6Vinit Deshpande cb_info *cbi = &(info->event_cb[i]); 371d4f6adc737f93d75d3a1be8427a144f907a4dde6Vinit Deshpande WifiCommand *cmd = (WifiCommand *)cbi->cb_arg; 3726d9f23bf01b35074e29c6319c4009a1295cb4aa6Vinit Deshpande ALOGE("Leaked command %p", cmd); 373d4f6adc737f93d75d3a1be8427a144f907a4dde6Vinit Deshpande } 37405e31d445f52da4746ff0cc0703d83814cea98d0Vinit Deshpande pthread_mutex_unlock(&info->cb_lock); 37556c89ca266b11be506192f3a13a1dba3f109c2cfAshwin internal_cleaned_up_handler(handle); 3761a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde} 3771a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 3781a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapndestatic int internal_pollin_handler(wifi_handle handle) 3791a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde{ 3801a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde hal_info *info = getHalInfo(handle); 3811a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde struct nl_cb *cb = nl_socket_get_cb(info->event_sock); 3821a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int res = nl_recvmsgs(info->event_sock, cb); 383642bfbe829f5438db3d99ce4678bcb770359a632Vinit Deshpande // ALOGD("nl_recvmsgs returned %d", res); 3841a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde nl_cb_put(cb); 3851a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return res; 3861a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde} 3871a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 3881a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde/* Run event handler */ 3891a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapndevoid wifi_event_loop(wifi_handle handle) 3901a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde{ 3911a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde hal_info *info = getHalInfo(handle); 3921a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (info->in_event_loop) { 3931a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return; 3941a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } else { 3951a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde info->in_event_loop = true; 3961a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 3971a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 39805e31d445f52da4746ff0cc0703d83814cea98d0Vinit Deshpande pollfd pfd[2]; 39905e31d445f52da4746ff0cc0703d83814cea98d0Vinit Deshpande memset(&pfd[0], 0, sizeof(pollfd) * 2); 4001a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 40105e31d445f52da4746ff0cc0703d83814cea98d0Vinit Deshpande pfd[0].fd = nl_socket_get_fd(info->event_sock); 40205e31d445f52da4746ff0cc0703d83814cea98d0Vinit Deshpande pfd[0].events = POLLIN; 40305e31d445f52da4746ff0cc0703d83814cea98d0Vinit Deshpande pfd[1].fd = info->cleanup_socks[1]; 40405e31d445f52da4746ff0cc0703d83814cea98d0Vinit Deshpande pfd[1].events = POLLIN; 4051a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 40605e31d445f52da4746ff0cc0703d83814cea98d0Vinit Deshpande char buf[2048]; 4071a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde /* TODO: Add support for timeouts */ 4081a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 4091a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde do { 4101a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int timeout = -1; /* Infinite timeout */ 41105e31d445f52da4746ff0cc0703d83814cea98d0Vinit Deshpande pfd[0].revents = 0; 41205e31d445f52da4746ff0cc0703d83814cea98d0Vinit Deshpande pfd[1].revents = 0; 413642bfbe829f5438db3d99ce4678bcb770359a632Vinit Deshpande // ALOGI("Polling socket"); 41405e31d445f52da4746ff0cc0703d83814cea98d0Vinit Deshpande int result = poll(pfd, 2, timeout); 4151a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 416e16283338c9f0e8798228c400e31415d612f7d09Vinit Deshpande // ALOGE("Error polling socket"); 41705e31d445f52da4746ff0cc0703d83814cea98d0Vinit Deshpande } else if (pfd[0].revents & POLLERR) { 418cc370437327c04d82dc8b3addc556d5bc30efc77Vinit Deshpande ALOGE("POLL Error; error no = %d", errno); 41905e31d445f52da4746ff0cc0703d83814cea98d0Vinit Deshpande int result2 = read(pfd[0].fd, buf, sizeof(buf)); 420cc370437327c04d82dc8b3addc556d5bc30efc77Vinit Deshpande ALOGE("Read after POLL returned %d, error no = %d", result2, errno); 42105e31d445f52da4746ff0cc0703d83814cea98d0Vinit Deshpande } else if (pfd[0].revents & POLLHUP) { 422cc370437327c04d82dc8b3addc556d5bc30efc77Vinit Deshpande ALOGE("Remote side hung up"); 423cc370437327c04d82dc8b3addc556d5bc30efc77Vinit Deshpande break; 42405e31d445f52da4746ff0cc0703d83814cea98d0Vinit Deshpande } else if (pfd[0].revents & POLLIN) { 425854a437fc5530b1555cd469319d1f96ba184b178Vinit Deshpande // ALOGI("Found some events!!!"); 426cc370437327c04d82dc8b3addc556d5bc30efc77Vinit Deshpande internal_pollin_handler(handle); 42705e31d445f52da4746ff0cc0703d83814cea98d0Vinit Deshpande } else if (pfd[1].revents & POLLIN) { 42856c89ca266b11be506192f3a13a1dba3f109c2cfAshwin memset(buf, 0, sizeof(buf)); 42905e31d445f52da4746ff0cc0703d83814cea98d0Vinit Deshpande int result2 = read(pfd[1].fd, buf, sizeof(buf)); 43056c89ca266b11be506192f3a13a1dba3f109c2cfAshwin ALOGE("%s: Read after POLL returned %d, error no = %d", __FUNCTION__, result2, errno); 43156c89ca266b11be506192f3a13a1dba3f109c2cfAshwin if (strncmp(buf, "Exit", 4) == 0) { 43256c89ca266b11be506192f3a13a1dba3f109c2cfAshwin ALOGD("Got a signal to exit!!!"); 43356c89ca266b11be506192f3a13a1dba3f109c2cfAshwin if (write(pfd[1].fd, "Done", 4) < 1) { 43456c89ca266b11be506192f3a13a1dba3f109c2cfAshwin ALOGE("could not write to the cleanup socket"); 43556c89ca266b11be506192f3a13a1dba3f109c2cfAshwin } 43656c89ca266b11be506192f3a13a1dba3f109c2cfAshwin break; 43756c89ca266b11be506192f3a13a1dba3f109c2cfAshwin } else { 43856c89ca266b11be506192f3a13a1dba3f109c2cfAshwin ALOGD("Rx'ed %s on the cleanup socket\n", buf); 43956c89ca266b11be506192f3a13a1dba3f109c2cfAshwin } 440cc370437327c04d82dc8b3addc556d5bc30efc77Vinit Deshpande } else { 44105e31d445f52da4746ff0cc0703d83814cea98d0Vinit Deshpande ALOGE("Unknown event - %0x, %0x", pfd[0].revents, pfd[1].revents); 4421a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 4431a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } while (!info->clean_up); 44456c89ca266b11be506192f3a13a1dba3f109c2cfAshwin ALOGI("Exit %s", __FUNCTION__); 4451a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde} 4461a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 4471a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde/////////////////////////////////////////////////////////////////////////////////////// 4481a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 449642bfbe829f5438db3d99ce4678bcb770359a632Vinit Deshpandestatic int internal_no_seq_check(struct nl_msg *msg, void *arg) 450642bfbe829f5438db3d99ce4678bcb770359a632Vinit Deshpande{ 451642bfbe829f5438db3d99ce4678bcb770359a632Vinit Deshpande return NL_OK; 452642bfbe829f5438db3d99ce4678bcb770359a632Vinit Deshpande} 453642bfbe829f5438db3d99ce4678bcb770359a632Vinit Deshpande 4541a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapndestatic int internal_valid_message_handler(nl_msg *msg, void *arg) 4551a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde{ 456854a437fc5530b1555cd469319d1f96ba184b178Vinit Deshpande // ALOGI("got an event"); 45705e31d445f52da4746ff0cc0703d83814cea98d0Vinit Deshpande 4581a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde wifi_handle handle = (wifi_handle)arg; 4591a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde hal_info *info = getHalInfo(handle); 4601a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 4611a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde WifiEvent event(msg); 4621a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int res = event.parse(); 4631a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (res < 0) { 4641a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGE("Failed to parse event: %d", res); 4651a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return NL_SKIP; 4661a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 4671a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 4681a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int cmd = event.get_cmd(); 4691a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde uint32_t vendor_id = 0; 4701a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int subcmd = 0; 4711a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 4721a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (cmd == NL80211_CMD_VENDOR) { 4731a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde vendor_id = event.get_u32(NL80211_ATTR_VENDOR_ID); 4741a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde subcmd = event.get_u32(NL80211_ATTR_VENDOR_SUBCMD); 475ec74fa4fcb49a35e6af54e086e63692b37d21b02Vinit Deshpande ALOGV("event received %s, vendor_id = 0x%0x, subcmd = 0x%0x", 4761a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde event.get_cmdString(), vendor_id, subcmd); 4771a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } else { 478ec74fa4fcb49a35e6af54e086e63692b37d21b02Vinit Deshpande // ALOGV("event received %s", event.get_cmdString()); 4791a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 4801a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 481ec74fa4fcb49a35e6af54e086e63692b37d21b02Vinit Deshpande // ALOGV("event received %s, vendor_id = 0x%0x", event.get_cmdString(), vendor_id); 4821a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde // event.log(); 4831a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 4841a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde bool dispatched = false; 485bb8a4d506769d7dc8b33445c6725a40b7523063cVinit Deshpande 486bb8a4d506769d7dc8b33445c6725a40b7523063cVinit Deshpande pthread_mutex_lock(&info->cb_lock); 487bb8a4d506769d7dc8b33445c6725a40b7523063cVinit Deshpande 4881a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde for (int i = 0; i < info->num_event_cb; i++) { 4891a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (cmd == info->event_cb[i].nl_cmd) { 4901a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (cmd == NL80211_CMD_VENDOR 4911a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde && ((vendor_id != info->event_cb[i].vendor_id) 4921a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde || (subcmd != info->event_cb[i].vendor_subcmd))) 4931a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde { 4941a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde /* event for a different vendor, ignore it */ 4951a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde continue; 4961a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 4971a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 4981a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde cb_info *cbi = &(info->event_cb[i]); 49928237f92de2634ec1d529c63b2d61d80e7485c83Vinit Deshpande nl_recvmsg_msg_cb_t cb_func = cbi->cb_func; 50028237f92de2634ec1d529c63b2d61d80e7485c83Vinit Deshpande void *cb_arg = cbi->cb_arg; 50128237f92de2634ec1d529c63b2d61d80e7485c83Vinit Deshpande WifiCommand *cmd = (WifiCommand *)cbi->cb_arg; 50228237f92de2634ec1d529c63b2d61d80e7485c83Vinit Deshpande if (cmd != NULL) { 50328237f92de2634ec1d529c63b2d61d80e7485c83Vinit Deshpande cmd->addRef(); 50428237f92de2634ec1d529c63b2d61d80e7485c83Vinit Deshpande } 50528237f92de2634ec1d529c63b2d61d80e7485c83Vinit Deshpande pthread_mutex_unlock(&info->cb_lock); 50656c89ca266b11be506192f3a13a1dba3f109c2cfAshwin if (cb_func) 50756c89ca266b11be506192f3a13a1dba3f109c2cfAshwin (*cb_func)(msg, cb_arg); 50828237f92de2634ec1d529c63b2d61d80e7485c83Vinit Deshpande if (cmd != NULL) { 50928237f92de2634ec1d529c63b2d61d80e7485c83Vinit Deshpande cmd->releaseRef(); 51028237f92de2634ec1d529c63b2d61d80e7485c83Vinit Deshpande } 51128237f92de2634ec1d529c63b2d61d80e7485c83Vinit Deshpande 51228237f92de2634ec1d529c63b2d61d80e7485c83Vinit Deshpande return NL_OK; 51328237f92de2634ec1d529c63b2d61d80e7485c83Vinit Deshpande } 5141a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 5151a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 516bb8a4d506769d7dc8b33445c6725a40b7523063cVinit Deshpande pthread_mutex_unlock(&info->cb_lock); 5171a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return NL_OK; 5181a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde} 5191a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 5201a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde/////////////////////////////////////////////////////////////////////////////////////// 5211a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 5221a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapndeclass GetMulticastIdCommand : public WifiCommand 5231a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde{ 5241a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapndeprivate: 5251a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde const char *mName; 5261a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde const char *mGroup; 5271a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int mId; 5281a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapndepublic: 5291a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GetMulticastIdCommand(wifi_handle handle, const char *name, const char *group) 530d4f6adc737f93d75d3a1be8427a144f907a4dde6Vinit Deshpande : WifiCommand("GetMulticastIdCommand", handle, 0) 5311a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde { 5321a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde mName = name; 5331a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde mGroup = group; 5341a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde mId = -1; 5351a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 5361a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 5371a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int getId() { 5381a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return mId; 5391a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 5401a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 5411a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde virtual int create() { 5421a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int nlctrlFamily = genl_ctrl_resolve(mInfo->cmd_sock, "nlctrl"); 5431a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde // ALOGI("ctrl family = %d", nlctrlFamily); 5441a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int ret = mMsg.create(nlctrlFamily, CTRL_CMD_GETFAMILY, 0, 0); 5451a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (ret < 0) { 5461a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return ret; 5471a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 5481a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ret = mMsg.put_string(CTRL_ATTR_FAMILY_NAME, mName); 5491a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return ret; 5501a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 5511a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 5521a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde virtual int handleResponse(WifiEvent& reply) { 5531a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 5541a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde // ALOGI("handling reponse in %s", __func__); 5551a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 5561a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde struct nlattr **tb = reply.attributes(); 5571a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde struct genlmsghdr *gnlh = reply.header(); 5581a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde struct nlattr *mcgrp = NULL; 5591a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int i; 5601a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 5611a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (!tb[CTRL_ATTR_MCAST_GROUPS]) { 5621a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGI("No multicast groups found"); 5631a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return NL_SKIP; 5641a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } else { 5651a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde // ALOGI("Multicast groups attr size = %d", nla_len(tb[CTRL_ATTR_MCAST_GROUPS])); 5661a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 5671a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 5681a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde for_each_attr(mcgrp, tb[CTRL_ATTR_MCAST_GROUPS], i) { 5691a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 5701a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde // ALOGI("Processing group"); 5711a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde struct nlattr *tb2[CTRL_ATTR_MCAST_GRP_MAX + 1]; 5721a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde nla_parse(tb2, CTRL_ATTR_MCAST_GRP_MAX, (nlattr *)nla_data(mcgrp), 5731a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde nla_len(mcgrp), NULL); 5741a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (!tb2[CTRL_ATTR_MCAST_GRP_NAME] || !tb2[CTRL_ATTR_MCAST_GRP_ID]) { 5751a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde continue; 5761a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 5771a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 5781a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde char *grpName = (char *)nla_data(tb2[CTRL_ATTR_MCAST_GRP_NAME]); 5791a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int grpNameLen = nla_len(tb2[CTRL_ATTR_MCAST_GRP_NAME]); 5801a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 5811a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde // ALOGI("Found group name %s", grpName); 5821a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 5831a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (strncmp(grpName, mGroup, grpNameLen) != 0) 5841a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde continue; 5851a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 5861a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde mId = nla_get_u32(tb2[CTRL_ATTR_MCAST_GRP_ID]); 5871a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde break; 5881a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 5891a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 5901a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return NL_SKIP; 5911a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 5921a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 5931a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde}; 5941a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 595f0d5070a931327e6356d765478069b9e66452a5bAshwinclass SetPnoMacAddrOuiCommand : public WifiCommand { 596f0d5070a931327e6356d765478069b9e66452a5bAshwin 597f0d5070a931327e6356d765478069b9e66452a5bAshwinprivate: 598f0d5070a931327e6356d765478069b9e66452a5bAshwin byte *mOui; 599f0d5070a931327e6356d765478069b9e66452a5bAshwin feature_set *fset; 600f0d5070a931327e6356d765478069b9e66452a5bAshwin feature_set *feature_matrix; 601f0d5070a931327e6356d765478069b9e66452a5bAshwin int *fm_size; 602f0d5070a931327e6356d765478069b9e66452a5bAshwin int set_size_max; 603f0d5070a931327e6356d765478069b9e66452a5bAshwinpublic: 604f0d5070a931327e6356d765478069b9e66452a5bAshwin SetPnoMacAddrOuiCommand(wifi_interface_handle handle, oui scan_oui) 605d4f6adc737f93d75d3a1be8427a144f907a4dde6Vinit Deshpande : WifiCommand("SetPnoMacAddrOuiCommand", handle, 0) 606f0d5070a931327e6356d765478069b9e66452a5bAshwin { 607f0d5070a931327e6356d765478069b9e66452a5bAshwin mOui = scan_oui; 608f0d5070a931327e6356d765478069b9e66452a5bAshwin } 609f0d5070a931327e6356d765478069b9e66452a5bAshwin 610f0d5070a931327e6356d765478069b9e66452a5bAshwin int createRequest(WifiRequest& request, int subcmd, byte *scan_oui) { 611f0d5070a931327e6356d765478069b9e66452a5bAshwin int result = request.create(GOOGLE_OUI, subcmd); 612f0d5070a931327e6356d765478069b9e66452a5bAshwin if (result < 0) { 613f0d5070a931327e6356d765478069b9e66452a5bAshwin return result; 614f0d5070a931327e6356d765478069b9e66452a5bAshwin } 615f0d5070a931327e6356d765478069b9e66452a5bAshwin 616f0d5070a931327e6356d765478069b9e66452a5bAshwin nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA); 617f0d5070a931327e6356d765478069b9e66452a5bAshwin result = request.put(ANDR_WIFI_ATTRIBUTE_PNO_RANDOM_MAC_OUI, scan_oui, DOT11_OUI_LEN); 618f0d5070a931327e6356d765478069b9e66452a5bAshwin if (result < 0) { 619f0d5070a931327e6356d765478069b9e66452a5bAshwin return result; 620f0d5070a931327e6356d765478069b9e66452a5bAshwin } 621f0d5070a931327e6356d765478069b9e66452a5bAshwin 622f0d5070a931327e6356d765478069b9e66452a5bAshwin request.attr_end(data); 623f0d5070a931327e6356d765478069b9e66452a5bAshwin return WIFI_SUCCESS; 624f0d5070a931327e6356d765478069b9e66452a5bAshwin 625f0d5070a931327e6356d765478069b9e66452a5bAshwin } 626f0d5070a931327e6356d765478069b9e66452a5bAshwin 627f0d5070a931327e6356d765478069b9e66452a5bAshwin int start() { 628f0d5070a931327e6356d765478069b9e66452a5bAshwin ALOGD("Sending mac address OUI"); 629f0d5070a931327e6356d765478069b9e66452a5bAshwin WifiRequest request(familyId(), ifaceId()); 630f0d5070a931327e6356d765478069b9e66452a5bAshwin int result = createRequest(request, WIFI_SUBCMD_SET_PNO_RANDOM_MAC_OUI, mOui); 631f0d5070a931327e6356d765478069b9e66452a5bAshwin if (result != WIFI_SUCCESS) { 632f0d5070a931327e6356d765478069b9e66452a5bAshwin ALOGE("failed to create request; result = %d", result); 633f0d5070a931327e6356d765478069b9e66452a5bAshwin return result; 634f0d5070a931327e6356d765478069b9e66452a5bAshwin } 635f0d5070a931327e6356d765478069b9e66452a5bAshwin 636f0d5070a931327e6356d765478069b9e66452a5bAshwin result = requestResponse(request); 637f0d5070a931327e6356d765478069b9e66452a5bAshwin if (result != WIFI_SUCCESS) { 638f0d5070a931327e6356d765478069b9e66452a5bAshwin ALOGE("failed to set scanning mac OUI; result = %d", result); 639f0d5070a931327e6356d765478069b9e66452a5bAshwin } 640f0d5070a931327e6356d765478069b9e66452a5bAshwin 641f0d5070a931327e6356d765478069b9e66452a5bAshwin return result; 642f0d5070a931327e6356d765478069b9e66452a5bAshwin } 643f0d5070a931327e6356d765478069b9e66452a5bAshwinprotected: 644f0d5070a931327e6356d765478069b9e66452a5bAshwin virtual int handleResponse(WifiEvent& reply) { 645f0d5070a931327e6356d765478069b9e66452a5bAshwin ALOGD("Request complete!"); 646f0d5070a931327e6356d765478069b9e66452a5bAshwin /* Nothing to do on response! */ 647f0d5070a931327e6356d765478069b9e66452a5bAshwin return NL_SKIP; 648f0d5070a931327e6356d765478069b9e66452a5bAshwin } 649f0d5070a931327e6356d765478069b9e66452a5bAshwin}; 650f0d5070a931327e6356d765478069b9e66452a5bAshwin 651b4ac10a4e1eddf00ddad32f3307cc050bb4e0963Dmitry Shmidtclass SetNodfsCommand : public WifiCommand { 652b4ac10a4e1eddf00ddad32f3307cc050bb4e0963Dmitry Shmidt 653b4ac10a4e1eddf00ddad32f3307cc050bb4e0963Dmitry Shmidtprivate: 654b4ac10a4e1eddf00ddad32f3307cc050bb4e0963Dmitry Shmidt u32 mNoDfs; 655b4ac10a4e1eddf00ddad32f3307cc050bb4e0963Dmitry Shmidtpublic: 656b4ac10a4e1eddf00ddad32f3307cc050bb4e0963Dmitry Shmidt SetNodfsCommand(wifi_interface_handle handle, u32 nodfs) 657d4f6adc737f93d75d3a1be8427a144f907a4dde6Vinit Deshpande : WifiCommand("SetNodfsCommand", handle, 0) { 658b4ac10a4e1eddf00ddad32f3307cc050bb4e0963Dmitry Shmidt mNoDfs = nodfs; 659b4ac10a4e1eddf00ddad32f3307cc050bb4e0963Dmitry Shmidt } 660b4ac10a4e1eddf00ddad32f3307cc050bb4e0963Dmitry Shmidt virtual int create() { 661b4ac10a4e1eddf00ddad32f3307cc050bb4e0963Dmitry Shmidt int ret; 662f0d5070a931327e6356d765478069b9e66452a5bAshwin 663b4ac10a4e1eddf00ddad32f3307cc050bb4e0963Dmitry Shmidt ret = mMsg.create(GOOGLE_OUI, WIFI_SUBCMD_NODFS_SET); 664b4ac10a4e1eddf00ddad32f3307cc050bb4e0963Dmitry Shmidt if (ret < 0) { 665b4ac10a4e1eddf00ddad32f3307cc050bb4e0963Dmitry Shmidt ALOGE("Can't create message to send to driver - %d", ret); 666b4ac10a4e1eddf00ddad32f3307cc050bb4e0963Dmitry Shmidt return ret; 667b4ac10a4e1eddf00ddad32f3307cc050bb4e0963Dmitry Shmidt } 668b4ac10a4e1eddf00ddad32f3307cc050bb4e0963Dmitry Shmidt 669b4ac10a4e1eddf00ddad32f3307cc050bb4e0963Dmitry Shmidt nlattr *data = mMsg.attr_start(NL80211_ATTR_VENDOR_DATA); 67065f9c6fbd929be309642cdaf255e8394aad2b0caJun Lim ret = mMsg.put_u32(ANDR_WIFI_ATTRIBUTE_NODFS_SET, mNoDfs); 671b4ac10a4e1eddf00ddad32f3307cc050bb4e0963Dmitry Shmidt if (ret < 0) { 672b4ac10a4e1eddf00ddad32f3307cc050bb4e0963Dmitry Shmidt return ret; 673b4ac10a4e1eddf00ddad32f3307cc050bb4e0963Dmitry Shmidt } 674b4ac10a4e1eddf00ddad32f3307cc050bb4e0963Dmitry Shmidt 675b4ac10a4e1eddf00ddad32f3307cc050bb4e0963Dmitry Shmidt mMsg.attr_end(data); 676b4ac10a4e1eddf00ddad32f3307cc050bb4e0963Dmitry Shmidt return WIFI_SUCCESS; 677b4ac10a4e1eddf00ddad32f3307cc050bb4e0963Dmitry Shmidt } 678b4ac10a4e1eddf00ddad32f3307cc050bb4e0963Dmitry Shmidt}; 679f0d5070a931327e6356d765478069b9e66452a5bAshwin 680c02e00563882d87ab29822c43097cbb1ce04b55dxinheclass SetCountryCodeCommand : public WifiCommand { 681c02e00563882d87ab29822c43097cbb1ce04b55dxinheprivate: 682c02e00563882d87ab29822c43097cbb1ce04b55dxinhe const char *mCountryCode; 683c02e00563882d87ab29822c43097cbb1ce04b55dxinhepublic: 684c02e00563882d87ab29822c43097cbb1ce04b55dxinhe SetCountryCodeCommand(wifi_interface_handle handle, const char *country_code) 685d4f6adc737f93d75d3a1be8427a144f907a4dde6Vinit Deshpande : WifiCommand("SetCountryCodeCommand", handle, 0) { 686c02e00563882d87ab29822c43097cbb1ce04b55dxinhe mCountryCode = country_code; 687c02e00563882d87ab29822c43097cbb1ce04b55dxinhe } 688c02e00563882d87ab29822c43097cbb1ce04b55dxinhe virtual int create() { 689c02e00563882d87ab29822c43097cbb1ce04b55dxinhe int ret; 690c02e00563882d87ab29822c43097cbb1ce04b55dxinhe 691c02e00563882d87ab29822c43097cbb1ce04b55dxinhe ret = mMsg.create(GOOGLE_OUI, WIFI_SUBCMD_SET_COUNTRY_CODE); 692c02e00563882d87ab29822c43097cbb1ce04b55dxinhe if (ret < 0) { 693c02e00563882d87ab29822c43097cbb1ce04b55dxinhe ALOGE("Can't create message to send to driver - %d", ret); 694c02e00563882d87ab29822c43097cbb1ce04b55dxinhe return ret; 695c02e00563882d87ab29822c43097cbb1ce04b55dxinhe } 696c02e00563882d87ab29822c43097cbb1ce04b55dxinhe 697c02e00563882d87ab29822c43097cbb1ce04b55dxinhe nlattr *data = mMsg.attr_start(NL80211_ATTR_VENDOR_DATA); 69865f9c6fbd929be309642cdaf255e8394aad2b0caJun Lim ret = mMsg.put_string(ANDR_WIFI_ATTRIBUTE_COUNTRY, mCountryCode); 699c02e00563882d87ab29822c43097cbb1ce04b55dxinhe if (ret < 0) { 700c02e00563882d87ab29822c43097cbb1ce04b55dxinhe return ret; 701c02e00563882d87ab29822c43097cbb1ce04b55dxinhe } 702c02e00563882d87ab29822c43097cbb1ce04b55dxinhe 703c02e00563882d87ab29822c43097cbb1ce04b55dxinhe mMsg.attr_end(data); 704c02e00563882d87ab29822c43097cbb1ce04b55dxinhe return WIFI_SUCCESS; 705c02e00563882d87ab29822c43097cbb1ce04b55dxinhe 706c02e00563882d87ab29822c43097cbb1ce04b55dxinhe } 707c02e00563882d87ab29822c43097cbb1ce04b55dxinhe}; 708c02e00563882d87ab29822c43097cbb1ce04b55dxinhe 709fef13c11034313585be68c32322b9a53c43a37b2Ashwinclass SetRSSIMonitorCommand : public WifiCommand { 710fef13c11034313585be68c32322b9a53c43a37b2Ashwinprivate: 711fef13c11034313585be68c32322b9a53c43a37b2Ashwin s8 mMax_rssi; 712fef13c11034313585be68c32322b9a53c43a37b2Ashwin s8 mMin_rssi; 713fef13c11034313585be68c32322b9a53c43a37b2Ashwin wifi_rssi_event_handler mHandler; 714fef13c11034313585be68c32322b9a53c43a37b2Ashwinpublic: 715fef13c11034313585be68c32322b9a53c43a37b2Ashwin SetRSSIMonitorCommand(wifi_request_id id, wifi_interface_handle handle, 716fef13c11034313585be68c32322b9a53c43a37b2Ashwin s8 max_rssi, s8 min_rssi, wifi_rssi_event_handler eh) 717d4f6adc737f93d75d3a1be8427a144f907a4dde6Vinit Deshpande : WifiCommand("SetRSSIMonitorCommand", handle, id), mMax_rssi(max_rssi), mMin_rssi 718d4f6adc737f93d75d3a1be8427a144f907a4dde6Vinit Deshpande (min_rssi), mHandler(eh) 719fef13c11034313585be68c32322b9a53c43a37b2Ashwin { 720fef13c11034313585be68c32322b9a53c43a37b2Ashwin } 721fef13c11034313585be68c32322b9a53c43a37b2Ashwin int createRequest(WifiRequest& request, int enable) { 722fef13c11034313585be68c32322b9a53c43a37b2Ashwin int result = request.create(GOOGLE_OUI, WIFI_SUBCMD_SET_RSSI_MONITOR); 723fef13c11034313585be68c32322b9a53c43a37b2Ashwin if (result < 0) { 724fef13c11034313585be68c32322b9a53c43a37b2Ashwin return result; 725fef13c11034313585be68c32322b9a53c43a37b2Ashwin } 726fef13c11034313585be68c32322b9a53c43a37b2Ashwin 727fef13c11034313585be68c32322b9a53c43a37b2Ashwin nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA); 728fef13c11034313585be68c32322b9a53c43a37b2Ashwin result = request.put_u32(RSSI_MONITOR_ATTRIBUTE_MAX_RSSI, (enable ? mMax_rssi: 0)); 729fef13c11034313585be68c32322b9a53c43a37b2Ashwin if (result < 0) { 730fef13c11034313585be68c32322b9a53c43a37b2Ashwin return result; 731fef13c11034313585be68c32322b9a53c43a37b2Ashwin } 732fef13c11034313585be68c32322b9a53c43a37b2Ashwin ALOGD("create request"); 733fef13c11034313585be68c32322b9a53c43a37b2Ashwin result = request.put_u32(RSSI_MONITOR_ATTRIBUTE_MIN_RSSI, (enable? mMin_rssi: 0)); 734fef13c11034313585be68c32322b9a53c43a37b2Ashwin if (result < 0) { 735fef13c11034313585be68c32322b9a53c43a37b2Ashwin return result; 736fef13c11034313585be68c32322b9a53c43a37b2Ashwin } 737fef13c11034313585be68c32322b9a53c43a37b2Ashwin result = request.put_u32(RSSI_MONITOR_ATTRIBUTE_START, enable); 738fef13c11034313585be68c32322b9a53c43a37b2Ashwin if (result < 0) { 739fef13c11034313585be68c32322b9a53c43a37b2Ashwin return result; 740fef13c11034313585be68c32322b9a53c43a37b2Ashwin } 741fef13c11034313585be68c32322b9a53c43a37b2Ashwin request.attr_end(data); 742fef13c11034313585be68c32322b9a53c43a37b2Ashwin return result; 743fef13c11034313585be68c32322b9a53c43a37b2Ashwin } 744fef13c11034313585be68c32322b9a53c43a37b2Ashwin 745fef13c11034313585be68c32322b9a53c43a37b2Ashwin int start() { 746fef13c11034313585be68c32322b9a53c43a37b2Ashwin WifiRequest request(familyId(), ifaceId()); 747fef13c11034313585be68c32322b9a53c43a37b2Ashwin int result = createRequest(request, 1); 748fef13c11034313585be68c32322b9a53c43a37b2Ashwin if (result < 0) { 749fef13c11034313585be68c32322b9a53c43a37b2Ashwin return result; 750fef13c11034313585be68c32322b9a53c43a37b2Ashwin } 751fef13c11034313585be68c32322b9a53c43a37b2Ashwin result = requestResponse(request); 752fef13c11034313585be68c32322b9a53c43a37b2Ashwin if (result < 0) { 753fef13c11034313585be68c32322b9a53c43a37b2Ashwin ALOGI("Failed to set RSSI Monitor, result = %d", result); 754fef13c11034313585be68c32322b9a53c43a37b2Ashwin return result; 755fef13c11034313585be68c32322b9a53c43a37b2Ashwin } 756fef13c11034313585be68c32322b9a53c43a37b2Ashwin ALOGI("Successfully set RSSI monitoring"); 757fef13c11034313585be68c32322b9a53c43a37b2Ashwin registerVendorHandler(GOOGLE_OUI, GOOGLE_RSSI_MONITOR_EVENT); 758fef13c11034313585be68c32322b9a53c43a37b2Ashwin 759fef13c11034313585be68c32322b9a53c43a37b2Ashwin 760fef13c11034313585be68c32322b9a53c43a37b2Ashwin if (result < 0) { 761fef13c11034313585be68c32322b9a53c43a37b2Ashwin unregisterVendorHandler(GOOGLE_OUI, GOOGLE_RSSI_MONITOR_EVENT); 762fef13c11034313585be68c32322b9a53c43a37b2Ashwin return result; 763fef13c11034313585be68c32322b9a53c43a37b2Ashwin } 764fef13c11034313585be68c32322b9a53c43a37b2Ashwin ALOGI("Done!"); 765fef13c11034313585be68c32322b9a53c43a37b2Ashwin return result; 766fef13c11034313585be68c32322b9a53c43a37b2Ashwin } 767fef13c11034313585be68c32322b9a53c43a37b2Ashwin 768fef13c11034313585be68c32322b9a53c43a37b2Ashwin virtual int cancel() { 769fef13c11034313585be68c32322b9a53c43a37b2Ashwin 770fef13c11034313585be68c32322b9a53c43a37b2Ashwin WifiRequest request(familyId(), ifaceId()); 771fef13c11034313585be68c32322b9a53c43a37b2Ashwin int result = createRequest(request, 0); 772fef13c11034313585be68c32322b9a53c43a37b2Ashwin if (result != WIFI_SUCCESS) { 773fef13c11034313585be68c32322b9a53c43a37b2Ashwin ALOGE("failed to create request; result = %d", result); 774fef13c11034313585be68c32322b9a53c43a37b2Ashwin } else { 775fef13c11034313585be68c32322b9a53c43a37b2Ashwin result = requestResponse(request); 776fef13c11034313585be68c32322b9a53c43a37b2Ashwin if (result != WIFI_SUCCESS) { 777fef13c11034313585be68c32322b9a53c43a37b2Ashwin ALOGE("failed to stop RSSI monitoring = %d", result); 778fef13c11034313585be68c32322b9a53c43a37b2Ashwin } 779fef13c11034313585be68c32322b9a53c43a37b2Ashwin } 780fef13c11034313585be68c32322b9a53c43a37b2Ashwin unregisterVendorHandler(GOOGLE_OUI, GOOGLE_RSSI_MONITOR_EVENT); 781fef13c11034313585be68c32322b9a53c43a37b2Ashwin return WIFI_SUCCESS; 782fef13c11034313585be68c32322b9a53c43a37b2Ashwin } 783fef13c11034313585be68c32322b9a53c43a37b2Ashwin 784fef13c11034313585be68c32322b9a53c43a37b2Ashwin virtual int handleResponse(WifiEvent& reply) { 785fef13c11034313585be68c32322b9a53c43a37b2Ashwin /* Nothing to do on response! */ 786fef13c11034313585be68c32322b9a53c43a37b2Ashwin return NL_SKIP; 787fef13c11034313585be68c32322b9a53c43a37b2Ashwin } 788fef13c11034313585be68c32322b9a53c43a37b2Ashwin 789fef13c11034313585be68c32322b9a53c43a37b2Ashwin virtual int handleEvent(WifiEvent& event) { 790fef13c11034313585be68c32322b9a53c43a37b2Ashwin ALOGI("Got a RSSI monitor event"); 791fef13c11034313585be68c32322b9a53c43a37b2Ashwin 792fef13c11034313585be68c32322b9a53c43a37b2Ashwin nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA); 793fef13c11034313585be68c32322b9a53c43a37b2Ashwin int len = event.get_vendor_data_len(); 794fef13c11034313585be68c32322b9a53c43a37b2Ashwin 795fef13c11034313585be68c32322b9a53c43a37b2Ashwin if (vendor_data == NULL || len == 0) { 796fef13c11034313585be68c32322b9a53c43a37b2Ashwin ALOGI("RSSI monitor: No data"); 797fef13c11034313585be68c32322b9a53c43a37b2Ashwin return NL_SKIP; 798fef13c11034313585be68c32322b9a53c43a37b2Ashwin } 799fef13c11034313585be68c32322b9a53c43a37b2Ashwin /* driver<->HAL event structure */ 800fef13c11034313585be68c32322b9a53c43a37b2Ashwin #define RSSI_MONITOR_EVT_VERSION 1 801fef13c11034313585be68c32322b9a53c43a37b2Ashwin typedef struct { 802fef13c11034313585be68c32322b9a53c43a37b2Ashwin u8 version; 803fef13c11034313585be68c32322b9a53c43a37b2Ashwin s8 cur_rssi; 804fef13c11034313585be68c32322b9a53c43a37b2Ashwin mac_addr BSSID; 805fef13c11034313585be68c32322b9a53c43a37b2Ashwin } rssi_monitor_evt; 806fef13c11034313585be68c32322b9a53c43a37b2Ashwin 807fef13c11034313585be68c32322b9a53c43a37b2Ashwin rssi_monitor_evt *data = (rssi_monitor_evt *)event.get_vendor_data(); 808fef13c11034313585be68c32322b9a53c43a37b2Ashwin 809fef13c11034313585be68c32322b9a53c43a37b2Ashwin if (data->version != RSSI_MONITOR_EVT_VERSION) { 810fef13c11034313585be68c32322b9a53c43a37b2Ashwin ALOGI("Event version mismatch %d, expected %d", data->version, RSSI_MONITOR_EVT_VERSION); 811fef13c11034313585be68c32322b9a53c43a37b2Ashwin return NL_SKIP; 812fef13c11034313585be68c32322b9a53c43a37b2Ashwin } 813fef13c11034313585be68c32322b9a53c43a37b2Ashwin 814fef13c11034313585be68c32322b9a53c43a37b2Ashwin if (*mHandler.on_rssi_threshold_breached) { 815fef13c11034313585be68c32322b9a53c43a37b2Ashwin (*mHandler.on_rssi_threshold_breached)(id(), data->BSSID, data->cur_rssi); 816fef13c11034313585be68c32322b9a53c43a37b2Ashwin } else { 817fef13c11034313585be68c32322b9a53c43a37b2Ashwin ALOGW("No RSSI monitor handler registered"); 818fef13c11034313585be68c32322b9a53c43a37b2Ashwin } 819fef13c11034313585be68c32322b9a53c43a37b2Ashwin 820fef13c11034313585be68c32322b9a53c43a37b2Ashwin return NL_SKIP; 821fef13c11034313585be68c32322b9a53c43a37b2Ashwin } 822fef13c11034313585be68c32322b9a53c43a37b2Ashwin 823fef13c11034313585be68c32322b9a53c43a37b2Ashwin}; 824fef13c11034313585be68c32322b9a53c43a37b2Ashwin 825dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharmaclass AndroidPktFilterCommand : public WifiCommand { 826dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma private: 827dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma const u8* mProgram; 828dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma u32 mProgramLen; 829dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma u32* mVersion; 830dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma u32* mMaxLen; 831dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma int mReqType; 832dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma public: 833dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma AndroidPktFilterCommand(wifi_interface_handle handle, 834dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma u32* version, u32* max_len) 835dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma : WifiCommand("AndroidPktFilterCommand", handle, 0), 836dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma mVersion(version), mMaxLen(max_len), 837dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma mReqType(GET_APF_CAPABILITIES) 838dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma { 839dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma } 840dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma 841dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma AndroidPktFilterCommand(wifi_interface_handle handle, 842dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma const u8* program, u32 len) 843dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma : WifiCommand("AndroidPktFilterCommand", handle, 0), 844dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma mProgram(program), mProgramLen(len), 845dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma mReqType(SET_APF_PROGRAM) 846dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma { 847dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma } 848dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma 849dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma int createRequest(WifiRequest& request) { 850dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma if (mReqType == SET_APF_PROGRAM) { 851dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma ALOGI("\n%s: APF set program request\n", __FUNCTION__); 852dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma return createSetPktFilterRequest(request); 853dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma } else if (mReqType == GET_APF_CAPABILITIES) { 854dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma ALOGI("\n%s: APF get capabilities request\n", __FUNCTION__); 855dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma return createGetPktFilterCapabilitesRequest(request); 856dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma } else { 857dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma ALOGE("\n%s Unknown APF request\n", __FUNCTION__); 858dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma return WIFI_ERROR_NOT_SUPPORTED; 859dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma } 860dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma return WIFI_SUCCESS; 861dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma } 862dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma 863dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma int createSetPktFilterRequest(WifiRequest& request) { 864dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma u8 *program = new u8[mProgramLen]; 8656af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma NULL_CHECK_RETURN(program, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); 866dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma int result = request.create(GOOGLE_OUI, APF_SUBCMD_SET_FILTER); 867dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma if (result < 0) { 868dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma return result; 869dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma } 870dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma 871dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA); 872dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma result = request.put_u32(APF_ATTRIBUTE_PROGRAM_LEN, mProgramLen); 873dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma if (result < 0) { 874dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma return result; 875dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma } 876dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma memcpy(program, mProgram, mProgramLen); 877dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma result = request.put(APF_ATTRIBUTE_PROGRAM, program, mProgramLen); 878dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma if (result < 0) { 879dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma return result; 880dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma } 881dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma request.attr_end(data); 8826587f308b0c2d658dfe7cd988518d158cbd2f202Sreenath Sharma delete[] program; 883dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma return result; 884dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma } 885dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma 886dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma int createGetPktFilterCapabilitesRequest(WifiRequest& request) { 887dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma int result = request.create(GOOGLE_OUI, APF_SUBCMD_GET_CAPABILITIES); 888dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma if (result < 0) { 889dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma return result; 890dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma } 891dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma 892dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA); 893dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma request.attr_end(data); 894dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma return result; 895dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma } 896dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma 897dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma int start() { 898dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma WifiRequest request(familyId(), ifaceId()); 899dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma int result = createRequest(request); 900dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma if (result < 0) { 901dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma return result; 902dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma } 903dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma result = requestResponse(request); 904dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma if (result < 0) { 905dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma ALOGI("Request Response failed for APF, result = %d", result); 906dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma return result; 907dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma } 908dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma ALOGI("Done!"); 909dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma return result; 910dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma } 911dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma 912dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma int cancel() { 913dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma return WIFI_SUCCESS; 914dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma } 915dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma 916dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma int handleResponse(WifiEvent& reply) { 917dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma ALOGD("In SetAPFCommand::handleResponse"); 918dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma 919dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma if (reply.get_cmd() != NL80211_CMD_VENDOR) { 920dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma ALOGD("Ignoring reply with cmd = %d", reply.get_cmd()); 921dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma return NL_SKIP; 922dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma } 923dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma 924dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma int id = reply.get_vendor_id(); 925dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma int subcmd = reply.get_vendor_subcmd(); 926dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma 927dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA); 928dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma int len = reply.get_vendor_data_len(); 929dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma 930dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma ALOGD("Id = %0x, subcmd = %d, len = %d", id, subcmd, len); 931dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma if (vendor_data == NULL || len == 0) { 932dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma ALOGE("no vendor data in SetAPFCommand response; ignoring it"); 933dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma return NL_SKIP; 934dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma } 935dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma if( mReqType == SET_APF_PROGRAM) { 936dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma ALOGD("Response recieved for set packet filter command\n"); 937dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma } else if (mReqType == GET_APF_CAPABILITIES) { 938dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma *mVersion = 0; 939dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma *mMaxLen = 0; 940dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma ALOGD("Response recieved for get packet filter capabilities command\n"); 941dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma for (nl_iterator it(vendor_data); it.has_next(); it.next()) { 942dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma if (it.get_type() == APF_ATTRIBUTE_VERSION) { 943dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma *mVersion = it.get_u32(); 944dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma ALOGI("APF version is %d\n", *mVersion); 945dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma } else if (it.get_type() == APF_ATTRIBUTE_MAX_LEN) { 946dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma *mMaxLen = it.get_u32(); 947dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma ALOGI("APF max len is %d\n", *mMaxLen); 948dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma } else { 949dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma ALOGE("Ignoring invalid attribute type = %d, size = %d", 950dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma it.get_type(), it.get_len()); 951dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma } 952dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma } 953dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma } 954dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma return NL_OK; 955dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma } 956dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma 957dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma int handleEvent(WifiEvent& event) { 958dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma /* No Event to recieve for APF commands */ 959dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma return NL_SKIP; 960dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma } 961dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma}; 962dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma 96365f9c6fbd929be309642cdaf255e8394aad2b0caJun Limclass SetNdoffloadCommand : public WifiCommand { 96465f9c6fbd929be309642cdaf255e8394aad2b0caJun Lim 96565f9c6fbd929be309642cdaf255e8394aad2b0caJun Limprivate: 96665f9c6fbd929be309642cdaf255e8394aad2b0caJun Lim u8 mEnable; 96765f9c6fbd929be309642cdaf255e8394aad2b0caJun Limpublic: 96865f9c6fbd929be309642cdaf255e8394aad2b0caJun Lim SetNdoffloadCommand(wifi_interface_handle handle, u8 enable) 96965f9c6fbd929be309642cdaf255e8394aad2b0caJun Lim : WifiCommand("SetNdoffloadCommand", handle, 0) { 97065f9c6fbd929be309642cdaf255e8394aad2b0caJun Lim mEnable = enable; 97165f9c6fbd929be309642cdaf255e8394aad2b0caJun Lim } 97265f9c6fbd929be309642cdaf255e8394aad2b0caJun Lim virtual int create() { 97365f9c6fbd929be309642cdaf255e8394aad2b0caJun Lim int ret; 97465f9c6fbd929be309642cdaf255e8394aad2b0caJun Lim 97565f9c6fbd929be309642cdaf255e8394aad2b0caJun Lim ret = mMsg.create(GOOGLE_OUI, WIFI_SUBCMD_CONFIG_ND_OFFLOAD); 97665f9c6fbd929be309642cdaf255e8394aad2b0caJun Lim if (ret < 0) { 97765f9c6fbd929be309642cdaf255e8394aad2b0caJun Lim ALOGE("Can't create message to send to driver - %d", ret); 97865f9c6fbd929be309642cdaf255e8394aad2b0caJun Lim return ret; 97965f9c6fbd929be309642cdaf255e8394aad2b0caJun Lim } 98065f9c6fbd929be309642cdaf255e8394aad2b0caJun Lim 98165f9c6fbd929be309642cdaf255e8394aad2b0caJun Lim nlattr *data = mMsg.attr_start(NL80211_ATTR_VENDOR_DATA); 98265f9c6fbd929be309642cdaf255e8394aad2b0caJun Lim ret = mMsg.put_u8(ANDR_WIFI_ATTRIBUTE_ND_OFFLOAD_VALUE, mEnable); 98365f9c6fbd929be309642cdaf255e8394aad2b0caJun Lim if (ret < 0) { 98465f9c6fbd929be309642cdaf255e8394aad2b0caJun Lim return ret; 98565f9c6fbd929be309642cdaf255e8394aad2b0caJun Lim } 98665f9c6fbd929be309642cdaf255e8394aad2b0caJun Lim 98765f9c6fbd929be309642cdaf255e8394aad2b0caJun Lim mMsg.attr_end(data); 98865f9c6fbd929be309642cdaf255e8394aad2b0caJun Lim return WIFI_SUCCESS; 98965f9c6fbd929be309642cdaf255e8394aad2b0caJun Lim } 99065f9c6fbd929be309642cdaf255e8394aad2b0caJun Lim}; 99165f9c6fbd929be309642cdaf255e8394aad2b0caJun Lim 9929a23388d5a9f58f106169700bb179de0a4af7840Ashwinclass GetFeatureSetCommand : public WifiCommand { 9939a23388d5a9f58f106169700bb179de0a4af7840Ashwin 9949a23388d5a9f58f106169700bb179de0a4af7840Ashwinprivate: 9959a23388d5a9f58f106169700bb179de0a4af7840Ashwin int feature_type; 9969a23388d5a9f58f106169700bb179de0a4af7840Ashwin feature_set *fset; 9979a23388d5a9f58f106169700bb179de0a4af7840Ashwin feature_set *feature_matrix; 9989a23388d5a9f58f106169700bb179de0a4af7840Ashwin int *fm_size; 9999a23388d5a9f58f106169700bb179de0a4af7840Ashwin int set_size_max; 10009a23388d5a9f58f106169700bb179de0a4af7840Ashwinpublic: 10019a23388d5a9f58f106169700bb179de0a4af7840Ashwin GetFeatureSetCommand(wifi_interface_handle handle, int feature, feature_set *set, 10029a23388d5a9f58f106169700bb179de0a4af7840Ashwin feature_set set_matrix[], int *size, int max_size) 1003d4f6adc737f93d75d3a1be8427a144f907a4dde6Vinit Deshpande : WifiCommand("GetFeatureSetCommand", handle, 0) 10049a23388d5a9f58f106169700bb179de0a4af7840Ashwin { 10059a23388d5a9f58f106169700bb179de0a4af7840Ashwin feature_type = feature; 10069a23388d5a9f58f106169700bb179de0a4af7840Ashwin fset = set; 10079a23388d5a9f58f106169700bb179de0a4af7840Ashwin feature_matrix = set_matrix; 10089a23388d5a9f58f106169700bb179de0a4af7840Ashwin fm_size = size; 10099a23388d5a9f58f106169700bb179de0a4af7840Ashwin set_size_max = max_size; 10109a23388d5a9f58f106169700bb179de0a4af7840Ashwin } 10119a23388d5a9f58f106169700bb179de0a4af7840Ashwin 10129a23388d5a9f58f106169700bb179de0a4af7840Ashwin virtual int create() { 10139a23388d5a9f58f106169700bb179de0a4af7840Ashwin int ret; 10149a23388d5a9f58f106169700bb179de0a4af7840Ashwin 101565f9c6fbd929be309642cdaf255e8394aad2b0caJun Lim if(feature_type == ANDR_WIFI_ATTRIBUTE_NUM_FEATURE_SET) { 10169a23388d5a9f58f106169700bb179de0a4af7840Ashwin ret = mMsg.create(GOOGLE_OUI, WIFI_SUBCMD_GET_FEATURE_SET); 101765f9c6fbd929be309642cdaf255e8394aad2b0caJun Lim } else if (feature_type == ANDR_WIFI_ATTRIBUTE_FEATURE_SET) { 10189a23388d5a9f58f106169700bb179de0a4af7840Ashwin ret = mMsg.create(GOOGLE_OUI, WIFI_SUBCMD_GET_FEATURE_SET_MATRIX); 10199a23388d5a9f58f106169700bb179de0a4af7840Ashwin } else { 10209a23388d5a9f58f106169700bb179de0a4af7840Ashwin ALOGE("Unknown feature type %d", feature_type); 10219a23388d5a9f58f106169700bb179de0a4af7840Ashwin return -1; 10229a23388d5a9f58f106169700bb179de0a4af7840Ashwin } 10239a23388d5a9f58f106169700bb179de0a4af7840Ashwin 10249a23388d5a9f58f106169700bb179de0a4af7840Ashwin if (ret < 0) { 10259a23388d5a9f58f106169700bb179de0a4af7840Ashwin ALOGE("Can't create message to send to driver - %d", ret); 10269a23388d5a9f58f106169700bb179de0a4af7840Ashwin } 10279a23388d5a9f58f106169700bb179de0a4af7840Ashwin 10289a23388d5a9f58f106169700bb179de0a4af7840Ashwin return ret; 10299a23388d5a9f58f106169700bb179de0a4af7840Ashwin } 10309a23388d5a9f58f106169700bb179de0a4af7840Ashwin 10319a23388d5a9f58f106169700bb179de0a4af7840Ashwinprotected: 10329a23388d5a9f58f106169700bb179de0a4af7840Ashwin virtual int handleResponse(WifiEvent& reply) { 10339a23388d5a9f58f106169700bb179de0a4af7840Ashwin 1034ec74fa4fcb49a35e6af54e086e63692b37d21b02Vinit Deshpande ALOGV("In GetFeatureSetCommand::handleResponse"); 10359a23388d5a9f58f106169700bb179de0a4af7840Ashwin 10369a23388d5a9f58f106169700bb179de0a4af7840Ashwin if (reply.get_cmd() != NL80211_CMD_VENDOR) { 10379a23388d5a9f58f106169700bb179de0a4af7840Ashwin ALOGD("Ignoring reply with cmd = %d", reply.get_cmd()); 10389a23388d5a9f58f106169700bb179de0a4af7840Ashwin return NL_SKIP; 10399a23388d5a9f58f106169700bb179de0a4af7840Ashwin } 10409a23388d5a9f58f106169700bb179de0a4af7840Ashwin 10419a23388d5a9f58f106169700bb179de0a4af7840Ashwin int id = reply.get_vendor_id(); 10429a23388d5a9f58f106169700bb179de0a4af7840Ashwin int subcmd = reply.get_vendor_subcmd(); 10439a23388d5a9f58f106169700bb179de0a4af7840Ashwin 10449a23388d5a9f58f106169700bb179de0a4af7840Ashwin nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA); 10459a23388d5a9f58f106169700bb179de0a4af7840Ashwin int len = reply.get_vendor_data_len(); 10469a23388d5a9f58f106169700bb179de0a4af7840Ashwin 1047ec74fa4fcb49a35e6af54e086e63692b37d21b02Vinit Deshpande ALOGV("Id = %0x, subcmd = %d, len = %d", id, subcmd, len); 10489a23388d5a9f58f106169700bb179de0a4af7840Ashwin if (vendor_data == NULL || len == 0) { 10499a23388d5a9f58f106169700bb179de0a4af7840Ashwin ALOGE("no vendor data in GetFeatureSetCommand response; ignoring it"); 10509a23388d5a9f58f106169700bb179de0a4af7840Ashwin return NL_SKIP; 10519a23388d5a9f58f106169700bb179de0a4af7840Ashwin } 105265f9c6fbd929be309642cdaf255e8394aad2b0caJun Lim if(feature_type == ANDR_WIFI_ATTRIBUTE_NUM_FEATURE_SET) { 10539a23388d5a9f58f106169700bb179de0a4af7840Ashwin void *data = reply.get_vendor_data(); 10549a23388d5a9f58f106169700bb179de0a4af7840Ashwin if(!fset) { 10559a23388d5a9f58f106169700bb179de0a4af7840Ashwin ALOGE("Buffers pointers not set"); 10569a23388d5a9f58f106169700bb179de0a4af7840Ashwin return NL_SKIP; 10579a23388d5a9f58f106169700bb179de0a4af7840Ashwin } 10589a23388d5a9f58f106169700bb179de0a4af7840Ashwin memcpy(fset, data, min(len, (int) sizeof(*fset))); 10599a23388d5a9f58f106169700bb179de0a4af7840Ashwin } else { 10609a23388d5a9f58f106169700bb179de0a4af7840Ashwin int num_features_set = 0; 10619a23388d5a9f58f106169700bb179de0a4af7840Ashwin int i = 0; 10629a23388d5a9f58f106169700bb179de0a4af7840Ashwin 10639a23388d5a9f58f106169700bb179de0a4af7840Ashwin if(!feature_matrix || !fm_size) { 10649a23388d5a9f58f106169700bb179de0a4af7840Ashwin ALOGE("Buffers pointers not set"); 10659a23388d5a9f58f106169700bb179de0a4af7840Ashwin return NL_SKIP; 10669a23388d5a9f58f106169700bb179de0a4af7840Ashwin } 10679a23388d5a9f58f106169700bb179de0a4af7840Ashwin 10689a23388d5a9f58f106169700bb179de0a4af7840Ashwin for (nl_iterator it(vendor_data); it.has_next(); it.next()) { 10699a23388d5a9f58f106169700bb179de0a4af7840Ashwin if (it.get_type() == ANDR_WIFI_ATTRIBUTE_NUM_FEATURE_SET) { 10709a23388d5a9f58f106169700bb179de0a4af7840Ashwin num_features_set = it.get_u32(); 1071ec74fa4fcb49a35e6af54e086e63692b37d21b02Vinit Deshpande ALOGV("Got feature list with %d concurrent sets", num_features_set); 10729a23388d5a9f58f106169700bb179de0a4af7840Ashwin if(set_size_max && (num_features_set > set_size_max)) 10739a23388d5a9f58f106169700bb179de0a4af7840Ashwin num_features_set = set_size_max; 10749a23388d5a9f58f106169700bb179de0a4af7840Ashwin *fm_size = num_features_set; 10759a23388d5a9f58f106169700bb179de0a4af7840Ashwin } else if ((it.get_type() == ANDR_WIFI_ATTRIBUTE_FEATURE_SET) && 10769a23388d5a9f58f106169700bb179de0a4af7840Ashwin i < num_features_set) { 10779a23388d5a9f58f106169700bb179de0a4af7840Ashwin feature_matrix[i] = it.get_u32(); 10789a23388d5a9f58f106169700bb179de0a4af7840Ashwin i++; 10799a23388d5a9f58f106169700bb179de0a4af7840Ashwin } else { 10809a23388d5a9f58f106169700bb179de0a4af7840Ashwin ALOGW("Ignoring invalid attribute type = %d, size = %d", 10819a23388d5a9f58f106169700bb179de0a4af7840Ashwin it.get_type(), it.get_len()); 10829a23388d5a9f58f106169700bb179de0a4af7840Ashwin } 10839a23388d5a9f58f106169700bb179de0a4af7840Ashwin } 10849a23388d5a9f58f106169700bb179de0a4af7840Ashwin 10859a23388d5a9f58f106169700bb179de0a4af7840Ashwin } 10869a23388d5a9f58f106169700bb179de0a4af7840Ashwin return NL_OK; 10879a23388d5a9f58f106169700bb179de0a4af7840Ashwin } 10889a23388d5a9f58f106169700bb179de0a4af7840Ashwin 10899a23388d5a9f58f106169700bb179de0a4af7840Ashwin}; 10909a23388d5a9f58f106169700bb179de0a4af7840Ashwin 10911a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapndestatic int wifi_get_multicast_id(wifi_handle handle, const char *name, const char *group) 10921a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde{ 10931a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GetMulticastIdCommand cmd(handle, name, group); 10941a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int res = cmd.requestResponse(); 10951a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (res < 0) 10961a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return res; 10971a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde else 10981a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return cmd.getId(); 10991a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde} 11001a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 11011a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde///////////////////////////////////////////////////////////////////////// 11021a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 11031a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapndestatic bool is_wifi_interface(const char *name) 11041a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde{ 11051a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (strncmp(name, "wlan", 4) != 0 && strncmp(name, "p2p", 3) != 0) { 11061a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde /* not a wifi interface; ignore it */ 11071a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return false; 11081a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } else { 11091a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return true; 11101a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 11111a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde} 11121a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 11131a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapndestatic int get_interface(const char *name, interface_info *info) 11141a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde{ 11151a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde strcpy(info->name, name); 11161a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde info->id = if_nametoindex(name); 11171a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde // ALOGI("found an interface : %s, id = %d", name, info->id); 11181a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return WIFI_SUCCESS; 11191a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde} 11201a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 11211a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapndewifi_error wifi_init_interfaces(wifi_handle handle) 11221a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde{ 11231a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde hal_info *info = (hal_info *)handle; 11241a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 11251a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde struct dirent *de; 11261a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 11271a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde DIR *d = opendir("/sys/class/net"); 11281a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (d == 0) 11291a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return WIFI_ERROR_UNKNOWN; 11301a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 11311a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int n = 0; 11321a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde while ((de = readdir(d))) { 11331a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (de->d_name[0] == '.') 11341a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde continue; 11351a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (is_wifi_interface(de->d_name) ) { 11361a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde n++; 11371a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 11381a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 11391a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 11401a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde closedir(d); 11411a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 11421a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde d = opendir("/sys/class/net"); 11431a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (d == 0) 11441a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return WIFI_ERROR_UNKNOWN; 11451a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 11461a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde info->interfaces = (interface_info **)malloc(sizeof(interface_info *) * n); 11471a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 11481a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int i = 0; 11491a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde while ((de = readdir(d))) { 11501a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (de->d_name[0] == '.') 11511a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde continue; 11521a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (is_wifi_interface(de->d_name)) { 11531a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde interface_info *ifinfo = (interface_info *)malloc(sizeof(interface_info)); 11541a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (get_interface(de->d_name, ifinfo) != WIFI_SUCCESS) { 11551a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde free(ifinfo); 11561a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde continue; 11571a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 11581a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ifinfo->handle = handle; 11591a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde info->interfaces[i] = ifinfo; 11601a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde i++; 11611a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 11621a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 11631a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 11641a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde closedir(d); 11651a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 11661a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde info->num_interfaces = n; 11671a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return WIFI_SUCCESS; 11681a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde} 11691a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 11701a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapndewifi_error wifi_get_ifaces(wifi_handle handle, int *num, wifi_interface_handle **interfaces) 11711a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde{ 11721a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde hal_info *info = (hal_info *)handle; 11731a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 11741a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde *interfaces = (wifi_interface_handle *)info->interfaces; 11751a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde *num = info->num_interfaces; 11761a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 11771a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return WIFI_SUCCESS; 11781a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde} 11791a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 11801a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapndewifi_error wifi_get_iface_name(wifi_interface_handle handle, char *name, size_t size) 11811a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde{ 11821a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde interface_info *info = (interface_info *)handle; 11831a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde strcpy(name, info->name); 11841a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return WIFI_SUCCESS; 11851a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde} 11861a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 11879a23388d5a9f58f106169700bb179de0a4af7840Ashwinwifi_error wifi_get_supported_feature_set(wifi_interface_handle handle, feature_set *set) 11889a23388d5a9f58f106169700bb179de0a4af7840Ashwin{ 118965f9c6fbd929be309642cdaf255e8394aad2b0caJun Lim GetFeatureSetCommand command(handle, ANDR_WIFI_ATTRIBUTE_NUM_FEATURE_SET, set, NULL, NULL, 1); 11909a23388d5a9f58f106169700bb179de0a4af7840Ashwin return (wifi_error) command.requestResponse(); 11919a23388d5a9f58f106169700bb179de0a4af7840Ashwin} 11929a23388d5a9f58f106169700bb179de0a4af7840Ashwin 11939a23388d5a9f58f106169700bb179de0a4af7840Ashwinwifi_error wifi_get_concurrency_matrix(wifi_interface_handle handle, int set_size_max, 11949a23388d5a9f58f106169700bb179de0a4af7840Ashwin feature_set set[], int *set_size) 11959a23388d5a9f58f106169700bb179de0a4af7840Ashwin{ 119665f9c6fbd929be309642cdaf255e8394aad2b0caJun Lim GetFeatureSetCommand command(handle, ANDR_WIFI_ATTRIBUTE_FEATURE_SET, NULL, 119765f9c6fbd929be309642cdaf255e8394aad2b0caJun Lim set, set_size, set_size_max); 11989a23388d5a9f58f106169700bb179de0a4af7840Ashwin return (wifi_error) command.requestResponse(); 11999a23388d5a9f58f106169700bb179de0a4af7840Ashwin} 12009a23388d5a9f58f106169700bb179de0a4af7840Ashwin 1201f0d5070a931327e6356d765478069b9e66452a5bAshwinwifi_error wifi_set_scanning_mac_oui(wifi_interface_handle handle, oui scan_oui) 1202f0d5070a931327e6356d765478069b9e66452a5bAshwin{ 1203f0d5070a931327e6356d765478069b9e66452a5bAshwin SetPnoMacAddrOuiCommand command(handle, scan_oui); 1204f0d5070a931327e6356d765478069b9e66452a5bAshwin return (wifi_error)command.start(); 1205f0d5070a931327e6356d765478069b9e66452a5bAshwin 1206f0d5070a931327e6356d765478069b9e66452a5bAshwin} 1207f0d5070a931327e6356d765478069b9e66452a5bAshwin 1208b4ac10a4e1eddf00ddad32f3307cc050bb4e0963Dmitry Shmidtwifi_error wifi_set_nodfs_flag(wifi_interface_handle handle, u32 nodfs) 1209b4ac10a4e1eddf00ddad32f3307cc050bb4e0963Dmitry Shmidt{ 1210b4ac10a4e1eddf00ddad32f3307cc050bb4e0963Dmitry Shmidt SetNodfsCommand command(handle, nodfs); 1211b4ac10a4e1eddf00ddad32f3307cc050bb4e0963Dmitry Shmidt return (wifi_error) command.requestResponse(); 1212b4ac10a4e1eddf00ddad32f3307cc050bb4e0963Dmitry Shmidt} 12131a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 1214c02e00563882d87ab29822c43097cbb1ce04b55dxinhewifi_error wifi_set_country_code(wifi_interface_handle handle, const char *country_code) 1215c02e00563882d87ab29822c43097cbb1ce04b55dxinhe{ 1216c02e00563882d87ab29822c43097cbb1ce04b55dxinhe SetCountryCodeCommand command(handle, country_code); 1217c02e00563882d87ab29822c43097cbb1ce04b55dxinhe return (wifi_error) command.requestResponse(); 1218c02e00563882d87ab29822c43097cbb1ce04b55dxinhe} 1219c02e00563882d87ab29822c43097cbb1ce04b55dxinhe 1220fef13c11034313585be68c32322b9a53c43a37b2Ashwinstatic wifi_error wifi_start_rssi_monitoring(wifi_request_id id, wifi_interface_handle 1221fef13c11034313585be68c32322b9a53c43a37b2Ashwin iface, s8 max_rssi, s8 min_rssi, wifi_rssi_event_handler eh) 1222fef13c11034313585be68c32322b9a53c43a37b2Ashwin{ 1223fef13c11034313585be68c32322b9a53c43a37b2Ashwin ALOGD("Start RSSI monitor %d", id); 1224fef13c11034313585be68c32322b9a53c43a37b2Ashwin wifi_handle handle = getWifiHandle(iface); 1225fef13c11034313585be68c32322b9a53c43a37b2Ashwin SetRSSIMonitorCommand *cmd = new SetRSSIMonitorCommand(id, iface, max_rssi, min_rssi, eh); 12266af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); 12276af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma wifi_error result = wifi_register_cmd(handle, id, cmd); 12286af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma if (result != WIFI_SUCCESS) { 12296af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma cmd->releaseRef(); 12306af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma return result; 12316af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma } 12326af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma result = (wifi_error)cmd->start(); 1233340c22b114039948cbdc124797fd84d58a80462cAshwin if (result != WIFI_SUCCESS) { 1234340c22b114039948cbdc124797fd84d58a80462cAshwin wifi_unregister_cmd(handle, id); 12356af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma cmd->releaseRef(); 12366af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma return result; 1237340c22b114039948cbdc124797fd84d58a80462cAshwin } 1238340c22b114039948cbdc124797fd84d58a80462cAshwin return result; 1239fef13c11034313585be68c32322b9a53c43a37b2Ashwin} 1240fef13c11034313585be68c32322b9a53c43a37b2Ashwin 1241fef13c11034313585be68c32322b9a53c43a37b2Ashwinstatic wifi_error wifi_stop_rssi_monitoring(wifi_request_id id, wifi_interface_handle iface) 1242fef13c11034313585be68c32322b9a53c43a37b2Ashwin{ 1243fef13c11034313585be68c32322b9a53c43a37b2Ashwin ALOGD("Stopping RSSI monitor"); 1244fef13c11034313585be68c32322b9a53c43a37b2Ashwin 1245fef13c11034313585be68c32322b9a53c43a37b2Ashwin if(id == -1) { 1246fef13c11034313585be68c32322b9a53c43a37b2Ashwin wifi_rssi_event_handler handler; 1247fef13c11034313585be68c32322b9a53c43a37b2Ashwin s8 max_rssi = 0, min_rssi = 0; 1248fef13c11034313585be68c32322b9a53c43a37b2Ashwin wifi_handle handle = getWifiHandle(iface); 1249fef13c11034313585be68c32322b9a53c43a37b2Ashwin memset(&handler, 0, sizeof(handler)); 1250fef13c11034313585be68c32322b9a53c43a37b2Ashwin SetRSSIMonitorCommand *cmd = new SetRSSIMonitorCommand(id, iface, 1251fef13c11034313585be68c32322b9a53c43a37b2Ashwin max_rssi, min_rssi, handler); 12526af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); 1253fef13c11034313585be68c32322b9a53c43a37b2Ashwin cmd->cancel(); 1254fef13c11034313585be68c32322b9a53c43a37b2Ashwin cmd->releaseRef(); 1255fef13c11034313585be68c32322b9a53c43a37b2Ashwin return WIFI_SUCCESS; 1256fef13c11034313585be68c32322b9a53c43a37b2Ashwin } 1257fef13c11034313585be68c32322b9a53c43a37b2Ashwin return wifi_cancel_cmd(id, iface); 1258fef13c11034313585be68c32322b9a53c43a37b2Ashwin} 1259fef13c11034313585be68c32322b9a53c43a37b2Ashwin 1260dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharmastatic wifi_error wifi_get_packet_filter_capabilities(wifi_interface_handle handle, 1261dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma u32 *version, u32 *max_len) 1262dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma{ 1263dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma ALOGD("Getting APF capabilities, halHandle = %p\n", handle); 1264dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma AndroidPktFilterCommand *cmd = new AndroidPktFilterCommand(handle, version, max_len); 12656af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); 12666af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma wifi_error result = (wifi_error)cmd->start(); 12676af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma if (result == WIFI_SUCCESS) { 1268dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma ALOGD("Getting APF capability, version = %d, max_len = %d\n", *version, *max_len); 1269dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma } 12706af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma cmd->releaseRef(); 12716af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma return result; 1272dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma} 1273dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma 1274dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharmastatic wifi_error wifi_set_packet_filter(wifi_interface_handle handle, 1275dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma const u8 *program, u32 len) 1276dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma{ 1277dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma ALOGD("Setting APF program, halHandle = %p\n", handle); 1278dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma AndroidPktFilterCommand *cmd = new AndroidPktFilterCommand(handle, program, len); 12796af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); 12806af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma wifi_error result = (wifi_error)cmd->start(); 12816af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma cmd->releaseRef(); 12826af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma return result; 1283dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma} 1284dfe5b594561312993f587dc29e524d400e8fbc77Sreenath Sharma 128565f9c6fbd929be309642cdaf255e8394aad2b0caJun Limstatic wifi_error wifi_configure_nd_offload(wifi_interface_handle handle, u8 enable) 128665f9c6fbd929be309642cdaf255e8394aad2b0caJun Lim{ 128765f9c6fbd929be309642cdaf255e8394aad2b0caJun Lim SetNdoffloadCommand command(handle, enable); 128865f9c6fbd929be309642cdaf255e8394aad2b0caJun Lim return (wifi_error) command.requestResponse(); 128965f9c6fbd929be309642cdaf255e8394aad2b0caJun Lim} 129065f9c6fbd929be309642cdaf255e8394aad2b0caJun Lim 1291b4ac10a4e1eddf00ddad32f3307cc050bb4e0963Dmitry Shmidt///////////////////////////////////////////////////////////////////////////// 1292