Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add macro to convert bits to bytes (CSE of rounding idiom) #2378

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions include/bitbuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@

#include <stdint.h>

// Round up (NUM_BITS / 8)
#define NUM_BYTES(NUM_BITS) (((NUM_BITS) + 7) >> 3)

// NOTE: Wireless mbus protocol needs at least ((256+16*2+3)*12)/8 => 437 bytes
// which fits even if RTL_433_REDUCE_STACK_USE is defined because of row spilling
#ifdef RTL_433_REDUCE_STACK_USE
Expand Down
16 changes: 8 additions & 8 deletions src/bitbuffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,8 @@ static void bitbuffer_set_width(bitbuffer_t *bits, uint16_t width)
// clear bits when truncating
if (bits->bits_per_row[bits->num_rows - 1] > width) {
uint8_t *b = bits->bb[bits->num_rows - 1];
unsigned clr_from = (width + 7) / 8;
unsigned clr_end = (bits->bits_per_row[bits->num_rows - 1] + 7) / 8;
unsigned clr_from = NUM_BYTES(width);
unsigned clr_end = NUM_BYTES(bits->bits_per_row[bits->num_rows - 1]);
memset(&b[clr_from], 0, clr_end - clr_from);

// note that width became strictly smaller, that way we don't overflow
Expand Down Expand Up @@ -191,11 +191,11 @@ void bitbuffer_extract_bytes(bitbuffer_t *bitbuffer, unsigned row,
if (len == 0)
return;
if ((pos & 7) == 0) {
memcpy(out, bits + (pos / 8), (len + 7) / 8);
memcpy(out, bits + (pos / 8), NUM_BYTES(len));
}
else {
unsigned shift = 8 - (pos & 7);
unsigned bytes = (len + 7) >> 3;
unsigned bytes = NUM_BYTES(len);
uint8_t *p = out;
uint16_t word;
pos = pos >> 3; // Convert to bytes
Expand Down Expand Up @@ -325,7 +325,7 @@ static void print_bitrow(uint8_t const *bitrow, unsigned bit_len, unsigned highe
unsigned row_len = 0;

fprintf(stderr, "{%2u} ", bit_len);
for (unsigned col = 0; col < (bit_len + 7) / 8; ++col) {
for (unsigned col = 0; col < NUM_BYTES(bit_len); ++col) {
row_len += fprintf(stderr, "%02x ", bitrow[col]);
}
// Print binary values also?
Expand Down Expand Up @@ -354,7 +354,7 @@ static void print_bitbuffer(const bitbuffer_t *bits, int always_binary)
*/
highest_indent = sizeof("[dd] {dd} ") - 1;
for (row = indent_this_row = 0; row < bits->num_rows; ++row) {
for (col = indent_this_col = 0; col < (unsigned)(bits->bits_per_row[row] + 7) / 8; ++col) {
for (col = indent_this_col = 0; col < (unsigned)NUM_BYTES(bits->bits_per_row[row]); ++col) {
indent_this_col += 2 + 1;
}
indent_this_row = indent_this_col;
Expand Down Expand Up @@ -398,7 +398,7 @@ int bitrow_snprint(uint8_t const *bitrow, unsigned bit_len, char *str, unsigned
str[0] = '\0';
}
int len = 0;
for (unsigned i = 0; size > (unsigned)len && i < (bit_len + 7) / 8; ++i) {
for (unsigned i = 0; size > (unsigned)len && i < NUM_BYTES(bit_len); ++i) {
len += snprintf(str + len, size - len, "%02x", bitrow[i]);
}
return len;
Expand Down Expand Up @@ -474,7 +474,7 @@ int bitbuffer_compare_rows(bitbuffer_t *bits, unsigned row_a, unsigned row_b, un
// full compare, no max_bits or rows too short
return (bits->bits_per_row[row_a] == bits->bits_per_row[row_b]
&& !memcmp(bits->bb[row_a], bits->bb[row_b],
(bits->bits_per_row[row_a] + 7) / 8));
NUM_BYTES(bits->bits_per_row[row_a])));
}
else {
// prefix-only compare, both rows are at least max_bits long
Expand Down
2 changes: 1 addition & 1 deletion src/decoder_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ static char *bitrow_asprint_code(uint8_t const *bitrow, unsigned bit_len)

row_bytes[0] = '\0';
// print byte-wide
for (unsigned col = 0; col < (unsigned)(bit_len + 7) / 8; ++col) {
for (unsigned col = 0; col < NUM_BYTES(bit_len); ++col) {
sprintf(&row_bytes[2 * col], "%02x", bitrow[col]);
}
// remove last nibble if needed
Expand Down
4 changes: 2 additions & 2 deletions src/devices/acurite.c
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,7 @@ static int acurite_6045_decode(r_device *decoder, bitbuffer_t *bitbuffer, unsign
int exception = 0;
data_t *data;

int browlen = (bitbuffer->bits_per_row[row] + 7) / 8;
int browlen = NUM_BYTES(bitbuffer->bits_per_row[row]);
uint8_t *bb = bitbuffer->bb[row];

char const *channel_str = acurite_getChannel(bb[0]); // same as TXR
Expand Down Expand Up @@ -798,7 +798,7 @@ static int acurite_atlas_decode(r_device *decoder, bitbuffer_t *bitbuffer, unsig
float tempf, wind_dir, wind_speed_mph;
data_t *data;

int browlen = (bitbuffer->bits_per_row[row] + 7) / 8;
int browlen = NUM_BYTES(bitbuffer->bits_per_row[row]);
uint8_t *bb = bitbuffer->bb[row];

message_type = bb[2] & 0x3f;
Expand Down
2 changes: 1 addition & 1 deletion src/devices/bresser_5in1.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ static int bresser_5in1_decode(r_device *decoder, bitbuffer_t *bitbuffer)
}
start_pos += sizeof (preamble_pattern) * 8;
len = bitbuffer->bits_per_row[0] - start_pos;
if (((len + 7) / 8) < sizeof (msg)) {
if (NUM_BYTES(len) < sizeof (msg)) {
decoder_logf(decoder, 2, __func__, "%u too short", len);
return DECODE_ABORT_LENGTH; // message too short
}
Expand Down
2 changes: 1 addition & 1 deletion src/devices/cmr113.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ Kudos to Jon Oxer for decoding this stream and putting it here:
*/

#define COMPARE_BITS 83
#define COMPARE_BYTES ((COMPARE_BITS + 7) / 8)
#define COMPARE_BYTES NUM_BYTES(COMPARE_BITS)

static int cmr113_decode(r_device *decoder, bitbuffer_t *bitbuffer)
{
Expand Down
10 changes: 5 additions & 5 deletions src/devices/danfoss.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ Nibble content:

#include "decoder.h"

#define NUM_BYTES 10 // Output contains 21 nibbles, but skip first nibble 0xE, as it is not part of CRC and to get byte alignment
#define DANFOSS_NUM_BYTES 10 // Output contains 21 nibbles, but skip first nibble 0xE, as it is not part of CRC and to get byte alignment
static const uint8_t HEADER[] = { 0x36, 0x5c }; // Encoded prefix. Full prefix is 3 nibbles => 18 bits (but checking 16 is ok)

// Mapping from 6 bits to 4 bits
Expand Down Expand Up @@ -78,7 +78,7 @@ static uint8_t danfoss_decode_nibble(uint8_t byte)

static int danfoss_cfr_callback(r_device *decoder, bitbuffer_t *bitbuffer)
{
uint8_t bytes[NUM_BYTES]; // Decoded bytes with two 4 bit nibbles in each
uint8_t bytes[DANFOSS_NUM_BYTES]; // Decoded bytes with two 4 bit nibbles in each
data_t *data;

// Validate package
Expand All @@ -93,7 +93,7 @@ static int danfoss_cfr_callback(r_device *decoder, bitbuffer_t *bitbuffer)
bit_offset += 6; // Skip first nibble 0xE to get byte alignment and remove from CRC calculation

// Decode input 6 bit nibbles to output 4 bit nibbles (packed in bytes)
for (unsigned n = 0; n < NUM_BYTES; ++n) {
for (unsigned n = 0; n < DANFOSS_NUM_BYTES; ++n) {
uint8_t nibble_h = danfoss_decode_nibble(bitrow_get_byte(bitbuffer->bb[0], n * 12 + bit_offset) >> 2);
uint8_t nibble_l = danfoss_decode_nibble(bitrow_get_byte(bitbuffer->bb[0], n * 12 + bit_offset + 6) >> 2);
if (nibble_h > 0xF || nibble_l > 0xF) {
Expand All @@ -104,10 +104,10 @@ static int danfoss_cfr_callback(r_device *decoder, bitbuffer_t *bitbuffer)
}

// Output raw decoded data for debug
decoder_log_bitrow(decoder, 1, __func__, bytes, NUM_BYTES * 8, "Danfoss: Raw 6b/4b decoded");
decoder_log_bitrow(decoder, 1, __func__, bytes, DANFOSS_NUM_BYTES * 8, "Danfoss: Raw 6b/4b decoded");

// Validate Prefix and CRC
uint16_t crc_calc = crc16(bytes, NUM_BYTES-2, 0x1021, 0x0000);
uint16_t crc_calc = crc16(bytes, DANFOSS_NUM_BYTES-2, 0x1021, 0x0000);
if (bytes[0] != 0x02 // Somewhat redundant to header search, but checks last bits
|| crc_calc != (((uint16_t)bytes[8] << 8) | bytes[9])
) {
Expand Down
2 changes: 1 addition & 1 deletion src/devices/digitech_xc0324.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ running this decoder with debug level :

//#define XC0324_DEVICE_BITLEN 148
#define XC0324_MESSAGE_BITLEN 48
#define XC0324_MESSAGE_BYTELEN (XC0324_MESSAGE_BITLEN + 7)/ 8
#define XC0324_MESSAGE_BYTELEN NUM_BYTES(XC0324_MESSAGE_BITLEN)
//#define XC0324_DEVICE_MINREPEATS 3

static int decode_xc0324_message(r_device *decoder, bitbuffer_t *bitbuffer,
Expand Down
2 changes: 1 addition & 1 deletion src/devices/efergy_e2_classic.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ static int efergy_e2_classic_callback(r_device *decoder, bitbuffer_t *bitbuffer)
return DECODE_FAIL_SANITY;
}

for (unsigned i = 0; i < (num_bits + 7) / 8; ++i) {
for (unsigned i = 0; i < NUM_BYTES(num_bits); ++i) {
bytes[i] <<= 1;
bytes[i] |= (bytes[i + 1] & 0x80) >> 7;
}
Expand Down
2 changes: 1 addition & 1 deletion src/devices/efergy_optical.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ static int efergy_optical_callback(r_device *decoder, bitbuffer_t *bitbuffer)
if (num_bits < 96)
return DECODE_ABORT_EARLY;

for (unsigned i = 0; i < (num_bits + 7) / 8; ++i) {
for (unsigned i = 0; i < NUM_BYTES(num_bits); ++i) {
bytes[i] <<= 1;
bytes[i] |= (bytes[i + 1] & 0x80) >> 7;
}
Expand Down
12 changes: 6 additions & 6 deletions src/devices/flex.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ static unsigned long extract_number(uint8_t *data, unsigned bit_offset, unsigned
{
unsigned pos = bit_offset / 8; // the first byte we need
unsigned shl = bit_offset - pos * 8; // shift left we need to align
unsigned len = (shl + bit_count + 7) / 8; // number of bytes we need
unsigned len = NUM_BYTES(shl + bit_count); // number of bytes we need
unsigned shr = 8 * len - shl - bit_count; // actual shift right
// fprintf(stderr, "pos: %d, shl: %d, len: %d, shr: %d\n", pos, shl, len, shr);
unsigned long val = data[pos];
Expand Down Expand Up @@ -105,7 +105,7 @@ static void print_row_bytes(char *row_bytes, uint8_t *bits, int num_bits)
{
row_bytes[0] = '\0';
// print byte-wide
for (int col = 0; col < (num_bits + 7) / 8; ++col) {
for (int col = 0; col < NUM_BYTES(num_bits); ++col) {
sprintf(&row_bytes[2 * col], "%02x", bits[col]);
}
// remove last nibble if needed
Expand Down Expand Up @@ -186,7 +186,7 @@ static int flex_callback(r_device *decoder, bitbuffer_t *bitbuffer)
if (params->reflect) {
// TODO: refactor to utils
for (i = 0; i < bitbuffer->num_rows; ++i) {
reflect_bytes(bitbuffer->bb[i], (bitbuffer->bits_per_row[i] + 7) / 8);
reflect_bytes(bitbuffer->bb[i], NUM_BYTES(bitbuffer->bits_per_row[i]));
}
}

Expand Down Expand Up @@ -220,7 +220,7 @@ static int flex_callback(r_device *decoder, bitbuffer_t *bitbuffer)
unsigned len = bitbuffer->bits_per_row[i] - pos;
bitbuffer_t tmp = {0};
bitbuffer_extract_bytes(bitbuffer, i, pos, tmp.bb[0], len);
memcpy(bitbuffer->bb[i], tmp.bb[0], (len + 7) / 8);
memcpy(bitbuffer->bb[i], tmp.bb[0], NUM_BYTES(len));
bitbuffer->bits_per_row[i] = len;
}
}
Expand Down Expand Up @@ -262,7 +262,7 @@ static int flex_callback(r_device *decoder, bitbuffer_t *bitbuffer)
bitbuffer_t tmp = {0};
bitbuffer_differential_manchester_decode(bitbuffer, i, 0, &tmp, len);
len = tmp.bits_per_row[0];
memcpy(bitbuffer->bb[i], tmp.bb[0], (len + 7) / 8); // safe to write over: can only be shorter
memcpy(bitbuffer->bb[i], tmp.bb[0], NUM_BYTES(len)); // safe to write over: can only be shorter
bitbuffer->bits_per_row[i] = len;
}
}
Expand Down Expand Up @@ -473,7 +473,7 @@ static unsigned parse_bits(const char *code, uint8_t *bitrow)
fprintf(stderr, "Bad flex spec, \"match\", \"preamble\", and getter mask may have up to 1024 bits (%u found)!\n", len);
usage();
}
memcpy(bitrow, bits.bb[0], (len + 7) / 8);
memcpy(bitrow, bits.bb[0], NUM_BYTES(len));
return len;
}

Expand Down
2 changes: 1 addition & 1 deletion src/devices/ft004b.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ static int ft004b_callback(r_device *decoder, bitbuffer_t *bitbuffer)

/* take the majority of all 46 bits (pattern is sent 3 times) and reverse them */
msg = bitbuffer->bb[0];
for (int i = 0; i < (46 + 7) / 8; i++) {
for (int i = 0; i < NUM_BYTES(46); i++) {
uint8_t a = bitrow_get_byte(msg, i * 8);
uint8_t b = bitrow_get_byte(msg, i * 8 + 46);
uint8_t c = bitrow_get_byte(msg, i * 8 + 46 * 2);
Expand Down
2 changes: 1 addition & 1 deletion src/devices/honeywell_cm921.c
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ static int parse_msg(bitbuffer_t *bmsg, int row, message_t *msg)
if (ipos < num_bits - 8)
{
unsigned num_unparsed_bits = (bmsg->bits_per_row[row] - 8) - ipos;
msg->unparsed_length = (num_unparsed_bits / 8) + (num_unparsed_bits % 8) ? 1 : 0;
msg->unparsed_length = NUM_BYTES(num_unparsed_bits);
if (msg->unparsed_length != 0)
bitbuffer_extract_bytes(bmsg, row, ipos, msg->unparsed, num_unparsed_bits);
}
Expand Down
2 changes: 1 addition & 1 deletion src/devices/ikea_sparsnas.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ detail. Many thanks to kodarn!

#include "decoder.h"
#define IKEA_SPARSNAS_MESSAGE_BITLEN 160 // 20 bytes incl 8 bit length, 8 bit address, 128 bits data, and 16 bits of CRC. Excluding preamble and sync word
#define IKEA_SPARSNAS_MESSAGE_BYTELEN ((IKEA_SPARSNAS_MESSAGE_BITLEN + 7) / 8)
#define IKEA_SPARSNAS_MESSAGE_BYTELEN NUM_BYTES(IKEA_SPARSNAS_MESSAGE_BITLEN)
#define IKEA_SPARSNAS_MESSAGE_BITLEN_MAX 260 // Just for early sanity checks

#define IKEA_SPARSNAS_PREAMBLE_BITLEN 32
Expand Down
2 changes: 1 addition & 1 deletion src/devices/inkbird_ith20r.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ static int inkbird_ith20r_callback(r_device *decoder, bitbuffer_t *bitbuffer)

decoder_logf(decoder, 2, __func__, "start_pos=%u len=%u", start_pos, len);

if (((len + 7) / 8) < sizeof (msg)) {
if (NUM_BYTES(len) < sizeof (msg)) {
decoder_logf(decoder, 1, __func__, "%u too short", len);
return DECODE_ABORT_LENGTH; // Message too short
}
Expand Down
2 changes: 1 addition & 1 deletion src/devices/interlogix.c
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ static int interlogix_decode(r_device *decoder, bitbuffer_t *bitbuffer)
// set message starting position (just past preamble and sync bit)
bit_offset += (sizeof preamble_pattern) * 8;

uint8_t message[(INTERLOGIX_MSG_BIT_LEN + 7) / 8];
uint8_t message[NUM_BYTES(INTERLOGIX_MSG_BIT_LEN)];

bitbuffer_extract_bytes(bitbuffer, row, bit_offset, message, INTERLOGIX_MSG_BIT_LEN);

Expand Down
2 changes: 1 addition & 1 deletion src/devices/oregon_scientific.c
Original file line number Diff line number Diff line change
Expand Up @@ -637,7 +637,7 @@ static int oregon_scientific_v3_decode(r_device *decoder, bitbuffer_t *bitbuffer
return DECODE_ABORT_EARLY;

bitbuffer_extract_bytes(bitbuffer, 0, msg_pos, msg, msg_len);
reflect_nibbles(msg, (msg_len + 7) / 8);
reflect_nibbles(msg, NUM_BYTES(msg_len));

int sensor_id = (msg[0] << 8) | msg[1]; // not for CM sensor types
int channel = (msg[2] >> 4) & 0x0f; // not for CM sensor types
Expand Down
2 changes: 1 addition & 1 deletion src/devices/tpms_tyreguard400.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ Flex decoder:

static int tpms_tyreguard400_decode(r_device *decoder, bitbuffer_t *bitbuffer, unsigned row, unsigned bitpos)
{
uint8_t b[(TPMS_TYREGUARD400_MESSAGE_BITLEN + 7) / 8];
uint8_t b[NUM_BYTES(TPMS_TYREGUARD400_MESSAGE_BITLEN)];

// Extract the message
bitbuffer_extract_bytes(bitbuffer, row, bitpos, b, TPMS_TYREGUARD400_MESSAGE_BITLEN);
Expand Down
Loading