summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXin Li <delphij@google.com>2022-02-11 06:57:37 +0000
committerXin Li <delphij@google.com>2022-02-11 06:57:37 +0000
commitd7cf82ba13d430e8d07290637f70d0b8994ded9b (patch)
tree40517ca0a3a340225c1f6b7fed6c34fe27f740a7
parentaf97769c0a8cca7edb53b13af439be6712a21cd4 (diff)
parentfd39d364f5f1582b13d1d39fbb1ba17d244e8a28 (diff)
downloadwlan-sam_222710654.tar.gz
Merge sc-v2-dev-plus-aosp-without-vendor@8084891sam_222710654
Bug: 214455710 Merged-In: Icf4354c4eee74cac3ebedcaba1116320e750b2a3 Change-Id: I3f481ff3c48d84971d4a499648e688eaed4637fe
-rwxr-xr-xbcmdhd/wifi_hal/common.cpp13
-rwxr-xr-xbcmdhd/wifi_hal/common.h1
-rwxr-xr-xbcmdhd/wifi_hal/cpp_bindings.h4
-rwxr-xr-xbcmdhd/wifi_hal/gscan.cpp41
-rw-r--r--bcmdhd/wifi_hal/rtt.cpp1
-rwxr-xr-xbcmdhd/wifi_hal/wifi_hal.cpp31
-rwxr-xr-xbcmdhd/wifi_hal/wifi_logger.cpp48
7 files changed, 104 insertions, 35 deletions
diff --git a/bcmdhd/wifi_hal/common.cpp b/bcmdhd/wifi_hal/common.cpp
index 887b530..5a9d5ab 100755
--- a/bcmdhd/wifi_hal/common.cpp
+++ b/bcmdhd/wifi_hal/common.cpp
@@ -166,14 +166,11 @@ void wifi_unregister_handler(wifi_handle handle, int cmd)
pthread_mutex_unlock(&info->cb_lock);
}
-void wifi_unregister_vendor_handler(wifi_handle handle, uint32_t id, int subcmd)
+void wifi_unregister_vendor_handler_without_lock(wifi_handle handle, uint32_t id, int subcmd)
{
hal_info *info = (hal_info *)handle;
- pthread_mutex_lock(&info->cb_lock);
-
for (int i = 0; i < info->num_event_cb; i++) {
-
if (info->event_cb[i].nl_cmd == NL80211_CMD_VENDOR
&& info->event_cb[i].vendor_id == id
&& info->event_cb[i].vendor_subcmd == subcmd) {
@@ -185,11 +182,17 @@ void wifi_unregister_vendor_handler(wifi_handle handle, uint32_t id, int subcmd)
break;
}
}
+}
+void wifi_unregister_vendor_handler(wifi_handle handle, uint32_t id, int subcmd)
+{
+ hal_info *info = (hal_info *)handle;
+
+ pthread_mutex_lock(&info->cb_lock);
+ wifi_unregister_vendor_handler_without_lock(handle, id, subcmd);
pthread_mutex_unlock(&info->cb_lock);
}
-
wifi_error wifi_register_cmd(wifi_handle handle, int id, WifiCommand *cmd)
{
hal_info *info = (hal_info *)handle;
diff --git a/bcmdhd/wifi_hal/common.h b/bcmdhd/wifi_hal/common.h
index d5bc971..9065802 100755
--- a/bcmdhd/wifi_hal/common.h
+++ b/bcmdhd/wifi_hal/common.h
@@ -424,6 +424,7 @@ wifi_error wifi_register_vendor_handler(wifi_handle handle,
uint32_t id, int subcmd, nl_recvmsg_msg_cb_t func, void *arg);
void wifi_unregister_handler(wifi_handle handle, int cmd);
+void wifi_unregister_vendor_handler_without_lock(wifi_handle handle, uint32_t id, int subcmd);
void wifi_unregister_vendor_handler(wifi_handle handle, uint32_t id, int subcmd);
wifi_error wifi_register_cmd(wifi_handle handle, int id, WifiCommand *cmd);
diff --git a/bcmdhd/wifi_hal/cpp_bindings.h b/bcmdhd/wifi_hal/cpp_bindings.h
index 456f31c..8b5600a 100755
--- a/bcmdhd/wifi_hal/cpp_bindings.h
+++ b/bcmdhd/wifi_hal/cpp_bindings.h
@@ -347,6 +347,10 @@ protected:
return wifi_register_vendor_handler(wifiHandle(), id, subcmd, &event_handler, this);
}
+ void unregisterVendorHandlerWithoutLock(uint32_t id, int subcmd) {
+ wifi_unregister_vendor_handler_without_lock(wifiHandle(), id, subcmd);
+ }
+
void unregisterVendorHandler(uint32_t id, int subcmd) {
wifi_unregister_vendor_handler(wifiHandle(), id, subcmd);
}
diff --git a/bcmdhd/wifi_hal/gscan.cpp b/bcmdhd/wifi_hal/gscan.cpp
index f012423..995c989 100755
--- a/bcmdhd/wifi_hal/gscan.cpp
+++ b/bcmdhd/wifi_hal/gscan.cpp
@@ -404,8 +404,8 @@ public:
result = requestResponse(request);
if (result != WIFI_SUCCESS) {
- ALOGE("failed to enable full scan results; result = %d", result);
unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_FULL_SCAN_RESULTS);
+ ALOGE("failed to enable full scan results; result = %d", result);
return result;
}
@@ -566,6 +566,12 @@ public:
return createFeatureRequest(request, GSCAN_SUBCMD_ENABLE_GSCAN, 0);
}
+ void unregisterVendorHandlerAll() {
+ unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_COMPLETE_SCAN);
+ unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_SCAN_RESULTS_AVAILABLE);
+ unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_FULL_SCAN_RESULTS);
+ }
+
int start() {
ALOGV("GSCAN start");
WifiRequest request(familyId(), ifaceId());
@@ -581,6 +587,7 @@ public:
result = requestResponse(request);
if (result != WIFI_SUCCESS) {
+ unregisterVendorHandlerAll();
ALOGE("failed to configure setup; result = %d", result);
return result;
}
@@ -589,12 +596,14 @@ public:
result = createScanConfigRequest(request);
if (result != WIFI_SUCCESS) {
+ unregisterVendorHandlerAll();
ALOGE("failed to create scan config request; result = %d", result);
return result;
}
result = requestResponse(request);
if (result != WIFI_SUCCESS) {
+ unregisterVendorHandlerAll();
ALOGE("failed to configure scan; result = %d", result);
return result;
}
@@ -603,16 +612,15 @@ public:
result = createStartRequest(request);
if (result != WIFI_SUCCESS) {
+ unregisterVendorHandlerAll();
ALOGE("failed to create start request; result = %d", result);
return result;
}
result = requestResponse(request);
if (result != WIFI_SUCCESS) {
+ unregisterVendorHandlerAll();
ALOGE("failed to start scan; result = %d", result);
- unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_COMPLETE_SCAN);
- unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_SCAN_RESULTS_AVAILABLE);
- unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_FULL_SCAN_RESULTS);
return result;
}
return result;
@@ -632,9 +640,7 @@ public:
}
}
- unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_COMPLETE_SCAN);
- unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_SCAN_RESULTS_AVAILABLE);
- unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_FULL_SCAN_RESULTS);
+ unregisterVendorHandlerAll();
return WIFI_SUCCESS;
}
@@ -1057,6 +1063,11 @@ public:
return result;
}
+ void unregisterVendorHandlerAll() {
+ unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_HOTLIST_RESULTS_FOUND);
+ unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_HOTLIST_RESULTS_LOST);
+ }
+
int start() {
ALOGI("Executing hotlist setup request, num = %d", mParams.num_bssid);
WifiRequest request(familyId(), ifaceId());
@@ -1070,22 +1081,21 @@ public:
result = requestResponse(request);
if (result < 0) {
+ unregisterVendorHandlerAll();
ALOGI("Failed to execute hotlist setup request, result = %d", result);
- unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_HOTLIST_RESULTS_FOUND);
- unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_HOTLIST_RESULTS_LOST);
return result;
}
ALOGI("Successfully set %d APs in the hotlist ", mParams.num_bssid);
result = createFeatureRequest(request, GSCAN_SUBCMD_ENABLE_GSCAN, 1);
if (result < 0) {
+ unregisterVendorHandlerAll();
return result;
}
result = requestResponse(request);
if (result < 0) {
- unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_HOTLIST_RESULTS_FOUND);
- unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_HOTLIST_RESULTS_LOST);
+ unregisterVendorHandlerAll();
return result;
}
@@ -1095,8 +1105,7 @@ public:
virtual int cancel() {
/* unregister event handler */
- unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_HOTLIST_RESULTS_FOUND);
- unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_HOTLIST_RESULTS_LOST);
+ unregisterVendorHandlerAll();
/* create set hotlist message with empty hotlist */
WifiRequest request(familyId(), ifaceId());
int result = createTeardownRequest(request);
@@ -1288,8 +1297,8 @@ public:
registerVendorHandler(GOOGLE_OUI, GSCAN_EVENT_EPNO_EVENT);
result = requestResponse(request);
if (result < 0) {
- ALOGI("Failed to execute ePNO setup request, result = %d", result);
unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_EPNO_EVENT);
+ ALOGI("Failed to execute ePNO setup request, result = %d", result);
return result;
}
@@ -1496,6 +1505,7 @@ public:
result = requestResponse(request);
if (result < 0) {
+ unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_SIGNIFICANT_CHANGE_RESULTS);
ALOGI("failed to set significant wifi change config %d", result);
return result;
}
@@ -1504,6 +1514,7 @@ public:
result = createFeatureRequest(request, GSCAN_SUBCMD_ENABLE_GSCAN, 1);
if (result < 0) {
+ unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_SIGNIFICANT_CHANGE_RESULTS);
return result;
}
@@ -1891,8 +1902,8 @@ public:
result = requestResponse(request);
if (result != WIFI_SUCCESS) {
- ALOGE("failed to set ANQPO networks; result = %d", result);
unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_ANQPO_HOTSPOT_MATCH);
+ ALOGE("failed to set ANQPO networks; result = %d", result);
return result;
}
diff --git a/bcmdhd/wifi_hal/rtt.cpp b/bcmdhd/wifi_hal/rtt.cpp
index 43a49e8..6bb0a49 100644
--- a/bcmdhd/wifi_hal/rtt.cpp
+++ b/bcmdhd/wifi_hal/rtt.cpp
@@ -488,6 +488,7 @@ public:
registerVendorHandler(GOOGLE_OUI, RTT_EVENT_COMPLETE);
result = requestResponse(request);
if (result != WIFI_SUCCESS) {
+ unregisterVendorHandler(GOOGLE_OUI, RTT_EVENT_COMPLETE);
ALOGE("failed to configure RTT setup; result = %d", result);
return result;
}
diff --git a/bcmdhd/wifi_hal/wifi_hal.cpp b/bcmdhd/wifi_hal/wifi_hal.cpp
index d3ffe57..c83c482 100755
--- a/bcmdhd/wifi_hal/wifi_hal.cpp
+++ b/bcmdhd/wifi_hal/wifi_hal.cpp
@@ -1043,7 +1043,36 @@ public:
: WifiCommand("SetRSSIMonitorCommand", handle, id), mMax_rssi(max_rssi), mMin_rssi
(min_rssi), mHandler(eh)
{
+ ALOGI("SetRSSIMonitorCommand %p created", this);
+ }
+
+ virtual ~SetRSSIMonitorCommand() {
+ /*
+ * Mostly, this call will be no effect. However, this could be valid
+ * when object destroy without calling unregisterVendorHandler().
+ * This is added to protect hal crash due to use-after-free.
+ */
+ ALOGI("Try to remove event handler if exist, vendor 0x%0x, subcmd 0x%x",
+ GOOGLE_OUI, GOOGLE_RSSI_MONITOR_EVENT);
+ unregisterVendorHandlerWithoutLock(GOOGLE_OUI, GOOGLE_RSSI_MONITOR_EVENT);
+ ALOGI("SetRSSIMonitorCommand %p destroyed", this);
+ }
+
+ virtual void addRef() {
+ int refs = __sync_add_and_fetch(&mRefs, 1);
+ ALOGI("addRef: WifiCommand %p has %d references", this, refs);
+ }
+
+ virtual void releaseRef() {
+ int refs = __sync_sub_and_fetch(&mRefs, 1);
+ if (refs == 0) {
+ ALOGI("releaseRef: WifiCommand %p has deleted", this);
+ delete this;
+ } else {
+ ALOGI("releaseRef: WifiCommand %p has %d references", this, refs);
}
+ }
+
int createRequest(WifiRequest& request, int enable) {
int result = request.create(GOOGLE_OUI, WIFI_SUBCMD_SET_RSSI_MONITOR);
if (result < 0) {
@@ -1759,11 +1788,13 @@ static wifi_error wifi_start_rssi_monitoring(wifi_request_id id, wifi_interface_
NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
wifi_error result = wifi_register_cmd(handle, id, cmd);
if (result != WIFI_SUCCESS) {
+ ALOGI("wifi_register_cmd() is failed %d", id);
cmd->releaseRef();
return result;
}
result = (wifi_error)cmd->start();
if (result != WIFI_SUCCESS) {
+ ALOGI("start() is failed %d", id);
wifi_unregister_cmd(handle, id);
cmd->releaseRef();
return result;
diff --git a/bcmdhd/wifi_hal/wifi_logger.cpp b/bcmdhd/wifi_hal/wifi_logger.cpp
index 440d9ba..85cf0e7 100755
--- a/bcmdhd/wifi_hal/wifi_logger.cpp
+++ b/bcmdhd/wifi_hal/wifi_logger.cpp
@@ -189,6 +189,27 @@ typedef enum {
#define HAL_START_REQUEST_ID 2
#define HAL_RESTART_ID 3
#define FILE_NAME_LEN 256
+
+typedef struct {
+ char hw_id[PROPERTY_VALUE_MAX];
+ char sku[MAX_SKU_NAME_LEN];
+} sku_info_t;
+
+sku_info_t sku_table[] = {
+ { {"G9S9B"}, {"MMW"} },
+ { {"G8V0U"}, {"MMW"} },
+ { {"GFQM1"}, {"MMW"} },
+ { {"GB62Z"}, {"MMW"} },
+ { {"GB7N6"}, {"ROW"} },
+ { {"GLU0G"}, {"ROW"} },
+ { {"GNA8F"}, {"ROW"} },
+ { {"GX7AS"}, {"ROW"} },
+ { {"GR1YH"}, {"JPN"} },
+ { {"GF5KQ"}, {"JPN"} },
+ { {"GPQ72"}, {"JPN"} },
+ { {"GB17L"}, {"JPN"} },
+ { {"G1AZG"}, {"EU"} }
+};
///////////////////////////////////////////////////////////////////////////////
class DebugCommand : public WifiCommand
{
@@ -633,7 +654,6 @@ public:
ALOGV("Register loghandler");
int result;
uint32_t event_sock_pid = getpid() + (WIFI_HAL_EVENT_SOCK_PORT << 22);
- registerVendorHandler(GOOGLE_OUI, GOOGLE_DEBUG_RING_EVENT);
WifiRequest request(familyId(), ifaceId());
@@ -643,14 +663,18 @@ public:
ALOGV("Failed to set Hal preInit; result = %d", result);
return result;
}
+ registerVendorHandler(GOOGLE_OUI, GOOGLE_DEBUG_RING_EVENT);
+
nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
result = request.put_u32(SET_HAL_START_ATTRIBUTE_EVENT_SOCK_PID, event_sock_pid);
if (result != WIFI_SUCCESS) {
+ unregisterVendorHandler(GOOGLE_OUI, GOOGLE_DEBUG_RING_EVENT);
ALOGV("Hal preInit Failed to put pic = %d", result);
return result;
}
if (result != WIFI_SUCCESS) {
+ unregisterVendorHandler(GOOGLE_OUI, GOOGLE_DEBUG_RING_EVENT);
ALOGV("Hal preInit Failed to put pid= %d", result);
return result;
}
@@ -659,6 +683,7 @@ public:
result = requestResponse(request);
if (result != WIFI_SUCCESS) {
+ unregisterVendorHandler(GOOGLE_OUI, GOOGLE_DEBUG_RING_EVENT);
ALOGE("Failed to register set Hal preInit; result = %d", result);
return result;
}
@@ -1994,21 +2019,14 @@ wifi_error wifi_hal_ota_update(wifi_interface_handle iface, uint32_t ota_version
property_get(HW_DEV_PROP, prop_revision_buf, NULL);
property_get(HW_SKU_PROP, prop_sku_buf, NULL);
- if (strcmp(prop_sku_buf, "G9S9B") == 0 ||
- strcmp(prop_sku_buf, "G8V0U") == 0 ||
- strcmp(prop_sku_buf, "GFQM1") == 0) {
- strncpy(sku_name, "MMW", MAX_SKU_NAME_LEN);
- } else if (strcmp(prop_sku_buf, "GR1YH") == 0 ||
- strcmp(prop_sku_buf, "GF5KQ") == 0 ||
- strcmp(prop_sku_buf, "GPQ72") == 0) {
- strncpy(sku_name, "JPN", MAX_SKU_NAME_LEN);
- } else if (strcmp(prop_sku_buf, "GB7N6") == 0 ||
- strcmp(prop_sku_buf, "GLU0G") == 0 ||
- strcmp(prop_sku_buf, "GNA8F") == 0) {
- strncpy(sku_name, "ROW", MAX_SKU_NAME_LEN);
- } else {
- strncpy(sku_name, "NA", MAX_SKU_NAME_LEN);
+ strncpy(sku_name, "NA", MAX_SKU_NAME_LEN);
+ for (int i = 0; i < ARRAYSIZE(sku_table); i ++) {
+ if (strcmp(prop_sku_buf, sku_table[i].hw_id) == 0) {
+ strncpy(sku_name, sku_table[i].sku, MAX_SKU_NAME_LEN);
+ break;
+ }
}
+ ALOGD("prop_sku_buf is %s, sku_name is %s", prop_sku_buf, sku_name);
check_multiple_nvram_clm(CLM_BLOB, prop_revision_buf, sku_name, &buffer_clm, &buf.ota_clm_len);
if (buffer_clm == NULL) {