diff options
author | Marcel Holtmann <marcel@holtmann.org> | 2013-08-21 23:04:59 -0700 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2013-08-21 23:04:59 -0700 |
commit | 6915f9bf888b6836b91b6fff13e4c5483de56973 (patch) | |
tree | fa981ccd26a1072ce97cbb02007356fb13ec37d8 /monitor/crc.c | |
parent | 6e8cf9a16787fd237319ca67a7f3e6ee3a850894 (diff) | |
download | bluez-6915f9bf888b6836b91b6fff13e4c5483de56973.tar.gz |
monitor: Add functions for link layer CRC calculations
Diffstat (limited to 'monitor/crc.c')
-rw-r--r-- | monitor/crc.c | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/monitor/crc.c b/monitor/crc.c new file mode 100644 index 000000000..9ea11fbf4 --- /dev/null +++ b/monitor/crc.c @@ -0,0 +1,84 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2011-2012 Intel Corporation + * Copyright (C) 2004-2010 Marcel Holtmann <marcel@holtmann.org> + * + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "crc.h" + +uint32_t crc24_bit_reverse(uint32_t value) +{ + uint32_t result = 0; + uint8_t i; + + for (i = 0; i < 24; i++) + result |= ((value >> i) & 1) << (23 - i); + + return result; +} + +uint32_t crc24_calculate(uint32_t preset, const uint8_t *data, uint8_t len) +{ + uint32_t state = preset; + uint8_t i; + + for (i = 0; i < len; i++) { + uint8_t n, cur = data[i]; + + for (n = 0; n < 8; n++) { + int next_bit = (state ^ cur) & 1; + + cur >>= 1; + state >>= 1; + if (next_bit) { + state |= 1 << 23; + state ^= 0x5a6000; + } + } + } + + return state; +} + +uint32_t crc24_reverse(uint32_t crc, const uint8_t *data, uint8_t len) +{ + uint32_t state = crc; + uint8_t i; + + for (i = 0; i < len; i++) { + uint8_t n, cur = data[len - i - 1]; + + for (n = 0; n < 8; n++) { + int top_bit = state >> 23; + + state = (state << 1) & 0xffffff; + state |= top_bit ^ ((cur >> (7 - n)) & 1); + if (top_bit) + state ^= 0xb4c000; + } + } + + return state; +} |