diff --git a/test/flash_tlv/btstack_tlv.h b/test/flash_tlv/btstack_tlv.h index 7132e16e4..bf551a663 100644 --- a/test/flash_tlv/btstack_tlv.h +++ b/test/flash_tlv/btstack_tlv.h @@ -46,33 +46,35 @@ extern "C" { #endif -/** - * Init Tag Length Value Store - */ -void btstack_tlv_init(const hal_flash_sector_t * hal_flash_sector_impl, void * hal_flash_sector_context); +typedef struct { -/** - * Get Value for Tag - * @param tag - * @param buffer - * @param buffer_size - * @returns size of value - */ -int btstack_tlv_get_tag(uint32_t tag, uint8_t * buffer, uint32_t buffer_size); + /** + * Get Value for Tag + * @param context + * @param tag + * @param buffer + * @param buffer_size + * @returns size of value + */ + int (*get_tag)(void * context, uint32_t tag, uint8_t * buffer, uint32_t buffer_size); -/** - * Store Tag - * @param tag - * @param data - * @param data_size - */ -void btstack_tlv_store_tag(uint32_t tag, const uint8_t * data, uint32_t data_size); + /** + * Store Tag + * @param context + * @param tag + * @param data + * @param data_size + */ + void (*store_tag)(void * context, uint32_t tag, const uint8_t * data, uint32_t data_size); -/** - * Delete Tag - * @param tag - */ -void btstack_tlv_delete_tag(uint32_t tag); + /** + * Delete Tag + * @param context + * @param tag + */ + void (*delete_tag)(void * context, uint32_t tag); + +} btstack_tlv_t; #if defined __cplusplus } diff --git a/test/flash_tlv/btstack_tlv_flash_sector.c b/test/flash_tlv/btstack_tlv_flash_sector.c index 439c9a329..b29b4c72f 100644 --- a/test/flash_tlv/btstack_tlv_flash_sector.c +++ b/test/flash_tlv/btstack_tlv_flash_sector.c @@ -29,6 +29,7 @@ * */ #include "btstack_tlv.h" +#include "btstack_tlv_flash_sector.h" #include "btstack_debug.h" #include "btstack_util.h" @@ -48,13 +49,6 @@ #define BTSTACK_TLV_HEADER_LEN 8 static const char * btstack_tlv_header_magic = "BTstack"; - -// globals -static int btstack_tlv_current_bank; -static int btstack_tlv_write_offset; -static const hal_flash_sector_t * hal_flash_sector_impl; -static void * hal_flash_sector_context; - // TLV Iterator typedef struct { @@ -64,37 +58,39 @@ typedef struct { uint32_t len; } tlv_iterator_t; -static void tlv_iterator_fetch_tag_len(tlv_iterator_t * it){ +static void btstack_tlv_flash_sector_iterator_fetch_tag_len(btstack_tlv_flash_sector_t * self, tlv_iterator_t * it){ uint8_t entry[8]; - hal_flash_sector_impl->read(hal_flash_sector_context, it->bank, it->offset, entry, 8); + self->hal_flash_sector_impl->read(self->hal_flash_sector_context, it->bank, it->offset, entry, 8); it->tag = big_endian_read_32(entry, 0); it->len = big_endian_read_32(entry, 4); } -static void tlv_iterator_init(tlv_iterator_t * it, int bank){ +static void btstack_tlv_flash_sector_iterator_init(btstack_tlv_flash_sector_t * self, tlv_iterator_t * it, int bank){ memset(it, 0, sizeof(tlv_iterator_t)); it->bank = bank; it->offset = BTSTACK_TLV_HEADER_LEN; - tlv_iterator_fetch_tag_len(it); + btstack_tlv_flash_sector_iterator_fetch_tag_len(self, it); } -static int tlv_iterator_has_next(tlv_iterator_t * it){ +static int btstack_tlv_flash_sector_iterator_has_next(btstack_tlv_flash_sector_t * self, tlv_iterator_t * it){ if (it->tag == 0xffffffff) return 0; - return it->offset + 8 + it->len < hal_flash_sector_impl->get_size(hal_flash_sector_context); + return it->offset + 8 + it->len < self->hal_flash_sector_impl->get_size(self->hal_flash_sector_context); } -static void tlv_iterator_fetch_next(tlv_iterator_t * it){ +static void btstack_tlv_flash_sector_iterator_fetch_next(btstack_tlv_flash_sector_t * self, tlv_iterator_t * it){ it->offset += 8 + it->len; - tlv_iterator_fetch_tag_len(it); + btstack_tlv_flash_sector_iterator_fetch_tag_len(self, it); } +// + // check both banks for headers and pick the one with the higher epoch % 4 // @returns bank or -1 if something is invalid -static int btstack_tlv_get_latest_bank(void){ +static int btstack_tlv_flash_sector_get_latest_bank(btstack_tlv_flash_sector_t * self){ uint8_t header0[BTSTACK_TLV_HEADER_LEN]; uint8_t header1[BTSTACK_TLV_HEADER_LEN]; - hal_flash_sector_impl->read(hal_flash_sector_context, 0, 0, &header0[0], BTSTACK_TLV_HEADER_LEN); - hal_flash_sector_impl->read(hal_flash_sector_context, 1, 0, &header1[0], BTSTACK_TLV_HEADER_LEN); + self->hal_flash_sector_impl->read(self->hal_flash_sector_context, 0, 0, &header0[0], BTSTACK_TLV_HEADER_LEN); + self->hal_flash_sector_impl->read(self->hal_flash_sector_context, 1, 0, &header1[0], BTSTACK_TLV_HEADER_LEN); int valid0 = memcmp(header1, btstack_tlv_header_magic, BTSTACK_TLV_HEADER_LEN-1) == 0; int valid1 = memcmp(header1, btstack_tlv_header_magic, BTSTACK_TLV_HEADER_LEN-1) == 0; if (!valid0 && !valid1) return -1; @@ -107,37 +103,38 @@ static int btstack_tlv_get_latest_bank(void){ return -1; // invalid, must not happen } -static void btstack_tlv_write_header(int bank, int epoch){ +static void btstack_tlv_flash_sector_write_header(btstack_tlv_flash_sector_t * self, int bank, int epoch){ uint8_t header[BTSTACK_TLV_HEADER_LEN]; memcpy(&header[0], btstack_tlv_header_magic, BTSTACK_TLV_HEADER_LEN-1); header[BTSTACK_TLV_HEADER_LEN-1] = epoch; - hal_flash_sector_impl->write(hal_flash_sector_context, bank, 0, header, BTSTACK_TLV_HEADER_LEN); + self->hal_flash_sector_impl->write(self->hal_flash_sector_context, bank, 0, header, BTSTACK_TLV_HEADER_LEN); } -static void btstack_tlv_migrate(void){ - int next_bank = 1 - btstack_tlv_current_bank; +static void btstack_tlv_flash_sector_migrate(btstack_tlv_flash_sector_t * self){ + + int next_bank = 1 - self->current_bank; // @TODO erase might not be needed - resp. already been performed - hal_flash_sector_impl->erase(hal_flash_sector_context, next_bank); + self->hal_flash_sector_impl->erase(self->hal_flash_sector_context, next_bank); int next_write_pos = 8; tlv_iterator_t it; - tlv_iterator_init(&it, btstack_tlv_current_bank); - while (tlv_iterator_has_next(&it)){ + btstack_tlv_flash_sector_iterator_init(self, &it, self->current_bank); + while (btstack_tlv_flash_sector_iterator_has_next(self, &it)){ // check if already exist in next bank int found = 0; tlv_iterator_t next_it; - tlv_iterator_init(&next_it, next_bank); - while (tlv_iterator_has_next(&next_it)){ + btstack_tlv_flash_sector_iterator_init(self, &next_it, next_bank); + while (btstack_tlv_flash_sector_iterator_has_next(self, &next_it)){ if (next_it.tag == it.tag){ found = 1; break; } - tlv_iterator_fetch_next(&next_it); + btstack_tlv_flash_sector_iterator_fetch_next(self, &next_it); } log_info("tag %x in next bank %u", it.tag, found); if (found) { - tlv_iterator_fetch_next(&it); + btstack_tlv_flash_sector_iterator_fetch_next(self, &it); continue; } @@ -145,13 +142,13 @@ static void btstack_tlv_migrate(void){ uint32_t tag_index = 0; uint32_t tag_len = 0; tlv_iterator_t scan_it; - tlv_iterator_init(&scan_it, btstack_tlv_current_bank); - while (tlv_iterator_has_next(&scan_it)){ + btstack_tlv_flash_sector_iterator_init(self, &scan_it, self->current_bank); + while (btstack_tlv_flash_sector_iterator_has_next(self, &scan_it)){ if (scan_it.tag == it.tag){ tag_index = scan_it.offset; tag_len = scan_it.len; } - tlv_iterator_fetch_next(&scan_it); + btstack_tlv_flash_sector_iterator_fetch_next(self, &scan_it); } // copy int bytes_to_copy = 8 + tag_len; @@ -159,53 +156,22 @@ static void btstack_tlv_migrate(void){ uint8_t copy_buffer[32]; while (bytes_to_copy){ int bytes_this_iteration = btstack_min(bytes_to_copy, sizeof(copy_buffer)); - hal_flash_sector_impl->read(hal_flash_sector_context, btstack_tlv_current_bank, tag_index, copy_buffer, bytes_this_iteration); - hal_flash_sector_impl->write(hal_flash_sector_context, next_bank, next_write_pos, copy_buffer, bytes_this_iteration); + self->hal_flash_sector_impl->read(self->hal_flash_sector_context, self->current_bank, tag_index, copy_buffer, bytes_this_iteration); + self->hal_flash_sector_impl->write(self->hal_flash_sector_context, next_bank, next_write_pos, copy_buffer, bytes_this_iteration); tag_index += bytes_this_iteration; next_write_pos += bytes_this_iteration; bytes_to_copy -= bytes_this_iteration; } - tlv_iterator_fetch_next(&it); + btstack_tlv_flash_sector_iterator_fetch_next(self, &it); } // prepare new one uint8_t epoch_buffer; - hal_flash_sector_impl->read(hal_flash_sector_context, btstack_tlv_current_bank, BTSTACK_TLV_HEADER_LEN-1, &epoch_buffer, 1); - btstack_tlv_write_header(next_bank, (epoch_buffer + 1) & 3); - btstack_tlv_current_bank = next_bank; - btstack_tlv_write_offset = next_write_pos; -} - -/** - * Init Tag Length Value Store - */ -void btstack_tlv_init(const hal_flash_sector_t * hal_flash_sector, void * context){ - - hal_flash_sector_impl = hal_flash_sector; - hal_flash_sector_context = context; - - // find current bank and erase both if none found - int current_bank = btstack_tlv_get_latest_bank(); - log_info("found bank %d", current_bank); - if (current_bank < 0){ - log_info("erase both banks"); - // erase both to get into stable state - hal_flash_sector_impl->erase(hal_flash_sector_context, 0); - hal_flash_sector_impl->erase(hal_flash_sector_context, 1); - current_bank = 0; - btstack_tlv_write_header(current_bank, 0); // epoch = 0; - } - btstack_tlv_current_bank = current_bank; - - // find write offset - tlv_iterator_t it; - tlv_iterator_init(&it, btstack_tlv_current_bank); - while (tlv_iterator_has_next(&it)){ - tlv_iterator_fetch_next(&it); - } - btstack_tlv_write_offset = it.offset; - log_info("write offset %u", btstack_tlv_write_offset); + self->hal_flash_sector_impl->read(self->hal_flash_sector_context, self->current_bank, BTSTACK_TLV_HEADER_LEN-1, &epoch_buffer, 1); + btstack_tlv_flash_sector_write_header(self, next_bank, (epoch_buffer + 1) & 3); + self->current_bank = next_bank; + self->write_offset = next_write_pos; } /** @@ -215,23 +181,26 @@ void btstack_tlv_init(const hal_flash_sector_t * hal_flash_sector, void * contex * @param buffer_size * @returns size of value */ -int btstack_tlv_get_tag(uint32_t tag, uint8_t * buffer, uint32_t buffer_size){ +static int btstack_tlv_flash_sector_get_tag(void * context, uint32_t tag, uint8_t * buffer, uint32_t buffer_size){ + + btstack_tlv_flash_sector_t * self = (btstack_tlv_flash_sector_t *) context; + uint32_t tag_index = 0; uint32_t tag_len = 0; tlv_iterator_t it; - tlv_iterator_init(&it, btstack_tlv_current_bank); - while (tlv_iterator_has_next(&it)){ + btstack_tlv_flash_sector_iterator_init(self, &it, self->current_bank); + while (btstack_tlv_flash_sector_iterator_has_next(self, &it)){ if (it.tag == tag){ log_info("Found tag '%x' at position %u", tag, it.offset); tag_index = it.offset; tag_len = it.len; } - tlv_iterator_fetch_next(&it); + btstack_tlv_flash_sector_iterator_fetch_next(self, &it); } if (tag_index == 0) return 0; if (!buffer) return tag_len; int copy_size = btstack_min(buffer_size, tag_len); - hal_flash_sector_impl->read(hal_flash_sector_context, btstack_tlv_current_bank, tag_index + 8, buffer, copy_size); + self->hal_flash_sector_impl->read(self->hal_flash_sector_context, self->current_bank, tag_index + 8, buffer, copy_size); return copy_size; } @@ -241,31 +210,73 @@ int btstack_tlv_get_tag(uint32_t tag, uint8_t * buffer, uint32_t buffer_size){ * @param data * @param data_size */ -void btstack_tlv_store_tag(uint32_t tag, const uint8_t * data, uint32_t data_size){ - if (btstack_tlv_write_offset + 8 + data_size > hal_flash_sector_impl->get_size(hal_flash_sector_context)){ - btstack_tlv_migrate(); +static void btstack_tlv_flash_sector_store_tag(void * context, uint32_t tag, const uint8_t * data, uint32_t data_size){ + + btstack_tlv_flash_sector_t * self = (btstack_tlv_flash_sector_t *) context; + + if (self->write_offset + 8 + data_size > self->hal_flash_sector_impl->get_size(self->hal_flash_sector_context)){ + btstack_tlv_flash_sector_migrate(self); } // prepare entry uint8_t entry[8]; big_endian_store_32(entry, 0, tag); big_endian_store_32(entry, 4, data_size); - log_info("write '%x', len %u at %u", tag, data_size, btstack_tlv_write_offset); + log_info("write '%x', len %u at %u", tag, data_size, self->write_offset); // write value first - hal_flash_sector_impl->write(hal_flash_sector_context, btstack_tlv_current_bank, btstack_tlv_write_offset + 8, data, data_size); + self->hal_flash_sector_impl->write(self->hal_flash_sector_context, self->current_bank, self->write_offset + 8, data, data_size); // then entry - hal_flash_sector_impl->write(hal_flash_sector_context, btstack_tlv_current_bank, btstack_tlv_write_offset, entry, sizeof(entry)); + self->hal_flash_sector_impl->write(self->hal_flash_sector_context, self->current_bank, self->write_offset, entry, sizeof(entry)); - btstack_tlv_write_offset += sizeof(entry) + data_size; + self->write_offset += sizeof(entry) + data_size; } /** * Delete Tag * @param tag */ -void btstack_tlv_delete_tag(uint32_t tag){ - btstack_tlv_store_tag(tag, NULL, 0); +static void btstack_tlv_flash_sector_delete_tag(void * context, uint32_t tag){ + btstack_tlv_flash_sector_store_tag(context, tag, NULL, 0); +} + +static const btstack_tlv_t btstack_tlv_flash_sector = { + /* int (*get_tag)(..); */ &btstack_tlv_flash_sector_get_tag, + /* void (*store_tag)(..); */ &btstack_tlv_flash_sector_store_tag, + /* void (*delete_tag)(v..); */ &btstack_tlv_flash_sector_delete_tag, +}; + +/** + * Init Tag Length Value Store + */ +const btstack_tlv_t * btstack_tlv_flash_sector_init_instance(btstack_tlv_flash_sector_t * self, const hal_flash_sector_t * hal_flash_sector_impl, void * hal_flash_sector_context){ + + self->hal_flash_sector_impl = hal_flash_sector_impl; + self->hal_flash_sector_context = hal_flash_sector_context; + + // find current bank and erase both if none found + int current_bank = btstack_tlv_flash_sector_get_latest_bank(self); + log_info("found bank %d", current_bank); + if (current_bank < 0){ + log_info("erase both banks"); + // erase both to get into stable state + hal_flash_sector_impl->erase(hal_flash_sector_context, 0); + hal_flash_sector_impl->erase(hal_flash_sector_context, 1); + current_bank = 0; + btstack_tlv_flash_sector_write_header(self, current_bank, 0); // epoch = 0; + } + self->current_bank = current_bank; + + // find write offset + tlv_iterator_t it; + btstack_tlv_flash_sector_iterator_init(self, &it, self->current_bank); + while (btstack_tlv_flash_sector_iterator_has_next(self, &it)){ + btstack_tlv_flash_sector_iterator_fetch_next(self, &it); + } + self->write_offset = it.offset; + log_info("write offset %u", self->write_offset); + + return &btstack_tlv_flash_sector; } diff --git a/test/flash_tlv/tlv_test.c b/test/flash_tlv/tlv_test.c index 7dae63f32..fa58064c8 100644 --- a/test/flash_tlv/tlv_test.c +++ b/test/flash_tlv/tlv_test.c @@ -5,6 +5,7 @@ #include "hal_flash_sector.h" #include "hal_flash_sector_memory.h" #include "btstack_tlv.h" +#include "btstack_tlv_flash_sector.h" #include "hci_dump.h" #define HAL_FLASH_SECTOR_MEMORY_STORAGE_SIZE 256 @@ -74,9 +75,16 @@ TEST(HAL_FLASH_SECTOR, TestWriteErase){ CHECK_EQUAL(buffer, 0xff); } +/// TLV + TEST_GROUP(BSTACK_TLV){ + const hal_flash_sector_t * hal_flash_sector_impl; - hal_flash_sector_memory_t hal_flash_sector_context; + hal_flash_sector_memory_t hal_flash_sector_context; + + const btstack_tlv_t * btstack_tlv_impl; + btstack_tlv_flash_sector_t btstack_tlv_context; + void setup(void){ hal_flash_sector_impl = hal_flash_sector_memory_init_instance(&hal_flash_sector_context, hal_flash_sector_memory_storage, HAL_FLASH_SECTOR_MEMORY_STORAGE_SIZE); hal_flash_sector_impl->erase(&hal_flash_sector_context, 0); @@ -85,56 +93,56 @@ TEST_GROUP(BSTACK_TLV){ }; TEST(BSTACK_TLV, TestMissingTag){ - btstack_tlv_init(hal_flash_sector_impl, &hal_flash_sector_context); + btstack_tlv_impl = btstack_tlv_flash_sector_init_instance(&btstack_tlv_context, hal_flash_sector_impl, &hal_flash_sector_context); uint32_t tag = 'abcd'; - int size = btstack_tlv_get_tag(tag, NULL, 0); + int size = btstack_tlv_impl->get_tag(&btstack_tlv_context, tag, NULL, 0); CHECK_EQUAL(size, 0); } TEST(BSTACK_TLV, TestWriteRead){ - btstack_tlv_init(hal_flash_sector_impl, &hal_flash_sector_context); + btstack_tlv_impl = btstack_tlv_flash_sector_init_instance(&btstack_tlv_context, hal_flash_sector_impl, &hal_flash_sector_context); uint32_t tag = 'abcd'; uint8_t data = 7; uint8_t buffer = data; - btstack_tlv_store_tag(tag, &buffer, 1); - int size = btstack_tlv_get_tag(tag, NULL, 0); + btstack_tlv_impl->store_tag(&btstack_tlv_context, tag, &buffer, 1); + int size = btstack_tlv_impl->get_tag(&btstack_tlv_context, tag, NULL, 0); CHECK_EQUAL(size, 1); - btstack_tlv_get_tag(tag, &buffer, 1); + btstack_tlv_impl->get_tag(&btstack_tlv_context, tag, &buffer, 1); CHECK_EQUAL(buffer, data); } TEST(BSTACK_TLV, TestWriteWriteRead){ - btstack_tlv_init(hal_flash_sector_impl, &hal_flash_sector_context); + btstack_tlv_impl = btstack_tlv_flash_sector_init_instance(&btstack_tlv_context, hal_flash_sector_impl, &hal_flash_sector_context); uint32_t tag = 'abcd'; uint8_t data = 7; uint8_t buffer = data; - btstack_tlv_store_tag(tag, &buffer, 1); + btstack_tlv_impl->store_tag(&btstack_tlv_context, tag, &buffer, 1); data++; buffer = data; - btstack_tlv_store_tag(tag, &buffer, 1); - int size = btstack_tlv_get_tag(tag, NULL, 0); + btstack_tlv_impl->store_tag(&btstack_tlv_context, tag, &buffer, 1); + int size = btstack_tlv_impl->get_tag(&btstack_tlv_context, tag, NULL, 0); CHECK_EQUAL(size, 1); - btstack_tlv_get_tag(tag, &buffer, 1); + btstack_tlv_impl->get_tag(&btstack_tlv_context, tag, &buffer, 1); CHECK_EQUAL(buffer, data); } TEST(BSTACK_TLV, TestWriteDeleteRead){ - btstack_tlv_init(hal_flash_sector_impl, &hal_flash_sector_context); + btstack_tlv_impl = btstack_tlv_flash_sector_init_instance(&btstack_tlv_context, hal_flash_sector_impl, &hal_flash_sector_context); uint32_t tag = 'abcd'; uint8_t data = 7; uint8_t buffer = data; - btstack_tlv_store_tag(tag, &buffer, 1); + btstack_tlv_impl->store_tag(&btstack_tlv_context, tag, &buffer, 1); data++; buffer = data; - btstack_tlv_store_tag(tag, &buffer, 1); - btstack_tlv_delete_tag(tag); - int size = btstack_tlv_get_tag(tag, NULL, 0); + btstack_tlv_impl->store_tag(&btstack_tlv_context, tag, &buffer, 1); + btstack_tlv_impl->delete_tag(&btstack_tlv_context, tag); + int size = btstack_tlv_impl->get_tag(&btstack_tlv_context, tag, NULL, 0); CHECK_EQUAL(size, 0); } TEST(BSTACK_TLV, TestMigrate){ - btstack_tlv_init(hal_flash_sector_impl, &hal_flash_sector_context); + btstack_tlv_impl = btstack_tlv_flash_sector_init_instance(&btstack_tlv_context, hal_flash_sector_impl, &hal_flash_sector_context); uint32_t tag = 'abcd'; uint8_t data[8]; @@ -144,19 +152,19 @@ TEST(BSTACK_TLV, TestMigrate){ int i; for (i=0;i<8;i++){ data[0] = '0' + i; - btstack_tlv_store_tag(tag, &data[0], 8); + btstack_tlv_impl->store_tag(&btstack_tlv_context, tag, &data[0], 8); } - btstack_tlv_init(hal_flash_sector_impl, &hal_flash_sector_context); + btstack_tlv_impl = btstack_tlv_flash_sector_init_instance(&btstack_tlv_context, hal_flash_sector_impl, &hal_flash_sector_context); uint8_t buffer[8]; - btstack_tlv_get_tag(tag, &buffer[0], 1); + btstack_tlv_impl->get_tag(&btstack_tlv_context, tag, &buffer[0], 1); CHECK_EQUAL(buffer[0], data[0]); } TEST(BSTACK_TLV, TestMigrate2){ - btstack_tlv_init(hal_flash_sector_impl, &hal_flash_sector_context); + btstack_tlv_impl = btstack_tlv_flash_sector_init_instance(&btstack_tlv_context, hal_flash_sector_impl, &hal_flash_sector_context); uint32_t tag1 = 0x11223344; uint32_t tag2 = 0x44556677; @@ -170,16 +178,16 @@ TEST(BSTACK_TLV, TestMigrate2){ for (i=0;i<8;i++){ data1[0] = '0' + i; data2[0] = 'a' + i; - btstack_tlv_store_tag(tag1, data1, 8); - btstack_tlv_store_tag(tag2, data2, 8); + btstack_tlv_impl->store_tag(&btstack_tlv_context, tag1, data1, 8); + btstack_tlv_impl->store_tag(&btstack_tlv_context, tag2, data2, 8); } - btstack_tlv_init(hal_flash_sector_impl, &hal_flash_sector_context); + btstack_tlv_impl = btstack_tlv_flash_sector_init_instance(&btstack_tlv_context, hal_flash_sector_impl, &hal_flash_sector_context); uint8_t buffer[8]; - btstack_tlv_get_tag(tag1, &buffer[0], 1); + btstack_tlv_impl->get_tag(&btstack_tlv_context, tag1, &buffer[0], 1); CHECK_EQUAL(buffer[0], data1[0]); - btstack_tlv_get_tag(tag2, &buffer[0], 1); + btstack_tlv_impl->get_tag(&btstack_tlv_context, tag2, &buffer[0], 1); CHECK_EQUAL(buffer[0], data2[0]); }