xref: /btstack/test/flash_tlv/tlv_test.cpp (revision 88cd67309cc94af545a96dac921d5ef21b3aa56e)
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