diff options
author | Ricardo Cerqueira <ricardo@cyngn.com> | 2015-11-05 00:45:58 +0000 |
---|---|---|
committer | Ricardo Cerqueira <ricardo@cyngn.com> | 2015-11-05 00:45:58 +0000 |
commit | 6695cb542f99c7acc99ac84601885348b717f2d0 (patch) | |
tree | 1217d27a7671efd5c86e4bc1124d5845c9193b2e | |
parent | 7dd9c55e31d965edcb40c95ddafe2b8dfcbbe23a (diff) | |
parent | 9437baca50d636f2f88f09e36dd4669e1bd4828a (diff) | |
download | android_hardware_qcom_wlan-stable/cm-13.0-ZNH0E.tar.gz android_hardware_qcom_wlan-stable/cm-13.0-ZNH0E.tar.bz2 android_hardware_qcom_wlan-stable/cm-13.0-ZNH0E.zip |
Merge tag 'android-6.0.0_r26' into cm-13.0stable/cm-13.0-ZNH0E
Android 6.0.0 release 26
30 files changed, 2012 insertions, 875 deletions
diff --git a/qcwcn/wifi_hal/Android.mk b/qcwcn/wifi_hal/Android.mk index 816e018..14676ff 100644 --- a/qcwcn/wifi_hal/Android.mk +++ b/qcwcn/wifi_hal/Android.mk @@ -19,6 +19,7 @@ LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_CFLAGS := -Wno-unused-parameter +LOCAL_CFLAGS += -DNAN_2_0 # gscan.cpp: address of array 'cached_results[i].results' will always evaluate to 'true' LOCAL_CLANG_CFLAGS := -Wno-pointer-bool-conversion diff --git a/qcwcn/wifi_hal/common.cpp b/qcwcn/wifi_hal/common.cpp index 9d9e71a..a8f5e30 100644 --- a/qcwcn/wifi_hal/common.cpp +++ b/qcwcn/wifi_hal/common.cpp @@ -18,6 +18,7 @@ #include <linux/pkt_sched.h> #include <netlink/object-api.h> #include <netlink-types.h> +#include <dlfcn.h> #include "wifi_hal.h" #include "common.h" @@ -67,7 +68,8 @@ wifi_error wifi_register_handler(wifi_handle handle, int cmd, nl_recvmsg_msg_cb_ info->event_cb[i].cb_func = func; ALOGI("Updated event handler %p for nl_cmd 0x%0x" " and arg %p", func, cmd, arg); - result = WIFI_SUCCESS; + pthread_mutex_unlock(&info->cb_lock); + return WIFI_SUCCESS; } } @@ -79,7 +81,7 @@ wifi_error wifi_register_handler(wifi_handle handle, int cmd, nl_recvmsg_msg_cb_ info->event_cb[info->num_event_cb].cb_arg = arg; info->num_event_cb++; ALOGI("Successfully added event handler %p for command %d", func, cmd); - result = WIFI_SUCCESS; + result = WIFI_SUCCESS; } else { result = WIFI_ERROR_OUT_OF_MEMORY; } @@ -105,7 +107,8 @@ wifi_error wifi_register_vendor_handler(wifi_handle handle, info->event_cb[i].cb_arg = arg; ALOGI("Updated event handler %p for vendor 0x%0x, subcmd 0x%0x" " and arg %p", func, id, subcmd, arg); - result = WIFI_SUCCESS; + pthread_mutex_unlock(&info->cb_lock); + return WIFI_SUCCESS; } } @@ -267,3 +270,189 @@ void hexdump(void *buf, u16 len) #ifdef __cplusplus } #endif /* __cplusplus */ + +/* Pointer to the table of LOWI callback funcs */ +lowi_cb_table_t *LowiWifiHalApi = NULL; +/* LowiSupportedCapabilities read */ +u32 lowiSupportedCapabilities = 0; + +int compareLowiVersion(u16 major, u16 minor, u16 micro) +{ + u32 currVersion = 0x10000*(WIFIHAL_LOWI_MAJOR_VERSION) + \ + 0x100*(WIFIHAL_LOWI_MINOR_VERSION) + \ + WIFIHAL_LOWI_MICRO_VERSION; + + u32 lowiVersion = 0x10000*(major) + \ + 0x100*(minor) + \ + micro; + + return (memcmp(&currVersion, &lowiVersion, sizeof(u32))); +} + +/* + * This function will open the lowi shared library and obtain the + * Lowi Callback table and the capabilities supported. + * A version check is also performed in this function and if the version + * check fails then the callback table returned will be NULL. + */ +wifi_error fetchLowiCbTableAndCapabilities(lowi_cb_table_t **lowi_wifihal_api, + bool *lowi_get_capa_supported) +{ + getCbTable_t* lowiCbTable = NULL; + int ret = 0; + wifi_error retVal = WIFI_SUCCESS; + + *lowi_wifihal_api = NULL; + *lowi_get_capa_supported = false; + +#if __WORDSIZE == 64 + void* lowi_handle = dlopen("/vendor/lib64/liblowi_wifihal.so", RTLD_NOW); +#else + void* lowi_handle = dlopen("/vendor/lib/liblowi_wifihal.so", RTLD_NOW); +#endif + if (!lowi_handle) { + ALOGE("%s: NULL lowi_handle, err: %s", __FUNCTION__, dlerror()); + return WIFI_ERROR_UNKNOWN; + } + + lowiCbTable = (getCbTable_t*)dlsym(lowi_handle, + "lowi_wifihal_get_cb_table"); + if (!lowiCbTable) { + ALOGE("%s: NULL lowi callback table", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + + *lowi_wifihal_api = lowiCbTable(); + + /* First check whether lowi module implements the get_lowi_version + * function. All the functions in lowi module starts with + * "lowi_wifihal_" prefix thus the below function name. + */ + if ((dlsym(lowi_handle, "lowi_wifihal_get_lowi_version") != NULL) && + ((*lowi_wifihal_api)->get_lowi_version != NULL)) { + u16 lowiMajorVersion = WIFIHAL_LOWI_MAJOR_VERSION; + u16 lowiMinorVersion = WIFIHAL_LOWI_MINOR_VERSION; + u16 lowiMicroVersion = WIFIHAL_LOWI_MICRO_VERSION; + int versionCheck = -1; + + ret = (*lowi_wifihal_api)->get_lowi_version(&lowiMajorVersion, + &lowiMinorVersion, + &lowiMicroVersion); + if (ret) { + ALOGI("%s: get_lowi_version returned error:%d", + __FUNCTION__, ret); + retVal = WIFI_ERROR_NOT_SUPPORTED; + goto cleanup; + } + ALOGI("%s: Lowi version:%d.%d.%d", __FUNCTION__, + lowiMajorVersion, lowiMinorVersion, + lowiMicroVersion); + + /* Compare the version with version in wifihal_internal.h */ + versionCheck = compareLowiVersion(lowiMajorVersion, + lowiMinorVersion, + lowiMicroVersion); + if (versionCheck < 0) { + ALOGI("%s: Version Check failed:%d", __FUNCTION__, + versionCheck); + retVal = WIFI_ERROR_NOT_SUPPORTED; + goto cleanup; + } + else { + ALOGI("%s: Version Check passed:%d", __FUNCTION__, + versionCheck); + } + } + else { + ALOGI("%s: lowi_wifihal_get_lowi_version not present", + __FUNCTION__); + } + + + /* Check if get_lowi_capabilities func pointer exists in + * the lowi lib and populate lowi_get_capa_supported + * All the functions in lowi modules starts with + * "lowi_wifihal_ prefix" thus the below function name. + */ + if (dlsym(lowi_handle, "lowi_wifihal_get_lowi_capabilities") != NULL) { + *lowi_get_capa_supported = true; + } + else { + ALOGI("lowi_wifihal_get_lowi_capabilities() is not supported."); + *lowi_get_capa_supported = false; + } +cleanup: + if (retVal) { + *lowi_wifihal_api = NULL; + } + return retVal; +} + +lowi_cb_table_t *getLowiCallbackTable(u32 requested_lowi_capabilities) +{ + int ret = WIFI_SUCCESS; + bool lowi_get_capabilities_support = false; + + if (requested_lowi_capabilities == GSCAN_SUPPORTED) { + ALOGV("%s: Returning Null, GSCAN not supported by lowi", + __FUNCTION__); + return NULL; + } + + ALOGI("%s: Entry", __FUNCTION__); + if (LowiWifiHalApi == NULL) { + ALOGI("%s: LowiWifiHalApi Null, Initialize Lowi", + __FUNCTION__); + ret = fetchLowiCbTableAndCapabilities(&LowiWifiHalApi, + &lowi_get_capabilities_support); + if (ret != WIFI_SUCCESS || LowiWifiHalApi == NULL || + LowiWifiHalApi->init == NULL) { + ALOGI("%s: LOWI is not supported.", __FUNCTION__); + goto cleanup; + } + /* Initialize LOWI if it isn't up already. */ + ret = LowiWifiHalApi->init(); + if (ret) { + ALOGE("%s: failed lowi initialization. " + "Returned error:%d. Exit.", __FUNCTION__, ret); + goto cleanup; + } + if (!lowi_get_capabilities_support || + LowiWifiHalApi->get_lowi_capabilities == NULL) { + ALOGI("%s: Allow rtt APIs thru LOWI to proceed even though " + "get_lowi_capabilities() is not supported. Returning", + __FUNCTION__); + lowiSupportedCapabilities |= + (ONE_SIDED_RANGING_SUPPORTED|DUAL_SIDED_RANGING_SUPPORED); + return LowiWifiHalApi; + } + ret = + LowiWifiHalApi->get_lowi_capabilities(&lowiSupportedCapabilities); + if (ret) { + ALOGI("%s: failed to get lowi supported capabilities." + "Returned error:%d. Exit.", __FUNCTION__, ret); + goto cleanup; + } + } + + if ((lowiSupportedCapabilities & requested_lowi_capabilities) == 0) { + ALOGE("%s: requested lowi capabilities: 0x%08x is not " + " in supported capabilities: 0x%08x. Return NULL.", + __FUNCTION__, requested_lowi_capabilities, + lowiSupportedCapabilities); + return NULL; + } + ALOGI("%s: Returning valid LowiWifiHalApi instance:%p", + __FUNCTION__, LowiWifiHalApi); + return LowiWifiHalApi; + +cleanup: + ALOGI("%s: Cleaning up Lowi due to failure. Return NULL", __FUNCTION__); + if (LowiWifiHalApi && LowiWifiHalApi->destroy) { + ret = LowiWifiHalApi->destroy(); + } + LowiWifiHalApi = NULL; + lowiSupportedCapabilities = 0; + return LowiWifiHalApi; +} + diff --git a/qcwcn/wifi_hal/common.h b/qcwcn/wifi_hal/common.h index a823a49..a9dad84 100644 --- a/qcwcn/wifi_hal/common.h +++ b/qcwcn/wifi_hal/common.h @@ -45,6 +45,7 @@ #include <utils/Log.h> #include "rb_wrapper.h" #include "pkt_stats.h" +#include "wifihal_internal.h" #define SOCKET_BUFFER_SIZE (32768U) #define RECV_BUF_SIZE (4096) @@ -83,6 +84,8 @@ typedef struct { int id; // id to use when talking to driver } interface_info; +struct gscan_event_handlers_s; + typedef struct hal_info_s { struct nl_sock *cmd_sock; // command socket object @@ -119,6 +122,17 @@ typedef struct hal_info_s { /* socket pair used to exit from blocking poll*/ int exit_sockets[2]; + u32 rx_buf_size_allocated; + u32 rx_buf_size_occupied; + wifi_ring_buffer_entry *rx_aggr_pkts; + rx_aggr_stats aggr_stats; + u32 prev_seq_no; + // pointer to structure having various gscan_event_handlers + struct gscan_event_handlers_s *gscan_handlers; + /* mutex for the log_handler access*/ + pthread_mutex_t lh_lock; + /* mutex for the alert_handler access*/ + pthread_mutex_t ah_lock; } hal_info; wifi_error wifi_register_handler(wifi_handle handle, int cmd, nl_recvmsg_msg_cb_t func, void *arg); @@ -138,7 +152,10 @@ hal_info *getHalInfo(wifi_handle handle); hal_info *getHalInfo(wifi_interface_handle handle); wifi_handle getWifiHandle(hal_info *info); wifi_interface_handle getIfaceHandle(interface_info *info); +wifi_error initializeGscanHandlers(hal_info *info); +wifi_error cleanupGscanHandlers(hal_info *info); +lowi_cb_table_t *getLowiCallbackTable(u32 requested_lowi_capabilities); wifi_error wifi_start_sending_offloaded_packet(wifi_request_id id, wifi_interface_handle iface, u8 *ip_packet, u16 ip_packet_len, @@ -153,6 +170,10 @@ wifi_error wifi_stop_rssi_monitoring(wifi_request_id id, wifi_interface_handle i #define min(x, y) ((x) < (y) ? (x) : (y)) #define max(x, y) ((x) > (y) ? (x) : (y)) +#define REQUEST_ID_MAX 1000 +#define get_requestid() ((arc4random()%REQUEST_ID_MAX) + 1) +#define WAIT_TIME_FOR_SET_REG_DOMAIN 50000 + #ifdef __cplusplus extern "C" { diff --git a/qcwcn/wifi_hal/cpp_bindings.cpp b/qcwcn/wifi_hal/cpp_bindings.cpp index e9272c6..381d8c8 100644 --- a/qcwcn/wifi_hal/cpp_bindings.cpp +++ b/qcwcn/wifi_hal/cpp_bindings.cpp @@ -820,8 +820,8 @@ int WifiVendorCommand::handleEvent(WifiEvent &event) mDataLen = nla_len(tb[NL80211_ATTR_VENDOR_DATA]); #ifdef QC_HAL_DEBUG ALOGD("%s: Vendor data len received:%d", __FUNCTION__, mDataLen); -#endif hexdump(mVendorData, mDataLen); +#endif } } return NL_SKIP; @@ -849,7 +849,6 @@ int WifiVendorCommand::create() { //insert the iface id to be "wlan0" ifindex = if_nametoindex("wlan0"); - ALOGE("%s ifindex obtained:%d",__FUNCTION__,ifindex); mMsg.set_iface_id(ifindex); out: return ret; @@ -971,7 +970,6 @@ void WifiVendorCommand::attr_end(struct nlattr *attribute) int WifiVendorCommand::set_iface_id(const char* name) { unsigned ifindex = if_nametoindex(name); - ALOGE("%s ifindex obtained:%d", __FUNCTION__,ifindex); return mMsg.set_iface_id(ifindex); } @@ -999,6 +997,7 @@ wifi_error WifiVendorCommand::get_mac_addr(struct nlattr **tb_vendor, } wifi_error initialize_vendor_cmd(wifi_interface_handle iface, + wifi_request_id id, u32 subcmd, WifiVendorCommand **vCommand) { @@ -1011,7 +1010,7 @@ wifi_error initialize_vendor_cmd(wifi_interface_handle iface, return WIFI_ERROR_INVALID_ARGS; } - *vCommand = new WifiVendorCommand(wifiHandle, 0, + *vCommand = new WifiVendorCommand(wifiHandle, id, OUI_QCA, subcmd); if (*vCommand == NULL) { diff --git a/qcwcn/wifi_hal/cpp_bindings.h b/qcwcn/wifi_hal/cpp_bindings.h index f7a4607..419110b 100644 --- a/qcwcn/wifi_hal/cpp_bindings.h +++ b/qcwcn/wifi_hal/cpp_bindings.h @@ -475,6 +475,7 @@ protected: pos = (nlattr *)nla_next(pos, &(rem))) wifi_error initialize_vendor_cmd(wifi_interface_handle iface, + wifi_request_id id, u32 subcmd, WifiVendorCommand **vCommand); #endif diff --git a/qcwcn/wifi_hal/gscan.cpp b/qcwcn/wifi_hal/gscan.cpp index 436d74b..4d40432 100644 --- a/qcwcn/wifi_hal/gscan.cpp +++ b/qcwcn/wifi_hal/gscan.cpp @@ -17,9 +17,9 @@ #include "sync.h" #define LOG_TAG "WifiHAL" #include <utils/Log.h> -#include <errno.h> #include <time.h> #include <errno.h> +#include <stdlib.h> #include "common.h" #include "cpp_bindings.h" @@ -28,13 +28,59 @@ #define GSCAN_EVENT_WAIT_TIME_SECONDS 4 -/* Used to handle gscan command events from driver/firmware. */ -GScanCommandEventHandler *GScanStartCmdEventHandler = NULL; -GScanCommandEventHandler *GScanSetBssidHotlistCmdEventHandler = NULL; -GScanCommandEventHandler *GScanSetSignificantChangeCmdEventHandler = NULL; -GScanCommandEventHandler *GScanSetSsidHotlistCmdEventHandler = NULL; -GScanCommandEventHandler *GScanSetPnoListCmdEventHandler = NULL; -GScanCommandEventHandler *GScanPnoSetPasspointListCmdEventHandler = NULL; +/* Used to handle gscan command events from driver/firmware.*/ +typedef struct gscan_event_handlers_s { + GScanCommandEventHandler *gscanStartCmdEventHandler; + GScanCommandEventHandler *gScanSetBssidHotlistCmdEventHandler; + GScanCommandEventHandler *gScanSetSignificantChangeCmdEventHandler; + GScanCommandEventHandler *gScanSetSsidHotlistCmdEventHandler; + GScanCommandEventHandler *gScanSetPnoListCmdEventHandler; + GScanCommandEventHandler *gScanPnoSetPasspointListCmdEventHandler; +} gscan_event_handlers; + +wifi_error initializeGscanHandlers(hal_info *info) +{ + info->gscan_handlers = (gscan_event_handlers *)malloc(sizeof(gscan_event_handlers)); + if (info->gscan_handlers) { + memset(info->gscan_handlers, 0, sizeof(gscan_event_handlers)); + } + else { + ALOGE("%s: Allocation of gscan event handlers failed", + __FUNCTION__); + return WIFI_ERROR_OUT_OF_MEMORY; + } + return WIFI_SUCCESS; +} + +wifi_error cleanupGscanHandlers(hal_info *info) +{ + gscan_event_handlers* event_handlers; + if (info && info->gscan_handlers) { + event_handlers = (gscan_event_handlers*) info->gscan_handlers; + if (event_handlers->gscanStartCmdEventHandler) { + delete event_handlers->gscanStartCmdEventHandler; + } + if (event_handlers->gScanSetBssidHotlistCmdEventHandler) { + delete event_handlers->gScanSetBssidHotlistCmdEventHandler; + } + if (event_handlers->gScanSetSignificantChangeCmdEventHandler) { + delete event_handlers->gScanSetSignificantChangeCmdEventHandler; + } + if (event_handlers->gScanSetSsidHotlistCmdEventHandler) { + delete event_handlers->gScanSetSsidHotlistCmdEventHandler; + } + if (event_handlers->gScanSetPnoListCmdEventHandler) { + delete event_handlers->gScanSetPnoListCmdEventHandler; + } + if (event_handlers->gScanPnoSetPasspointListCmdEventHandler) { + delete event_handlers->gScanPnoSetPasspointListCmdEventHandler; + } + memset(event_handlers, 0, sizeof(gscan_event_handlers)); + return WIFI_SUCCESS; + } + ALOGE ("%s: info or info->gscan_handlers NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; +} /* Implementation of the API functions exposed in gscan.h */ wifi_error wifi_get_valid_channels(wifi_interface_handle handle, @@ -46,18 +92,26 @@ wifi_error wifi_get_valid_channels(wifi_interface_handle handle, interface_info *ifaceInfo = getIfaceInfo(handle); wifi_handle wifiHandle = getWifiHandle(handle); hal_info *info = getHalInfo(wifiHandle); + lowi_cb_table_t *lowiWifiHalApi = NULL; - if (!(info->supported_feature_set & WIFI_FEATURE_GSCAN)) { - ALOGE("%s: GSCAN is not supported by driver", - __FUNCTION__); - return WIFI_ERROR_NOT_SUPPORTED; + /* Route GSCAN request through LOWI if supported */ + lowiWifiHalApi = getLowiCallbackTable(GSCAN_SUPPORTED); + if (lowiWifiHalApi == NULL || + lowiWifiHalApi->get_valid_channels == NULL) { + ALOGD("%s: Sending cmd directly to host", __FUNCTION__); + } else { + ret = lowiWifiHalApi->get_valid_channels(handle, band, max_channels, + channels, num_channels); + ALOGI("%s: lowi get_valid_channels " + "returned: %d. Exit.", __FUNCTION__, ret); + return (wifi_error)ret; } /* No request id from caller, so generate one and pass it on to the driver. * Generate one randomly. */ - requestId = rand(); - ALOGI("%s: RequestId:%d Enter band:%d max_channels:%d", __FUNCTION__, + requestId = get_requestid(); + ALOGI("%s: RequestId:%d band:%d max_channels:%d", __FUNCTION__, requestId, band, max_channels); if (channels == NULL) { @@ -116,7 +170,6 @@ wifi_error wifi_get_valid_channels(wifi_interface_handle handle, cleanup: delete gScanCommand; - ALOGI("%s: Exit.", __FUNCTION__); return (wifi_error)ret; } @@ -130,6 +183,7 @@ wifi_error wifi_get_gscan_capabilities(wifi_interface_handle handle, interface_info *ifaceInfo = getIfaceInfo(handle); wifi_handle wifiHandle = getWifiHandle(handle); hal_info *info = getHalInfo(wifiHandle); + lowi_cb_table_t *lowiWifiHalApi = NULL; if (!(info->supported_feature_set & WIFI_FEATURE_GSCAN)) { ALOGE("%s: GSCAN is not supported by driver", @@ -137,11 +191,24 @@ wifi_error wifi_get_gscan_capabilities(wifi_interface_handle handle, return WIFI_ERROR_NOT_SUPPORTED; } + /* Route GSCAN request through LOWI if supported */ + lowiWifiHalApi = getLowiCallbackTable(GSCAN_SUPPORTED); + if (lowiWifiHalApi == NULL || + lowiWifiHalApi->get_gscan_capabilities == NULL) { + ALOGD("%s: Sending cmd directly to host", __FUNCTION__); + } else { + ret = lowiWifiHalApi->get_gscan_capabilities(handle, + capabilities); + ALOGI("%s: lowi get_gscan_capabilities " + "returned: %d. Exit.", __FUNCTION__, ret); + return (wifi_error)ret; + } + /* No request id from caller, so generate one and pass it on to the driver. * Generate it randomly. */ - requestId = rand(); - ALOGI("%s: Enter RequestId:%d", __FUNCTION__, requestId); + requestId = get_requestid(); + ALOGI("%s: RequestId:%d", __FUNCTION__, requestId); if (capabilities == NULL) { ALOGE("%s: NULL capabilities pointer provided. Exit.", @@ -199,7 +266,6 @@ wifi_error wifi_get_gscan_capabilities(wifi_interface_handle handle, cleanup: gScanCommand->freeRspParams(eGScanGetCapabilitiesRspParams); delete gScanCommand; - ALOGI("%s: Exit.", __FUNCTION__); return (wifi_error)ret; } @@ -219,6 +285,12 @@ wifi_error wifi_start_gscan(wifi_request_id id, struct nlattr *nlBuckectSpecList; bool previousGScanRunning = false; hal_info *info = getHalInfo(wifiHandle); + lowi_cb_table_t *lowiWifiHalApi = NULL; + gscan_event_handlers* event_handlers; + GScanCommandEventHandler *gScanStartCmdEventHandler; + + event_handlers = (gscan_event_handlers*)info->gscan_handlers; + gScanStartCmdEventHandler = event_handlers->gscanStartCmdEventHandler; if (!(info->supported_feature_set & WIFI_FEATURE_GSCAN)) { ALOGE("%s: GSCAN is not supported by driver", @@ -226,12 +298,24 @@ wifi_error wifi_start_gscan(wifi_request_id id, return WIFI_ERROR_NOT_SUPPORTED; } - ALOGI("%s: Enter RequestId:%d ", __FUNCTION__, id); + /* Route GSCAN request through LOWI if supported */ + lowiWifiHalApi = getLowiCallbackTable(GSCAN_SUPPORTED); + if (lowiWifiHalApi == NULL || + lowiWifiHalApi->start_gscan == NULL) { + ALOGD("%s: Sending cmd directly to host", __FUNCTION__); + } else { + ret = lowiWifiHalApi->start_gscan(id, iface, params, handler); + ALOGI("%s: lowi start_gscan " + "returned: %d. Exit.", __FUNCTION__, ret); + return (wifi_error)ret; + } + + ALOGI("%s: RequestId:%d ", __FUNCTION__, id); /* Wi-Fi HAL doesn't need to check if a similar request to start gscan was * made earlier. If start_gscan() is called while another gscan is already * running, the request will be sent down to driver and firmware. If new * request is successfully honored, then Wi-Fi HAL will use the new request - * id for the GScanStartCmdEventHandler object. + * id for the gScanStartCmdEventHandler object. */ gScanCommand = new GScanCommand( wifiHandle, @@ -375,24 +459,21 @@ wifi_error wifi_start_gscan(wifi_request_id id, callbackHandler.on_scan_event = handler.on_scan_event; /* Create an object to handle the related events from firmware/driver. */ - if (GScanStartCmdEventHandler == NULL) { - GScanStartCmdEventHandler = new GScanCommandEventHandler( + if (gScanStartCmdEventHandler == NULL) { + gScanStartCmdEventHandler = new GScanCommandEventHandler( wifiHandle, id, OUI_QCA, QCA_NL80211_VENDOR_SUBCMD_GSCAN_START, callbackHandler); - if (GScanStartCmdEventHandler == NULL) { - ALOGE("%s: Error GScanStartCmdEventHandler NULL", __FUNCTION__); + if (gScanStartCmdEventHandler == NULL) { + ALOGE("%s: Error gScanStartCmdEventHandler NULL", __FUNCTION__); ret = WIFI_ERROR_UNKNOWN; goto cleanup; } + event_handlers->gscanStartCmdEventHandler = gScanStartCmdEventHandler; } else { - previousGScanRunning = true; - ALOGD("%s: " - "GScan is already running with request id=%d", - __FUNCTION__, - GScanStartCmdEventHandler->get_request_id()); + gScanStartCmdEventHandler->setCallbackHandler(callbackHandler); } ret = gScanCommand->requestResponse(); @@ -401,20 +482,19 @@ wifi_error wifi_start_gscan(wifi_request_id id, goto cleanup; } - if (GScanStartCmdEventHandler != NULL) { - GScanStartCmdEventHandler->set_request_id(id); + if (gScanStartCmdEventHandler != NULL) { + gScanStartCmdEventHandler->set_request_id(id); + gScanStartCmdEventHandler->enableEventHandling(); } cleanup: delete gScanCommand; - /* Delete the command event handler object if ret != 0 */ - if (!previousGScanRunning && ret && GScanStartCmdEventHandler) { - ALOGI("%s: Error ret:%d, delete event handler object.", + /* Disable Event Handling if ret != 0 */ + if (ret && gScanStartCmdEventHandler) { + ALOGI("%s: Error ret:%d, disable event handling", __FUNCTION__, ret); - delete GScanStartCmdEventHandler; - GScanStartCmdEventHandler = NULL; + gScanStartCmdEventHandler->disableEventHandling(); } - ALOGI("%s: Exit.", __FUNCTION__); return (wifi_error)ret; } @@ -425,10 +505,16 @@ wifi_error wifi_stop_gscan(wifi_request_id id, int ret = 0; GScanCommand *gScanCommand; struct nlattr *nlData; + lowi_cb_table_t *lowiWifiHalApi = NULL; interface_info *ifaceInfo = getIfaceInfo(iface); wifi_handle wifiHandle = getWifiHandle(iface); hal_info *info = getHalInfo(wifiHandle); + gscan_event_handlers* event_handlers; + GScanCommandEventHandler *gScanStartCmdEventHandler; + + event_handlers = (gscan_event_handlers*)info->gscan_handlers; + gScanStartCmdEventHandler = event_handlers->gscanStartCmdEventHandler; if (!(info->supported_feature_set & WIFI_FEATURE_GSCAN)) { ALOGE("%s: GSCAN is not supported by driver", @@ -436,8 +522,21 @@ wifi_error wifi_stop_gscan(wifi_request_id id, return WIFI_ERROR_NOT_SUPPORTED; } - ALOGI("%s: Enter RequestId:%d", __FUNCTION__, id); - if (GScanStartCmdEventHandler == NULL) { + /* Route GSCAN request through LOWI if supported */ + lowiWifiHalApi = getLowiCallbackTable(GSCAN_SUPPORTED); + if (lowiWifiHalApi == NULL || + lowiWifiHalApi->stop_gscan == NULL) { + ALOGD("%s: Sending cmd directly to host", __FUNCTION__); + } else { + ret = lowiWifiHalApi->stop_gscan(id, iface); + ALOGI("%s: lowi stop_gscan " + "returned: %d. Exit.", __FUNCTION__, ret); + return (wifi_error)ret; + } + + ALOGI("%s: RequestId:%d", __FUNCTION__, id); + if (gScanStartCmdEventHandler == NULL || + gScanStartCmdEventHandler->isEventHandlingEnabled() == false) { ALOGE("%s: GSCAN isn't running or already stopped. " "Nothing to do. Exit", __FUNCTION__); return WIFI_ERROR_NOT_AVAILABLE; @@ -479,23 +578,15 @@ wifi_error wifi_stop_gscan(wifi_request_id id, ret = gScanCommand->requestResponse(); if (ret != 0) { ALOGE("%s: requestResponse Error:%d",__FUNCTION__, ret); - /* Delete different GSCAN event handlers for the specified Request ID. */ - if (GScanStartCmdEventHandler) { - delete GScanStartCmdEventHandler; - GScanStartCmdEventHandler = NULL; - } - goto cleanup; } - /* Delete different GSCAN event handlers for the specified Request ID. */ - if (GScanStartCmdEventHandler) { - delete GScanStartCmdEventHandler; - GScanStartCmdEventHandler = NULL; + /* Disable Event Handling. */ + if (gScanStartCmdEventHandler) { + gScanStartCmdEventHandler->disableEventHandling(); } cleanup: delete gScanCommand; - ALOGI("%s: Exit.", __FUNCTION__); return (wifi_error)ret; } @@ -512,6 +603,13 @@ wifi_error wifi_set_bssid_hotlist(wifi_request_id id, wifi_handle wifiHandle = getWifiHandle(iface); bool previousGScanSetBssidRunning = false; hal_info *info = getHalInfo(wifiHandle); + lowi_cb_table_t *lowiWifiHalApi = NULL; + gscan_event_handlers* event_handlers; + GScanCommandEventHandler *gScanSetBssidHotlistCmdEventHandler; + + event_handlers = (gscan_event_handlers*)info->gscan_handlers; + gScanSetBssidHotlistCmdEventHandler = + event_handlers->gScanSetBssidHotlistCmdEventHandler; if (!(info->supported_feature_set & WIFI_FEATURE_GSCAN)) { ALOGE("%s: GSCAN is not supported by driver", @@ -519,13 +617,25 @@ wifi_error wifi_set_bssid_hotlist(wifi_request_id id, return WIFI_ERROR_NOT_SUPPORTED; } - ALOGI("%s: Enter RequestId:%d", __FUNCTION__, id); + /* Route request through LOWI if supported*/ + lowiWifiHalApi = getLowiCallbackTable(GSCAN_SUPPORTED); + if (lowiWifiHalApi == NULL || + lowiWifiHalApi->set_bssid_hotlist == NULL) { + ALOGD("%s: Sending cmd directly to host", __FUNCTION__); + } else { + ret = lowiWifiHalApi->set_bssid_hotlist(id, iface, params,handler); + ALOGI("%s: lowi set_bssid_hotlist " + "returned: %d. Exit.", __FUNCTION__, ret); + return (wifi_error)ret; + } + + ALOGI("%s: RequestId:%d", __FUNCTION__, id); /* Wi-Fi HAL doesn't need to check if a similar request to set bssid * hotlist was made earlier. If set_bssid_hotlist() is called while * another one is running, the request will be sent down to driver and * firmware. If the new request is successfully honored, then Wi-Fi HAL - * will use the new request id for the GScanSetBssidHotlistCmdEventHandler + * will use the new request id for the gScanSetBssidHotlistCmdEventHandler * object. */ @@ -618,27 +728,24 @@ wifi_error wifi_set_bssid_hotlist(wifi_request_id id, /* Create an object of the event handler class to take care of the * asychronous events on the north-bound. */ - if (GScanSetBssidHotlistCmdEventHandler == NULL) { - GScanSetBssidHotlistCmdEventHandler = new GScanCommandEventHandler( + if (gScanSetBssidHotlistCmdEventHandler == NULL) { + gScanSetBssidHotlistCmdEventHandler = new GScanCommandEventHandler( wifiHandle, id, OUI_QCA, QCA_NL80211_VENDOR_SUBCMD_GSCAN_SET_BSSID_HOTLIST, callbackHandler); - if (GScanSetBssidHotlistCmdEventHandler == NULL) { + if (gScanSetBssidHotlistCmdEventHandler == NULL) { ALOGE("%s: Error instantiating " - "GScanSetBssidHotlistCmdEventHandler.", __FUNCTION__); + "gScanSetBssidHotlistCmdEventHandler.", __FUNCTION__); ret = WIFI_ERROR_UNKNOWN; goto cleanup; } + event_handlers->gScanSetBssidHotlistCmdEventHandler = + gScanSetBssidHotlistCmdEventHandler; ALOGD("%s: Handler object was created for HOTLIST_AP_FOUND.", __FUNCTION__); } else { - previousGScanSetBssidRunning = true; - ALOGD("%s: " - "A HOTLIST_AP_FOUND event handler object already exists " - "with request id=%d", - __FUNCTION__, - GScanSetBssidHotlistCmdEventHandler->get_request_id()); + gScanSetBssidHotlistCmdEventHandler->setCallbackHandler(callbackHandler); } ret = gScanCommand->requestResponse(); @@ -647,19 +754,19 @@ wifi_error wifi_set_bssid_hotlist(wifi_request_id id, goto cleanup; } - if (GScanSetBssidHotlistCmdEventHandler != NULL) { - GScanSetBssidHotlistCmdEventHandler->set_request_id(id); + if (gScanSetBssidHotlistCmdEventHandler != NULL) { + gScanSetBssidHotlistCmdEventHandler->set_request_id(id); + gScanSetBssidHotlistCmdEventHandler->enableEventHandling(); } cleanup: delete gScanCommand; - /* Delete the command event handler object if ret != 0 */ - if (!previousGScanSetBssidRunning && ret - && GScanSetBssidHotlistCmdEventHandler) { - delete GScanSetBssidHotlistCmdEventHandler; - GScanSetBssidHotlistCmdEventHandler = NULL; + /* Disable Event Handling if ret != 0 */ + if (ret && gScanSetBssidHotlistCmdEventHandler) { + ALOGI("%s: Error ret:%d, disable event handling", + __FUNCTION__, ret); + gScanSetBssidHotlistCmdEventHandler->disableEventHandling(); } - ALOGI("%s: Exit.", __FUNCTION__); return (wifi_error)ret; } @@ -672,6 +779,13 @@ wifi_error wifi_reset_bssid_hotlist(wifi_request_id id, interface_info *ifaceInfo = getIfaceInfo(iface); wifi_handle wifiHandle = getWifiHandle(iface); hal_info *info = getHalInfo(wifiHandle); + lowi_cb_table_t *lowiWifiHalApi = NULL; + gscan_event_handlers* event_handlers; + GScanCommandEventHandler *gScanSetBssidHotlistCmdEventHandler; + + event_handlers = (gscan_event_handlers*)info->gscan_handlers; + gScanSetBssidHotlistCmdEventHandler = + event_handlers->gScanSetBssidHotlistCmdEventHandler; if (!(info->supported_feature_set & WIFI_FEATURE_GSCAN)) { ALOGE("%s: GSCAN is not supported by driver", @@ -679,9 +793,23 @@ wifi_error wifi_reset_bssid_hotlist(wifi_request_id id, return WIFI_ERROR_NOT_SUPPORTED; } - ALOGI("%s: Enter RequestId:%d", __FUNCTION__, id); + /* Route request through LOWI if supported*/ + lowiWifiHalApi = getLowiCallbackTable(GSCAN_SUPPORTED); + if (lowiWifiHalApi == NULL || + lowiWifiHalApi->reset_bssid_hotlist == NULL) { + ALOGD("%s: Sending cmd directly to host", __FUNCTION__); + } else { + ret = lowiWifiHalApi->reset_bssid_hotlist(id, iface); + ALOGI("%s: lowi reset_bssid_hotlist " + "returned: %d. Exit.", __FUNCTION__, ret); + return (wifi_error)ret; + } - if (GScanSetBssidHotlistCmdEventHandler == NULL) { + ALOGI("%s: RequestId:%d", __FUNCTION__, id); + + if (gScanSetBssidHotlistCmdEventHandler == NULL || + (gScanSetBssidHotlistCmdEventHandler->isEventHandlingEnabled() == + false)) { ALOGE("wifi_reset_bssid_hotlist: GSCAN bssid_hotlist isn't set. " "Nothing to do. Exit"); return WIFI_ERROR_NOT_AVAILABLE; @@ -723,21 +851,15 @@ wifi_error wifi_reset_bssid_hotlist(wifi_request_id id, ret = gScanCommand->requestResponse(); if (ret != 0) { ALOGE("%s: requestResponse Error:%d",__FUNCTION__, ret); - if (GScanSetBssidHotlistCmdEventHandler) { - delete GScanSetBssidHotlistCmdEventHandler; - GScanSetBssidHotlistCmdEventHandler = NULL; - } - goto cleanup; } - if (GScanSetBssidHotlistCmdEventHandler) { - delete GScanSetBssidHotlistCmdEventHandler; - GScanSetBssidHotlistCmdEventHandler = NULL; + /* Disable Event Handling. */ + if (gScanSetBssidHotlistCmdEventHandler) { + gScanSetBssidHotlistCmdEventHandler->disableEventHandling(); } cleanup: delete gScanCommand; - ALOGI("%s: Exit.", __FUNCTION__); return (wifi_error)ret; } @@ -754,6 +876,13 @@ wifi_error wifi_set_significant_change_handler(wifi_request_id id, wifi_handle wifiHandle = getWifiHandle(iface); bool previousGScanSetSigChangeRunning = false; hal_info *info = getHalInfo(wifiHandle); + lowi_cb_table_t *lowiWifiHalApi = NULL; + gscan_event_handlers* event_handlers; + GScanCommandEventHandler *gScanSetSignificantChangeCmdEventHandler; + + event_handlers = (gscan_event_handlers*)info->gscan_handlers; + gScanSetSignificantChangeCmdEventHandler = + event_handlers->gScanSetSignificantChangeCmdEventHandler; if (!(info->supported_feature_set & WIFI_FEATURE_GSCAN)) { ALOGE("%s: GSCAN is not supported by driver", @@ -761,13 +890,28 @@ wifi_error wifi_set_significant_change_handler(wifi_request_id id, return WIFI_ERROR_NOT_SUPPORTED; } - ALOGI("%s: Enter RequestId:%d", __FUNCTION__, id); + /* Route request through LOWI if supported*/ + lowiWifiHalApi = getLowiCallbackTable(GSCAN_SUPPORTED); + if (lowiWifiHalApi == NULL || + lowiWifiHalApi->set_significant_change_handler == NULL) { + ALOGD("%s: Sending cmd directly to host", __FUNCTION__); + } else { + ret = lowiWifiHalApi->set_significant_change_handler(id, + iface, + params, + handler); + ALOGI("%s: lowi set_significant_change_handler " + "returned: %d. Exit.", __FUNCTION__, ret); + return (wifi_error)ret; + } + + ALOGI("%s: RequestId:%d", __FUNCTION__, id); /* Wi-Fi HAL doesn't need to check if a similar request to set significant * change list was made earlier. If set_significant_change() is called while * another one is running, the request will be sent down to driver and * firmware. If the new request is successfully honored, then Wi-Fi HAL - * will use the new request id for the GScanSetBssidHotlistCmdEventHandler + * will use the new request id for the gScanSetSignificantChangeCmdEventHandler * object. */ @@ -869,30 +1013,27 @@ wifi_error wifi_set_significant_change_handler(wifi_request_id id, /* Create an object of the event handler class to take care of the * asychronous events on the north-bound. */ - if (GScanSetSignificantChangeCmdEventHandler == NULL) { - GScanSetSignificantChangeCmdEventHandler = + if (gScanSetSignificantChangeCmdEventHandler == NULL) { + gScanSetSignificantChangeCmdEventHandler = new GScanCommandEventHandler( wifiHandle, id, OUI_QCA, QCA_NL80211_VENDOR_SUBCMD_GSCAN_SET_SIGNIFICANT_CHANGE, callbackHandler); - if (GScanSetSignificantChangeCmdEventHandler == NULL) { + if (gScanSetSignificantChangeCmdEventHandler == NULL) { ALOGE("%s: Error in instantiating, " - "GScanSetSignificantChangeCmdEventHandler.", + "gScanSetSignificantChangeCmdEventHandler.", __FUNCTION__); ret = WIFI_ERROR_UNKNOWN; goto cleanup; } + event_handlers->gScanSetSignificantChangeCmdEventHandler = + gScanSetSignificantChangeCmdEventHandler; ALOGD("%s: Event handler object was created for SIGNIFICANT_CHANGE.", __FUNCTION__); } else { - previousGScanSetSigChangeRunning = true; - ALOGD("%s: " - "A SIGNIFICANT_CHANGE event handler object already exists " - "with request id=%d", - __FUNCTION__, - GScanSetSignificantChangeCmdEventHandler->get_request_id()); + gScanSetSignificantChangeCmdEventHandler->setCallbackHandler(callbackHandler); } ret = gScanCommand->requestResponse(); @@ -901,19 +1042,19 @@ wifi_error wifi_set_significant_change_handler(wifi_request_id id, goto cleanup; } - if (GScanSetSignificantChangeCmdEventHandler != NULL) { - GScanSetSignificantChangeCmdEventHandler->set_request_id(id); + if (gScanSetSignificantChangeCmdEventHandler != NULL) { + gScanSetSignificantChangeCmdEventHandler->set_request_id(id); + gScanSetSignificantChangeCmdEventHandler->enableEventHandling(); } cleanup: - /* Delete the command event handler object if ret != 0 */ - if (!previousGScanSetSigChangeRunning && ret - && GScanSetSignificantChangeCmdEventHandler) { - delete GScanSetSignificantChangeCmdEventHandler; - GScanSetSignificantChangeCmdEventHandler = NULL; + /* Disable Event Handling if ret != 0 */ + if (ret && gScanSetSignificantChangeCmdEventHandler) { + ALOGI("%s: Error ret:%d, disable event handling", + __FUNCTION__, ret); + gScanSetSignificantChangeCmdEventHandler->disableEventHandling(); } delete gScanCommand; - ALOGI("%s: Exit.", __FUNCTION__); return (wifi_error)ret; } @@ -927,6 +1068,13 @@ wifi_error wifi_reset_significant_change_handler(wifi_request_id id, interface_info *ifaceInfo = getIfaceInfo(iface); wifi_handle wifiHandle = getWifiHandle(iface); hal_info *info = getHalInfo(wifiHandle); + lowi_cb_table_t *lowiWifiHalApi = NULL; + gscan_event_handlers* event_handlers; + GScanCommandEventHandler *gScanSetSignificantChangeCmdEventHandler; + + event_handlers = (gscan_event_handlers*)info->gscan_handlers; + gScanSetSignificantChangeCmdEventHandler = + event_handlers->gScanSetSignificantChangeCmdEventHandler; if (!(info->supported_feature_set & WIFI_FEATURE_GSCAN)) { ALOGE("%s: GSCAN is not supported by driver", @@ -934,9 +1082,23 @@ wifi_error wifi_reset_significant_change_handler(wifi_request_id id, return WIFI_ERROR_NOT_SUPPORTED; } - ALOGI("%s: Enter RequestId:%d", __FUNCTION__, id); + /* Route request through LOWI if supported*/ + lowiWifiHalApi = getLowiCallbackTable(GSCAN_SUPPORTED); + if (lowiWifiHalApi == NULL || + lowiWifiHalApi->reset_significant_change_handler == NULL) { + ALOGD("%s: Sending cmd directly to host", __FUNCTION__); + } else { + ret = lowiWifiHalApi->reset_significant_change_handler(id, iface); + ALOGI("%s: lowi reset_significant_change_handler " + "returned: %d. Exit.", __FUNCTION__, ret); + return (wifi_error)ret; + } + + ALOGI("%s: RequestId:%d", __FUNCTION__, id); - if (GScanSetSignificantChangeCmdEventHandler == NULL) { + if (gScanSetSignificantChangeCmdEventHandler == NULL || + (gScanSetSignificantChangeCmdEventHandler->isEventHandlingEnabled() == + false)) { ALOGE("wifi_reset_significant_change_handler: GSCAN significant_change" " isn't set. Nothing to do. Exit"); return WIFI_ERROR_NOT_AVAILABLE; @@ -980,21 +1142,15 @@ wifi_error wifi_reset_significant_change_handler(wifi_request_id id, ret = gScanCommand->requestResponse(); if (ret != 0) { ALOGE("%s: requestResponse Error:%d",__FUNCTION__, ret); - if (GScanSetSignificantChangeCmdEventHandler) { - delete GScanSetSignificantChangeCmdEventHandler; - GScanSetSignificantChangeCmdEventHandler = NULL; - } - goto cleanup; } - if (GScanSetSignificantChangeCmdEventHandler) { - delete GScanSetSignificantChangeCmdEventHandler; - GScanSetSignificantChangeCmdEventHandler = NULL; + /* Disable Event Handling. */ + if (gScanSetSignificantChangeCmdEventHandler) { + gScanSetSignificantChangeCmdEventHandler->disableEventHandling(); } cleanup: delete gScanCommand; - ALOGI("%s: Exit.", __FUNCTION__); return (wifi_error)ret; } @@ -1013,6 +1169,7 @@ wifi_error wifi_get_cached_gscan_results(wifi_interface_handle iface, GScanCommand *gScanCommand; struct nlattr *nlData; wifi_cached_scan_results *cached_results; + lowi_cb_table_t *lowiWifiHalApi = NULL; interface_info *ifaceInfo = getIfaceInfo(iface); wifi_handle wifiHandle = getWifiHandle(iface); @@ -1024,10 +1181,26 @@ wifi_error wifi_get_cached_gscan_results(wifi_interface_handle iface, return WIFI_ERROR_NOT_SUPPORTED; } + /* Route GSCAN request through LOWI if supported */ + lowiWifiHalApi = getLowiCallbackTable(GSCAN_SUPPORTED); + if (lowiWifiHalApi == NULL || + lowiWifiHalApi->get_cached_gscan_results == NULL) { + ALOGD("%s: Sending cmd directly to host", __FUNCTION__); + } else { + ret = lowiWifiHalApi->get_cached_gscan_results(iface, + flush, + max, + results, + num); + ALOGI("%s: lowi get_cached_gscan_results" + "returned: %d. Exit.", __FUNCTION__, ret); + return (wifi_error)ret; + } + /* No request id from caller, so generate one and pass it on to the driver. */ /* Generate it randomly */ - requestId = rand(); - ALOGI("%s: Enter RequestId:%d", __FUNCTION__, requestId); + requestId = get_requestid(); + ALOGI("%s: RequestId:%d", __FUNCTION__, requestId); if (results == NULL || num == NULL) { ALOGE("%s: NULL pointer provided. Exit.", @@ -1126,7 +1299,6 @@ wifi_error wifi_get_cached_gscan_results(wifi_interface_handle iface, cleanup: gScanCommand->freeRspParams(eGScanGetCachedResultsRspParams); delete gScanCommand; - ALOGI("%s: Exit.", __FUNCTION__); return (wifi_error)ret; } @@ -1139,8 +1311,6 @@ wifi_error wifi_set_scanning_mac_oui(wifi_interface_handle handle, oui scan_oui) interface_info *iinfo = getIfaceInfo(handle); wifi_handle wifiHandle = getWifiHandle(handle); - ALOGI("%s: Enter", __FUNCTION__); - vCommand = new WifiVendorCommand(wifiHandle, 0, OUI_QCA, QCA_NL80211_VENDOR_SUBCMD_SCANNING_MAC_OUI); @@ -1163,7 +1333,8 @@ wifi_error wifi_set_scanning_mac_oui(wifi_interface_handle handle, oui scan_oui) if (!nlData) goto cleanup; - ALOGI("MAC_OUI - %02x:%02x:%02x", scan_oui[0], scan_oui[1], scan_oui[2]); + ALOGI("%s: MAC_OUI - %02x:%02x:%02x", __FUNCTION__, + scan_oui[0], scan_oui[1], scan_oui[2]); /* Add the fixed part of the mac_oui to the nl command */ ret = vCommand->put_bytes( @@ -1183,7 +1354,6 @@ wifi_error wifi_set_scanning_mac_oui(wifi_interface_handle handle, oui scan_oui) cleanup: delete vCommand; - ALOGI("%s: Exit.", __FUNCTION__); return (wifi_error)ret; } @@ -1201,6 +1371,13 @@ wifi_error wifi_set_ssid_hotlist(wifi_request_id id, wifi_handle wifiHandle = getWifiHandle(iface); bool previousGScanSetSsidRunning = false; hal_info *info = getHalInfo(wifiHandle); + lowi_cb_table_t *lowiWifiHalApi = NULL; + gscan_event_handlers* event_handlers; + GScanCommandEventHandler *gScanSetSsidHotlistCmdEventHandler; + + event_handlers = (gscan_event_handlers*)info->gscan_handlers; + gScanSetSsidHotlistCmdEventHandler = + event_handlers->gScanSetSsidHotlistCmdEventHandler; if (!(info->supported_feature_set & WIFI_FEATURE_GSCAN)) { ALOGE("%s: GSCAN is not supported by driver", @@ -1208,13 +1385,25 @@ wifi_error wifi_set_ssid_hotlist(wifi_request_id id, return WIFI_ERROR_NOT_SUPPORTED; } - ALOGI("%s: Enter RequestId:%d", __FUNCTION__, id); + /* Route request through LOWI if supported*/ + lowiWifiHalApi = getLowiCallbackTable(GSCAN_SUPPORTED); + if (lowiWifiHalApi == NULL || + lowiWifiHalApi->set_ssid_hotlist == NULL) { + ALOGD("%s: Sending cmd directly to host", __FUNCTION__); + } else { + ret = lowiWifiHalApi->set_ssid_hotlist(id, iface, params,handler); + ALOGI("%s: lowi set_ssid_hotlist " + "returned: %d. Exit.", __FUNCTION__, ret); + return (wifi_error)ret; + } + + ALOGI("%s: RequestId:%d", __FUNCTION__, id); /* Wi-Fi HAL doesn't need to check if a similar request to set ssid * hotlist was made earlier. If set_ssid_hotlist() is called while * another one is running, the request will be sent down to driver and * firmware. If the new request is successfully honored, then Wi-Fi HAL - * will use the new request id for the GScanSetSsidHotlistCmdEventHandler + * will use the new request id for the gScanSetSsidHotlistCmdEventHandler * object. */ @@ -1313,27 +1502,24 @@ wifi_error wifi_set_ssid_hotlist(wifi_request_id id, /* Create an object of the event handler class to take care of the * asychronous events on the north-bound. */ - if (GScanSetSsidHotlistCmdEventHandler == NULL) { - GScanSetSsidHotlistCmdEventHandler = new GScanCommandEventHandler( + if (gScanSetSsidHotlistCmdEventHandler == NULL) { + gScanSetSsidHotlistCmdEventHandler = new GScanCommandEventHandler( wifiHandle, id, OUI_QCA, QCA_NL80211_VENDOR_SUBCMD_GSCAN_SET_SSID_HOTLIST, callbackHandler); - if (GScanSetSsidHotlistCmdEventHandler == NULL) { + if (gScanSetSsidHotlistCmdEventHandler == NULL) { ALOGE("%s: Error instantiating " - "GScanSetSsidHotlistCmdEventHandler.", __FUNCTION__); + "gScanSetSsidHotlistCmdEventHandler.", __FUNCTION__); ret = WIFI_ERROR_UNKNOWN; goto cleanup; } ALOGD("%s: Handler object was created for HOTLIST_AP_FOUND.", __FUNCTION__); + event_handlers->gScanSetSsidHotlistCmdEventHandler = + gScanSetSsidHotlistCmdEventHandler; } else { - previousGScanSetSsidRunning = true; - ALOGD("%s: " - "A HOTLIST_AP_FOUND event handler object already exists " - "with request id=%d", - __FUNCTION__, - GScanSetSsidHotlistCmdEventHandler->get_request_id()); + gScanSetSsidHotlistCmdEventHandler->setCallbackHandler(callbackHandler); } ret = gScanCommand->requestResponse(); @@ -1342,19 +1528,19 @@ wifi_error wifi_set_ssid_hotlist(wifi_request_id id, goto cleanup; } - if (GScanSetSsidHotlistCmdEventHandler != NULL) { - GScanSetSsidHotlistCmdEventHandler->set_request_id(id); + if (gScanSetSsidHotlistCmdEventHandler != NULL) { + gScanSetSsidHotlistCmdEventHandler->set_request_id(id); + gScanSetSsidHotlistCmdEventHandler->enableEventHandling(); } cleanup: delete gScanCommand; - /* Delete the command event handler object if ret != 0 */ - if (!previousGScanSetSsidRunning && ret - && GScanSetSsidHotlistCmdEventHandler) { - delete GScanSetSsidHotlistCmdEventHandler; - GScanSetSsidHotlistCmdEventHandler = NULL; + /* Disable Event Handling if ret != 0 */ + if (ret && gScanSetSsidHotlistCmdEventHandler) { + ALOGI("%s: Error ret:%d, disable event handling", + __FUNCTION__, ret); + gScanSetSsidHotlistCmdEventHandler->disableEventHandling(); } - ALOGI("%s: Exit.", __FUNCTION__); return (wifi_error)ret; } @@ -1367,6 +1553,13 @@ wifi_error wifi_reset_ssid_hotlist(wifi_request_id id, interface_info *ifaceInfo = getIfaceInfo(iface); wifi_handle wifiHandle = getWifiHandle(iface); hal_info *info = getHalInfo(wifiHandle); + lowi_cb_table_t *lowiWifiHalApi = NULL; + gscan_event_handlers* event_handlers; + GScanCommandEventHandler *gScanSetSsidHotlistCmdEventHandler; + + event_handlers = (gscan_event_handlers*)info->gscan_handlers; + gScanSetSsidHotlistCmdEventHandler = + event_handlers->gScanSetSsidHotlistCmdEventHandler; if (!(info->supported_feature_set & WIFI_FEATURE_GSCAN)) { ALOGE("%s: GSCAN is not supported by driver", @@ -1374,9 +1567,23 @@ wifi_error wifi_reset_ssid_hotlist(wifi_request_id id, return WIFI_ERROR_NOT_SUPPORTED; } - ALOGI("%s: Enter RequestId:%d", __FUNCTION__, id); + /* Route request through LOWI if supported*/ + lowiWifiHalApi = getLowiCallbackTable(GSCAN_SUPPORTED); + if (lowiWifiHalApi == NULL || + lowiWifiHalApi->reset_ssid_hotlist == NULL) { + ALOGD("%s: Sending cmd directly to host", __FUNCTION__); + } else { + ret = lowiWifiHalApi->reset_ssid_hotlist(id, iface); + ALOGI("%s: lowi reset_ssid_hotlist " + "returned: %d. Exit.", __FUNCTION__, ret); + return (wifi_error)ret; + } + + ALOGI("%s: RequestId:%d", __FUNCTION__, id); - if (GScanSetSsidHotlistCmdEventHandler == NULL) { + if (gScanSetSsidHotlistCmdEventHandler == NULL || + (gScanSetSsidHotlistCmdEventHandler->isEventHandlingEnabled() == + false)) { ALOGE("wifi_reset_ssid_hotlist: GSCAN ssid_hotlist isn't set. " "Nothing to do. Exit"); return WIFI_ERROR_NOT_AVAILABLE; @@ -1418,21 +1625,15 @@ wifi_error wifi_reset_ssid_hotlist(wifi_request_id id, ret = gScanCommand->requestResponse(); if (ret != 0) { ALOGE("%s: requestResponse Error:%d",__FUNCTION__, ret); - if (GScanSetSsidHotlistCmdEventHandler) { - delete GScanSetSsidHotlistCmdEventHandler; - GScanSetSsidHotlistCmdEventHandler = NULL; - } - goto cleanup; } - if (GScanSetSsidHotlistCmdEventHandler) { - delete GScanSetSsidHotlistCmdEventHandler; - GScanSetSsidHotlistCmdEventHandler = NULL; + /* Disable Event Handling. */ + if (gScanSetSsidHotlistCmdEventHandler) { + gScanSetSsidHotlistCmdEventHandler->disableEventHandling(); } cleanup: delete gScanCommand; - ALOGI("%s: Exit.", __FUNCTION__); return (wifi_error)ret; } @@ -1480,8 +1681,10 @@ int GScanCommand::create() { if (ret < 0) goto out; +#ifdef QC_HAL_DEBUG ALOGI("%s: mVendor_id = %d, Subcmd = %d.", __FUNCTION__, mVendor_id, mSubcmd); +#endif out: return ret; @@ -1752,7 +1955,7 @@ int GScanCommand::handleResponse(WifiEvent &reply) { int GScanCommand::gscan_parse_capabilities(struct nlattr **tbVendor) { if (!mGetCapabilitiesRspParams){ - ALOGE("%s: mGetCapabilitiesRspParams ptr is NULL. Exit. ", + ALOGE("%s: mGetCapabilitiesRspParams ptr is NULL. Exit.", __FUNCTION__); return WIFI_ERROR_INVALID_ARGS; } @@ -2193,6 +2396,12 @@ wifi_error wifi_set_epno_list(wifi_request_id id, wifi_handle wifiHandle = getWifiHandle(iface); bool previousGScanSetEpnoListRunning = false; hal_info *info = getHalInfo(wifiHandle); + gscan_event_handlers* event_handlers; + GScanCommandEventHandler *gScanSetPnoListCmdEventHandler; + + event_handlers = (gscan_event_handlers*)info->gscan_handlers; + gScanSetPnoListCmdEventHandler = + event_handlers->gScanSetPnoListCmdEventHandler; if (!(info->supported_feature_set & WIFI_FEATURE_HAL_EPNO)) { ALOGE("%s: Enhanced PNO is not supported by the driver", @@ -2200,13 +2409,13 @@ wifi_error wifi_set_epno_list(wifi_request_id id, return WIFI_ERROR_NOT_SUPPORTED; } - ALOGI("%s: Enter RequestId:%d", __FUNCTION__, id); + ALOGI("%s: RequestId:%d", __FUNCTION__, id); /* Wi-Fi HAL doesn't need to check if a similar request to set ePNO * list was made earlier. If wifi_set_epno_list() is called while * another one is running, the request will be sent down to driver and * firmware. If the new request is successfully honored, then Wi-Fi HAL - * will use the new request id for the GScanSetPnoListCmdEventHandler + * will use the new request id for the gScanSetPnoListCmdEventHandler * object. */ @@ -2306,28 +2515,25 @@ wifi_error wifi_set_epno_list(wifi_request_id id, /* Create an object of the event handler class to take care of the * asychronous events on the north-bound. */ - if (GScanSetPnoListCmdEventHandler == NULL) { - GScanSetPnoListCmdEventHandler = new GScanCommandEventHandler( + if (gScanSetPnoListCmdEventHandler == NULL) { + gScanSetPnoListCmdEventHandler = new GScanCommandEventHandler( wifiHandle, id, OUI_QCA, QCA_NL80211_VENDOR_SUBCMD_PNO_SET_LIST, callbackHandler); - if (GScanSetPnoListCmdEventHandler == NULL) { + if (gScanSetPnoListCmdEventHandler == NULL) { ALOGE("%s: Error instantiating " - "GScanSetPnoListCmdEventHandler.", __FUNCTION__); + "gScanSetPnoListCmdEventHandler.", __FUNCTION__); ret = WIFI_ERROR_UNKNOWN; goto cleanup; } + event_handlers->gScanSetPnoListCmdEventHandler = + gScanSetPnoListCmdEventHandler; ALOGD("%s: Handler object was created for PNO_NETWORK_FOUND.", __FUNCTION__); } else { - previousGScanSetEpnoListRunning = true; - ALOGD("%s: " - "A PNO_NETWORK_FOUND event handler object already exists" - " with request id=%d", - __FUNCTION__, - GScanSetPnoListCmdEventHandler->get_request_id()); + gScanSetPnoListCmdEventHandler->setCallbackHandler(callbackHandler); } ret = gScanCommand->requestResponse(); @@ -2336,19 +2542,19 @@ wifi_error wifi_set_epno_list(wifi_request_id id, goto cleanup; } - if (GScanSetPnoListCmdEventHandler != NULL) { - GScanSetPnoListCmdEventHandler->set_request_id(id); + if (gScanSetPnoListCmdEventHandler != NULL) { + gScanSetPnoListCmdEventHandler->set_request_id(id); + gScanSetPnoListCmdEventHandler->enableEventHandling(); } cleanup: delete gScanCommand; - /* Delete the command event handler object if ret != 0 */ - if (!previousGScanSetEpnoListRunning && ret - && GScanSetPnoListCmdEventHandler) { - delete GScanSetPnoListCmdEventHandler; - GScanSetPnoListCmdEventHandler = NULL; + /* Disable Event Handling if ret != 0 */ + if (ret && gScanSetPnoListCmdEventHandler) { + ALOGI("%s: Error ret:%d, disable event handling", + __FUNCTION__, ret); + gScanSetPnoListCmdEventHandler->disableEventHandling(); } - ALOGI("%s: Exit.", __FUNCTION__); return (wifi_error)ret; } @@ -2365,6 +2571,12 @@ wifi_error wifi_set_passpoint_list(wifi_request_id id, wifi_handle wifiHandle = getWifiHandle(iface); bool previousGScanPnoSetPasspointListRunning = false; hal_info *info = getHalInfo(wifiHandle); + gscan_event_handlers* event_handlers; + GScanCommandEventHandler *gScanPnoSetPasspointListCmdEventHandler; + + event_handlers = (gscan_event_handlers*)info->gscan_handlers; + gScanPnoSetPasspointListCmdEventHandler = + event_handlers->gScanPnoSetPasspointListCmdEventHandler; if (!(info->supported_feature_set & WIFI_FEATURE_HAL_EPNO)) { ALOGE("%s: Enhanced PNO is not supported by the driver", @@ -2372,14 +2584,14 @@ wifi_error wifi_set_passpoint_list(wifi_request_id id, return WIFI_ERROR_NOT_SUPPORTED; } - ALOGI("%s: Enter RequestId:%d", __FUNCTION__, id); + ALOGI("%s: RequestId:%d", __FUNCTION__, id); /* Wi-Fi HAL doesn't need to check if a similar request to set ePNO * passpoint list was made earlier. If wifi_set_passpoint_list() is called * while another one is running, the request will be sent down to driver and * firmware. If the new request is successfully honored, then Wi-Fi HAL * will use the new request id for the - * GScanPnoSetPasspointListCmdEventHandler object. + * gScanPnoSetPasspointListCmdEventHandler object. */ gScanCommand = new GScanCommand( @@ -2477,28 +2689,25 @@ wifi_error wifi_set_passpoint_list(wifi_request_id id, /* Create an object of the event handler class to take care of the * asychronous events on the north-bound. */ - if (GScanPnoSetPasspointListCmdEventHandler == NULL) { - GScanPnoSetPasspointListCmdEventHandler = new GScanCommandEventHandler( + if (gScanPnoSetPasspointListCmdEventHandler == NULL) { + gScanPnoSetPasspointListCmdEventHandler = new GScanCommandEventHandler( wifiHandle, id, OUI_QCA, QCA_NL80211_VENDOR_SUBCMD_PNO_SET_PASSPOINT_LIST, callbackHandler); - if (GScanPnoSetPasspointListCmdEventHandler == NULL) { + if (gScanPnoSetPasspointListCmdEventHandler == NULL) { ALOGE("%s: Error instantiating " - "GScanPnoSetPasspointListCmdEventHandler.", __FUNCTION__); + "gScanPnoSetPasspointListCmdEventHandler.", __FUNCTION__); ret = WIFI_ERROR_UNKNOWN; goto cleanup; } + event_handlers->gScanPnoSetPasspointListCmdEventHandler = + gScanPnoSetPasspointListCmdEventHandler; ALOGD("%s: Handler object was created for PNO_PASSPOINT_" "NETWORK_FOUND.", __FUNCTION__); } else { - previousGScanPnoSetPasspointListRunning = true; - ALOGD("%s: " - "A PNO_PASSPOINT_NETWORK_FOUND event handler object " - "already exists with request id=%d", - __FUNCTION__, - GScanPnoSetPasspointListCmdEventHandler->get_request_id()); + gScanPnoSetPasspointListCmdEventHandler->setCallbackHandler(callbackHandler); } ret = gScanCommand->requestResponse(); @@ -2507,19 +2716,19 @@ wifi_error wifi_set_passpoint_list(wifi_request_id id, goto cleanup; } - if (GScanPnoSetPasspointListCmdEventHandler != NULL) { - GScanPnoSetPasspointListCmdEventHandler->set_request_id(id); + if (gScanPnoSetPasspointListCmdEventHandler != NULL) { + gScanPnoSetPasspointListCmdEventHandler->set_request_id(id); + gScanPnoSetPasspointListCmdEventHandler->enableEventHandling(); } cleanup: delete gScanCommand; - /* Delete the command event handler object if ret != 0 */ - if (!previousGScanPnoSetPasspointListRunning && ret - && GScanPnoSetPasspointListCmdEventHandler) { - delete GScanPnoSetPasspointListCmdEventHandler; - GScanPnoSetPasspointListCmdEventHandler = NULL; + /* Disable Event Handling if ret != 0 */ + if (ret && gScanPnoSetPasspointListCmdEventHandler) { + ALOGI("%s: Error ret:%d, disable event handling", + __FUNCTION__, ret); + gScanPnoSetPasspointListCmdEventHandler->disableEventHandling(); } - ALOGI("%s: Exit.", __FUNCTION__); return (wifi_error)ret; } @@ -2532,6 +2741,12 @@ wifi_error wifi_reset_passpoint_list(wifi_request_id id, interface_info *ifaceInfo = getIfaceInfo(iface); wifi_handle wifiHandle = getWifiHandle(iface); hal_info *info = getHalInfo(wifiHandle); + gscan_event_handlers* event_handlers; + GScanCommandEventHandler *gScanPnoSetPasspointListCmdEventHandler; + + event_handlers = (gscan_event_handlers*)info->gscan_handlers; + gScanPnoSetPasspointListCmdEventHandler = + event_handlers->gScanPnoSetPasspointListCmdEventHandler; if (!(info->supported_feature_set & WIFI_FEATURE_HAL_EPNO)) { ALOGE("%s: Enhanced PNO is not supported by the driver", @@ -2539,11 +2754,13 @@ wifi_error wifi_reset_passpoint_list(wifi_request_id id, return WIFI_ERROR_NOT_SUPPORTED; } - ALOGI("%s: Enter RequestId:%d", __FUNCTION__, id); + ALOGI("%s: RequestId:%d", __FUNCTION__, id); - if (GScanPnoSetPasspointListCmdEventHandler == NULL) { + if (gScanPnoSetPasspointListCmdEventHandler == NULL || + (gScanPnoSetPasspointListCmdEventHandler->isEventHandlingEnabled() == + false)) { ALOGE("wifi_reset_passpoint_list: ePNO passpoint_list isn't set. " - "Nothing to do. Exit"); + "Nothing to do. Exit."); return WIFI_ERROR_NOT_AVAILABLE; } @@ -2593,37 +2810,18 @@ wifi_error wifi_reset_passpoint_list(wifi_request_id id, ret = gScanCommand->requestResponse(); if (ret != 0) { ALOGE("%s: requestResponse Error:%d",__FUNCTION__, ret); - if (GScanPnoSetPasspointListCmdEventHandler) { - delete GScanPnoSetPasspointListCmdEventHandler; - GScanPnoSetPasspointListCmdEventHandler = NULL; - } - goto cleanup; } - if (GScanPnoSetPasspointListCmdEventHandler) { - delete GScanPnoSetPasspointListCmdEventHandler; - GScanPnoSetPasspointListCmdEventHandler = NULL; + /* Disable Event Handling. */ + if (gScanPnoSetPasspointListCmdEventHandler) { + gScanPnoSetPasspointListCmdEventHandler->disableEventHandling(); } cleanup: delete gScanCommand; - ALOGI("%s: Exit.", __FUNCTION__); return (wifi_error)ret; } -int GScanCommand::setCallbackHandler(GScanCallbackHandler nHandler) -{ - int res = 0; - mHandler = nHandler; - res = registerVendorHandler(mVendor_id, mSubcmd); - if (res != 0) { - /* Error case: should not happen, so print a log when it does. */ - ALOGE("%s: Unable to register Vendor Handler Vendor Id=0x%x subcmd=%u", - __FUNCTION__, mVendor_id, mSubcmd); - } - return res; -} - int GScanCommand::allocCachedResultsTemp(int max, wifi_cached_scan_results *cached_results) { @@ -2723,8 +2921,6 @@ wifi_error GScanCommand::copyCachedScanResults( int i; wifi_cached_scan_results *cachedResultRsp; - ALOGI("%s: Enter", __FUNCTION__); - if (mGetCachedResultsRspParams && cached_results) { /* Populate the number of parsed cached results. */ @@ -2754,7 +2950,6 @@ wifi_error GScanCommand::copyCachedScanResults( *numResults = 0; ret = WIFI_ERROR_INVALID_ARGS; } - ALOGI("%s: Exit", __FUNCTION__); return ret; } @@ -2801,7 +2996,7 @@ wifi_error wifi_set_ssid_white_list(wifi_request_id id, return WIFI_ERROR_NOT_SUPPORTED; } - ALOGI("%s: Enter RequestId:%d", __FUNCTION__, id); + ALOGI("%s: RequestId:%d", __FUNCTION__, id); ALOGI("Number of SSIDs : %d", num_networks); for (i = 0; i < num_networks; i++) { @@ -2869,7 +3064,6 @@ wifi_error wifi_set_ssid_white_list(wifi_request_id id, cleanup: delete roamCommand; - ALOGI("%s: Exit.", __FUNCTION__); return (wifi_error)ret; } @@ -2891,7 +3085,7 @@ wifi_error wifi_set_gscan_roam_params(wifi_request_id id, return WIFI_ERROR_NOT_SUPPORTED; } - ALOGI("%s: Enter RequestId:%d", __FUNCTION__, id); + ALOGI("%s: RequestId:%d", __FUNCTION__, id); if(params) { ALOGI("A_band_boost_threshold %d", params->A_band_boost_threshold); @@ -2968,7 +3162,6 @@ wifi_error wifi_set_gscan_roam_params(wifi_request_id id, cleanup: delete roamCommand; - ALOGI("%s: Exit.", __FUNCTION__); return (wifi_error)ret; } @@ -3038,7 +3231,6 @@ wifi_error wifi_enable_lazy_roam(wifi_request_id id, cleanup: delete roamCommand; - ALOGI("%s: Exit.", __FUNCTION__); return (wifi_error)ret; } @@ -3061,7 +3253,7 @@ wifi_error wifi_set_bssid_preference(wifi_request_id id, return WIFI_ERROR_NOT_SUPPORTED; } - ALOGI("%s: Enter RequestId:%d", __FUNCTION__, id); + ALOGI("%s: RequestId:%d", __FUNCTION__, id); ALOGI("Number of BSSIDs: %d", num_bssid); if(prefs && num_bssid) { @@ -3140,7 +3332,6 @@ wifi_error wifi_set_bssid_preference(wifi_request_id id, cleanup: delete roamCommand; - ALOGI("%s: Exit.", __FUNCTION__); return (wifi_error)ret; } @@ -3162,7 +3353,7 @@ wifi_error wifi_set_bssid_blacklist(wifi_request_id id, return WIFI_ERROR_NOT_SUPPORTED; } - ALOGI("%s: Enter RequestId:%d", __FUNCTION__, id); + ALOGI("%s: RequestId:%d", __FUNCTION__, id); for (i = 0; i < params.num_bssid; i++) { ALOGI("BSSID: %d : %02x:%02x:%02x:%02x:%02x:%02x", i, @@ -3231,7 +3422,6 @@ wifi_error wifi_set_bssid_blacklist(wifi_request_id id, cleanup: delete roamCommand; - ALOGI("%s: Exit.", __FUNCTION__); return (wifi_error)ret; } diff --git a/qcwcn/wifi_hal/gscan_event_handler.cpp b/qcwcn/wifi_hal/gscan_event_handler.cpp index dc54c70..371bc94 100644 --- a/qcwcn/wifi_hal/gscan_event_handler.cpp +++ b/qcwcn/wifi_hal/gscan_event_handler.cpp @@ -50,6 +50,26 @@ void GScanCommandEventHandler::set_request_id(int request_id) mRequestId = request_id; } +void GScanCommandEventHandler::enableEventHandling() +{ + mEventHandlingEnabled = true; +} + +void GScanCommandEventHandler::disableEventHandling() +{ + mEventHandlingEnabled = false; +} + +bool GScanCommandEventHandler::isEventHandlingEnabled() +{ + return mEventHandlingEnabled; +} + +void GScanCommandEventHandler::setCallbackHandler(GScanCallbackHandler handler) +{ + mHandler = handler; +} + GScanCommandEventHandler::GScanCommandEventHandler(wifi_handle handle, int id, u32 vendor_id, u32 subcmd, @@ -64,6 +84,9 @@ GScanCommandEventHandler::GScanCommandEventHandler(wifi_handle handle, int id, mHotlistApFoundResults = NULL; mHotlistApFoundNumResults = 0; mHotlistApFoundMoreData = false; + mHotlistApLostResults = NULL; + mHotlistApLostNumResults = 0; + mHotlistApLostMoreData = false; mSignificantChangeResults = NULL; mSignificantChangeNumResults = 0; mSignificantChangeMoreData = false; @@ -80,6 +103,7 @@ GScanCommandEventHandler::GScanCommandEventHandler(wifi_handle handle, int id, mPasspointAnqp = NULL; mPasspointAnqpLen = 0; mPasspointNetId = -1; + mEventHandlingEnabled = false; switch(mSubCommandId) { @@ -94,7 +118,7 @@ GScanCommandEventHandler::GScanCommandEventHandler(wifi_handle handle, int id, QCA_NL80211_VENDOR_SUBCMD_GSCAN_FULL_SCAN_RESULT) || registerVendorHandler(mVendor_id, QCA_NL80211_VENDOR_SUBCMD_GSCAN_SCAN_EVENT); - if (ret < 0) + if (ret) ALOGD("%s: Error in registering handler for " "GSCAN_START. \n", __FUNCTION__); } @@ -104,7 +128,7 @@ GScanCommandEventHandler::GScanCommandEventHandler(wifi_handle handle, int id, { ret = registerVendorHandler(mVendor_id, QCA_NL80211_VENDOR_SUBCMD_GSCAN_SIGNIFICANT_CHANGE); - if (ret < 0) + if (ret) ALOGD("%s: Error in registering handler for " "GSCAN_SIGNIFICANT_CHANGE. \n", __FUNCTION__); } @@ -114,13 +138,13 @@ GScanCommandEventHandler::GScanCommandEventHandler(wifi_handle handle, int id, { ret = registerVendorHandler(mVendor_id, QCA_NL80211_VENDOR_SUBCMD_GSCAN_HOTLIST_AP_FOUND); - if (ret < 0) + if (ret) ALOGD("%s: Error in registering handler for" " GSCAN_HOTLIST_AP_FOUND. \n", __FUNCTION__); ret = registerVendorHandler(mVendor_id, QCA_NL80211_VENDOR_SUBCMD_GSCAN_HOTLIST_AP_LOST); - if (ret < 0) + if (ret) ALOGD("%s: Error in registering handler for" " GSCAN_HOTLIST_AP_LOST. \n", __FUNCTION__); } @@ -130,13 +154,13 @@ GScanCommandEventHandler::GScanCommandEventHandler(wifi_handle handle, int id, { ret = registerVendorHandler(mVendor_id, QCA_NL80211_VENDOR_SUBCMD_GSCAN_HOTLIST_SSID_FOUND); - if (ret < 0) + if (ret) ALOGD("%s: Error in registering handler for" " GSCAN_HOTLIST_SSID_FOUND. \n", __FUNCTION__); ret = registerVendorHandler(mVendor_id, QCA_NL80211_VENDOR_SUBCMD_GSCAN_HOTLIST_SSID_LOST); - if (ret < 0) + if (ret) ALOGD("%s: Error in registering handler for" " GSCAN_HOTLIST_SSID_LOST. \n", __FUNCTION__); } @@ -146,7 +170,7 @@ GScanCommandEventHandler::GScanCommandEventHandler(wifi_handle handle, int id, { ret = registerVendorHandler(mVendor_id, QCA_NL80211_VENDOR_SUBCMD_PNO_NETWORK_FOUND); - if (ret < 0) + if (ret) ALOGD("%s: Error in registering handler for" " PNO_NETWORK_FOUND. \n", __FUNCTION__); } @@ -156,7 +180,7 @@ GScanCommandEventHandler::GScanCommandEventHandler(wifi_handle handle, int id, { ret = registerVendorHandler(mVendor_id, QCA_NL80211_VENDOR_SUBCMD_PNO_PASSPOINT_NETWORK_FOUND); - if (ret < 0) + if (ret) ALOGD("%s: Error in registering handler for" " PNO_PASSPOINT_NETWORK_FOUND. \n", __FUNCTION__); } @@ -1077,14 +1101,19 @@ wifi_error GScanCommandEventHandler::gscan_parse_pno_network_results( */ int GScanCommandEventHandler::handleEvent(WifiEvent &event) { - ALOGI("GScanCommandEventHandler::handleEvent: Got a GSCAN Event" - " message from the Driver."); unsigned i=0; int ret = WIFI_SUCCESS; u32 status; wifi_scan_result *result = NULL; struct nlattr *tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX + 1]; + if (mEventHandlingEnabled == false) + { + ALOGD("%s:Discarding event: %d", + __FUNCTION__, mSubcmd); + return NL_SKIP; + } + WifiVendorCommand::handleEvent(event); nla_parse(tbVendor, QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX, @@ -1100,9 +1129,10 @@ int GScanCommandEventHandler::handleEvent(WifiEvent &event) u32 resultsBufSize = 0; u32 lengthOfInfoElements = 0; +#ifdef QC_HAL_DEBUG ALOGD("Event QCA_NL80211_VENDOR_SUBCMD_GSCAN_FULL_SCAN_RESULT " "received."); - +#endif if (!tbVendor[ QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID]) { @@ -1118,8 +1148,10 @@ int GScanCommandEventHandler::handleEvent(WifiEvent &event) * request_id value which we're maintaining. */ if (reqId != mRequestId) { +#ifdef QC_HAL_DEBUG ALOGE("%s: Event has Req. ID:%d <> Ours:%d, continue...", __FUNCTION__, reqId, mRequestId); +#endif reqId = mRequestId; } @@ -1137,7 +1169,7 @@ int GScanCommandEventHandler::handleEvent(WifiEvent &event) nla_get_u32( tbVendor[ QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_IE_LENGTH]); - ALOGI("%s: RESULTS_SCAN_RESULT_IE_LENGTH =%d", + ALOGD("%s: RESULTS_SCAN_RESULT_IE_LENGTH =%d", __FUNCTION__, lengthOfInfoElements); resultsBufSize = lengthOfInfoElements + sizeof(wifi_scan_result); diff --git a/qcwcn/wifi_hal/gscan_event_handler.h b/qcwcn/wifi_hal/gscan_event_handler.h index 41b5d95..cc828f9 100644 --- a/qcwcn/wifi_hal/gscan_event_handler.h +++ b/qcwcn/wifi_hal/gscan_event_handler.h @@ -60,6 +60,7 @@ private: * WifiVendorCommand::handleEvent() */ u32 mSubCommandId; + bool mEventHandlingEnabled; public: GScanCommandEventHandler(wifi_handle handle, int id, u32 vendor_id, @@ -69,6 +70,10 @@ public: virtual int get_request_id(); virtual void set_request_id(int request_id); virtual int handleEvent(WifiEvent &event); + void enableEventHandling(); + void disableEventHandling(); + bool isEventHandlingEnabled(); + void setCallbackHandler(GScanCallbackHandler handler); wifi_error gscan_parse_hotlist_ap_results( u32 num_results, wifi_scan_result *results, diff --git a/qcwcn/wifi_hal/gscancommand.h b/qcwcn/wifi_hal/gscancommand.h index 77acca7..f03bb45 100644 --- a/qcwcn/wifi_hal/gscancommand.h +++ b/qcwcn/wifi_hal/gscancommand.h @@ -122,7 +122,6 @@ public: virtual int create(); virtual int requestResponse(); virtual int handleResponse(WifiEvent &reply); - virtual int setCallbackHandler(GScanCallbackHandler nHandler); virtual void setMaxChannels(int max_channels); virtual void setChannels(int *channels); virtual void setNumChannelsPtr(int *num_channels); diff --git a/qcwcn/wifi_hal/llstats.cpp b/qcwcn/wifi_hal/llstats.cpp index 5ae8452..f900054 100644 --- a/qcwcn/wifi_hal/llstats.cpp +++ b/qcwcn/wifi_hal/llstats.cpp @@ -47,7 +47,6 @@ int LLStatsCommand::create() { if (ret < 0) goto out; - ALOGI("mVendor_id = %d, Subcmd = %d in %s:%d\n", mVendor_id, mSubcmd, __func__, __LINE__); out: return ret; } @@ -55,7 +54,6 @@ out: LLStatsCommand::LLStatsCommand(wifi_handle handle, int id, u32 vendor_id, u32 subcmd) : WifiVendorCommand(handle, id, vendor_id, subcmd) { - ALOGV("LLStatsCommand %p constructed", this); memset(&mClearRspParams, 0,sizeof(LLStatsClearRspParams)); memset(&mResultsParams, 0,sizeof(LLStatsResultsParams)); memset(&mHandler, 0,sizeof(mHandler)); @@ -63,7 +61,6 @@ LLStatsCommand::LLStatsCommand(wifi_handle handle, int id, u32 vendor_id, u32 su LLStatsCommand::~LLStatsCommand() { - ALOGW("LLStatsCommand %p distructor", this); mLLStatsCommandInstance = NULL; } @@ -77,7 +74,6 @@ LLStatsCommand* LLStatsCommand::instance(wifi_handle handle) mLLStatsCommandInstance = new LLStatsCommand(handle, 0, OUI_QCA, QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET); - ALOGV("LLStatsCommand %p created", mLLStatsCommandInstance); return mLLStatsCommandInstance; } else @@ -90,7 +86,6 @@ LLStatsCommand* LLStatsCommand::instance(wifi_handle handle) mLLStatsCommandInstance->mInfo = (hal_info *)handle; } } - ALOGV("LLStatsCommand %p created already", mLLStatsCommandInstance); return mLLStatsCommandInstance; } @@ -193,17 +188,30 @@ static wifi_error get_wifi_interface_info(wifi_interface_link_layer_info *stats, memcpy(&stats->country_str[0], nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR]), len); - ALOGI("STATS IFACE: Mode %d", stats->mode); - ALOGI("STATS IFACE: MAC %pM", stats->mac_addr); - ALOGI("STATS IFACE: State %d ", stats->state); - ALOGI("STATS IFACE: Roaming %d ", stats->roaming); - ALOGI("STATS IFACE: capabilities %0x ", stats->capabilities); - ALOGI("STATS IFACE: SSID %s ", stats->ssid); - ALOGI("STATS IFACE: BSSID %pM ", stats->bssid); - ALOGI("STATS IFACE: AP country str %c%c%c ", stats->ap_country_str[0], - stats->ap_country_str[1], stats->ap_country_str[2]); - ALOGI("STATS IFACE:Country String for this Association %c%c%c", stats->country_str[0], - stats->country_str[1], stats->country_str[2]); + ALOGV("Mode : %d\n" + "Mac addr : " + MAC_ADDR_STR + "\nState : %d\n" + "Roaming : %d\n" + "capabilities : %0x\n" + "SSID :%s\n" + "BSSID : " + MAC_ADDR_STR + "\nAP country str : %c%c%c\n" + "Country String for this Association : %c%c%c", + stats->mode, + MAC_ADDR_ARRAY(stats->mac_addr), + stats->state, + stats->roaming, + stats->capabilities, + stats->ssid, + MAC_ADDR_ARRAY(stats->bssid), + stats->ap_country_str[0], + stats->ap_country_str[1], + stats->ap_country_str[2], + stats->country_str[0], + stats->country_str[1], + stats->country_str[2]); return WIFI_SUCCESS; } @@ -316,27 +324,25 @@ static wifi_error get_wifi_wmm_ac_stat(wifi_wmm_ac_stat *stats, } stats->contention_num_samples = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES]); - ALOGI("STATS IFACE: ac %u ", stats->ac); - ALOGI("STATS IFACE: txMpdu %u ", stats->tx_mpdu) ; - ALOGI("STATS IFACE: rxMpdu %u ", stats->rx_mpdu); - ALOGI("STATS IFACE: txMcast %u ", stats->tx_mcast); - ALOGI("STATS IFACE: rxMcast %u ", stats->rx_mcast); - ALOGI("STATS IFACE: rxAmpdu %u ", stats->rx_ampdu); - ALOGI("STATS IFACE: txAmpdu %u ", stats->tx_ampdu); - ALOGI("STATS IFACE: mpduLost %u ", stats->mpdu_lost); - ALOGI("STATS IFACE: retries %u ", stats->retries); - ALOGI("STATS IFACE: retriesShort %u ", - stats->retries_short); - ALOGI("STATS IFACE: retriesLong %u ", - stats->retries_long); - ALOGI("STATS IFACE: contentionTimeMin %u ", - stats->contention_time_min); - ALOGI("STATS IFACE: contentionTimeMax %u ", - stats->contention_time_max); - ALOGI("STATS IFACE: contentionTimeAvg %u ", - stats->contention_time_avg); - ALOGI("STATS IFACE: contentionNumSamples %u ", - stats->contention_num_samples); + ALOGV("%4u | %6u | %6u | %7u | %7u | %7u |" + " %7u | %8u | %7u | %12u |" + " %11u | %17u | %17u |" + " %17u | %20u", + stats->ac, + stats->tx_mpdu, + stats->rx_mpdu, + stats->tx_mcast, + stats->rx_mcast, + stats->rx_ampdu, + stats->tx_ampdu, + stats->mpdu_lost, + stats->retries, + stats->retries_short, + stats->retries_long, + stats->contention_time_min, + stats->contention_time_max, + stats->contention_time_avg, + stats->contention_num_samples); return WIFI_SUCCESS; } @@ -421,18 +427,18 @@ static wifi_error get_wifi_rate_stat(wifi_rate_stat *stats, } stats->retries_long = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG]); - ALOGI("STATS PEER_ALL : preamble %u", stats->rate.preamble); - ALOGI("STATS PEER_ALL : nss %u", stats->rate.nss); - ALOGI("STATS PEER_ALL : bw %u", stats->rate.bw); - ALOGI("STATS PEER_ALL : rateMcsIdx %u", stats->rate.rateMcsIdx); - ALOGI("STATS PEER_ALL : bitrate %u", stats->rate.bitrate); - - ALOGI("STATS PEER_ALL : txMpdu %u", stats->tx_mpdu); - ALOGI("STATS PEER_ALL : rxMpdu %u", stats->rx_mpdu); - ALOGI("STATS PEER_ALL : mpduLost %u", stats->mpdu_lost); - ALOGI("STATS PEER_ALL : retries %u", stats->retries); - ALOGI("STATS PEER_ALL : retriesShort %u", stats->retries_short); - ALOGI("STATS PEER_ALL : retriesLong %u", stats->retries_long); + ALOGV("%8u | %3u | %2u | %10u | %7u | %6u | %6u | %8u | %7u | %12u | %11u", + stats->rate.preamble, + stats->rate.nss, + stats->rate.bw, + stats->rate.rateMcsIdx, + stats->rate.bitrate, + stats->tx_mpdu, + stats->rx_mpdu, + stats->mpdu_lost, + stats->retries, + stats->retries_short, + stats->retries_long); return WIFI_SUCCESS; } @@ -476,13 +482,10 @@ static wifi_error get_wifi_peer_info(wifi_peer_info *stats, } stats->num_rate = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES]); - ALOGI("STATS PEER_ALL : numPeers %u", stats->type); - ALOGI("STATS PEER_ALL : peerMacAddress %0x:%0x:%0x:%0x:%0x:%0x ", - stats->peer_mac_address[0], stats->peer_mac_address[1], - stats->peer_mac_address[2],stats->peer_mac_address[3], - stats->peer_mac_address[4],stats->peer_mac_address[5]); - ALOGI("STATS PEER_ALL : capabilities %0x", stats->capabilities); - ALOGI("STATS PEER_ALL : numRate %u", stats->num_rate); + ALOGV("PEER STATS"); + ALOGV("numPeers %u Peer MAC addr :" MAC_ADDR_STR " capabilities %0x numRate %u", + stats->type, MAC_ADDR_ARRAY(stats->peer_mac_address), + stats->capabilities, stats->num_rate); if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO]) @@ -490,6 +493,8 @@ static wifi_error get_wifi_peer_info(wifi_peer_info *stats, ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO not found", __func__); return WIFI_ERROR_INVALID_ARGS; } + ALOGV("%8s | %3s | %2s | %10s | %7s | %6s | %6s | %8s | %7s | %12s | %11s", + "preamble", "nss", "bw", "rateMcsIdx", "bitrate", "txMpdu", "rxMpdu", "mpduLost", "retries", "retriesShort", "retriesLong"); for (rateInfo = (struct nlattr *) nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO]), rem = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO]); nla_ok(rateInfo, rem); rateInfo = nla_next(rateInfo, &(rem))) @@ -624,14 +629,21 @@ wifi_error LLStatsCommand::get_wifi_iface_stats(wifi_iface_stat *stats, stats->rssi_ack = get_s32(tb_vendor[ QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK]); - ALOGI("STATS IFACE: beaconRx : %u ", stats->beacon_rx); - ALOGI("STATS IFACE: mgmtRx %u ", stats->mgmt_rx); - ALOGI("STATS IFACE: mgmtActionRx %u ", stats->mgmt_action_rx); - ALOGI("STATS IFACE: mgmtActionTx %u ", stats->mgmt_action_tx); - ALOGI("STATS IFACE: rssiMgmt %d ", stats->rssi_mgmt); - ALOGI("STATS IFACE: rssiData %d ", stats->rssi_data); - ALOGI("STATS IFACE: rssiAck %d ", stats->rssi_ack); - + ALOGV("WMM STATS"); + ALOGV("beaconRx : %u " + "mgmtRx : %u " + "mgmtActionRx : %u " + "mgmtActionTx : %u " + "rssiMgmt : %d " + "rssiData : %d " + "rssiAck : %d ", + stats->beacon_rx, + stats->mgmt_rx, + stats->mgmt_action_rx, + stats->mgmt_action_tx, + stats->rssi_mgmt, + stats->rssi_data, + stats->rssi_ack); if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO]) { ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO" @@ -639,6 +651,14 @@ wifi_error LLStatsCommand::get_wifi_iface_stats(wifi_iface_stat *stats, return WIFI_ERROR_INVALID_ARGS; } + ALOGV("%4s | %6s | %6s | %7s | %7s | %7s |" + " %7s | %8s | %7s | %12s |" + " %11s | %17s | %17s |" + " %17s | %20s", + "ac","txMpdu", "rxMpdu", "txMcast", "rxMcast", "rxAmpdu", + "txAmpdu", "mpduLost", "retries", "retriesShort", + "retriesLong", "contentionTimeMin", "contentionTimeMax", + "contentionTimeAvg", "contentionNumSamples"); for (wmmInfo = (struct nlattr *) nla_data(tb_vendor[ QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO]), rem = nla_len(tb_vendor[ @@ -821,7 +841,6 @@ int LLStatsCommand::requestResponse() int LLStatsCommand::handleResponse(WifiEvent &reply) { - ALOGI("Got a LLStats message from Driver"); unsigned i=0; int status = WIFI_ERROR_NONE; WifiVendorCommand::handleResponse(reply); @@ -852,8 +871,7 @@ int LLStatsCommand::handleResponse(WifiEvent &reply) { case QCA_NL80211_VENDOR_SUBCMD_LL_STATS_TYPE_RADIO: { - ALOGI("QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS" - " Received"); + ALOGV("Radio Stats Received: "); if (!tb_vendor[ QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS ]) @@ -865,10 +883,6 @@ int LLStatsCommand::handleResponse(WifiEvent &reply) goto cleanup; } - ALOGI(" NumChan is %d\n ", - nla_get_u32(tb_vendor[ - QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS])); - resultsBufSize += (nla_get_u32(tb_vendor[ QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS]) * sizeof(wifi_channel_stat) @@ -891,24 +905,24 @@ int LLStatsCommand::handleResponse(WifiEvent &reply) goto cleanup; } - ALOGI(" radio is %u ", mResultsParams.radio_stat->radio); - ALOGI(" onTime is %u ", mResultsParams.radio_stat->on_time); - ALOGI(" txTime is %u ", mResultsParams.radio_stat->tx_time); - ALOGI(" rxTime is %u ", mResultsParams.radio_stat->rx_time); - ALOGI(" onTimeScan is %u ", - mResultsParams.radio_stat->on_time_scan); - ALOGI(" onTimeNbd is %u ", - mResultsParams.radio_stat->on_time_nbd); - ALOGI(" onTimeGscan is %u ", - mResultsParams.radio_stat->on_time_gscan); - ALOGI(" onTimeRoamScan is %u", - mResultsParams.radio_stat->on_time_roam_scan); - ALOGI(" onTimePnoScan is %u ", - mResultsParams.radio_stat->on_time_pno_scan); - ALOGI(" onTimeHs20 is %u ", - mResultsParams.radio_stat->on_time_hs20); - ALOGI(" numChannels is %u ", - mResultsParams.radio_stat->num_channels); + ALOGV("radio :%u onTime :%u txTime :%u rxTime :%u" + " onTimeScan :%u onTimeNbd :%u onTimeGscan :%u" + " onTimeRoamScan :%u onTimePnoScan :%u" + " onTimeHs20 :%u numChannels :%u", + mResultsParams.radio_stat->radio, + mResultsParams.radio_stat->on_time, + mResultsParams.radio_stat->tx_time, + mResultsParams.radio_stat->rx_time, + mResultsParams.radio_stat->on_time_scan, + mResultsParams.radio_stat->on_time_nbd, + mResultsParams.radio_stat->on_time_gscan, + mResultsParams.radio_stat->on_time_roam_scan, + mResultsParams.radio_stat->on_time_pno_scan, + mResultsParams.radio_stat->on_time_hs20, + mResultsParams.radio_stat->num_channels); + ALOGV("%5s | %10s | %11s | %11s | %6s | %11s", "width", + "CenterFreq", "CenterFreq0", "CenterFreq1", + "onTime", "ccaBusyTime"); for ( i=0; i < mResultsParams.radio_stat->num_channels; i++) { pWifiChannelStats = @@ -916,26 +930,20 @@ int LLStatsCommand::handleResponse(WifiEvent &reply) (u8 *)mResultsParams.radio_stat->channels + (i * sizeof(wifi_channel_stat))); - ALOGI(" width is %u ", - pWifiChannelStats->channel.width); - ALOGI(" CenterFreq %u ", - pWifiChannelStats->channel.center_freq); - ALOGI(" CenterFreq0 %u ", - pWifiChannelStats->channel.center_freq0); - ALOGI(" CenterFreq1 %u ", - pWifiChannelStats->channel.center_freq1); - ALOGI(" onTime %u ", - pWifiChannelStats->on_time); - ALOGI(" ccaBusyTime %u ", - pWifiChannelStats->cca_busy_time); + ALOGV("%5u | %10u | %11u | %11u | %6u | %11u", + pWifiChannelStats->channel.width, + pWifiChannelStats->channel.center_freq, + pWifiChannelStats->channel.center_freq0, + pWifiChannelStats->channel.center_freq1, + pWifiChannelStats->on_time, + pWifiChannelStats->cca_busy_time); } } break; case QCA_NL80211_VENDOR_SUBCMD_LL_STATS_TYPE_IFACE: { - ALOGI("QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS" - " Received"); + ALOGV("Iface Stats Received"); resultsBufSize = sizeof(wifi_iface_stat); mResultsParams.iface_stat = (wifi_iface_stat *) malloc (resultsBufSize); @@ -963,16 +971,14 @@ int LLStatsCommand::handleResponse(WifiEvent &reply) { ALOGE("%s:QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS" " not found", __func__); - ALOGE("Expecting Peer stats event"); } else { mResultsParams.iface_stat->num_peers = nla_get_u32(tb_vendor[ QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS]); - ALOGI("%s: numPeers is %u\n", __func__, + ALOGV("%s: numPeers is %u\n", __func__, mResultsParams.iface_stat->num_peers); if(mResultsParams.iface_stat->num_peers == 0) { - ALOGE("Not Expecting Peer stats event"); // Number of Radios are 1 for now mHandler.on_link_stats_results(mRequestId, mResultsParams.iface_stat, @@ -995,8 +1001,7 @@ int LLStatsCommand::handleResponse(WifiEvent &reply) struct nlattr *peerInfo; wifi_iface_stat *pIfaceStat; u32 numPeers, num_rates = 0; - ALOGI("QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS" - " Received"); + ALOGV("Peer Stats Received"); if (!tb_vendor[ QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS]) { @@ -1005,7 +1010,7 @@ int LLStatsCommand::handleResponse(WifiEvent &reply) status = WIFI_ERROR_INVALID_ARGS; goto cleanup; } - ALOGI(" numPeers is %u in %s\n", + ALOGV(" numPeers is %u in %s\n", nla_get_u32(tb_vendor[ QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS]), __func__); @@ -1190,6 +1195,8 @@ wifi_error wifi_set_link_stats(wifi_interface_handle iface, interface_info *iinfo = getIfaceInfo(iface); wifi_handle handle = getWifiHandle(iface); + ALOGI("mpdu_size_threshold : %u, aggressive_statistics_gathering : %u", + params.mpdu_size_threshold, params.aggressive_statistics_gathering); LLCommand = LLStatsCommand::instance(handle); if (LLCommand == NULL) { ALOGE("%s: Error LLStatsCommand NULL", __func__); @@ -1302,6 +1309,7 @@ wifi_error wifi_clear_link_stats(wifi_interface_handle iface, interface_info *iinfo = getIfaceInfo(iface); wifi_handle handle = getWifiHandle(iface); + ALOGI("clear_req : %x, stop_req : %u", stats_clear_req_mask, stop_req); LLCommand = LLStatsCommand::instance(handle); if (LLCommand == NULL) { ALOGE("%s: Error LLStatsCommand NULL", __func__); diff --git a/qcwcn/wifi_hal/nan_ind.cpp b/qcwcn/wifi_hal/nan_ind.cpp index 85d747d..78daf89 100755 --- a/qcwcn/wifi_hal/nan_ind.cpp +++ b/qcwcn/wifi_hal/nan_ind.cpp @@ -898,9 +898,16 @@ int NanCommand::getNanFurtherAvailabilityMap(const u8 *pInValue, __func__, pFam->numchans); return -1; } + + if (length < (sizeof(u8) + + (pFam->numchans * sizeof(NanFurtherAvailabilityChan)))) { + ALOGE("%s: Invalid TLV Length", __func__); + return -1; + } + for (idx = 0; idx < pFam->numchans; idx++) { pNanFurtherAvailabilityChan pRsp = \ - (pNanFurtherAvailabilityChan)(pInValue[1] + \ + (pNanFurtherAvailabilityChan)((u8 *)&pInValue[1] + \ (idx * sizeof(NanFurtherAvailabilityChan))); NanFurtherAvailabilityChannel *pFamChan = &pFam->famchan[idx]; diff --git a/qcwcn/wifi_hal/nan_req.cpp b/qcwcn/wifi_hal/nan_req.cpp index dd9b787..7eb7d97 100755..100644 --- a/qcwcn/wifi_hal/nan_req.cpp +++ b/qcwcn/wifi_hal/nan_req.cpp @@ -1050,9 +1050,8 @@ void NanCommand::fillNanFurtherAvailabilityMapVal( const NanFurtherAvailabilityMap *pFam, u8 *pOutValue) { -//ToDo: Fixme - build issue -#if 0 int idx = 0; + if (pFam && pOutValue) { u32 famsize = calcNanFurtherAvailabilityMapSize(pFam); pNanFurtherAvailabilityMapAttrTlv pFwReq = \ @@ -1080,7 +1079,6 @@ void NanCommand::fillNanFurtherAvailabilityMapVal( ALOGI("%s: Filled FurtherAvailabilityMapVal", __func__); hexdump((char*)pOutValue, famsize); } -#endif return; } @@ -1093,8 +1091,7 @@ int NanCommand::calcNanFurtherAvailabilityMapSize( /* Fixed size of u8 for numchans*/ ret = sizeof(u8); /* numchans * sizeof(FamChannels) */ - //ToDo: Fix build - //ret += (pFam->numchans * sizeof(NanFurtherAvailabilityChan)); + ret += (pFam->numchans * sizeof(NanFurtherAvailabilityChan)); } ALOGI("%s:size:%d", __func__, ret); return ret; diff --git a/qcwcn/wifi_hal/pkt_stats.h b/qcwcn/wifi_hal/pkt_stats.h index a8bd10e..89e51e9 100644 --- a/qcwcn/wifi_hal/pkt_stats.h +++ b/qcwcn/wifi_hal/pkt_stats.h @@ -44,6 +44,30 @@ #define PKTLOG_TYPE_RC_UPDATE 7 #define PKTLOG_TYPE_TX_VIRT_ADDR 8 #define PKTLOG_TYPE_MAX 9 +#define BW_OFFSET 8 +#define INVALID_RSSI 255 + +#define PKT_INFO_FLG_TX_LOCAL_S 0x1 +#define PKT_INFO_FLG_RX_HOST_RXD 0x2 +#define PKT_INFO_FLG_TX_REMOTE_S 0x4 +#define PKT_INFO_FLG_RX_LOCAL_S 0x8 +#define PKT_INFO_FLG_RX_REMOTE_S 0x10 +#define PKT_INFO_FLG_RX_LOCAL_DISCARD_S 0x20 +#define PKT_INFO_FLG_RX_REMOTE_DISCARD_S 0x40 +#define PKT_INFO_FLG_RX_REORDER_STORE_S 0x80 +#define PKT_INFO_FLG_RX_REORDER_DROP_S 0x100 +#define PKT_INFO_FLG_RX_PEER_INFO_S 0x200 +#define PKT_INFO_FLG_UNKNOWN_S 0x400 + +/* MASK value of flags based on RX_STAT content. + * These are the events that carry Rx decriptor + */ +#define PKT_INFO_FLG_RX_RXDESC_MASK \ + (PKT_INFO_FLG_RX_HOST_RXD | \ + PKT_INFO_FLG_RX_LOCAL_S | \ + PKT_INFO_FLG_RX_REMOTE_S | \ + PKT_INFO_FLG_RX_LOCAL_DISCARD_S | \ + PKT_INFO_FLG_RX_REMOTE_DISCARD_S) /* Format of the packet stats event*/ typedef struct { @@ -55,6 +79,24 @@ typedef struct { } __attribute__((packed)) wh_pktlog_hdr_t; /*Rx stats specific structures. */ +struct rx_attention { + u32 first_mpdu : 1; //[0] + u32 last_mpdu : 1; //[1] + u32 reserved1 : 6; //[7:2] + u32 mgmt_type : 1; //[8] + u32 ctrl_type : 1; //[9] + u32 reserved2 : 6; //[15:10] + u32 overflow_err : 1; //[16] + u32 msdu_length_err : 1; //[17] + u32 tcp_udp_chksum_fail : 1; //[18] + u32 ip_chksum_fail : 1; //[19] + u32 reserved3 : 7; //[26:20] + u32 mpdu_length_err : 1; //[27] + u32 tkip_mic_err : 1; //[28] + u32 decrypt_err : 1; //[29] + u32 fcs_err : 1; //[30] + u32 msdu_done : 1; //[31] +} __attribute__((packed)); struct rx_mpdu_start { u32 reserved1 : 13; //[12:0] @@ -83,17 +125,40 @@ struct rx_msdu_start { u32 reserved3 : 22; //[31:10] } __attribute__((packed)); +struct rx_msdu_end { + u32 reserved1[4]; + u32 reserved2 : 15; + u32 last_msdu : 1; //[15] + u32 reserved3 : 16; //[31:16] +} __attribute__((packed)); + struct rx_mpdu_end { - u32 reserved1 : 29; //[28:0] + u32 reserved1 : 13; //[12:0] + u32 overflow_err : 1; //[13] + u32 last_mpdu : 1; //[14] + u32 post_delim_err : 1; //[15] + u32 reserved2 : 12; //[27:16] + u32 mpdu_length_err : 1; //[28] u32 tkip_mic_err : 1; //[29] - u32 reserved2 : 2; //[31:30] + u32 decrypt_err : 1; //[30] + u32 fcs_err : 1; //[31] } __attribute__((packed)); #define PREAMBLE_L_SIG_RATE 0x04 #define PREAMBLE_VHT_SIG_A_1 0x08 #define PREAMBLE_VHT_SIG_A_2 0x0c +/* Wifi Logger preamble */ +#define WL_PREAMBLE_CCK 0 +#define WL_PREAMBLE_OFDM 1 +#define WL_PREAMBLE_HT 2 +#define WL_PREAMBLE_VHT 3 + #define BITMASK(x) ((1<<(x)) - 1 ) +#define MAX_BA_WINDOW_SIZE 64 +#define SEQ_NUM_RANGE 4096 +#define BITMAP_VAR_SIZE 32 + /* Contains MCS related stats */ struct rx_ppdu_start { u32 reserved1[4]; @@ -111,17 +176,20 @@ struct rx_ppdu_start { } __attribute__((packed)); struct rx_ppdu_end { - u32 reserved1[17]; - u32 wb_timestamp; - u32 reserved2[4]; + u32 reserved1[16]; + u32 tsf_timestamp; + u32 reserved2[5]; } __attribute__((packed)); +#define MAX_MSDUS_PER_MPDU 3 +#define MAX_RXMPDUS_PER_AMPDU 64 #define RX_HTT_HDR_STATUS_LEN 64 typedef struct { - u32 reserved1[2]; + struct rx_attention attention; + u32 reserved1; struct rx_mpdu_start mpdu_start; struct rx_msdu_start msdu_start; - u32 reserved2[5]; + struct rx_msdu_end msdu_end; struct rx_mpdu_end mpdu_end; struct rx_ppdu_start ppdu_start; struct rx_ppdu_end ppdu_end; @@ -130,25 +198,34 @@ typedef struct { /*Tx stats specific structures. */ struct ppdu_status { - u32 reserved1 : 31; //[30:0] + u32 ba_start_seq_num : 12; //[11:0] + u32 reserved1 : 3; //[14:12] + u32 ba_status : 1; //[15] + u32 reserved2 : 15; //[30:16] u32 tx_ok : 1; //[31] - u32 reserved2[10]; + u32 ba_bitmap_31_0 : 32; //[31:0] + u32 ba_bitmap_63_32 : 32; //[31:0] + u32 reserved3[8]; u32 ack_rssi_ave : 8; //[7:0] - u32 reserved3 : 16; //[23:8] + u32 reserved4 : 16; //[23:8] u32 total_tries : 5; //[28:24] - u32 reserved4 : 3; //[31:29] - u32 reserved5[4]; + u32 reserved5 : 3; //[31:29] + u32 reserved6[4]; } __attribute__((packed)); /*Contains tx timestamp*/ struct try_status { u32 timestamp : 23; //[22:0] - u32 reserved : 9; //[23] + u32 reserved1 : 1; //[23] + u32 series : 1; //[24] + u32 reserved2 : 3; //[27:25] + u32 packet_bw : 2; //[29:28] + u32 reserved3 : 1; //[30] + u32 tx_packet : 1; //[31] } __attribute__((packed)); struct try_list { - struct try_status try_00; - u32 reserved[15]; + struct try_status try_st[16]; } __attribute__((packed)); @@ -181,13 +258,19 @@ struct tx_ppdu_start { u32 reserved1[2]; u32 start_seq_num : 12; //[11:0] u32 reserved2 : 20; //[31:12] - u32 reserved3[11]; - u32 reserved4 : 16; //[15:0] + u32 seqnum_bitmap_31_0 : 32; //[31:0] + u32 seqnum_bitmap_63_32 : 32; //[31:0] + u32 reserved3[8]; + u32 reserved4 : 15; //[14:0] + u32 ampdu : 1; //[15] + u32 no_ack : 1; //[16] + u32 reserved5 : 15; //[31:17] + u32 reserved6 : 16; //[15:0] u32 frame_control : 16; //[31:16] - u32 reserved5 : 16; //[23:21] + u32 reserved7 : 16; //[23:21] u32 qos_ctl : 16; //[31:16] - u32 reserved6[4]; - u32 reserved7 : 24; //[23:21] + u32 reserved8[4]; + u32 reserved9 : 24; //[23:21] u32 valid_s0_bw20 : 1; //[24] u32 valid_s0_bw40 : 1; //[25] u32 valid_s0_bw80 : 1; //[26] @@ -204,7 +287,7 @@ struct tx_ppdu_start { struct series_bw s1_bw40; struct series_bw s1_bw80; struct series_bw s1_bw160; - u32 reserved8[3]; + u32 reserved10[3]; } __attribute__((packed)); #define PKTLOG_MAX_TXCTL_WORDS 57 /* +2 words for bitmap */ @@ -227,14 +310,26 @@ typedef struct { */ #define RING_BUF_ENTRY_SIZE 512 +#define PKT_STATS_BUF_SIZE 128 struct pkt_stats_s { u8 tx_stats_events; - u32 prev_seq_no; /* TODO: Need to handle the case if size of the stats are more * than 512 bytes. Currently, the tx size is 34 bytes and ring buffer entry * size is 12 bytes. */ - u8 tx_stats[RING_BUF_ENTRY_SIZE]; + u8 tx_stats[PKT_STATS_BUF_SIZE]; + u8 num_msdu; + u16 start_seq_num; + u16 ba_seq_num; + u32 ba_bitmap_31_0; + u32 ba_bitmap_63_32; + u32 tx_seqnum_bitmap_31_0; + u32 tx_seqnum_bitmap_63_32; + u32 shifted_bitmap_31_0; + u32 shifted_bitmap_63_32; + bool isBlockAck; + u8 tx_bandwidth; + u8 series; }; typedef union { @@ -242,11 +337,22 @@ typedef union { u16 rate : 4; u16 nss : 2; u16 preamble : 2; - u16 bw : 8; + u16 bw : 2; + u16 short_gi : 1; + u16 reserved : 5; } mcs_s; u16 mcs; } MCS; +typedef struct { + MCS RxMCS; + u16 last_transmit_rate; + u16 rssi; + u32 timestamp; + u8 tid; +} rx_aggr_stats; + + typedef struct drv_msg_s { u16 length; diff --git a/qcwcn/wifi_hal/rb_wrapper.cpp b/qcwcn/wifi_hal/rb_wrapper.cpp index 45b7ef5..4c9e475 100644 --- a/qcwcn/wifi_hal/rb_wrapper.cpp +++ b/qcwcn/wifi_hal/rb_wrapper.cpp @@ -86,13 +86,24 @@ int is_rb_name_match(struct rb_info *rb_info, char *name) } wifi_error ring_buffer_write(struct rb_info *rb_info, u8 *buf, size_t length, - int no_of_records) + int no_of_records, size_t record_length) { - if (rb_write(rb_info->rb_ctx, buf, length, 0) != RB_SUCCESS) { - ALOGE("Failed to write into rb, RB migght be full"); - /* TODO Probably the data can be read from here the RB and then - * rb_write can be tried */ - return WIFI_ERROR_OUT_OF_MEMORY; + enum rb_status status; + + status = rb_write(rb_info->rb_ctx, buf, length, 0, record_length); + if ((status == RB_FULL) || (status == RB_RETRY)) { + push_out_rb_data(rb_info); + /* Try writing the data after reading it out */ + status = rb_write(rb_info->rb_ctx, buf, length, 0, record_length); + if (status != RB_SUCCESS) { + ALOGE("Failed to rewrite %zu bytes to rb %s with error %d", length, + rb_info->name, status); + return WIFI_ERROR_UNKNOWN; + } + } else if (status == RB_FAILURE) { + ALOGE("Failed to write %zu bytes to rb %s with error %d", length, + rb_info->name, status); + return WIFI_ERROR_UNKNOWN; } rb_info->written_records += no_of_records; @@ -104,11 +115,7 @@ void push_out_rb_data(void *cb_ctx) struct rb_info *rb_info = (struct rb_info *)cb_ctx; hal_info *info = (hal_info *)rb_info->ctx; wifi_ring_buffer_status rbs; - - if (info->on_ring_buffer_data == NULL) { - ALOGE("on_ring_buffer_data handle is not set yet"); - return; - } + wifi_ring_buffer_data_handler handler; while (1) { size_t length = 0; @@ -119,7 +126,13 @@ void push_out_rb_data(void *cb_ctx) break; } get_rb_status(rb_info, &rbs); - info->on_ring_buffer_data(rb_info->name, (char *)buf, length, &rbs); + pthread_mutex_lock(&info->lh_lock); + handler.on_ring_buffer_data = info->on_ring_buffer_data; + pthread_mutex_unlock(&info->lh_lock); + if (handler.on_ring_buffer_data) { + handler.on_ring_buffer_data(rb_info->name, (char *)buf, + length, &rbs); + } free(buf); }; gettimeofday(&rb_info->last_push_time, NULL); diff --git a/qcwcn/wifi_hal/rb_wrapper.h b/qcwcn/wifi_hal/rb_wrapper.h index a0b6b1b..6160ebc 100644 --- a/qcwcn/wifi_hal/rb_wrapper.h +++ b/qcwcn/wifi_hal/rb_wrapper.h @@ -52,6 +52,6 @@ wifi_error rb_start_logging(struct rb_info *rb_info, u32 verbose_level, u32 flags, u32 max_interval_sec, u32 min_data_size); int is_rb_name_match(struct rb_info *rb_info, char *name); wifi_error ring_buffer_write(struct rb_info *rb_info, u8 *buf, size_t length, - int no_of_records); + int no_of_records, size_t record_length); void push_out_rb_data(void *cb_ctx); #endif /* __RB_WRAPPER_H */ diff --git a/qcwcn/wifi_hal/ring_buffer.cpp b/qcwcn/wifi_hal/ring_buffer.cpp index 771de1a..f346b2d 100644 --- a/qcwcn/wifi_hal/ring_buffer.cpp +++ b/qcwcn/wifi_hal/ring_buffer.cpp @@ -46,12 +46,18 @@ enum rb_bool { RB_FALSE = 1 }; +typedef struct rb_entry_s { + u8 *data; + unsigned int last_wr_index; + u8 full; +} rb_entry_t; + typedef struct ring_buf_cb { unsigned int rd_buf_no; // Current buffer number to be read from unsigned int wr_buf_no; // Current buffer number to be written into unsigned int cur_rd_buf_idx; // Read index within the current read buffer unsigned int cur_wr_buf_idx; // Write index within the current write buffer - u8 **bufs; // Array of buffer pointers + rb_entry_t *bufs; // Array of buffer pointers unsigned int max_num_bufs; // Maximum number of buffers that should be used size_t each_buf_size; // Size of each buffer in bytes @@ -102,13 +108,13 @@ void * ring_buffer_init(size_t size_of_buf, int num_bufs) } memset(rbc, 0, sizeof(struct ring_buf_cb)); - rbc->bufs = (u8 **)malloc(num_bufs * sizeof(void *)); + rbc->bufs = (rb_entry_t *)malloc(num_bufs * sizeof(rb_entry_t)); if (rbc->bufs == NULL) { free(rbc); ALOGE("Failed to alloc rbc->bufs"); return NULL; } - memset(rbc->bufs, 0, (num_bufs * sizeof(void *))); + memset(rbc->bufs, 0, (num_bufs * sizeof(rb_entry_t))); rbc->each_buf_size = size_of_buf; rbc->max_num_bufs = num_bufs; @@ -134,13 +140,18 @@ void ring_buffer_deinit(void *ctx) // TODO handle the lock destroy failure } for (buf_no = 0; buf_no < rbc->max_num_bufs; buf_no++) { - free(rbc->bufs[buf_no]); + free(rbc->bufs[buf_no].data); } free(rbc->bufs); free(rbc); } -enum rb_status rb_write (void *ctx, u8 *buf, size_t length, int overwrite) +/* + * record_length : 0 - byte boundary + * : >0 - Ensures to write record_length no.of bytes to the same buffer. + */ +enum rb_status rb_write (void *ctx, u8 *buf, size_t length, int overwrite, + size_t record_length) { rbc_t *rbc = (rbc_t *)ctx; unsigned int bytes_written = 0; // bytes written into rb so far @@ -148,24 +159,81 @@ enum rb_status rb_write (void *ctx, u8 *buf, size_t length, int overwrite) // write in current buffer unsigned int total_push_in_rd_ptr = 0; // Total amount of push in read pointer in this write - /* Check if this write fits into remaining ring buffer */ - if ((overwrite == 0) && - (length > - ((rbc->max_num_bufs * rbc->each_buf_size) - rbc->cur_valid_bytes))) { + if (record_length > rbc->each_buf_size) { return RB_FAILURE; } + if (overwrite == 0) { + /* Check if the complete RB is full. If the current wr_buf is also + * full, it indicates that the complete RB is full + */ + if (rbc->bufs[rbc->wr_buf_no].full == 1) + return RB_FULL; + /* Check whether record fits in current buffer */ + if (rbc->wr_buf_no == rbc->rd_buf_no) { + if ((rbc->cur_wr_buf_idx == rbc->cur_rd_buf_idx) && + rbc->cur_valid_bytes) { + return RB_FULL; + } else if (rbc->cur_wr_buf_idx < rbc->cur_rd_buf_idx) { + if (record_length > + (rbc->cur_rd_buf_idx - rbc->cur_wr_buf_idx)) { + return RB_FULL; + } + } else { + if (record_length > (rbc->each_buf_size - rbc->cur_wr_buf_idx)) { + /* Check if the next buffer is not full to write this record into + * next buffer + */ + unsigned int next_buf_no = rbc->wr_buf_no + 1; + + if (next_buf_no >= rbc->max_num_bufs) { + next_buf_no = 0; + } + if (rbc->bufs[next_buf_no].full == 1) { + return RB_FULL; + } + } + } + } else if (record_length > (rbc->each_buf_size - rbc->cur_wr_buf_idx)) { + /* Check if the next buffer is not full to write this record into + * next buffer + */ + unsigned int next_buf_no = rbc->wr_buf_no + 1; + + if (next_buf_no >= rbc->max_num_bufs) { + next_buf_no = 0; + } + if (rbc->bufs[next_buf_no].full == 1) { + return RB_FULL; + } + } + } + + /* Go to next buffer if the current buffer is not enough to write the + * complete record + */ + if (record_length > (rbc->each_buf_size - rbc->cur_wr_buf_idx)) { + rbc->bufs[rbc->wr_buf_no].full = 1; + rbc->bufs[rbc->wr_buf_no].last_wr_index = rbc->cur_wr_buf_idx; + rbc->wr_buf_no++; + if (rbc->wr_buf_no == rbc->max_num_bufs) { + rbc->wr_buf_no = 0; + } + rbc->cur_wr_buf_idx = 0; + } + + /* In each iteration of below loop, the data that can be fit into * buffer @wr_buf_no will be copied from input buf */ while (bytes_written < length) { unsigned int cur_copy_len; /* Allocate a buffer if no buf available @ wr_buf_no */ - if (rbc->bufs[rbc->wr_buf_no] == NULL) { - rbc->bufs[rbc->wr_buf_no] = (u8 *)malloc(rbc->each_buf_size); - if (rbc->bufs[rbc->wr_buf_no] == NULL) { + if (rbc->bufs[rbc->wr_buf_no].data == NULL) { + rbc->bufs[rbc->wr_buf_no].data = (u8 *)malloc(rbc->each_buf_size); + if (rbc->bufs[rbc->wr_buf_no].data == NULL) { ALOGE("Failed to alloc write buffer"); - return RB_FAILURE; + return RB_RETRY; } } @@ -193,13 +261,18 @@ enum rb_status rb_write (void *ctx, u8 *buf, size_t length, int overwrite) push_in_rd_ptr += cur_copy_len - (rbc->cur_rd_buf_idx - rbc->cur_wr_buf_idx); rbc->cur_rd_buf_idx = rbc->cur_wr_buf_idx + cur_copy_len; - if (rbc->cur_rd_buf_idx == rbc->each_buf_size) { + if (rbc->cur_rd_buf_idx >= + rbc->bufs[rbc->rd_buf_no].last_wr_index) { rbc->cur_rd_buf_idx = 0; rbc->rd_buf_no++; if (rbc->rd_buf_no == rbc->max_num_bufs) { rbc->rd_buf_no = 0; ALOGD("Pushing read to the start of ring buffer"); } + /* the previous buffer might have little more empty room + * after overwriting the remaining bytes + */ + rbc->bufs[rbc->wr_buf_no].full = 0; } } } @@ -209,7 +282,7 @@ enum rb_status rb_write (void *ctx, u8 *buf, size_t length, int overwrite) /* don't use lock while doing memcpy, so that we don't block the read * context for too long. There is no harm while writing the memory if * locking is properly done while upgrading the pointers */ - memcpy((rbc->bufs[rbc->wr_buf_no] + rbc->cur_wr_buf_idx), + memcpy((rbc->bufs[rbc->wr_buf_no].data + rbc->cur_wr_buf_idx), (buf + bytes_written), cur_copy_len); @@ -218,6 +291,8 @@ enum rb_status rb_write (void *ctx, u8 *buf, size_t length, int overwrite) rbc->cur_wr_buf_idx += cur_copy_len; if (rbc->cur_wr_buf_idx == rbc->each_buf_size) { /* Increment the wr_buf_no as the current buffer is full */ + rbc->bufs[rbc->wr_buf_no].full = 1; + rbc->bufs[rbc->wr_buf_no].last_wr_index = rbc->cur_wr_buf_idx; rbc->wr_buf_no++; if (rbc->wr_buf_no == rbc->max_num_bufs) { ALOGD("Write rolling over to the start of ring buffer"); @@ -250,6 +325,7 @@ enum rb_status rb_write (void *ctx, u8 *buf, size_t length, int overwrite) /* check if valid bytes is going more than threshold */ if ((rbc->threshold_reached == RB_FALSE) && (rbc->cur_valid_bytes >= rbc->num_min_bytes) && + ((length == record_length) || !record_length) && rbc->threshold_cb) { /* Release the lock before calling threshold_cb as it might call rb_read * in this same context in order to avoid dead lock @@ -273,7 +349,7 @@ size_t rb_read (void *ctx, u8 *buf, size_t max_length) while (bytes_read < max_length) { unsigned int cur_cpy_len; - if (rbc->bufs[rbc->rd_buf_no] == NULL) { + if (rbc->bufs[rbc->rd_buf_no].data == NULL) { break; } @@ -313,7 +389,7 @@ size_t rb_read (void *ctx, u8 *buf, size_t max_length) } memcpy((buf + bytes_read), - (rbc->bufs[rbc->rd_buf_no] + rbc->cur_rd_buf_idx), + (rbc->bufs[rbc->rd_buf_no].data + rbc->cur_rd_buf_idx), cur_cpy_len); /* Update the read index */ @@ -321,8 +397,8 @@ size_t rb_read (void *ctx, u8 *buf, size_t max_length) if (rbc->cur_rd_buf_idx == rbc->each_buf_size) { /* Increment rd_buf_no as the current buffer is completely read */ if (rbc->rd_buf_no != rbc->wr_buf_no) { - free(rbc->bufs[rbc->rd_buf_no]); - rbc->bufs[rbc->rd_buf_no] = NULL; + free(rbc->bufs[rbc->rd_buf_no].data); + rbc->bufs[rbc->rd_buf_no].data = NULL; } rbc->rd_buf_no++; if (rbc->rd_buf_no == rbc->max_num_bufs) { @@ -365,12 +441,25 @@ u8 *rb_get_read_buf(void *ctx, size_t *length) u8 *buf; /* If no buffer is available for reading */ - if (rbc->bufs[rbc->rd_buf_no] == NULL) { + if (rbc->bufs[rbc->rd_buf_no].data == NULL) { *length = 0; return NULL; } rb_lock(&rbc->rb_rw_lock); + if ((rbc->bufs[rbc->rd_buf_no].full == 1) && + (rbc->cur_rd_buf_idx == rbc->bufs[rbc->rd_buf_no].last_wr_index)) { + if (rbc->wr_buf_no != rbc->rd_buf_no) { + free(rbc->bufs[rbc->rd_buf_no].data); + rbc->bufs[rbc->rd_buf_no].data = NULL; + } + rbc->bufs[rbc->rd_buf_no].full = 0; + rbc->rd_buf_no++; + if (rbc->rd_buf_no == rbc->max_num_bufs) { + rbc->rd_buf_no = 0; + } + rbc->cur_rd_buf_idx = 0; + } if (rbc->wr_buf_no == rbc->rd_buf_no) { /* If read and write are happening on the same buffer currently, use @@ -386,24 +475,26 @@ u8 *rb_get_read_buf(void *ctx, size_t *length) cur_read_len = rbc->cur_wr_buf_idx - rbc->cur_rd_buf_idx; } else { /* write is rolled over and just behind the read */ - cur_read_len = rbc->each_buf_size - rbc->cur_rd_buf_idx; + cur_read_len = rbc->bufs[rbc->rd_buf_no].last_wr_index - rbc->cur_rd_buf_idx; } } else { if (rbc->cur_rd_buf_idx == 0) { /* The complete buffer can be read out */ - cur_read_len = rbc->each_buf_size; + cur_read_len = rbc->bufs[rbc->rd_buf_no].last_wr_index; } else { /* Read the remaining bytes in this buffer */ - cur_read_len = rbc->each_buf_size - rbc->cur_rd_buf_idx; + cur_read_len = rbc->bufs[rbc->rd_buf_no].last_wr_index - rbc->cur_rd_buf_idx; } } - if (cur_read_len == rbc->each_buf_size) { + if ((rbc->bufs[rbc->rd_buf_no].full == 1) && + (rbc->cur_rd_buf_idx == 0)) { /* Pluck out the complete buffer and send it out */ - buf = rbc->bufs[rbc->rd_buf_no]; - rbc->bufs[rbc->rd_buf_no] = NULL; + buf = rbc->bufs[rbc->rd_buf_no].data; + rbc->bufs[rbc->rd_buf_no].data = NULL; /* Move to the next buffer */ + rbc->bufs[rbc->rd_buf_no].full = 0; rbc->rd_buf_no++; if (rbc->rd_buf_no == rbc->max_num_bufs) { ALOGD("Read rolling over to the start of ring buffer"); @@ -414,14 +505,17 @@ u8 *rb_get_read_buf(void *ctx, size_t *length) * and copy the data into it. */ buf = (u8 *)malloc(cur_read_len); - memcpy(buf, (rbc->bufs[rbc->rd_buf_no] + rbc->cur_rd_buf_idx), cur_read_len); + memcpy(buf, + (rbc->bufs[rbc->rd_buf_no].data + rbc->cur_rd_buf_idx), + cur_read_len); /* Update the read index */ - if ((cur_read_len + rbc->cur_rd_buf_idx) == rbc->each_buf_size) { + if (rbc->bufs[rbc->rd_buf_no].full == 1) { if (rbc->wr_buf_no != rbc->rd_buf_no) { - free(rbc->bufs[rbc->rd_buf_no]); - rbc->bufs[rbc->rd_buf_no] = NULL; + free(rbc->bufs[rbc->rd_buf_no].data); + rbc->bufs[rbc->rd_buf_no].data = NULL; } + rbc->bufs[rbc->rd_buf_no].full = 0; rbc->rd_buf_no++; if (rbc->rd_buf_no == rbc->max_num_bufs) { rbc->rd_buf_no = 0; diff --git a/qcwcn/wifi_hal/ring_buffer.h b/qcwcn/wifi_hal/ring_buffer.h index 4af5578..3a310b7 100644 --- a/qcwcn/wifi_hal/ring_buffer.h +++ b/qcwcn/wifi_hal/ring_buffer.h @@ -33,6 +33,8 @@ enum rb_status { RB_SUCCESS = 0, RB_FAILURE = 1, + RB_FULL = 2, + RB_RETRY = 3, }; struct rb_stats { @@ -52,7 +54,8 @@ void * ring_buffer_init(size_t size_of_buf, int num_bufs); void ring_buffer_deinit(void *ctx); /* Writes writes length of bytes from buf to ring buffer */ -enum rb_status rb_write(void *ctx, u8 *buf, size_t length, int overwrite); +enum rb_status rb_write(void *ctx, u8 *buf, size_t length, int overwrite, + size_t record_length); /* Tries to read max_length of bytes from ring buffer to buf * and returns actual length of bytes read from ring buffer diff --git a/qcwcn/wifi_hal/rssi_monitor.cpp b/qcwcn/wifi_hal/rssi_monitor.cpp index 1a698ae..06bb835 100644 --- a/qcwcn/wifi_hal/rssi_monitor.cpp +++ b/qcwcn/wifi_hal/rssi_monitor.cpp @@ -55,6 +55,11 @@ RSSIMonitorCommand::~RSSIMonitorCommand() mRSSIMonitorCommandInstance = NULL; } +void RSSIMonitorCommand::setReqId(wifi_request_id reqid) +{ + mId = reqid; +} + RSSIMonitorCommand* RSSIMonitorCommand::instance(wifi_handle handle, wifi_request_id id) { @@ -66,7 +71,6 @@ RSSIMonitorCommand* RSSIMonitorCommand::instance(wifi_handle handle, mRSSIMonitorCommandInstance = new RSSIMonitorCommand(handle, id, OUI_QCA, QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI); - ALOGV("RSSIMonitorCommand %p created", mRSSIMonitorCommandInstance); return mRSSIMonitorCommandInstance; } else @@ -78,8 +82,8 @@ RSSIMonitorCommand* RSSIMonitorCommand::instance(wifi_handle handle, ALOGI("Handle different, update the handle"); mRSSIMonitorCommandInstance->mInfo = (hal_info *)handle; } + mRSSIMonitorCommandInstance->setReqId(id); } - ALOGV("RSSIMonitorCommand %p created already", mRSSIMonitorCommandInstance); return mRSSIMonitorCommandInstance; } @@ -123,10 +127,10 @@ int RSSIMonitorCommand::handleEvent(WifiEvent &event) /* If event has a different request_id, ignore that and use the * request_id value which we're maintaining. */ - if (reqId != wifi_request_id()) { - ALOGE("%s: Event has Req. ID:%d <> Ours:%d, continue...", - __FUNCTION__, reqId, wifi_request_id()); - reqId = wifi_request_id(); + if (reqId != id()) { + ALOGD("%s: Event has Req. ID:%d <> Ours:%d, continue...", + __FUNCTION__, reqId, id()); + reqId = id(); } ret = get_mac_addr(tb_vendor, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_BSSID, @@ -175,10 +179,8 @@ int RSSIMonitorCommand::setCallbackHandler(wifi_rssi_event_handler nHandler, return ret; } -wifi_error RSSIMonitorCommand::unregisterHandler(u32 subCmd, wifi_request_id id) +wifi_error RSSIMonitorCommand::unregisterHandler(u32 subCmd) { - if (id != (wifi_request_id)mVendor_id) - return WIFI_ERROR_INVALID_REQUEST_ID; unregisterVendorHandler(mVendor_id, subCmd); return WIFI_SUCCESS; } @@ -195,7 +197,7 @@ wifi_error wifi_start_rssi_monitoring(wifi_request_id id, wifi_handle wifiHandle = getWifiHandle(iface); RSSIMonitorCommand *rssiCommand; - ret = initialize_vendor_cmd(iface, + ret = initialize_vendor_cmd(iface, id, QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI, &vCommand); if (ret != WIFI_SUCCESS) { @@ -203,7 +205,8 @@ wifi_error wifi_start_rssi_monitoring(wifi_request_id id, return (wifi_error)ret; } - ALOGI("Max RSSI : %d\nMin RSSI : %d", max_rssi, min_rssi); + ALOGI("%s: Max RSSI:%d Min RSSI:%d", __FUNCTION__, + max_rssi, min_rssi); /* Add the vendor specific attributes for the NL command. */ nlData = vCommand->attr_start(NL80211_ATTR_VENDOR_DATA); if (!nlData) @@ -256,7 +259,7 @@ wifi_error wifi_stop_rssi_monitoring(wifi_request_id id, wifi_handle wifiHandle = getWifiHandle(iface); RSSIMonitorCommand *rssiCommand; - ret = initialize_vendor_cmd(iface, + ret = initialize_vendor_cmd(iface, id, QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI, &vCommand); if (ret != WIFI_SUCCESS) { @@ -292,8 +295,8 @@ wifi_error wifi_stop_rssi_monitoring(wifi_request_id id, goto cleanup; } - ret = rssiCommand->unregisterHandler(QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI, - id); + ret = rssiCommand->unregisterHandler( + QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI); if (ret != WIFI_SUCCESS) goto cleanup; diff --git a/qcwcn/wifi_hal/rssi_monitor.h b/qcwcn/wifi_hal/rssi_monitor.h index 5b6a9f6..bd3d88e 100644 --- a/qcwcn/wifi_hal/rssi_monitor.h +++ b/qcwcn/wifi_hal/rssi_monitor.h @@ -48,7 +48,8 @@ public: static RSSIMonitorCommand* instance(wifi_handle handle, wifi_request_id id); virtual int setCallbackHandler(wifi_rssi_event_handler nHandler, u32 event); virtual int handleEvent(WifiEvent &event); - virtual wifi_error unregisterHandler(u32 subCmd, wifi_request_id id); + virtual wifi_error unregisterHandler(u32 subCmd); + virtual void setReqId(wifi_request_id reqid); }; #ifdef __cplusplus diff --git a/qcwcn/wifi_hal/rtt.cpp b/qcwcn/wifi_hal/rtt.cpp index 4c064d1..39bed86 100644 --- a/qcwcn/wifi_hal/rtt.cpp +++ b/qcwcn/wifi_hal/rtt.cpp @@ -27,7 +27,6 @@ */ #define LOG_TAG "WifiHAL" -#include <dlfcn.h> #include <cutils/sched_policy.h> #include <unistd.h> @@ -40,46 +39,12 @@ #include "wifi_hal.h" #include "wifihal_internal.h" -/* Used to keep track of RTT enabled/disabled last state change. */ -u8 RttLowiIfaceEnabled = 0; -/* Pointer to the table of LOWI callback funcs. */ -lowi_cb_table_t *LowiWifiHalApi = NULL; - -static wifi_error getLowiCbTable(lowi_cb_table_t **lowi_wifihal_api) -{ - getCbTable_t* lowiCbTable = NULL; -#if __WORDSIZE == 64 - void* lowi_handle = dlopen("/vendor/lib64/liblowi_wifihal.so", RTLD_NOW); -#else - void* lowi_handle = dlopen("/vendor/lib/liblowi_wifihal.so", RTLD_NOW); -#endif - if (!lowi_handle) - ALOGE("NULL lowi_handle, err: %s", dlerror()); - if (lowi_handle != (void*)NULL) - { - lowiCbTable = (getCbTable_t*)dlsym(lowi_handle, - "lowi_wifihal_get_cb_table"); - if (lowiCbTable != NULL) { - ALOGE("before calling lowi_wifihal_api = (*lowiCbTable)()"); - *lowi_wifihal_api = lowiCbTable(); - } else { - /* LOWI is not there. */ - ALOGE("getLowiCbTable:dlsym failed. Exit."); - return WIFI_ERROR_NOT_SUPPORTED; - } - } else { - /* LOWI is not there. */ - ALOGE("getLowiCbTable: LOWI is not supported. Exit."); - return WIFI_ERROR_UNINITIALIZED; - } - return WIFI_SUCCESS; -} - /* Implementation of the API functions exposed in rtt.h */ wifi_error wifi_get_rtt_capabilities(wifi_interface_handle iface, wifi_rtt_capabilities *capabilities) { int ret = WIFI_SUCCESS; + lowi_cb_table_t *lowiWifiHalApi = NULL; ALOGD("wifi_get_rtt_capabilities: Entry"); @@ -98,41 +63,28 @@ wifi_error wifi_get_rtt_capabilities(wifi_interface_handle iface, return WIFI_ERROR_INVALID_ARGS; } - if (LowiWifiHalApi == NULL) { - ret = getLowiCbTable(&LowiWifiHalApi); - if (ret != WIFI_SUCCESS || LowiWifiHalApi == NULL) { - ALOGE("wifi_rtt_range_request: LOWI is not supported. Exit."); - goto cleanup; - } - } - - /* Initialize LOWI if it isn't up already. */ - if (RttLowiIfaceEnabled == 0) { - ALOGE("before calling lowi init()"); - ret = LowiWifiHalApi->init(); - if (ret) { - ALOGE("wifi_get_rtt_capabilities(): failed lowi initialization. " - "Returned error:%d. Exit.", ret); - goto cleanup; - } + /* RTT commands are diverted through LOWI interface. */ + /* Open LOWI dynamic library, retrieve handler to LOWI APIs and initialize + * LOWI if it isn't up yet. + */ + lowiWifiHalApi = getLowiCallbackTable( + ONE_SIDED_RANGING_SUPPORTED|DUAL_SIDED_RANGING_SUPPORED); + if (lowiWifiHalApi == NULL || + lowiWifiHalApi->get_rtt_capabilities == NULL) { + ALOGE("wifi_get_rtt_capabilities: getLowiCallbackTable returned NULL or " + "the function pointer is NULL. Exit."); + ret = WIFI_ERROR_NOT_SUPPORTED; + goto cleanup; } - RttLowiIfaceEnabled = 1; - ALOGE("before calling get_rtt_capabilities"); - ret = LowiWifiHalApi->get_rtt_capabilities(iface, capabilities); + ret = lowiWifiHalApi->get_rtt_capabilities(iface, capabilities); if (ret != WIFI_SUCCESS) { - ALOGE("wifi_get_rtt_capabilities(): lowi_wifihal_get_rtt_capabilities " + ALOGE("wifi_get_rtt_capabilities: lowi_wifihal_get_rtt_capabilities " "returned error:%d. Exit.", ret); goto cleanup; } cleanup: - /* Check if RTT cmd failed because Wi-Fi is Off */ - if (ret == WIFI_ERROR_NOT_AVAILABLE && LowiWifiHalApi) { - ret = LowiWifiHalApi->destroy(); - RttLowiIfaceEnabled = 0; - LowiWifiHalApi = NULL; - } return (wifi_error)ret; } @@ -144,6 +96,7 @@ wifi_error wifi_rtt_range_request(wifi_request_id id, wifi_rtt_event_handler handler) { int ret = WIFI_SUCCESS; + lowi_cb_table_t *lowiWifiHalApi = NULL; ALOGD("wifi_rtt_range_request: Entry"); @@ -174,26 +127,21 @@ wifi_error wifi_rtt_range_request(wifi_request_id id, return WIFI_ERROR_INVALID_ARGS; } - if (LowiWifiHalApi == NULL) { - ret = getLowiCbTable(&LowiWifiHalApi); - if (ret != WIFI_SUCCESS || LowiWifiHalApi == NULL) { - ALOGE("wifi_rtt_range_request: LOWI is not supported. Exit."); - goto cleanup; - } - } - - /* Initialize LOWI if it isn't up already. */ - if (RttLowiIfaceEnabled == 0) { - ret = LowiWifiHalApi->init(); - if (ret) { - ALOGE("wifi_rtt_range_request(): failed lowi initialization. " - "Returned error:%d. Exit.", ret); - goto cleanup; - } + /* RTT commands are diverted through LOWI interface. */ + /* Open LOWI dynamic library, retrieve handler to LOWI APIs and initialize + * LOWI if it isn't up yet. + */ + lowiWifiHalApi = getLowiCallbackTable( + ONE_SIDED_RANGING_SUPPORTED|DUAL_SIDED_RANGING_SUPPORED); + if (lowiWifiHalApi == NULL || + lowiWifiHalApi->rtt_range_request == NULL) { + ALOGE("wifi_rtt_range_request: getLowiCallbackTable returned NULL or " + "the function pointer is NULL. Exit."); + ret = WIFI_ERROR_NOT_SUPPORTED; + goto cleanup; } - RttLowiIfaceEnabled = 1; - ret = LowiWifiHalApi->rtt_range_request(id, + ret = lowiWifiHalApi->rtt_range_request(id, iface, num_rtt_config, rtt_config, @@ -205,12 +153,6 @@ wifi_error wifi_rtt_range_request(wifi_request_id id, } cleanup: - /* Check if RTT cmd failed because Wi-Fi is Off. */ - if (ret == WIFI_ERROR_NOT_AVAILABLE && LowiWifiHalApi) { - ret = LowiWifiHalApi->destroy(); - RttLowiIfaceEnabled = 0; - LowiWifiHalApi = NULL; - } return (wifi_error)ret; } @@ -221,6 +163,7 @@ wifi_error wifi_rtt_range_cancel(wifi_request_id id, mac_addr addr[]) { int ret = WIFI_SUCCESS; + lowi_cb_table_t *lowiWifiHalApi = NULL; ALOGD("wifi_rtt_range_cancel: Entry"); @@ -245,26 +188,21 @@ wifi_error wifi_rtt_range_cancel(wifi_request_id id, return WIFI_ERROR_INVALID_ARGS; } - if (LowiWifiHalApi == NULL) { - ret = getLowiCbTable(&LowiWifiHalApi); - if (ret != WIFI_SUCCESS || LowiWifiHalApi == NULL) { - ALOGE("wifi_rtt_range_cancel: LOWI is not supported. Exit."); - goto cleanup; - } - } - - /* Initialize LOWI if it isn't up already. */ - if (RttLowiIfaceEnabled == 0) { - ret = LowiWifiHalApi->init(); - if (ret) { - ALOGE("wifi_rtt_range_cancel(): failed lowi initialization. " - "Returned error:%d. Exit.", ret); - goto cleanup; - } + /* RTT commands are diverted through LOWI interface. */ + /* Open LOWI dynamic library, retrieve handler to LOWI APIs and initialize + * LOWI if it isn't up yet. + */ + lowiWifiHalApi = getLowiCallbackTable( + ONE_SIDED_RANGING_SUPPORTED|DUAL_SIDED_RANGING_SUPPORED); + if (lowiWifiHalApi == NULL || + lowiWifiHalApi->rtt_range_cancel == NULL) { + ALOGE("wifi_rtt_range_cancel: getLowiCallbackTable returned NULL or " + "the function pointer is NULL. Exit."); + ret = WIFI_ERROR_NOT_SUPPORTED; + goto cleanup; } - RttLowiIfaceEnabled = 1; - ret = LowiWifiHalApi->rtt_range_cancel(id, num_devices, addr); + ret = lowiWifiHalApi->rtt_range_cancel(id, num_devices, addr); if (ret != WIFI_SUCCESS) { ALOGE("wifi_rtt_range_cancel: lowi_wifihal_rtt_range_cancel " "returned error:%d. Exit.", ret); @@ -272,13 +210,104 @@ wifi_error wifi_rtt_range_cancel(wifi_request_id id, } cleanup: - /* Check if RTT cmd failed because Wi-Fi is Off. */ - if (ret == WIFI_ERROR_NOT_AVAILABLE && LowiWifiHalApi != NULL) { - ALOGE("wifi_rtt_range_cancel: before calling destroy, ret=%d", ret); - ret = LowiWifiHalApi->destroy(); - RttLowiIfaceEnabled = 0; - LowiWifiHalApi = NULL; + return (wifi_error)ret; +} + +// API to configure the LCI. Used in RTT Responder mode only +wifi_error wifi_set_lci(wifi_request_id id, wifi_interface_handle iface, + wifi_lci_information *lci) +{ + int ret = WIFI_SUCCESS; + lowi_cb_table_t *lowiWifiHalApi = NULL; + + ALOGD("%s: Entry", __FUNCTION__); + + if (iface == NULL) { + ALOGE("%s: NULL iface pointer provided." + " Exit.", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; } + + interface_info *ifaceInfo = getIfaceInfo(iface); + wifi_handle wifiHandle = getWifiHandle(iface); + + if (lci == NULL) { + ALOGE("%s: NULL lci pointer provided." + " Exit.", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + + /* RTT commands are diverted through LOWI interface. */ + /* Open LOWI dynamic library, retrieve handler to LOWI APIs and initialize + * LOWI if it isn't up yet. + */ + lowiWifiHalApi = getLowiCallbackTable( + ONE_SIDED_RANGING_SUPPORTED|DUAL_SIDED_RANGING_SUPPORED); + if (lowiWifiHalApi == NULL || + lowiWifiHalApi->rtt_set_lci == NULL) { + ALOGE("%s: getLowiCallbackTable returned NULL or " + "the function pointer is NULL. Exit.", __FUNCTION__); + ret = WIFI_ERROR_NOT_SUPPORTED; + goto cleanup; + } + + ret = lowiWifiHalApi->rtt_set_lci(id, iface, lci); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: returned error:%d. Exit.", + __FUNCTION__, ret); + goto cleanup; + } + +cleanup: + return (wifi_error)ret; +} + +// API to configure the LCR. Used in RTT Responder mode only. +wifi_error wifi_set_lcr(wifi_request_id id, wifi_interface_handle iface, + wifi_lcr_information *lcr) +{ + int ret = WIFI_SUCCESS; + lowi_cb_table_t *lowiWifiHalApi = NULL; + + ALOGD("%s: Entry", __FUNCTION__); + + if (iface == NULL) { + ALOGE("%s: NULL iface pointer provided." + " Exit.", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + + interface_info *ifaceInfo = getIfaceInfo(iface); + wifi_handle wifiHandle = getWifiHandle(iface); + + if (lcr == NULL) { + ALOGE("%s: NULL lcr pointer provided." + " Exit.", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + + /* RTT commands are diverted through LOWI interface. */ + /* Open LOWI dynamic library, retrieve handler to LOWI APIs and initialize + * LOWI if it isn't up yet. + */ + lowiWifiHalApi = getLowiCallbackTable( + ONE_SIDED_RANGING_SUPPORTED|DUAL_SIDED_RANGING_SUPPORED); + if (lowiWifiHalApi == NULL || + lowiWifiHalApi->rtt_set_lcr == NULL) { + ALOGE("%s: getLowiCallbackTable returned NULL or " + "the function pointer is NULL. Exit.", __FUNCTION__); + ret = WIFI_ERROR_NOT_SUPPORTED; + goto cleanup; + } + + ret = lowiWifiHalApi->rtt_set_lcr(id, iface, lcr); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: returned error:%d. Exit.", + __FUNCTION__, ret); + goto cleanup; + } + +cleanup: return (wifi_error)ret; } diff --git a/qcwcn/wifi_hal/tdls.cpp b/qcwcn/wifi_hal/tdls.cpp index af6bdcf..f7eafad 100755 --- a/qcwcn/wifi_hal/tdls.cpp +++ b/qcwcn/wifi_hal/tdls.cpp @@ -189,7 +189,6 @@ int TdlsCommand::handleEvent(WifiEvent &event) int TdlsCommand::handleResponse(WifiEvent &reply) { - ALOGI("Received a TDLS response message from Driver"); u32 status; int i = 0; WifiVendorCommand::handleResponse(reply); diff --git a/qcwcn/wifi_hal/vendor_definitions.h b/qcwcn/wifi_hal/vendor_definitions.h index 2699458..8012cba 100644 --- a/qcwcn/wifi_hal/vendor_definitions.h +++ b/qcwcn/wifi_hal/vendor_definitions.h @@ -594,6 +594,8 @@ enum qca_wlan_vendor_attr_gscan_config_params QCA_WLAN_VENDOR_ATTR_GSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW, /* Signed 32-bit value */ QCA_WLAN_VENDOR_ATTR_GSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH, + /* Unsigned 32-bit value; a bitmask w/additional gscan config flag. */ + QCA_WLAN_VENDOR_ATTR_GSCAN_CONFIGURATION_FLAGS, /* keep last */ QCA_WLAN_VENDOR_ATTR_GSCAN_SUBCMD_CONFIG_PARAM_AFTER_LAST, @@ -933,6 +935,12 @@ enum qca_wlan_vendor_attr_wifi_config { QCA_WLAN_VENDOR_ATTR_WIFI_CONFIG_AFTER_LAST - 1, }; +enum qca_wlan_epno_type +{ + QCA_WLAN_EPNO, + QCA_WLAN_PNO +}; + enum qca_wlan_vendor_attr_pno_config_params { QCA_WLAN_VENDOR_ATTR_PNO_INVALID = 0, /* NL attributes for data used by @@ -983,6 +991,18 @@ enum qca_wlan_vendor_attr_pno_config_params { QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_EPNO_NETWORK_FLAGS = 11, /* Unsigned 8-bit value; auth bit field for matching WPA IE */ QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_EPNO_NETWORK_AUTH_BIT = 12, + /* Unsigned 8-bit to indicate ePNO type; + * It takes values from qca_wlan_epno_type + */ + QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_EPNO_TYPE = 13, + + /* Nested attribute to send the channel list */ + QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_EPNO_CHANNEL_LIST = 14, + + /* Unsigned 32-bit value; indicates the Interval between PNO scan + * cycles in msec + */ + QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_EPNO_SCAN_INTERVAL = 15, /* keep last */ QCA_WLAN_VENDOR_ATTR_PNO_AFTER_LAST, diff --git a/qcwcn/wifi_hal/wifi_hal.cpp b/qcwcn/wifi_hal/wifi_hal.cpp index f397e35..4d5c02e 100644 --- a/qcwcn/wifi_hal/wifi_hal.cpp +++ b/qcwcn/wifi_hal/wifi_hal.cpp @@ -49,6 +49,7 @@ #include "cpp_bindings.h" #include "ifaceeventhandler.h" #include "wifiloggercmd.h" +#include "vendor_definitions.h" /* BUGBUG: normally, libnl allocates ports for all connections it makes; but @@ -126,7 +127,6 @@ static nl_sock * wifi_create_nl_socket(int port, int protocol) return NULL; } - ALOGI("Socket Value:%p", sock); return sock; } @@ -250,6 +250,8 @@ wifi_error init_wifi_vendor_hal_func_table(wifi_hal_fn *fn) { fn->wifi_set_scanning_mac_oui = wifi_set_scanning_mac_oui; fn->wifi_get_ifaces = wifi_get_ifaces; fn->wifi_get_iface_name = wifi_get_iface_name; + fn->wifi_set_iface_event_handler = wifi_set_iface_event_handler; + fn->wifi_reset_iface_event_handler = wifi_reset_iface_event_handler; 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; @@ -275,7 +277,9 @@ wifi_error init_wifi_vendor_hal_func_table(wifi_hal_fn *fn) { fn->wifi_get_tdls_capabilities = wifi_get_tdls_capabilities; fn->wifi_get_firmware_memory_dump = wifi_get_firmware_memory_dump; fn->wifi_set_log_handler = wifi_set_log_handler; + fn->wifi_reset_log_handler = wifi_reset_log_handler; fn->wifi_set_alert_handler = wifi_set_alert_handler; + fn->wifi_reset_alert_handler = wifi_reset_alert_handler; fn->wifi_get_firmware_version = wifi_get_firmware_version; fn->wifi_get_ring_buffers_status = wifi_get_ring_buffers_status; fn->wifi_get_logger_supported_feature_set = wifi_get_logger_supported_feature_set; @@ -288,6 +292,8 @@ wifi_error init_wifi_vendor_hal_func_table(wifi_hal_fn *fn) { fn->wifi_set_bssid_preference = wifi_set_bssid_preference; fn->wifi_set_gscan_roam_params = wifi_set_gscan_roam_params; fn->wifi_set_ssid_white_list = wifi_set_ssid_white_list; + fn->wifi_set_lci = wifi_set_lci; + fn->wifi_set_lcr = wifi_set_lcr; fn->wifi_start_sending_offloaded_packet = wifi_start_sending_offloaded_packet; fn->wifi_stop_sending_offloaded_packet = wifi_stop_sending_offloaded_packet; @@ -306,7 +312,6 @@ wifi_error wifi_initialize(wifi_handle *handle) struct nl_sock *cmd_sock = NULL; struct nl_sock *event_sock = NULL; struct nl_cb *cb = NULL; - srand(getpid()); ALOGI("Initializing wifi"); hal_info *info = (hal_info *)malloc(sizeof(hal_info)); @@ -317,7 +322,6 @@ wifi_error wifi_initialize(wifi_handle *handle) memset(info, 0, sizeof(*info)); - ALOGI("Creating socket"); cmd_sock = wifi_create_nl_socket(WIFI_HAL_CMD_SOCK_PORT, NETLINK_GENERIC); if (cmd_sock == NULL) { @@ -328,13 +332,10 @@ wifi_error wifi_initialize(wifi_handle *handle) /* Set the socket buffer size */ if (nl_socket_set_buffer_size(cmd_sock, (256*1024), 0) < 0) { - ALOGE("Could not set nl_socket RX buffer size: %s", + ALOGE("Could not set nl_socket RX buffer size for cmd_sock: %s", strerror(errno)); /* continue anyway with the default (smaller) buffer */ } - else { - ALOGI("nl_socket_set_buffer_size successful"); - } event_sock = wifi_create_nl_socket(WIFI_HAL_EVENT_SOCK_PORT, NETLINK_GENERIC); @@ -344,6 +345,13 @@ wifi_error wifi_initialize(wifi_handle *handle) goto unload; } + /* Set the socket buffer size */ + if (nl_socket_set_buffer_size(event_sock, (256*1024), 0) < 0) { + ALOGE("Could not set nl_socket RX buffer size for event_sock: %s", + strerror(errno)); + /* continue anyway with the default (smaller) buffer */ + } + cb = nl_socket_get_cb(event_sock); if (cb == NULL) { ALOGE("Failed to get NL control block for event socket port"); @@ -390,7 +398,6 @@ wifi_error wifi_initialize(wifi_handle *handle) ret = WIFI_ERROR_UNKNOWN; goto unload; } - ALOGI("%s: family_id:%d", __func__, info->nl80211_family_id); pthread_mutex_init(&info->cb_lock, NULL); @@ -450,7 +457,6 @@ wifi_error wifi_initialize(wifi_handle *handle) ret = WIFI_SUCCESS; } - ALOGI("Initializing Wifi Logger Rings"); ret = wifi_logger_ring_buffers_init(info); if (ret != WIFI_SUCCESS) { ALOGE("Wifi Logger Ring Initialization Failed"); @@ -465,6 +471,20 @@ wifi_error wifi_initialize(wifi_handle *handle) goto unload; } + info->rx_buf_size_allocated = MAX_RXMPDUS_PER_AMPDU * MAX_MSDUS_PER_MPDU + * PKT_STATS_BUF_SIZE; + + info->rx_aggr_pkts = + (wifi_ring_buffer_entry *)malloc(info->rx_buf_size_allocated); + if (!info->rx_aggr_pkts) { + ALOGE("%s: malloc Failed for size: %d", + __FUNCTION__, info->rx_buf_size_allocated); + ret = WIFI_ERROR_OUT_OF_MEMORY; + info->rx_buf_size_allocated = 0; + goto unload; + } + memset(info->rx_aggr_pkts, 0, info->rx_buf_size_allocated); + info->exit_sockets[0] = -1; info->exit_sockets[1] = -1; @@ -474,6 +494,13 @@ wifi_error wifi_initialize(wifi_handle *handle) goto unload; } + ALOGI("Initializing Gscan Event Handlers"); + ret = initializeGscanHandlers(info); + if (ret != WIFI_SUCCESS) { + ALOGE("Initializing Gscan Event Handlers Failed"); + goto unload; + } + ALOGI("Initialized Wifi HAL Successfully; vendor cmd = %d Supported" " features : %x", NL80211_CMD_VENDOR, info->supported_feature_set); @@ -487,6 +514,9 @@ unload: if (info->cmd) free(info->cmd); if (info->event_cb) free(info->event_cb); if (info->user_sock) nl_socket_free(info->user_sock); + if (info->pkt_stats) free(info->pkt_stats); + if (info->rx_aggr_pkts) free(info->rx_aggr_pkts); + cleanupGscanHandlers(info); free(info); } } @@ -531,8 +561,13 @@ static void internal_cleaned_up_handler(wifi_handle handle) info->user_sock = NULL; } - free(info->pkt_stats); + if (info->pkt_stats) + free(info->pkt_stats); + if (info->rx_aggr_pkts) + free(info->rx_aggr_pkts); wifi_logger_ring_buffers_deinit(info); + ALOGI("Cleanup Gscan Event Handlers"); + cleanupGscanHandlers(info); if (info->exit_sockets[0] >= 0) { close(info->exit_sockets[0]); @@ -671,10 +706,14 @@ 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); + /* Restrict printing GSCAN_FULL_RESULT which is causing lot + of logs in bug report */ + if (subcmd != QCA_NL80211_VENDOR_SUBCMD_GSCAN_FULL_SCAN_RESULT) { + ALOGI("event received %s, vendor_id = 0x%0x, subcmd = 0x%0x", + event.get_cmdString(), vendor_id, subcmd); + } } else { - ALOGI("event received %s", event.get_cmdString()); + ALOGV("event received %s", event.get_cmdString()); } // event.log(); @@ -695,16 +734,19 @@ static int internal_valid_message_handler(nl_msg *msg, void *arg) cb_info *cbi = &(info->event_cb[i]); pthread_mutex_unlock(&info->cb_lock); - (*(cbi->cb_func))(msg, cbi->cb_arg); - dispatched = true; - + if (cbi && cbi->cb_func) { + (*(cbi->cb_func))(msg, cbi->cb_arg); + dispatched = true; + } return NL_OK; } } +#ifdef QC_HAL_DEBUG if (!dispatched) { ALOGI("event ignored!!"); } +#endif pthread_mutex_unlock(&info->cb_lock); return NL_OK; @@ -878,7 +920,6 @@ wifi_error wifi_init_interfaces(wifi_handle handle) closedir(d); info->num_interfaces = n; - ALOGI("Found %d interfaces", info->num_interfaces); return WIFI_SUCCESS; } @@ -979,7 +1020,6 @@ wifi_error wifi_get_concurrency_matrix(wifi_interface_handle handle, } cleanup: - ALOGI("%s: Delete object.", __func__); delete vCommand; if (ret) { *set_size = 0; @@ -1045,7 +1085,7 @@ wifi_error wifi_start_sending_offloaded_packet(wifi_request_id id, struct nlattr *nlData; WifiVendorCommand *vCommand = NULL; - ret = initialize_vendor_cmd(iface, + ret = initialize_vendor_cmd(iface, id, QCA_NL80211_VENDOR_SUBCMD_OFFLOADED_PACKETS, &vCommand); if (ret != WIFI_SUCCESS) { @@ -1104,7 +1144,7 @@ wifi_error wifi_stop_sending_offloaded_packet(wifi_request_id id, struct nlattr *nlData; WifiVendorCommand *vCommand = NULL; - ret = initialize_vendor_cmd(iface, + ret = initialize_vendor_cmd(iface, id, QCA_NL80211_VENDOR_SUBCMD_OFFLOADED_PACKETS, &vCommand); if (ret != WIFI_SUCCESS) { diff --git a/qcwcn/wifi_hal/wificonfig.cpp b/qcwcn/wifi_hal/wificonfig.cpp index 5f30891..e332895 100644 --- a/qcwcn/wifi_hal/wificonfig.cpp +++ b/qcwcn/wifi_hal/wificonfig.cpp @@ -31,6 +31,7 @@ #include <utils/Log.h> #include <time.h> #include <errno.h> +#include <stdlib.h> #include "wificonfigcommand.h" /* Implementation of the API functions exposed in wifi_config.h */ @@ -45,7 +46,7 @@ wifi_error wifi_extended_dtim_config_set(wifi_request_id id, wifi_handle wifiHandle = getWifiHandle(iface); hal_info *info = getHalInfo(wifiHandle); - ALOGD("wifi_extended_dtim_config_set(): Enter"); + ALOGD("%s: extended_dtim:%d", __FUNCTION__, extended_dtim); wifiConfigCommand = new WiFiConfigCommand( wifiHandle, @@ -54,7 +55,7 @@ wifi_error wifi_extended_dtim_config_set(wifi_request_id id, QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION); if (wifiConfigCommand == NULL) { - ALOGE("%s: Error wifiConfigCommand NULL", __func__); + ALOGE("%s: Error wifiConfigCommand NULL", __FUNCTION__); return WIFI_ERROR_UNKNOWN; } @@ -99,7 +100,6 @@ wifi_error wifi_extended_dtim_config_set(wifi_request_id id, } cleanup: - ALOGI("%s: Delete object.", __func__); delete wifiConfigCommand; return (wifi_error)ret; } @@ -115,13 +115,12 @@ wifi_error wifi_set_country_code(wifi_interface_handle iface, wifi_handle wifiHandle = getWifiHandle(iface); hal_info *info = getHalInfo(wifiHandle); - ALOGD("wifi_set_country_code(): Enter"); + ALOGD("%s: %s", __FUNCTION__, country_code); /* No request id from caller, so generate one and pass it on to the driver. * Generate it randomly. */ - srand(time(NULL)); - requestId = rand(); + requestId = get_requestid(); wifiConfigCommand = new WiFiConfigCommand( wifiHandle, @@ -129,7 +128,7 @@ wifi_error wifi_set_country_code(wifi_interface_handle iface, OUI_QCA, QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION); if (wifiConfigCommand == NULL) { - ALOGE("%s: Error wifiConfigCommand NULL", __func__); + ALOGE("%s: Error wifiConfigCommand NULL", __FUNCTION__); return WIFI_ERROR_UNKNOWN; } @@ -152,9 +151,9 @@ wifi_error wifi_set_country_code(wifi_interface_handle iface, ALOGE("wifi_set_country_code(): requestEvent Error:%d", ret); goto cleanup; } + usleep(WAIT_TIME_FOR_SET_REG_DOMAIN); cleanup: - ALOGI("%s: Delete object.", __func__); delete wifiConfigCommand; return (wifi_error)ret; } @@ -171,14 +170,14 @@ wifi_error wifi_set_beacon_wifi_iface_stats_averaging_factor( wifi_handle wifiHandle = getWifiHandle(iface); hal_info *info = getHalInfo(wifiHandle); - ALOGD("wifi_set_beacon_wifi_iface_stats_averaging_factor(): Enter"); + ALOGD("%s factor:%u", __FUNCTION__, factor); wifiConfigCommand = new WiFiConfigCommand( wifiHandle, id, OUI_QCA, QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION); if (wifiConfigCommand == NULL) { - ALOGE("%s: Error wifiConfigCommand NULL", __func__); + ALOGE("%s: Error wifiConfigCommand NULL", __FUNCTION__); return WIFI_ERROR_UNKNOWN; } @@ -224,7 +223,6 @@ wifi_error wifi_set_beacon_wifi_iface_stats_averaging_factor( } cleanup: - ALOGI("%s: Delete object.", __func__); delete wifiConfigCommand; return (wifi_error)ret; } @@ -240,7 +238,7 @@ wifi_error wifi_set_guard_time(wifi_request_id id, wifi_handle wifiHandle = getWifiHandle(iface); hal_info *info = getHalInfo(wifiHandle); - ALOGD("wifi_set_guard_time(): Enter"); + ALOGD("%s : guard_time:%u", __FUNCTION__, guard_time); wifiConfigCommand = new WiFiConfigCommand( wifiHandle, @@ -248,7 +246,7 @@ wifi_error wifi_set_guard_time(wifi_request_id id, OUI_QCA, QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION); if (wifiConfigCommand == NULL) { - ALOGE("%s: Error wifiConfigCommand NULL", __func__); + ALOGE("%s: Error wifiConfigCommand NULL", __FUNCTION__); return WIFI_ERROR_UNKNOWN; } @@ -290,7 +288,6 @@ wifi_error wifi_set_guard_time(wifi_request_id id, } cleanup: - ALOGI("%s: Delete object.", __func__); delete wifiConfigCommand; return (wifi_error)ret; } @@ -300,7 +297,6 @@ WiFiConfigCommand::WiFiConfigCommand(wifi_handle handle, u32 subcmd) : WifiVendorCommand(handle, id, vendor_id, subcmd) { - ALOGD("WiFiConfigCommand %p constructed", this); /* Initialize the member data variables here */ mWaitforRsp = false; mRequestId = id; @@ -308,7 +304,6 @@ WiFiConfigCommand::WiFiConfigCommand(wifi_handle handle, WiFiConfigCommand::~WiFiConfigCommand() { - ALOGD("WiFiConfigCommand %p destructor", this); unregisterVendorHandler(mVendor_id, mSubcmd); } @@ -327,16 +322,12 @@ int WiFiConfigCommand::create() { ret = mMsg.put_u32(NL80211_ATTR_VENDOR_SUBCMD, mSubcmd); if (ret < 0) goto out; - - ALOGI("%s: mVendor_id = %d, Subcmd = %d.", - __func__, mVendor_id, mSubcmd); out: return ret; } /* This function implements creation of generic NL command */ int WiFiConfigCommand::create_generic(u8 cmdId) { - ALOGI("%s: cmdId = %d", __func__, cmdId); int ret = mMsg.create(cmdId, 0, 0); return ret; } @@ -355,7 +346,7 @@ static int error_handler_wifi_config(struct sockaddr_nl *nla, int *ret = (int *)arg; tmp = nla; *ret = err->error; - ALOGE("%s: Error code:%d (%s)", __func__, *ret, strerror(-(*ret))); + ALOGE("%s: Error code:%d (%s)", __FUNCTION__, *ret, strerror(-(*ret))); return NL_STOP; } @@ -365,7 +356,6 @@ static int ack_handler_wifi_config(struct nl_msg *msg, void *arg) int *ret = (int *)arg; struct nl_msg * a; - ALOGE("%s: called", __func__); a = msg; *ret = 0; return NL_STOP; @@ -377,7 +367,6 @@ static int finish_handler_wifi_config(struct nl_msg *msg, void *arg) int *ret = (int *)arg; struct nl_msg * a; - ALOGE("%s: called", __func__); a = msg; *ret = 0; return NL_SKIP; @@ -394,17 +383,13 @@ int WiFiConfigCommand::requestEvent() int res = -1; struct nl_cb *cb; - ALOGD("%s: Entry.", __func__); - cb = nl_cb_alloc(NL_CB_DEFAULT); if (!cb) { - ALOGE("%s: Callback allocation failed",__func__); + ALOGE("%s: Callback allocation failed",__FUNCTION__); res = -1; goto out; } - /* Send message */ - ALOGE("%s:Handle:%p Socket Value:%p", __func__, mInfo, mInfo->cmd_sock); res = nl_send_auto_complete(mInfo->cmd_sock, mMsg.getMessage()); if (res < 0) goto out; @@ -420,7 +405,6 @@ int WiFiConfigCommand::requestEvent() nl_recvmsgs(mInfo->cmd_sock, cb); } - ALOGD("%s: Msg sent, res=%d, mWaitForRsp=%d", __func__, res, mWaitforRsp); /* Only wait for the asynchronous event if HDD returns success, res=0 */ if (!res && (mWaitforRsp == true)) { struct timespec abstime; @@ -429,10 +413,10 @@ int WiFiConfigCommand::requestEvent() res = mCondition.wait(abstime); if (res == ETIMEDOUT) { - ALOGE("%s: Time out happened.", __func__); + ALOGE("%s: Time out happened.", __FUNCTION__); } ALOGD("%s: Command invoked return value:%d, mWaitForRsp=%d", - __func__, res, mWaitforRsp); + __FUNCTION__, res, mWaitforRsp); } out: /* Cleanup the mMsg */ diff --git a/qcwcn/wifi_hal/wifihal_internal.h b/qcwcn/wifi_hal/wifihal_internal.h index ef72317..379cc48 100755 --- a/qcwcn/wifi_hal/wifihal_internal.h +++ b/qcwcn/wifi_hal/wifihal_internal.h @@ -30,20 +30,31 @@ #define __WIFI_HAL_LOWI_INTERNAL_H__ /* - * The file defines the interface by which wifihal can call LOWI for the purposes - * of initialization, rtt and gscan. - */ + * The file defines the interface by which wifihal can call LOWI for the + * purposes of initialization, rtt and gscan. + */ #include "wifi_hal.h" +#define WIFIHAL_LOWI_MAJOR_VERSION 1 +#define WIFIHAL_LOWI_MINOR_VERSION 1 +#define WIFIHAL_LOWI_MICRO_VERSION 0 + +/* LOWI supported capabilities bit masks */ +#define ONE_SIDED_RANGING_SUPPORTED 0x00000001 +#define DUAL_SIDED_RANGING_SUPPORED 0x00000002 +#define GSCAN_SUPPORTED 0x00000004 + /* - * This structure is a table of function pointers to the functions - * used by the wifihal to interface with LOWI - */ + * This structure is a table of function pointers to the functions + * used by the wifihal to interface with LOWI + */ typedef struct { + /* lowi-client interface functions */ int (*init)(); int (*destroy)(); + /* rtt functions */ int (*get_rtt_capabilities)(wifi_interface_handle iface, wifi_rtt_capabilities *capabilities); int (*rtt_range_request)(u32 request_id, @@ -54,6 +65,69 @@ typedef struct int (*rtt_range_cancel)(u32 request_id, u32 num_devices, mac_addr addr[]); + /* Additional lowi-client interface functions */ + int (*get_lowi_version) (u16* major_version, + u16* minor_version, + u16* micro_version); + int (*get_lowi_capabilities)(u32* capabilities); + /* gscan functions */ + wifi_error (*get_valid_channels)(wifi_interface_handle iface, + u32 band, + u32 max_channels, + wifi_channel *channels, + int *num_channels); + + wifi_error (*get_gscan_capabilities)(wifi_interface_handle handle, + wifi_gscan_capabilities *capabilities); + + wifi_error (*start_gscan)(wifi_request_id request_id, + wifi_interface_handle iface, + wifi_scan_cmd_params params, + wifi_scan_result_handler handler); + + wifi_error (*stop_gscan)(wifi_request_id request_id, + wifi_interface_handle iface); + + wifi_error (*get_cached_gscan_results)(wifi_interface_handle iface, + byte flush, + u32 max, + wifi_cached_scan_results *results, + int *num); + + wifi_error (*set_bssid_hotlist)(wifi_request_id request_id, + wifi_interface_handle iface, + wifi_bssid_hotlist_params params, + wifi_hotlist_ap_found_handler handler); + + wifi_error (*reset_bssid_hotlist)(wifi_request_id request_id, + wifi_interface_handle iface); + + wifi_error (*set_significant_change_handler)(wifi_request_id id, + wifi_interface_handle iface, + wifi_significant_change_params params, + wifi_significant_change_handler handler); + + wifi_error (*reset_significant_change_handler)(wifi_request_id id, + wifi_interface_handle iface); + + wifi_error (*set_ssid_hotlist)(wifi_request_id id, + wifi_interface_handle iface, + wifi_ssid_hotlist_params params, + wifi_hotlist_ssid_handler handler); + + wifi_error (*reset_ssid_hotlist)(wifi_request_id id, + wifi_interface_handle iface); + + // API to configure the LCI. Used in RTT Responder mode only + wifi_error (*rtt_set_lci)(wifi_request_id id, + wifi_interface_handle iface, + wifi_lci_information *lci); + + // API to configure the LCR. Used in RTT Responder mode only. + wifi_error (*rtt_set_lcr)(wifi_request_id id, + wifi_interface_handle iface, + wifi_lcr_information *lcr); + } lowi_cb_table_t; /* diff --git a/qcwcn/wifi_hal/wifilogger.cpp b/qcwcn/wifi_hal/wifilogger.cpp index 17c4b0c..277d41c 100644 --- a/qcwcn/wifi_hal/wifilogger.cpp +++ b/qcwcn/wifi_hal/wifilogger.cpp @@ -35,6 +35,7 @@ #include <utils/Log.h> #include "wifiloggercmd.h" #include "rb_wrapper.h" +#include <stdlib.h> #define LOGGER_MEMDUMP_FILENAME "/proc/debug/fwdump" #define LOGGER_MEMDUMP_CHUNKSIZE (4 * 1024) @@ -77,7 +78,7 @@ wifi_error wifi_start_logging(wifi_interface_handle iface, * No request id from caller, so generate one and pass it on to the driver. * Generate one randomly. */ - requestId = rand(); + requestId = get_requestid(); if (buffer_name == NULL) { ALOGE("%s: Invalid Ring Name. \n", __FUNCTION__); @@ -147,7 +148,7 @@ wifi_error wifi_start_logging(wifi_interface_handle iface, } } - ALOGI("%s: Logging Started for %s.", __FUNCTION__, buffer_name); + ALOGV("%s: Logging Started for %s.", __FUNCTION__, buffer_name); rb_start_logging(&info->rb_infos[ring_id], verbose_level, flags, max_interval_sec, min_data_size); cleanup: @@ -198,9 +199,14 @@ void push_out_all_ring_buffers(hal_info *info) void send_alert(hal_info *info, int reason_code) { - //TODO check locking - if (info->on_alert) { - info->on_alert(0, NULL, 0, reason_code); + wifi_alert_handler handler; + + pthread_mutex_lock(&info->ah_lock); + handler.on_alert = info->on_alert; + pthread_mutex_unlock(&info->ah_lock); + + if (handler.on_alert) { + handler.on_alert(0, NULL, 0, reason_code); } } @@ -223,7 +229,7 @@ wifi_error wifi_get_logger_supported_feature_set(wifi_interface_handle iface, /* No request id from caller, so generate one and pass it on to the driver. * Generate one randomly. */ - requestId = rand(); + requestId = get_requestid(); wifiLoggerCommand = new WifiLoggerCommand( wifiHandle, @@ -292,7 +298,7 @@ wifi_error wifi_get_ring_data(wifi_interface_handle iface, return WIFI_ERROR_UNKNOWN; } - requestId = rand(); + requestId = get_requestid(); wifiLoggerCommand = new WifiLoggerCommand( wifiHandle, @@ -328,7 +334,6 @@ wifi_error wifi_get_ring_data(wifi_interface_handle iface, } wifiLoggerCommand->attr_end(nlData); - //TBD Is there requestResponse here /* Send the msg and wait for a response. */ ret = wifiLoggerCommand->requestResponse(); if (ret) { @@ -359,7 +364,7 @@ wifi_error wifi_get_firmware_version(wifi_interface_handle iface, /* No request id from caller, so generate one and pass it on to the driver. * Generate one randomly. */ - requestId = rand(); + requestId = get_requestid(); wifiLoggerCommand = new WifiLoggerCommand( wifiHandle, @@ -423,7 +428,7 @@ wifi_error wifi_get_driver_version(wifi_interface_handle iface, /* No request id from caller, so generate one and pass it on to the driver. * Generate one randomly. */ - requestId = rand(); + requestId = get_requestid(); wifiLoggerCommand = new WifiLoggerCommand( wifiHandle, @@ -486,7 +491,7 @@ wifi_error wifi_get_firmware_memory_dump(wifi_interface_handle iface, /* No request id from caller, so generate one and pass it on to the driver. * Generate one randomly. */ - requestId = rand(); + requestId = get_requestid(); wifiLoggerCommand = new WifiLoggerCommand( wifiHandle, @@ -527,9 +532,8 @@ wifi_error wifi_get_firmware_memory_dump(wifi_interface_handle iface, if (ret < 0) goto cleanup; - /* Send the msg and wait for the memory dump event */ - wifiLoggerCommand->waitForRsp(true); - ret = wifiLoggerCommand->requestEvent(); + /* Send the msg and wait for the memory dump response */ + ret = wifiLoggerCommand->requestResponse(); if (ret) { ALOGE("%s: Error %d happened. ", __FUNCTION__, ret); } @@ -546,9 +550,11 @@ wifi_error wifi_set_log_handler(wifi_request_id id, wifi_handle wifiHandle = getWifiHandle(iface); hal_info *info = getHalInfo(wifiHandle); + pthread_mutex_lock(&info->lh_lock); info->on_ring_buffer_data = handler.on_ring_buffer_data; + pthread_mutex_unlock(&info->lh_lock); if (handler.on_ring_buffer_data == NULL) { - ALOGE("Input handler is NULL"); + ALOGE("Set log handler is NULL"); return WIFI_ERROR_UNKNOWN; } return WIFI_SUCCESS; @@ -560,8 +566,9 @@ wifi_error wifi_reset_log_handler(wifi_request_id id, wifi_handle wifiHandle = getWifiHandle(iface); hal_info *info = getHalInfo(wifiHandle); - /* Some locking needs to be introduced here */ + pthread_mutex_lock(&info->lh_lock); info->on_ring_buffer_data = NULL; + pthread_mutex_unlock(&info->lh_lock); return WIFI_SUCCESS; } @@ -572,12 +579,13 @@ wifi_error wifi_set_alert_handler(wifi_request_id id, wifi_handle wifiHandle = getWifiHandle(iface); hal_info *info = getHalInfo(wifiHandle); - if (handler.on_alert) { - ALOGE("Input handler is NULL"); + if (handler.on_alert == NULL) { + ALOGE("Set alert handler is NULL"); return WIFI_ERROR_UNKNOWN; } - //TODO check locking + pthread_mutex_lock(&info->ah_lock); info->on_alert = handler.on_alert; + pthread_mutex_unlock(&info->ah_lock); return WIFI_SUCCESS; } @@ -587,8 +595,9 @@ wifi_error wifi_reset_alert_handler(wifi_request_id id, wifi_handle wifiHandle = getWifiHandle(iface); hal_info *info = getHalInfo(wifiHandle); - /* Some locking needs to be introduced here */ + pthread_mutex_lock(&info->ah_lock); info->on_alert = NULL; + pthread_mutex_unlock(&info->ah_lock); return WIFI_SUCCESS; } @@ -607,7 +616,7 @@ WifiLoggerCommand::WifiLoggerCommand(wifi_handle handle, int id, u32 vendor_id, WifiLoggerCommand::~WifiLoggerCommand() { - ALOGD("WifiLoggerCommand %p destructor", this); + ALOGV("WifiLoggerCommand %p destructor", this); unregisterVendorHandler(mVendor_id, mSubcmd); } @@ -627,7 +636,7 @@ int WifiLoggerCommand::create() { if (ret < 0) goto out; - ALOGI("%s: mVendor_id = %d, Subcmd = %d.", + ALOGV("%s: mVendor_id = %d, Subcmd = %d.", __FUNCTION__, mVendor_id, mSubcmd); out: @@ -699,6 +708,9 @@ wifi_error wifi_logger_ring_buffers_init(hal_info *info) goto cleanup; } + pthread_mutex_init(&info->lh_lock, NULL); + pthread_mutex_init(&info->ah_lock, NULL); + return ret; cleanup: @@ -713,6 +725,8 @@ void wifi_logger_ring_buffers_deinit(hal_info *info) for (i = 0; i < NUM_RING_BUFS; i++) { rb_deinit(&info->rb_infos[i]); } + pthread_mutex_destroy(&info->lh_lock); + pthread_mutex_destroy(&info->ah_lock); } @@ -735,7 +749,6 @@ static int ack_handler_wifi_logger(struct nl_msg *msg, void *arg) int *ret = (int *)arg; struct nl_msg * a; - ALOGE("%s: called", __FUNCTION__); a = msg; *ret = 0; return NL_STOP; @@ -747,7 +760,6 @@ static int finish_handler_wifi_logger(struct nl_msg *msg, void *arg) int *ret = (int *)arg; struct nl_msg * a; - ALOGE("%s: called", __FUNCTION__); a = msg; *ret = 0; return NL_SKIP; @@ -758,8 +770,6 @@ int WifiLoggerCommand::requestEvent() int res = -1; struct nl_cb *cb; - ALOGD("%s: Entry.", __FUNCTION__); - cb = nl_cb_alloc(NL_CB_DEFAULT); if (!cb) { ALOGE("%s: Callback allocation failed",__FUNCTION__); @@ -782,7 +792,7 @@ int WifiLoggerCommand::requestEvent() nl_recvmsgs(mInfo->cmd_sock, cb); } - ALOGD("%s: Msg sent, res=%d, mWaitForRsp=%d", __FUNCTION__, res, mWaitforRsp); + ALOGV("%s: Msg sent, res=%d, mWaitForRsp=%d", __FUNCTION__, res, mWaitforRsp); /* Only wait for the asynchronous event if HDD returns success, res=0 */ if (!res && (mWaitforRsp == true)) { struct timespec abstime; @@ -793,7 +803,7 @@ int WifiLoggerCommand::requestEvent() { ALOGE("%s: Time out happened.", __FUNCTION__); } - ALOGD("%s: Command invoked return value:%d, mWaitForRsp=%d", + ALOGV("%s: Command invoked return value:%d, mWaitForRsp=%d", __FUNCTION__, res, mWaitforRsp); } out: @@ -808,14 +818,16 @@ int WifiLoggerCommand::requestResponse() } int WifiLoggerCommand::handleResponse(WifiEvent &reply) { - ALOGD("Received a WifiLogger response message from Driver"); u32 status; int ret = WIFI_SUCCESS; int i = 0; int len = 0, version; char version_type[20]; + char* memBuffer = NULL; + FILE* memDumpFilePtr = NULL; WifiVendorCommand::handleResponse(reply); + memset(version_type, 0, 20); switch(mSubcmd) { case QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO: @@ -866,36 +878,7 @@ int WifiLoggerCommand::handleResponse(WifiEvent &reply) { } } break; - default : - ALOGE("%s: Wrong Wifi Logger subcmd response received %d", - __FUNCTION__, mSubcmd); - } - - return NL_SKIP; -} -/* This function will be the main handler for incoming (from driver) - * WIFI_LOGGER_SUBCMD. - * Calls the appropriate callback handler after parsing the vendor data. - */ -int WifiLoggerCommand::handleEvent(WifiEvent &event) -{ - unsigned i = 0; - u32 status; - int ret = WIFI_SUCCESS; - char* memBuffer = NULL; - FILE* memDumpFilePtr = NULL; - - WifiVendorCommand::handleEvent(event); - - struct nlattr *tbVendor[ - QCA_WLAN_VENDOR_ATTR_LOGGER_RESULTS_MAX + 1]; - nla_parse(tbVendor, QCA_WLAN_VENDOR_ATTR_LOGGER_RESULTS_MAX, - (struct nlattr *)mVendorData, - mDataLen, NULL); - - switch(mSubcmd) - { case QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP: { int id = 0; @@ -903,24 +886,17 @@ int WifiLoggerCommand::handleEvent(WifiEvent &event) int numRecordsRead = 0; u32 remaining = 0; char* buffer = NULL; + struct nlattr *tbVendor[ + QCA_WLAN_VENDOR_ATTR_LOGGER_RESULTS_MAX + 1]; - if (!tbVendor[ - QCA_WLAN_VENDOR_ATTR_LOGGER_RESULTS_REQUEST_ID]) { - ALOGE("%s: LOGGER_RESULTS_REQUEST_ID not" - "found, continuing...", __func__); - } - else { - id = nla_get_u32(tbVendor[ - QCA_WLAN_VENDOR_ATTR_LOGGER_RESULTS_REQUEST_ID] - ); - ALOGI("%s: Event has Req. ID:%d, ours:%d", - __func__, id, mRequestId); - } + nla_parse(tbVendor, QCA_WLAN_VENDOR_ATTR_LOGGER_RESULTS_MAX, + (struct nlattr *)mVendorData, + mDataLen, NULL); if (!tbVendor[ QCA_WLAN_VENDOR_ATTR_LOGGER_RESULTS_MEMDUMP_SIZE]) { ALOGE("%s: LOGGER_RESULTS_MEMDUMP_SIZE not" - "found", __func__); + "found", __FUNCTION__); break; } @@ -971,7 +947,7 @@ int WifiLoggerCommand::handleEvent(WifiEvent &event) if (numRecordsRead) { remaining -= readSize; buffer += readSize; - ALOGI("%s: Read successful for size:%u " + ALOGV("%s: Read successful for size:%u " "remaining:%u", __func__, readSize, remaining); } @@ -992,6 +968,31 @@ int WifiLoggerCommand::handleEvent(WifiEvent &event) } break; + default : + ALOGE("%s: Wrong Wifi Logger subcmd response received %d", + __FUNCTION__, mSubcmd); + } + + /* free the allocated memory */ + if (memBuffer) { + free(memBuffer); + } + if (memDumpFilePtr) { + fclose(memDumpFilePtr); + } + return NL_SKIP; +} + +/* This function will be the main handler for incoming (from driver) + * WIFI_LOGGER_SUBCMD. + * Calls the appropriate callback handler after parsing the vendor data. + */ +int WifiLoggerCommand::handleEvent(WifiEvent &event) +{ + WifiVendorCommand::handleEvent(event); + + switch(mSubcmd) + { default: /* Error case should not happen print log */ ALOGE("%s: Wrong subcmd received %d", __func__, mSubcmd); @@ -999,10 +1000,6 @@ int WifiLoggerCommand::handleEvent(WifiEvent &event) } cleanup: - /* free the allocated memory */ - if (memBuffer) { - free(memBuffer); - } return NL_SKIP; } diff --git a/qcwcn/wifi_hal/wifilogger_diag.cpp b/qcwcn/wifi_hal/wifilogger_diag.cpp index 3c73630..742bc98 100644 --- a/qcwcn/wifi_hal/wifilogger_diag.cpp +++ b/qcwcn/wifi_hal/wifilogger_diag.cpp @@ -39,12 +39,11 @@ #include "wifilogger_vendor_tag_defs.h" #include "pkt_stats.h" -#define RING_BUF_ENTRY_SIZE 512 -#define MAX_CONNECTIVITY_EVENTS 15 // should match the value in wifi_logger.h +#define MAX_CONNECTIVITY_EVENTS 16 // should match the value in wifi_logger.h static event_remap_t events[MAX_CONNECTIVITY_EVENTS] = { {WLAN_PE_DIAG_ASSOC_REQ_EVENT, WIFI_EVENT_ASSOCIATION_REQUESTED}, {WLAN_PE_DIAG_AUTH_COMP_EVENT, WIFI_EVENT_AUTH_COMPLETE}, - {WLAN_PE_DIAG_ASSOC_COMP_EVENT, WIFI_EVENT_ASSOC_COMPLETE}, + {WLAN_PE_DIAG_CONNECTED, WIFI_EVENT_ASSOC_COMPLETE}, {WLAN_PE_DIAG_AUTH_START_EVENT, WIFI_EVENT_FW_AUTH_STARTED}, {WLAN_PE_DIAG_ASSOC_START_EVENT, WIFI_EVENT_FW_ASSOC_STARTED}, {WLAN_PE_DIAG_REASSOC_START_EVENT, WIFI_EVENT_FW_RE_ASSOC_STARTED}, @@ -54,9 +53,10 @@ static event_remap_t events[MAX_CONNECTIVITY_EVENTS] = { {WLAN_PE_DIAG_DISASSOC_REQ_EVENT, WIFI_EVENT_DISASSOCIATION_REQUESTED}, {WLAN_PE_DIAG_ASSOC_REQ_EVENT, WIFI_EVENT_RE_ASSOCIATION_REQUESTED}, {WLAN_PE_DIAG_ROAM_AUTH_START_EVENT, WIFI_EVENT_ROAM_AUTH_STARTED}, - {WLAN_PE_DIAG_ROAM_AUTH_COMP_EVENT, WIFI_EVENT_ROAM_AUTH_COMPLETE}, + {WLAN_PE_DIAG_PRE_AUTH_RSP_EVENT, WIFI_EVENT_ROAM_AUTH_COMPLETE}, {WLAN_PE_DIAG_ROAM_ASSOC_START_EVENT, WIFI_EVENT_ROAM_ASSOC_STARTED}, {WLAN_PE_DIAG_ROAM_ASSOC_COMP_EVENT, WIFI_EVENT_ROAM_ASSOC_COMPLETE}, + {WLAN_PE_DIAG_SWITCH_CHL_REQ_EVENT, WIFI_EVENT_CHANNEL_SWITCH_ANOUNCEMENT}, }; tlv_log* addLoggerTlv(u16 type, u16 length, u8* value, tlv_log *pOutTlv) @@ -101,14 +101,112 @@ static wifi_error update_connectivity_ring_buf(hal_info *info, if (info->rb_infos[CONNECTIVITY_EVENTS_RB_ID].verbose_level >= 1 && info->on_ring_buffer_data) { return ring_buffer_write(&info->rb_infos[CONNECTIVITY_EVENTS_RB_ID], - (u8*)rbe, total_length, 1); - } else { - return WIFI_ERROR_NOT_AVAILABLE; + (u8*)rbe, total_length, 1, total_length); } return WIFI_SUCCESS; } +#define SCAN_CAP_ENTRY_SIZE 1024 +static wifi_error process_log_extscan_capabilities(hal_info *info, + u8* buf, int length) +{ + wifi_ring_buffer_driver_connectivity_event *pConnectEvent; + wifi_ring_buffer_entry *pRingBufferEntry; + wlan_ext_scan_capabilities_payload_type *pScanCapabilities; + wifi_gscan_capabilities gscan_cap; + gscan_capabilities_vendor_data_t cap_vendor_data; + tlv_log *pTlv; + int tot_len = sizeof(wifi_ring_buffer_driver_connectivity_event); + u8 out_buf[SCAN_CAP_ENTRY_SIZE]; + wifi_error status; + + pRingBufferEntry = (wifi_ring_buffer_entry *)&out_buf[0]; + memset(pRingBufferEntry, 0, SCAN_CAP_ENTRY_SIZE); + pConnectEvent = (wifi_ring_buffer_driver_connectivity_event *) + (pRingBufferEntry + 1); + + pConnectEvent->event = WIFI_EVENT_G_SCAN_CAPABILITIES; + pTlv = &pConnectEvent->tlvs[0]; + + pScanCapabilities = (wlan_ext_scan_capabilities_payload_type *)buf; + pTlv = addLoggerTlv(WIFI_TAG_REQUEST_ID, + sizeof(pScanCapabilities->request_id), + (u8 *)&pScanCapabilities->request_id, pTlv); + tot_len += sizeof(tlv_log) + sizeof(pScanCapabilities->request_id); + + gscan_cap.max_scan_cache_size = + pScanCapabilities->extscan_cache_capabilities.scan_cache_entry_size; + gscan_cap.max_scan_buckets = + pScanCapabilities->extscan_cache_capabilities.max_buckets; + gscan_cap.max_ap_cache_per_scan = + pScanCapabilities->extscan_cache_capabilities.max_bssid_per_scan; + gscan_cap.max_rssi_sample_size = FEATURE_NOT_SUPPORTED; + gscan_cap.max_scan_reporting_threshold = + pScanCapabilities->extscan_cache_capabilities.max_table_usage_threshold; + gscan_cap.max_hotlist_bssids = + pScanCapabilities->extscan_hotlist_monitor_capabilities.max_hotlist_entries; + gscan_cap.max_hotlist_ssids = + pScanCapabilities->extscan_capabilities.num_extscan_hotlist_ssid; + gscan_cap.max_significant_wifi_change_aps = FEATURE_NOT_SUPPORTED; + gscan_cap.max_bssid_history_entries = FEATURE_NOT_SUPPORTED; + gscan_cap.max_number_epno_networks = + pScanCapabilities->extscan_capabilities.num_epno_networks; + gscan_cap.max_number_epno_networks_by_ssid = + pScanCapabilities->extscan_capabilities.num_epno_networks; + gscan_cap.max_number_of_white_listed_ssid = + pScanCapabilities->extscan_capabilities.num_roam_ssid_whitelist; + + pTlv = addLoggerTlv(WIFI_TAG_GSCAN_CAPABILITIES, + sizeof(wifi_gscan_capabilities), + (u8 *)&gscan_cap, pTlv); + tot_len += sizeof(tlv_log) + sizeof(wifi_gscan_capabilities); + + cap_vendor_data.hotlist_mon_table_id = + pScanCapabilities->extscan_hotlist_monitor_capabilities.table_id; + cap_vendor_data.wlan_hotlist_entry_size = + pScanCapabilities->extscan_hotlist_monitor_capabilities.wlan_hotlist_entry_size; + cap_vendor_data.cache_cap_table_id = + pScanCapabilities->extscan_cache_capabilities.table_id; + cap_vendor_data.requestor_id = + pScanCapabilities->extscan_capabilities.requestor_id; + cap_vendor_data.vdev_id = + pScanCapabilities->extscan_capabilities.vdev_id; + cap_vendor_data.num_extscan_cache_tables = + pScanCapabilities->extscan_capabilities.num_extscan_cache_tables; + cap_vendor_data.num_wlan_change_monitor_tables = + pScanCapabilities->extscan_capabilities.num_wlan_change_monitor_tables; + cap_vendor_data.num_hotlist_monitor_tables = + pScanCapabilities->extscan_capabilities.num_hotlist_monitor_tables; + cap_vendor_data.rtt_one_sided_supported = + pScanCapabilities->extscan_capabilities.rtt_one_sided_supported; + cap_vendor_data.rtt_11v_supported = + pScanCapabilities->extscan_capabilities.rtt_11v_supported; + cap_vendor_data.rtt_ftm_supported = + pScanCapabilities->extscan_capabilities.rtt_ftm_supported; + cap_vendor_data.num_extscan_cache_capabilities = + pScanCapabilities->extscan_capabilities.num_extscan_cache_capabilities; + cap_vendor_data.num_extscan_wlan_change_capabilities = + pScanCapabilities->extscan_capabilities.num_extscan_wlan_change_capabilities; + cap_vendor_data.num_extscan_hotlist_capabilities = + pScanCapabilities->extscan_capabilities.num_extscan_hotlist_capabilities; + cap_vendor_data.num_roam_bssid_blacklist = + pScanCapabilities->extscan_capabilities.num_roam_bssid_blacklist; + cap_vendor_data.num_roam_bssid_preferred_list = + pScanCapabilities->extscan_capabilities.num_roam_bssid_preferred_list; + + pTlv = addLoggerTlv(WIFI_TAG_VENDOR_SPECIFIC, + sizeof(gscan_capabilities_vendor_data_t), + (u8 *)&cap_vendor_data, pTlv); + tot_len += sizeof(tlv_log) + sizeof(gscan_capabilities_vendor_data_t); + + status = update_connectivity_ring_buf(info, pRingBufferEntry, tot_len); + if (status != WIFI_SUCCESS) { + ALOGE("Failed to write ext scan capabilities event into ring buffer"); + } + return status; +} + static wifi_error process_bt_coex_scan_event(hal_info *info, u32 id, u8* buf, int length) { @@ -378,8 +476,8 @@ static wifi_error process_extscan_event(hal_info *info, u32 id, pConnectEvent->event = WIFI_EVENT_G_SCAN_STOP; pExtScanStop = (wlan_ext_scan_feature_stop_payload_type *)buf; pTlv = addLoggerTlv(WIFI_TAG_REQUEST_ID, - sizeof(wlan_ext_scan_feature_stop_payload_type), - (u8 *)&pExtScanStop, pTlv); + sizeof(pExtScanStop->request_id), + (u8 *)&pExtScanStop->request_id, pTlv); tot_len += sizeof(tlv_log) + sizeof(wlan_ext_scan_feature_stop_payload_type); } @@ -502,7 +600,7 @@ static wifi_error process_addba_failed_event(hal_info *info, pTlv = addLoggerTlv(WIFI_TAG_VENDOR_SPECIFIC, sizeof(addba_failed_vendor_data_t), - (u8 *)&pAddBAFailed, pTlv); + (u8 *)&addBAFailedVenData, pTlv); tot_len += sizeof(tlv_log) + sizeof(addba_failed_vendor_data_t); status = update_connectivity_ring_buf(info, pRingBufferEntry, tot_len); @@ -675,19 +773,19 @@ wifi_error process_firmware_prints(hal_info *info, u8 *buf, u16 length) * complete payload memcpy */ status = ring_buffer_write(&info->rb_infos[FIRMWARE_PRINTS_RB_ID], (u8*)&rb_entry_hdr, - sizeof(wifi_ring_buffer_entry), 0); + sizeof(wifi_ring_buffer_entry), + 0, + sizeof(wifi_ring_buffer_entry) + length); if (status != WIFI_SUCCESS) { ALOGE("Failed to write firmware prints rb header %d", status); return status; } status = ring_buffer_write(&info->rb_infos[FIRMWARE_PRINTS_RB_ID], - buf, length, 1); + buf, length, 1, length); if (status != WIFI_SUCCESS) { ALOGE("Failed to write firmware prints rb payload %d", status); return status; } - } else { - return WIFI_ERROR_NOT_AVAILABLE; } return WIFI_SUCCESS; @@ -785,14 +883,30 @@ static wifi_error process_fw_diag_msg(hal_info *info, u8* buf, u16 length) break; case WLAN_DIAG_TYPE_LOG: { + id = diag_msg_hdr->diag_id; + payloadlen = diag_msg_hdr->u.payload_len; + + switch (id) { + case LOG_WLAN_EXTSCAN_CAPABILITIES: + status = process_log_extscan_capabilities(info, + diag_msg_hdr->payload, + payloadlen); + if (status != WIFI_SUCCESS) { + ALOGE("Failed to process extscan capabilities"); + return status; + } + break; + default: + return WIFI_SUCCESS; + } } break; case WLAN_DIAG_TYPE_MSG: { /* Length field is only one byte for WLAN_DIAG_TYPE_MSG */ payloadlen = diag_msg_hdr->u.msg_hdr.payload_len; - process_firmware_prints(info, diag_msg_hdr->payload, - payloadlen); + process_firmware_prints(info, (u8 *)diag_msg_hdr, + payloadlen + sizeof(fw_diag_msg_hdr_t)); } break; default: @@ -900,7 +1014,7 @@ static wifi_error process_wlan_eapol_event(hal_info *info, u8* buf, int length) else if ((pWlanEapolEvent->eapol_key_info & EAPOL_MASK) == EAPOL_M4_MASK) eapol_msg_type = 4; else - ALOGI("Unknow EAPOL message type \n"); + ALOGI("Unknown EAPOL message type \n"); pTlv = addLoggerTlv(WIFI_TAG_EAPOL_MESSAGE_TYPE, sizeof(u32), (u8 *)&eapol_msg_type, pTlv); tot_len += sizeof(tlv_log) + sizeof(u32); @@ -976,9 +1090,11 @@ static wifi_error process_wakelock_event(hal_info *info, u8* buf, int length) info->on_ring_buffer_data) { status = ring_buffer_write(&info->rb_infos[POWER_EVENTS_RB_ID], (u8*)pRingBufferEntry, - len_ring_buffer_entry, 1); + len_ring_buffer_entry, + 1, + len_ring_buffer_entry); } else { - status = WIFI_ERROR_NOT_AVAILABLE; + status = WIFI_SUCCESS; } if ((u8 *)pRingBufferEntry != wl_ring_buffer) { @@ -1027,15 +1143,14 @@ static wifi_error update_stats_to_ring_buf(hal_info *info, ring_buffer_write(&info->rb_infos[PKT_STATS_RB_ID], (u8*)pRingBufferEntry, size, - num_records); - } else { - return WIFI_ERROR_NOT_AVAILABLE; + num_records, + size); } return WIFI_SUCCESS; } -static u16 get_rate(u16 mcs_r, u8 short_gi) +static u16 get_rate(u16 mcs_r) { u16 tx_rate = 0; MCS mcs; @@ -1064,11 +1179,11 @@ static u16 get_rate(u16 mcs_r, u8 short_gi) { 0, 0, 720, 800,1560,1733, 3120, 3467}}; mcs.mcs = mcs_r; - if ((mcs.mcs_s.preamble < 4) && (mcs.mcs_s.rate < 10)) { + if ((mcs.mcs_s.preamble <= WL_PREAMBLE_VHT) && (mcs.mcs_s.rate < 10)) { switch(mcs.mcs_s.preamble) { - case 0: - case 1: + case WL_PREAMBLE_CCK: + case WL_PREAMBLE_OFDM: if(mcs.mcs_s.rate<8) { tx_rate = rate_lookup [mcs.mcs_s.preamble][mcs.mcs_s.rate]; if (mcs.mcs_s.nss) @@ -1077,25 +1192,25 @@ static u16 get_rate(u16 mcs_r, u8 short_gi) ALOGE("Unexpected rate value"); } break; - case 2: + case WL_PREAMBLE_HT: if(mcs.mcs_s.rate<8) { if (!mcs.mcs_s.nss) tx_rate = MCS_rate_lookup_ht[mcs.mcs_s.rate] - [2*mcs.mcs_s.bw+short_gi]; + [2*mcs.mcs_s.bw+mcs.mcs_s.short_gi]; else tx_rate = MCS_rate_lookup_ht[10+mcs.mcs_s.rate] - [2*mcs.mcs_s.bw+short_gi]; + [2*mcs.mcs_s.bw+mcs.mcs_s.short_gi]; } else { ALOGE("Unexpected HT mcs.mcs_s index"); } break; - case 3: + case WL_PREAMBLE_VHT: if (!mcs.mcs_s.nss) tx_rate = MCS_rate_lookup_ht[mcs.mcs_s.rate] - [2*mcs.mcs_s.bw+short_gi]; + [2*mcs.mcs_s.bw+mcs.mcs_s.short_gi]; else tx_rate = MCS_rate_lookup_ht[10+mcs.mcs_s.rate] - [2*mcs.mcs_s.bw+short_gi]; + [2*mcs.mcs_s.bw+mcs.mcs_s.short_gi]; break; default: ALOGE("Unexpected preamble"); @@ -1104,49 +1219,105 @@ static u16 get_rate(u16 mcs_r, u8 short_gi) return tx_rate; } -static u16 get_rx_rate(u16 mcs) +static wifi_error populate_rx_aggr_stats(hal_info *info) { - /* TODO: guard interval is not specified currently */ - return get_rate(mcs, 0); + wifi_error status; + wifi_ring_buffer_entry *pRingBufferEntry = info->rx_aggr_pkts; + wifi_ring_per_packet_status_entry *pps_entry; + u32 index = 0; + + while (index < info->rx_buf_size_occupied) { + pps_entry = (wifi_ring_per_packet_status_entry *)(pRingBufferEntry + 1); + + pps_entry->MCS = info->aggr_stats.RxMCS.mcs; + pps_entry->last_transmit_rate = info->aggr_stats.last_transmit_rate; + pps_entry->rssi = info->aggr_stats.rssi; + pps_entry->firmware_entry_timestamp = info->aggr_stats.timestamp; + pps_entry->tid = info->aggr_stats.tid; + + index += pRingBufferEntry->entry_size; + status = update_stats_to_ring_buf(info, (u8 *)pRingBufferEntry, + pRingBufferEntry->entry_size); + + if (status != WIFI_SUCCESS) { + ALOGE("Failed to write Rx stats into the ring buffer"); + return status; + } + /* update_stats_to_ring_buf() modifies the size. Update the same again + * here by adding sizeof(wifi_ring_buffer_entry) to continue parsing + */ + pRingBufferEntry = (wifi_ring_buffer_entry *)((u8 *)pRingBufferEntry + + sizeof(wifi_ring_buffer_entry) + + pRingBufferEntry->entry_size); + } + memset(info->rx_aggr_pkts, 0, info->rx_buf_size_occupied); + info->rx_buf_size_occupied = 0; + + return WIFI_SUCCESS; } static wifi_error parse_rx_stats(hal_info *info, u8 *buf, u16 size) { wifi_error status; rb_pkt_stats_t *rx_stats_rcvd = (rb_pkt_stats_t *)buf; - u8 rb_pkt_entry_buf[RING_BUF_ENTRY_SIZE]; wifi_ring_buffer_entry *pRingBufferEntry; u32 len_ring_buffer_entry = 0; + if (size < sizeof(rb_pkt_stats_t)) { + ALOGE("%s Unexpected rx stats event length: %d", __FUNCTION__, size); + memset(info->rx_aggr_pkts, 0, info->rx_buf_size_occupied); + memset(&info->aggr_stats, 0, sizeof(rx_aggr_stats)); + info->rx_buf_size_occupied = 0; + return WIFI_ERROR_UNKNOWN; + } + len_ring_buffer_entry = sizeof(wifi_ring_buffer_entry) + sizeof(wifi_ring_per_packet_status_entry) + RX_HTT_HDR_STATUS_LEN; - if (len_ring_buffer_entry > RING_BUF_ENTRY_SIZE) { - pRingBufferEntry = (wifi_ring_buffer_entry *)malloc( - len_ring_buffer_entry); - if (pRingBufferEntry == NULL) { - ALOGE("%s: Failed to allocate memory", __FUNCTION__); + if (len_ring_buffer_entry + info->rx_buf_size_occupied + > info->rx_buf_size_allocated) { + wifi_ring_buffer_entry *temp; + temp = (wifi_ring_buffer_entry *)realloc(info->rx_aggr_pkts, + len_ring_buffer_entry + info->rx_buf_size_occupied); + if (temp == NULL) { + ALOGE("%s: Failed to reallocate memory", __FUNCTION__); + free(info->rx_aggr_pkts); + info->rx_aggr_pkts = NULL; return WIFI_ERROR_OUT_OF_MEMORY; } - } else { - pRingBufferEntry = (wifi_ring_buffer_entry *)rb_pkt_entry_buf; + info->rx_aggr_pkts = temp; + memset((u8 *)info->rx_aggr_pkts + info->rx_buf_size_allocated, 0, + len_ring_buffer_entry + info->rx_buf_size_occupied + - info->rx_buf_size_allocated); + info->rx_buf_size_allocated = + len_ring_buffer_entry + info->rx_buf_size_occupied; } + pRingBufferEntry = (wifi_ring_buffer_entry *)((u8 *)info->rx_aggr_pkts + + info->rx_buf_size_occupied); + + info->rx_buf_size_occupied += len_ring_buffer_entry; + + /* Fill size of the entry in rb entry which can be used while populating + * the data. Actual size that needs to be sent to ring buffer is only pps + * entry size + */ + pRingBufferEntry->entry_size = len_ring_buffer_entry; wifi_ring_per_packet_status_entry *rb_pkt_stats = (wifi_ring_per_packet_status_entry *)(pRingBufferEntry + 1); - if (size != sizeof(rb_pkt_stats_t)) { - ALOGE("%s Unexpected rx stats event length: %d", __FUNCTION__, size); - return WIFI_ERROR_UNKNOWN; - } - memset(rb_pkt_stats, 0, sizeof(wifi_ring_per_packet_status_entry)); /* Peer tx packet and it is an Rx packet for us */ rb_pkt_stats->flags |= PER_PACKET_ENTRY_FLAGS_DIRECTION_TX; - if (!rx_stats_rcvd->mpdu_end.tkip_mic_err) + if (!((rx_stats_rcvd->mpdu_end.overflow_err) || + (rx_stats_rcvd->attention.fcs_err) || + (rx_stats_rcvd->attention.mpdu_length_err) || + (rx_stats_rcvd->attention.msdu_length_err) || + (rx_stats_rcvd->attention.tkip_mic_err) || + (rx_stats_rcvd->attention.decrypt_err))) rb_pkt_stats->flags |= PER_PACKET_ENTRY_FLAGS_TX_SUCCESS; rb_pkt_stats->flags |= PER_PACKET_ENTRY_FLAGS_80211_HEADER; @@ -1154,119 +1325,175 @@ static wifi_error parse_rx_stats(hal_info *info, u8 *buf, u16 size) if (rx_stats_rcvd->mpdu_start.encrypted) rb_pkt_stats->flags |= PER_PACKET_ENTRY_FLAGS_PROTECTED; - rb_pkt_stats->tid = rx_stats_rcvd->mpdu_start.tid; - - if (rx_stats_rcvd->ppdu_start.preamble_type == PREAMBLE_L_SIG_RATE) { - if (!rx_stats_rcvd->ppdu_start.l_sig_rate_select) - rb_pkt_stats->MCS |= 1 << 6; - rb_pkt_stats->MCS |= rx_stats_rcvd->ppdu_start.l_sig_rate % 8; - /*BW is 0 for legacy cases*/ - } else if (rx_stats_rcvd->ppdu_start.preamble_type == - PREAMBLE_VHT_SIG_A_1) { - rb_pkt_stats->MCS |= 2 << 6; - rb_pkt_stats->MCS |= - (rx_stats_rcvd->ppdu_start.ht_sig_vht_sig_a_1 & BITMASK(7)) %8; - rb_pkt_stats->MCS |= - ((rx_stats_rcvd->ppdu_start.ht_sig_vht_sig_a_1 >> 7) & 1) << 8; - } else if (rx_stats_rcvd->ppdu_start.preamble_type == - PREAMBLE_VHT_SIG_A_2) { - rb_pkt_stats->MCS |= 3 << 6; - rb_pkt_stats->MCS |= - (rx_stats_rcvd->ppdu_start.ht_sig_vht_sig_a_2 >> 4) & BITMASK(4); - rb_pkt_stats->MCS |= - (rx_stats_rcvd->ppdu_start.ht_sig_vht_sig_a_1 & 3) << 8; - } - rb_pkt_stats->last_transmit_rate = get_rx_rate(rb_pkt_stats->MCS); + if (rx_stats_rcvd->attention.first_mpdu) { + MCS *mcs = &info->aggr_stats.RxMCS; + u32 ht_vht_sig; + + /* Flush the cached stats as this is the first MPDU. */ + memset(&info->aggr_stats, 0, sizeof(rx_aggr_stats)); + if (rx_stats_rcvd->ppdu_start.preamble_type == PREAMBLE_L_SIG_RATE) { + if (rx_stats_rcvd->ppdu_start.l_sig_rate_select) + mcs->mcs_s.preamble = WL_PREAMBLE_OFDM; + mcs->mcs_s.rate = rx_stats_rcvd->ppdu_start.l_sig_rate - 8; + /*BW is 0 for legacy cases*/ + } else if (rx_stats_rcvd->ppdu_start.preamble_type == + PREAMBLE_VHT_SIG_A_1) { + ht_vht_sig = rx_stats_rcvd->ppdu_start.ht_sig_vht_sig_a_1; + mcs->mcs_s.nss = ((ht_vht_sig >> 3) & 0x3); + mcs->mcs_s.preamble = WL_PREAMBLE_HT; + mcs->mcs_s.rate = (ht_vht_sig & BITMASK(7)) >> 3; + mcs->mcs_s.bw = ((ht_vht_sig >> 7) & 1); + mcs->mcs_s.short_gi = + ((rx_stats_rcvd->ppdu_start.ht_sig_vht_sig_a_2 >> 7) & 1); + } else if (rx_stats_rcvd->ppdu_start.preamble_type == + PREAMBLE_VHT_SIG_A_2) { + ht_vht_sig = rx_stats_rcvd->ppdu_start.ht_sig_vht_sig_a_1; + mcs->mcs_s.nss = ((ht_vht_sig >> 10) & 0x3); + mcs->mcs_s.preamble = WL_PREAMBLE_VHT; + mcs->mcs_s.rate = + (rx_stats_rcvd->ppdu_start.ht_sig_vht_sig_a_2 >> 4) & BITMASK(4); + mcs->mcs_s.bw = (ht_vht_sig & 3); + mcs->mcs_s.short_gi = + (rx_stats_rcvd->ppdu_start.ht_sig_vht_sig_a_2 & 1); + } + + info->aggr_stats.last_transmit_rate + = get_rate(info->aggr_stats.RxMCS.mcs); - rb_pkt_stats->rssi = rx_stats_rcvd->ppdu_start.rssi_comb; + info->aggr_stats.rssi = rx_stats_rcvd->ppdu_start.rssi_comb; + info->aggr_stats.tid = rx_stats_rcvd->mpdu_start.tid; + } rb_pkt_stats->link_layer_transmit_sequence = rx_stats_rcvd->mpdu_start.seq_num; - rb_pkt_stats->firmware_entry_timestamp - = rx_stats_rcvd->ppdu_end.wb_timestamp; - memcpy(&rb_pkt_stats->data[0], &rx_stats_rcvd->rx_hdr_status[0], RX_HTT_HDR_STATUS_LEN); - status = update_stats_to_ring_buf(info, (u8 *)pRingBufferEntry, - len_ring_buffer_entry); - - if (status != WIFI_SUCCESS) { - ALOGE("Failed to write Rx stats into the ring buffer"); - } - - if ((u8 *)pRingBufferEntry != rb_pkt_entry_buf) { - ALOGI("Message with more than RING_BUF_ENTRY_SIZE"); - free (pRingBufferEntry); + if ((rx_stats_rcvd->attention.last_mpdu + && rx_stats_rcvd->msdu_end.last_msdu) + || (rx_stats_rcvd->attention.first_mpdu + && rx_stats_rcvd->attention.last_mpdu)) { + info->aggr_stats.timestamp = rx_stats_rcvd->ppdu_end.tsf_timestamp; + status = populate_rx_aggr_stats(info); } return status; } -static void parse_tx_rate_and_mcs(struct tx_ppdu_start *ppdu_start, - wifi_ring_per_packet_status_entry *rb_pkt_stats) +static u16 get_tx_mcs(u8 series, + struct tx_ppdu_start *ppdu_start) { - u16 tx_rate = 0, short_gi = 0; + u16 tx_rate = 0; MCS mcs; + struct series_bw *sbw = NULL; + + mcs.mcs = 0; + + if (series == 0) { + if (ppdu_start->valid_s0_bw20) + sbw = &ppdu_start->s0_bw20; + else if (ppdu_start->valid_s0_bw40) + sbw = &ppdu_start->s0_bw40; + else if (ppdu_start->valid_s0_bw80) + sbw = &ppdu_start->s0_bw80; + else if (ppdu_start->valid_s0_bw160) + sbw = &ppdu_start->s0_bw160; + } else { + if (ppdu_start->valid_s1_bw20) + sbw = &ppdu_start->s1_bw20; + else if (ppdu_start->valid_s1_bw40) + sbw = &ppdu_start->s1_bw40; + else if (ppdu_start->valid_s1_bw80) + sbw = &ppdu_start->s1_bw80; + else if (ppdu_start->valid_s1_bw160) + sbw = &ppdu_start->s1_bw160; + } - if (ppdu_start->valid_s0_bw20) { - short_gi = ppdu_start->s0_bw20.short_gi; - mcs.mcs_s.rate = ppdu_start->s0_bw20.rate; - mcs.mcs_s.nss = ppdu_start->s0_bw20.nss; - mcs.mcs_s.preamble = ppdu_start->s0_bw20.preamble_type; - mcs.mcs_s.bw = BW_20_MHZ; - } else if (ppdu_start->valid_s0_bw40) { - short_gi = ppdu_start->s0_bw40.short_gi; - mcs.mcs_s.rate = ppdu_start->s0_bw40.rate; - mcs.mcs_s.nss = ppdu_start->s0_bw40.nss; - mcs.mcs_s.preamble = ppdu_start->s0_bw40.preamble_type; - mcs.mcs_s.bw = BW_40_MHZ; - } else if (ppdu_start->valid_s0_bw80) { - short_gi = ppdu_start->s0_bw80.short_gi; - mcs.mcs_s.rate = ppdu_start->s0_bw80.rate; - mcs.mcs_s.nss = ppdu_start->s0_bw80.nss; - mcs.mcs_s.preamble = ppdu_start->s0_bw80.preamble_type; - mcs.mcs_s.bw = BW_80_MHZ; - } else if (ppdu_start->valid_s0_bw160) { - short_gi = ppdu_start->s0_bw160.short_gi; - mcs.mcs_s.rate = ppdu_start->s0_bw160.rate; - mcs.mcs_s.nss = ppdu_start->s0_bw160.nss; - mcs.mcs_s.preamble = ppdu_start->s0_bw160.preamble_type; - mcs.mcs_s.bw = BW_160_MHZ; - } else if (ppdu_start->valid_s1_bw20) { - short_gi = ppdu_start->s1_bw20.short_gi; - mcs.mcs_s.rate = ppdu_start->s1_bw20.rate; - mcs.mcs_s.nss = ppdu_start->s1_bw20.nss; - mcs.mcs_s.preamble = ppdu_start->s1_bw20.preamble_type; - mcs.mcs_s.bw = BW_20_MHZ; - } else if (ppdu_start->valid_s1_bw40) { - short_gi = ppdu_start->s1_bw40.short_gi; - mcs.mcs_s.rate = ppdu_start->s1_bw40.rate; - mcs.mcs_s.nss = ppdu_start->s1_bw40.nss; - mcs.mcs_s.preamble = ppdu_start->s1_bw40.preamble_type; - mcs.mcs_s.bw = BW_40_MHZ; - } else if (ppdu_start->valid_s1_bw80) { - short_gi = ppdu_start->s1_bw80.short_gi; - mcs.mcs_s.rate = ppdu_start->s1_bw80.rate; - mcs.mcs_s.nss = ppdu_start->s1_bw80.nss; - mcs.mcs_s.preamble = ppdu_start->s1_bw80.preamble_type; - mcs.mcs_s.bw = BW_80_MHZ; - } else if (ppdu_start->valid_s1_bw160) { - short_gi = ppdu_start->s1_bw160.short_gi; - mcs.mcs_s.rate = ppdu_start->s1_bw160.rate; - mcs.mcs_s.nss = ppdu_start->s1_bw160.nss; - mcs.mcs_s.preamble = ppdu_start->s1_bw160.preamble_type; - mcs.mcs_s.bw = BW_160_MHZ; + if (sbw) { + mcs.mcs_s.rate = sbw->rate; + mcs.mcs_s.nss = sbw->nss; + mcs.mcs_s.preamble = sbw->preamble_type; + mcs.mcs_s.short_gi = sbw->short_gi; } - rb_pkt_stats->MCS = mcs.mcs; - rb_pkt_stats->last_transmit_rate = get_rate(mcs.mcs, short_gi); + return mcs.mcs; +} + +static void get_tx_aggr_stats(struct tx_ppdu_start *ppdu_start, hal_info *info) +{ + u32 baBitmap0 = 0; + u32 baBitmap1 = 0; + + info->pkt_stats->tx_seqnum_bitmap_31_0 = ppdu_start->seqnum_bitmap_31_0; + info->pkt_stats->tx_seqnum_bitmap_63_32 = ppdu_start->seqnum_bitmap_63_32; + + if (info->pkt_stats->isBlockAck) { + int baShift = ppdu_start->start_seq_num - info->pkt_stats->ba_seq_num; + //There are 4 scenarios in total: + //1.TxSeq No. >= BaSeq No. and no roll over. + //2.TxSeq No. >= BaSeq No. and TxSeq No. rolls over. + //3.TxSeq No. <= BaSeq No. and no roll over. + //4.TxSeq No. <= BaSeq No. and BaSeq No. rolls over. + + baBitmap0 = info->pkt_stats->ba_bitmap_31_0; + baBitmap1 = info->pkt_stats->ba_bitmap_63_32; + + if (((baShift >= 0) && (baShift < SEQ_NUM_RANGE/2)) || + (baShift < -SEQ_NUM_RANGE/2)) { + //Scenario No.1 and No.2 + baShift = baShift < -SEQ_NUM_RANGE/2 ? (SEQ_NUM_RANGE + baShift) : + baShift; + + if (baShift < BITMAP_VAR_SIZE) { + info->pkt_stats->shifted_bitmap_31_0 = + ((baBitmap1 << (32 - baShift)) | (baBitmap0 >> baShift)); + info->pkt_stats->shifted_bitmap_63_32 = baBitmap1 >> baShift; + } else { + info->pkt_stats->shifted_bitmap_31_0 = + baBitmap1 >> (baShift - BITMAP_VAR_SIZE); + info->pkt_stats->shifted_bitmap_63_32 = 0; + } + } else { + baShift = (baShift >= SEQ_NUM_RANGE/2) ? (SEQ_NUM_RANGE - baShift) : + -baShift; + if (baShift < BITMAP_VAR_SIZE) { + info->pkt_stats->shifted_bitmap_31_0 = baBitmap0 << baShift; + info->pkt_stats->shifted_bitmap_63_32 = + ((baBitmap0 << (32 - baShift)) | + (baBitmap1 >> baShift)); + } else { + info->pkt_stats->shifted_bitmap_31_0 = 0; + info->pkt_stats->shifted_bitmap_63_32 = + baBitmap0 << (baShift - BITMAP_VAR_SIZE); + } + } + } else { + info->pkt_stats->shifted_bitmap_31_0 = 0; + info->pkt_stats->shifted_bitmap_63_32 = 0; + } +} + +static void get_try_status_params(hal_info *info, + struct tx_ppdu_end *tx_ppdu_end) +{ + int try_list_index; + + if (tx_ppdu_end->stat.total_tries > 0) + try_list_index = tx_ppdu_end->stat.total_tries - 1; + else + try_list_index = 0; + + info->pkt_stats->tx_bandwidth = + tx_ppdu_end->try_list.try_st[try_list_index].packet_bw; + info->pkt_stats->series = + tx_ppdu_end->try_list.try_st[try_list_index].series; } static wifi_error parse_tx_stats(hal_info *info, void *buf, u32 buflen, u8 logtype) { - wifi_error status; + wifi_error status = WIFI_SUCCESS; + int i; wifi_ring_buffer_entry *pRingBufferEntry = (wifi_ring_buffer_entry *)info->pkt_stats->tx_stats; @@ -1278,7 +1505,7 @@ static wifi_error parse_tx_stats(hal_info *info, void *buf, { case PKTLOG_TYPE_TX_CTRL: { - if (buflen != sizeof (wh_pktlog_txctl)) { + if (buflen < sizeof (wh_pktlog_txctl)) { ALOGE("Unexpected tx_ctrl event length: %d", buflen); return WIFI_ERROR_UNKNOWN; } @@ -1292,14 +1519,20 @@ static wifi_error parse_tx_stats(hal_info *info, void *buf, PER_PACKET_ENTRY_FLAGS_PROTECTED; rb_pkt_stats->link_layer_transmit_sequence = ppdu_start->start_seq_num; + info->pkt_stats->start_seq_num = ppdu_start->start_seq_num; rb_pkt_stats->tid = ppdu_start->qos_ctl & 0xF; - parse_tx_rate_and_mcs(ppdu_start, rb_pkt_stats); + rb_pkt_stats->MCS = get_tx_mcs(info->pkt_stats->series, ppdu_start) | + (info->pkt_stats->tx_bandwidth << BW_OFFSET); + rb_pkt_stats->last_transmit_rate = get_rate(rb_pkt_stats->MCS); + + if (ppdu_start->ampdu) + get_tx_aggr_stats(ppdu_start, info); info->pkt_stats->tx_stats_events |= BIT(PKTLOG_TYPE_TX_CTRL); } break; case PKTLOG_TYPE_TX_STAT: { - if (buflen != sizeof(struct tx_ppdu_end)) { + if (buflen < sizeof(struct tx_ppdu_end)) { ALOGE("Unexpected tx_stat event length: %d", buflen); return WIFI_ERROR_UNKNOWN; } @@ -1314,20 +1547,33 @@ static wifi_error parse_tx_stats(hal_info *info, void *buf, struct tx_ppdu_end *tx_ppdu_end = (struct tx_ppdu_end*)(buf); + info->pkt_stats->ba_seq_num = tx_ppdu_end->stat.ba_start_seq_num; + info->pkt_stats->isBlockAck = tx_ppdu_end->stat.ba_status; + if (tx_ppdu_end->stat.tx_ok) - rb_pkt_stats->flags |= - PER_PACKET_ENTRY_FLAGS_TX_SUCCESS; + rb_pkt_stats->flags |= PER_PACKET_ENTRY_FLAGS_TX_SUCCESS; + info->pkt_stats->isBlockAck = tx_ppdu_end->stat.ba_status; + + info->pkt_stats->ba_bitmap_31_0 = tx_ppdu_end->stat.ba_bitmap_31_0; + info->pkt_stats->ba_bitmap_63_32 = + tx_ppdu_end->stat.ba_bitmap_63_32; rb_pkt_stats->transmit_success_timestamp = - tx_ppdu_end->try_list.try_00.timestamp; + tx_ppdu_end->try_list.try_st[0].timestamp; rb_pkt_stats->rssi = tx_ppdu_end->stat.ack_rssi_ave; - rb_pkt_stats->num_retries = - tx_ppdu_end->stat.total_tries; + rb_pkt_stats->num_retries = tx_ppdu_end->stat.total_tries; + get_try_status_params(info, tx_ppdu_end); - info->pkt_stats->tx_stats_events = BIT(PKTLOG_TYPE_TX_STAT); + info->pkt_stats->tx_stats_events |= BIT(PKTLOG_TYPE_TX_STAT); } break; - case PKTLOG_TYPE_RC_UPDATE: case PKTLOG_TYPE_TX_MSDU_ID: + { + memset(info->pkt_stats, 0, sizeof(struct pkt_stats_s)); + info->pkt_stats->num_msdu = *(u8 *)buf; + info->pkt_stats->tx_stats_events = BIT(PKTLOG_TYPE_TX_MSDU_ID); + } + break; + case PKTLOG_TYPE_RC_UPDATE: case PKTLOG_TYPE_TX_FRM_HDR: case PKTLOG_TYPE_RC_FIND: case PKTLOG_TYPE_TX_VIRT_ADDR: @@ -1342,15 +1588,72 @@ static wifi_error parse_tx_stats(hal_info *info, void *buf, } } - if ((info->pkt_stats->tx_stats_events & BIT(PKTLOG_TYPE_TX_CTRL))&& - (info->pkt_stats->tx_stats_events & BIT(PKTLOG_TYPE_TX_STAT))) { + if ((info->pkt_stats->tx_stats_events & BIT(PKTLOG_TYPE_TX_CTRL)) && + (info->pkt_stats->tx_stats_events & BIT(PKTLOG_TYPE_TX_STAT)) && + (info->pkt_stats->tx_stats_events & BIT(PKTLOG_TYPE_TX_MSDU_ID))) { /* No tx payload as of now, add the length to parameter size(3rd) * if there is any payload */ - status = update_stats_to_ring_buf(info, - (u8 *)pRingBufferEntry, + + if (info->pkt_stats->num_msdu == 1) { + if (!(rb_pkt_stats->flags & PER_PACKET_ENTRY_FLAGS_TX_SUCCESS)) + rb_pkt_stats->rssi = INVALID_RSSI; + /* Handle non aggregated cases */ + status = update_stats_to_ring_buf(info, + (u8 *)pRingBufferEntry, sizeof(wifi_ring_buffer_entry) + sizeof(wifi_ring_per_packet_status_entry)); + if (status != WIFI_SUCCESS) { + ALOGE("Failed to write into the ring buffer : %d", logtype); + } + } else { + /* Handle aggregated cases */ + for (i = 0; i < MAX_BA_WINDOW_SIZE; i++) { + if (i < BITMAP_VAR_SIZE) { + if (info->pkt_stats->tx_seqnum_bitmap_31_0 & BIT(i)) { + if (info->pkt_stats->shifted_bitmap_31_0 & BIT(i)) { + rb_pkt_stats->flags |= + PER_PACKET_ENTRY_FLAGS_TX_SUCCESS; + } else { + rb_pkt_stats->flags &= + ~PER_PACKET_ENTRY_FLAGS_TX_SUCCESS; + rb_pkt_stats->rssi = INVALID_RSSI; + } + } else { + continue; + } + } else { + if (info->pkt_stats->tx_seqnum_bitmap_63_32 + & BIT(i - BITMAP_VAR_SIZE)) { + if (info->pkt_stats->shifted_bitmap_63_32 + & BIT(i - BITMAP_VAR_SIZE)) { + rb_pkt_stats->flags |= + PER_PACKET_ENTRY_FLAGS_TX_SUCCESS; + } else { + rb_pkt_stats->flags &= + ~PER_PACKET_ENTRY_FLAGS_TX_SUCCESS; + rb_pkt_stats->rssi = INVALID_RSSI; + } + } else { + continue; + } + } + rb_pkt_stats->link_layer_transmit_sequence = + info->pkt_stats->start_seq_num + i; + + /* Take care of roll over SEQ_NUM_RANGE */ + rb_pkt_stats->link_layer_transmit_sequence &= 0xFFF; + + status = update_stats_to_ring_buf(info, + (u8 *)pRingBufferEntry, + sizeof(wifi_ring_buffer_entry) + + sizeof(wifi_ring_per_packet_status_entry)); + if (status != WIFI_SUCCESS) { + ALOGE("Failed to write into the ring buffer: %d", logtype); + break; + } + } + } /* Flush the local copy after writing the stats to ring buffer * for tx-stats. @@ -1359,23 +1662,28 @@ static wifi_error parse_tx_stats(hal_info *info, void *buf, memset(rb_pkt_stats, 0, sizeof(wifi_ring_per_packet_status_entry)); - if (status != WIFI_SUCCESS) { - ALOGE("Failed to write into the ring buffer: %d", logtype); - return status; - } } - return WIFI_SUCCESS; + return status; } -static wifi_error parse_stats_record(hal_info *info, u8 *buf, u16 record_type, - u16 record_len) +static wifi_error parse_stats_record(hal_info *info, + wh_pktlog_hdr_t *pkt_stats_header) { wifi_error status; - if (record_type == PKTLOG_TYPE_RX_STAT) { - status = parse_rx_stats(info, buf, record_len); + if (pkt_stats_header->log_type == PKTLOG_TYPE_RX_STAT) { + /* Ignore the event if it doesn't carry RX descriptor */ + if (pkt_stats_header->flags & PKT_INFO_FLG_RX_RXDESC_MASK) + status = parse_rx_stats(info, + (u8 *)(pkt_stats_header + 1), + pkt_stats_header->size); + else + status = WIFI_SUCCESS; } else { - status = parse_tx_stats(info, buf, record_len, record_type); + status = parse_tx_stats(info, + (u8 *)(pkt_stats_header + 1), + pkt_stats_header->size, + pkt_stats_header->log_type); } return status; } @@ -1397,10 +1705,7 @@ static wifi_error parse_stats(hal_info *info, u8 *data, u32 buflen) status = WIFI_ERROR_INVALID_ARGS; break; } - status = parse_stats_record(info, - (u8 *)(pkt_stats_header + 1), - pkt_stats_header->log_type, - pkt_stats_header->size); + status = parse_stats_record(info, pkt_stats_header); if (status != WIFI_SUCCESS) { ALOGE("Failed to parse the stats type : %d", pkt_stats_header->log_type); @@ -1432,19 +1737,19 @@ wifi_error process_driver_prints(hal_info *info, u8 *buf, u16 length) * complete payload memcpy */ status = ring_buffer_write(&info->rb_infos[DRIVER_PRINTS_RB_ID], (u8*)&rb_entry_hdr, - sizeof(wifi_ring_buffer_entry), 0); + sizeof(wifi_ring_buffer_entry), + 0, + sizeof(wifi_ring_buffer_entry) + length); if (status != WIFI_SUCCESS) { - ALOGE("Failed to write kernel prints rb header %d", status); + ALOGE("Failed to write driver prints rb header %d", status); return status; } status = ring_buffer_write(&info->rb_infos[DRIVER_PRINTS_RB_ID], - buf, length, 1); + buf, length, 1, length); if (status != WIFI_SUCCESS) { - ALOGE("Failed to write kernel prints rb payload %d", status); + ALOGE("Failed to write driver prints rb payload %d", status); return status; } - } else { - return WIFI_ERROR_NOT_AVAILABLE; } return WIFI_SUCCESS; @@ -1493,11 +1798,11 @@ wifi_error diag_message_handler(hal_info *info, nl_msg *msg) ALOGV("diag event_type = %0x length = %d", drv_msg->event_type, drv_msg->length); if (drv_msg->event_type == WLAN_PKT_LOG_STATS) { - if ((info->pkt_stats->prev_seq_no + 1) != + if ((info->prev_seq_no + 1) != drv_msg->u.pkt_stats_event.msg_seq_no) { ALOGE("Few pkt stats messages missed: rcvd = %d, prev = %d", drv_msg->u.pkt_stats_event.msg_seq_no, - info->pkt_stats->prev_seq_no); + info->prev_seq_no); if (info->pkt_stats->tx_stats_events) { info->pkt_stats->tx_stats_events = 0; memset(&info->pkt_stats->tx_stats, 0, @@ -1505,7 +1810,7 @@ wifi_error diag_message_handler(hal_info *info, nl_msg *msg) } } - info->pkt_stats->prev_seq_no = + info->prev_seq_no = drv_msg->u.pkt_stats_event.msg_seq_no; status = parse_stats(info, drv_msg->u.pkt_stats_event.payload, diff --git a/qcwcn/wifi_hal/wifilogger_diag.h b/qcwcn/wifi_hal/wifilogger_diag.h index 6bba3db..38bbde9 100644 --- a/qcwcn/wifi_hal/wifilogger_diag.h +++ b/qcwcn/wifi_hal/wifilogger_diag.h @@ -45,6 +45,7 @@ #define ANI_NL_MSG_LOG_HOST_PRINT_TYPE 89 #define WLAN_PKT_LOG_STATS 0x18E0 +#define FEATURE_NOT_SUPPORTED 0xFF /* * - verbose_level 0 corresponds to no collection diff --git a/qcwcn/wifi_hal/wifilogger_event_defs.h b/qcwcn/wifi_hal/wifilogger_event_defs.h index a02fdad..baf9bee 100644 --- a/qcwcn/wifi_hal/wifilogger_event_defs.h +++ b/qcwcn/wifi_hal/wifilogger_event_defs.h @@ -324,7 +324,7 @@ typedef struct { u16 Tsco; u8 Rsco; } __attribute__((packed)) wlan_bt_coex_bt_sco_stop_payload_type; -/*End EVENT_WLAN_BT_COEX_BT_SCO_STOP*/ +/* End EVENT_WLAN_BT_COEX_BT_SCO_STOP */ /* EVENT_WLAN_BT_COEX_BT_SCAN_START */ typedef struct { @@ -332,16 +332,16 @@ typedef struct { u8 scan_bitmap; } __attribute__((packed)) wlan_bt_coex_bt_scan_start_payload_type; -/*End EVENT_WLAN_BT_COEX_BT_SCAN_START*/ +/* End EVENT_WLAN_BT_COEX_BT_SCAN_START */ /* EVENT_WLAN_BT_COEX_BT_SCAN_STOP */ typedef struct { u8 scan_type; u8 scan_bitmap; } __attribute__((packed)) wlan_bt_coex_bt_scan_stop_payload_type; -/*End EVENT_WLAN_BT_COEX_BT_SCAN_STOP*/ +/* End EVENT_WLAN_BT_COEX_BT_SCAN_STOP */ -/*EVENT_WIFI_BT_COEX_BT_HID_START */ +/* EVENT_WIFI_BT_COEX_BT_HID_START */ typedef struct { u8 link_id; u8 link_state; @@ -349,7 +349,7 @@ typedef struct { u8 Tsniff; u8 attempts; } __attribute__((packed)) wlan_bt_coex_bt_hid_start_payload_type; -/*End EVENT_WIFI_BT_COEX_BT_HID_START */ +/* End EVENT_WIFI_BT_COEX_BT_HID_START */ /* EVENT_WIFI_BT_COEX_BT_HID_STOP */ typedef struct { @@ -378,7 +378,7 @@ typedef struct { } __attribute__((packed)) wlan_ext_scan_results_available_payload_type; /* End EVENT_WLAN_EXTSCAN_RESULTS_AVAILABLE */ -/* EVENT_WLAN_EXTSCAN_CAPABILITIES */ +/* Log LOG_WLAN_EXTSCAN_CAPABILITIES */ typedef struct { u32 header; u32 request_id; @@ -423,7 +423,7 @@ typedef struct { wlan_extscan_cache_capabilities extscan_cache_capabilities; wlan_extscan_hotlist_monitor_capabilities extscan_hotlist_monitor_capabilities; } __attribute__((packed)) wlan_ext_scan_capabilities_payload_type; -/* End EVENT_WLAN_EXTSCAN_CAPABILITIES*/ +/* End LOG_WLAN_EXTSCAN_CAPABILITIES */ /* EVENT_WLAN_BEACON_RECEIVED */ typedef struct { diff --git a/qcwcn/wifi_hal/wifilogger_vendor_tag_defs.h b/qcwcn/wifi_hal/wifilogger_vendor_tag_defs.h index 8b8aadf..148e3d5 100644 --- a/qcwcn/wifi_hal/wifilogger_vendor_tag_defs.h +++ b/qcwcn/wifi_hal/wifilogger_vendor_tag_defs.h @@ -108,4 +108,23 @@ typedef struct { u8 fInitiator; } __attribute__((packed)) addba_failed_vendor_data_t; +typedef struct { + u32 hotlist_mon_table_id; + u32 wlan_hotlist_entry_size; + u32 cache_cap_table_id; + u32 max_scan_cache_entries; + u32 requestor_id; + u32 vdev_id; + u32 num_extscan_cache_tables; + u32 num_wlan_change_monitor_tables; + u32 num_hotlist_monitor_tables; + u32 rtt_one_sided_supported; + u32 rtt_11v_supported; + u32 rtt_ftm_supported; + u32 num_extscan_cache_capabilities; + u32 num_extscan_wlan_change_capabilities; + u32 num_extscan_hotlist_capabilities; + u32 num_roam_bssid_blacklist; + u32 num_roam_bssid_preferred_list; +} __attribute__((packed)) gscan_capabilities_vendor_data_t; #endif /* __WIFI_HAL_WIFILOGGER_VENDOR_EVENTS_H__ */ |