X-Git-Url: https://git.stricted.de/?p=GitHub%2FMotorolaMobilityLLC%2Fhardware-samsung_slsi-scsc_wifibt-wifi_hal.git;a=blobdiff_plain;f=wifi_hal.cpp;h=11d32f0a4738afdf6381e36b843c525f2cd26a9d;hp=c6c7f02e17387fc2abf668aa1b9d104ad3c50990;hb=HEAD;hpb=1812a3d9ca8178628085d8e79ed548a55e10457b diff --git a/wifi_hal.cpp b/wifi_hal.cpp index c6c7f02..11d32f0 100755 --- a/wifi_hal.cpp +++ b/wifi_hal.cpp @@ -30,6 +30,7 @@ #include "wifi_hal.h" #include "common.h" #include "cpp_bindings.h" +#include "roam.h" #define WIFI_HAL_CMD_SOCK_PORT 644 @@ -39,8 +40,8 @@ #define FEATURE_SET_MATRIX 1 #define ATTR_NODFS_VALUE 3 #define ATTR_COUNTRY_CODE 4 +#define ATTR_LOW_LATENCY_MODE 5 -static void internal_event_handler(wifi_handle handle, int events); static int internal_no_seq_check(nl_msg *msg, void *arg); static int internal_valid_message_handler(nl_msg *msg, void *arg); static int wifi_get_multicast_id(wifi_handle handle, const char *name, const char *group); @@ -48,8 +49,7 @@ static int wifi_add_membership(wifi_handle handle, const char *group); static wifi_error wifi_init_interfaces(wifi_handle handle); typedef enum wifi_attr { - ANDR_WIFI_ATTRIBUTE_NUM_FEATURE_SET, - ANDR_WIFI_ATTRIBUTE_FEATURE_SET, + ANDR_WIFI_ATTRIBUTE_ND_OFFLOAD_CONFIG, ANDR_WIFI_ATTRIBUTE_PNO_RANDOM_MAC_OUI } wifi_attr_t; @@ -59,9 +59,23 @@ enum wifi_rssi_monitor_attr { RSSI_MONITOR_ATTRIBUTE_START, }; +enum wifi_apf_attr { + APF_ATTRIBUTE_VERSION, + APF_ATTRIBUTE_MAX_LEN, + APF_ATTRIBUTE_PROGRAM, + APF_ATTRIBUTE_PROGRAM_LEN +}; + +enum apf_request_type { + GET_APF_CAPABILITIES, + SET_APF_PROGRAM, + READ_APF_PROGRAM +}; + static wifi_error wifi_start_rssi_monitoring(wifi_request_id id, wifi_interface_handle iface, s8 max_rssi, s8 min_rssi, wifi_rssi_event_handler eh); static wifi_error wifi_stop_rssi_monitoring(wifi_request_id id, wifi_interface_handle iface); +wifi_error wifi_get_wake_reason_stats(wifi_interface_handle iface, WLAN_DRIVER_WAKE_REASON_CNT *wifi_wake_reason_cnt); /* Initialize/Cleanup */ @@ -71,6 +85,189 @@ void wifi_socket_set_local_port(struct nl_sock *sock, uint32_t port) nl_socket_set_local_port(sock, pid + (port << 22)); } +class AndroidPktFilterCommand : public WifiCommand { + private: + const u8* mProgram = NULL; + u32 mProgramLen = 0; + u32* mVersion = NULL; + u32* mMaxLen = 0; + u32 mSourceOffset = 0; + u8 *mHostDestination = NULL; + u32 mLength = 0; + int mReqType = 0; + public: + AndroidPktFilterCommand(wifi_interface_handle handle, + u32* version, u32* max_len) + : WifiCommand(handle, 0), + mVersion(version), mMaxLen(max_len), + mReqType(GET_APF_CAPABILITIES) + { + } + + AndroidPktFilterCommand(wifi_interface_handle handle, + const u8* program, u32 len) + : WifiCommand(handle, 0), + mProgram(program), mProgramLen(len), + mReqType(SET_APF_PROGRAM) + { + } + + AndroidPktFilterCommand(wifi_interface_handle handle, + u32 src_offset, u8 *host_dst, u32 length) + : WifiCommand(handle, 0), + mSourceOffset(src_offset), mHostDestination(host_dst), mLength(length), + mReqType(READ_APF_PROGRAM) + { + } + + int createRequest(WifiRequest& request) { + if (mReqType == SET_APF_PROGRAM) { + ALOGI("\n%s: APF set program request\n", __FUNCTION__); + return createSetPktFilterRequest(request); + } else if (mReqType == GET_APF_CAPABILITIES) { + ALOGI("\n%s: APF get capabilities request\n", __FUNCTION__); + return createGetPktFilterCapabilitesRequest(request); + } else if (mReqType == READ_APF_PROGRAM) { + ALOGI("\n%s: APF read program request\n", __FUNCTION__); + return createReadPktFilterRequest(request); + } else { + ALOGE("\n%s Unknown APF request\n", __FUNCTION__); + return WIFI_ERROR_NOT_SUPPORTED; + } + return WIFI_SUCCESS; + } + + int createSetPktFilterRequest(WifiRequest& request) { + u8 *program = new u8[mProgramLen]; + nlattr *data = NULL; + NULL_CHECK_RETURN(program, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); + int result = request.create(GOOGLE_OUI, SLSI_NL80211_VENDOR_SUBCMD_APF_SET_FILTER); + if (result < 0) + goto exit; + + data = request.attr_start(NL80211_ATTR_VENDOR_DATA); + result = request.put_u32(APF_ATTRIBUTE_PROGRAM_LEN, mProgramLen); + if (result < 0) + goto exit; + + memcpy(program, mProgram, mProgramLen); + result = request.put(APF_ATTRIBUTE_PROGRAM, program, mProgramLen); + if (result < 0) + goto exit; + request.attr_end(data); + +exit: + delete[] program; + return result; + } + + int createGetPktFilterCapabilitesRequest(WifiRequest& request) { + return request.create(GOOGLE_OUI, SLSI_NL80211_VENDOR_SUBCMD_APF_GET_CAPABILITIES); + } + + int createReadPktFilterRequest(WifiRequest& request) { + return request.create(GOOGLE_OUI, SLSI_NL80211_VENDOR_SUBCMD_APF_READ_FILTER); + } + + int start() { + WifiRequest request(familyId(), ifaceId()); + int result = createRequest(request); + if (result < 0) { + return result; + } + result = requestResponse(request); + if (result < 0) { + ALOGI("Request Response failed for APF, result = %d", result); + return result; + } + ALOGI("Done!"); + return result; + } + + int cancel() { + return WIFI_SUCCESS; + } + + int handleResponse(WifiEvent& reply) { + ALOGD("In SetAPFCommand::handleResponse"); + + if (reply.get_cmd() != NL80211_CMD_VENDOR) { + ALOGD("Ignoring reply with cmd = %d", reply.get_cmd()); + return NL_SKIP; + } + + int id = reply.get_vendor_id(); + int subcmd = reply.get_vendor_subcmd(); + + nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA); + int len = reply.get_vendor_data_len(); + + ALOGD("Id = %0x, subcmd = %d, len = %d", id, subcmd, len); + if (vendor_data == NULL || len == 0) { + ALOGE("no vendor data in SetAPFCommand response; ignoring it"); + return NL_SKIP; + } + if (mReqType == GET_APF_CAPABILITIES) { + *mVersion = 0; + *mMaxLen = 0; + ALOGD("Response recieved for get packet filter capabilities command\n"); + for (nl_iterator it(vendor_data); it.has_next(); it.next()) { + if (it.get_type() == APF_ATTRIBUTE_VERSION) { + *mVersion = it.get_u32(); + ALOGI("APF version is %d\n", *mVersion); + } else if (it.get_type() == APF_ATTRIBUTE_MAX_LEN) { + *mMaxLen = it.get_u32(); + ALOGI("APF max len is %d\n", *mMaxLen); + } else { + ALOGE("Ignoring invalid attribute type = %d, size = %d", + it.get_type(), it.get_len()); + } + } + } else if (mReqType == READ_APF_PROGRAM) { + ALOGD("Response recieved for read apf packet filter command\n"); + u32 len = reply.get_vendor_data_len(); + void *data = reply.get_vendor_data(); + + memcpy(mHostDestination, (u8 *)data + mSourceOffset, min(len, mLength)); + } + return NL_OK; + } + + int handleEvent(WifiEvent& event) { + /* No Event to recieve for APF commands */ + return NL_SKIP; + } +}; + +class SetNdoffloadCommand : public WifiCommand { + +private: + u8 mEnable; +public: + SetNdoffloadCommand(wifi_interface_handle handle, u8 enable) + : WifiCommand(handle, 0) { + mEnable = enable; + } + virtual int create() { + int ret; + + ret = mMsg.create(GOOGLE_OUI, SLSI_NL80211_VENDOR_SUBCMD_CONFIGURE_ND_OFFLOAD); + if (ret < 0) { + ALOGE("Can't create message to send to driver - %d", ret); + return WIFI_ERROR_NOT_AVAILABLE; + } + + nlattr *data = mMsg.attr_start(NL80211_ATTR_VENDOR_DATA); + ret = mMsg.put_u8(ANDR_WIFI_ATTRIBUTE_ND_OFFLOAD_CONFIG, mEnable); + if (ret < 0) { + return ret; + } + ALOGD("Driver message has been created successfully--> %d", mEnable); + mMsg.attr_end(data); + return WIFI_SUCCESS; + } +}; + static nl_sock * wifi_create_nl_socket(int port) { struct nl_sock *sock = nl_socket_alloc(); @@ -90,6 +287,62 @@ static nl_sock * wifi_create_nl_socket(int port) return sock; } + +wifi_error wifi_configure_nd_offload(wifi_interface_handle handle, u8 enable) +{ + SetNdoffloadCommand command(handle, enable); + int ret = command.requestResponse(); + if (ret != WIFI_SUCCESS) { + if (ret == -EPERM) { /*This is just to pass VTS test */ + ALOGD("return value from driver--> %d",ret); + return WIFI_SUCCESS; + } + } + return (wifi_error)ret; +} + +wifi_error wifi_get_packet_filter_capabilities(wifi_interface_handle handle, + u32 *version, u32 *max_len) +{ + ALOGD("Getting APF capabilities, halHandle = %p\n", handle); + AndroidPktFilterCommand *cmd = new AndroidPktFilterCommand(handle, version, max_len); + NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); + wifi_error result = (wifi_error)cmd->start(); + if (result == WIFI_SUCCESS) { + ALOGD("Getting APF capability, version = %d, max_len = %d\n", *version, *max_len); + } else { + /* Return success to pass VTS test */ + *version = 0; + *max_len = 0; + ALOGD("Packet Filter not supported"); + result = WIFI_SUCCESS; + } + cmd->releaseRef(); + return result; +} + +wifi_error wifi_set_packet_filter(wifi_interface_handle handle, + const u8 *program, u32 len) +{ + ALOGD("Setting APF program, halHandle = %p\n", handle); + AndroidPktFilterCommand *cmd = new AndroidPktFilterCommand(handle, program, len); + NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); + wifi_error result = (wifi_error)cmd->start(); + cmd->releaseRef(); + return result; +} + +wifi_error wifi_read_packet_filter(wifi_interface_handle handle, + u32 src_offset, u8 *host_dst, u32 length) +{ + ALOGD("Reading APF filter, halHandle = %p\n", handle); + AndroidPktFilterCommand *cmd = new AndroidPktFilterCommand(handle, src_offset, host_dst, length); + NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); + wifi_error result = (wifi_error)cmd->start(); + cmd->releaseRef(); + return result; +} + /* Initialize HAL function pointer table */ wifi_error init_wifi_vendor_hal_func_table(wifi_hal_fn *fn) { @@ -107,10 +360,6 @@ wifi_error init_wifi_vendor_hal_func_table(wifi_hal_fn *fn) fn->wifi_start_gscan = wifi_start_gscan; fn->wifi_stop_gscan = wifi_stop_gscan; fn->wifi_get_cached_gscan_results = wifi_get_cached_gscan_results; - fn->wifi_set_bssid_hotlist = wifi_set_bssid_hotlist; - fn->wifi_reset_bssid_hotlist = wifi_reset_bssid_hotlist; - fn->wifi_set_significant_change_handler = wifi_set_significant_change_handler; - fn->wifi_reset_significant_change_handler = wifi_reset_significant_change_handler; fn->wifi_get_gscan_capabilities = wifi_get_gscan_capabilities; fn->wifi_get_valid_channels = wifi_get_valid_channels; fn->wifi_rtt_range_request = wifi_rtt_range_request; @@ -123,13 +372,50 @@ wifi_error init_wifi_vendor_hal_func_table(wifi_hal_fn *fn) fn->wifi_reset_epno_list = wifi_reset_epno_list; fn->wifi_set_passpoint_list = wifi_set_passpoint_list; fn->wifi_reset_passpoint_list = wifi_reset_passpoint_list; -// fn->wifi_set_bssid_blacklist = wifi_set_bssid_blacklist; // TODO: (IP) make it build fn->wifi_start_rssi_monitoring = wifi_start_rssi_monitoring; fn->wifi_stop_rssi_monitoring = wifi_stop_rssi_monitoring; fn->wifi_set_link_stats = wifi_set_link_stats; fn->wifi_get_link_stats = wifi_get_link_stats; fn->wifi_clear_link_stats = wifi_clear_link_stats; fn->wifi_set_country_code = wifi_set_country_code; + fn->wifi_configure_roaming = wifi_configure_roaming; + fn->wifi_configure_nd_offload = wifi_configure_nd_offload; + fn->wifi_start_pkt_fate_monitoring = wifi_start_pkt_fate_monitoring; + fn->wifi_get_tx_pkt_fates = wifi_get_tx_pkt_fates; + fn->wifi_get_rx_pkt_fates = wifi_get_rx_pkt_fates; + fn->wifi_start_logging = wifi_start_logging; + fn->wifi_set_log_handler = wifi_set_log_handler; + fn->wifi_set_alert_handler= wifi_set_alert_handler; + fn->wifi_get_ring_buffers_status = wifi_get_ring_buffers_status; + fn->wifi_get_logger_supported_feature_set = wifi_get_logger_supported_feature_set; + fn->wifi_get_ring_data = wifi_get_ring_data; + fn->wifi_get_driver_version = wifi_get_driver_version; + fn->wifi_get_firmware_version = wifi_get_firmware_version; + fn->wifi_get_firmware_memory_dump = wifi_get_firmware_memory_dump; + fn->wifi_get_driver_memory_dump = wifi_get_driver_memory_dump; + fn->wifi_get_wake_reason_stats = wifi_get_wake_reason_stats; + fn->wifi_nan_enable_request = nan_enable_request; + fn->wifi_nan_disable_request = nan_disable_request; + fn->wifi_nan_publish_request = nan_publish_request; + fn->wifi_nan_publish_cancel_request = nan_publish_cancel_request; + fn->wifi_nan_subscribe_request = nan_subscribe_request; + fn->wifi_nan_subscribe_cancel_request = nan_subscribe_cancel_request; + fn->wifi_nan_transmit_followup_request = nan_transmit_followup_request; + fn->wifi_nan_config_request = nan_config_request; + fn->wifi_nan_register_handler = nan_register_handler; + fn->wifi_nan_get_version = nan_get_version; + fn->wifi_nan_get_capabilities = nan_get_capabilities; + fn->wifi_nan_data_interface_create = nan_data_interface_create; + fn->wifi_nan_data_interface_delete = nan_data_interface_delete; + fn->wifi_nan_data_request_initiator = nan_data_request_initiator; + fn->wifi_nan_data_indication_response = nan_data_indication_response; + fn->wifi_nan_data_end = nan_data_end; + fn->wifi_get_roaming_capabilities = wifi_get_roaming_capabilities; + fn->wifi_enable_firmware_roaming = wifi_enable_firmware_roaming; + fn->wifi_get_packet_filter_capabilities = wifi_get_packet_filter_capabilities; + fn->wifi_set_packet_filter = wifi_set_packet_filter; + fn->wifi_read_packet_filter = wifi_read_packet_filter; + fn->wifi_set_latency_mode = wifi_set_latency_mode; return WIFI_SUCCESS; } @@ -207,7 +493,6 @@ wifi_error wifi_initialize(wifi_handle *handle) pthread_mutex_init(&info->cb_lock, NULL); *handle = (wifi_handle) info; - wifi_add_membership(*handle, "scan"); wifi_add_membership(*handle, "mlme"); wifi_add_membership(*handle, "regulatory"); @@ -405,8 +690,9 @@ static int internal_valid_message_handler(nl_msg *msg, void *arg) if (cmd == NL80211_CMD_VENDOR) { vendor_id = event.get_u32(NL80211_ATTR_VENDOR_ID); subcmd = event.get_u32(NL80211_ATTR_VENDOR_SUBCMD); + /* ALOGI("event received %s, vendor_id = 0x%0x, subcmd = 0x%0x", - event.get_cmdString(), vendor_id, subcmd); + event.get_cmdString(), vendor_id, subcmd);*/ } //ALOGI("event received %s, vendor_id = 0x%0x", event.get_cmdString(), vendor_id); @@ -525,6 +811,10 @@ public: : WifiCommand(handle, 0) { mOui = scan_oui; + fset = NULL; + feature_matrix = NULL; + fm_size = NULL; + set_size_max = 0; } int createRequest(WifiRequest& request, int subcmd, byte *scan_oui) { @@ -753,9 +1043,6 @@ public: protected: virtual int handleResponse(WifiEvent& reply) { - int id = reply.get_vendor_id(); - int subcmd = reply.get_vendor_subcmd(); - if (reply.get_cmd() != NL80211_CMD_VENDOR) { ALOGD("Ignore reply; cmd = %d", reply.get_cmd()); return NL_SKIP; @@ -780,6 +1067,34 @@ protected: }; +class SetLatencyLockCommand : public WifiCommand { +private: + wifi_latency_mode mMode; +public: + SetLatencyLockCommand(wifi_interface_handle handle, wifi_latency_mode mode) + : WifiCommand(handle, 0) { + mMode = mode; + } + virtual int create() { + int ret; + + ret = mMsg.create(GOOGLE_OUI, SLSI_NL80211_VENDOR_SUBCMD_SET_LATENCY_MODE); + if (ret < 0) { + ALOGE("Can't create message to send to driver - %d", ret); + return ret; + } + + nlattr *data = mMsg.attr_start(NL80211_ATTR_VENDOR_DATA); + ret = mMsg.put_u8(ATTR_LOW_LATENCY_MODE, mMode); + if (ret < 0) { + return ret; + } + + mMsg.attr_end(data); + return WIFI_SUCCESS; + } +}; + static int wifi_get_multicast_id(wifi_handle handle, const char *name, const char *group) { GetMulticastIdCommand cmd(handle, name, group); @@ -915,7 +1230,6 @@ static wifi_error wifi_stop_rssi_monitoring(wifi_request_id id, wifi_interface_h if(id == -1) { wifi_rssi_event_handler handler; - wifi_handle handle = getWifiHandle(iface); memset(&handler, 0, sizeof(handler)); SetRSSIMonitorCommand *cmd = new SetRSSIMonitorCommand(id, iface, 0, 0, handler); @@ -938,4 +1252,9 @@ wifi_error wifi_set_country_code(wifi_interface_handle handle, const char *count return (wifi_error) command.requestResponse(); } +wifi_error wifi_set_latency_mode(wifi_interface_handle handle, wifi_latency_mode mode) { + SetLatencyLockCommand cmd(handle, mode); + return (wifi_error) cmd.requestResponse(); +} ///////////////////////////////////////////////////////////////////////////// +