Add more byte operation util functions

This commit is contained in:
Christian W. Zuckschwerdt 2018-12-12 13:34:47 +01:00
parent 1f550118fb
commit 8d1439da5a
5 changed files with 82 additions and 22 deletions

View file

@ -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

View file

@ -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");
}

View file

@ -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

View file

@ -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) {

View file

@ -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