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