1 2 #include "CppUTest/TestHarness.h" 3 #include "CppUTest/CommandLineTestRunner.h" 4 5 #include "hal_flash_bank.h" 6 #include "hal_flash_bank_memory.h" 7 #include "btstack_tlv.h" 8 #include "btstack_tlv_flash_bank.h" 9 #include "hci_dump.h" 10 #include "hci_dump_posix_fs.h" 11 #include "classic/btstack_link_key_db.h" 12 #include "classic/btstack_link_key_db_tlv.h" 13 #include "btstack_util.h" 14 #include "btstack_config.h" 15 #include "btstack_debug.h" 16 17 #ifdef ENABLE_TLV_FLASH_EXPLICIT_DELETE_FIELD 18 // Provide additional bytes for 3 x delete fields (in both banks) 19 #define HAL_FLASH_BANK_MEMORY_STORAGE_SIZE (256 + 24) 20 #define TAG_OVERHEAD 16 21 #else 22 #define HAL_FLASH_BANK_MEMORY_STORAGE_SIZE (256) 23 #define TAG_OVERHEAD 8 24 #endif 25 #define HAL_FLASH_BANK_MEMORY_BANK_SIZE (HAL_FLASH_BANK_MEMORY_STORAGE_SIZE / 2) 26 27 28 29 static uint8_t hal_flash_bank_memory_storage[HAL_FLASH_BANK_MEMORY_STORAGE_SIZE]; 30 31 static void CHECK_EQUAL_ARRAY(uint8_t * expected, uint8_t * actual, int size){ 32 int i; 33 for (i=0; i<size; i++){ 34 if (expected[i] != actual[i]) { 35 printf("offset %u wrong\n", i); 36 printf("expected: "); printf_hexdump(expected, size); 37 printf("actual: "); printf_hexdump(actual, size); 38 } 39 BYTES_EQUAL(expected[i], actual[i]); 40 } 41 } 42 43 TEST_GROUP(HAL_FLASH_bank){ 44 const hal_flash_bank_t * hal_flash_bank_impl; 45 hal_flash_bank_memory_t hal_flash_bank_context; 46 void setup(void){ 47 hal_flash_bank_impl = hal_flash_bank_memory_init_instance(&hal_flash_bank_context, hal_flash_bank_memory_storage, HAL_FLASH_BANK_MEMORY_STORAGE_SIZE); 48 hal_flash_bank_impl->erase(&hal_flash_bank_context, 0); 49 hal_flash_bank_impl->erase(&hal_flash_bank_context, 1); 50 } 51 }; 52 53 TEST(HAL_FLASH_bank, TestErased){ 54 uint8_t buffer; 55 int offsets[] = { 0, 10, 100}; 56 int i; 57 for (i=0;i<sizeof(offsets)/sizeof(int);i++){ 58 int bank; 59 for (bank=0;bank<2;bank++){ 60 hal_flash_bank_impl->read(&hal_flash_bank_context, bank, offsets[i], &buffer, 1); 61 CHECK_EQUAL(buffer, 0xff); 62 } 63 } 64 } 65 66 TEST(HAL_FLASH_bank, TestWrite){ 67 uint8_t buffer; 68 int offsets[] = { 0, 10, 100}; 69 int i; 70 for (i=0;i<sizeof(offsets)/sizeof(int);i++){ 71 int bank; 72 for (bank=0;bank<2;bank++){ 73 buffer = i; 74 hal_flash_bank_impl->write(&hal_flash_bank_context, bank, offsets[i], &buffer, 1); 75 } 76 } 77 for (i=0;i<sizeof(offsets)/sizeof(int);i++){ 78 int bank; 79 for (bank=0;bank<2;bank++){ 80 hal_flash_bank_impl->read(&hal_flash_bank_context, bank, offsets[i], &buffer, 1); 81 CHECK_EQUAL(buffer, i); 82 } 83 } 84 } 85 86 #if 0 87 // prints error and exits tests. maybe all functions need to return ok 88 TEST(HAL_FLASH_bank, TestWriteTwice){ 89 uint8_t buffer = 5; 90 hal_flash_bank_impl->write(&hal_flash_bank_context, 0, 5, &buffer, 1); 91 hal_flash_bank_impl->write(&hal_flash_bank_context, 0, 5, &buffer, 1); 92 } 93 #endif 94 95 TEST(HAL_FLASH_bank, TestWriteErase){ 96 uint32_t offset = 7; 97 uint8_t value = 9; 98 uint8_t buffer = value; 99 hal_flash_bank_impl->write(&hal_flash_bank_context, 0, offset, &buffer, 1); 100 hal_flash_bank_impl->read(&hal_flash_bank_context, 0, offset, &buffer, 1); 101 CHECK_EQUAL(buffer, value); 102 hal_flash_bank_impl->erase(&hal_flash_bank_context, 0); 103 hal_flash_bank_impl->read(&hal_flash_bank_context, 0, offset, &buffer, 1); 104 CHECK_EQUAL(buffer, 0xff); 105 } 106 107 /// TLV 108 TEST_GROUP(BSTACK_TLV){ 109 110 const hal_flash_bank_t * hal_flash_bank_impl; 111 hal_flash_bank_memory_t hal_flash_bank_context; 112 113 const btstack_tlv_t * btstack_tlv_impl; 114 btstack_tlv_flash_bank_t btstack_tlv_context; 115 116 void setup(void){ 117 hal_flash_bank_impl = hal_flash_bank_memory_init_instance(&hal_flash_bank_context, hal_flash_bank_memory_storage, HAL_FLASH_BANK_MEMORY_STORAGE_SIZE); 118 hal_flash_bank_impl->erase(&hal_flash_bank_context, 0); 119 hal_flash_bank_impl->erase(&hal_flash_bank_context, 1); 120 } 121 }; 122 123 TEST(BSTACK_TLV, TestMissingTag){ 124 btstack_tlv_impl = btstack_tlv_flash_bank_init_instance(&btstack_tlv_context, hal_flash_bank_impl, &hal_flash_bank_context); 125 uint32_t tag = 'abcd'; 126 int size = btstack_tlv_impl->get_tag(&btstack_tlv_context, tag, NULL, 0); 127 CHECK_EQUAL(size, 0); 128 } 129 130 TEST(BSTACK_TLV, TestWriteRead){ 131 btstack_tlv_impl = btstack_tlv_flash_bank_init_instance(&btstack_tlv_context, hal_flash_bank_impl, &hal_flash_bank_context); 132 uint32_t tag = 'abcd'; 133 uint8_t data = 7; 134 uint8_t buffer = data; 135 btstack_tlv_impl->store_tag(&btstack_tlv_context, tag, &buffer, 1); 136 int size = btstack_tlv_impl->get_tag(&btstack_tlv_context, tag, NULL, 0); 137 CHECK_EQUAL(size, 1); 138 btstack_tlv_impl->get_tag(&btstack_tlv_context, tag, &buffer, 1); 139 CHECK_EQUAL(buffer, data); 140 } 141 142 TEST(BSTACK_TLV, TestWriteWriteRead){ 143 btstack_tlv_impl = btstack_tlv_flash_bank_init_instance(&btstack_tlv_context, hal_flash_bank_impl, &hal_flash_bank_context); 144 uint32_t tag = 'abcd'; 145 uint8_t data = 7; 146 uint8_t buffer = data; 147 btstack_tlv_impl->store_tag(&btstack_tlv_context, tag, &buffer, 1); 148 data++; 149 buffer = data; 150 btstack_tlv_impl->store_tag(&btstack_tlv_context, tag, &buffer, 1); 151 int size = btstack_tlv_impl->get_tag(&btstack_tlv_context, tag, NULL, 0); 152 CHECK_EQUAL(size, 1); 153 btstack_tlv_impl->get_tag(&btstack_tlv_context, tag, &buffer, 1); 154 CHECK_EQUAL(buffer, data); 155 } 156 157 TEST(BSTACK_TLV, TestWriteABARead){ 158 btstack_tlv_impl = btstack_tlv_flash_bank_init_instance(&btstack_tlv_context, hal_flash_bank_impl, &hal_flash_bank_context); 159 uint32_t tag_a = 'aaaa'; 160 uint32_t tag_b = 'bbbb'; 161 uint8_t data = 7; 162 uint8_t buffer = data; 163 btstack_tlv_impl->store_tag(&btstack_tlv_context, tag_a, &buffer, 1); 164 data++; 165 buffer = data; 166 btstack_tlv_impl->store_tag(&btstack_tlv_context, tag_b, &buffer, 1); 167 data++; 168 buffer = data; 169 btstack_tlv_impl->store_tag(&btstack_tlv_context, tag_a, &buffer, 1); 170 int size = btstack_tlv_impl->get_tag(&btstack_tlv_context, tag_a, NULL, 0); 171 CHECK_EQUAL(size, 1); 172 btstack_tlv_impl->get_tag(&btstack_tlv_context, tag_a, &buffer, 1); 173 CHECK_EQUAL(buffer, data); 174 } 175 176 TEST(BSTACK_TLV, TestWriteDeleteRead){ 177 btstack_tlv_impl = btstack_tlv_flash_bank_init_instance(&btstack_tlv_context, hal_flash_bank_impl, &hal_flash_bank_context); 178 uint32_t tag = 'abcd'; 179 uint8_t data = 7; 180 uint8_t buffer = data; 181 btstack_tlv_impl->store_tag(&btstack_tlv_context, tag, &buffer, 1); 182 data++; 183 buffer = data; 184 btstack_tlv_impl->store_tag(&btstack_tlv_context, tag, &buffer, 1); 185 btstack_tlv_impl->delete_tag(&btstack_tlv_context, tag); 186 int size = btstack_tlv_impl->get_tag(&btstack_tlv_context, tag, NULL, 0); 187 CHECK_EQUAL(size, 0); 188 } 189 190 TEST(BSTACK_TLV, TestMigrate){ 191 192 btstack_tlv_impl = btstack_tlv_flash_bank_init_instance(&btstack_tlv_context, hal_flash_bank_impl, &hal_flash_bank_context); 193 194 uint32_t tag = 'abcd'; 195 uint8_t data[8]; 196 memcpy(data, "01234567", 8); 197 198 // entry 8 + data 8 = 16. 199 int i; 200 for (i=0;i<8;i++){ 201 data[0] = '0' + i; 202 btstack_tlv_impl->store_tag(&btstack_tlv_context, tag, &data[0], 8); 203 } 204 205 btstack_tlv_impl = btstack_tlv_flash_bank_init_instance(&btstack_tlv_context, hal_flash_bank_impl, &hal_flash_bank_context); 206 207 uint8_t buffer[8]; 208 btstack_tlv_impl->get_tag(&btstack_tlv_context, tag, &buffer[0], 1); 209 CHECK_EQUAL(buffer[0], data[0]); 210 } 211 212 TEST(BSTACK_TLV, TestMigrate2){ 213 214 btstack_tlv_impl = btstack_tlv_flash_bank_init_instance(&btstack_tlv_context, hal_flash_bank_impl, &hal_flash_bank_context); 215 216 uint32_t tag1 = 0x11223344; 217 uint32_t tag2 = 0x44556677; 218 uint8_t data1[8]; 219 memcpy(data1, "01234567", 8); 220 uint8_t data2[8]; 221 memcpy(data2, "abcdefgh", 8); 222 223 // entry 8 + data 8 = 16. 224 int i; 225 for (i=0;i<8;i++){ 226 data1[0] = '0' + i; 227 data2[0] = 'a' + i; 228 btstack_tlv_impl->store_tag(&btstack_tlv_context, tag1, data1, 8); 229 btstack_tlv_impl->store_tag(&btstack_tlv_context, tag2, data2, 8); 230 } 231 232 btstack_tlv_impl = btstack_tlv_flash_bank_init_instance(&btstack_tlv_context, hal_flash_bank_impl, &hal_flash_bank_context); 233 234 uint8_t buffer[8]; 235 btstack_tlv_impl->get_tag(&btstack_tlv_context, tag1, &buffer[0], 1); 236 CHECK_EQUAL(buffer[0], data1[0]); 237 btstack_tlv_impl->get_tag(&btstack_tlv_context, tag2, &buffer[0], 1); 238 CHECK_EQUAL(buffer[0], data2[0]); 239 } 240 241 TEST(BSTACK_TLV, TestWriteResetRead){ 242 btstack_tlv_impl = btstack_tlv_flash_bank_init_instance(&btstack_tlv_context, hal_flash_bank_impl, &hal_flash_bank_context); 243 uint32_t tag = 'abcd'; 244 uint8_t data = 7; 245 uint8_t buffer = data; 246 btstack_tlv_impl->store_tag(&btstack_tlv_context, tag, &buffer, 1); 247 btstack_tlv_impl = btstack_tlv_flash_bank_init_instance(&btstack_tlv_context, hal_flash_bank_impl, &hal_flash_bank_context); 248 int size = btstack_tlv_impl->get_tag(&btstack_tlv_context, tag, NULL, 0); 249 CHECK_EQUAL(size, 1); 250 btstack_tlv_impl->get_tag(&btstack_tlv_context, tag, &buffer, 1); 251 CHECK_EQUAL(buffer, data); 252 } 253 254 TEST(BSTACK_TLV, TestFullBank){ 255 btstack_tlv_impl = btstack_tlv_flash_bank_init_instance(&btstack_tlv_context, hal_flash_bank_impl, &hal_flash_bank_context); 256 257 // fill-up flash bank 258 uint32_t tag = 'abcd'; 259 uint8_t blob[HAL_FLASH_BANK_MEMORY_BANK_SIZE - 8 - TAG_OVERHEAD]; 260 btstack_tlv_impl->store_tag(&btstack_tlv_context, tag, (uint8_t *) &blob, sizeof(blob)); 261 CHECK_EQUAL(0, btstack_tlv_context.current_bank); 262 CHECK_EQUAL(HAL_FLASH_BANK_MEMORY_BANK_SIZE, btstack_tlv_context.write_offset); 263 264 // check 265 btstack_tlv_impl = btstack_tlv_flash_bank_init_instance(&btstack_tlv_context, hal_flash_bank_impl, &hal_flash_bank_context); 266 CHECK_EQUAL(0, btstack_tlv_context.current_bank); 267 CHECK_EQUAL(HAL_FLASH_BANK_MEMORY_BANK_SIZE, btstack_tlv_context.write_offset); 268 } 269 270 TEST(BSTACK_TLV, TestAlmostFullBank){ 271 btstack_tlv_impl = btstack_tlv_flash_bank_init_instance(&btstack_tlv_context, hal_flash_bank_impl, &hal_flash_bank_context); 272 273 // fill-up flash bank without the last byte 274 uint32_t tag = 'abcd'; 275 uint8_t blob[HAL_FLASH_BANK_MEMORY_BANK_SIZE - 8 - TAG_OVERHEAD - 1]; 276 btstack_tlv_impl->store_tag(&btstack_tlv_context, tag, (uint8_t *) &blob, sizeof(blob)); 277 CHECK_EQUAL(0, btstack_tlv_context.current_bank); 278 CHECK_EQUAL(HAL_FLASH_BANK_MEMORY_BANK_SIZE-1, btstack_tlv_context.write_offset); 279 280 // check 281 btstack_tlv_impl = btstack_tlv_flash_bank_init_instance(&btstack_tlv_context, hal_flash_bank_impl, &hal_flash_bank_context); 282 CHECK_EQUAL(0, btstack_tlv_context.current_bank); 283 CHECK_EQUAL(HAL_FLASH_BANK_MEMORY_BANK_SIZE-1, btstack_tlv_context.write_offset); 284 } 285 286 TEST(BSTACK_TLV, TestFullBankPlusMigrate){ 287 btstack_tlv_impl = btstack_tlv_flash_bank_init_instance(&btstack_tlv_context, hal_flash_bank_impl, &hal_flash_bank_context); 288 289 // fill-up flash bank 290 uint32_t tag = 'abcd'; 291 uint8_t blob[((HAL_FLASH_BANK_MEMORY_BANK_SIZE - 8) / 2) - TAG_OVERHEAD]; 292 btstack_tlv_impl->store_tag(&btstack_tlv_context, tag, (uint8_t *) &blob, sizeof(blob)); 293 btstack_tlv_impl->store_tag(&btstack_tlv_context, tag, (uint8_t *) &blob, sizeof(blob)); 294 CHECK_EQUAL(0, btstack_tlv_context.current_bank); 295 CHECK_EQUAL(HAL_FLASH_BANK_MEMORY_BANK_SIZE, btstack_tlv_context.write_offset); 296 297 // check 298 btstack_tlv_impl = btstack_tlv_flash_bank_init_instance(&btstack_tlv_context, hal_flash_bank_impl, &hal_flash_bank_context); 299 CHECK_EQUAL(0, btstack_tlv_context.current_bank); 300 CHECK_EQUAL(HAL_FLASH_BANK_MEMORY_BANK_SIZE, btstack_tlv_context.write_offset); 301 302 // store one more -> trigger migration 303 btstack_tlv_impl->store_tag(&btstack_tlv_context, tag, (uint8_t *) &blob, sizeof(blob)); 304 CHECK_EQUAL(1, btstack_tlv_context.current_bank); 305 CHECK_EQUAL(8 + 2 * (TAG_OVERHEAD + sizeof(blob)), btstack_tlv_context.write_offset); 306 } 307 308 // 309 TEST_GROUP(LINK_KEY_DB){ 310 const hal_flash_bank_t * hal_flash_bank_impl; 311 hal_flash_bank_memory_t hal_flash_bank_context; 312 313 const btstack_tlv_t * btstack_tlv_impl; 314 btstack_tlv_flash_bank_t btstack_tlv_context; 315 316 const btstack_link_key_db_t * btstack_link_key_db; 317 318 bd_addr_t addr1, addr2, addr3; 319 link_key_t link_key1, link_key2; 320 link_key_type_t link_key_type; 321 322 void setup(void){ 323 // hal_flash_bank 324 hal_flash_bank_impl = hal_flash_bank_memory_init_instance(&hal_flash_bank_context, hal_flash_bank_memory_storage, HAL_FLASH_BANK_MEMORY_STORAGE_SIZE); 325 hal_flash_bank_impl->erase(&hal_flash_bank_context, 0); 326 hal_flash_bank_impl->erase(&hal_flash_bank_context, 1); 327 // btstack_tlv 328 btstack_tlv_impl = btstack_tlv_flash_bank_init_instance(&btstack_tlv_context, hal_flash_bank_impl, &hal_flash_bank_context); 329 // btstack_link_key_db 330 btstack_link_key_db = btstack_link_key_db_tlv_get_instance(btstack_tlv_impl, &btstack_tlv_context); 331 332 bd_addr_t addr_1 = {0x00, 0x01, 0x02, 0x03, 0x04, 0x01 }; 333 bd_addr_t addr_2 = {0x00, 0x01, 0x02, 0x03, 0x04, 0x02 }; 334 bd_addr_t addr_3 = {0x00, 0x01, 0x02, 0x03, 0x04, 0x03 }; 335 bd_addr_copy(addr1, addr_1); 336 bd_addr_copy(addr2, addr_2); 337 bd_addr_copy(addr3, addr_3); 338 for (int i=0;i<16;i++) { 339 link_key1[i] = 'a'+i; 340 link_key2[i] = 'A'+i; 341 } 342 link_key_type = COMBINATION_KEY; 343 } 344 }; 345 346 TEST(LINK_KEY_DB, SinglePutGetDeleteKey){ 347 348 link_key_t test_link_key; 349 link_key_type_t test_link_key_type; 350 351 btstack_link_key_db->delete_link_key(addr1); 352 CHECK(btstack_link_key_db->get_link_key(addr1, test_link_key, &test_link_key_type) == 0); 353 354 btstack_link_key_db->put_link_key(addr1, link_key1, link_key_type); 355 CHECK(btstack_link_key_db->get_link_key(addr1, test_link_key, &test_link_key_type) == 1); 356 CHECK_EQUAL_ARRAY(link_key1, test_link_key, 16); 357 358 btstack_link_key_db->delete_link_key(addr1); 359 CHECK(btstack_link_key_db->get_link_key(addr1, test_link_key, &test_link_key_type) == 0); 360 } 361 362 TEST(LINK_KEY_DB, UpdateKey){ 363 link_key_t test_link_key; 364 link_key_type_t test_link_key_type; 365 366 btstack_link_key_db->put_link_key(addr1, link_key1, link_key_type); 367 btstack_link_key_db->put_link_key(addr1, link_key2, link_key_type); 368 CHECK(btstack_link_key_db->get_link_key(addr1, test_link_key, &test_link_key_type) == 1); 369 CHECK_EQUAL_ARRAY(link_key2, test_link_key, 16); 370 } 371 372 TEST(LINK_KEY_DB, NumKeys){ 373 CHECK(NVM_NUM_LINK_KEYS == 2); 374 } 375 376 TEST(LINK_KEY_DB, KeyReplacement){ 377 link_key_t test_link_key; 378 link_key_type_t test_link_key_type; 379 380 btstack_link_key_db->put_link_key(addr1, link_key1, link_key_type); 381 btstack_link_key_db->put_link_key(addr2, link_key1, link_key_type); 382 btstack_link_key_db->put_link_key(addr3, link_key1, link_key_type); 383 384 CHECK(btstack_link_key_db->get_link_key(addr3, test_link_key, &test_link_key_type) == 1); 385 CHECK(btstack_link_key_db->get_link_key(addr2, test_link_key, &test_link_key_type) == 1); 386 CHECK(btstack_link_key_db->get_link_key(addr1, test_link_key, &test_link_key_type) == 0); 387 CHECK_EQUAL_ARRAY(link_key1, test_link_key, 16); 388 } 389 390 int main (int argc, const char * argv[]){ 391 // log into file using HCI_DUMP_PACKETLOGGER format 392 #ifdef ENABLE_TLV_FLASH_WRITE_ONCE 393 const char * pklg_path = "hci_dump_write_once.pklg"; 394 #else 395 const char * pklg_path = "hci_dump.pklg"; 396 #endif 397 hci_dump_posix_fs_open(pklg_path, HCI_DUMP_PACKETLOGGER); 398 hci_dump_init(hci_dump_posix_fs_get_instance()); 399 printf("Packet Log: %s\n", pklg_path); 400 401 return CommandLineTestRunner::RunAllTests(argc, argv); 402 } 403