1eb886013SMatthias Ringwald /* 2eb886013SMatthias Ringwald * Copyright (C) 2014 BlueKitchen GmbH 3eb886013SMatthias Ringwald * 4eb886013SMatthias Ringwald * Redistribution and use in source and binary forms, with or without 5eb886013SMatthias Ringwald * modification, are permitted provided that the following conditions 6eb886013SMatthias Ringwald * are met: 7eb886013SMatthias Ringwald * 8eb886013SMatthias Ringwald * 1. Redistributions of source code must retain the above copyright 9eb886013SMatthias Ringwald * notice, this list of conditions and the following disclaimer. 10eb886013SMatthias Ringwald * 2. Redistributions in binary form must reproduce the above copyright 11eb886013SMatthias Ringwald * notice, this list of conditions and the following disclaimer in the 12eb886013SMatthias Ringwald * documentation and/or other materials provided with the distribution. 13eb886013SMatthias Ringwald * 3. Neither the name of the copyright holders nor the names of 14eb886013SMatthias Ringwald * contributors may be used to endorse or promote products derived 15eb886013SMatthias Ringwald * from this software without specific prior written permission. 16eb886013SMatthias Ringwald * 4. Any redistribution, use, or modification is done solely for 17eb886013SMatthias Ringwald * personal benefit and not for any commercial purpose or for 18eb886013SMatthias Ringwald * monetary gain. 19eb886013SMatthias Ringwald * 20eb886013SMatthias Ringwald * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS 21eb886013SMatthias Ringwald * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22eb886013SMatthias Ringwald * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23eb886013SMatthias Ringwald * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS 24eb886013SMatthias Ringwald * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 25eb886013SMatthias Ringwald * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 26eb886013SMatthias Ringwald * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 27eb886013SMatthias Ringwald * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 28eb886013SMatthias Ringwald * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29eb886013SMatthias Ringwald * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 30eb886013SMatthias Ringwald * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31eb886013SMatthias Ringwald * SUCH DAMAGE. 32eb886013SMatthias Ringwald * 33eb886013SMatthias Ringwald * Please inquire about commercial licensing options at 34eb886013SMatthias Ringwald * [email protected] 35eb886013SMatthias Ringwald * 36eb886013SMatthias Ringwald */ 37eb886013SMatthias Ringwald 38eb886013SMatthias Ringwald /* 39eb886013SMatthias Ringwald * btstack_util.c 40eb886013SMatthias Ringwald * 41eb886013SMatthias Ringwald * General utility functions 42eb886013SMatthias Ringwald * 43eb886013SMatthias Ringwald * Created by Matthias Ringwald on 7/23/09. 44eb886013SMatthias Ringwald */ 45eb886013SMatthias Ringwald 467907f069SMatthias Ringwald #include "btstack_config.h" 47eb886013SMatthias Ringwald #include "btstack_util.h" 48eb886013SMatthias Ringwald #include <stdio.h> 49eb886013SMatthias Ringwald #include <string.h> 50eb886013SMatthias Ringwald #include "btstack_debug.h" 51eb886013SMatthias Ringwald 52f8fbdce0SMatthias Ringwald void little_endian_store_16(uint8_t *buffer, uint16_t pos, uint16_t value){ 53eb886013SMatthias Ringwald buffer[pos++] = value; 54eb886013SMatthias Ringwald buffer[pos++] = value >> 8; 55eb886013SMatthias Ringwald } 56eb886013SMatthias Ringwald 57f8fbdce0SMatthias Ringwald void little_endian_store_32(uint8_t *buffer, uint16_t pos, uint32_t value){ 58eb886013SMatthias Ringwald buffer[pos++] = value; 59eb886013SMatthias Ringwald buffer[pos++] = value >> 8; 60eb886013SMatthias Ringwald buffer[pos++] = value >> 16; 61eb886013SMatthias Ringwald buffer[pos++] = value >> 24; 62eb886013SMatthias Ringwald } 63eb886013SMatthias Ringwald 64f8fbdce0SMatthias Ringwald void big_endian_store_16(uint8_t *buffer, uint16_t pos, uint16_t value){ 65eb886013SMatthias Ringwald buffer[pos++] = value >> 8; 66eb886013SMatthias Ringwald buffer[pos++] = value; 67eb886013SMatthias Ringwald } 68eb886013SMatthias Ringwald 69f8fbdce0SMatthias Ringwald void big_endian_store_32(uint8_t *buffer, uint16_t pos, uint32_t value){ 70eb886013SMatthias Ringwald buffer[pos++] = value >> 24; 71eb886013SMatthias Ringwald buffer[pos++] = value >> 16; 72eb886013SMatthias Ringwald buffer[pos++] = value >> 8; 73eb886013SMatthias Ringwald buffer[pos++] = value; 74eb886013SMatthias Ringwald } 75eb886013SMatthias Ringwald 76eb886013SMatthias Ringwald void bt_flip_addr(bd_addr_t dest, bd_addr_t src){ 77eb886013SMatthias Ringwald dest[0] = src[5]; 78eb886013SMatthias Ringwald dest[1] = src[4]; 79eb886013SMatthias Ringwald dest[2] = src[3]; 80eb886013SMatthias Ringwald dest[3] = src[2]; 81eb886013SMatthias Ringwald dest[4] = src[1]; 82eb886013SMatthias Ringwald dest[5] = src[0]; 83eb886013SMatthias Ringwald } 84eb886013SMatthias Ringwald 85eb886013SMatthias Ringwald // general swap/endianess utils 86eb886013SMatthias Ringwald void swapX(const uint8_t *src, uint8_t *dst, int len){ 87eb886013SMatthias Ringwald int i; 88eb886013SMatthias Ringwald for (i = 0; i < len; i++) 89eb886013SMatthias Ringwald dst[len - 1 - i] = src[i]; 90eb886013SMatthias Ringwald } 91bf1b35bfSMatthias Ringwald void swap24(const uint8_t * src, uint8_t * dst){ 92eb886013SMatthias Ringwald swapX(src, dst, 3); 93eb886013SMatthias Ringwald } 94bf1b35bfSMatthias Ringwald void swap48(const uint8_t * src, uint8_t * dst){ 95bf1b35bfSMatthias Ringwald swapX(src, dst, 6); 96bf1b35bfSMatthias Ringwald } 97bf1b35bfSMatthias Ringwald void swap56(const uint8_t * src, uint8_t * dst){ 98eb886013SMatthias Ringwald swapX(src, dst, 7); 99eb886013SMatthias Ringwald } 100bf1b35bfSMatthias Ringwald void swap64(const uint8_t * src, uint8_t * dst){ 101eb886013SMatthias Ringwald swapX(src, dst, 8); 102eb886013SMatthias Ringwald } 103bf1b35bfSMatthias Ringwald void swap128(const uint8_t * src, uint8_t * dst){ 104eb886013SMatthias Ringwald swapX(src, dst, 16); 105eb886013SMatthias Ringwald } 106eb886013SMatthias Ringwald 107eb886013SMatthias Ringwald char char_for_nibble(int nibble){ 108eb886013SMatthias Ringwald if (nibble < 10) return '0' + nibble; 109eb886013SMatthias Ringwald nibble -= 10; 110eb886013SMatthias Ringwald if (nibble < 6) return 'A' + nibble; 111eb886013SMatthias Ringwald return '?'; 112eb886013SMatthias Ringwald } 113eb886013SMatthias Ringwald 114eb886013SMatthias Ringwald void printf_hexdump(const void *data, int size){ 115eb886013SMatthias Ringwald if (size <= 0) return; 116eb886013SMatthias Ringwald int i; 117eb886013SMatthias Ringwald for (i=0; i<size;i++){ 118eb886013SMatthias Ringwald printf("%02X ", ((uint8_t *)data)[i]); 119eb886013SMatthias Ringwald } 120eb886013SMatthias Ringwald printf("\n"); 121eb886013SMatthias Ringwald } 122eb886013SMatthias Ringwald 123*caed94dfSMatthias Ringwald void hexdumpf(const void *data, int size){ 124*caed94dfSMatthias Ringwald char buffer[6*16+1]; 125*caed94dfSMatthias Ringwald int i, j; 126*caed94dfSMatthias Ringwald 127*caed94dfSMatthias Ringwald uint8_t low = 0x0F; 128*caed94dfSMatthias Ringwald uint8_t high = 0xF0; 129*caed94dfSMatthias Ringwald j = 0; 130*caed94dfSMatthias Ringwald for (i=0; i<size;i++){ 131*caed94dfSMatthias Ringwald uint8_t byte = ((uint8_t *)data)[i]; 132*caed94dfSMatthias Ringwald buffer[j++] = '0'; 133*caed94dfSMatthias Ringwald buffer[j++] = 'x'; 134*caed94dfSMatthias Ringwald buffer[j++] = char_for_nibble((byte & high) >> 4); 135*caed94dfSMatthias Ringwald buffer[j++] = char_for_nibble(byte & low); 136*caed94dfSMatthias Ringwald buffer[j++] = ','; 137*caed94dfSMatthias Ringwald buffer[j++] = ' '; 138*caed94dfSMatthias Ringwald if (j >= 6*16 ){ 139*caed94dfSMatthias Ringwald buffer[j] = 0; 140*caed94dfSMatthias Ringwald printf("%s\n", buffer); 141*caed94dfSMatthias Ringwald j = 0; 142*caed94dfSMatthias Ringwald } 143*caed94dfSMatthias Ringwald } 144*caed94dfSMatthias Ringwald if (j != 0){ 145*caed94dfSMatthias Ringwald buffer[j] = 0; 146*caed94dfSMatthias Ringwald printf("%s\n", buffer); 147*caed94dfSMatthias Ringwald } 148*caed94dfSMatthias Ringwald } 149*caed94dfSMatthias Ringwald 150*caed94dfSMatthias Ringwald // void log_info_hexdump(..){ 151*caed94dfSMatthias Ringwald // 152*caed94dfSMatthias Ringwald // } 153*caed94dfSMatthias Ringwald 154eb886013SMatthias Ringwald void hexdump(const void *data, int size){ 155eb886013SMatthias Ringwald #ifdef ENABLE_LOG_INFO 156eb886013SMatthias Ringwald char buffer[6*16+1]; 157eb886013SMatthias Ringwald int i, j; 158eb886013SMatthias Ringwald 159eb886013SMatthias Ringwald uint8_t low = 0x0F; 160eb886013SMatthias Ringwald uint8_t high = 0xF0; 161eb886013SMatthias Ringwald j = 0; 162eb886013SMatthias Ringwald for (i=0; i<size;i++){ 163eb886013SMatthias Ringwald uint8_t byte = ((uint8_t *)data)[i]; 164eb886013SMatthias Ringwald buffer[j++] = '0'; 165eb886013SMatthias Ringwald buffer[j++] = 'x'; 166eb886013SMatthias Ringwald buffer[j++] = char_for_nibble((byte & high) >> 4); 167eb886013SMatthias Ringwald buffer[j++] = char_for_nibble(byte & low); 168eb886013SMatthias Ringwald buffer[j++] = ','; 169eb886013SMatthias Ringwald buffer[j++] = ' '; 170eb886013SMatthias Ringwald if (j >= 6*16 ){ 171eb886013SMatthias Ringwald buffer[j] = 0; 172eb886013SMatthias Ringwald log_info("%s", buffer); 173eb886013SMatthias Ringwald j = 0; 174eb886013SMatthias Ringwald } 175eb886013SMatthias Ringwald } 176eb886013SMatthias Ringwald if (j != 0){ 177eb886013SMatthias Ringwald buffer[j] = 0; 178eb886013SMatthias Ringwald log_info("%s", buffer); 179eb886013SMatthias Ringwald } 180eb886013SMatthias Ringwald #endif 181eb886013SMatthias Ringwald } 182eb886013SMatthias Ringwald 183eb886013SMatthias Ringwald void log_key(const char * name, sm_key_t key){ 184eb886013SMatthias Ringwald log_info("%-6s ", name); 185eb886013SMatthias Ringwald hexdump(key, 16); 186eb886013SMatthias Ringwald } 187eb886013SMatthias Ringwald 188eb886013SMatthias Ringwald // Bluetooth Base UUID: 00000000-0000-1000-8000- 00805F9B34FB 189eb886013SMatthias Ringwald const uint8_t sdp_bluetooth_base_uuid[] = { 0x00, 0x00, 0x00, 0x00, /* - */ 0x00, 0x00, /* - */ 0x10, 0x00, /* - */ 190eb886013SMatthias Ringwald 0x80, 0x00, /* - */ 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB }; 191eb886013SMatthias Ringwald 192eb886013SMatthias Ringwald void sdp_normalize_uuid(uint8_t *uuid, uint32_t shortUUID){ 193eb886013SMatthias Ringwald memcpy(uuid, sdp_bluetooth_base_uuid, 16); 194f8fbdce0SMatthias Ringwald big_endian_store_32(uuid, 0, shortUUID); 195eb886013SMatthias Ringwald } 196eb886013SMatthias Ringwald 197eb886013SMatthias Ringwald int sdp_has_blueooth_base_uuid(uint8_t * uuid128){ 198eb886013SMatthias Ringwald return memcmp(&uuid128[4], &sdp_bluetooth_base_uuid[4], 12) == 0; 199eb886013SMatthias Ringwald } 200eb886013SMatthias Ringwald 201eb886013SMatthias Ringwald static char uuid128_to_str_buffer[32+4+1]; 202eb886013SMatthias Ringwald char * uuid128_to_str(uint8_t * uuid){ 203eb886013SMatthias Ringwald sprintf(uuid128_to_str_buffer, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", 204eb886013SMatthias Ringwald uuid[0], uuid[1], uuid[2], uuid[3], uuid[4], uuid[5], uuid[6], uuid[7], 205eb886013SMatthias Ringwald uuid[8], uuid[9], uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15]); 206eb886013SMatthias Ringwald return uuid128_to_str_buffer; 207eb886013SMatthias Ringwald } 208eb886013SMatthias Ringwald void printUUID128(uint8_t *uuid) { 209eb886013SMatthias Ringwald printf("%s", uuid128_to_str(uuid)); 210eb886013SMatthias Ringwald } 211eb886013SMatthias Ringwald 212eb886013SMatthias Ringwald static char bd_addr_to_str_buffer[6*3]; // 12:45:78:01:34:67\0 213eb886013SMatthias Ringwald char * bd_addr_to_str(bd_addr_t addr){ 214eb886013SMatthias Ringwald // orig code 215eb886013SMatthias Ringwald // sprintf(bd_addr_to_str_buffer, "%02x:%02x:%02x:%02x:%02x:%02x", addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]); 216eb886013SMatthias Ringwald // sprintf-free code 217eb886013SMatthias Ringwald char * p = bd_addr_to_str_buffer; 218eb886013SMatthias Ringwald int i; 219eb886013SMatthias Ringwald for (i = 0; i < 6 ; i++) { 220eb886013SMatthias Ringwald *p++ = char_for_nibble((addr[i] >> 4) & 0x0F); 221eb886013SMatthias Ringwald *p++ = char_for_nibble((addr[i] >> 0) & 0x0F); 222eb886013SMatthias Ringwald *p++ = ':'; 223eb886013SMatthias Ringwald } 224eb886013SMatthias Ringwald *--p = 0; 225eb886013SMatthias Ringwald return (char *) bd_addr_to_str_buffer; 226eb886013SMatthias Ringwald } 227eb886013SMatthias Ringwald 228eb886013SMatthias Ringwald void print_bd_addr( bd_addr_t addr){ 229eb886013SMatthias Ringwald log_info("%s", bd_addr_to_str(addr)); 230eb886013SMatthias Ringwald } 231eb886013SMatthias Ringwald 232eb886013SMatthias Ringwald int sscan_bd_addr(uint8_t * addr_string, bd_addr_t addr){ 233eb886013SMatthias Ringwald unsigned int bd_addr_buffer[BD_ADDR_LEN]; //for sscanf, integer needed 234eb886013SMatthias Ringwald // reset result buffer 235eb886013SMatthias Ringwald memset(bd_addr_buffer, 0, sizeof(bd_addr_buffer)); 236eb886013SMatthias Ringwald 237eb886013SMatthias Ringwald // parse 238eb886013SMatthias Ringwald int result = sscanf( (char *) addr_string, "%2x:%2x:%2x:%2x:%2x:%2x", &bd_addr_buffer[0], &bd_addr_buffer[1], &bd_addr_buffer[2], 239eb886013SMatthias Ringwald &bd_addr_buffer[3], &bd_addr_buffer[4], &bd_addr_buffer[5]); 240eb886013SMatthias Ringwald 241eb886013SMatthias Ringwald if (result != BD_ADDR_LEN) return 0; 242eb886013SMatthias Ringwald 243eb886013SMatthias Ringwald // store 244eb886013SMatthias Ringwald int i; 245eb886013SMatthias Ringwald for (i = 0; i < BD_ADDR_LEN; i++) { 246eb886013SMatthias Ringwald addr[i] = (uint8_t) bd_addr_buffer[i]; 247eb886013SMatthias Ringwald } 248eb886013SMatthias Ringwald return 1; 249eb886013SMatthias Ringwald } 250eb886013SMatthias Ringwald 251eb886013SMatthias Ringwald 252eb886013SMatthias Ringwald /* 253eb886013SMatthias Ringwald * CRC (reversed crc) lookup table as calculated by the table generator in ETSI TS 101 369 V6.3.0. 254eb886013SMatthias Ringwald */ 255eb886013SMatthias Ringwald static const uint8_t crc8table[256] = { /* reversed, 8-bit, poly=0x07 */ 256eb886013SMatthias Ringwald 0x00, 0x91, 0xE3, 0x72, 0x07, 0x96, 0xE4, 0x75, 0x0E, 0x9F, 0xED, 0x7C, 0x09, 0x98, 0xEA, 0x7B, 257eb886013SMatthias Ringwald 0x1C, 0x8D, 0xFF, 0x6E, 0x1B, 0x8A, 0xF8, 0x69, 0x12, 0x83, 0xF1, 0x60, 0x15, 0x84, 0xF6, 0x67, 258eb886013SMatthias Ringwald 0x38, 0xA9, 0xDB, 0x4A, 0x3F, 0xAE, 0xDC, 0x4D, 0x36, 0xA7, 0xD5, 0x44, 0x31, 0xA0, 0xD2, 0x43, 259eb886013SMatthias Ringwald 0x24, 0xB5, 0xC7, 0x56, 0x23, 0xB2, 0xC0, 0x51, 0x2A, 0xBB, 0xC9, 0x58, 0x2D, 0xBC, 0xCE, 0x5F, 260eb886013SMatthias Ringwald 0x70, 0xE1, 0x93, 0x02, 0x77, 0xE6, 0x94, 0x05, 0x7E, 0xEF, 0x9D, 0x0C, 0x79, 0xE8, 0x9A, 0x0B, 261eb886013SMatthias Ringwald 0x6C, 0xFD, 0x8F, 0x1E, 0x6B, 0xFA, 0x88, 0x19, 0x62, 0xF3, 0x81, 0x10, 0x65, 0xF4, 0x86, 0x17, 262eb886013SMatthias Ringwald 0x48, 0xD9, 0xAB, 0x3A, 0x4F, 0xDE, 0xAC, 0x3D, 0x46, 0xD7, 0xA5, 0x34, 0x41, 0xD0, 0xA2, 0x33, 263eb886013SMatthias Ringwald 0x54, 0xC5, 0xB7, 0x26, 0x53, 0xC2, 0xB0, 0x21, 0x5A, 0xCB, 0xB9, 0x28, 0x5D, 0xCC, 0xBE, 0x2F, 264eb886013SMatthias Ringwald 0xE0, 0x71, 0x03, 0x92, 0xE7, 0x76, 0x04, 0x95, 0xEE, 0x7F, 0x0D, 0x9C, 0xE9, 0x78, 0x0A, 0x9B, 265eb886013SMatthias Ringwald 0xFC, 0x6D, 0x1F, 0x8E, 0xFB, 0x6A, 0x18, 0x89, 0xF2, 0x63, 0x11, 0x80, 0xF5, 0x64, 0x16, 0x87, 266eb886013SMatthias Ringwald 0xD8, 0x49, 0x3B, 0xAA, 0xDF, 0x4E, 0x3C, 0xAD, 0xD6, 0x47, 0x35, 0xA4, 0xD1, 0x40, 0x32, 0xA3, 267eb886013SMatthias Ringwald 0xC4, 0x55, 0x27, 0xB6, 0xC3, 0x52, 0x20, 0xB1, 0xCA, 0x5B, 0x29, 0xB8, 0xCD, 0x5C, 0x2E, 0xBF, 268eb886013SMatthias Ringwald 0x90, 0x01, 0x73, 0xE2, 0x97, 0x06, 0x74, 0xE5, 0x9E, 0x0F, 0x7D, 0xEC, 0x99, 0x08, 0x7A, 0xEB, 269eb886013SMatthias Ringwald 0x8C, 0x1D, 0x6F, 0xFE, 0x8B, 0x1A, 0x68, 0xF9, 0x82, 0x13, 0x61, 0xF0, 0x85, 0x14, 0x66, 0xF7, 270eb886013SMatthias Ringwald 0xA8, 0x39, 0x4B, 0xDA, 0xAF, 0x3E, 0x4C, 0xDD, 0xA6, 0x37, 0x45, 0xD4, 0xA1, 0x30, 0x42, 0xD3, 271eb886013SMatthias Ringwald 0xB4, 0x25, 0x57, 0xC6, 0xB3, 0x22, 0x50, 0xC1, 0xBA, 0x2B, 0x59, 0xC8, 0xBD, 0x2C, 0x5E, 0xCF 272eb886013SMatthias Ringwald }; 273eb886013SMatthias Ringwald 274eb886013SMatthias Ringwald #define CRC8_INIT 0xFF // Initial FCS value 275eb886013SMatthias Ringwald #define CRC8_OK 0xCF // Good final FCS value 276eb886013SMatthias Ringwald /*-----------------------------------------------------------------------------------*/ 277eb886013SMatthias Ringwald static uint8_t crc8(uint8_t *data, uint16_t len) 278eb886013SMatthias Ringwald { 279eb886013SMatthias Ringwald uint16_t count; 280eb886013SMatthias Ringwald uint8_t crc = CRC8_INIT; 281eb886013SMatthias Ringwald for (count = 0; count < len; count++) 282eb886013SMatthias Ringwald crc = crc8table[crc ^ data[count]]; 283eb886013SMatthias Ringwald return crc; 284eb886013SMatthias Ringwald } 285eb886013SMatthias Ringwald 286eb886013SMatthias Ringwald /*-----------------------------------------------------------------------------------*/ 287eb886013SMatthias Ringwald uint8_t crc8_check(uint8_t *data, uint16_t len, uint8_t check_sum) 288eb886013SMatthias Ringwald { 289eb886013SMatthias Ringwald uint8_t crc; 290eb886013SMatthias Ringwald 291eb886013SMatthias Ringwald crc = crc8(data, len); 292eb886013SMatthias Ringwald 293eb886013SMatthias Ringwald crc = crc8table[crc ^ check_sum]; 294eb886013SMatthias Ringwald if (crc == CRC8_OK) 295eb886013SMatthias Ringwald return 0; /* Valid */ 296eb886013SMatthias Ringwald else 297eb886013SMatthias Ringwald return 1; /* Failed */ 298eb886013SMatthias Ringwald 299eb886013SMatthias Ringwald } 300eb886013SMatthias Ringwald 301eb886013SMatthias Ringwald /*-----------------------------------------------------------------------------------*/ 302eb886013SMatthias Ringwald uint8_t crc8_calc(uint8_t *data, uint16_t len) 303eb886013SMatthias Ringwald { 304eb886013SMatthias Ringwald /* Ones complement */ 305eb886013SMatthias Ringwald return 0xFF - crc8(data, len); 306eb886013SMatthias Ringwald } 307eb886013SMatthias Ringwald 308