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