Add more byte operation util functions
This commit is contained in:
parent
1f550118fb
commit
8d1439da5a
5 changed files with 82 additions and 22 deletions
|
@ -29,11 +29,18 @@
|
|||
#define min(a,b) ((a) < (b) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
/// Reverse the bits in an 8 bit byte
|
||||
/// Reverse (reflect) the bits in an 8 bit byte.
|
||||
///
|
||||
/// @param x: input byte
|
||||
/// @return bit reversed byte
|
||||
uint8_t reverse8(uint8_t x);
|
||||
|
||||
/// Reflect (reverse LSB to MSB) each byte of a number of bytes.
|
||||
///
|
||||
/// @param message bytes of message data
|
||||
/// @param num_bytes number of bytes to reflect
|
||||
void reflect_bytes(uint8_t message[], unsigned num_bytes);
|
||||
|
||||
/// CRC-4
|
||||
///
|
||||
/// @param message[]: array of bytes to check
|
||||
|
@ -94,7 +101,8 @@ uint16_t crc16lsb(uint8_t const message[], unsigned nBytes, uint16_t polynomial,
|
|||
/// @return CRC value
|
||||
uint16_t crc16(uint8_t const message[], unsigned nBytes, uint16_t polynomial, uint16_t init);
|
||||
|
||||
/// Digest-8 by "LFSR-based Toeplitz hash"
|
||||
/// Digest-8 by "LFSR-based Toeplitz hash".
|
||||
///
|
||||
/// @param message bytes of message data
|
||||
/// @param bytes number of bytes to digest
|
||||
/// @param gen key stream generator, needs to includes the MSB if the LFSR is rolling
|
||||
|
@ -102,7 +110,8 @@ uint16_t crc16(uint8_t const message[], unsigned nBytes, uint16_t polynomial, ui
|
|||
/// @return digest value
|
||||
uint8_t lfsr_digest8(uint8_t const message[], unsigned bytes, uint8_t gen, uint8_t key);
|
||||
|
||||
/// Digest-16 by "LFSR-based Toeplitz hash"
|
||||
/// Digest-16 by "LFSR-based Toeplitz hash".
|
||||
///
|
||||
/// @param data up to 32 bits data, LSB aligned
|
||||
/// @param bits number of bits to digest
|
||||
/// @param gen key stream generator, needs to includes the MSB if the LFSR is rolling
|
||||
|
@ -110,11 +119,32 @@ uint8_t lfsr_digest8(uint8_t const message[], unsigned bytes, uint8_t gen, uint8
|
|||
/// @return digest value
|
||||
uint16_t lfsr_digest16(uint32_t data, int bits, uint16_t gen, uint16_t key);
|
||||
|
||||
/// compute bit parity of a single byte
|
||||
/// Compute bit parity of a single byte (8 bits).
|
||||
///
|
||||
/// @param inByte: single byte to check
|
||||
/// @param byte: single byte to check
|
||||
/// @return 1 odd parity, 0 even parity
|
||||
int byteParity(uint8_t inByte);
|
||||
int parity8(uint8_t byte);
|
||||
|
||||
/// Compute bit parity of a number of bytes.
|
||||
///
|
||||
/// @param message bytes of message data
|
||||
/// @param num_bytes number of bytes to sum
|
||||
/// @return 1 odd parity, 0 even parity
|
||||
int parity_bytes(uint8_t const message[], unsigned num_bytes);
|
||||
|
||||
/// Compute XOR (byte-wide parity) of a number of bytes.
|
||||
///
|
||||
/// @param message bytes of message data
|
||||
/// @param num_bytes number of bytes to sum
|
||||
/// @return summation value, per bit-position 1 odd parity, 0 even parity
|
||||
uint8_t xor_bytes(uint8_t const message[], unsigned num_bytes);
|
||||
|
||||
/// Compute Addition of a number of bytes.
|
||||
///
|
||||
/// @param message bytes of message data
|
||||
/// @param num_bytes number of bytes to sum
|
||||
/// @return summation value
|
||||
int add_bytes(uint8_t const message[], unsigned num_bytes);
|
||||
|
||||
// buffer to hold localized timestamp "YYYY-MM-DD HH:MM:SS.000000"
|
||||
#define LOCAL_TIME_BUFLEN 32
|
||||
|
|
|
@ -524,7 +524,7 @@ static int acurite_6045_decode(r_device *decoder, bitrow_t bb, int browlen)
|
|||
sensor_id, channel, message_type, tempf, humidity, strike_count, strike_distance, l_status);
|
||||
for (int i=0; i < browlen; i++) {
|
||||
char pc;
|
||||
pc = byteParity(bb[i]) == 0 ? ' ' : '*';
|
||||
pc = parity8(bb[i]) == 0 ? ' ' : '*';
|
||||
fprintf(stdout, " %02x%c", bb[i], pc);
|
||||
}
|
||||
printf("\n");
|
||||
|
@ -617,7 +617,7 @@ static int acurite_txr_callback(r_device *decoder, bitbuffer_t *bitbuf)
|
|||
if (decoder->verbose) {
|
||||
fprintf(stderr, "acurite_txr Parity: ");
|
||||
for (uint8_t i = 0; i < browlen; i++) {
|
||||
fprintf(stderr,"%d",byteParity(bb[i]));
|
||||
fprintf(stderr, "%d", parity8(bb[i]));
|
||||
}
|
||||
fprintf(stderr,"\n");
|
||||
}
|
||||
|
|
|
@ -61,7 +61,7 @@ static int hideki_ts04_callback(r_device *decoder, bitbuffer_t *bitbuffer) {
|
|||
packet[i] = (b[i+offset] << (i%8)) | (b[i+offset+1] >> (8 - i%8));
|
||||
// check parity
|
||||
uint8_t parity = (b[i+offset+1] >> (7 - i%8)) & 1;
|
||||
if (parity != byteParity(packet[i])) {
|
||||
if (parity != parity8(packet[i])) {
|
||||
if (decoder->verbose)
|
||||
fprintf(stderr, "%s: Parity error at %d\n", __func__, i);
|
||||
return 0;
|
||||
|
@ -69,10 +69,7 @@ static int hideki_ts04_callback(r_device *decoder, bitbuffer_t *bitbuffer) {
|
|||
}
|
||||
|
||||
// XOR check all bytes
|
||||
chk = 0;
|
||||
for (int i = 1; i < unstuffed_len - 1; ++i) {
|
||||
chk ^= packet[i];
|
||||
}
|
||||
chk = xor_bytes(&packet[1], unstuffed_len - 2);
|
||||
if (chk) {
|
||||
if (decoder->verbose)
|
||||
fprintf(stderr, "%s: XOR error\n", __func__);
|
||||
|
@ -87,8 +84,7 @@ static int hideki_ts04_callback(r_device *decoder, bitbuffer_t *bitbuffer) {
|
|||
}
|
||||
|
||||
// Reflect LSB first to LSB last
|
||||
for (int i = 0; i < unstuffed_len; ++i)
|
||||
packet[i] = reverse8(packet[i]);
|
||||
reflect_bytes(packet, unstuffed_len);
|
||||
|
||||
// Parse data
|
||||
if (packet[0] != 0x9f) // NOTE: other valid ids might exist
|
||||
|
|
|
@ -57,8 +57,8 @@ static int honeywell_wdb_callback(r_device *decoder, bitbuffer_t *bitbuffer) {
|
|||
|
||||
bitbuffer_invert(bitbuffer);
|
||||
|
||||
/* Pairity check (must be EVEN) */
|
||||
parity = byteParity(bytes[0]) ^ byteParity(bytes[1]) ^ byteParity(bytes[2]) ^ byteParity(bytes[3]) ^ byteParity(bytes[4]) ^ byteParity(bytes[5]);
|
||||
/* Parity check (must be EVEN) */
|
||||
parity = parity_bytes(bytes, 6);
|
||||
|
||||
if (parity) { // ODD parity detected
|
||||
if (decoder->verbose > 1) {
|
||||
|
|
44
src/util.c
44
src/util.c
|
@ -21,6 +21,13 @@ uint8_t reverse8(uint8_t x)
|
|||
return x;
|
||||
}
|
||||
|
||||
void reflect_bytes(uint8_t message[], unsigned num_bytes)
|
||||
{
|
||||
for (unsigned i = 0; i < num_bytes; ++i) {
|
||||
message[i] = reverse8(message[i]);
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t crc4(uint8_t const message[], unsigned nBytes, uint8_t polynomial, uint8_t init)
|
||||
{
|
||||
unsigned remainder = init << 4; // LSBs are unused
|
||||
|
@ -205,12 +212,39 @@ void lfsr_keys_rwd16(int rounds, uint16_t gen, uint16_t key)
|
|||
}
|
||||
*/
|
||||
|
||||
|
||||
int byteParity(uint8_t inByte)
|
||||
// we could use popcount intrinsic, but don't actually need the performance
|
||||
int parity8(uint8_t byte)
|
||||
{
|
||||
inByte ^= inByte >> 4;
|
||||
inByte &= 0xf;
|
||||
return (0x6996 >> inByte) & 1;
|
||||
byte ^= byte >> 4;
|
||||
byte &= 0xf;
|
||||
return (0x6996 >> byte) & 1;
|
||||
}
|
||||
|
||||
int parity_bytes(uint8_t const message[], unsigned num_bytes)
|
||||
{
|
||||
int result = 0;
|
||||
for (unsigned i = 0; i < num_bytes; ++i) {
|
||||
result ^= parity8(message[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
uint8_t xor_bytes(uint8_t const message[], unsigned num_bytes)
|
||||
{
|
||||
uint8_t result = 0;
|
||||
for (unsigned i = 0; i < num_bytes; ++i) {
|
||||
result ^= message[i];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int add_bytes(uint8_t const message[], unsigned num_bytes)
|
||||
{
|
||||
int result = 0;
|
||||
for (unsigned i = 0; i < num_bytes; ++i) {
|
||||
result += message[i];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#if _WIN32
|
||||
|
|
Loading…
Add table
Reference in a new issue