diff options
author | Harald Welte <laforge@osmocom.org> | 2020-08-02 21:54:30 +0200 |
---|---|---|
committer | Harald Welte <laforge@osmocom.org> | 2020-08-02 21:57:05 +0200 |
commit | 44964981c29d2251a5fed88ca4f87d0732826dfc (patch) | |
tree | a11a7c755975f506f1b048990d0d1b3fee999775 /src/gsm | |
parent | b3b474d8ade2c28ab8b0e3021dea87fae19b333c (diff) |
i460: Fix bit- and subslots ordering of I.460 mux + demux
When I wrote the new I.460 mux + demux code, I failed to realize that
* bit numbers in relevant ITU specs start with 1 as MSB ... 8 as LSB
* sub-slot 0 is bits 1+2, i.e. the two MSBs of a byte
* bit-ordering within each sub-slot is also MSB first
As a result, the code and test data was broken.
Change-Id: I6df7dbf411efbdeaf516e72ac552432bf5a569d0
Diffstat (limited to 'src/gsm')
-rw-r--r-- | src/gsm/i460_mux.c | 59 |
1 files changed, 32 insertions, 27 deletions
diff --git a/src/gsm/i460_mux.c b/src/gsm/i460_mux.c index 320e781b..91ab2a19 100644 --- a/src/gsm/i460_mux.c +++ b/src/gsm/i460_mux.c @@ -89,32 +89,34 @@ static void demux_subchan_extract_bits(struct osmo_i460_subchan *schan, const ui for (i = 0; i < data_len; i++) { uint8_t inbyte = data[i]; - uint8_t inbits = inbyte >> schan->bit_offset; + /* I.460 defines sub-channel 0 is using bit positions 1+2 (the two + * most significant bits, hence we extract msb-first */ + uint8_t inbits = inbyte << schan->bit_offset; /* extract the bits relevant to the given schan */ switch (schan->rate) { case OSMO_I460_RATE_8k: - demux_subchan_append_bit(schan, inbits & 0x01); + demux_subchan_append_bit(schan, inbits & 0x80); break; case OSMO_I460_RATE_16k: - demux_subchan_append_bit(schan, inbits & 0x01); - demux_subchan_append_bit(schan, inbits & 0x02); + demux_subchan_append_bit(schan, inbits & 0x80); + demux_subchan_append_bit(schan, inbits & 0x40); break; case OSMO_I460_RATE_32k: - demux_subchan_append_bit(schan, inbits & 0x01); - demux_subchan_append_bit(schan, inbits & 0x02); - demux_subchan_append_bit(schan, inbits & 0x04); - demux_subchan_append_bit(schan, inbits & 0x08); + demux_subchan_append_bit(schan, inbits & 0x80); + demux_subchan_append_bit(schan, inbits & 0x40); + demux_subchan_append_bit(schan, inbits & 0x20); + demux_subchan_append_bit(schan, inbits & 0x10); break; case OSMO_I460_RATE_64k: - demux_subchan_append_bit(schan, inbits & 0x01); - demux_subchan_append_bit(schan, inbits & 0x02); - demux_subchan_append_bit(schan, inbits & 0x04); - demux_subchan_append_bit(schan, inbits & 0x08); - demux_subchan_append_bit(schan, inbits & 0x10); - demux_subchan_append_bit(schan, inbits & 0x20); - demux_subchan_append_bit(schan, inbits & 0x40); demux_subchan_append_bit(schan, inbits & 0x80); + demux_subchan_append_bit(schan, inbits & 0x40); + demux_subchan_append_bit(schan, inbits & 0x20); + demux_subchan_append_bit(schan, inbits & 0x10); + demux_subchan_append_bit(schan, inbits & 0x08); + demux_subchan_append_bit(schan, inbits & 0x04); + demux_subchan_append_bit(schan, inbits & 0x02); + demux_subchan_append_bit(schan, inbits & 0x01); break; default: OSMO_ASSERT(0); @@ -205,22 +207,25 @@ static uint8_t mux_subchan_provide_bits(struct osmo_i460_subchan *schan, uint8_t uint8_t outbits = 0; uint8_t outmask; + /* I.460 defines sub-channel 0 is using bit positions 1+2 (the two + * most significant bits, hence we provide msb-first */ + switch (schan->rate) { case OSMO_I460_RATE_8k: - outbits = mux_schan_provide_bit(schan); - outmask = 0x01; + outbits = mux_schan_provide_bit(schan) << 7; + outmask = 0x80; break; case OSMO_I460_RATE_16k: - outbits |= mux_schan_provide_bit(schan) << 1; - outbits |= mux_schan_provide_bit(schan) << 0; - outmask = 0x03; + outbits |= mux_schan_provide_bit(schan) << 7; + outbits |= mux_schan_provide_bit(schan) << 6; + outmask = 0xC0; break; case OSMO_I460_RATE_32k: - outbits |= mux_schan_provide_bit(schan) << 3; - outbits |= mux_schan_provide_bit(schan) << 2; - outbits |= mux_schan_provide_bit(schan) << 1; - outbits |= mux_schan_provide_bit(schan) << 0; - outmask = 0x0F; + outbits |= mux_schan_provide_bit(schan) << 7; + outbits |= mux_schan_provide_bit(schan) << 6; + outbits |= mux_schan_provide_bit(schan) << 5; + outbits |= mux_schan_provide_bit(schan) << 4; + outmask = 0xF0; break; case OSMO_I460_RATE_64k: outbits |= mux_schan_provide_bit(schan) << 7; @@ -236,8 +241,8 @@ static uint8_t mux_subchan_provide_bits(struct osmo_i460_subchan *schan, uint8_t default: OSMO_ASSERT(0); } - *mask = outmask << schan->bit_offset; - return outbits << schan->bit_offset; + *mask = outmask >> schan->bit_offset; + return outbits >> schan->bit_offset; } /* provide one byte of multiplexed I.460 bits */ |