1 #include "CppUTest/TestHarness.h"
2 #include "CppUTest/CommandLineTestRunner.h"
3
4 #include "btstack_debug.h"
5 #include "btstack_util.h"
6
TEST_GROUP(BTstackUtil)7 TEST_GROUP(BTstackUtil){
8 void setup(void){
9 }
10 void teardown(void){
11 }
12 };
13
TEST(BTstackUtil,btstack_next_cid_ignoring_zero)14 TEST(BTstackUtil, btstack_next_cid_ignoring_zero){
15 CHECK_EQUAL(1, btstack_next_cid_ignoring_zero(0));
16 CHECK_EQUAL(5, btstack_next_cid_ignoring_zero(4));
17 CHECK_EQUAL(1, btstack_next_cid_ignoring_zero(0xFFFF));
18 }
19
TEST(BTstackUtil,bd_addr_cmp)20 TEST(BTstackUtil, bd_addr_cmp){
21 bd_addr_t a = {0};
22 bd_addr_t b = {0};
23 CHECK_EQUAL(0, bd_addr_cmp(a, b));
24
25 bd_addr_t a1 = {0xBC, 0xEC, 0x5D, 0xE6, 0x15, 0x03};
26 bd_addr_t b1 = {0xBC, 0xEC, 0x5D, 0xE6, 0x15, 0x03};
27 CHECK_EQUAL(0, bd_addr_cmp(a1, b1));
28 }
29
TEST(BTstackUtil,bd_addr_copy)30 TEST(BTstackUtil, bd_addr_copy){
31 bd_addr_t a = {0xBC, 0xEC, 0x5D, 0xE6, 0x15, 0x03};
32 bd_addr_t b = {0};
33 CHECK(0 != bd_addr_cmp(a, b));
34
35 bd_addr_copy(a,b);
36 CHECK_EQUAL(0, bd_addr_cmp(a, b));
37 }
38
TEST(BTstackUtil,little_endian_read)39 TEST(BTstackUtil, little_endian_read){
40 const uint8_t buffer[] = {0xBC, 0xEC, 0x5D, 0xE6, 0x15, 0x03};
41 uint32_t value;
42
43 value = little_endian_read_16(buffer, 0);
44 CHECK_EQUAL(0xECBC, value);
45
46 value = little_endian_read_24(buffer, 0);
47 CHECK_EQUAL(0x5DECBC, value);
48
49 value = little_endian_read_32(buffer, 0);
50 CHECK_EQUAL(0xE65DECBC, value);
51 }
52
TEST(BTstackUtil,little_endian_store)53 TEST(BTstackUtil, little_endian_store){
54 uint8_t buffer[6];
55 uint32_t expected_value = 0xE65DECBC;
56 uint32_t value;
57
58 memset(buffer, 0, sizeof(buffer));
59 little_endian_store_16(buffer, 0, expected_value);
60 value = little_endian_read_16(buffer, 0);
61 CHECK_EQUAL(0xECBC, value);
62
63 memset(buffer, 0, sizeof(buffer));
64 little_endian_store_24(buffer, 0, expected_value);
65 value = little_endian_read_24(buffer, 0);
66 CHECK_EQUAL(0x5DECBC, value);
67
68 memset(buffer, 0, sizeof(buffer));
69 little_endian_store_32(buffer, 0, expected_value);
70 value = little_endian_read_32(buffer, 0);
71 CHECK_EQUAL(0xE65DECBC, value);
72 }
73
TEST(BTstackUtil,big_endian_read)74 TEST(BTstackUtil, big_endian_read){
75 const uint8_t buffer[] = {0xBC, 0xEC, 0x5D, 0xE6, 0x15, 0x03};
76 uint32_t value;
77
78 value = big_endian_read_16(buffer, 0);
79 CHECK_EQUAL(0xBCEC, value);
80
81 value = big_endian_read_24(buffer, 0);
82 CHECK_EQUAL(0xBCEC5D, value);
83
84 value = big_endian_read_32(buffer, 0);
85 CHECK_EQUAL(0xBCEC5DE6, value);
86 }
87
TEST(BTstackUtil,big_endian_store)88 TEST(BTstackUtil, big_endian_store){
89 uint8_t buffer[6];
90 uint32_t expected_value = 0xE65DECBC;
91 uint32_t value;
92
93 memset(buffer, 0, sizeof(buffer));
94 big_endian_store_16(buffer, 0, expected_value);
95 value = big_endian_read_16(buffer, 0);
96 CHECK_EQUAL(0xECBC, value);
97
98 memset(buffer, 0, sizeof(buffer));
99 big_endian_store_24(buffer, 0, expected_value);
100 value = big_endian_read_24(buffer, 0);
101 CHECK_EQUAL(0x5DECBC, value);
102
103 memset(buffer, 0, sizeof(buffer));
104 big_endian_store_32(buffer, 0, expected_value);
105 value = big_endian_read_32(buffer, 0);
106 CHECK_EQUAL(0xE65DECBC, value);
107 }
108
TEST(BTstackUtil,reverse_bytes)109 TEST(BTstackUtil, reverse_bytes){
110 uint8_t src[32];
111 uint8_t buffer[32];
112 uint32_t value;
113
114 int i;
115 for (i = 0; i < sizeof(src); i++){
116 src[i] = i + 1;
117 }
118
119 memset(buffer, 0, sizeof(buffer));
120 reverse_bytes(src, buffer, sizeof(buffer));
121 value = big_endian_read_32(buffer, 0);
122 CHECK_EQUAL(0x201F1E1D, value);
123
124 memset(buffer, 0, sizeof(buffer));
125 reverse_24(src, buffer);
126 value = big_endian_read_32(buffer, 0);
127 CHECK_EQUAL(0x03020100, value);
128
129 memset(buffer, 0, sizeof(buffer));
130 reverse_48(src, buffer);
131 value = big_endian_read_32(buffer, 0);
132 CHECK_EQUAL(0x06050403, value);
133
134 memset(buffer, 0, sizeof(buffer));
135 reverse_56(src, buffer);
136 value = big_endian_read_32(buffer, 0);
137 CHECK_EQUAL(0x07060504, value);
138
139 memset(buffer, 0, sizeof(buffer));
140 reverse_64(src, buffer);
141 value = big_endian_read_32(buffer, 0);
142 CHECK_EQUAL(0x08070605, value);
143
144 memset(buffer, 0, sizeof(buffer));
145 reverse_128(src, buffer);
146 value = big_endian_read_32(buffer, 0);
147 CHECK_EQUAL(0x100F0E0D, value);
148
149 memset(buffer, 0, sizeof(buffer));
150 reverse_256(src, buffer);
151 value = big_endian_read_32(buffer, 0);
152 CHECK_EQUAL(0x201F1E1D, value);
153 }
154
TEST(BTstackUtil,reverse_bd_addr)155 TEST(BTstackUtil, reverse_bd_addr){
156 bd_addr_t src = {0xBC, 0xEC, 0x5D, 0xE6, 0x15, 0x03};
157 bd_addr_t dest = {0};
158 reverse_bd_addr(src, dest);
159
160 uint32_t value = big_endian_read_32(dest, 0);
161 CHECK_EQUAL(0x0315E65D, value);
162 }
163
TEST(BTstackUtil,btstack_min_max)164 TEST(BTstackUtil, btstack_min_max){
165 uint32_t a = 30;
166 uint32_t b = 100;
167
168 CHECK_EQUAL(a, btstack_min(a,b));
169 CHECK_EQUAL(a, btstack_min(b,a));
170
171 CHECK_EQUAL(b, btstack_max(a,b));
172 CHECK_EQUAL(b, btstack_max(b,a));
173 }
174
TEST(BTstackUtil,char_for_nibble)175 TEST(BTstackUtil, char_for_nibble){
176 CHECK_EQUAL('A', char_for_nibble(10));
177 CHECK_EQUAL('?', char_for_nibble(20));
178 // CHECK_EQUAL('?', char_for_nibble(-5));
179 }
180
TEST(BTstackUtil,nibble_for_char)181 TEST(BTstackUtil, nibble_for_char){
182 CHECK_EQUAL(0, nibble_for_char('0'));
183 CHECK_EQUAL(5, nibble_for_char('5'));
184 CHECK_EQUAL(9, nibble_for_char('9'));
185
186 CHECK_EQUAL(10, nibble_for_char('a'));
187 CHECK_EQUAL(12, nibble_for_char('c'));
188 CHECK_EQUAL(15, nibble_for_char('f'));
189
190 CHECK_EQUAL(10, nibble_for_char('A'));
191 CHECK_EQUAL(12, nibble_for_char('C'));
192 CHECK_EQUAL(15, nibble_for_char('F'));
193
194 CHECK_EQUAL(-1, nibble_for_char('-'));
195 }
196
TEST(BTstackUtil,logging)197 TEST(BTstackUtil, logging){
198 uint8_t data[6 * 16 + 5] = {0x54, 0x65, 0x73, 0x74, 0x20, 0x6c, 0x6f, 0x67, 0x20, 0x69, 0x6e, 0x66, 0x6f};
199 #ifdef ENABLE_LOG_DEBUG
200 log_debug_hexdump(data, sizeof(data));
201 #endif
202
203 #ifdef ENABLE_LOG_INFO
204 log_info_hexdump(data, sizeof(data));
205 sm_key_t key = {0x54, 0x65, 0x73, 0x74, 0x20, 0x6c, 0x6f, 0x67, 0x20, 0x69, 0x6e, 0x66, 0x6f, 0x01, 0x014, 0xFF};
206 log_info_key("test key", key);
207 #endif
208 }
209
TEST(BTstackUtil,uuids)210 TEST(BTstackUtil, uuids){
211 uint32_t shortUUID = 0x44445555;
212 uint8_t uuid[16];
213 uint8_t uuid128[] = {0x44, 0x44, 0x55, 0x55, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB};
214
215 memset(uuid, 0, sizeof(uuid));
216 uuid_add_bluetooth_prefix(uuid, shortUUID);
217 MEMCMP_EQUAL(uuid128, uuid, sizeof(uuid));
218
219 CHECK_EQUAL(1, uuid_has_bluetooth_prefix(uuid128));
220
221 uuid128[5] = 0xff;
222 CHECK(1 != uuid_has_bluetooth_prefix(uuid128));
223
224 char * uuid128_str = uuid128_to_str(uuid128);
225 STRCMP_EQUAL("44445555-00FF-1000-8000-00805F9B34FB", uuid128_str);
226 }
227
TEST(BTstackUtil,bd_addr_utils)228 TEST(BTstackUtil, bd_addr_utils){
229 const bd_addr_t addr = {0xBC, 0xEC, 0x5D, 0xE6, 0x15, 0x03};
230 char * device_addr_string = (char *)"BC:EC:5D:E6:15:03";
231
232 char * addr_str = bd_addr_to_str(addr);
233 STRCMP_EQUAL(device_addr_string, addr_str);
234
235 uint8_t device_name[50];
236 strcpy((char *)device_name, "Device name 00:00:00:00:00:00");
237 btstack_replace_bd_addr_placeholder(device_name, strlen((const char*) device_name), addr);
238 STRCMP_EQUAL("Device name BC:EC:5D:E6:15:03", (const char *) device_name);
239
240 bd_addr_t device_addr;
241 CHECK_EQUAL(1, sscanf_bd_addr(device_addr_string, device_addr));
242 MEMCMP_EQUAL(addr, device_addr, sizeof(addr));
243
244 CHECK_EQUAL(1, sscanf_bd_addr("BC EC 5D E6 15 03", device_addr));
245 CHECK_EQUAL(1, sscanf_bd_addr("BC-EC-5D-E6-15-03", device_addr));
246
247 CHECK_EQUAL(0, sscanf_bd_addr("", device_addr));
248 CHECK_EQUAL(0, sscanf_bd_addr("GG-EC-5D-E6-15-03", device_addr));
249 CHECK_EQUAL(0, sscanf_bd_addr("8G-EC-5D-E6-15-03", device_addr));
250 CHECK_EQUAL(0, sscanf_bd_addr("BCxECx5DxE6:15:03", device_addr));
251
252 }
253
TEST(BTstackUtil,atoi)254 TEST(BTstackUtil, atoi){
255 CHECK_EQUAL(102, btstack_atoi("102"));
256 CHECK_EQUAL(0, btstack_atoi("-102"));
257 CHECK_EQUAL(1, btstack_atoi("1st"));
258 CHECK_EQUAL(1, btstack_atoi("1st2"));
259 }
260
TEST(BTstackUtil,string_len_for_uint32)261 TEST(BTstackUtil, string_len_for_uint32){
262 CHECK_EQUAL(1, string_len_for_uint32(9));
263 CHECK_EQUAL(2, string_len_for_uint32(19));
264 CHECK_EQUAL(3, string_len_for_uint32(109));
265 CHECK_EQUAL(4, string_len_for_uint32(1009));
266 CHECK_EQUAL(5, string_len_for_uint32(10009));
267 CHECK_EQUAL(6, string_len_for_uint32(100009));
268 CHECK_EQUAL(7, string_len_for_uint32(1000009));
269 CHECK_EQUAL(8, string_len_for_uint32(10000009));
270 CHECK_EQUAL(9, string_len_for_uint32(100000009));
271 CHECK_EQUAL(10, string_len_for_uint32(1000000000));
272 }
273
TEST(BTstackUtil,count_set_bits_uint32)274 TEST(BTstackUtil, count_set_bits_uint32){
275 CHECK_EQUAL(4, count_set_bits_uint32(0x0F));
276 }
277
TEST(BTstackUtil,crc8)278 TEST(BTstackUtil, crc8){
279 uint8_t data[] = {1,2,3,4,5,6,7,8,9};
280 CHECK_EQUAL(84, btstack_crc8_calc(data, sizeof(data)));
281
282 CHECK_EQUAL(0, btstack_crc8_check(data, sizeof(data), 84));
283 CHECK_EQUAL(1, btstack_crc8_check(data, sizeof(data), 74));
284 }
285
TEST(BTstackUtil,strcat)286 TEST(BTstackUtil, strcat){
287 char summaries[3][7 * 8 + 1];
288 CHECK_EQUAL((7*8+1), sizeof(summaries[0]));
289 summaries[0][0] = 0;
290 char item_text[10];
291 sprintf(item_text, "%04x:%02d ", 1 ,2);
292 btstack_strcat(summaries[0], sizeof(summaries[0]), item_text);
293 sprintf(item_text, "%04x:%02d ", 3 ,4);
294 btstack_strcat(summaries[0], sizeof(summaries[0]), item_text);
295 STRCMP_EQUAL("0001:02 0003:04 ", summaries[0]);
296 }
297
TEST(BTstackUtil,btstack_is_null)298 TEST(BTstackUtil, btstack_is_null){
299 CHECK_EQUAL(btstack_is_null(NULL, 0), true);
300
301 const uint8_t addr[] = {0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa};
302 CHECK_EQUAL(btstack_is_null(addr, sizeof(addr)), false);
303
304 const uint8_t null_addr[] = {0,0,0,0,0,0};
305 CHECK_EQUAL(btstack_is_null(null_addr, sizeof(null_addr)), true);
306
307 }
308
TEST(BTstackUtil,btstack_is_null_bd_addr)309 TEST(BTstackUtil, btstack_is_null_bd_addr){
310 const bd_addr_t addr = {0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa};
311 CHECK_EQUAL(btstack_is_null_bd_addr(addr), false);
312
313 const bd_addr_t null_addr = {0,0,0,0,0,0};
314 CHECK_EQUAL(btstack_is_null_bd_addr(null_addr), true);
315 }
316
TEST(BTstackUtil,btstack_time16_delta)317 TEST(BTstackUtil, btstack_time16_delta){
318 CHECK_EQUAL(btstack_time16_delta(25, 26), -1);
319 }
320
TEST(BTstackUtil,btstack_strcpy)321 TEST(BTstackUtil, btstack_strcpy){
322 static char * field_data = "btstack";
323 char buffer[10];
324
325 btstack_strcpy(buffer, sizeof(buffer), field_data);
326 MEMCMP_EQUAL(buffer, field_data, strlen(field_data));
327 }
328
TEST(BTstackUtil,btstack_virtual_memcpy)329 TEST(BTstackUtil, btstack_virtual_memcpy){
330 uint16_t bytes_copied;
331 const uint8_t field_data[] = {0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff};
332 uint16_t field_len = sizeof(field_data);
333 uint16_t field_offset = 0;
334
335 uint8_t buffer[100];
336
337 btstack_virtual_memcpy(field_data, field_len, 0, buffer, sizeof(buffer), 0);
338 MEMCMP_EQUAL(buffer, field_data, field_len);
339
340 btstack_virtual_memcpy(field_data, field_len, 3, buffer, sizeof(buffer), 0);
341 MEMCMP_EQUAL(buffer, field_data, field_len - 3);
342
343 // bail before buffer
344 bytes_copied = btstack_virtual_memcpy(field_data, field_len, 0, buffer, sizeof(buffer), sizeof(buffer));
345 CHECK_EQUAL(bytes_copied, 0);
346
347 // bail after buffer
348 bytes_copied = btstack_virtual_memcpy(field_data, field_len, sizeof(field_data), buffer, 0, 0);
349 CHECK_EQUAL(bytes_copied, 0);
350 }
351
TEST(BTstackUtil,btstack_virtual_memcpy_two)352 TEST(BTstackUtil, btstack_virtual_memcpy_two){
353 uint16_t bytes_copied;
354 const uint8_t field_data[] = {0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff};
355 uint16_t field_len = sizeof(field_data);
356 uint16_t field_offset = 0;
357
358 uint8_t buffer[14];
359 uint16_t buffer_size = sizeof(buffer);
360 uint16_t records_offset = 0;
361
362 bytes_copied = btstack_virtual_memcpy(field_data, field_len, records_offset, buffer, sizeof(buffer), 0);
363 records_offset += bytes_copied;
364 CHECK_EQUAL(bytes_copied, field_len);
365
366 bytes_copied = btstack_virtual_memcpy(field_data, field_len, records_offset, buffer, sizeof(buffer), 0);
367 records_offset += bytes_copied;
368 CHECK_EQUAL(bytes_copied, field_len);
369
370 // buffer can store only a fragment of the record, and will skip remaining bytes
371 // skip_at_end
372 bytes_copied = btstack_virtual_memcpy(field_data, field_len, records_offset, buffer, sizeof(buffer), 0);
373 records_offset += bytes_copied;
374 CHECK_EQUAL(bytes_copied, 2);
375 }
376
TEST(BTstackUtil,crc_updated)377 TEST(BTstackUtil, crc_updated){
378 uint32_t crc_initial = btstack_crc32_init();
379 CHECK_EQUAL(crc_initial, 0xffffffff);
380
381 const uint8_t data[] = {0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff};
382 uint32_t crc_updated = btstack_crc32_update(crc_initial, data, sizeof(data));
383 CHECK_EQUAL(crc_updated, 1648583859);
384
385 uint32_t crc_final = btstack_crc32_finalize(crc_updated);
386 CHECK_EQUAL(crc_final, crc_updated ^ 0xffffffff);
387 }
388
main(int argc,const char * argv[])389 int main (int argc, const char * argv[]){
390 return CommandLineTestRunner::RunAllTests(argc, argv);
391 }
392