Merge "WiFi-HAL: Donot dump empty vendor data buffer" into nyc-mr1-dev
diff --git a/qcwcn/wifi_hal/common.h b/qcwcn/wifi_hal/common.h
index f0b8373..3185b08 100644
--- a/qcwcn/wifi_hal/common.h
+++ b/qcwcn/wifi_hal/common.h
@@ -86,6 +86,7 @@
} interface_info;
struct gscan_event_handlers_s;
+struct rssi_monitor_event_handler_s;
typedef struct hal_info_s {
@@ -139,6 +140,7 @@
packet_fate_monitor_info *pkt_fate_stats;
/* mutex for the packet fate stats shared resource protection */
pthread_mutex_t pkt_fate_stats_lock;
+ struct rssi_monitor_event_handler_s *rssi_handlers;
} hal_info;
wifi_error wifi_register_handler(wifi_handle handle, int cmd, nl_recvmsg_msg_cb_t func, void *arg);
@@ -160,6 +162,8 @@
wifi_interface_handle getIfaceHandle(interface_info *info);
wifi_error initializeGscanHandlers(hal_info *info);
wifi_error cleanupGscanHandlers(hal_info *info);
+wifi_error initializeRSSIMonitorHandler(hal_info *info);
+wifi_error cleanupRSSIMonitorHandler(hal_info *info);
lowi_cb_table_t *getLowiCallbackTable(u32 requested_lowi_capabilities);
diff --git a/qcwcn/wifi_hal/rssi_monitor.cpp b/qcwcn/wifi_hal/rssi_monitor.cpp
index 6b96c10..8cffe98 100644
--- a/qcwcn/wifi_hal/rssi_monitor.cpp
+++ b/qcwcn/wifi_hal/rssi_monitor.cpp
@@ -38,20 +38,88 @@
#include "rssi_monitor.h"
#include "vendor_definitions.h"
-//Singleton Static Instance
-RSSIMonitorCommand* RSSIMonitorCommand::mRSSIMonitorCommandInstance = NULL;
+/* Used to handle rssi command events from driver/firmware.*/
+typedef struct rssi_monitor_event_handler_s {
+ RSSIMonitorCommand* mRSSIMonitorCommandInstance;
+} rssi_monitor_event_handlers;
+
+wifi_error initializeRSSIMonitorHandler(hal_info *info)
+{
+ info->rssi_handlers = (rssi_monitor_event_handlers *)malloc(sizeof(
+ rssi_monitor_event_handlers));
+ if (info->rssi_handlers) {
+ memset(info->rssi_handlers, 0, sizeof(rssi_monitor_event_handlers));
+ }
+ else {
+ ALOGE("%s: Allocation of RSSI event handlers failed",
+ __FUNCTION__);
+ return WIFI_ERROR_OUT_OF_MEMORY;
+ }
+ return WIFI_SUCCESS;
+}
+
+wifi_error cleanupRSSIMonitorHandler(hal_info *info)
+{
+ rssi_monitor_event_handlers* event_handlers;
+ if (info && info->rssi_handlers) {
+ event_handlers = (rssi_monitor_event_handlers*) info->rssi_handlers;
+ if (event_handlers->mRSSIMonitorCommandInstance) {
+ delete event_handlers->mRSSIMonitorCommandInstance;
+ }
+ memset(event_handlers, 0, sizeof(rssi_monitor_event_handlers));
+ return WIFI_SUCCESS;
+ }
+ ALOGE ("%s: info or info->rssi_handlers NULL", __FUNCTION__);
+ return WIFI_ERROR_UNKNOWN;
+}
+
+void RSSIMonitorCommand::enableEventHandling()
+{
+ pthread_mutex_lock(&rm_lock);
+ mEventHandlingEnabled = true;
+ pthread_mutex_unlock(&rm_lock);
+}
+
+void RSSIMonitorCommand::disableEventHandling()
+{
+ pthread_mutex_lock(&rm_lock);
+ mEventHandlingEnabled = false;
+ pthread_mutex_unlock(&rm_lock);
+}
+
+bool RSSIMonitorCommand::isEventHandlingEnabled()
+{
+ bool eventHandlingEnabled;
+ pthread_mutex_lock(&rm_lock);
+ eventHandlingEnabled = mEventHandlingEnabled;
+ pthread_mutex_unlock(&rm_lock);
+
+ return eventHandlingEnabled;
+}
+
+void RSSIMonitorCommand::setCallbackHandler(wifi_rssi_event_handler handler)
+{
+ mHandler = handler;
+}
RSSIMonitorCommand::RSSIMonitorCommand(wifi_handle handle, int id,
u32 vendor_id, u32 subcmd)
: WifiVendorCommand(handle, id, vendor_id, subcmd)
{
- mRSSIMonitorCommandInstance = NULL;
memset(&mHandler, 0, sizeof(mHandler));
+ if (registerVendorHandler(vendor_id, subcmd)) {
+ /* Error case should not happen print log */
+ ALOGE("%s: Unable to register Vendor Handler Vendor Id=0x%x subcmd=%u",
+ __FUNCTION__, vendor_id, subcmd);
+ }
+ pthread_mutex_init(&rm_lock, NULL);
+ disableEventHandling();
}
RSSIMonitorCommand::~RSSIMonitorCommand()
{
- mRSSIMonitorCommandInstance = NULL;
+ unregisterVendorHandler(mVendor_id, mSubcmd);
+ pthread_mutex_destroy(&rm_lock);
}
void RSSIMonitorCommand::setReqId(wifi_request_id reqid)
@@ -66,10 +134,20 @@
ALOGE("Interface Handle is invalid");
return NULL;
}
+ hal_info *info = getHalInfo(handle);
+ if (!info || !info->rssi_handlers) {
+ ALOGE("rssi_handlers is invalid");
+ return NULL;
+ }
+
+ RSSIMonitorCommand* mRSSIMonitorCommandInstance =
+ info->rssi_handlers->mRSSIMonitorCommandInstance;
+
if (mRSSIMonitorCommandInstance == NULL) {
mRSSIMonitorCommandInstance = new RSSIMonitorCommand(handle, id,
OUI_QCA,
QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI);
+ info->rssi_handlers->mRSSIMonitorCommandInstance = mRSSIMonitorCommandInstance;
return mRSSIMonitorCommandInstance;
}
else
@@ -92,6 +170,13 @@
int RSSIMonitorCommand::handleEvent(WifiEvent &event)
{
int ret = WIFI_SUCCESS;
+
+ if (isEventHandlingEnabled() == false) {
+ ALOGE("%s: RSSI monitor isn't running or already stopped. "
+ "Nothing to do. Exit", __FUNCTION__);
+ return ret;
+ }
+
WifiVendorCommand::handleEvent(event);
/* Parse the vendordata and get the attribute */
@@ -159,29 +244,9 @@
ALOGE("%s: Wrong subcmd received %d", __FUNCTION__, mSubcmd);
}
- return NL_SKIP;
-}
-
-int RSSIMonitorCommand::setCallbackHandler(wifi_rssi_event_handler nHandler,
- u32 event)
-{
- int ret;
- mHandler = nHandler;
- ret = registerVendorHandler(mVendor_id, event);
- if (ret != 0) {
- /* Error case should not happen print log */
- ALOGE("%s: Unable to register Vendor Handler Vendor Id=0x%x subcmd=%u",
- __FUNCTION__, mVendor_id, mSubcmd);
- }
return ret;
}
-wifi_error RSSIMonitorCommand::unregisterHandler(u32 subCmd)
-{
- unregisterVendorHandler(mVendor_id, subCmd);
- return WIFI_SUCCESS;
-}
-
wifi_error wifi_start_rssi_monitoring(wifi_request_id id,
wifi_interface_handle iface,
s8 max_rssi,
@@ -233,15 +298,14 @@
return WIFI_ERROR_OUT_OF_MEMORY;
}
- ret = rssiCommand->setCallbackHandler(eh,
- QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI);
- if (ret < 0)
- goto cleanup;
+ rssiCommand->setCallbackHandler(eh);
ret = vCommand->requestResponse();
if (ret < 0)
goto cleanup;
+ rssiCommand->enableEventHandling();
+
cleanup:
delete vCommand;
return (wifi_error)ret;
@@ -255,6 +319,18 @@
WifiVendorCommand *vCommand = NULL;
wifi_handle wifiHandle = getWifiHandle(iface);
RSSIMonitorCommand *rssiCommand;
+ rssi_monitor_event_handlers* event_handlers;
+ hal_info *info = getHalInfo(wifiHandle);
+
+ event_handlers = (rssi_monitor_event_handlers*)info->rssi_handlers;
+ rssiCommand = event_handlers->mRSSIMonitorCommandInstance;
+
+ if (rssiCommand == NULL ||
+ rssiCommand->isEventHandlingEnabled() == false) {
+ ALOGE("%s: RSSI monitor isn't running or already stopped. "
+ "Nothing to do. Exit", __FUNCTION__);
+ return WIFI_ERROR_NOT_AVAILABLE;
+ }
ret = initialize_vendor_cmd(iface, id,
QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI,
@@ -285,19 +361,8 @@
if (ret < 0)
goto cleanup;
- rssiCommand = RSSIMonitorCommand::instance(wifiHandle, id);
- if (rssiCommand == NULL) {
- ALOGE("%s: Error rssiCommand NULL", __FUNCTION__);
- ret = WIFI_ERROR_OUT_OF_MEMORY;
- goto cleanup;
- }
+ rssiCommand->disableEventHandling();
- ret = rssiCommand->unregisterHandler(
- QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI);
- if (ret != WIFI_SUCCESS)
- goto cleanup;
-
- delete rssiCommand;
cleanup:
delete vCommand;
diff --git a/qcwcn/wifi_hal/rssi_monitor.h b/qcwcn/wifi_hal/rssi_monitor.h
index bd3d88e..c6ea692 100644
--- a/qcwcn/wifi_hal/rssi_monitor.h
+++ b/qcwcn/wifi_hal/rssi_monitor.h
@@ -42,14 +42,19 @@
static RSSIMonitorCommand *mRSSIMonitorCommandInstance;
wifi_rssi_event_handler mHandler;
RSSIMonitorCommand(wifi_handle handle, int id, u32 vendor_id, u32 subcmd);
+ bool mEventHandlingEnabled;
+ /* mutex for the mEventHandlingEnabled access*/
+ pthread_mutex_t rm_lock;
public:
virtual ~RSSIMonitorCommand();
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);
virtual void setReqId(wifi_request_id reqid);
+ virtual void setCallbackHandler(wifi_rssi_event_handler nHandler);
+ void enableEventHandling();
+ void disableEventHandling();
+ bool isEventHandlingEnabled();
};
#ifdef __cplusplus
diff --git a/qcwcn/wifi_hal/wifi_hal.cpp b/qcwcn/wifi_hal/wifi_hal.cpp
index d59d138..64c0143 100644
--- a/qcwcn/wifi_hal/wifi_hal.cpp
+++ b/qcwcn/wifi_hal/wifi_hal.cpp
@@ -97,15 +97,10 @@
void wifi_socket_set_local_port(struct nl_sock *sock, uint32_t port)
{
- uint32_t pid = getpid() & 0x3FFFFF;
-
- if (port == 0) {
- sock->s_flags &= ~NL_OWN_PORT;
- } else {
- sock->s_flags |= NL_OWN_PORT;
- }
-
- sock->s_local.nl_pid = pid + (port << 22);
+ /* Release local port pool maintained by libnl and assign a own port
+ * identifier to the socket.
+ */
+ nl_socket_set_local_port(sock, ((uint32_t)getpid() & 0x3FFFFFU) | (port << 22));
}
static nl_sock * wifi_create_nl_socket(int port, int protocol)
@@ -560,6 +555,12 @@
goto unload;
}
+ ret = initializeRSSIMonitorHandler(info);
+ if (ret != WIFI_SUCCESS) {
+ ALOGE("Initializing RSSI Event Handler Failed");
+ goto unload;
+ }
+
ALOGV("Initialized Wifi HAL Successfully; vendor cmd = %d Supported"
" features : %x", NL80211_CMD_VENDOR, info->supported_feature_set);
@@ -576,6 +577,7 @@
if (info->pkt_stats) free(info->pkt_stats);
if (info->rx_aggr_pkts) free(info->rx_aggr_pkts);
cleanupGscanHandlers(info);
+ cleanupRSSIMonitorHandler(info);
free(info);
}
}
@@ -626,6 +628,7 @@
free(info->rx_aggr_pkts);
wifi_logger_ring_buffers_deinit(info);
cleanupGscanHandlers(info);
+ cleanupRSSIMonitorHandler(info);
if (info->exit_sockets[0] >= 0) {
close(info->exit_sockets[0]);