summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorandroid-build-team Robot <android-build-team-robot@google.com>2017-08-08 07:23:47 +0000
committerandroid-build-team Robot <android-build-team-robot@google.com>2017-08-08 07:23:47 +0000
commit72f7adb98ef69010077989b1d7fadc140cb525de (patch)
tree013e954e4eeb4bdb250ba23337caace3ba9fc4c4
parenta8f61332dad9499c7a081b809e9edb422f7b9f10 (diff)
parent436058ee3f52419fde558068a77222a67153e40d (diff)
downloadandroid_system_bt-72f7adb98ef69010077989b1d7fadc140cb525de.tar.gz
android_system_bt-72f7adb98ef69010077989b1d7fadc140cb525de.tar.bz2
android_system_bt-72f7adb98ef69010077989b1d7fadc140cb525de.zip
release-request-ef177764-b092-4138-885c-f9ecf5a80dc4-for-git_oc-dr1-release-4253863 snap-temp-L73600000090287988
Change-Id: I39de6f3a1039f5288efd4988815fff042c21907f
-rw-r--r--bta/dm/bta_dm_pm.cc20
-rw-r--r--stack/btm/btm_ble_gap.cc7
-rw-r--r--stack/include/advertise_data_parser.h30
-rw-r--r--stack/test/ad_parser_unittest.cc21
4 files changed, 68 insertions, 10 deletions
diff --git a/bta/dm/bta_dm_pm.cc b/bta/dm/bta_dm_pm.cc
index 89cf80dfd..472b7e1c8 100644
--- a/bta/dm/bta_dm_pm.cc
+++ b/bta/dm/bta_dm_pm.cc
@@ -65,7 +65,8 @@ static void bta_dm_pm_ssr(BD_ADDR peer_addr);
#endif
tBTA_DM_CONNECTED_SRVCS bta_dm_conn_srvcs;
-static std::recursive_mutex pm_timer_mutex;
+static std::recursive_mutex pm_timer_schedule_mutex;
+static std::recursive_mutex pm_timer_state_mutex;
/*******************************************************************************
*
@@ -270,7 +271,8 @@ static void bta_dm_pm_stop_timer_by_srvc_id(BD_ADDR peer_addr,
static void bta_dm_pm_start_timer(tBTA_PM_TIMER* p_timer, uint8_t timer_idx,
period_ms_t timeout_ms, uint8_t srvc_id,
uint8_t pm_action) {
- std::unique_lock<std::recursive_mutex> lock(pm_timer_mutex);
+ std::unique_lock<std::recursive_mutex> schedule_lock(pm_timer_schedule_mutex);
+ std::unique_lock<std::recursive_mutex> state_lock(pm_timer_state_mutex);
p_timer->in_use = true;
if (p_timer->srvc_id[timer_idx] == BTA_ID_MAX) p_timer->active++;
@@ -279,7 +281,7 @@ static void bta_dm_pm_start_timer(tBTA_PM_TIMER* p_timer, uint8_t timer_idx,
p_timer->pm_action[timer_idx] = pm_action;
p_timer->srvc_id[timer_idx] = srvc_id;
- lock.unlock();
+ state_lock.unlock();
alarm_set_on_queue(p_timer->timer[timer_idx], timeout_ms,
bta_dm_pm_timer_cback, p_timer->timer[timer_idx],
@@ -300,19 +302,21 @@ static void bta_dm_pm_stop_timer_by_index(tBTA_PM_TIMER* p_timer,
uint8_t timer_idx) {
if ((p_timer == NULL) || (timer_idx >= BTA_DM_PM_MODE_TIMER_MAX)) return;
+ std::unique_lock<std::recursive_mutex> schedule_lock(pm_timer_schedule_mutex);
+ std::unique_lock<std::recursive_mutex> state_lock(pm_timer_state_mutex);
if (p_timer->srvc_id[timer_idx] == BTA_ID_MAX)
return; /* The timer was not scheduled */
CHECK(p_timer->in_use && (p_timer->active > 0));
- alarm_cancel(p_timer->timer[timer_idx]);
-
- std::lock_guard<std::recursive_mutex> lock(pm_timer_mutex);
p_timer->srvc_id[timer_idx] = BTA_ID_MAX;
/* NOTE: pm_action[timer_idx] intentionally not reset */
p_timer->active--;
if (p_timer->active == 0) p_timer->in_use = false;
+ state_lock.unlock();
+
+ alarm_cancel(p_timer->timer[timer_idx]);
}
/*******************************************************************************
@@ -878,7 +882,7 @@ static void bta_dm_pm_timer_cback(void* data) {
uint8_t i, j;
alarm_t* alarm = (alarm_t*)data;
- std::unique_lock<std::recursive_mutex> lock(pm_timer_mutex);
+ std::unique_lock<std::recursive_mutex> state_lock(pm_timer_state_mutex);
for (i = 0; i < BTA_DM_NUM_PM_TIMER; i++) {
APPL_TRACE_DEBUG("dm_pm_timer[%d] in use? %d", i,
bta_dm_cb.pm_timer[i].in_use);
@@ -896,7 +900,7 @@ static void bta_dm_pm_timer_cback(void* data) {
if (j < BTA_DM_PM_MODE_TIMER_MAX) break;
}
}
- lock.unlock();
+ state_lock.unlock();
/* no more timers */
if (i == BTA_DM_NUM_PM_TIMER) return;
diff --git a/stack/btm/btm_ble_gap.cc b/stack/btm/btm_ble_gap.cc
index be12e6117..fe093e2bd 100644
--- a/stack/btm/btm_ble_gap.cc
+++ b/stack/btm/btm_ble_gap.cc
@@ -2103,11 +2103,14 @@ static void btm_ble_process_adv_pkt_cont(
bool is_scannable = ble_evt_type_is_scannable(evt_type);
bool is_scan_resp = ble_evt_type_is_scan_resp(evt_type);
+ bool is_start =
+ ble_evt_type_is_legacy(evt_type) && is_scannable && !is_scan_resp;
+
+ if (is_start) AdvertiseDataParser::RemoveTrailingZeros(tmp);
+
// We might have send scan request to this device before, but didn't get the
// response. In such case make sure data is put at start, not appended to
// already existing data.
- bool is_start =
- ble_evt_type_is_legacy(evt_type) && is_scannable && !is_scan_resp;
std::vector<uint8_t> const& adv_data =
is_start ? cache.Set(addr_type, bda, std::move(tmp))
: cache.Append(addr_type, bda, std::move(tmp));
diff --git a/stack/include/advertise_data_parser.h b/stack/include/advertise_data_parser.h
index 1c5f99f8f..0efac4f57 100644
--- a/stack/include/advertise_data_parser.h
+++ b/stack/include/advertise_data_parser.h
@@ -22,6 +22,36 @@
class AdvertiseDataParser {
public:
+ static void RemoveTrailingZeros(std::vector<uint8_t>& ad) {
+ size_t position = 0;
+
+ size_t ad_len = ad.size();
+ while (position != ad_len) {
+ uint8_t len = ad[position];
+
+ // A field length of 0 would be invalid as it should at least contain the
+ // EIR field type. However, some existing devices send zero padding at the
+ // end of advertisement. If this is the case, cut the zero padding from
+ // end of the packet. Otherwise i.e. gluing scan response to advertise
+ // data will result in data with zero padding in the middle.
+ if (len == 0) {
+ size_t zeros_start = position;
+ for (size_t i = position + 1; i < ad_len; i++) {
+ if (ad[i] != 0) return;
+ }
+
+ ad.erase(ad.begin() + zeros_start, ad.end());
+ return;
+ }
+
+ if (position + len >= ad_len) {
+ return;
+ }
+
+ position += len + 1;
+ }
+ }
+
/**
* Return true if this |ad| represent properly formatted advertising data.
*/
diff --git a/stack/test/ad_parser_unittest.cc b/stack/test/ad_parser_unittest.cc
index 3202130a3..ab6df5606 100644
--- a/stack/test/ad_parser_unittest.cc
+++ b/stack/test/ad_parser_unittest.cc
@@ -100,4 +100,25 @@ TEST(AdvertiseDataParserTest, GetFieldByType) {
data = AdvertiseDataParser::GetFieldByType(data1, 0x03, &p_length);
EXPECT_EQ(nullptr, data);
EXPECT_EQ(0, p_length);
+}
+
+// This test makes sure that RemoveTrailingZeros is working correctly. It does
+// run the RemoveTrailingZeros for ad data, then glue scan response at end of
+// it, and checks that the resulting data is good.
+TEST(AdvertiseDataParserTest, RemoveTrailingZeros) {
+ std::vector<uint8_t> podo_ad_data{
+ 0x02, 0x01, 0x02, 0x11, 0x06, 0x66, 0x9a, 0x0c, 0x20, 0x00, 0x08,
+ 0x37, 0xa8, 0xe5, 0x11, 0x81, 0x8b, 0xd0, 0xf0, 0xf0, 0xf0, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+ const std::vector<uint8_t> podo_scan_resp{
+ 0x03, 0x19, 0x00, 0x80, 0x09, 0x09, 0x50, 0x6f, 0x64, 0x6f, 0x51,
+ 0x35, 0x56, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+ AdvertiseDataParser::RemoveTrailingZeros(podo_ad_data);
+
+ std::vector<uint8_t> glued(podo_ad_data);
+ glued.insert(glued.end(), podo_ad_data.begin(), podo_ad_data.end());
+
+ EXPECT_TRUE(AdvertiseDataParser::IsValid(glued));
} \ No newline at end of file