Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Eclipse Titan » Incorrect decoding of an unaligned bit-field (BIT5)
Incorrect decoding of an unaligned bit-field (BIT5) [message #1826490] Sat, 25 April 2020 18:50 Go to next message
Vadim Yanitskiy is currently offline Vadim YanitskiyFriend
Messages: 5
Registered: May 2018
Junior Member
I am currently working on TTCN-3 test cases for the OsmoPCU (Osmocom Packet Control Unit) project:

https://gerrit.osmocom.org/c/osmo-ttcn3-hacks/+/17706

where I need to decode and verify the contents of RR Immediate Assignment message, in particular its CSN.1 encoded part called "Rect Octets" (see 3GPP TS 44.018, section 10.5.2.16). Unfortunately, TITAN's RAW codec fails to decode one of the message fields correctly (compared to Wireshark). According to the law of Sod, this is exactly the field I need to verify in my unit tests (Extended RA). All other fields seem to be decoded correctly.

Here is how the packet looks like in Wireshark (most important part of it):

IA Rest Octets
    L... .... = First Discriminator Bit: Low
    .H.. .... = Second Discriminator Bit: High
    ..0. .... = Discriminator bit: EGPRS Packet Uplink Assignment or Multiple blocks Packet Downlink Assignment
    ...0 .... = Downlink/Uplink: EGPRS Packet Uplink Assignment
    EGPRS Packet Uplink Assignment
        .... 0001  1... .... = Extended_RA: 3  // <------------ (!)
        .0.. .... = Access Technologies Request: Not Present
        ..1. .... = TFI/Multiblock: TFI Assignment Present
        ...0 0000 = TFI_Assignment: 0
        0... .... = Polling: no action is required from MS
        .0.. .... = Allocation Type: Dynamic Allocation (mandatory after Rel-4)
        ..00 0... = USF: 0
        .... .0.. = USF_granularity: the mobile station shall transmit one RLC/MAC block
        .... ..0. = P0: Not Present
        .... ...0  001. .... = Egprs_Modulation_and_Coding_Scheme: MCS-2 (1)
        ...0 .... = TLLI_Block_Channel_Coding: mobile station shall use CS-1 in GPRS TBF mode or MCS-1 in EGPRS TBF mode
        .... 0... = BEP_PERIOD2: Not Present
        .... .0.. = Resegment: Retransmitted RLC data blocks shall not be re-segmented
        .... ..00  000. .... = Egprs_Windows_Size: 64 (0)
        ...0 .... = Alpha: Not Present
        .... 0000  0... .... = Gamma: 0 dB (0)
        .0.. .... = Timing Advance Index: Not Present
        ..0. .... = TBF Starting Time: Not Present
        ...L .... = Additions in Rel-7: Not Present


and here is what TITAN's logs:

rest_octets := {
	presence := '01'B,
	ll := omit,
	lh := {
		presence := '00'B,
		egprs_ul := {
			ext_ra := '10001'B, // <------ (!)
			ats_present := '0'B,
			ats := omit,
			presence := '1'B,
			dynamic := {
				tfi_assignment := 0,
				polling := '0'B,
				spare := '0'B,
				usf := 0,
				usf_granularity := '0'B,
				p0_present := '0'B,
				p0 := omit,
				pr_mode := omit,
				egprs_ch_coding_cmd := CH_CODING_MCS2 (1),
				tlli_block_chan_coding := '0'B,
				bep_period2_present := '0'B,
				bep_period2 := omit,
				resegment := '0'B,
				egprs_window_size := EGPRS_WS_64 (0),
				alpha_present := '0'B,
				alpha := omit,
				gamma := 0,
				ta_index_present := '0'B,
				ta_index := omit,
				tbf_starting_time_present := '0'B,
				tbf_starting_time := omit
			},
			multiblock := omit
		},
		multiblock_dl_ass := omit
	},
	hl := omit,
	hh := omit
}


As can be seen, Extended_RA does not match ('00011'B vs '10001'B). I did a little investigation, and managed to reproduce the problem with a simple record containing several bit-fields:

private type record TestRecord {
        BIT2            msg_disc, // xx.. .... .... ....
        BIT1            field1,   // ..x. .... .... ....
        BIT1            field2,   // ...x .... .... ....
        BIT5            field3,   // .... xxxx x... .... (!)
        BIT3            field4,   // .... .... .xxx ....
        BIT4            field5    // .... .... .... xxxx
} with {
        encode "RAW";
        variant "FIELDORDER(msb)"
        variant "BYTEORDER(last)"
        variant "BITORDER(msb)"
};

private external function enc_TestRecord(in TestRecord rec) return bitstring
        with { extension "prototype(convert) encode(RAW)" };
private external function dec_TestRecord(in bitstring rec) return TestRecord
        with { extension "prototype(convert) decode(RAW)" };

/* Some test sequences (recognisable pattern) */
private const bitstring test_seq00 := '0000000000000000'B;
private const bitstring test_seq01 := '0101010101010101'B; // (!)
private const bitstring test_seq11 := '1111111111111111'B;

private template TestRecord tr_TestSeq00 := {
        msg_disc := '00'B,
        field1 := '0'B,
        field2 := '0'B,
        field3 := '00000'B,
        field4 := '000'B,
        field5 := '0000'B
};

private template TestRecord tr_TestSeq01 := {
        msg_disc := '01'B,
        field1 := '0'B,
        field2 := '1'B,
        field3 := '01010'B,
        field4 := '101'B,
        field5 := '0101'B
};

private template TestRecord tr_TestSeq11 := {
        msg_disc := '11'B,
        field1 := '1'B,
        field2 := '1'B,
        field3 := '11111'B,
        field4 := '111'B,
        field5 := '1111'B
};

private function f_TC_bitstring_selftest(in bitstring seq, template TestRecord tr_rec)
{
        var TestRecord rec_dec;
        var bitstring seq_enc;

        log("Testing sequence: ", seq);

        /* decode -> encode a given test sequence */
        rec_dec := dec_TestRecord(seq);
        seq_enc := enc_TestRecord(rec_dec);

        if (seq_enc != seq) {
                setverdict(fail, "Encoded sequence does not match: ", seq_enc, " vs ", seq);
        }

        if (not match(rec_dec, tr_rec)) {
                setverdict(fail, "Decoded record does not match: ", rec_dec);
        }

        setverdict(pass);
}

testcase TC_bitstring_selftest() runs on RAW_PCU_Test_CT
{
        f_TC_bitstring_selftest(test_seq00, tr_TestSeq00); // pass
        f_TC_bitstring_selftest(test_seq01, tr_TestSeq01); // fail
        f_TC_bitstring_selftest(test_seq11, tr_TestSeq11); // pass
}


and here is the result:

MTC@DELL: Testing sequence: '0000000000000000'B
MTC@DELL: dec_TestRecord(): Stream before decoding: '0000000000000000'B
MTC@DELL: dec_TestRecord(): Decoded @PCU_Tests_RAW.TestRecord: { msg_disc := '00'B, field1 := '0'B, field2 := '0'B, field3 := '00000'B, field4 := '000'B, field5 := '0000'B }
MTC@DELL: enc_TestRecord(): Encoding @PCU_Tests_RAW.TestRecord: { msg_disc := '00'B, field1 := '0'B, field2 := '0'B, field3 := '00000'B, field4 := '000'B, field5 := '0000'B } 
MTC@DELL: enc_TestRecord(): Stream after encoding: '0000000000000000'B

MTC@DELL: Testing sequence: '0101010101010101'B
MTC@DELL: dec_TestRecord(): Stream before decoding: '0101010101010101'B
MTC@DELL: dec_TestRecord(): Decoded @PCU_Tests_RAW.TestRecord: { msg_disc := '01'B, field1 := '0'B, field2 := '1'B, field3 := '00101'B, field4 := '101'B, field5 := '0101'B }
MTC@DELL: enc_TestRecord(): Encoding @PCU_Tests_RAW.TestRecord: { msg_disc := '01'B, field1 := '0'B, field2 := '1'B, field3 := '00101'B, field4 := '101'B, field5 := '0101'B } 
MTC@DELL: enc_TestRecord(): Stream after encoding: '0101010101010101'B

MTC@DELL: Testing sequence: '1111111111111111'B
MTC@DELL: dec_TestRecord(): Stream before decoding: '1111111111111111'B
MTC@DELL: dec_TestRecord(): Decoded @PCU_Tests_RAW.TestRecord: { msg_disc := '11'B, field1 := '1'B, field2 := '1'B, field3 := '11111'B, field4 := '111'B, field5 := '1111'B } 
MTC@DELL: enc_TestRecord(): Encoding @PCU_Tests_RAW.TestRecord: { msg_disc := '11'B, field1 := '1'B, field2 := '1'B, field3 := '11111'B, field4 := '111'B, field5 := '1111'B }
MTC@DELL: enc_TestRecord(): Stream after encoding: '1111111111111111'B

MTC@DELL: Test case TC_bitstring_selftest finished. Verdict: fail reason: Decoded record does not match: { msg_disc := '01'B, field1 := '0'B, field2 := '1'B, field3 := '
00101'B, field4 := '101'B, field5 := '0101'B }


Am I missing something? I have managed to work this around by using an integer type with fixed length instead of a bitstring, and also by splitting BIT5 into { BIT4, BIT1 }. But it still feels like a hack, and now I want to know why BIT5 does not work as expected.

Thanks in advance!


With best regards,
Vadim Yanitskiy.
Re: Incorrect decoding of an unaligned bit-field (BIT5) [message #1826506 is a reply to message #1826490] Sun, 26 April 2020 06:16 Go to previous messageGo to next message
Jeno Attila Balasko is currently offline Jeno Attila BalaskoFriend
Messages: 80
Registered: September 2013
Location: Budapest, Hungary
Member

Hi Vadim,

thank you for your description and the example below.
Our tracking method is Bugzilla. Can you copy your example into
https://bugs.eclipse.org/bugs/enter_bug.cgi?product=Titan
, please.
We will investigate it soon.

Best regards
Jeno
Re: Incorrect decoding of an unaligned bit-field (BIT5) [message #1826511 is a reply to message #1826506] Sun, 26 April 2020 08:55 Go to previous messageGo to next message
Vadim Yanitskiy is currently offline Vadim YanitskiyFriend
Messages: 5
Registered: May 2018
Junior Member
Hi Jeno,

please see: https://bugs.eclipse.org/bugs/show_bug.cgi?id=562488.

> We will investigate it soon.

Thank you! Let me know if you would need more details.

With best regards,
Vadim Yanitskiy.


With best regards,
Vadim Yanitskiy.
Re: Incorrect decoding of an unaligned bit-field (BIT5) [message #1826562 is a reply to message #1826511] Mon, 27 April 2020 07:15 Go to previous messageGo to next message
Gábor Szalai is currently offline Gábor SzalaiFriend
Messages: 131
Registered: December 2015
Senior Member
The variant attributes BYTEORDER and BITORDER doesn't have any effect if applied to the whole record. They are not applied to the fields of the record in this way.

Using the following definition the example works:
private type record TestRecord {
        BIT2            msg_disc, // xx.. .... .... ....
        BIT1            field1,   // ..x. .... .... ....
        BIT1            field2,   // ...x .... .... ....
        BIT5            field3,   // .... xxxx x... .... (!)
        BIT3            field4,   // .... .... .xxx ....
        BIT4            field5    // .... .... .... xxxx
} with {
        encode "RAW";
        variant "FIELDORDER(msb)"
        variant (field3) "BYTEORDER(last)"
};

Re: Incorrect decoding of an unaligned bit-field (BIT5) [message #1826609 is a reply to message #1826562] Mon, 27 April 2020 17:38 Go to previous message
Vadim Yanitskiy is currently offline Vadim YanitskiyFriend
Messages: 5
Registered: May 2018
Junior Member
> The variant attributes BYTEORDER and BITORDER doesn't have any effect if applied to the whole record.

However it seems to work like a charm when applied to the whole module. The problem is solved now, thank you!


With best regards,
Vadim Yanitskiy.
Previous Topic:Problem executing STF525 CAM Test
Next Topic:Conversion from CharString to Universal Charstring
Goto Forum:
  


Current Time: Fri Mar 29 09:18:23 GMT 2024

Powered by FUDForum. Page generated in 0.02981 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top