diff --git a/src/gsm/i460_mux.c b/src/gsm/i460_mux.c index 320e781ba..91ab2a19b 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 */ diff --git a/tests/i460_mux/i460_mux_test.c b/tests/i460_mux/i460_mux_test.c index d63b2ae6d..9d5fcf786 100644 --- a/tests/i460_mux/i460_mux_test.c +++ b/tests/i460_mux/i460_mux_test.c @@ -234,8 +234,8 @@ static void test_32k_subchan(void) int i; for (i = 0; i < sizeof(sequence); i++) sequence[i] = 0; - sequence[0] = 0x0f; sequence[1] = 0xf0; + sequence[0] = 0x0f; sequence[2] = 0xff; osmo_i460_demux_in(ts, sequence, sizeof(sequence)); @@ -278,10 +278,10 @@ static void test_16k_subchan(void) int i; for (i = 0; i < sizeof(sequence); i++) sequence[i] = 0; - sequence[0] = 0x03; - sequence[1] = 0x0c; - sequence[2] = 0x30; - sequence[3] = 0xc0; + sequence[0] = 0xC0; + sequence[1] = 0x30; + sequence[2] = 0x0c; + sequence[3] = 0x03; sequence[4] = 0xff; osmo_i460_demux_in(ts, sequence, sizeof(sequence)); @@ -328,16 +328,16 @@ static void test_8k_subchan(void) for (i = 0; i < sizeof(sequence); i++) sequence[i] = 0; i = 0; - sequence[i++] = 0x01; - sequence[i++] = 0x02; - sequence[i++] = 0x04; - sequence[i++] = 0x08; - sequence[i++] = 0x0f; - sequence[i++] = 0x10; - sequence[i++] = 0x20; - sequence[i++] = 0x40; sequence[i++] = 0x80; + sequence[i++] = 0x40; + sequence[i++] = 0x20; + sequence[i++] = 0x10; sequence[i++] = 0xf0; + sequence[i++] = 0x08; + sequence[i++] = 0x04; + sequence[i++] = 0x02; + sequence[i++] = 0x01; + sequence[i++] = 0x0f; sequence[i++] = 0xff; osmo_i460_demux_in(ts, sequence, sizeof(sequence)); diff --git a/tests/i460_mux/i460_mux_test.ok b/tests/i460_mux/i460_mux_test.ok index b94fb7b9b..79c55ed0d 100644 --- a/tests/i460_mux/i460_mux_test.ok +++ b/tests/i460_mux/i460_mux_test.ok @@ -7,15 +7,15 @@ demux_bits_cb '64k': 00000000000000010000001000000011000001000000010100000110000 mux_out: 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 ==> test_32k_subchan -demux_bits_cb '32k_0': 1111000011110000000000000000000000000000 -demux_bits_cb '32k_4': 0000111111110000000000000000000000000000 +demux_bits_cb '32k_0': 0000111111110000000000000000000000000000 +demux_bits_cb '32k_4': 1111000011110000000000000000000000000000 test_32k_subchan-single-0 -mux_out: f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 -mux_out: f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 +mux_out: 5f 5f 5f 5f 5f 5f 5f 5f 5f 5f 5f 5f 5f 5f 5f 5f +mux_out: 5f 5f 5f 5f 5f 5f 5f 5f 5f 5f 5f 5f 5f 5f 5f 5f mux_out: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff test_32k_subchan-single-1 -mux_out: 5f 5f 5f 5f 5f 5f 5f 5f 5f 5f 5f 5f 5f 5f 5f 5f -mux_out: 5f 5f 5f 5f 5f 5f 5f 5f 5f 5f 5f 5f 5f 5f 5f 5f +mux_out: f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 +mux_out: f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 mux_out: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ==> test_16k_subchan @@ -24,28 +24,28 @@ demux_bits_cb '16k_2': 0011000011000000000000000000000000000000 demux_bits_cb '16k_4': 0000110011000000000000000000000000000000 demux_bits_cb '16k_6': 0000001111000000000000000000000000000000 test_16k_subchan-single-0 -mux_out: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd -mux_out: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd -mux_out: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd -mux_out: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd +mux_out: 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f +mux_out: 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f +mux_out: 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f +mux_out: 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f mux_out: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff test_16k_subchan-single-1 -mux_out: f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 -mux_out: f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 -mux_out: f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 -mux_out: f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 +mux_out: df df df df df df df df df df df df df df df df +mux_out: df df df df df df df df df df df df df df df df +mux_out: df df df df df df df df df df df df df df df df +mux_out: df df df df df df df df df df df df df df df df mux_out: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff test_16k_subchan-single-2 -mux_out: df df df df df df df df df df df df df df df df -mux_out: df df df df df df df df df df df df df df df df -mux_out: df df df df df df df df df df df df df df df df -mux_out: df df df df df df df df df df df df df df df df +mux_out: f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 +mux_out: f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 +mux_out: f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 +mux_out: f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 mux_out: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff test_16k_subchan-single-3 -mux_out: 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f -mux_out: 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f -mux_out: 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f -mux_out: 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f +mux_out: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd +mux_out: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd +mux_out: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd +mux_out: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd mux_out: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ==> test_8k_subchan @@ -58,58 +58,58 @@ demux_bits_cb '8k_5': 0000001001100000000000000000000000000000 demux_bits_cb '8k_6': 0000000101100000000000000000000000000000 demux_bits_cb '8k_7': 0000000011100000000000000000000000000000 test_8k_subchan-single-0 -mux_out: fe ff fe ff fe ff fe ff fe ff fe ff fe ff fe ff -mux_out: fe ff fe ff fe ff fe ff fe ff fe ff fe ff fe ff -mux_out: fe ff fe ff fe ff fe ff fe ff fe ff fe ff fe ff -mux_out: fe ff fe ff fe ff fe ff fe ff fe ff fe ff fe ff +mux_out: 7f ff 7f ff 7f ff 7f ff 7f ff 7f ff 7f ff 7f ff +mux_out: 7f ff 7f ff 7f ff 7f ff 7f ff 7f ff 7f ff 7f ff +mux_out: 7f ff 7f ff 7f ff 7f ff 7f ff 7f ff 7f ff 7f ff +mux_out: 7f ff 7f ff 7f ff 7f ff 7f ff 7f ff 7f ff 7f ff mux_out: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff test_8k_subchan-single-1 -mux_out: fd ff fd ff fd ff fd ff fd ff fd ff fd ff fd ff -mux_out: fd ff fd ff fd ff fd ff fd ff fd ff fd ff fd ff -mux_out: fd ff fd ff fd ff fd ff fd ff fd ff fd ff fd ff -mux_out: fd ff fd ff fd ff fd ff fd ff fd ff fd ff fd ff +mux_out: bf ff bf ff bf ff bf ff bf ff bf ff bf ff bf ff +mux_out: bf ff bf ff bf ff bf ff bf ff bf ff bf ff bf ff +mux_out: bf ff bf ff bf ff bf ff bf ff bf ff bf ff bf ff +mux_out: bf ff bf ff bf ff bf ff bf ff bf ff bf ff bf ff mux_out: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff test_8k_subchan-single-2 -mux_out: fb ff fb ff fb ff fb ff fb ff fb ff fb ff fb ff -mux_out: fb ff fb ff fb ff fb ff fb ff fb ff fb ff fb ff -mux_out: fb ff fb ff fb ff fb ff fb ff fb ff fb ff fb ff -mux_out: fb ff fb ff fb ff fb ff fb ff fb ff fb ff fb ff +mux_out: df ff df ff df ff df ff df ff df ff df ff df ff +mux_out: df ff df ff df ff df ff df ff df ff df ff df ff +mux_out: df ff df ff df ff df ff df ff df ff df ff df ff +mux_out: df ff df ff df ff df ff df ff df ff df ff df ff mux_out: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff test_8k_subchan-single-3 -mux_out: f7 ff f7 ff f7 ff f7 ff f7 ff f7 ff f7 ff f7 ff -mux_out: f7 ff f7 ff f7 ff f7 ff f7 ff f7 ff f7 ff f7 ff -mux_out: f7 ff f7 ff f7 ff f7 ff f7 ff f7 ff f7 ff f7 ff -mux_out: f7 ff f7 ff f7 ff f7 ff f7 ff f7 ff f7 ff f7 ff +mux_out: ef ff ef ff ef ff ef ff ef ff ef ff ef ff ef ff +mux_out: ef ff ef ff ef ff ef ff ef ff ef ff ef ff ef ff +mux_out: ef ff ef ff ef ff ef ff ef ff ef ff ef ff ef ff +mux_out: ef ff ef ff ef ff ef ff ef ff ef ff ef ff ef ff mux_out: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff test_8k_subchan-single-4 -mux_out: ef ff ef ff ef ff ef ff ef ff ef ff ef ff ef ff -mux_out: ef ff ef ff ef ff ef ff ef ff ef ff ef ff ef ff -mux_out: ef ff ef ff ef ff ef ff ef ff ef ff ef ff ef ff -mux_out: ef ff ef ff ef ff ef ff ef ff ef ff ef ff ef ff +mux_out: f7 ff f7 ff f7 ff f7 ff f7 ff f7 ff f7 ff f7 ff +mux_out: f7 ff f7 ff f7 ff f7 ff f7 ff f7 ff f7 ff f7 ff +mux_out: f7 ff f7 ff f7 ff f7 ff f7 ff f7 ff f7 ff f7 ff +mux_out: f7 ff f7 ff f7 ff f7 ff f7 ff f7 ff f7 ff f7 ff mux_out: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff test_8k_subchan-single-5 -mux_out: df ff df ff df ff df ff df ff df ff df ff df ff -mux_out: df ff df ff df ff df ff df ff df ff df ff df ff -mux_out: df ff df ff df ff df ff df ff df ff df ff df ff -mux_out: df ff df ff df ff df ff df ff df ff df ff df ff +mux_out: fb ff fb ff fb ff fb ff fb ff fb ff fb ff fb ff +mux_out: fb ff fb ff fb ff fb ff fb ff fb ff fb ff fb ff +mux_out: fb ff fb ff fb ff fb ff fb ff fb ff fb ff fb ff +mux_out: fb ff fb ff fb ff fb ff fb ff fb ff fb ff fb ff mux_out: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff test_8k_subchan-single-6 -mux_out: bf ff bf ff bf ff bf ff bf ff bf ff bf ff bf ff -mux_out: bf ff bf ff bf ff bf ff bf ff bf ff bf ff bf ff -mux_out: bf ff bf ff bf ff bf ff bf ff bf ff bf ff bf ff -mux_out: bf ff bf ff bf ff bf ff bf ff bf ff bf ff bf ff +mux_out: fd ff fd ff fd ff fd ff fd ff fd ff fd ff fd ff +mux_out: fd ff fd ff fd ff fd ff fd ff fd ff fd ff fd ff +mux_out: fd ff fd ff fd ff fd ff fd ff fd ff fd ff fd ff +mux_out: fd ff fd ff fd ff fd ff fd ff fd ff fd ff fd ff mux_out: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff test_8k_subchan-single-7 -mux_out: 7f ff 7f ff 7f ff 7f ff 7f ff 7f ff 7f ff 7f ff -mux_out: 7f ff 7f ff 7f ff 7f ff 7f ff 7f ff 7f ff 7f ff -mux_out: 7f ff 7f ff 7f ff 7f ff 7f ff 7f ff 7f ff 7f ff -mux_out: 7f ff 7f ff 7f ff 7f ff 7f ff 7f ff 7f ff 7f ff +mux_out: fe ff fe ff fe ff fe ff fe ff fe ff fe ff fe ff +mux_out: fe ff fe ff fe ff fe ff fe ff fe ff fe ff fe ff +mux_out: fe ff fe ff fe ff fe ff fe ff fe ff fe ff fe ff +mux_out: fe ff fe ff fe ff fe ff fe ff fe ff fe ff fe ff mux_out: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ==> test_unused_subchan test_unused_subchan-single -mux_out: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc -mux_out: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc -mux_out: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc -mux_out: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc +mux_out: 3f 3f 3f 3f 3f 3f 3f 3f 3f 3f 3f 3f 3f 3f 3f 3f +mux_out: 3f 3f 3f 3f 3f 3f 3f 3f 3f 3f 3f 3f 3f 3f 3f 3f +mux_out: 3f 3f 3f 3f 3f 3f 3f 3f 3f 3f 3f 3f 3f 3f 3f 3f +mux_out: 3f 3f 3f 3f 3f 3f 3f 3f 3f 3f 3f 3f 3f 3f 3f 3f mux_out: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff