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 52*f8fbdce0SMatthias 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 57*f8fbdce0SMatthias 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 64*f8fbdce0SMatthias 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 69*f8fbdce0SMatthias 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 123eb886013SMatthias Ringwald void hexdump(const void *data, int size){ 124eb886013SMatthias Ringwald #ifdef ENABLE_LOG_INFO 125eb886013SMatthias Ringwald char buffer[6*16+1]; 126eb886013SMatthias Ringwald int i, j; 127eb886013SMatthias Ringwald 128eb886013SMatthias Ringwald uint8_t low = 0x0F; 129eb886013SMatthias Ringwald uint8_t high = 0xF0; 130eb886013SMatthias Ringwald j = 0; 131eb886013SMatthias Ringwald for (i=0; i<size;i++){ 132eb886013SMatthias Ringwald uint8_t byte = ((uint8_t *)data)[i]; 133eb886013SMatthias Ringwald buffer[j++] = '0'; 134eb886013SMatthias Ringwald buffer[j++] = 'x'; 135eb886013SMatthias Ringwald buffer[j++] = char_for_nibble((byte & high) >> 4); 136eb886013SMatthias Ringwald buffer[j++] = char_for_nibble(byte & low); 137eb886013SMatthias Ringwald buffer[j++] = ','; 138eb886013SMatthias Ringwald buffer[j++] = ' '; 139eb886013SMatthias Ringwald if (j >= 6*16 ){ 140eb886013SMatthias Ringwald buffer[j] = 0; 141eb886013SMatthias Ringwald log_info("%s", buffer); 142eb886013SMatthias Ringwald j = 0; 143eb886013SMatthias Ringwald } 144eb886013SMatthias Ringwald } 145eb886013SMatthias Ringwald if (j != 0){ 146eb886013SMatthias Ringwald buffer[j] = 0; 147eb886013SMatthias Ringwald log_info("%s", buffer); 148eb886013SMatthias Ringwald } 149eb886013SMatthias Ringwald #endif 150eb886013SMatthias Ringwald } 151eb886013SMatthias Ringwald 152eb886013SMatthias Ringwald void hexdumpf(const void *data, int size){ 153eb886013SMatthias Ringwald char buffer[6*16+1]; 154eb886013SMatthias Ringwald int i, j; 155eb886013SMatthias Ringwald 156eb886013SMatthias Ringwald uint8_t low = 0x0F; 157eb886013SMatthias Ringwald uint8_t high = 0xF0; 158eb886013SMatthias Ringwald j = 0; 159eb886013SMatthias Ringwald for (i=0; i<size;i++){ 160eb886013SMatthias Ringwald uint8_t byte = ((uint8_t *)data)[i]; 161eb886013SMatthias Ringwald buffer[j++] = '0'; 162eb886013SMatthias Ringwald buffer[j++] = 'x'; 163eb886013SMatthias Ringwald buffer[j++] = char_for_nibble((byte & high) >> 4); 164eb886013SMatthias Ringwald buffer[j++] = char_for_nibble(byte & low); 165eb886013SMatthias Ringwald buffer[j++] = ','; 166eb886013SMatthias Ringwald buffer[j++] = ' '; 167eb886013SMatthias Ringwald if (j >= 6*16 ){ 168eb886013SMatthias Ringwald buffer[j] = 0; 169eb886013SMatthias Ringwald printf("%s\n", buffer); 170eb886013SMatthias Ringwald j = 0; 171eb886013SMatthias Ringwald } 172eb886013SMatthias Ringwald } 173eb886013SMatthias Ringwald if (j != 0){ 174eb886013SMatthias Ringwald buffer[j] = 0; 175eb886013SMatthias Ringwald printf("%s\n", buffer); 176eb886013SMatthias Ringwald } 177eb886013SMatthias Ringwald } 178eb886013SMatthias Ringwald 179eb886013SMatthias Ringwald void log_key(const char * name, sm_key_t key){ 180eb886013SMatthias Ringwald log_info("%-6s ", name); 181eb886013SMatthias Ringwald hexdump(key, 16); 182eb886013SMatthias Ringwald } 183eb886013SMatthias Ringwald 184eb886013SMatthias Ringwald // Bluetooth Base UUID: 00000000-0000-1000-8000- 00805F9B34FB 185eb886013SMatthias Ringwald const uint8_t sdp_bluetooth_base_uuid[] = { 0x00, 0x00, 0x00, 0x00, /* - */ 0x00, 0x00, /* - */ 0x10, 0x00, /* - */ 186eb886013SMatthias Ringwald 0x80, 0x00, /* - */ 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB }; 187eb886013SMatthias Ringwald 188eb886013SMatthias Ringwald void sdp_normalize_uuid(uint8_t *uuid, uint32_t shortUUID){ 189eb886013SMatthias Ringwald memcpy(uuid, sdp_bluetooth_base_uuid, 16); 190*f8fbdce0SMatthias Ringwald big_endian_store_32(uuid, 0, shortUUID); 191eb886013SMatthias Ringwald } 192eb886013SMatthias Ringwald 193eb886013SMatthias Ringwald int sdp_has_blueooth_base_uuid(uint8_t * uuid128){ 194eb886013SMatthias Ringwald return memcmp(&uuid128[4], &sdp_bluetooth_base_uuid[4], 12) == 0; 195eb886013SMatthias Ringwald } 196eb886013SMatthias Ringwald 197eb886013SMatthias Ringwald static char uuid128_to_str_buffer[32+4+1]; 198eb886013SMatthias Ringwald char * uuid128_to_str(uint8_t * uuid){ 199eb886013SMatthias Ringwald sprintf(uuid128_to_str_buffer, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", 200eb886013SMatthias Ringwald uuid[0], uuid[1], uuid[2], uuid[3], uuid[4], uuid[5], uuid[6], uuid[7], 201eb886013SMatthias Ringwald uuid[8], uuid[9], uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15]); 202eb886013SMatthias Ringwald return uuid128_to_str_buffer; 203eb886013SMatthias Ringwald } 204eb886013SMatthias Ringwald void printUUID128(uint8_t *uuid) { 205eb886013SMatthias Ringwald printf("%s", uuid128_to_str(uuid)); 206eb886013SMatthias Ringwald } 207eb886013SMatthias Ringwald 208eb886013SMatthias Ringwald static char bd_addr_to_str_buffer[6*3]; // 12:45:78:01:34:67\0 209eb886013SMatthias Ringwald char * bd_addr_to_str(bd_addr_t addr){ 210eb886013SMatthias Ringwald // orig code 211eb886013SMatthias 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]); 212eb886013SMatthias Ringwald // sprintf-free code 213eb886013SMatthias Ringwald char * p = bd_addr_to_str_buffer; 214eb886013SMatthias Ringwald int i; 215eb886013SMatthias Ringwald for (i = 0; i < 6 ; i++) { 216eb886013SMatthias Ringwald *p++ = char_for_nibble((addr[i] >> 4) & 0x0F); 217eb886013SMatthias Ringwald *p++ = char_for_nibble((addr[i] >> 0) & 0x0F); 218eb886013SMatthias Ringwald *p++ = ':'; 219eb886013SMatthias Ringwald } 220eb886013SMatthias Ringwald *--p = 0; 221eb886013SMatthias Ringwald return (char *) bd_addr_to_str_buffer; 222eb886013SMatthias Ringwald } 223eb886013SMatthias Ringwald 224eb886013SMatthias Ringwald static char link_key_to_str_buffer[LINK_KEY_STR_LEN+1]; // 11223344556677889900112233445566\0 225eb886013SMatthias Ringwald char *link_key_to_str(link_key_t link_key){ 226eb886013SMatthias Ringwald char * p = link_key_to_str_buffer; 227eb886013SMatthias Ringwald int i; 228eb886013SMatthias Ringwald for (i = 0; i < LINK_KEY_LEN ; i++) { 229eb886013SMatthias Ringwald *p++ = char_for_nibble((link_key[i] >> 4) & 0x0F); 230eb886013SMatthias Ringwald *p++ = char_for_nibble((link_key[i] >> 0) & 0x0F); 231eb886013SMatthias Ringwald } 232eb886013SMatthias Ringwald *p = 0; 233eb886013SMatthias Ringwald return (char *) link_key_to_str_buffer; 234eb886013SMatthias Ringwald } 235eb886013SMatthias Ringwald 236eb886013SMatthias Ringwald static char link_key_type_to_str_buffer[2]; 237eb886013SMatthias Ringwald char *link_key_type_to_str(link_key_type_t link_key){ 238eb886013SMatthias Ringwald snprintf(link_key_type_to_str_buffer, sizeof(link_key_type_to_str_buffer), "%d", link_key); 239eb886013SMatthias Ringwald return (char *) link_key_type_to_str_buffer; 240eb886013SMatthias Ringwald } 241eb886013SMatthias Ringwald 242eb886013SMatthias Ringwald void print_bd_addr( bd_addr_t addr){ 243eb886013SMatthias Ringwald log_info("%s", bd_addr_to_str(addr)); 244eb886013SMatthias Ringwald } 245eb886013SMatthias Ringwald 246eb886013SMatthias Ringwald int sscan_bd_addr(uint8_t * addr_string, bd_addr_t addr){ 247eb886013SMatthias Ringwald unsigned int bd_addr_buffer[BD_ADDR_LEN]; //for sscanf, integer needed 248eb886013SMatthias Ringwald // reset result buffer 249eb886013SMatthias Ringwald memset(bd_addr_buffer, 0, sizeof(bd_addr_buffer)); 250eb886013SMatthias Ringwald 251eb886013SMatthias Ringwald // parse 252eb886013SMatthias 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], 253eb886013SMatthias Ringwald &bd_addr_buffer[3], &bd_addr_buffer[4], &bd_addr_buffer[5]); 254eb886013SMatthias Ringwald 255eb886013SMatthias Ringwald if (result != BD_ADDR_LEN) return 0; 256eb886013SMatthias Ringwald 257eb886013SMatthias Ringwald // store 258eb886013SMatthias Ringwald int i; 259eb886013SMatthias Ringwald for (i = 0; i < BD_ADDR_LEN; i++) { 260eb886013SMatthias Ringwald addr[i] = (uint8_t) bd_addr_buffer[i]; 261eb886013SMatthias Ringwald } 262eb886013SMatthias Ringwald return 1; 263eb886013SMatthias Ringwald } 264eb886013SMatthias Ringwald 265eb886013SMatthias Ringwald int sscan_link_key(char * addr_string, link_key_t link_key){ 266eb886013SMatthias Ringwald unsigned int buffer[LINK_KEY_LEN]; 267eb886013SMatthias Ringwald 268eb886013SMatthias Ringwald // reset result buffer 269eb886013SMatthias Ringwald memset(&buffer, 0, sizeof(buffer)); 270eb886013SMatthias Ringwald 271eb886013SMatthias Ringwald // parse 272eb886013SMatthias Ringwald int result = sscanf( (char *) addr_string, "%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x", 273eb886013SMatthias Ringwald &buffer[0], &buffer[1], &buffer[2], &buffer[3], 274eb886013SMatthias Ringwald &buffer[4], &buffer[5], &buffer[6], &buffer[7], 275eb886013SMatthias Ringwald &buffer[8], &buffer[9], &buffer[10], &buffer[11], 276eb886013SMatthias Ringwald &buffer[12], &buffer[13], &buffer[14], &buffer[15] ); 277eb886013SMatthias Ringwald 278eb886013SMatthias Ringwald if (result != LINK_KEY_LEN) return 0; 279eb886013SMatthias Ringwald 280eb886013SMatthias Ringwald // store 281eb886013SMatthias Ringwald int i; 282eb886013SMatthias Ringwald uint8_t *p = (uint8_t *) link_key; 283eb886013SMatthias Ringwald for (i=0; i<LINK_KEY_LEN; i++ ) { 284eb886013SMatthias Ringwald *p++ = (uint8_t) buffer[i]; 285eb886013SMatthias Ringwald } 286eb886013SMatthias Ringwald return 1; 287eb886013SMatthias Ringwald } 288eb886013SMatthias Ringwald 289eb886013SMatthias Ringwald 290eb886013SMatthias Ringwald // treat standard pairing as Authenticated as it uses a PIN 291eb886013SMatthias Ringwald int is_authenticated_link_key(link_key_type_t link_key_type){ 292eb886013SMatthias Ringwald switch (link_key_type){ 293eb886013SMatthias Ringwald case COMBINATION_KEY: 294eb886013SMatthias Ringwald case AUTHENTICATED_COMBINATION_KEY_GENERATED_FROM_P192: 295eb886013SMatthias Ringwald case AUTHENTICATED_COMBINATION_KEY_GENERATED_FROM_P256: 296eb886013SMatthias Ringwald return 1; 297eb886013SMatthias Ringwald default: 298eb886013SMatthias Ringwald return 0; 299eb886013SMatthias Ringwald } 300eb886013SMatthias Ringwald } 301eb886013SMatthias Ringwald 302eb886013SMatthias Ringwald /* 303eb886013SMatthias Ringwald * CRC (reversed crc) lookup table as calculated by the table generator in ETSI TS 101 369 V6.3.0. 304eb886013SMatthias Ringwald */ 305eb886013SMatthias Ringwald static const uint8_t crc8table[256] = { /* reversed, 8-bit, poly=0x07 */ 306eb886013SMatthias Ringwald 0x00, 0x91, 0xE3, 0x72, 0x07, 0x96, 0xE4, 0x75, 0x0E, 0x9F, 0xED, 0x7C, 0x09, 0x98, 0xEA, 0x7B, 307eb886013SMatthias Ringwald 0x1C, 0x8D, 0xFF, 0x6E, 0x1B, 0x8A, 0xF8, 0x69, 0x12, 0x83, 0xF1, 0x60, 0x15, 0x84, 0xF6, 0x67, 308eb886013SMatthias Ringwald 0x38, 0xA9, 0xDB, 0x4A, 0x3F, 0xAE, 0xDC, 0x4D, 0x36, 0xA7, 0xD5, 0x44, 0x31, 0xA0, 0xD2, 0x43, 309eb886013SMatthias Ringwald 0x24, 0xB5, 0xC7, 0x56, 0x23, 0xB2, 0xC0, 0x51, 0x2A, 0xBB, 0xC9, 0x58, 0x2D, 0xBC, 0xCE, 0x5F, 310eb886013SMatthias Ringwald 0x70, 0xE1, 0x93, 0x02, 0x77, 0xE6, 0x94, 0x05, 0x7E, 0xEF, 0x9D, 0x0C, 0x79, 0xE8, 0x9A, 0x0B, 311eb886013SMatthias Ringwald 0x6C, 0xFD, 0x8F, 0x1E, 0x6B, 0xFA, 0x88, 0x19, 0x62, 0xF3, 0x81, 0x10, 0x65, 0xF4, 0x86, 0x17, 312eb886013SMatthias Ringwald 0x48, 0xD9, 0xAB, 0x3A, 0x4F, 0xDE, 0xAC, 0x3D, 0x46, 0xD7, 0xA5, 0x34, 0x41, 0xD0, 0xA2, 0x33, 313eb886013SMatthias Ringwald 0x54, 0xC5, 0xB7, 0x26, 0x53, 0xC2, 0xB0, 0x21, 0x5A, 0xCB, 0xB9, 0x28, 0x5D, 0xCC, 0xBE, 0x2F, 314eb886013SMatthias Ringwald 0xE0, 0x71, 0x03, 0x92, 0xE7, 0x76, 0x04, 0x95, 0xEE, 0x7F, 0x0D, 0x9C, 0xE9, 0x78, 0x0A, 0x9B, 315eb886013SMatthias Ringwald 0xFC, 0x6D, 0x1F, 0x8E, 0xFB, 0x6A, 0x18, 0x89, 0xF2, 0x63, 0x11, 0x80, 0xF5, 0x64, 0x16, 0x87, 316eb886013SMatthias Ringwald 0xD8, 0x49, 0x3B, 0xAA, 0xDF, 0x4E, 0x3C, 0xAD, 0xD6, 0x47, 0x35, 0xA4, 0xD1, 0x40, 0x32, 0xA3, 317eb886013SMatthias Ringwald 0xC4, 0x55, 0x27, 0xB6, 0xC3, 0x52, 0x20, 0xB1, 0xCA, 0x5B, 0x29, 0xB8, 0xCD, 0x5C, 0x2E, 0xBF, 318eb886013SMatthias Ringwald 0x90, 0x01, 0x73, 0xE2, 0x97, 0x06, 0x74, 0xE5, 0x9E, 0x0F, 0x7D, 0xEC, 0x99, 0x08, 0x7A, 0xEB, 319eb886013SMatthias Ringwald 0x8C, 0x1D, 0x6F, 0xFE, 0x8B, 0x1A, 0x68, 0xF9, 0x82, 0x13, 0x61, 0xF0, 0x85, 0x14, 0x66, 0xF7, 320eb886013SMatthias Ringwald 0xA8, 0x39, 0x4B, 0xDA, 0xAF, 0x3E, 0x4C, 0xDD, 0xA6, 0x37, 0x45, 0xD4, 0xA1, 0x30, 0x42, 0xD3, 321eb886013SMatthias Ringwald 0xB4, 0x25, 0x57, 0xC6, 0xB3, 0x22, 0x50, 0xC1, 0xBA, 0x2B, 0x59, 0xC8, 0xBD, 0x2C, 0x5E, 0xCF 322eb886013SMatthias Ringwald }; 323eb886013SMatthias Ringwald 324eb886013SMatthias Ringwald #define CRC8_INIT 0xFF // Initial FCS value 325eb886013SMatthias Ringwald #define CRC8_OK 0xCF // Good final FCS value 326eb886013SMatthias Ringwald /*-----------------------------------------------------------------------------------*/ 327eb886013SMatthias Ringwald static uint8_t crc8(uint8_t *data, uint16_t len) 328eb886013SMatthias Ringwald { 329eb886013SMatthias Ringwald uint16_t count; 330eb886013SMatthias Ringwald uint8_t crc = CRC8_INIT; 331eb886013SMatthias Ringwald for (count = 0; count < len; count++) 332eb886013SMatthias Ringwald crc = crc8table[crc ^ data[count]]; 333eb886013SMatthias Ringwald return crc; 334eb886013SMatthias Ringwald } 335eb886013SMatthias Ringwald 336eb886013SMatthias Ringwald /*-----------------------------------------------------------------------------------*/ 337eb886013SMatthias Ringwald uint8_t crc8_check(uint8_t *data, uint16_t len, uint8_t check_sum) 338eb886013SMatthias Ringwald { 339eb886013SMatthias Ringwald uint8_t crc; 340eb886013SMatthias Ringwald 341eb886013SMatthias Ringwald crc = crc8(data, len); 342eb886013SMatthias Ringwald 343eb886013SMatthias Ringwald crc = crc8table[crc ^ check_sum]; 344eb886013SMatthias Ringwald if (crc == CRC8_OK) 345eb886013SMatthias Ringwald return 0; /* Valid */ 346eb886013SMatthias Ringwald else 347eb886013SMatthias Ringwald return 1; /* Failed */ 348eb886013SMatthias Ringwald 349eb886013SMatthias Ringwald } 350eb886013SMatthias Ringwald 351eb886013SMatthias Ringwald /*-----------------------------------------------------------------------------------*/ 352eb886013SMatthias Ringwald uint8_t crc8_calc(uint8_t *data, uint16_t len) 353eb886013SMatthias Ringwald { 354eb886013SMatthias Ringwald /* Ones complement */ 355eb886013SMatthias Ringwald return 0xFF - crc8(data, len); 356eb886013SMatthias Ringwald } 357eb886013SMatthias Ringwald 358