xref: /btstack/src/btstack_util.c (revision 5cc4aee33b159086f22d3ba2c90a8f9f43142a48)
1 /*
2  * Copyright (C) 2014 BlueKitchen GmbH
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the copyright holders nor the names of
14  *    contributors may be used to endorse or promote products derived
15  *    from this software without specific prior written permission.
16  * 4. Any redistribution, use, or modification is done solely for
17  *    personal benefit and not for any commercial purpose or for
18  *    monetary gain.
19  *
20  * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
21  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BLUEKITCHEN
24  * GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
27  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
30  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  *
33  * Please inquire about commercial licensing options at
34  * [email protected]
35  *
36  */
37 
38 #define BTSTACK_FILE__ "btstack_util.c"
39 
40 /*
41  *  General utility functions
42  */
43 
44 #include "btstack_config.h"
45 #include "btstack_debug.h"
46 #include "btstack_util.h"
47 
48 #ifdef _MSC_VER
49 #include <intrin.h>
50 #include <windows.h>
51 #endif
52 
53 #ifdef ENABLE_PRINTF_HEXDUMP
54 #include <stdio.h>
55 #endif
56 
57 #include <string.h>
58 
59 /**
60  * @brief Compare two Bluetooth addresses
61  * @param a
62  * @param b
63  * @return 0 if equal
64  */
65 int bd_addr_cmp(const bd_addr_t a, const bd_addr_t b){
66     return memcmp(a,b, BD_ADDR_LEN);
67 }
68 
69 /**
70  * @brief Copy Bluetooth address
71  * @param dest
72  * @param src
73  */
74 void bd_addr_copy(bd_addr_t dest, const bd_addr_t src){
75     (void)memcpy(dest, src, BD_ADDR_LEN);
76 }
77 
78 uint16_t little_endian_read_16(const uint8_t * buffer, int position){
79     return (uint16_t)(((uint16_t) buffer[position]) | (((uint16_t)buffer[position+1]) << 8));
80 }
81 uint32_t little_endian_read_24(const uint8_t * buffer, int position){
82     return ((uint32_t) buffer[position]) | (((uint32_t)buffer[position+1]) << 8) | (((uint32_t)buffer[position+2]) << 16);
83 }
84 uint32_t little_endian_read_32(const uint8_t * buffer, int position){
85     return ((uint32_t) buffer[position]) | (((uint32_t)buffer[position+1]) << 8) | (((uint32_t)buffer[position+2]) << 16) | (((uint32_t) buffer[position+3]) << 24);
86 }
87 
88 void little_endian_store_16(uint8_t * buffer, uint16_t position, uint16_t value){
89     uint16_t pos = position;
90     buffer[pos++] = (uint8_t)value;
91     buffer[pos++] = (uint8_t)(value >> 8);
92 }
93 
94 void little_endian_store_24(uint8_t * buffer, uint16_t position, uint32_t value){
95     uint16_t pos = position;
96     buffer[pos++] = (uint8_t)(value);
97     buffer[pos++] = (uint8_t)(value >> 8);
98     buffer[pos++] = (uint8_t)(value >> 16);
99 }
100 
101 void little_endian_store_32(uint8_t * buffer, uint16_t position, uint32_t value){
102     uint16_t pos = position;
103     buffer[pos++] = (uint8_t)(value);
104     buffer[pos++] = (uint8_t)(value >> 8);
105     buffer[pos++] = (uint8_t)(value >> 16);
106     buffer[pos++] = (uint8_t)(value >> 24);
107 }
108 
109 uint32_t big_endian_read_16(const uint8_t * buffer, int position) {
110     return (uint16_t)(((uint16_t) buffer[position+1]) | (((uint16_t)buffer[position]) << 8));
111 }
112 
113 uint32_t big_endian_read_24(const uint8_t * buffer, int position) {
114     return ( ((uint32_t)buffer[position+2]) | (((uint32_t)buffer[position+1]) << 8) | (((uint32_t) buffer[position]) << 16));
115 }
116 
117 uint32_t big_endian_read_32(const uint8_t * buffer, int position) {
118     return ((uint32_t) buffer[position+3]) | (((uint32_t)buffer[position+2]) << 8) | (((uint32_t)buffer[position+1]) << 16) | (((uint32_t) buffer[position]) << 24);
119 }
120 
121 void big_endian_store_16(uint8_t * buffer, uint16_t position, uint16_t value){
122     uint16_t pos = position;
123     buffer[pos++] = (uint8_t)(value >> 8);
124     buffer[pos++] = (uint8_t)(value);
125 }
126 
127 void big_endian_store_24(uint8_t * buffer, uint16_t position, uint32_t value){
128     uint16_t pos = position;
129     buffer[pos++] = (uint8_t)(value >> 16);
130     buffer[pos++] = (uint8_t)(value >> 8);
131     buffer[pos++] = (uint8_t)(value);
132 }
133 
134 void big_endian_store_32(uint8_t * buffer, uint16_t position, uint32_t value){
135     uint16_t pos = position;
136     buffer[pos++] = (uint8_t)(value >> 24);
137     buffer[pos++] = (uint8_t)(value >> 16);
138     buffer[pos++] = (uint8_t)(value >> 8);
139     buffer[pos++] = (uint8_t)(value);
140 }
141 
142 // general swap/endianess utils
143 void reverse_bytes(const uint8_t * src, uint8_t * dest, int len){
144     int i;
145     for (i = 0; i < len; i++)
146         dest[len - 1 - i] = src[i];
147 }
148 void reverse_24(const uint8_t * src, uint8_t * dest){
149     reverse_bytes(src, dest, 3);
150 }
151 void reverse_48(const uint8_t * src, uint8_t * dest){
152     reverse_bytes(src, dest, 6);
153 }
154 void reverse_56(const uint8_t * src, uint8_t * dest){
155     reverse_bytes(src, dest, 7);
156 }
157 void reverse_64(const uint8_t * src, uint8_t * dest){
158     reverse_bytes(src, dest, 8);
159 }
160 void reverse_128(const uint8_t * src, uint8_t * dest){
161     reverse_bytes(src, dest, 16);
162 }
163 void reverse_256(const uint8_t * src, uint8_t * dest){
164     reverse_bytes(src, dest, 32);
165 }
166 
167 void reverse_bd_addr(const bd_addr_t src, bd_addr_t dest){
168     reverse_bytes(src, dest, 6);
169 }
170 
171 bool btstack_is_null(const uint8_t * buffer, uint16_t size){
172     uint16_t i;
173     for (i=0; i < size ; i++){
174         if (buffer[i] != 0) {
175             return false;
176         }
177     }
178     return true;
179 }
180 
181 bool btstack_is_null_bd_addr( const bd_addr_t addr ){
182     return btstack_is_null( addr, sizeof(bd_addr_t) );
183 }
184 
185 uint32_t btstack_min(uint32_t a, uint32_t b){
186     return (a < b) ? a : b;
187 }
188 
189 uint32_t btstack_max(uint32_t a, uint32_t b){
190     return (a > b) ? a : b;
191 }
192 
193 /**
194  * @brief Calculate delta between two uint32_t points in time
195  * @return time_a - time_b - result > 0 if time_a is newer than time_b
196  */
197 int32_t btstack_time_delta(uint32_t time_a, uint32_t time_b){
198     return (int32_t)(time_a - time_b);
199 }
200 
201 /**
202  * @brief Calculate delta between two uint16_t points in time
203  * @return time_a - time_b - result > 0 if time_a is newer than time_b
204  */
205 int16_t btstack_time16_delta(uint16_t time_a, uint16_t time_b){
206     return (int16_t)(time_a - time_b);
207 }
208 
209 char char_for_nibble(uint8_t nibble){
210 
211     static const char * char_to_nibble = "0123456789ABCDEF";
212 
213     if (nibble < 16){
214         return char_to_nibble[nibble];
215     } else {
216         return '?';
217     }
218 }
219 
220 static inline char char_for_high_nibble(int value){
221     return char_for_nibble((value >> 4) & 0x0f);
222 }
223 
224 static inline char char_for_low_nibble(int value){
225     return char_for_nibble(value & 0x0f);
226 }
227 
228 
229 int nibble_for_char(char c){
230     if ((c >= '0') && (c <= '9')) return c - '0';
231     if ((c >= 'a') && (c <= 'f')) return c - 'a' + 10;
232     if ((c >= 'A') && (c <= 'F')) return c - 'A' + 10;
233     return -1;
234 }
235 
236 #ifdef ENABLE_PRINTF_HEXDUMP
237 void printf_hexdump(const void * data, int size){
238     char buffer[4];
239     buffer[2] = ' ';
240     buffer[3] =  0;
241     const uint8_t * ptr = (const uint8_t *) data;
242     while (size > 0){
243         uint8_t byte = *ptr++;
244         buffer[0] = char_for_high_nibble(byte);
245         buffer[1] = char_for_low_nibble(byte);
246         printf("%s", buffer);
247         size--;
248     }
249     printf("\n");
250 }
251 #endif
252 
253 #if defined(ENABLE_LOG_INFO) || defined(ENABLE_LOG_DEBUG)
254 static void log_hexdump(int level, const void * data, int size){
255 #define ITEMS_PER_LINE 16
256 // template '0x12, '
257 #define BYTES_PER_BYTE  6
258     char buffer[BYTES_PER_BYTE*ITEMS_PER_LINE+1];
259     int i, j;
260     j = 0;
261     for (i=0; i<size;i++){
262 
263         // help static analyzer proof that j stays within bounds
264         if (j > (BYTES_PER_BYTE * (ITEMS_PER_LINE-1))){
265             j = 0;
266         }
267 
268         uint8_t byte = ((uint8_t *)data)[i];
269         buffer[j++] = '0';
270         buffer[j++] = 'x';
271         buffer[j++] = char_for_high_nibble(byte);
272         buffer[j++] = char_for_low_nibble(byte);
273         buffer[j++] = ',';
274         buffer[j++] = ' ';
275 
276         if (j >= (BYTES_PER_BYTE * ITEMS_PER_LINE) ){
277             buffer[j] = 0;
278             HCI_DUMP_LOG(level, "%s", buffer);
279             j = 0;
280         }
281     }
282     if (j != 0){
283         buffer[j] = 0;
284         HCI_DUMP_LOG(level, "%s", buffer);
285     }
286 }
287 #endif
288 
289 void log_debug_hexdump(const void * data, int size){
290 #ifdef ENABLE_LOG_DEBUG
291     log_hexdump(HCI_DUMP_LOG_LEVEL_DEBUG, data, size);
292 #else
293     UNUSED(data);   // ok: no code
294     UNUSED(size);   // ok: no code
295 #endif
296 }
297 
298 void log_info_hexdump(const void * data, int size){
299 #ifdef ENABLE_LOG_INFO
300     log_hexdump(HCI_DUMP_LOG_LEVEL_INFO, data, size);
301 #else
302     UNUSED(data);   // ok: no code
303     UNUSED(size);   // ok: no code
304 #endif
305 }
306 
307 void log_info_key(const char * name, sm_key_t key){
308 #ifdef ENABLE_LOG_INFO
309     char buffer[16*2+1];
310     int i;
311     int j = 0;
312     for (i=0; i<16;i++){
313         uint8_t byte = key[i];
314         buffer[j++] = char_for_high_nibble(byte);
315         buffer[j++] = char_for_low_nibble(byte);
316     }
317     buffer[j] = 0;
318     log_info("%-6s %s", name, buffer);
319 #else
320     UNUSED(name);
321     (void)key;
322 #endif
323 }
324 
325 // UUIDs are stored in big endian, similar to bd_addr_t
326 
327 // Bluetooth Base UUID: 00000000-0000-1000-8000- 00805F9B34FB
328 const uint8_t bluetooth_base_uuid[] = { 0x00, 0x00, 0x00, 0x00, /* - */ 0x00, 0x00, /* - */ 0x10, 0x00, /* - */
329     0x80, 0x00, /* - */ 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB };
330 
331 void uuid_add_bluetooth_prefix(uint8_t * uuid128, uint32_t short_uuid){
332     (void)memcpy(uuid128, bluetooth_base_uuid, 16);
333     big_endian_store_32(uuid128, 0, short_uuid);
334 }
335 
336 bool uuid_has_bluetooth_prefix(const uint8_t * uuid128){
337     return memcmp(&uuid128[4], &bluetooth_base_uuid[4], 12) == 0;
338 }
339 
340 static char uuid128_to_str_buffer[32+4+1];
341 char * uuid128_to_str(const uint8_t * uuid){
342     int i;
343     int j = 0;
344     // after 4, 6, 8, and 10 bytes = XYXYXYXY-XYXY-XYXY-XYXY-XYXYXYXYXYXY, there's a dash
345     const int dash_locations = (1<<3) | (1<<5) | (1<<7) | (1<<9);
346     for (i=0;i<16;i++){
347         uint8_t byte = uuid[i];
348         uuid128_to_str_buffer[j++] = char_for_high_nibble(byte);
349         uuid128_to_str_buffer[j++] = char_for_low_nibble(byte);
350         if (dash_locations & (1<<i)){
351             uuid128_to_str_buffer[j++] = '-';
352         }
353     }
354     return uuid128_to_str_buffer;
355 }
356 
357 static char bd_addr_to_str_buffer[6*3];  // 12:45:78:01:34:67\0
358 char * bd_addr_to_str_with_delimiter(const bd_addr_t addr, char delimiter){
359     char * p = bd_addr_to_str_buffer;
360     int i;
361     for (i = 0; i < 6 ; i++) {
362         uint8_t byte = addr[i];
363         *p++ = char_for_high_nibble(byte);
364         *p++ = char_for_low_nibble(byte);
365         *p++ = delimiter;
366     }
367     *--p = 0;
368     return (char *) bd_addr_to_str_buffer;
369 }
370 
371 char * bd_addr_to_str(const bd_addr_t addr){
372     return bd_addr_to_str_with_delimiter(addr, ':');
373 }
374 
375 void btstack_replace_bd_addr_placeholder(uint8_t * buffer, uint16_t size, const bd_addr_t address){
376     const int bd_addr_string_len = 17;
377     uint16_t i = 0;
378     while ((i + bd_addr_string_len) <= size){
379         if (memcmp(&buffer[i], "00:00:00:00:00:00", bd_addr_string_len)) {
380             i++;
381             continue;
382         }
383         // set address
384         (void)memcpy(&buffer[i], bd_addr_to_str(address), bd_addr_string_len);
385         i += bd_addr_string_len;
386     }
387 }
388 
389 static int scan_hex_byte(const char * byte_string){
390     int upper_nibble = nibble_for_char(byte_string[0]);
391     if (upper_nibble < 0) return -1;
392     int lower_nibble = nibble_for_char(byte_string[1]);
393     if (lower_nibble < 0) return -1;
394     return (upper_nibble << 4) | lower_nibble;
395 }
396 
397 int sscanf_bd_addr(const char * addr_string, bd_addr_t addr){
398     const char * the_string = addr_string;
399     uint8_t buffer[BD_ADDR_LEN];
400     int result = 0;
401     int i;
402     for (i = 0; i < BD_ADDR_LEN; i++) {
403         int single_byte = scan_hex_byte(the_string);
404         if (single_byte < 0) break;
405         the_string += 2;
406         buffer[i] = (uint8_t)single_byte;
407         // don't check separator after last byte
408         if (i == (BD_ADDR_LEN - 1)) {
409             result = 1;
410             break;
411         }
412         // skip supported separators
413         char next_char = *the_string;
414         if ((next_char == ':') || (next_char == '-') || (next_char == ' ')) {
415             the_string++;
416         }
417     }
418 
419     if (result != 0){
420         bd_addr_copy(addr, buffer);
421     }
422 	return result;
423 }
424 
425 uint32_t btstack_atoi(const char * str){
426     const char * the_string = str;
427     uint32_t val = 0;
428     while (true){
429         char chr = *the_string++;
430         if (!chr || (chr < '0') || (chr > '9'))
431             return val;
432         val = (val * 10u) + (uint8_t)(chr - '0');
433     }
434 }
435 
436 int string_len_for_uint32(uint32_t i){
437     if (i <         10) return 1;
438     if (i <        100) return 2;
439     if (i <       1000) return 3;
440     if (i <      10000) return 4;
441     if (i <     100000) return 5;
442     if (i <    1000000) return 6;
443     if (i <   10000000) return 7;
444     if (i <  100000000) return 8;
445     if (i < 1000000000) return 9;
446     return 10;
447 }
448 
449 int count_set_bits_uint32(uint32_t x){
450     uint32_t v = x;
451     v = (v & 0x55555555) + ((v >> 1)  & 0x55555555U);
452     v = (v & 0x33333333) + ((v >> 2)  & 0x33333333U);
453     v = (v & 0x0F0F0F0F) + ((v >> 4)  & 0x0F0F0F0FU);
454     v = (v & 0x00FF00FF) + ((v >> 8)  & 0x00FF00FFU);
455     v = (v & 0x0000FFFF) + ((v >> 16) & 0x0000FFFFU);
456     return v;
457 }
458 
459 uint8_t btstack_clz(uint32_t value) {
460     btstack_assert( value != 0 );
461 #if defined(__GNUC__) || defined (__clang__)
462     // use gcc/clang intrinsic
463     return (uint8_t) __builtin_clz(value);
464 #elif defined(_MSC_VER)
465     // use MSVC intrinsic
466     DWORD leading_zero = 0;
467     _BitScanReverse( &leading_zero, value );
468 	return (uint8_t)(31 - leading_zero);
469 #else
470     // divide-and-conquer implementation for 32-bit integers
471     uint32_t x = value;
472     uint8_t r = 0;
473     if ((x & 0xffff0000u) == 0) {
474         x <<= 16;
475         r += 16;
476     }
477     if ((x & 0xff000000u) == 0) {
478         x <<= 8;
479         r += 8;
480     }
481     if ((x & 0xf0000000u) == 0) {
482         x <<= 4;
483         r += 4;
484     }
485     if ((x & 0xc0000000u) == 0) {
486         x <<= 2;
487         r += 2;
488     }
489     if ((x & 0x80000000u) == 0) {
490         x <<= 1;
491         r += 1;
492     }
493     return r;
494 #endif
495 }
496 
497 /*
498  * CRC-8 (reversed crc) lookup table as calculated by the table generator in ETSI TS 101 369 V6.3.0.
499  */
500 
501 #define CRC8_INIT  0xFF          // Initial FCS value
502 #define CRC8_OK    0xCF          // Good final FCS value
503 
504 static const uint8_t crc8table[256] = {    /* reversed, 8-bit, poly=0x07 */
505     0x00, 0x91, 0xE3, 0x72, 0x07, 0x96, 0xE4, 0x75, 0x0E, 0x9F, 0xED, 0x7C, 0x09, 0x98, 0xEA, 0x7B,
506     0x1C, 0x8D, 0xFF, 0x6E, 0x1B, 0x8A, 0xF8, 0x69, 0x12, 0x83, 0xF1, 0x60, 0x15, 0x84, 0xF6, 0x67,
507     0x38, 0xA9, 0xDB, 0x4A, 0x3F, 0xAE, 0xDC, 0x4D, 0x36, 0xA7, 0xD5, 0x44, 0x31, 0xA0, 0xD2, 0x43,
508     0x24, 0xB5, 0xC7, 0x56, 0x23, 0xB2, 0xC0, 0x51, 0x2A, 0xBB, 0xC9, 0x58, 0x2D, 0xBC, 0xCE, 0x5F,
509     0x70, 0xE1, 0x93, 0x02, 0x77, 0xE6, 0x94, 0x05, 0x7E, 0xEF, 0x9D, 0x0C, 0x79, 0xE8, 0x9A, 0x0B,
510     0x6C, 0xFD, 0x8F, 0x1E, 0x6B, 0xFA, 0x88, 0x19, 0x62, 0xF3, 0x81, 0x10, 0x65, 0xF4, 0x86, 0x17,
511     0x48, 0xD9, 0xAB, 0x3A, 0x4F, 0xDE, 0xAC, 0x3D, 0x46, 0xD7, 0xA5, 0x34, 0x41, 0xD0, 0xA2, 0x33,
512     0x54, 0xC5, 0xB7, 0x26, 0x53, 0xC2, 0xB0, 0x21, 0x5A, 0xCB, 0xB9, 0x28, 0x5D, 0xCC, 0xBE, 0x2F,
513     0xE0, 0x71, 0x03, 0x92, 0xE7, 0x76, 0x04, 0x95, 0xEE, 0x7F, 0x0D, 0x9C, 0xE9, 0x78, 0x0A, 0x9B,
514     0xFC, 0x6D, 0x1F, 0x8E, 0xFB, 0x6A, 0x18, 0x89, 0xF2, 0x63, 0x11, 0x80, 0xF5, 0x64, 0x16, 0x87,
515     0xD8, 0x49, 0x3B, 0xAA, 0xDF, 0x4E, 0x3C, 0xAD, 0xD6, 0x47, 0x35, 0xA4, 0xD1, 0x40, 0x32, 0xA3,
516     0xC4, 0x55, 0x27, 0xB6, 0xC3, 0x52, 0x20, 0xB1, 0xCA, 0x5B, 0x29, 0xB8, 0xCD, 0x5C, 0x2E, 0xBF,
517     0x90, 0x01, 0x73, 0xE2, 0x97, 0x06, 0x74, 0xE5, 0x9E, 0x0F, 0x7D, 0xEC, 0x99, 0x08, 0x7A, 0xEB,
518     0x8C, 0x1D, 0x6F, 0xFE, 0x8B, 0x1A, 0x68, 0xF9, 0x82, 0x13, 0x61, 0xF0, 0x85, 0x14, 0x66, 0xF7,
519     0xA8, 0x39, 0x4B, 0xDA, 0xAF, 0x3E, 0x4C, 0xDD, 0xA6, 0x37, 0x45, 0xD4, 0xA1, 0x30, 0x42, 0xD3,
520     0xB4, 0x25, 0x57, 0xC6, 0xB3, 0x22, 0x50, 0xC1, 0xBA, 0x2B, 0x59, 0xC8, 0xBD, 0x2C, 0x5E, 0xCF
521 };
522 
523 /*-----------------------------------------------------------------------------------*/
524 static uint8_t crc8(uint8_t *data, uint16_t len){
525     uint16_t count;
526     uint8_t crc = CRC8_INIT;
527     for (count = 0; count < len; count++){
528         crc = crc8table[crc ^ data[count]];
529     }
530     return crc;
531 }
532 
533 /*-----------------------------------------------------------------------------------*/
534 uint8_t btstack_crc8_check(uint8_t *data, uint16_t len, uint8_t check_sum){
535     uint8_t crc;
536     crc = crc8(data, len);
537     crc = crc8table[crc ^ check_sum];
538     if (crc == CRC8_OK){
539         return 0;               /* Valid */
540     } else {
541         return 1;               /* Failed */
542     }
543 }
544 
545 /*-----------------------------------------------------------------------------------*/
546 uint8_t btstack_crc8_calc(uint8_t *data, uint16_t len){
547     /* Ones complement */
548     return 0xFFu - crc8(data, len);
549 }
550 
551 /*
552  * CRC-32 lookup table as calculated by the table generator. Polynomial (normal) 0x04c11db7, ISO 3309 (HDLC)
553  *
554  * Created using pycrc tool (https://pycrc.org) with "crc-32" as model, and "table-driven" algorithm
555  *  python3 pycrc.py --model crc-32 --algorithm table-driven --generate h -o crc32.h
556  *  python3 pycrc.py --model crc-32 --algorithm table-driven --generate c -o crc32.c
557  */
558 
559 /**
560  * Static table used for the table_driven implementation.
561  */
562 static const uint32_t crc_table[256] = {
563     0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
564     0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
565     0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
566     0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
567     0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
568     0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
569     0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
570     0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
571     0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
572     0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
573     0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
574     0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
575     0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
576     0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
577     0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
578     0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
579     0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
580     0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
581     0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
582     0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
583     0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
584     0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
585     0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
586     0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
587     0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
588     0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
589     0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
590     0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
591     0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
592     0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
593     0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
594     0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
595 };
596 
597 uint32_t btstack_crc32_init(void){
598     return 0xffffffff;
599 }
600 
601 uint32_t btstack_crc32_update(uint32_t crc, const uint8_t * data, uint32_t data_len){
602     const uint8_t *d = data;
603     uint32_t tbl_idx;
604 
605     while (data_len--) {
606         tbl_idx = (crc ^ *d) & 0xff;
607         crc = (crc_table[tbl_idx] ^ (crc >> 8)) & 0xffffffff;
608         d++;
609     }
610     return crc & 0xffffffff;
611 }
612 
613 uint32_t btstack_crc32_finalize(uint32_t crc){
614     return crc ^ 0xffffffff;
615 }
616 
617 /*-----------------------------------------------------------------------------------*/
618 
619 uint16_t btstack_next_cid_ignoring_zero(uint16_t current_cid){
620     uint16_t next_cid;
621     if (current_cid == 0xffff) {
622         next_cid = 1;
623     } else {
624         next_cid = current_cid + 1;
625     }
626     return next_cid;
627 }
628 
629 uint16_t btstack_strcpy(char * dst, uint16_t dst_size, const char * src){
630     uint16_t bytes_to_copy = (uint16_t) btstack_min( dst_size - 1, (uint16_t) strlen(src));
631     (void) memcpy(dst, src, bytes_to_copy);
632     dst[bytes_to_copy] = 0;
633     return bytes_to_copy + 1;
634 }
635 
636 void btstack_strcat(char * dst, uint16_t dst_size, const char * src){
637     uint16_t src_len = (uint16_t) strlen(src);
638     uint16_t dst_len = (uint16_t) strlen(dst);
639     uint16_t bytes_to_copy = btstack_min( src_len, dst_size - dst_len - 1);
640     (void) memcpy( &dst[dst_len], src, bytes_to_copy);
641     dst[dst_len + bytes_to_copy] = 0;
642 }
643 
644 uint16_t btstack_virtual_memcpy(
645     const uint8_t * field_data, uint16_t field_len, uint16_t field_offset, // position of field in complete data block
646     uint8_t * buffer, uint16_t buffer_size, uint16_t buffer_offset){
647 
648     uint16_t after_buffer = buffer_offset + buffer_size ;
649     // bail before buffer
650     if ((field_offset + field_len) < buffer_offset){
651         return 0;
652     }
653     // bail after buffer
654     if (field_offset >= after_buffer){
655         return 0;
656     }
657     // calc overlap
658     uint16_t bytes_to_copy = field_len;
659 
660     uint16_t skip_at_start = 0;
661     if (field_offset < buffer_offset){
662         skip_at_start = buffer_offset - field_offset;
663         bytes_to_copy -= skip_at_start;
664     }
665 
666     uint16_t skip_at_end = 0;
667     if ((field_offset + field_len) > after_buffer){
668         skip_at_end = (field_offset + field_len) - after_buffer;
669         bytes_to_copy -= skip_at_end;
670     }
671 
672     btstack_assert((skip_at_end + skip_at_start) <= field_len);
673     btstack_assert(bytes_to_copy <= field_len);
674 
675     memcpy(&buffer[(field_offset + skip_at_start) - buffer_offset], &field_data[skip_at_start], bytes_to_copy);
676     return bytes_to_copy;
677 }
678