Loading system/stack/btm/btm_ble_gap.cc +5 −2 Original line number Diff line number Diff line Loading @@ -2017,11 +2017,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)); Loading system/stack/include/advertise_data_parser.h +30 −0 Original line number Diff line number Diff line Loading @@ -44,6 +44,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. */ Loading system/stack/test/ad_parser_unittest.cc +21 −0 Original line number Diff line number Diff line Loading @@ -128,3 +128,24 @@ TEST(AdvertiseDataParserTest, GetFieldByType) { 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 Loading
system/stack/btm/btm_ble_gap.cc +5 −2 Original line number Diff line number Diff line Loading @@ -2017,11 +2017,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)); Loading
system/stack/include/advertise_data_parser.h +30 −0 Original line number Diff line number Diff line Loading @@ -44,6 +44,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. */ Loading
system/stack/test/ad_parser_unittest.cc +21 −0 Original line number Diff line number Diff line Loading @@ -128,3 +128,24 @@ TEST(AdvertiseDataParserTest, GetFieldByType) { 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