summaryrefslogtreecommitdiffstats
path: root/bcmdhd/wifi_hal
diff options
context:
space:
mode:
authoreccopark@broadcom.com <eccopark@broadcom.com>2015-03-13 20:10:23 -0700
committereccopark@broadcom.com <eccopark@broadcom.com>2015-03-19 14:07:09 -0700
commit215b92f52a64b5f4b56589fcb7c788fc68b43aa5 (patch)
tree53a2553414877a9f936c8fdadcee715e7acd372f /bcmdhd/wifi_hal
parent97f03599b75a2b98720e4627efcc12fe764ed811 (diff)
downloadhardware_broadcom_wlan-215b92f52a64b5f4b56589fcb7c788fc68b43aa5.zip
hardware_broadcom_wlan-215b92f52a64b5f4b56589fcb7c788fc68b43aa5.tar.gz
hardware_broadcom_wlan-215b92f52a64b5f4b56589fcb7c788fc68b43aa5.tar.bz2
net: wireles: bcmdhd rtt.cpp changes for 11mc of halutil
Change-Id: If4ccdf6e7956d25f51c946b0fbfa483a22bcdd64 Signed-off-by: eccopark@broadcom.com <eccopark@broadcom.com>
Diffstat (limited to 'bcmdhd/wifi_hal')
-rw-r--r--bcmdhd/wifi_hal/Android.mk2
-rwxr-xr-x[-rw-r--r--]bcmdhd/wifi_hal/rtt.cpp251
2 files changed, 214 insertions, 39 deletions
diff --git a/bcmdhd/wifi_hal/Android.mk b/bcmdhd/wifi_hal/Android.mk
index 74a36c3..0755a45 100644
--- a/bcmdhd/wifi_hal/Android.mk
+++ b/bcmdhd/wifi_hal/Android.mk
@@ -26,6 +26,8 @@ LOCAL_CPPFLAGS += -Wno-conversion-null
LOCAL_C_INCLUDES += \
external/libnl/include \
+ external/stlport/stlport \
+ bionic \
$(call include-path-for, libhardware_legacy)/hardware_legacy \
external/wpa_supplicant_8/src/drivers
diff --git a/bcmdhd/wifi_hal/rtt.cpp b/bcmdhd/wifi_hal/rtt.cpp
index 92896fb..67c32cd 100644..100755
--- a/bcmdhd/wifi_hal/rtt.cpp
+++ b/bcmdhd/wifi_hal/rtt.cpp
@@ -22,11 +22,14 @@
#define LOG_TAG "WifiHAL"
#include <utils/Log.h>
+#include <utils/String8.h>
#include "wifi_hal.h"
#include "common.h"
#include "cpp_bindings.h"
+using namespace android;
+#define RTT_RESULT_SIZE (sizeof(wifi_rtt_result));
typedef enum {
RTT_SUBCMD_SET_CONFIG = ANDROID_NL80211_SUBCMD_RTT_RANGE_START,
@@ -35,19 +38,78 @@ typedef enum {
} RTT_SUB_COMMAND;
typedef enum {
- RTT_ATTRIBUTE_TARGET_CNT,
+ RTT_ATTRIBUTE_TARGET_CNT = 0,
RTT_ATTRIBUTE_TARGET_INFO,
RTT_ATTRIBUTE_TARGET_MAC,
RTT_ATTRIBUTE_TARGET_TYPE,
RTT_ATTRIBUTE_TARGET_PEER,
RTT_ATTRIBUTE_TARGET_CHAN,
- RTT_ATTRIBUTE_TARGET_MODE,
RTT_ATTRIBUTE_TARGET_INTERVAL,
- RTT_ATTRIBUTE_TARGET_NUM_MEASUREMENT,
- RTT_ATTRIBUTE_TARGET_NUM_PKT,
- RTT_ATTRIBUTE_TARGET_NUM_RETRY,
+ RTT_ATTRIBUTE_TARGET_NUM_BURST,
+ RTT_ATTRIBUTE_TARGET_NUM_FTM_BURST,
+ RTT_ATTRIBUTE_TARGET_NUM_RETRY_FTM,
+ RTT_ATTRIBUTE_TARGET_NUM_RETRY_FTMR,
+ RTT_ATTRIBUTE_TARGET_LCI,
+ RTT_ATTRIBUTE_TARGET_LCR,
+ RTT_ATTRIBUTE_TARGET_BURST_TIMEOUT,
+ RTT_ATTRIBUTE_TARGET_PREAMBLE,
+ RTT_ATTRIBUTE_TARGET_BW,
+ RTT_ATTRIBUTE_RESULTS_COMPLETE = 30,
+ RTT_ATTRIBUTE_RESULTS_PER_TARGET,
+ RTT_ATTRIBUTE_RESULT_CNT,
+ RTT_ATTRIBUTE_RESULT
+} RTT_ATTRIBUTE;
+typedef struct strmap_entry {
+ int id;
+ String8 text;
+} strmap_entry_t;
+struct dot11_rm_ie {
+ u8 id;
+ u8 len;
+ u8 token;
+ u8 mode;
+ u8 type;
+} __attribute__ ((packed));
+typedef struct dot11_rm_ie dot11_rm_ie_t;
+#define DOT11_HDR_LEN 2
+#define DOT11_RM_IE_LEN 5
+#define DOT11_MNG_MEASURE_REQUEST_ID 38 /* 11H MeasurementRequest */
+#define DOT11_MEASURE_TYPE_LCI 8 /* d11 measurement LCI type */
+#define DOT11_MEASURE_TYPE_CIVICLOC 11 /* d11 measurement location civic */
+
+static const strmap_entry_t err_info[] = {
+ {RTT_STATUS_SUCCESS, String8("Success")},
+ {RTT_STATUS_FAILURE, String8("Failure")},
+ {RTT_STATUS_FAIL_NO_RSP, String8("No reponse")},
+ {RTT_STATUS_FAIL_INVALID_TS, String8("Invalid Timestamp")},
+ {RTT_STATUS_FAIL_PROTOCOL, String8("Protocol error")},
+ {RTT_STATUS_FAIL_REJECTED, String8("Rejected")},
+ {RTT_STATUS_FAIL_NOT_SCHEDULED_YET, String8("not scheduled")},
+ {RTT_STATUS_FAIL_SCHEDULE, String8("schedule failed")},
+ {RTT_STATUS_FAIL_TM_TIMEOUT, String8("timeout")},
+ {RTT_STATUS_FAIL_AP_ON_DIFF_CHANNEL, String8("AP is on difference channel")},
+ {RTT_STATUS_FAIL_NO_CAPABILITY, String8("no capability")},
+ {RTT_STATUS_FAIL_BUSY_TRY_LATER, String8("busy and try later")},
+ {RTT_STATUS_ABORTED, String8("aborted")}
+};
+
+ static const char*
+get_err_info(int status)
+{
+ int i;
+ const strmap_entry_t *p_entry;
+ int num_entries = sizeof(err_info)/ sizeof(err_info[0]);
+ /* scan thru the table till end */
+ p_entry = err_info;
+ for (i = 0; i < (int) num_entries; i++)
+ {
+ if (p_entry->id == status)
+ return p_entry->text;
+ p_entry++; /* next entry */
+ }
+ return "unknown error"; /* not found */
+}
-} GSCAN_ATTRIBUTE;
class GetRttCapabilitiesCommand : public WifiCommand
{
wifi_rtt_capabilities *mCapabilities;
@@ -86,7 +148,7 @@ protected:
int len = reply.get_vendor_data_len();
ALOGD("Id = %0x, subcmd = %d, len = %d, expected len = %d", id, subcmd, len,
- sizeof(*mCapabilities));
+ sizeof(*mCapabilities));
memcpy(mCapabilities, data, min(len, (int) sizeof(*mCapabilities)));
@@ -98,16 +160,24 @@ protected:
class RttCommand : public WifiCommand
{
unsigned numRttParams;
- static const int MAX_RESULTS = 64;
- wifi_rtt_result rttResults[MAX_RESULTS];
+ int mCompleted;
+ int currentIdx;
+ int totalCnt;
+ static const int MAX_RESULTS = 1024;
+ wifi_rtt_result *rttResults[MAX_RESULTS];
wifi_rtt_config *rttParams;
wifi_rtt_event_handler rttHandler;
public:
RttCommand(wifi_interface_handle iface, int id, unsigned num_rtt_config,
- wifi_rtt_config rtt_config[], wifi_rtt_event_handler handler)
+ wifi_rtt_config rtt_config[], wifi_rtt_event_handler handler)
: WifiCommand(iface, id), numRttParams(num_rtt_config), rttParams(rtt_config),
- rttHandler(handler)
- { }
+ rttHandler(handler)
+ {
+ memset(rttResults, 0, sizeof(rttResults));
+ currentIdx = 0;
+ mCompleted = 0;
+ totalCnt = 0;
+ }
int createSetupRequest(WifiRequest& request) {
@@ -123,7 +193,6 @@ public:
}
nlattr *rtt_config = request.attr_start(RTT_ATTRIBUTE_TARGET_INFO);
for (unsigned i = 0; i < numRttParams; i++) {
-
nlattr *attr2 = request.attr_start(i);
if (attr2 == NULL) {
return WIFI_ERROR_OUT_OF_MEMORY;
@@ -133,39 +202,72 @@ public:
if (result < 0) {
return result;
}
+
result = request.put_u8(RTT_ATTRIBUTE_TARGET_TYPE, rttParams[i].type);
if (result < 0) {
return result;
}
+
result = request.put_u8(RTT_ATTRIBUTE_TARGET_PEER, rttParams[i].peer);
if (result < 0) {
return result;
}
+
result = request.put(RTT_ATTRIBUTE_TARGET_CHAN, &rttParams[i].channel,
- sizeof(wifi_channel_info));
+ sizeof(wifi_channel_info));
if (result < 0) {
return result;
}
- result = request.put_u8(RTT_ATTRIBUTE_TARGET_MODE, rttParams[i].num_burst > 0 ? 1: 0 );
+
+ result = request.put_u32(RTT_ATTRIBUTE_TARGET_NUM_BURST, rttParams[i].num_burst);
if (result < 0) {
return result;
}
- result = request.put_u32(RTT_ATTRIBUTE_TARGET_INTERVAL, rttParams[i].interval);
+
+ result = request.put_u32(RTT_ATTRIBUTE_TARGET_NUM_FTM_BURST,
+ rttParams[i].num_frames_per_burst);
if (result < 0) {
return result;
}
- result = request.put_u32(RTT_ATTRIBUTE_TARGET_NUM_MEASUREMENT,
- rttParams[i].num_burst);
+
+ result = request.put_u32(RTT_ATTRIBUTE_TARGET_NUM_RETRY_FTM,
+ rttParams[i].num_retries_per_measurement_frame);
if (result < 0) {
return result;
}
- result = request.put_u32(RTT_ATTRIBUTE_TARGET_NUM_PKT,
- rttParams[i].num_frames_per_burst);
+
+ result = request.put_u32(RTT_ATTRIBUTE_TARGET_NUM_RETRY_FTMR,
+ rttParams[i].num_retries_per_ftmr);
if (result < 0) {
return result;
}
- result = request.put_u32(RTT_ATTRIBUTE_TARGET_NUM_RETRY,
- rttParams[i].num_retries_per_measurement_frame);
+
+ result = request.put_u32(RTT_ATTRIBUTE_TARGET_BURST_TIMEOUT,
+ rttParams[i].burst_timeout);
+ if (result < 0) {
+ return result;
+ }
+
+ result = request.put_u8(RTT_ATTRIBUTE_TARGET_LCI,
+ rttParams[i].LCI_request);
+ if (result < 0) {
+ return result;
+ }
+
+ result = request.put_u8(RTT_ATTRIBUTE_TARGET_LCR,
+ rttParams[i].LCR_request);
+ if (result < 0) {
+ return result;
+ }
+
+ result = request.put_u8(RTT_ATTRIBUTE_TARGET_BW,
+ rttParams[i].bw);
+ if (result < 0) {
+ return result;
+ }
+
+ result = request.put_u8(RTT_ATTRIBUTE_TARGET_PREAMBLE,
+ rttParams[i].preamble);
if (result < 0) {
return result;
}
@@ -257,27 +359,100 @@ public:
virtual int handleEvent(WifiEvent& event) {
ALOGI("Got an RTT event");
-
- // event.log();
-
nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA);
int len = event.get_vendor_data_len();
-
if (vendor_data == NULL || len == 0) {
ALOGI("No rtt results found");
}
+ for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
+ if (it.get_type() == RTT_ATTRIBUTE_RESULTS_COMPLETE) {
+ mCompleted = it.get_u32();
+ ALOGI("retrieved completed flag : %d\n", mCompleted);
+ } else if (it.get_type() == RTT_ATTRIBUTE_RESULTS_PER_TARGET) {
+ int result_cnt = 0;
+ mac_addr bssid;
+ for (nl_iterator it2(it.get()); it2.has_next(); it2.next()) {
+ if (it2.get_type() == RTT_ATTRIBUTE_TARGET_MAC) {
+ memcpy(bssid, it2.get_data(), sizeof(mac_addr));
+ ALOGI("retrived target mac : %02x:%02x:%02x:%02x:%02x:%02x\n",
+ bssid[0],
+ bssid[1],
+ bssid[2],
+ bssid[3],
+ bssid[4],
+ bssid[5]);
+ } else if (it2.get_type() == RTT_ATTRIBUTE_RESULT_CNT) {
+ result_cnt = it2.get_u32();
+ ALOGI("retrieved result_cnt : %d\n", result_cnt);
+ } else if (it2.get_type() == RTT_ATTRIBUTE_RESULT) {
+ int result_len = it2.get_len();
+ rttResults[currentIdx] = (wifi_rtt_result *)malloc(it2.get_len());
+ wifi_rtt_result *rtt_result = rttResults[currentIdx];
+ if (rtt_result == NULL) {
+ mCompleted = 1;
+ ALOGE("failed to allocate the wifi_rtt_result\n");
+ break;
+ }
+ memcpy(rtt_result, it2.get_data(), it2.get_len());
+ result_len -= sizeof(wifi_rtt_result);
+ if (result_len > 0) {
+ result_len -= sizeof(wifi_rtt_result);
+ dot11_rm_ie_t *ele_1;
+ dot11_rm_ie_t *ele_2;
+ /* The result has LCI or LCR element */
+ ele_1 = (dot11_rm_ie_t *)(rtt_result + 1);
+ if (ele_1->id == DOT11_MNG_MEASURE_REQUEST_ID) {
+ if (ele_1->type == DOT11_MEASURE_TYPE_LCI) {
+ rtt_result->LCI = (wifi_information_element *)ele_1;
+ result_len -= (ele_1->len + DOT11_HDR_LEN);
+ /* get a next rm ie */
+ if (result_len > 0) {
+ ele_2 = (dot11_rm_ie_t *)((char *)ele_1 + (ele_1->len + DOT11_HDR_LEN));
+ if ((ele_2->id == DOT11_MNG_MEASURE_REQUEST_ID) &&
+ (ele_2->type == DOT11_MEASURE_TYPE_CIVICLOC)) {
+ rtt_result->LCR = (wifi_information_element *)ele_2;
+ }
+ }
+ } else if (ele_1->type == DOT11_MEASURE_TYPE_CIVICLOC){
+ rtt_result->LCR = (wifi_information_element *)ele_1;
+ result_len -= (ele_1->len + DOT11_HDR_LEN);
+ /* get a next rm ie */
+ if (result_len > 0) {
+ ele_2 = (dot11_rm_ie_t *)((char *)ele_1 + (ele_1->len + DOT11_HDR_LEN));
+ if ((ele_2->id == DOT11_MNG_MEASURE_REQUEST_ID) &&
+ (ele_2->type == DOT11_MEASURE_TYPE_LCI)) {
+ rtt_result->LCI = (wifi_information_element *)ele_2;
+ }
+ }
+ }
+ }
+ }
+ totalCnt++;
+ ALOGI("retrived rtt_result : \n\tburst_num :%d, measurement_number : %d, success_number : %d\n"
+ "\tnumber_per_burst_peer : %d, status : %s, retry_after_duration : %d s\n"
+ "\trssi : %d dbm, rx_rate : %d Kbps, rtt : %llu ns, rtt_sd : %llu\n"
+ "\tdistance : %d, burst_duration : %d ms\n",
+ rtt_result->burst_num, rtt_result->measurement_number,
+ rtt_result->success_number, rtt_result->number_per_burst_peer,
+ get_err_info(rtt_result->status), rtt_result->retry_after_duration,
+ rtt_result->rssi, rtt_result->rx_rate.bitrate * 100,
+ rtt_result->rtt/10, rtt_result->rtt_sd, rtt_result->distance, rtt_result->burst_duration);
+ currentIdx++;
+ }
+ }
+ }
- unregisterVendorHandler(GOOGLE_OUI, RTT_EVENT_COMPLETE);
- wifi_unregister_cmd(wifiHandle(), id());
-
- memset(rttResults, 0, sizeof(wifi_rtt_result) * MAX_RESULTS);
-
- int num = len / sizeof(wifi_rtt_result);
- num = min(MAX_RESULTS, num);
- memcpy(rttResults, event.get_vendor_data(), num * sizeof(wifi_rtt_result));
- ALOGI("Retrieved %d rtt results", num);
-
- (*rttHandler.on_rtt_results)(id(), num, rttResults);
+ }
+ if (mCompleted) {
+ unregisterVendorHandler(GOOGLE_OUI, RTT_EVENT_COMPLETE);
+ wifi_unregister_cmd(wifiHandle(), id());
+ (*rttHandler.on_rtt_results)(id(), totalCnt, rttResults);
+ for (int i = 0; i < currentIdx; i++) {
+ free(rttResults[i]);
+ rttResults[i] = NULL;
+ }
+ totalCnt = currentIdx = 0;
+ }
return NL_SKIP;
}
};
@@ -316,5 +491,3 @@ wifi_error wifi_get_rtt_capabilities(wifi_interface_handle iface,
GetRttCapabilitiesCommand command(iface, capabilities);
return (wifi_error) command.requestResponse();
}
-
-