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