# HG changeset patch # User Mychaela Falconia # Date 1719221308 0 # Node ID bacc590ec839f864298e02ed63a6937dbedc0acc # Parent 2ee910aa03c3b6dce6407f9ee1254ab7ebd92949 ater: implement EFR CRC inversion option diff -r 2ee910aa03c3 -r bacc590ec839 ater/out_frame.c --- a/ater/out_frame.c Mon Jun 24 09:20:54 2024 +0000 +++ b/ater/out_frame.c Mon Jun 24 09:28:28 2024 +0000 @@ -99,10 +99,18 @@ } } +static void invert_crc3(ubit_t *crc) +{ + crc[0] = !crc[0]; + crc[1] = !crc[1]; + crc[2] = !crc[2]; +} + static void fill_data_efr(const uint8_t *data, struct osmo_trau_frame *tf) { int i, j; ubit_t check_bits[26]; + uint8_t crc_inv; /* reassemble d-bits */ tf->d_bits[0] = 1; @@ -131,6 +139,19 @@ efr_parity_bits_5(check_bits, tf->d_bits); osmo_crc8gen_set_bits(&gsm0860_efr_crc3, check_bits, 8, tf->d_bits + 257); + + /* inverted CRC option */ + crc_inv = data[31]; + if (crc_inv & 0x80) + invert_crc3(tf->d_bits + 39); + if (crc_inv & 0x40) + invert_crc3(tf->d_bits + 95); + if (crc_inv & 0x20) + invert_crc3(tf->d_bits + 148); + if (crc_inv & 0x10) + invert_crc3(tf->d_bits + 204); + if (crc_inv & 0x08) + invert_crc3(tf->d_bits + 257); } void trau_frame_from_record(const uint8_t *rec, bool is_efr,