diff options
author | eccopark@broadcom.com <eccopark@broadcom.com> | 2015-03-13 20:10:23 -0700 |
---|---|---|
committer | eccopark@broadcom.com <eccopark@broadcom.com> | 2015-03-19 14:07:09 -0700 |
commit | 215b92f52a64b5f4b56589fcb7c788fc68b43aa5 (patch) | |
tree | 53a2553414877a9f936c8fdadcee715e7acd372f /bcmdhd/wifi_hal | |
parent | 97f03599b75a2b98720e4627efcc12fe764ed811 (diff) | |
download | hardware_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.mk | 2 | ||||
-rwxr-xr-x[-rw-r--r--] | bcmdhd/wifi_hal/rtt.cpp | 251 |
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(); } - - |