From d88bb2e825ec868a9634985fedad7a85f8e77944 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Fri, 11 Dec 2015 14:53:29 +0100 Subject: rlc: Dump RLC data for debugging Log incoming RLC data messages and RLC data units to LOGL_DEBUG. Sponsored-by: On-Waves ehf --- src/bts.cpp | 2 ++ src/tbf_ul.cpp | 3 +++ tests/tbf/TbfTest.err | 18 ++++++++++++++++++ 3 files changed, 23 insertions(+) diff --git a/src/bts.cpp b/src/bts.cpp index d1d738c6..b7244aa5 100644 --- a/src/bts.cpp +++ b/src/bts.cpp @@ -1180,6 +1180,8 @@ int gprs_rlcmac_pdch::rcv_data_block(uint8_t *data, uint32_t fn, } } + LOGP(DRLCMACUL, LOGL_DEBUG, " UL data: %s\n", osmo_hexdump(data, len)); + rc = Decoding::rlc_parse_ul_data_header(&rlc_dec, data, cs); if (rc < 0) { LOGP(DRLCMACUL, LOGL_ERROR, diff --git a/src/tbf_ul.cpp b/src/tbf_ul.cpp index a133d3e7..271f87aa 100644 --- a/src/tbf_ul.cpp +++ b/src/tbf_ul.cpp @@ -242,6 +242,9 @@ int gprs_rlcmac_ul_tbf::rcv_data_block_acknowledged( Decoding::rlc_copy_to_aligned_buffer(rlc, block_idx, data, rlc_data); + LOGP(DRLCMACUL, LOGL_DEBUG, + "%s: data_length=%d, data=%s\n", + name(), block->len, osmo_hexdump(rlc_data, block->len)); /* TODO: Handle SPB != 0 -> set state to partly received * (upper/lower) and continue with the loop, unless the other diff --git a/tests/tbf/TbfTest.err b/tests/tbf/TbfTest.err index 27c5fe31..f5509d7e 100644 --- a/tests/tbf/TbfTest.err +++ b/tests/tbf/TbfTest.err @@ -1394,11 +1394,13 @@ TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=FLOW) RX: [PCU <- BTS] RACH qbit-ta=31 ra TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=FLOW) TX: START Immediate Assignment Uplink (AGCH) Sending data request: trx=0 ts=0 sapi=2 arfcn=0 fn=0 block=0 data=2d 06 3f 10 0f 00 00 03 8b 29 07 00 c8 00 10 0b 2b 2b 2b 2b 2b 2b 2b Got RLC block, coding scheme: CS-1, length: 23 (23)) + UL data: 00 01 01 f1 22 33 44 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Got CS-1 RLC block: R=0, SI=0, TFI=0, CPS=0, RSB=0, rc=184 UL DATA TFI=0 received (V(Q)=0 .. V(R)=0) TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=FLOW) restarting timer 3169 while old timer 3169 pending TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=FLOW): Got CS-1 RLC data block: CV=0, BSN=0, SPB=0, PI=0, E=1, TI=1, bitoffs=24 - BSN 0 storing in window (0..63) +TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=FLOW): data_length=20, data=f1 22 33 44 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Decoded premier TLLI=0x00000000 of UL DATA TFI=0. Modifying MS object, UL TLLI: 0x00000000 -> 0xf1223344, not yet confirmed - Raising V(R) to 1 @@ -1485,11 +1487,13 @@ RX: [PCU <- BTS] TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) Packet Control A TBF: [DOWNLINK] UPLINK ASSIGNED TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) changes state from ASSIGN to FLOW Got RLC block, coding scheme: CS-1, length: 23 (23)) + UL data: 3c 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Got CS-1 RLC block: R=0, SI=0, TFI=0, CPS=0, RSB=0, rc=184 UL DATA TFI=0 received (V(Q)=0 .. V(R)=0) TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW) restarting timer 3169 while old timer 3169 pending TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW): Got CS-1 RLC data block: CV=15, BSN=0, SPB=0, PI=0, E=1, TI=0, bitoffs=24 - BSN 0 storing in window (0..63) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW): data_length=20, data=00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - Raising V(R) to 1 - Taking block 0 out, raising V(Q) to 1 - Assembling frames: (len=20) @@ -1566,11 +1570,13 @@ RX: [PCU <- BTS] TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) Packet Control A TBF: [DOWNLINK] UPLINK ASSIGNED TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) changes state from ASSIGN to FLOW Got RLC block, coding scheme: CS-1, length: 23 (23)) + UL data: 3c 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Got CS-1 RLC block: R=0, SI=0, TFI=0, CPS=0, RSB=0, rc=184 UL DATA TFI=0 received (V(Q)=0 .. V(R)=0) TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW) restarting timer 3169 while old timer 3169 pending TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW): Got CS-1 RLC data block: CV=15, BSN=0, SPB=0, PI=0, E=1, TI=0, bitoffs=24 - BSN 0 storing in window (0..63) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW): data_length=20, data=00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - Raising V(R) to 1 - Taking block 0 out, raising V(Q) to 1 - Assembling frames: (len=20) @@ -1693,11 +1699,13 @@ RX: [PCU <- BTS] TBF(TFI=1 TLLI=0xf5667788 DIR=UL STATE=ASSIGN) Packet Control A TBF: [DOWNLINK] UPLINK ASSIGNED TBF(TFI=1 TLLI=0xf5667788 DIR=UL STATE=ASSIGN) TBF(TFI=1 TLLI=0xf5667788 DIR=UL STATE=ASSIGN) changes state from ASSIGN to FLOW Got RLC block, coding scheme: CS-1, length: 23 (23)) + UL data: 3c 02 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Got CS-1 RLC block: R=0, SI=0, TFI=1, CPS=0, RSB=0, rc=184 UL DATA TFI=1 received (V(Q)=0 .. V(R)=0) TBF(TFI=1 TLLI=0xf5667788 DIR=UL STATE=FLOW) restarting timer 3169 while old timer 3169 pending TBF(TFI=1 TLLI=0xf5667788 DIR=UL STATE=FLOW): Got CS-1 RLC data block: CV=15, BSN=0, SPB=0, PI=0, E=1, TI=0, bitoffs=24 - BSN 0 storing in window (0..63) +TBF(TFI=1 TLLI=0xf5667788 DIR=UL STATE=FLOW): data_length=20, data=00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - Raising V(R) to 1 - Taking block 0 out, raising V(Q) to 1 - Assembling frames: (len=20) @@ -1760,11 +1768,13 @@ RX: [PCU <- BTS] TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) Packet Control A TBF: [DOWNLINK] UPLINK ASSIGNED TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) changes state from ASSIGN to FLOW Got RLC block, coding scheme: CS-1, length: 23 (23)) + UL data: 3c 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Got CS-1 RLC block: R=0, SI=0, TFI=0, CPS=0, RSB=0, rc=184 UL DATA TFI=0 received (V(Q)=0 .. V(R)=0) TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW) restarting timer 3169 while old timer 3169 pending TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW): Got CS-1 RLC data block: CV=15, BSN=0, SPB=0, PI=0, E=1, TI=0, bitoffs=24 - BSN 0 storing in window (0..63) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW): data_length=20, data=00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - Raising V(R) to 1 - Taking block 0 out, raising V(Q) to 1 - Assembling frames: (len=20) @@ -1867,11 +1877,13 @@ Send dowlink assignment on PACCH, because TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=ASSIGN) starting timer 0. Got RLC block, coding scheme: CS-1, length: 23 (23)) + UL data: 3c 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Got CS-1 RLC block: R=0, SI=0, TFI=0, CPS=0, RSB=0, rc=184 UL DATA TFI=0 received (V(Q)=0 .. V(R)=0) TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW) restarting timer 3169 while old timer 3169 pending TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW): Got CS-1 RLC data block: CV=15, BSN=0, SPB=0, PI=0, E=1, TI=0, bitoffs=24 - BSN 0 storing in window (0..63) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW): data_length=20, data=00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - Raising V(R) to 1 - Taking block 0 out, raising V(Q) to 1 - Assembling frames: (len=20) @@ -1925,11 +1937,13 @@ RX: [PCU <- BTS] TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) Packet Control A TBF: [DOWNLINK] UPLINK ASSIGNED TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) changes state from ASSIGN to FLOW Got RLC block, coding scheme: CS-1, length: 23 (23)) + UL data: 3c 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Got CS-1 RLC block: R=0, SI=0, TFI=0, CPS=0, RSB=0, rc=184 UL DATA TFI=0 received (V(Q)=0 .. V(R)=0) TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW) restarting timer 3169 while old timer 3169 pending TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW): Got CS-1 RLC data block: CV=15, BSN=0, SPB=0, PI=0, E=1, TI=0, bitoffs=24 - BSN 0 storing in window (0..63) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW): data_length=20, data=00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - Raising V(R) to 1 - Taking block 0 out, raising V(Q) to 1 - Assembling frames: (len=20) @@ -1994,11 +2008,13 @@ TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=FLOW) RX: [PCU <- BTS] RACH qbit-ta=31 ra TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=FLOW) TX: START Immediate Assignment Uplink (AGCH) Sending data request: trx=0 ts=0 sapi=2 arfcn=0 fn=0 block=0 data=2d 06 3f 10 0f 00 00 03 8b ed 07 00 c8 00 10 0b 2b 2b 2b 2b 2b 2b 2b Got RLC block, coding scheme: CS-1, length: 23 (23)) + UL data: 00 01 01 f1 22 33 44 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Got CS-1 RLC block: R=0, SI=0, TFI=0, CPS=0, RSB=0, rc=184 UL DATA TFI=0 received (V(Q)=0 .. V(R)=0) TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=FLOW) restarting timer 3169 while old timer 3169 pending TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=FLOW): Got CS-1 RLC data block: CV=0, BSN=0, SPB=0, PI=0, E=1, TI=1, bitoffs=24 - BSN 0 storing in window (0..63) +TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=FLOW): data_length=20, data=f1 22 33 44 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Decoded premier TLLI=0x00000000 of UL DATA TFI=0. Detaching TBF from MS object, TLLI = 0xf1223344, TBF = TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=ASSIGN) Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=ASSIGN) @@ -2067,11 +2083,13 @@ RX: [PCU <- BTS] TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) Packet Control A TBF: [DOWNLINK] UPLINK ASSIGNED TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) changes state from ASSIGN to FLOW Got RLC block, coding scheme: CS-1, length: 23 (23)) + UL data: 3c 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Got CS-1 RLC block: R=0, SI=0, TFI=0, CPS=0, RSB=0, rc=184 UL DATA TFI=0 received (V(Q)=0 .. V(R)=0) TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW) restarting timer 3169 while old timer 3169 pending TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW): Got CS-1 RLC data block: CV=15, BSN=0, SPB=0, PI=0, E=1, TI=0, bitoffs=24 - BSN 0 storing in window (0..63) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW): data_length=20, data=00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - Raising V(R) to 1 - Taking block 0 out, raising V(Q) to 1 - Assembling frames: (len=20) -- cgit v1.2.3 From 5c75480e9075b4f60deb220a09507ee41f2479fb Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Mon, 21 Dec 2015 15:31:13 +0100 Subject: edge: Move the GPRS UL Ack/Nack encoding into a separate function Currently the Encoding::write_packet_uplink_ack function only supports GPRS. Split this function into a generic and a GPRS specific part. Sponsored-by: On-Waves ehf --- src/encoding.cpp | 59 +++++++++++++++++++++++++++++++++----------------------- 1 file changed, 35 insertions(+), 24 deletions(-) diff --git a/src/encoding.cpp b/src/encoding.cpp index 7f4bf797..1b6e295b 100644 --- a/src/encoding.cpp +++ b/src/encoding.cpp @@ -399,6 +399,38 @@ void Encoding::encode_rbb(const char *show_rbb, uint8_t *rbb) } } +static void write_packet_uplink_ack_gprs(struct gprs_rlcmac_bts *bts, + PU_AckNack_GPRS_t *acknack, struct gprs_rlcmac_ul_tbf *tbf, + int is_final) +{ + Common_Uplink_Ack_Nack_Data_t *acknack_data = + &acknack->Common_Uplink_Ack_Nack_Data; + char rbb[65]; + + tbf->m_window.update_rbb(rbb); + + acknack->CHANNEL_CODING_COMMAND = tbf->current_cs() - 1; + acknack->Ack_Nack_Description.FINAL_ACK_INDICATION = is_final; + acknack->Ack_Nack_Description.STARTING_SEQUENCE_NUMBER = tbf->m_window.ssn(); + + Encoding::encode_rbb(rbb, acknack->Ack_Nack_Description.RECEIVED_BLOCK_BITMAP); + + /* rbb is not NULL terminated */ + rbb[64] = 0; + LOGP(DRLCMACUL, LOGL_DEBUG, "- V(N): \"%s\" R=Received " + "I=Invalid\n", rbb); + + acknack->UnionType = 0x0; /* Fixed Allocation Dummy = on */ + acknack->u.FixedAllocationDummy = 0x0; /* Fixed Allocation Dummy */ + acknack->Exist_AdditionsR99 = 0x0; /* AdditionsR99 = off */ + + acknack_data->Exist_CONTENTION_RESOLUTION_TLLI = 0x1; + acknack_data->CONTENTION_RESOLUTION_TLLI = tbf->tlli(); + acknack_data->Exist_Packet_Timing_Advance = 0x0; + acknack_data->Exist_Extension_Bits = 0x0; + acknack_data->Exist_Power_Control_Parameters = 0x0; +} + /* generate uplink ack */ void Encoding::write_packet_uplink_ack(struct gprs_rlcmac_bts *bts, RlcMacDownlink_t * block, struct gprs_rlcmac_ul_tbf *tbf, @@ -406,10 +438,6 @@ void Encoding::write_packet_uplink_ack(struct gprs_rlcmac_bts *bts, { // Packet Uplink Ack/Nack TS 44.060 11.2.28 - char rbb[65]; - - tbf->m_window.update_rbb(rbb); - LOGP(DRLCMACUL, LOGL_DEBUG, "Encoding Ack/Nack for %s " "(final=%d)\n", tbf_name(tbf), final); @@ -423,26 +451,9 @@ void Encoding::write_packet_uplink_ack(struct gprs_rlcmac_bts *bts, block->u.Packet_Uplink_Ack_Nack.UPLINK_TFI = tbf->tfi(); // Uplink TFI block->u.Packet_Uplink_Ack_Nack.UnionType = 0x0; // PU_AckNack_GPRS = on - block->u.Packet_Uplink_Ack_Nack.u.PU_AckNack_GPRS_Struct.CHANNEL_CODING_COMMAND = tbf->current_cs() - 1; // CS1 - block->u.Packet_Uplink_Ack_Nack.u.PU_AckNack_GPRS_Struct.Ack_Nack_Description.FINAL_ACK_INDICATION = final; // FINAL ACK INDICATION - block->u.Packet_Uplink_Ack_Nack.u.PU_AckNack_GPRS_Struct.Ack_Nack_Description.STARTING_SEQUENCE_NUMBER = tbf->m_window.ssn(); // STARTING_SEQUENCE_NUMBER - - encode_rbb(rbb, block->u.Packet_Uplink_Ack_Nack.u.PU_AckNack_GPRS_Struct.Ack_Nack_Description.RECEIVED_BLOCK_BITMAP); - - /* rbb is not NULL terminated */ - rbb[64] = 0; - LOGP(DRLCMACUL, LOGL_DEBUG, "- V(N): \"%s\" R=Received " - "I=Invalid\n", rbb); - - block->u.Packet_Uplink_Ack_Nack.u.PU_AckNack_GPRS_Struct.UnionType = 0x0; // Fixed Allocation Dummy = on - block->u.Packet_Uplink_Ack_Nack.u.PU_AckNack_GPRS_Struct.u.FixedAllocationDummy = 0x0; // Fixed Allocation Dummy - block->u.Packet_Uplink_Ack_Nack.u.PU_AckNack_GPRS_Struct.Exist_AdditionsR99 = 0x0; // AdditionsR99 = off - - block->u.Packet_Uplink_Ack_Nack.u.PU_AckNack_GPRS_Struct.Common_Uplink_Ack_Nack_Data.Exist_CONTENTION_RESOLUTION_TLLI = 0x1; - block->u.Packet_Uplink_Ack_Nack.u.PU_AckNack_GPRS_Struct.Common_Uplink_Ack_Nack_Data.CONTENTION_RESOLUTION_TLLI = tbf->tlli(); - block->u.Packet_Uplink_Ack_Nack.u.PU_AckNack_GPRS_Struct.Common_Uplink_Ack_Nack_Data.Exist_Packet_Timing_Advance = 0x0; - block->u.Packet_Uplink_Ack_Nack.u.PU_AckNack_GPRS_Struct.Common_Uplink_Ack_Nack_Data.Exist_Extension_Bits = 0x0; - block->u.Packet_Uplink_Ack_Nack.u.PU_AckNack_GPRS_Struct.Common_Uplink_Ack_Nack_Data.Exist_Power_Control_Parameters = 0x0; + write_packet_uplink_ack_gprs(bts, + &block->u.Packet_Uplink_Ack_Nack.u.PU_AckNack_GPRS_Struct, + tbf, final); } unsigned Encoding::write_packet_paging_request(bitvec * dest) -- cgit v1.2.3 From 2e3a81e4b3454ec5aa3b332215044008ed8014aa Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Mon, 21 Dec 2015 17:19:53 +0100 Subject: rlc: Use a pointer instead of repeated selector chains Currently the same selector chain is used several times in the same function. This commit adds a pointer to Packet_Uplink_Ack_Nack and uses that instead. Sponsored-by: On-Waves ehf --- src/encoding.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/encoding.cpp b/src/encoding.cpp index 1b6e295b..b57117f4 100644 --- a/src/encoding.cpp +++ b/src/encoding.cpp @@ -437,6 +437,7 @@ void Encoding::write_packet_uplink_ack(struct gprs_rlcmac_bts *bts, uint8_t final) { // Packet Uplink Ack/Nack TS 44.060 11.2.28 + Packet_Uplink_Ack_Nack_t *acknack; LOGP(DRLCMACUL, LOGL_DEBUG, "Encoding Ack/Nack for %s " "(final=%d)\n", tbf_name(tbf), final); @@ -446,14 +447,16 @@ void Encoding::write_packet_uplink_ack(struct gprs_rlcmac_bts *bts, block->SP = final; // RRBP field is valid, if it is final ack block->USF = 0x0; // Uplink state flag - block->u.Packet_Uplink_Ack_Nack.MESSAGE_TYPE = 0x9; // Packet Downlink Assignment - block->u.Packet_Uplink_Ack_Nack.PAGE_MODE = 0x0; // Normal Paging - block->u.Packet_Uplink_Ack_Nack.UPLINK_TFI = tbf->tfi(); // Uplink TFI + acknack = &block->u.Packet_Uplink_Ack_Nack; - block->u.Packet_Uplink_Ack_Nack.UnionType = 0x0; // PU_AckNack_GPRS = on + acknack->MESSAGE_TYPE = 0x9; // Packet Downlink Assignment + acknack->PAGE_MODE = 0x0; // Normal Paging + acknack->UPLINK_TFI = tbf->tfi(); // Uplink TFI + + /* PU_AckNack_GPRS = on */ + acknack->UnionType = 0x0; write_packet_uplink_ack_gprs(bts, - &block->u.Packet_Uplink_Ack_Nack.u.PU_AckNack_GPRS_Struct, - tbf, final); + &acknack->u.PU_AckNack_GPRS_Struct, tbf, final); } unsigned Encoding::write_packet_paging_request(bitvec * dest) -- cgit v1.2.3 From 2b3121eebf1ec6cbcb25422d6a254d2b4fc15d18 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Mon, 21 Dec 2015 17:23:16 +0100 Subject: edge: Support EGPRS uplink Ack/Nack messages This commit adds EGPRS UL Ack/Nack encoding based on the CSN1 code. Note that the bitmap encoding is still broken and not easy to fix with the CSN1 framework, especially w.r.t. the length field. Therefore this implementation will be abandoned and replaced by a bitvec based one. Sponsored-by: On-Waves ehf --- src/encoding.cpp | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 61 insertions(+), 4 deletions(-) diff --git a/src/encoding.cpp b/src/encoding.cpp index b57117f4..d05177fb 100644 --- a/src/encoding.cpp +++ b/src/encoding.cpp @@ -431,6 +431,54 @@ static void write_packet_uplink_ack_gprs(struct gprs_rlcmac_bts *bts, acknack_data->Exist_Power_Control_Parameters = 0x0; } +static void write_packet_uplink_ack_egprs(struct gprs_rlcmac_bts *bts, + PU_AckNack_EGPRS_00_t *acknack, struct gprs_rlcmac_ul_tbf *tbf, + int is_final) +{ + Common_Uplink_Ack_Nack_Data_t *acknack_data = + &acknack->Common_Uplink_Ack_Nack_Data; + char rbb[65]; + + int bow = 1; + int eow = 1; + int ssn = (tbf->m_window.v_q() + 1) & tbf->m_window.mod_sns(); + + tbf->m_window.update_rbb(rbb); + + /* rbb is not NULL terminated */ + rbb[64] = 0; + LOGP(DRLCMACUL, LOGL_DEBUG, "- V(N): \"%s\" R=Received " + "I=Invalid\n", rbb); + + /* TODO: Use tbf->current_cs() when it supports EGPRS */ + acknack->EGPRS_ChannelCodingCommand = 2; /* MCS-3 */ + acknack->RESEGMENT = 0; /* NYI */ + acknack->PRE_EMPTIVE_TRANSMISSION = 1; /* TODO: This resembles GPRS, change it? */ + acknack->PRR_RETRANSMISSION_REQUEST = 0; /* TODO: Needs clarification */ + acknack->ARAC_RETRANSMISSION_REQUEST = 0; /* TODO: Needs clarification */ + + acknack_data->Exist_CONTENTION_RESOLUTION_TLLI = 0x1; + acknack_data->CONTENTION_RESOLUTION_TLLI = tbf->tlli(); + + acknack->TBF_EST = 1; /* Enable RR on PACCH */ + + acknack_data->Exist_Packet_Timing_Advance = 0x0; + acknack->Exist_Packet_Extended_Timing_Advance = 0x0; + acknack_data->Exist_Power_Control_Parameters = 0x0; + acknack_data->Exist_Extension_Bits = 0x0; + + acknack->EGPRS_AckNack.UnionType = 0; + + acknack->EGPRS_AckNack.Desc.FINAL_ACK_INDICATION = is_final; + acknack->EGPRS_AckNack.Desc.BEGINNING_OF_WINDOW = eow; + acknack->EGPRS_AckNack.Desc.END_OF_WINDOW = bow; + acknack->EGPRS_AckNack.Desc.STARTING_SEQUENCE_NUMBER = ssn; + acknack->EGPRS_AckNack.Desc.Exist_CRBB = 0; /* TODO: Implement compressed bitmaps */ + acknack->EGPRS_AckNack.Desc.URBB_LENGTH = 64; + + Encoding::encode_rbb(rbb, acknack->EGPRS_AckNack.Desc.URBB); +} + /* generate uplink ack */ void Encoding::write_packet_uplink_ack(struct gprs_rlcmac_bts *bts, RlcMacDownlink_t * block, struct gprs_rlcmac_ul_tbf *tbf, @@ -453,10 +501,19 @@ void Encoding::write_packet_uplink_ack(struct gprs_rlcmac_bts *bts, acknack->PAGE_MODE = 0x0; // Normal Paging acknack->UPLINK_TFI = tbf->tfi(); // Uplink TFI - /* PU_AckNack_GPRS = on */ - acknack->UnionType = 0x0; - write_packet_uplink_ack_gprs(bts, - &acknack->u.PU_AckNack_GPRS_Struct, tbf, final); + if (tbf->is_egprs_enabled()) { + /* PU_AckNack_EGPRS = on */ + acknack->UnionType = 0x1; + acknack->u.PU_AckNack_EGPRS_Struct.UnionType = 0x0; + write_packet_uplink_ack_egprs(bts, + &acknack->u.PU_AckNack_EGPRS_Struct.u.PU_AckNack_EGPRS_00, + tbf, final); + } else { + /* PU_AckNack_GPRS = on */ + acknack->UnionType = 0x0; + write_packet_uplink_ack_gprs(bts, + &acknack->u.PU_AckNack_GPRS_Struct, tbf, final); + } } unsigned Encoding::write_packet_paging_request(bitvec * dest) -- cgit v1.2.3 From 93c55d04e5917aa54ce37a9e997d0af87cc8be85 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Wed, 23 Dec 2015 16:29:07 +0100 Subject: rlc: Add and use mod_sns(bsn) method Currently there is only a mod_sns() method which is being used in expression like bsn_expr & win.mod_sns(). This only works, because it is known that mod_sns() is (sns() - 1) where sns() in turn is always 2^n. This is error prone, hard to read, and relies on window specifics that should be kept inside the respective module. This commit adds a mod_sns(uint bsn) method to gprs_rlc_ul_window and gprs_rlc_dl_window, that encapsulates and hides this optimized computation. Sponsored-by: On-Waves ehf --- src/encoding.cpp | 2 +- src/rlc.cpp | 22 +++++++++++----------- src/rlc.h | 20 ++++++++++++++++---- src/tbf_dl.cpp | 15 +++++++-------- src/tbf_ul.cpp | 9 ++++----- 5 files changed, 39 insertions(+), 29 deletions(-) diff --git a/src/encoding.cpp b/src/encoding.cpp index d05177fb..6d66a725 100644 --- a/src/encoding.cpp +++ b/src/encoding.cpp @@ -441,7 +441,7 @@ static void write_packet_uplink_ack_egprs(struct gprs_rlcmac_bts *bts, int bow = 1; int eow = 1; - int ssn = (tbf->m_window.v_q() + 1) & tbf->m_window.mod_sns(); + int ssn = tbf->m_window.mod_sns(tbf->m_window.v_q() + 1); tbf->m_window.update_rbb(rbb); diff --git a/src/rlc.cpp b/src/rlc.cpp index 227fa362..c7336670 100644 --- a/src/rlc.cpp +++ b/src/rlc.cpp @@ -57,7 +57,7 @@ void gprs_rlc_dl_window::reset() int gprs_rlc_dl_window::resend_needed() { - for (uint16_t bsn = v_a(); bsn != v_s(); bsn = (bsn + 1) & mod_sns()) { + for (uint16_t bsn = v_a(); bsn != v_s(); bsn = mod_sns(bsn + 1)) { if (m_v_b.is_nacked(bsn) || m_v_b.is_resend(bsn)) return bsn; } @@ -69,7 +69,7 @@ int gprs_rlc_dl_window::mark_for_resend() { int resend = 0; - for (uint16_t bsn = v_a(); bsn != v_s(); bsn = (bsn + 1) & mod_sns()) { + for (uint16_t bsn = v_a(); bsn != v_s(); bsn = mod_sns(bsn + 1)) { if (m_v_b.is_unacked(bsn)) { /* mark to be re-send */ m_v_b.mark_resend(bsn); @@ -85,7 +85,7 @@ int gprs_rlc_dl_window::count_unacked() uint16_t unacked = 0; uint16_t bsn; - for (bsn = v_a(); bsn != v_s(); bsn = (bsn + 1) & mod_sns()) { + for (bsn = v_a(); bsn != v_s(); bsn = mod_sns(bsn + 1)) { if (!m_v_b.is_acked(bsn)) unacked += 1; } @@ -93,9 +93,9 @@ int gprs_rlc_dl_window::count_unacked() return unacked; } -static uint16_t bitnum_to_bsn(int bitnum, uint16_t ssn, uint16_t mod_sns) +static uint16_t bitnum_to_bsn(int bitnum, uint16_t ssn) { - return (ssn - 1 - bitnum) & mod_sns; + return (ssn - 1 - bitnum); } void gprs_rlc_dl_window::update(BTS *bts, char *show_rbb, uint8_t ssn, @@ -103,9 +103,9 @@ void gprs_rlc_dl_window::update(BTS *bts, char *show_rbb, uint8_t ssn, { /* SSN - 1 is in range V(A)..V(S)-1 */ for (int bitpos = 0; bitpos < ws(); bitpos++) { - uint16_t bsn = bitnum_to_bsn(bitpos, ssn, mod_sns()); + uint16_t bsn = mod_sns(bitnum_to_bsn(bitpos, ssn)); - if (bsn == ((v_a() - 1) & mod_sns())) + if (bsn == mod_sns(v_a() - 1)) break; if (show_rbb[ws() - 1 - bitpos] == 'R') { @@ -128,7 +128,7 @@ int gprs_rlc_dl_window::move_window() uint16_t bsn; int moved = 0; - for (i = 0, bsn = v_a(); bsn != v_s(); i++, bsn = (bsn + 1) & mod_sns()) { + for (i = 0, bsn = v_a(); bsn != v_s(); i++, bsn = mod_sns(bsn + 1)) { if (m_v_b.is_acked(bsn)) { m_v_b.mark_invalid(bsn); moved += 1; @@ -144,7 +144,7 @@ void gprs_rlc_dl_window::show_state(char *show_v_b) int i; uint16_t bsn; - for (i = 0, bsn = v_a(); bsn != v_s(); i++, bsn = (bsn + 1) & mod_sns()) { + for (i = 0, bsn = v_a(); bsn != v_s(); i++, bsn = mod_sns(bsn + 1)) { uint16_t index = bsn & mod_sns_half(); switch(m_v_b.get_state(index)) { case GPRS_RLC_DL_BSN_INVALID: @@ -188,7 +188,7 @@ void gprs_rlc_ul_window::update_rbb(char *rbb) void gprs_rlc_ul_window::raise_v_r(const uint16_t bsn) { uint16_t offset_v_r; - offset_v_r = (bsn + 1 - v_r()) & mod_sns(); + offset_v_r = mod_sns(bsn + 1 - v_r()); /* Positive offset, so raise. */ if (offset_v_r < (sns() >> 1)) { while (offset_v_r--) { @@ -212,7 +212,7 @@ uint16_t gprs_rlc_ul_window::raise_v_q() if (!m_v_n.is_received(v_q())) break; LOGP(DRLCMACUL, LOGL_DEBUG, "- Taking block %d out, raising " - "V(Q) to %d\n", v_q(), (v_q() + 1) & mod_sns()); + "V(Q) to %d\n", v_q(), mod_sns(v_q() + 1)); raise_v_q(1); count += 1; } diff --git a/src/rlc.h b/src/rlc.h index f2acb98a..4905aa1f 100644 --- a/src/rlc.h +++ b/src/rlc.h @@ -140,6 +140,7 @@ private: struct gprs_rlc_dl_window { void reset(); const uint16_t mod_sns() const; + const uint16_t mod_sns(uint16_t bsn) const; const uint16_t sns() const; const uint16_t ws() const; @@ -186,6 +187,7 @@ private: struct gprs_rlc_ul_window { const uint16_t mod_sns() const; + const uint16_t mod_sns(uint16_t bsn) const; const uint16_t sns() const; const uint16_t ws() const; @@ -353,6 +355,11 @@ inline const uint16_t gprs_rlc_dl_window::mod_sns() const return sns() - 1; } +inline const uint16_t gprs_rlc_dl_window::mod_sns(uint16_t bsn) const +{ + return bsn & mod_sns(); +} + inline const uint16_t gprs_rlc_dl_window::v_s() const { return m_v_s; @@ -360,7 +367,7 @@ inline const uint16_t gprs_rlc_dl_window::v_s() const inline const uint16_t gprs_rlc_dl_window::v_s_mod(int offset) const { - return (m_v_s + offset) & mod_sns(); + return mod_sns(m_v_s + offset); } inline const uint16_t gprs_rlc_dl_window::v_a() const @@ -370,7 +377,7 @@ inline const uint16_t gprs_rlc_dl_window::v_a() const inline bool gprs_rlc_dl_window::window_stalled() const { - return ((m_v_s - m_v_a) & mod_sns()) == ws(); + return (mod_sns(m_v_s - m_v_a)) == ws(); } inline bool gprs_rlc_dl_window::window_empty() const @@ -428,6 +435,11 @@ inline const uint16_t gprs_rlc_ul_window::mod_sns() const return sns() - 1; } +inline const uint16_t gprs_rlc_ul_window::mod_sns(uint16_t bsn) const +{ + return bsn & mod_sns(); +} + inline const uint16_t gprs_rlc_ul_window::v_r() const { return m_v_r; @@ -445,12 +457,12 @@ inline const uint16_t gprs_rlc_ul_window::ssn() const inline void gprs_rlc_ul_window::raise_v_r_to(int moves) { - m_v_r = (m_v_r + moves) & mod_sns(); + m_v_r = mod_sns(m_v_r + moves); } inline void gprs_rlc_ul_window::raise_v_q(int incr) { - m_v_q = (m_v_q + incr) & mod_sns(); + m_v_q = mod_sns(m_v_q + incr); } inline void gprs_rlc_v_n::mark_received(int bsn) diff --git a/src/tbf_dl.cpp b/src/tbf_dl.cpp index 70194f7c..8bac99f3 100644 --- a/src/tbf_dl.cpp +++ b/src/tbf_dl.cpp @@ -703,9 +703,9 @@ struct msgb *gprs_rlcmac_dl_tbf::create_dl_acked_block( return dl_msg; } -static uint16_t bitnum_to_bsn(int bitnum, uint16_t ssn, uint16_t mod_sns) +static uint16_t bitnum_to_bsn(int bitnum, uint16_t ssn) { - return (ssn - 1 - bitnum) & mod_sns; + return ssn - 1 - bitnum; } int gprs_rlcmac_dl_tbf::analyse_errors(char *show_rbb, uint8_t ssn, @@ -724,9 +724,9 @@ int gprs_rlcmac_dl_tbf::analyse_errors(char *show_rbb, uint8_t ssn, for (int bitpos = 0; bitpos < m_window.ws(); bitpos++) { bool is_received = show_rbb[m_window.ws() - 1 - bitpos] == 'R'; - bsn = bitnum_to_bsn(bitpos, ssn, m_window.mod_sns()); + bsn = m_window.mod_sns(bitnum_to_bsn(bitpos, ssn)); - if (bsn == ((m_window.v_a() - 1) & m_window.mod_sns())) { + if (bsn == m_window.mod_sns(m_window.v_a() - 1)) { info[bitpos] = '$'; break; } @@ -794,19 +794,18 @@ int gprs_rlcmac_dl_tbf::update_window(const uint8_t ssn, const uint8_t *rbb) uint16_t lost = 0, received = 0; char show_rbb[65]; char show_v_b[RLC_MAX_SNS + 1]; - const uint16_t mod_sns = m_window.mod_sns(); int error_rate; struct ana_result ana_res; Decoding::extract_rbb(rbb, show_rbb); /* show received array in debug (bit 64..1) */ LOGP(DRLCMACDL, LOGL_DEBUG, "- ack: (BSN=%d)\"%s\"" - "(BSN=%d) R=ACK I=NACK\n", (ssn - 64) & mod_sns, - show_rbb, (ssn - 1) & mod_sns); + "(BSN=%d) R=ACK I=NACK\n", m_window.mod_sns(ssn - 64), + show_rbb, m_window.mod_sns(ssn - 1)); /* apply received array to receive state (SSN-64..SSN-1) */ /* calculate distance of ssn from V(S) */ - dist = (m_window.v_s() - ssn) & mod_sns; + dist = m_window.mod_sns(m_window.v_s() - ssn); /* check if distance is less than distance V(A)..V(S) */ if (dist >= m_window.distance()) { /* this might happpen, if the downlink assignment diff --git a/src/tbf_ul.cpp b/src/tbf_ul.cpp index 271f87aa..cde361f9 100644 --- a/src/tbf_ul.cpp +++ b/src/tbf_ul.cpp @@ -145,7 +145,6 @@ int gprs_rlcmac_ul_tbf::rcv_data_block_acknowledged( { int8_t rssi = meas->have_rssi ? meas->rssi : 0; - const uint16_t mod_sns = m_window.mod_sns(); const uint16_t ws = m_window.ws(); this->state_flags |= (1 << GPRS_RLCMAC_FLAG_UL_DATA); @@ -194,7 +193,7 @@ int gprs_rlcmac_ul_tbf::rcv_data_block_acknowledged( LOGP(DRLCMACUL, LOGL_DEBUG, "- BSN %d out of window " "%d..%d (it's normal)\n", rdbi->bsn, m_window.v_q(), - (m_window.v_q() + ws - 1) & mod_sns); + m_window.mod_sns(m_window.v_q() + ws - 1)); } else if (m_window.is_received(rdbi->bsn)) { LOGP(DRLCMACUL, LOGL_DEBUG, "- BSN %d already received\n", rdbi->bsn); @@ -219,7 +218,7 @@ int gprs_rlcmac_ul_tbf::rcv_data_block_acknowledged( LOGP(DRLCMACUL, LOGL_DEBUG, "- BSN %d storing in window (%d..%d)\n", rdbi->bsn, m_window.v_q(), - (m_window.v_q() + ws - 1) & mod_sns); + m_window.mod_sns(m_window.v_q() + ws - 1)); block = m_rlc.block(rdbi->bsn); block->block_info = *rdbi; block->cs = rlc->cs; @@ -296,7 +295,7 @@ int gprs_rlcmac_ul_tbf::rcv_data_block_acknowledged( /* Retrieve LLC frames from blocks that are ready */ for (uint16_t i = 0; i < count; ++i) { - uint16_t index = (v_q_beg + i) & mod_sns; + uint16_t index = m_window.mod_sns(v_q_beg + i); assemble_forward_llc(m_rlc.block(index)); } @@ -304,7 +303,7 @@ int gprs_rlcmac_ul_tbf::rcv_data_block_acknowledged( if (this->state_is(GPRS_RLCMAC_FLOW) /* still in flow state */ && this->m_window.v_q() == this->m_window.v_r()) { /* if complete */ struct gprs_rlc_data *block = - m_rlc.block((m_window.v_r() - 1) & mod_sns); + m_rlc.block(m_window.mod_sns(m_window.v_r() - 1)); const struct gprs_rlc_ul_data_block_info *rdbi = &block->block_info; -- cgit v1.2.3 From e1ca87f0570674526e6586c697e06a1c83b8071b Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Wed, 23 Dec 2015 16:40:56 +0100 Subject: rlc/edge: Consistently use uint16_t for BSNs and SSNs Currently in some places uint8_t is being used to encode BSNs and SSNs. This is inconsistent and (even worse) not enough for EPGRS which uses an SNS of 2014. This commit changes these to uint16_t. Sponsored-by: On-Waves ehf --- src/rlc.cpp | 2 +- src/rlc.h | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/rlc.cpp b/src/rlc.cpp index c7336670..f6d6f4aa 100644 --- a/src/rlc.cpp +++ b/src/rlc.cpp @@ -98,7 +98,7 @@ static uint16_t bitnum_to_bsn(int bitnum, uint16_t ssn) return (ssn - 1 - bitnum); } -void gprs_rlc_dl_window::update(BTS *bts, char *show_rbb, uint8_t ssn, +void gprs_rlc_dl_window::update(BTS *bts, char *show_rbb, uint16_t ssn, uint16_t *lost, uint16_t *received) { /* SSN - 1 is in range V(A)..V(S)-1 */ diff --git a/src/rlc.h b/src/rlc.h index 4905aa1f..f16a910a 100644 --- a/src/rlc.h +++ b/src/rlc.h @@ -158,7 +158,7 @@ struct gprs_rlc_dl_window { /* Methods to manage reception */ int resend_needed(); int mark_for_resend(); - void update(BTS *bts, char *show_rbb, uint8_t ssn, + void update(BTS *bts, char *show_rbb, uint16_t ssn, uint16_t *lost, uint16_t *received); int move_window(); void show_state(char *show_rbb); @@ -196,8 +196,8 @@ struct gprs_rlc_ul_window { const uint16_t ssn() const; - bool is_in_window(uint8_t bsn) const; - bool is_received(uint8_t bsn) const; + bool is_in_window(uint16_t bsn) const; + bool is_received(uint16_t bsn) const; void update_rbb(char *rbb); void raise_v_r_to(int moves); @@ -400,7 +400,7 @@ inline const int16_t gprs_rlc_dl_window::distance() const return (m_v_s - m_v_a) & mod_sns(); } -inline bool gprs_rlc_ul_window::is_in_window(uint8_t bsn) const +inline bool gprs_rlc_ul_window::is_in_window(uint16_t bsn) const { uint16_t offset_v_q; @@ -411,7 +411,7 @@ inline bool gprs_rlc_ul_window::is_in_window(uint8_t bsn) const return offset_v_q < ws(); } -inline bool gprs_rlc_ul_window::is_received(uint8_t bsn) const +inline bool gprs_rlc_ul_window::is_received(uint16_t bsn) const { uint16_t offset_v_r; -- cgit v1.2.3 From a3a567e7655b9842c9542d2ba5d1bf5237b46af0 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Mon, 28 Dec 2015 13:46:32 +0100 Subject: rlc: Add constructor to window classes Currently the gprs_rlc_dl_window and gprs_rlc_ul_window do not have constructors, but need to get initialized explicitly. This commit adds constructors to both classes and removes explicit external initialization code. Sponsored-by: On-Waves ehf --- src/rlc.h | 16 ++++++++++++++++ src/tbf.cpp | 2 -- tests/types/TypesTest.cpp | 6 +++--- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/rlc.h b/src/rlc.h index f16a910a..0247a45d 100644 --- a/src/rlc.h +++ b/src/rlc.h @@ -168,6 +168,8 @@ struct gprs_rlc_dl_window { uint16_t m_v_a; /* ack state */ gprs_rlc_v_b m_v_b; + + gprs_rlc_dl_window(); }; struct gprs_rlc_v_n { @@ -213,6 +215,8 @@ struct gprs_rlc_ul_window { uint16_t m_v_q; /* receive window state */ gprs_rlc_v_n m_v_n; + + gprs_rlc_ul_window(); }; extern "C" { @@ -340,6 +344,12 @@ inline void gprs_rlc_v_b::mark_invalid(int bsn) return mark(bsn, GPRS_RLC_DL_BSN_INVALID); } +inline gprs_rlc_dl_window::gprs_rlc_dl_window() + : m_v_s(0) + , m_v_a(0) +{ +} + inline const uint16_t gprs_rlc_dl_window::sns() const { return RLC_MAX_SNS; @@ -400,6 +410,12 @@ inline const int16_t gprs_rlc_dl_window::distance() const return (m_v_s - m_v_a) & mod_sns(); } +inline gprs_rlc_ul_window::gprs_rlc_ul_window() + : m_v_r(0) + , m_v_q(0) +{ +} + inline bool gprs_rlc_ul_window::is_in_window(uint16_t bsn) const { uint16_t offset_v_q; diff --git a/src/tbf.cpp b/src/tbf.cpp index 556f6e83..fd0cd98f 100644 --- a/src/tbf.cpp +++ b/src/tbf.cpp @@ -587,7 +587,6 @@ gprs_rlcmac_ul_tbf::gprs_rlcmac_ul_tbf(BTS *bts_) : m_contention_resolution_done(0), m_final_ack_sent(0) { - memset(&m_window, 0, sizeof(m_window)); memset(&m_usf, 0, sizeof(m_usf)); } @@ -650,7 +649,6 @@ gprs_rlcmac_dl_tbf::gprs_rlcmac_dl_tbf(BTS *bts_) : m_last_dl_poll_fn(0), m_last_dl_drained_fn(0) { - memset(&m_window, 0, sizeof(m_window)); memset(&m_llc_timer, 0, sizeof(m_llc_timer)); } diff --git a/tests/types/TypesTest.cpp b/tests/types/TypesTest.cpp index 776e051e..3447f695 100644 --- a/tests/types/TypesTest.cpp +++ b/tests/types/TypesTest.cpp @@ -147,7 +147,7 @@ static void test_rlc_v_n() static void test_rlc_dl_ul_basic() { { - gprs_rlc_dl_window dl_win = { 0, }; + gprs_rlc_dl_window dl_win; OSMO_ASSERT(dl_win.window_empty()); OSMO_ASSERT(!dl_win.window_stalled()); OSMO_ASSERT(dl_win.distance() == 0); @@ -192,7 +192,7 @@ static void test_rlc_dl_ul_basic() } { - gprs_rlc_ul_window ul_win = { 0, }; + gprs_rlc_ul_window ul_win; int count; const char *rbb; char win_rbb[65]; @@ -328,7 +328,7 @@ static void test_rlc_dl_ul_basic() uint16_t lost = 0, recv = 0; char show_rbb[65]; BTS dummy_bts; - gprs_rlc_dl_window dl_win = { 0, }; + gprs_rlc_dl_window dl_win; dl_win.m_v_b.reset(); -- cgit v1.2.3 From 8f8197f3fde1bafa1d720d9f685288eb4cd36e23 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Mon, 28 Dec 2015 13:51:44 +0100 Subject: rlc: Make WS and SNS variable Currently the values for WS and SNS are fixed to 64 (WS) and 128 (SNS) which are the only values that can be used with GPRS. On the other hand, EGPRS requires an SNS of 2014 and a WS in the range of 64 to 1024. This commit adds member variables and setters to both window classes. By default, the GPRS values are being used. Sponsored-by: On-Waves ehf --- src/rlc.cpp | 32 ++++++++++++++++++++++++++++++++ src/rlc.h | 35 ++++++++++++++++++++++++++++------- 2 files changed, 60 insertions(+), 7 deletions(-) diff --git a/src/rlc.cpp b/src/rlc.cpp index f6d6f4aa..4f62f23c 100644 --- a/src/rlc.cpp +++ b/src/rlc.cpp @@ -55,6 +55,22 @@ void gprs_rlc_dl_window::reset() m_v_b.reset(); } +void gprs_rlc_dl_window::set_sns(uint16_t sns) +{ + OSMO_ASSERT(sns >= RLC_GPRS_SNS); + OSMO_ASSERT(sns <= RLC_MAX_SNS); + /* check for 2^n */ + OSMO_ASSERT((sns & (-sns)) == sns); + m_sns = sns; +} + +void gprs_rlc_dl_window::set_ws(uint16_t ws) +{ + OSMO_ASSERT(ws >= RLC_GPRS_SNS/2); + OSMO_ASSERT(ws <= RLC_MAX_SNS/2); + m_ws = ws; +} + int gprs_rlc_dl_window::resend_needed() { for (uint16_t bsn = v_a(); bsn != v_s(); bsn = mod_sns(bsn + 1)) { @@ -172,6 +188,22 @@ void gprs_rlc_v_n::reset() m_v_n[i] = GPRS_RLC_UL_BSN_INVALID; } +void gprs_rlc_ul_window::set_sns(uint16_t sns) +{ + OSMO_ASSERT(sns >= RLC_GPRS_SNS); + OSMO_ASSERT(sns <= RLC_MAX_SNS); + /* check for 2^n */ + OSMO_ASSERT((sns & (-sns)) == sns); + m_sns = sns; +} + +void gprs_rlc_ul_window::set_ws(uint16_t ws) +{ + OSMO_ASSERT(ws >= RLC_GPRS_SNS/2); + OSMO_ASSERT(ws <= RLC_MAX_SNS/2); + m_ws = ws; +} + /* Update the receive block bitmap */ void gprs_rlc_ul_window::update_rbb(char *rbb) { diff --git a/src/rlc.h b/src/rlc.h index 0247a45d..c7bb98dc 100644 --- a/src/rlc.h +++ b/src/rlc.h @@ -25,9 +25,14 @@ #include -#define RLC_MAX_SNS 128 /* GPRS, must be power of 2 */ -#define RLC_MAX_WS 64 /* max window size */ -#define RLC_MAX_LEN 54 /* CS-4 including spare bits */ +#define RLC_GPRS_SNS 128 /* GPRS, must be power of 2 */ +#define RLC_GPRS_WS 64 /* max window size */ +#define RLC_EGPRS_SNS 2048 /* EGPRS, must be power of 2 */ +#define RLC_EGPRS_MIN_WS 64 /* min window size */ +#define RLC_EGPRS_MAX_WS 1024 /* min window size */ +#define RLC_EGPRS_SNS 2048 /* EGPRS, must be power of 2 */ +#define RLC_MAX_SNS RLC_EGPRS_SNS +#define RLC_MAX_LEN 74 /* MCS-9 data unit */ struct BTS; struct gprs_rlc_v_n; @@ -169,7 +174,13 @@ struct gprs_rlc_dl_window { gprs_rlc_v_b m_v_b; + void set_sns(uint16_t sns); + void set_ws(uint16_t ws); + gprs_rlc_dl_window(); +private: + uint16_t m_sns; + uint16_t m_ws; }; struct gprs_rlc_v_n { @@ -216,7 +227,13 @@ struct gprs_rlc_ul_window { gprs_rlc_v_n m_v_n; + void set_sns(uint16_t sns); + void set_ws(uint16_t ws); + gprs_rlc_ul_window(); +private: + uint16_t m_sns; + uint16_t m_ws; }; extern "C" { @@ -347,17 +364,19 @@ inline void gprs_rlc_v_b::mark_invalid(int bsn) inline gprs_rlc_dl_window::gprs_rlc_dl_window() : m_v_s(0) , m_v_a(0) + , m_sns(RLC_GPRS_SNS) + , m_ws(RLC_GPRS_WS) { } inline const uint16_t gprs_rlc_dl_window::sns() const { - return RLC_MAX_SNS; + return m_sns; } inline const uint16_t gprs_rlc_dl_window::ws() const { - return RLC_MAX_WS; + return m_ws; } inline const uint16_t gprs_rlc_dl_window::mod_sns() const @@ -413,6 +432,8 @@ inline const int16_t gprs_rlc_dl_window::distance() const inline gprs_rlc_ul_window::gprs_rlc_ul_window() : m_v_r(0) , m_v_q(0) + , m_sns(RLC_GPRS_SNS) + , m_ws(RLC_GPRS_WS) { } @@ -438,12 +459,12 @@ inline bool gprs_rlc_ul_window::is_received(uint16_t bsn) const inline const uint16_t gprs_rlc_ul_window::sns() const { - return RLC_MAX_SNS; + return m_sns; } inline const uint16_t gprs_rlc_ul_window::ws() const { - return RLC_MAX_WS; + return m_ws; } inline const uint16_t gprs_rlc_ul_window::mod_sns() const -- cgit v1.2.3 From 869449cdd0d4fd85279226a009aafb71ef3332cb Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Mon, 28 Dec 2015 14:01:50 +0100 Subject: edge: Move EGPRS setup from setup_tbf to tbf_alloc_ul_tbf Currently the EGPRS mode is enabled in setup_tbf depending on the values of egprs_ms_class and bts->egprs_enabled (both must be != 0). This makes it difficult to set different values (like window parameters) depending on the direction. This commit moved the initialisation part to tbf_alloc_ul_tbf und just leaves the setting of the ms_class to setup_tbf. Sponsored-by: On-Waves ehf --- src/tbf.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/tbf.cpp b/src/tbf.cpp index fd0cd98f..670d6335 100644 --- a/src/tbf.cpp +++ b/src/tbf.cpp @@ -546,10 +546,9 @@ static int setup_tbf(struct gprs_rlcmac_tbf *tbf, bts = tbf->bts->bts_data(); - if (egprs_ms_class > 0 && bts->egprs_enabled) { + if (tbf->is_egprs_enabled()) { /* TODO: only for 8PSK, otherwise the GPRS MS class has to be used */ ms_class = egprs_ms_class; - tbf->enable_egprs(); } tbf->m_created_ts = time(NULL); @@ -619,6 +618,12 @@ struct gprs_rlcmac_ul_tbf *tbf_alloc_ul_tbf(struct gprs_rlcmac_bts *bts, if (!ms) ms = bts->bts->ms_alloc(ms_class, egprs_ms_class); + if (egprs_ms_class > 0 && bts->egprs_enabled) { + /* TODO: only for 8PSK, otherwise the GPRS MS class has to be used */ + ms_class = egprs_ms_class; + tbf->enable_egprs(); + } + rc = setup_tbf(tbf, ms, use_trx, ms_class, egprs_ms_class, single_slot); /* if no resource */ if (rc < 0) { -- cgit v1.2.3 From 8e323b39f99b7dd1be6ecd335c0620546ca0bfd8 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Mon, 28 Dec 2015 14:07:21 +0100 Subject: edge: Set the EGPRS window parameters Currently the GPRS parameters are used, which is ok for the WS but not for the SNS. This commit uses RLC_EGPRS_SNS and RLC_EGPRS_MIN_WS for the window configuration. Sponsored-by: On-Waves ehf --- src/tbf.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/tbf.cpp b/src/tbf.cpp index 670d6335..86d99acc 100644 --- a/src/tbf.cpp +++ b/src/tbf.cpp @@ -622,6 +622,8 @@ struct gprs_rlcmac_ul_tbf *tbf_alloc_ul_tbf(struct gprs_rlcmac_bts *bts, /* TODO: only for 8PSK, otherwise the GPRS MS class has to be used */ ms_class = egprs_ms_class; tbf->enable_egprs(); + tbf->m_window.set_sns(RLC_EGPRS_SNS); + tbf->m_window.set_ws(RLC_EGPRS_MIN_WS); } rc = setup_tbf(tbf, ms, use_trx, ms_class, egprs_ms_class, single_slot); -- cgit v1.2.3 From 580edbc326268f0c3f4d0cbffeac963d06ffe8ac Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Mon, 28 Dec 2015 14:10:14 +0100 Subject: sched: Assert that the generated message is not empty Currently the msg data is accessed and index 0 assuming the msg is not empty. While this should be always the case, the msg can be empty if there are software errors in the message creation functions. This commit adds an assertion to catch this kind of bugs. Sponsored-by: On-Waves ehf --- src/gprs_rlcmac_sched.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gprs_rlcmac_sched.cpp b/src/gprs_rlcmac_sched.cpp index b4db88ce..8bf25734 100644 --- a/src/gprs_rlcmac_sched.cpp +++ b/src/gprs_rlcmac_sched.cpp @@ -330,6 +330,7 @@ int gprs_rlcmac_rcv_rts_block(struct gprs_rlcmac_bts *bts, /* msg is now available */ /* set USF */ + OSMO_ASSERT(msgb_length(msg) > 0); msg->data[0] = (msg->data[0] & 0xf8) | usf; /* Used to measure the leak rate, count all blocks */ -- cgit v1.2.3 From 37005a165d487d1ffd5bfc6fde1f918a022b718d Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Tue, 22 Dec 2015 14:58:34 +0100 Subject: encoding: Add bitvec based write_packet_uplink_ack The current write_packet_uplink_ack implementation is based on the CSN.1 encoder which makes it difficult to do the bitmap encoding for EGPRS. Add a new implementation based on bitvec functions to create the PACKET UPLINK ACK/NACK messages. Sponsored-by: On-Waves ehf --- src/encoding.cpp | 176 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/encoding.h | 3 + 2 files changed, 179 insertions(+) diff --git a/src/encoding.cpp b/src/encoding.cpp index 6d66a725..4cbcd8c8 100644 --- a/src/encoding.cpp +++ b/src/encoding.cpp @@ -516,6 +516,182 @@ void Encoding::write_packet_uplink_ack(struct gprs_rlcmac_bts *bts, } } +static void write_packet_ack_nack_desc_gprs( + struct gprs_rlcmac_bts *bts, bitvec * dest, unsigned& wp, + gprs_rlc_ul_window *window, bool is_final) +{ + char rbb[65]; + + window->update_rbb(rbb); + + rbb[64] = 0; + LOGP(DRLCMACUL, LOGL_DEBUG, "- V(N): \"%s\" R=Received " + "I=Invalid\n", rbb); + + bitvec_write_field(dest, wp, is_final, 1); // FINAL_ACK_INDICATION + bitvec_write_field(dest, wp, window->ssn(), 7); // STARTING_SEQUENCE_NUMBER + + for (int i = 0; i < 64; i++) { + /* Set bit at the appropriate position (see 3GPP TS 04.60 9.1.8.1) */ + bool is_ack = (rbb[i] == 'R'); + bitvec_write_field(dest, wp, is_ack, 1); + } +} + +static void write_packet_uplink_ack_gprs( + struct gprs_rlcmac_bts *bts, bitvec * dest, unsigned& wp, + struct gprs_rlcmac_ul_tbf *tbf, bool is_final) +{ + + bitvec_write_field(dest, wp, tbf->current_cs() - 1, 2); // CHANNEL_CODING_COMMAND + write_packet_ack_nack_desc_gprs(bts, dest, wp, &tbf->m_window, is_final); + + bitvec_write_field(dest, wp, 1, 1); // 1: have CONTENTION_RESOLUTION_TLLI + bitvec_write_field(dest, wp, tbf->tlli(), 32); // CONTENTION_RESOLUTION_TLLI + + bitvec_write_field(dest, wp, 0, 1); // 0: don't have Packet Timing Advance + bitvec_write_field(dest, wp, 0, 1); // 0: don't have Power Control Parameters + bitvec_write_field(dest, wp, 0, 1); // 0: don't have Extension Bits + bitvec_write_field(dest, wp, 0, 1); // fixed 0 + bitvec_write_field(dest, wp, 1, 1); // 1: have Additions R99 + bitvec_write_field(dest, wp, 0, 1); // 0: don't have Packet Extended Timing Advance + bitvec_write_field(dest, wp, 1, 1); // TBF_EST (enabled) + bitvec_write_field(dest, wp, 0, 1); // 0: don't have REL 5 +}; + +static void write_packet_ack_nack_desc_egprs( + struct gprs_rlcmac_bts *bts, bitvec * dest, unsigned& wp, + gprs_rlc_ul_window *window, bool is_final) +{ + int urbb_len = 0; + int crbb_len = 0; + int len; + bool bow = true; + bool eow = true; + int ssn = window->mod_sns(window->v_q() + 1); + int num_blocks = window->mod_sns(window->v_r() - window->v_q()); + int esn_crbb = window->mod_sns(ssn - 1); + int rest_bits = dest->data_len * 8 - wp; + + if (num_blocks > 0) + /* V(Q) is NACK and omitted -> SSN = V(Q) + 1 */ + num_blocks -= 1; + + if (num_blocks > window->ws()) + num_blocks = window->ws(); + + if (num_blocks > rest_bits) { + eow = false; + urbb_len = rest_bits; + /* TODO: use compression, start encoding bits and stop when the + * space is exhausted. Use the first combination that encodes + * all bits. If there is none, use the combination that encodes + * the largest number of bits (e.g. by setting num_blocks to the + * max and repeating the construction). + */ + } else if (num_blocks > rest_bits - 9) { + /* union bit and length field take 9 bits */ + eow = false; + urbb_len = rest_bits - 9; + /* TODO: use compression (see above) */ + } + + if (urbb_len + crbb_len == rest_bits) + len = -1; + else if (crbb_len == 0) + len = urbb_len + 15; + else + len = urbb_len + crbb_len + 23; + + /* EGPRS Ack/Nack Description IE */ + if (len < 0) { + bitvec_write_field(dest, wp, 0, 1); // 0: don't have length + } else { + bitvec_write_field(dest, wp, 1, 1); // 1: have length + bitvec_write_field(dest, wp, len, 8); // length + } + + bitvec_write_field(dest, wp, is_final, 1); // FINAL_ACK_INDICATION + bitvec_write_field(dest, wp, bow, 1); // BEGINNING_OF_WINDOW + bitvec_write_field(dest, wp, eow, 1); // END_OF_WINDOW + bitvec_write_field(dest, wp, ssn, 11); // STARTING_SEQUENCE_NUMBER + bitvec_write_field(dest, wp, 0, 1); // 0: don't have CRBB + + /* TODO: Add CRBB support */ + + LOGP(DRLCMACUL, LOGL_DEBUG, + " - EGPRS URBB, len = %d, SSN = %d, ESN_CRBB = %d, " + "SNS = %d, WS = %d, V(Q) = %d, V(R) = %d%s%s\n", + urbb_len, ssn, esn_crbb, + window->sns(), window->ws(), window->v_q(), window->v_r(), + bow ? ", BOW" : "", eow ? ", EOW" : ""); + for (int i = urbb_len; i > 0; i--) { + /* Set bit at the appropriate position (see 3GPP TS 04.60 12.3.1) */ + bool is_ack = window->m_v_n.is_received(esn_crbb + i); + bitvec_write_field(dest, wp, is_ack, 1); + } +} + +static void write_packet_uplink_ack_egprs( + struct gprs_rlcmac_bts *bts, bitvec * dest, unsigned& wp, + struct gprs_rlcmac_ul_tbf *tbf, bool is_final) +{ + bitvec_write_field(dest, wp, 0, 2); // fixed 00 + bitvec_write_field(dest, wp, 2, 4); // CHANNEL_CODING_COMMAND: MCS-3 + // bitvec_write_field(dest, wp, tbf->current_cs() - 1, 4); // CHANNEL_CODING_COMMAND + bitvec_write_field(dest, wp, 0, 1); // 0: no RESEGMENT (nyi) + bitvec_write_field(dest, wp, 1, 1); // PRE_EMPTIVE_TRANSMISSION, TODO: This resembles GPRS, change it? + bitvec_write_field(dest, wp, 0, 1); // 0: no PRR_RETRANSMISSION_REQUEST, TODO: clarify + bitvec_write_field(dest, wp, 0, 1); // 0: no ARAC_RETRANSMISSION_REQUEST, TODO: clarify + bitvec_write_field(dest, wp, 1, 1); // 1: have CONTENTION_RESOLUTION_TLLI + bitvec_write_field(dest, wp, tbf->tlli(), 32); // CONTENTION_RESOLUTION_TLLI + bitvec_write_field(dest, wp, 1, 1); // TBF_EST (enabled) + bitvec_write_field(dest, wp, 0, 1); // 0: don't have Packet Timing Advance + bitvec_write_field(dest, wp, 0, 1); // 0: don't have Packet Extended Timing Advance + bitvec_write_field(dest, wp, 0, 1); // 0: don't have Power Control Parameters + bitvec_write_field(dest, wp, 0, 1); // 0: don't have Extension Bits + + write_packet_ack_nack_desc_egprs(bts, dest, wp, &tbf->m_window, is_final); + + bitvec_write_field(dest, wp, 0, 1); // fixed 0 + bitvec_write_field(dest, wp, 0, 1); // 0: don't have REL 5 +}; + +void Encoding::write_packet_uplink_ack( + struct gprs_rlcmac_bts *bts, bitvec * dest, + struct gprs_rlcmac_ul_tbf *tbf, bool is_final) +{ + unsigned wp = 0; + + LOGP(DRLCMACUL, LOGL_DEBUG, "Encoding Ack/Nack for %s " + "(final=%d)\n", tbf_name(tbf), is_final); + + bitvec_write_field(dest, wp, 0x1, 2); // Payload Type + bitvec_write_field(dest, wp, 0x0, 2); // Uplink block with TDMA framenumber (N+13) + bitvec_write_field(dest, wp, is_final, 1); // Suppl/Polling Bit + bitvec_write_field(dest, wp, 0x0, 3); // Uplink state flag + bitvec_write_field(dest, wp, 0x9, 6); // MESSAGE TYPE Uplink Ack/Nack + bitvec_write_field(dest, wp, 0x0, 2); // Page Mode + + bitvec_write_field(dest, wp, 0x0, 2); // fixed 00 + bitvec_write_field(dest, wp, tbf->tfi(), 5); // Uplink TFI + + if (tbf->is_egprs_enabled()) { + /* PU_AckNack_EGPRS = on */ + bitvec_write_field(dest, wp, 1, 1); // 1: EGPRS + write_packet_uplink_ack_egprs(bts, dest, wp, tbf, is_final); + } else { + /* PU_AckNack_GPRS = on */ + bitvec_write_field(dest, wp, 0, 1); // 0: GPRS + write_packet_uplink_ack_gprs(bts, dest, wp, tbf, is_final); + } + + LOGP(DRLCMACUL, LOGL_DEBUG, + "Uplink Ack/Nack bit count %d, max %d, message = %s\n", + wp, dest->data_len * 8, + osmo_hexdump(dest->data, dest->data_len)); +} + unsigned Encoding::write_packet_paging_request(bitvec * dest) { unsigned wp = 0; diff --git a/src/encoding.h b/src/encoding.h index ac66838d..e88ef22a 100644 --- a/src/encoding.h +++ b/src/encoding.h @@ -58,6 +58,9 @@ public: static void write_packet_uplink_ack(struct gprs_rlcmac_bts *bts, RlcMacDownlink_t * block, struct gprs_rlcmac_ul_tbf *tbf, uint8_t final); + static void write_packet_uplink_ack( + struct gprs_rlcmac_bts *bts, bitvec * dest, + struct gprs_rlcmac_ul_tbf *tbf, bool is_final); static int write_paging_request(bitvec * dest, uint8_t *ptmsi, uint16_t ptmsi_len); -- cgit v1.2.3 From a24e1cd50839ef217ba4fe213ad840693b9fb82d Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Tue, 22 Dec 2015 14:59:13 +0100 Subject: tbf: Use bitvec based write_packet_uplink_ack Use the new bitvec based encoder for PACKET UPLINK ACK/NACK messages and disable the old CSN.1 encoder based one. Sponsored-by: On-Waves ehf --- src/tbf_ul.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/tbf_ul.cpp b/src/tbf_ul.cpp index cde361f9..4237162a 100644 --- a/src/tbf_ul.cpp +++ b/src/tbf_ul.cpp @@ -116,12 +116,17 @@ struct msgb *gprs_rlcmac_ul_tbf::create_ul_ack(uint32_t fn) } bitvec_unhex(ack_vec, "2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b"); + /* RlcMacDownlink_t * mac_control_block = (RlcMacDownlink_t *)talloc_zero(tall_pcu_ctx, RlcMacDownlink_t); Encoding::write_packet_uplink_ack(bts_data(), mac_control_block, this, final); encode_gsm_rlcmac_downlink(ack_vec, mac_control_block); + */ + Encoding::write_packet_uplink_ack(bts_data(), ack_vec, this, final); bitvec_pack(ack_vec, msgb_put(msg, 23)); bitvec_free(ack_vec); + /* talloc_free(mac_control_block); + */ /* now we must set this flag, so we are allowed to assign downlink * TBF on PACCH. it is only allowed when TLLI is acknowledged. */ -- cgit v1.2.3 From 5ffbb2744f77f497db80efceb405ff248386cb1c Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Mon, 28 Dec 2015 14:54:08 +0100 Subject: encoding: Remove RlcMacDownlink_t based write_packet_uplink_ack This is the CSN1-encoder based variant, which has been replaced and is no longer being used. Sponsored-by: On-Waves ehf --- src/encoding.cpp | 117 ------------------------------------------------------- src/encoding.h | 2 - src/tbf_ul.cpp | 8 ---- 3 files changed, 127 deletions(-) diff --git a/src/encoding.cpp b/src/encoding.cpp index 4cbcd8c8..158625e6 100644 --- a/src/encoding.cpp +++ b/src/encoding.cpp @@ -399,123 +399,6 @@ void Encoding::encode_rbb(const char *show_rbb, uint8_t *rbb) } } -static void write_packet_uplink_ack_gprs(struct gprs_rlcmac_bts *bts, - PU_AckNack_GPRS_t *acknack, struct gprs_rlcmac_ul_tbf *tbf, - int is_final) -{ - Common_Uplink_Ack_Nack_Data_t *acknack_data = - &acknack->Common_Uplink_Ack_Nack_Data; - char rbb[65]; - - tbf->m_window.update_rbb(rbb); - - acknack->CHANNEL_CODING_COMMAND = tbf->current_cs() - 1; - acknack->Ack_Nack_Description.FINAL_ACK_INDICATION = is_final; - acknack->Ack_Nack_Description.STARTING_SEQUENCE_NUMBER = tbf->m_window.ssn(); - - Encoding::encode_rbb(rbb, acknack->Ack_Nack_Description.RECEIVED_BLOCK_BITMAP); - - /* rbb is not NULL terminated */ - rbb[64] = 0; - LOGP(DRLCMACUL, LOGL_DEBUG, "- V(N): \"%s\" R=Received " - "I=Invalid\n", rbb); - - acknack->UnionType = 0x0; /* Fixed Allocation Dummy = on */ - acknack->u.FixedAllocationDummy = 0x0; /* Fixed Allocation Dummy */ - acknack->Exist_AdditionsR99 = 0x0; /* AdditionsR99 = off */ - - acknack_data->Exist_CONTENTION_RESOLUTION_TLLI = 0x1; - acknack_data->CONTENTION_RESOLUTION_TLLI = tbf->tlli(); - acknack_data->Exist_Packet_Timing_Advance = 0x0; - acknack_data->Exist_Extension_Bits = 0x0; - acknack_data->Exist_Power_Control_Parameters = 0x0; -} - -static void write_packet_uplink_ack_egprs(struct gprs_rlcmac_bts *bts, - PU_AckNack_EGPRS_00_t *acknack, struct gprs_rlcmac_ul_tbf *tbf, - int is_final) -{ - Common_Uplink_Ack_Nack_Data_t *acknack_data = - &acknack->Common_Uplink_Ack_Nack_Data; - char rbb[65]; - - int bow = 1; - int eow = 1; - int ssn = tbf->m_window.mod_sns(tbf->m_window.v_q() + 1); - - tbf->m_window.update_rbb(rbb); - - /* rbb is not NULL terminated */ - rbb[64] = 0; - LOGP(DRLCMACUL, LOGL_DEBUG, "- V(N): \"%s\" R=Received " - "I=Invalid\n", rbb); - - /* TODO: Use tbf->current_cs() when it supports EGPRS */ - acknack->EGPRS_ChannelCodingCommand = 2; /* MCS-3 */ - acknack->RESEGMENT = 0; /* NYI */ - acknack->PRE_EMPTIVE_TRANSMISSION = 1; /* TODO: This resembles GPRS, change it? */ - acknack->PRR_RETRANSMISSION_REQUEST = 0; /* TODO: Needs clarification */ - acknack->ARAC_RETRANSMISSION_REQUEST = 0; /* TODO: Needs clarification */ - - acknack_data->Exist_CONTENTION_RESOLUTION_TLLI = 0x1; - acknack_data->CONTENTION_RESOLUTION_TLLI = tbf->tlli(); - - acknack->TBF_EST = 1; /* Enable RR on PACCH */ - - acknack_data->Exist_Packet_Timing_Advance = 0x0; - acknack->Exist_Packet_Extended_Timing_Advance = 0x0; - acknack_data->Exist_Power_Control_Parameters = 0x0; - acknack_data->Exist_Extension_Bits = 0x0; - - acknack->EGPRS_AckNack.UnionType = 0; - - acknack->EGPRS_AckNack.Desc.FINAL_ACK_INDICATION = is_final; - acknack->EGPRS_AckNack.Desc.BEGINNING_OF_WINDOW = eow; - acknack->EGPRS_AckNack.Desc.END_OF_WINDOW = bow; - acknack->EGPRS_AckNack.Desc.STARTING_SEQUENCE_NUMBER = ssn; - acknack->EGPRS_AckNack.Desc.Exist_CRBB = 0; /* TODO: Implement compressed bitmaps */ - acknack->EGPRS_AckNack.Desc.URBB_LENGTH = 64; - - Encoding::encode_rbb(rbb, acknack->EGPRS_AckNack.Desc.URBB); -} - -/* generate uplink ack */ -void Encoding::write_packet_uplink_ack(struct gprs_rlcmac_bts *bts, - RlcMacDownlink_t * block, struct gprs_rlcmac_ul_tbf *tbf, - uint8_t final) -{ - // Packet Uplink Ack/Nack TS 44.060 11.2.28 - Packet_Uplink_Ack_Nack_t *acknack; - - LOGP(DRLCMACUL, LOGL_DEBUG, "Encoding Ack/Nack for %s " - "(final=%d)\n", tbf_name(tbf), final); - - block->PAYLOAD_TYPE = 0x1; // RLC/MAC control block that does not include the optional octets of the RLC/MAC control header - block->RRBP = 0x0; // N+13 - block->SP = final; // RRBP field is valid, if it is final ack - block->USF = 0x0; // Uplink state flag - - acknack = &block->u.Packet_Uplink_Ack_Nack; - - acknack->MESSAGE_TYPE = 0x9; // Packet Downlink Assignment - acknack->PAGE_MODE = 0x0; // Normal Paging - acknack->UPLINK_TFI = tbf->tfi(); // Uplink TFI - - if (tbf->is_egprs_enabled()) { - /* PU_AckNack_EGPRS = on */ - acknack->UnionType = 0x1; - acknack->u.PU_AckNack_EGPRS_Struct.UnionType = 0x0; - write_packet_uplink_ack_egprs(bts, - &acknack->u.PU_AckNack_EGPRS_Struct.u.PU_AckNack_EGPRS_00, - tbf, final); - } else { - /* PU_AckNack_GPRS = on */ - acknack->UnionType = 0x0; - write_packet_uplink_ack_gprs(bts, - &acknack->u.PU_AckNack_GPRS_Struct, tbf, final); - } -} - static void write_packet_ack_nack_desc_gprs( struct gprs_rlcmac_bts *bts, bitvec * dest, unsigned& wp, gprs_rlc_ul_window *window, bool is_final) diff --git a/src/encoding.h b/src/encoding.h index e88ef22a..ce17d6f6 100644 --- a/src/encoding.h +++ b/src/encoding.h @@ -56,8 +56,6 @@ public: static void encode_rbb(const char *show_rbb, uint8_t *rbb); - static void write_packet_uplink_ack(struct gprs_rlcmac_bts *bts, RlcMacDownlink_t * block, struct gprs_rlcmac_ul_tbf *tbf, - uint8_t final); static void write_packet_uplink_ack( struct gprs_rlcmac_bts *bts, bitvec * dest, struct gprs_rlcmac_ul_tbf *tbf, bool is_final); diff --git a/src/tbf_ul.cpp b/src/tbf_ul.cpp index 4237162a..4abfaaa0 100644 --- a/src/tbf_ul.cpp +++ b/src/tbf_ul.cpp @@ -116,17 +116,9 @@ struct msgb *gprs_rlcmac_ul_tbf::create_ul_ack(uint32_t fn) } bitvec_unhex(ack_vec, "2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b"); - /* - RlcMacDownlink_t * mac_control_block = (RlcMacDownlink_t *)talloc_zero(tall_pcu_ctx, RlcMacDownlink_t); - Encoding::write_packet_uplink_ack(bts_data(), mac_control_block, this, final); - encode_gsm_rlcmac_downlink(ack_vec, mac_control_block); - */ Encoding::write_packet_uplink_ack(bts_data(), ack_vec, this, final); bitvec_pack(ack_vec, msgb_put(msg, 23)); bitvec_free(ack_vec); - /* - talloc_free(mac_control_block); - */ /* now we must set this flag, so we are allowed to assign downlink * TBF on PACCH. it is only allowed when TLLI is acknowledged. */ -- cgit v1.2.3 From 38f18698b3413bf3e608026aff519427af740335 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Mon, 1 Feb 2016 10:08:00 +0100 Subject: edge/test: Rename test_rlc_decoder to test_rlc_unit_decoder This test only covers RLC data units and not whole RLC messages. Sponsored-by: On-Waves ehf --- tests/edge/EdgeTest.cpp | 4 ++-- tests/edge/EdgeTest.ok | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/edge/EdgeTest.cpp b/tests/edge/EdgeTest.cpp index 31150546..57567741 100644 --- a/tests/edge/EdgeTest.cpp +++ b/tests/edge/EdgeTest.cpp @@ -171,7 +171,7 @@ static void test_coding_scheme() printf("=== end %s ===\n", __func__); } -static void test_rlc_decoder() +static void test_rlc_unit_decoder() { struct gprs_rlc_ul_data_block_info rdbi = {0}; GprsCodingScheme cs; @@ -524,7 +524,7 @@ int main(int argc, char **argv) pcu_vty_init(&debug_log_info); test_coding_scheme(); - test_rlc_decoder(); + test_rlc_unit_decoder(); if (getenv("TALLOC_REPORT_FULL")) talloc_report_full(tall_pcu_ctx, stderr); diff --git a/tests/edge/EdgeTest.ok b/tests/edge/EdgeTest.ok index 6597f07e..791f0d5e 100644 --- a/tests/edge/EdgeTest.ok +++ b/tests/edge/EdgeTest.ok @@ -1,4 +1,4 @@ === start test_coding_scheme === === end test_coding_scheme === -=== start test_rlc_decoder === -=== end test_rlc_decoder === +=== start test_rlc_unit_decoder === +=== end test_rlc_unit_decoder === -- cgit v1.2.3 From aa9daa1b9dfc74deb2ab4993f74ba61ee2712f73 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Mon, 28 Dec 2015 18:49:12 +0100 Subject: tbf: Replace static casts by calls to as_ul_tbf/as_dl_tbf Currently casts from gprs_rlcmac_tbf to gprs_rlcmac_ul_tbf and gprs_rlcmac_dl_tbf are done by using static_cast. This doesn't provide protection against converting a gprs_rlcmac_ul_tbf pointer to a gprs_rlcmac_dl_tbf pointer and vice versa. This commit provides two functions as_ul_tbf and as_dl_tbf, that behave similar like dynamic_cast but use the direction field instead of RTTI. Sponsored-by: On-Waves ehf --- src/bts.cpp | 14 ++++++-------- src/gprs_ms.cpp | 4 ++-- src/gprs_rlcmac_ts_alloc.cpp | 12 ++++-------- src/tbf.cpp | 10 +++++----- src/tbf.h | 17 +++++++++++++++++ 5 files changed, 34 insertions(+), 23 deletions(-) diff --git a/src/bts.cpp b/src/bts.cpp index b7244aa5..1eea0824 100644 --- a/src/bts.cpp +++ b/src/bts.cpp @@ -305,7 +305,7 @@ gprs_rlcmac_dl_tbf *BTS::dl_tbf_by_poll_fn(uint32_t fn, uint8_t trx, uint8_t ts) && tbf->poll_state == GPRS_RLCMAC_POLL_SCHED && tbf->poll_fn == fn && tbf->trx->trx_no == trx && tbf->control_ts == ts) { - return static_cast(tbf); + return tbf; } } return NULL; @@ -322,7 +322,7 @@ gprs_rlcmac_ul_tbf *BTS::ul_tbf_by_poll_fn(uint32_t fn, uint8_t trx, uint8_t ts) && tbf->poll_state == GPRS_RLCMAC_POLL_SCHED && tbf->poll_fn == fn && tbf->trx->trx_no == trx && tbf->control_ts == ts) { - return static_cast(tbf); + return tbf; } } return NULL; @@ -1259,14 +1259,12 @@ gprs_rlcmac_tbf *gprs_rlcmac_pdch::tbf_from_list_by_tfi(struct llist_head *tbf_l gprs_rlcmac_ul_tbf *gprs_rlcmac_pdch::ul_tbf_by_tfi(uint8_t tfi) { - return static_cast( - tbf_by_tfi(tfi, GPRS_RLCMAC_UL_TBF)); + return as_ul_tbf(tbf_by_tfi(tfi, GPRS_RLCMAC_UL_TBF)); } gprs_rlcmac_dl_tbf *gprs_rlcmac_pdch::dl_tbf_by_tfi(uint8_t tfi) { - return static_cast( - tbf_by_tfi(tfi, GPRS_RLCMAC_DL_TBF)); + return as_dl_tbf(tbf_by_tfi(tfi, GPRS_RLCMAC_DL_TBF)); } /* lookup TBF Entity (by TFI) */ @@ -1302,7 +1300,7 @@ void gprs_rlcmac_pdch::attach_tbf(gprs_rlcmac_tbf *tbf) m_num_tbfs[tbf->direction] += 1; if (tbf->direction == GPRS_RLCMAC_UL_TBF) { - ul_tbf = static_cast(tbf); + ul_tbf = as_ul_tbf(tbf); m_assigned_usf |= 1 << ul_tbf->m_usf[ts_no]; } m_assigned_tfi[tbf->direction] |= 1UL << tbf->tfi(); @@ -1322,7 +1320,7 @@ void gprs_rlcmac_pdch::detach_tbf(gprs_rlcmac_tbf *tbf) m_num_tbfs[tbf->direction] -= 1; if (tbf->direction == GPRS_RLCMAC_UL_TBF) { - ul_tbf = static_cast(tbf); + ul_tbf = as_ul_tbf(tbf); m_assigned_usf &= ~(1 << ul_tbf->m_usf[ts_no]); } m_assigned_tfi[tbf->direction] &= ~(1UL << tbf->tfi()); diff --git a/src/gprs_ms.cpp b/src/gprs_ms.cpp index 76fe47c2..2d482846 100644 --- a/src/gprs_ms.cpp +++ b/src/gprs_ms.cpp @@ -218,9 +218,9 @@ void GprsMs::stop_timer() void GprsMs::attach_tbf(struct gprs_rlcmac_tbf *tbf) { if (tbf->direction == GPRS_RLCMAC_DL_TBF) - attach_dl_tbf(static_cast(tbf)); + attach_dl_tbf(as_dl_tbf(tbf)); else - attach_ul_tbf(static_cast(tbf)); + attach_ul_tbf(as_ul_tbf(tbf)); } void GprsMs::attach_ul_tbf(struct gprs_rlcmac_ul_tbf *tbf) diff --git a/src/gprs_rlcmac_ts_alloc.cpp b/src/gprs_rlcmac_ts_alloc.cpp index 0daeaf5c..e6c8ad4c 100644 --- a/src/gprs_rlcmac_ts_alloc.cpp +++ b/src/gprs_rlcmac_ts_alloc.cpp @@ -480,14 +480,12 @@ int alloc_algorithm_a(struct gprs_rlcmac_bts *bts, /* The allocation will be successful, so the system state and tbf_/ms_ * may be modified from now on. */ if (tbf->direction == GPRS_RLCMAC_UL_TBF) { - struct gprs_rlcmac_ul_tbf *ul_tbf = - static_cast(tbf_); + struct gprs_rlcmac_ul_tbf *ul_tbf = as_ul_tbf(tbf_); LOGP(DRLCMAC, LOGL_DEBUG, "- Assign uplink TS=%d TFI=%d USF=%d\n", ts, tfi, usf); assign_uplink_tbf_usf(pdch, ul_tbf, tfi, usf); } else { - struct gprs_rlcmac_dl_tbf *dl_tbf = - static_cast(tbf_); + struct gprs_rlcmac_dl_tbf *dl_tbf = as_dl_tbf(tbf_); LOGP(DRLCMAC, LOGL_DEBUG, "- Assign downlink TS=%d TFI=%d\n", ts, tfi); assign_dlink_tbf(pdch, dl_tbf, tfi); @@ -1010,8 +1008,7 @@ int alloc_algorithm_b(struct gprs_rlcmac_bts *bts, tbf_->first_ts = first_ts; if (tbf->direction == GPRS_RLCMAC_DL_TBF) { - struct gprs_rlcmac_dl_tbf *dl_tbf = - static_cast(tbf_); + struct gprs_rlcmac_dl_tbf *dl_tbf = as_dl_tbf(tbf_); for (ts = 0; ts < 8; ts++) { if (!(dl_slots & (1 << ts))) continue; @@ -1021,8 +1018,7 @@ int alloc_algorithm_b(struct gprs_rlcmac_bts *bts, assign_dlink_tbf(&trx->pdch[ts], dl_tbf, tfi); } } else { - struct gprs_rlcmac_ul_tbf *ul_tbf = - static_cast(tbf_); + struct gprs_rlcmac_ul_tbf *ul_tbf = as_ul_tbf(tbf_); for (ts = 0; ts < 8; ts++) { if (!(ul_slots & (1 << ts))) diff --git a/src/tbf.cpp b/src/tbf.cpp index 86d99acc..ea1b89d7 100644 --- a/src/tbf.cpp +++ b/src/tbf.cpp @@ -315,7 +315,7 @@ void tbf_free(struct gprs_rlcmac_tbf *tbf) /* Give final measurement report */ gprs_rlcmac_rssi_rep(tbf); if (tbf->direction == GPRS_RLCMAC_DL_TBF) { - gprs_rlcmac_dl_tbf *dl_tbf = static_cast(tbf); + gprs_rlcmac_dl_tbf *dl_tbf = as_dl_tbf(tbf); gprs_rlcmac_lost_rep(dl_tbf); dl_tbf->cleanup(); } @@ -446,7 +446,7 @@ void gprs_rlcmac_tbf::poll_timeout() ul_ack_state = GPRS_RLCMAC_UL_ACK_NONE; bts->rlc_ack_timedout(); if (state_is(GPRS_RLCMAC_FINISHED)) { - gprs_rlcmac_ul_tbf *ul_tbf = static_cast(this); + gprs_rlcmac_ul_tbf *ul_tbf = as_ul_tbf(this); ul_tbf->m_n3103++; if (ul_tbf->m_n3103 == ul_tbf->bts->bts_data()->n3103) { LOGP(DRLCMAC, LOGL_NOTICE, @@ -500,7 +500,7 @@ void gprs_rlcmac_tbf::poll_timeout() /* reschedule DL assignment */ dl_ass_state = GPRS_RLCMAC_DL_ASS_SEND_ASS; } else if (direction == GPRS_RLCMAC_DL_TBF) { - gprs_rlcmac_dl_tbf *dl_tbf = static_cast(this); + gprs_rlcmac_dl_tbf *dl_tbf = as_dl_tbf(this); if (!(dl_tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_TO_DL_ACK))) { LOGP(DRLCMAC, LOGL_NOTICE, "- Timeout for polling " @@ -732,7 +732,7 @@ void gprs_rlcmac_tbf::handle_timeout() "in assign state\n", tbf_name(this)); } if ((state_flags & (1 << GPRS_RLCMAC_FLAG_CCCH))) { - gprs_rlcmac_dl_tbf *dl_tbf = static_cast(this); + gprs_rlcmac_dl_tbf *dl_tbf = as_dl_tbf(this); dl_tbf->m_wait_confirm = 0; if (dl_tbf->state_is(GPRS_RLCMAC_ASSIGN)) { tbf_assign_control_ts(dl_tbf); @@ -828,7 +828,7 @@ struct msgb *gprs_rlcmac_tbf::create_dl_ass(uint32_t fn) /* on uplink TBF we get the downlink TBF to be assigned. */ if (direction == GPRS_RLCMAC_UL_TBF) { - gprs_rlcmac_ul_tbf *ul_tbf = static_cast(this); + gprs_rlcmac_ul_tbf *ul_tbf = as_ul_tbf(this); /* be sure to check first, if contention resolution is done, * otherwise we cannot send the assignment yet */ diff --git a/src/tbf.h b/src/tbf.h index a3a2eeba..190101bf 100644 --- a/src/tbf.h +++ b/src/tbf.h @@ -452,6 +452,23 @@ inline enum gprs_rlcmac_tbf_direction reverse(enum gprs_rlcmac_tbf_direction dir return (enum gprs_rlcmac_tbf_direction) ((int)GPRS_RLCMAC_UL_TBF - (int)dir + (int)GPRS_RLCMAC_DL_TBF); } + +inline gprs_rlcmac_ul_tbf *as_ul_tbf(gprs_rlcmac_tbf *tbf) +{ + if (tbf && tbf->direction == GPRS_RLCMAC_UL_TBF) + return static_cast(tbf); + else + return NULL; +} + +inline gprs_rlcmac_dl_tbf *as_dl_tbf(gprs_rlcmac_tbf *tbf) +{ + if (tbf && tbf->direction == GPRS_RLCMAC_DL_TBF) + return static_cast(tbf); + else + return NULL; +} + #endif #ifdef __cplusplus -- cgit v1.2.3 From bf49f042d432780fe37c53aed5e4e3f34ac80793 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Mon, 28 Dec 2015 19:06:09 +0100 Subject: tbf/vty: Move tbf_print_vty_info to pcu_vty_functions.cpp This function is similar to the show_ms function already present in the target file. Since the TBF lists will be turned into LListHead based lists, they will get an iteration function in pcu_vty_functions.cpp, too. Sponsored-by: On-Waves ehf --- src/pcu_vty_functions.cpp | 21 +++++++++++++++++++++ src/pcu_vty_functions.h | 2 ++ src/tbf.cpp | 22 ---------------------- src/tbf.h | 11 ----------- 4 files changed, 23 insertions(+), 33 deletions(-) diff --git a/src/pcu_vty_functions.cpp b/src/pcu_vty_functions.cpp index ce2a006a..74780c2c 100644 --- a/src/pcu_vty_functions.cpp +++ b/src/pcu_vty_functions.cpp @@ -39,6 +39,27 @@ int pcu_vty_config_write_pcu_ext(struct vty *vty) return CMD_SUCCESS; } +void tbf_print_vty_info(struct vty *vty, struct llist_head *ltbf) +{ + gprs_rlcmac_tbf *tbf = llist_pods_entry(ltbf, gprs_rlcmac_tbf); + vty_out(vty, "TBF: TFI=%d TLLI=0x%08x (%s) DIR=%s IMSI=%s%s", tbf->tfi(), + tbf->tlli(), tbf->is_tlli_valid() ? "valid" : "invalid", + tbf->direction == GPRS_RLCMAC_UL_TBF ? "UL" : "DL", + tbf->imsi(), VTY_NEWLINE); + vty_out(vty, " created=%lu state=%08x 1st_TS=%d 1st_cTS=%d ctrl_TS=%d " + "MS_CLASS=%d%s", + tbf->created_ts(), tbf->state_flags, tbf->first_ts, + tbf->first_common_ts, tbf->control_ts, tbf->ms_class(), + VTY_NEWLINE); + vty_out(vty, " TS_alloc="); + for (int i = 0; i < 8; i++) { + if (tbf->pdch[i]) + vty_out(vty, "%d ", i); + } + vty_out(vty, " CS=%d%s%s", tbf->ms() ? tbf->ms()->current_cs_dl() : 1, + VTY_NEWLINE, VTY_NEWLINE); +} + int pcu_vty_show_ms_all(struct vty *vty, struct gprs_rlcmac_bts *bts_data) { BTS *bts = bts_data->bts; diff --git a/src/pcu_vty_functions.h b/src/pcu_vty_functions.h index 1f4ad916..170ad2e2 100644 --- a/src/pcu_vty_functions.h +++ b/src/pcu_vty_functions.h @@ -34,6 +34,8 @@ int pcu_vty_show_ms_by_tlli(struct vty *vty, struct gprs_rlcmac_bts *bts_data, int pcu_vty_show_ms_by_imsi(struct vty *vty, struct gprs_rlcmac_bts *bts_data, const char *imsi); +void tbf_print_vty_info(struct vty *vty, struct llist_head *tbf); + #ifdef __cplusplus } #endif diff --git a/src/tbf.cpp b/src/tbf.cpp index ea1b89d7..b3d0c0dd 100644 --- a/src/tbf.cpp +++ b/src/tbf.cpp @@ -1140,25 +1140,3 @@ uint8_t gprs_rlcmac_tbf::ul_slots() const return slots; } - -void tbf_print_vty_info(struct vty *vty, struct llist_head *ltbf) -{ - gprs_rlcmac_tbf *tbf = llist_pods_entry(ltbf, gprs_rlcmac_tbf); - - vty_out(vty, "TBF: TFI=%d TLLI=0x%08x (%s) DIR=%s IMSI=%s%s", tbf->tfi(), - tbf->tlli(), tbf->is_tlli_valid() ? "valid" : "invalid", - tbf->direction == GPRS_RLCMAC_UL_TBF ? "UL" : "DL", - tbf->imsi(), VTY_NEWLINE); - vty_out(vty, " created=%lu state=%08x 1st_TS=%d 1st_cTS=%d ctrl_TS=%d " - "MS_CLASS=%d%s", - tbf->created_ts(), tbf->state_flags, tbf->first_ts, - tbf->first_common_ts, tbf->control_ts, tbf->ms_class(), - VTY_NEWLINE); - vty_out(vty, " TS_alloc="); - for (int i = 0; i < 8; i++) { - if (tbf->pdch[i]) - vty_out(vty, "%d ", i); - } - vty_out(vty, " CS=%d%s%s", tbf->ms() ? tbf->ms()->current_cs_dl() : 1, - VTY_NEWLINE, VTY_NEWLINE); -} diff --git a/src/tbf.h b/src/tbf.h index 190101bf..de7063da 100644 --- a/src/tbf.h +++ b/src/tbf.h @@ -470,14 +470,3 @@ inline gprs_rlcmac_dl_tbf *as_dl_tbf(gprs_rlcmac_tbf *tbf) } #endif - -#ifdef __cplusplus -extern "C" { -#endif -#include -#include - - void tbf_print_vty_info(struct vty *vty, struct llist_head *tbf); -#ifdef __cplusplus -} -#endif -- cgit v1.2.3 From ed2dbf6954b9883218f5ace1d801c0e316df912a Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Mon, 28 Dec 2015 19:15:40 +0100 Subject: tbf: Use LListHead instead of llist_pods LListHead does basically the same like llist_pods, but more C++ish and with type safety. This commit turns the former list field of gprs_rlcmac_tbf into a private field, provides accessors, moves the related code from pcu_vty.c to pcu_vty_functions.cpp, and removes the llist_pods type and related code. Sponsored-by: On-Waves ehf --- src/bts.cpp | 31 +++++++++++++++++-------------- src/bts.h | 26 +++++++++++++++++++------- src/gprs_rlcmac_sched.cpp | 14 +++++++++----- src/pcu_vty.c | 14 +------------- src/pcu_vty_functions.cpp | 19 +++++++++++++++++-- src/pcu_vty_functions.h | 3 +-- src/poll_controller.cpp | 9 +++++---- src/rlc.h | 6 +----- src/tbf.cpp | 17 +++++++---------- src/tbf.h | 37 ++++++++++++++----------------------- tests/alloc/AllocTest.cpp | 12 ++++++------ 11 files changed, 97 insertions(+), 91 deletions(-) diff --git a/src/bts.cpp b/src/bts.cpp index 1eea0824..52811c2c 100644 --- a/src/bts.cpp +++ b/src/bts.cpp @@ -127,8 +127,6 @@ BTS::BTS() , m_ms_store(this) { memset(&m_bts, 0, sizeof(m_bts)); - INIT_LLIST_HEAD(&m_bts.ul_tbfs); - INIT_LLIST_HEAD(&m_bts.dl_tbfs); m_bts.bts = this; /* initialize back pointers */ @@ -214,14 +212,14 @@ int BTS::add_paging(uint8_t chan_needed, uint8_t *identity_lv) { uint8_t l, trx, ts, any_tbf = 0; struct gprs_rlcmac_tbf *tbf; - struct llist_pods *lpods; + LListHead *pos; struct gprs_rlcmac_paging *pag; uint8_t slot_mask[8]; int8_t first_ts; /* must be signed */ - llist_head *tbfs_lists[] = { - &m_bts.ul_tbfs, - &m_bts.dl_tbfs, + LListHead *tbfs_lists[] = { + &m_ul_tbfs, + &m_dl_tbfs, NULL }; @@ -235,7 +233,8 @@ int BTS::add_paging(uint8_t chan_needed, uint8_t *identity_lv) * Don't mark, if TBF uses a different slot that is already marked. */ memset(slot_mask, 0, sizeof(slot_mask)); for (l = 0; tbfs_lists[l]; l++) { - llist_pods_for_each_entry(tbf, tbfs_lists[l], list, lpods) { + llist_for_each(pos, tbfs_lists[l]) { + tbf = pos->entry(); first_ts = -1; for (ts = 0; ts < 8; ts++) { if (tbf->pdch[ts]) { @@ -296,11 +295,12 @@ int BTS::add_paging(uint8_t chan_needed, uint8_t *identity_lv) gprs_rlcmac_dl_tbf *BTS::dl_tbf_by_poll_fn(uint32_t fn, uint8_t trx, uint8_t ts) { struct gprs_rlcmac_dl_tbf *tbf; - struct llist_pods *lpods; + LListHead *pos; /* only one TBF can poll on specific TS/FN, because scheduler can only * schedule one downlink control block (with polling) at a FN per TS */ - llist_pods_for_each_entry(tbf, &m_bts.dl_tbfs, list, lpods) { + llist_for_each(pos, &m_dl_tbfs) { + tbf = as_dl_tbf(pos->entry()); if (tbf->state_is_not(GPRS_RLCMAC_RELEASING) && tbf->poll_state == GPRS_RLCMAC_POLL_SCHED && tbf->poll_fn == fn && tbf->trx->trx_no == trx @@ -313,11 +313,12 @@ gprs_rlcmac_dl_tbf *BTS::dl_tbf_by_poll_fn(uint32_t fn, uint8_t trx, uint8_t ts) gprs_rlcmac_ul_tbf *BTS::ul_tbf_by_poll_fn(uint32_t fn, uint8_t trx, uint8_t ts) { struct gprs_rlcmac_ul_tbf *tbf; - struct llist_pods *lpods; + LListHead *pos; /* only one TBF can poll on specific TS/FN, because scheduler can only * schedule one downlink control block (with polling) at a FN per TS */ - llist_pods_for_each_entry(tbf, &m_bts.ul_tbfs, list, lpods) { + llist_for_each(pos, &m_ul_tbfs) { + tbf = as_ul_tbf(pos->entry()); if (tbf->state_is_not(GPRS_RLCMAC_RELEASING) && tbf->poll_state == GPRS_RLCMAC_POLL_SCHED && tbf->poll_fn == fn && tbf->trx->trx_no == trx @@ -1241,13 +1242,15 @@ int gprs_rlcmac_pdch::rcv_block_gprs(uint8_t *data, uint32_t fn, return rc; } -gprs_rlcmac_tbf *gprs_rlcmac_pdch::tbf_from_list_by_tfi(struct llist_head *tbf_list, uint8_t tfi, +gprs_rlcmac_tbf *gprs_rlcmac_pdch::tbf_from_list_by_tfi( + LListHead *tbf_list, uint8_t tfi, enum gprs_rlcmac_tbf_direction dir) { gprs_rlcmac_tbf *tbf; - struct llist_pods *lpods; + LListHead *pos; - llist_pods_for_each_entry(tbf, tbf_list, list, lpods) { + llist_for_each(pos, tbf_list) { + tbf = pos->entry(); if (tbf->tfi() != tfi) continue; if (!tbf->pdch[ts_no]) diff --git a/src/bts.h b/src/bts.h index 45432eaa..704a5bec 100644 --- a/src/bts.h +++ b/src/bts.h @@ -109,7 +109,8 @@ private: void rcv_control_dl_ack_nack(Packet_Downlink_Ack_Nack_t *, uint32_t fn); void rcv_resource_request(Packet_Resource_Request_t *t, uint32_t fn); void rcv_measurement_report(Packet_Measurement_Report_t *t, uint32_t fn); - gprs_rlcmac_tbf *tbf_from_list_by_tfi(struct llist_head *tbf_list, uint8_t tfi, + gprs_rlcmac_tbf *tbf_from_list_by_tfi( + LListHead *tbf_list, uint8_t tfi, enum gprs_rlcmac_tbf_direction dir); gprs_rlcmac_tbf *tbf_by_tfi(uint8_t tfi, enum gprs_rlcmac_tbf_direction dir); @@ -185,12 +186,6 @@ struct gprs_rlcmac_bts { struct {int16_t low; int16_t high;} cs_lqual_ranges[4]; uint16_t cs_downgrade_threshold; /* downgrade if less packets left (DL) */ - /* TBF handling, make private or move into TBFController */ - /* list of uplink TBFs */ - struct llist_head ul_tbfs; - /* list of downlink TBFs */ - struct llist_head dl_tbfs; - /* State for dynamic algorithm selection */ int multislot_disabled; @@ -319,6 +314,8 @@ public: struct rate_ctr_group *rate_counters() const; struct osmo_stat_item_group *stat_items() const; + LListHead& ul_tbfs(); + LListHead& dl_tbfs(); private: int m_cur_fn; int m_cur_blk_fn; @@ -330,6 +327,11 @@ private: GprsMsStorage m_ms_store; + /* list of uplink TBFs */ + LListHead m_ul_tbfs; + /* list of downlink TBFs */ + LListHead m_dl_tbfs; + private: /* disable copying to avoid slicing */ BTS(const BTS&); @@ -361,6 +363,16 @@ inline GprsMs *BTS::ms_by_imsi(const char *imsi) return ms_store().get_ms(0, 0, imsi); } +inline LListHead& BTS::ul_tbfs() +{ + return m_ul_tbfs; +} + +inline LListHead& BTS::dl_tbfs() +{ + return m_dl_tbfs; +} + inline BTS *gprs_rlcmac_pdch::bts() const { return trx->bts; diff --git a/src/gprs_rlcmac_sched.cpp b/src/gprs_rlcmac_sched.cpp index 8bf25734..4939efd8 100644 --- a/src/gprs_rlcmac_sched.cpp +++ b/src/gprs_rlcmac_sched.cpp @@ -25,7 +25,7 @@ #include "pcu_utils.h" -static uint32_t sched_poll(struct gprs_rlcmac_bts *bts, +static uint32_t sched_poll(BTS *bts, uint8_t trx, uint8_t ts, uint32_t fn, uint8_t block_nr, struct gprs_rlcmac_tbf **poll_tbf, struct gprs_rlcmac_tbf **ul_ass_tbf, @@ -34,7 +34,7 @@ static uint32_t sched_poll(struct gprs_rlcmac_bts *bts, { struct gprs_rlcmac_ul_tbf *ul_tbf; struct gprs_rlcmac_dl_tbf *dl_tbf; - struct llist_pods *lpods; + LListHead *pos; uint32_t poll_fn; /* check special TBF for events */ @@ -42,7 +42,9 @@ static uint32_t sched_poll(struct gprs_rlcmac_bts *bts, if ((block_nr % 3) == 2) poll_fn ++; poll_fn = poll_fn % 2715648; - llist_pods_for_each_entry(ul_tbf, &bts->ul_tbfs, list, lpods) { + llist_for_each(pos, &bts->ul_tbfs()) { + ul_tbf = as_ul_tbf(pos->entry()); + OSMO_ASSERT(ul_tbf); /* this trx, this ts */ if (ul_tbf->trx->trx_no != trx || ul_tbf->control_ts != ts) continue; @@ -58,7 +60,9 @@ static uint32_t sched_poll(struct gprs_rlcmac_bts *bts, *ul_ass_tbf = ul_tbf; #warning "Is this supposed to be fair? The last TBF for each wins? Maybe use llist_add_tail and skip once we have all states?" } - llist_pods_for_each_entry(dl_tbf, &bts->dl_tbfs, list, lpods) { + llist_for_each(pos, &bts->dl_tbfs()) { + dl_tbf = as_dl_tbf(pos->entry()); + OSMO_ASSERT(dl_tbf); /* this trx, this ts */ if (dl_tbf->trx->trx_no != trx || dl_tbf->control_ts != ts) continue; @@ -292,7 +296,7 @@ int gprs_rlcmac_rcv_rts_block(struct gprs_rlcmac_bts *bts, /* store last frame number of RTS */ pdch->last_rts_fn = fn; - poll_fn = sched_poll(bts, trx, ts, fn, block_nr, &poll_tbf, &ul_ass_tbf, + poll_fn = sched_poll(bts->bts, trx, ts, fn, block_nr, &poll_tbf, &ul_ass_tbf, &dl_ass_tbf, &ul_ack_tbf); /* check uplink resource for polling */ if (poll_tbf) diff --git a/src/pcu_vty.c b/src/pcu_vty.c index aa29b4c6..ce9db29a 100644 --- a/src/pcu_vty.c +++ b/src/pcu_vty.c @@ -775,19 +775,7 @@ DEFUN(show_tbf, SHOW_STR "information about TBFs\n" "All TBFs\n") { struct gprs_rlcmac_bts *bts = bts_main_data(); - struct llist_head *tbf; - - vty_out(vty, "UL TBFs%s", VTY_NEWLINE); - llist_for_each(tbf, &bts->ul_tbfs) { - tbf_print_vty_info(vty, tbf); - } - - vty_out(vty, "%sDL TBFs%s", VTY_NEWLINE, VTY_NEWLINE); - llist_for_each(tbf, &bts->dl_tbfs) { - tbf_print_vty_info(vty, tbf); - } - - return CMD_SUCCESS; + return pcu_vty_show_tbf_all(vty, bts); } DEFUN(show_ms_all, diff --git a/src/pcu_vty_functions.cpp b/src/pcu_vty_functions.cpp index 74780c2c..7082d990 100644 --- a/src/pcu_vty_functions.cpp +++ b/src/pcu_vty_functions.cpp @@ -39,9 +39,8 @@ int pcu_vty_config_write_pcu_ext(struct vty *vty) return CMD_SUCCESS; } -void tbf_print_vty_info(struct vty *vty, struct llist_head *ltbf) +static void tbf_print_vty_info(struct vty *vty, gprs_rlcmac_tbf *tbf) { - gprs_rlcmac_tbf *tbf = llist_pods_entry(ltbf, gprs_rlcmac_tbf); vty_out(vty, "TBF: TFI=%d TLLI=0x%08x (%s) DIR=%s IMSI=%s%s", tbf->tfi(), tbf->tlli(), tbf->is_tlli_valid() ? "valid" : "invalid", tbf->direction == GPRS_RLCMAC_UL_TBF ? "UL" : "DL", @@ -60,6 +59,22 @@ void tbf_print_vty_info(struct vty *vty, struct llist_head *ltbf) VTY_NEWLINE, VTY_NEWLINE); } +int pcu_vty_show_tbf_all(struct vty *vty, struct gprs_rlcmac_bts *bts_data) +{ + BTS *bts = bts_data->bts; + LListHead *ms_iter; + + vty_out(vty, "UL TBFs%s", VTY_NEWLINE); + llist_for_each(ms_iter, &bts->ul_tbfs()) + tbf_print_vty_info(vty, ms_iter->entry()); + + vty_out(vty, "%sDL TBFs%s", VTY_NEWLINE, VTY_NEWLINE); + llist_for_each(ms_iter, &bts->dl_tbfs()) + tbf_print_vty_info(vty, ms_iter->entry()); + + return CMD_SUCCESS; +} + int pcu_vty_show_ms_all(struct vty *vty, struct gprs_rlcmac_bts *bts_data) { BTS *bts = bts_data->bts; diff --git a/src/pcu_vty_functions.h b/src/pcu_vty_functions.h index 170ad2e2..35acf64c 100644 --- a/src/pcu_vty_functions.h +++ b/src/pcu_vty_functions.h @@ -28,14 +28,13 @@ struct vty; struct gprs_rlcmac_bts; int pcu_vty_config_write_pcu_ext(struct vty *vty); +int pcu_vty_show_tbf_all(struct vty *vty, struct gprs_rlcmac_bts *bts_data); int pcu_vty_show_ms_all(struct vty *vty, struct gprs_rlcmac_bts *bts_data); int pcu_vty_show_ms_by_tlli(struct vty *vty, struct gprs_rlcmac_bts *bts_data, uint32_t tlli); int pcu_vty_show_ms_by_imsi(struct vty *vty, struct gprs_rlcmac_bts *bts_data, const char *imsi); -void tbf_print_vty_info(struct vty *vty, struct llist_head *tbf); - #ifdef __cplusplus } #endif diff --git a/src/poll_controller.cpp b/src/poll_controller.cpp index 8108f742..54e3bc76 100644 --- a/src/poll_controller.cpp +++ b/src/poll_controller.cpp @@ -30,14 +30,14 @@ PollController::PollController(BTS& bts) void PollController::expireTimedout(int frame_number, unsigned max_delay) { - struct gprs_rlcmac_bts *bts = m_bts.bts_data(); struct gprs_rlcmac_dl_tbf *dl_tbf; struct gprs_rlcmac_ul_tbf *ul_tbf; struct gprs_rlcmac_sba *sba, *sba2; - struct llist_pods *lpods; + LListHead *pos; uint32_t elapsed; - llist_pods_for_each_entry(ul_tbf, &bts->ul_tbfs, list, lpods) { + llist_for_each(pos, &m_bts.ul_tbfs()) { + ul_tbf = as_ul_tbf(pos->entry()); if (ul_tbf->poll_state == GPRS_RLCMAC_POLL_SCHED) { elapsed = (frame_number + 2715648 - ul_tbf->poll_fn) % 2715648; @@ -45,7 +45,8 @@ void PollController::expireTimedout(int frame_number, unsigned max_delay) ul_tbf->poll_timeout(); } } - llist_pods_for_each_entry(dl_tbf, &bts->dl_tbfs, list, lpods) { + llist_for_each(pos, &m_bts.dl_tbfs()) { + dl_tbf = as_dl_tbf(pos->entry()); if (dl_tbf->poll_state == GPRS_RLCMAC_POLL_SCHED) { elapsed = (frame_number + 2715648 - dl_tbf->poll_fn) % 2715648; diff --git a/src/rlc.h b/src/rlc.h index c7bb98dc..46d821d3 100644 --- a/src/rlc.h +++ b/src/rlc.h @@ -136,11 +136,7 @@ private: /** - * TODO: The UL/DL code could/should share a baseclass but - * we are using llist_for_each_entry for the TBF which - * requires everything which creates a requirement for a POD - * type and in < C++11 something that is using even if the - * most simple form of inheritance is not a POD anymore. + * TODO: The UL/DL code could/should share a base class. */ struct gprs_rlc_dl_window { void reset(); diff --git a/src/tbf.cpp b/src/tbf.cpp index b3d0c0dd..185f0bd7 100644 --- a/src/tbf.cpp +++ b/src/tbf.cpp @@ -74,12 +74,12 @@ gprs_rlcmac_tbf::gprs_rlcmac_tbf(BTS *bts_, gprs_rlcmac_tbf_direction dir) : m_ms(NULL), m_ta(0), m_ms_class(0), + m_list(this), m_ms_list(this), m_egprs_enabled(false) { /* The classes of these members do not have proper constructors yet. * Just set them to 0 like talloc_zero did */ - memset(&list, 0, sizeof(list)); memset(&pdch, 0, sizeof(pdch)); memset(&timer, 0, sizeof(timer)); memset(&m_rlc, 0, sizeof(m_rlc)); @@ -88,9 +88,6 @@ gprs_rlcmac_tbf::gprs_rlcmac_tbf(BTS *bts_, gprs_rlcmac_tbf_direction dir) : m_llc.init(); m_name_buf[0] = '\0'; - - /* Back pointer for PODS llist compatibility */ - list.back = this; } gprs_rlcmac_bts *gprs_rlcmac_tbf::bts_data() const @@ -336,7 +333,7 @@ void tbf_free(struct gprs_rlcmac_tbf *tbf) tbf->stop_timer(); #warning "TODO: Could/Should generate bssgp_tx_llc_discarded" tbf_unlink_pdch(tbf); - llist_del(&tbf->list.list); + llist_del(&tbf->list()); if (tbf->direction == GPRS_RLCMAC_UL_TBF) tbf->bts->tbf_ul_freed(); @@ -633,7 +630,7 @@ struct gprs_rlcmac_ul_tbf *tbf_alloc_ul_tbf(struct gprs_rlcmac_bts *bts, return NULL; } - llist_add(&tbf->list.list, &bts->ul_tbfs); + llist_add(&tbf->list(), &bts->bts->ul_tbfs()); tbf->bts->tbf_ul_created(); return tbf; @@ -694,7 +691,7 @@ struct gprs_rlcmac_dl_tbf *tbf_alloc_dl_tbf(struct gprs_rlcmac_bts *bts, return NULL; } - llist_add(&tbf->list.list, &bts->dl_tbfs); + llist_add(&tbf->list(), &bts->bts->dl_tbfs()); tbf->bts->tbf_dl_created(); tbf->m_last_dl_poll_fn = -1; @@ -1093,11 +1090,11 @@ const char *gprs_rlcmac_tbf::name() const void gprs_rlcmac_tbf::rotate_in_list() { - llist_del(&list.list); + llist_del(&list()); if (direction == GPRS_RLCMAC_UL_TBF) - llist_add(&list.list, &bts->bts_data()->ul_tbfs); + llist_add(&list(), &bts->ul_tbfs()); else - llist_add(&list.list, &bts->bts_data()->dl_tbfs); + llist_add(&list(), &bts->dl_tbfs()); } uint8_t gprs_rlcmac_tbf::tsc() const diff --git a/src/tbf.h b/src/tbf.h index de7063da..8ba65756 100644 --- a/src/tbf.h +++ b/src/tbf.h @@ -88,28 +88,6 @@ enum gprs_rlcmac_tbf_direction { #define GPRS_RLCMAC_FLAG_TO_DL_ASS 7 #define GPRS_RLCMAC_FLAG_TO_MASK 0xf0 /* timeout bits */ -struct llist_pods { - struct llist_head list; - void *back; -}; - -#define llist_pods_entry(ptr, type) \ - ((type *)(container_of(ptr, struct llist_pods, list)->back)) - -/** - * llist_pods_for_each_entry - like llist_for_each_entry, but uses - * struct llist_pods ->back to access the entry. - * This is necessary for non-PODS classes because container_of is - * not guaranteed to work anymore. */ -#define llist_pods_for_each_entry(pos, head, member, lpods) \ - for (lpods = llist_entry((head)->next, typeof(struct llist_pods), list), \ - pos = ((typeof(pos))lpods->back), \ - prefetch(pos->member.list.next); \ - &lpods->list != (head); \ - lpods = llist_entry(lpods->list.next, typeof(struct llist_pods), list), \ - pos = ((typeof(pos))lpods->back),\ - prefetch(pos->member.list.next)) - struct gprs_rlcmac_tbf { gprs_rlcmac_tbf(BTS *bts_, gprs_rlcmac_tbf_direction dir); @@ -175,7 +153,9 @@ struct gprs_rlcmac_tbf { LListHead& ms_list() {return this->m_ms_list;} const LListHead& ms_list() const {return this->m_ms_list;} - struct llist_pods list; + LListHead& list(); + const LListHead& list() const; + uint32_t state_flags; enum gprs_rlcmac_tbf_direction direction; struct gprs_rlcmac_trx *trx; @@ -251,6 +231,7 @@ protected: uint8_t m_ms_class; private: + LListHead m_list; LListHead m_ms_list; bool m_egprs_enabled; @@ -302,6 +283,16 @@ inline void gprs_rlcmac_tbf::set_state(enum gprs_rlcmac_tbf_state new_state) state = new_state; } +inline LListHead& gprs_rlcmac_tbf::list() +{ + return this->m_list; +} + +inline const LListHead& gprs_rlcmac_tbf::list() const +{ + return this->m_list; +} + inline GprsMs *gprs_rlcmac_tbf::ms() const { return m_ms; diff --git a/tests/alloc/AllocTest.cpp b/tests/alloc/AllocTest.cpp index d338b786..c3efd4d9 100644 --- a/tests/alloc/AllocTest.cpp +++ b/tests/alloc/AllocTest.cpp @@ -52,23 +52,23 @@ static gprs_rlcmac_tbf *tbf_alloc(struct gprs_rlcmac_bts *bts, static void check_tfi_usage(BTS *the_bts) { int pdch_no; - struct gprs_rlcmac_bts *bts = the_bts->bts_data(); struct gprs_rlcmac_tbf *tfi_usage[8][8][2][32] = {{{{NULL}}}}; - struct llist_head *tbf_lists[2] = { - &bts->ul_tbfs, - &bts->dl_tbfs + LListHead *tbf_lists[2] = { + &the_bts->ul_tbfs(), + &the_bts->dl_tbfs() }; + LListHead *pos; gprs_rlcmac_tbf *tbf; - struct llist_pods *lpods; unsigned list_idx; struct gprs_rlcmac_tbf **tbf_var; for (list_idx = 0; list_idx < ARRAY_SIZE(tbf_lists); list_idx += 1) { - llist_pods_for_each_entry(tbf, tbf_lists[list_idx], list, lpods) { + llist_for_each(pos, tbf_lists[list_idx]) { + tbf = pos->entry(); for (pdch_no = 0; pdch_no < 8; pdch_no += 1) { struct gprs_rlcmac_pdch *pdch = tbf->pdch[pdch_no]; if (pdch == NULL) -- cgit v1.2.3 From 0d05805b7612f5244077aaaa21bb1f28cbf146d9 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Thu, 7 Jan 2016 11:48:28 +0100 Subject: edge: Add max_mcs_ul and max_mcs_dl config This sets the maximum MCS encoding used for EGPRS RLC data blocks in either direction. The following VTY command are added to node config-pcu: - mcs max <1-9> set maximum for both, uplink and downlink - mcs max <1-9> <1-9> set maximum for downlink and uplink (in that order) - no mcs max do not limit Note that using a value of 4 or below for each direction implies that a GMSK-only TBF may be assumed, which for instance would allow the use of the GPRS MS class instead of the possibly more restrictive EGPRS MS class. Sponsored-by: On-Waves ehf --- src/bts.h | 1 + src/pcu_main.cpp | 2 ++ src/pcu_vty.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 52 insertions(+), 3 deletions(-) diff --git a/src/bts.h b/src/bts.h index 704a5bec..1498ced3 100644 --- a/src/bts.h +++ b/src/bts.h @@ -156,6 +156,7 @@ struct gprs_rlcmac_bts { uint8_t cs4; uint8_t initial_cs_dl, initial_cs_ul; uint8_t max_cs_dl, max_cs_ul; + uint8_t max_mcs_dl, max_mcs_ul; uint8_t force_cs; /* 0=use from BTS 1=use from VTY */ uint16_t force_llc_lifetime; /* overrides lifetime from SGSN */ uint32_t llc_discard_csec; diff --git a/src/pcu_main.cpp b/src/pcu_main.cpp index 77e1082d..4156c4b8 100644 --- a/src/pcu_main.cpp +++ b/src/pcu_main.cpp @@ -179,6 +179,8 @@ int main(int argc, char *argv[]) bts->cs_adj_lower_limit = 10; /* Increase CS if the error rate is below */ bts->max_cs_ul = 4; bts->max_cs_dl = 4; + bts->max_mcs_ul = 4; + bts->max_mcs_dl = 4; /* CS-1 to CS-4 */ bts->cs_lqual_ranges[0].low = -256; bts->cs_lqual_ranges[0].high = 6; diff --git a/src/pcu_vty.c b/src/pcu_vty.c index ce9db29a..ee3116fd 100644 --- a/src/pcu_vty.c +++ b/src/pcu_vty.c @@ -111,6 +111,15 @@ static int config_write_pcu(struct vty *vty) bts->cs_lqual_ranges[3].low, VTY_NEWLINE); + if (bts->max_mcs_dl && bts->max_mcs_ul) { + if (bts->max_mcs_ul == bts->max_mcs_dl) + vty_out(vty, " mcs max %d%s", bts->max_mcs_dl, + VTY_NEWLINE); + else + vty_out(vty, " mcs max %d %d%s", bts->max_mcs_dl, + bts->max_mcs_ul, VTY_NEWLINE); + } + if (bts->force_llc_lifetime == 0xffff) vty_out(vty, " queue lifetime infinite%s", VTY_NEWLINE); else if (bts->force_llc_lifetime) @@ -361,11 +370,12 @@ DEFUN(cfg_pcu_no_cs, return CMD_SUCCESS; } +#define CS_MAX_STR "Set maximum values for adaptive CS selection (overrides BTS config)\n" DEFUN(cfg_pcu_cs_max, cfg_pcu_cs_max_cmd, "cs max <1-4> [<1-4>]", CS_STR - "Set maximum values for adaptive CS selection (overrides BTS config)\n" + CS_MAX_STR "Maximum CS value to be used\n" "Use a different maximum CS value for the uplink") { @@ -384,8 +394,7 @@ DEFUN(cfg_pcu_cs_max, DEFUN(cfg_pcu_no_cs_max, cfg_pcu_no_cs_max_cmd, "no cs max", - NO_STR CS_STR - "Set maximum values for adaptive CS selection (overrides BTS config)\n") + NO_STR CS_STR CS_MAX_STR) { struct gprs_rlcmac_bts *bts = bts_main_data(); @@ -395,6 +404,41 @@ DEFUN(cfg_pcu_no_cs_max, return CMD_SUCCESS; } +#define MCS_STR "Modulation and Coding Scheme configuration (EGPRS)\n" + +DEFUN(cfg_pcu_mcs_max, + cfg_pcu_mcs_max_cmd, + "mcs max <1-4> [<1-4>]", + MCS_STR + CS_MAX_STR + "Maximum MCS value to be used\n" + "Use a different maximum MCS value for the uplink") +{ + struct gprs_rlcmac_bts *bts = bts_main_data(); + uint8_t mcs = atoi(argv[0]); + + bts->max_mcs_dl = mcs; + if (argc > 1) + bts->max_mcs_ul = atoi(argv[1]); + else + bts->max_mcs_ul = mcs; + + return CMD_SUCCESS; +} + +DEFUN(cfg_pcu_no_mcs_max, + cfg_pcu_no_mcs_max_cmd, + "no mcs max", + NO_STR MCS_STR CS_MAX_STR) +{ + struct gprs_rlcmac_bts *bts = bts_main_data(); + + bts->max_mcs_dl = 0; + bts->max_mcs_ul = 0; + + return CMD_SUCCESS; +} + #define QUEUE_STR "Packet queue options\n" #define LIFETIME_STR "Set lifetime limit of LLC frame in centi-seconds " \ "(overrides the value given by SGSN)\n" @@ -848,6 +892,8 @@ int pcu_vty_init(const struct log_info *cat) install_element(PCU_NODE, &cfg_pcu_cs_downgrade_thrsh_cmd); install_element(PCU_NODE, &cfg_pcu_no_cs_downgrade_thrsh_cmd); install_element(PCU_NODE, &cfg_pcu_cs_lqual_ranges_cmd); + install_element(PCU_NODE, &cfg_pcu_mcs_max_cmd); + install_element(PCU_NODE, &cfg_pcu_no_mcs_max_cmd); install_element(PCU_NODE, &cfg_pcu_queue_lifetime_cmd); install_element(PCU_NODE, &cfg_pcu_queue_lifetime_inf_cmd); install_element(PCU_NODE, &cfg_pcu_no_queue_lifetime_cmd); -- cgit v1.2.3 From 4c9e549aa3d65c6b8c6b001895904cc82cb81a64 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Mon, 4 Jan 2016 16:00:05 +0100 Subject: edge: Add methods and operators to GprsCodingScheme Add a few new operators and methods to support the use of GprsCodingScheme instead of the plain integer currently used. Sponsored-by: On-Waves ehf --- src/gprs_coding_scheme.cpp | 56 ++++++++++++++++++++++++ src/gprs_coding_scheme.h | 106 ++++++++++++++++++++++++++++++++------------- src/tbf_dl.cpp | 2 +- tests/edge/EdgeTest.cpp | 7 +-- 4 files changed, 138 insertions(+), 33 deletions(-) diff --git a/src/gprs_coding_scheme.cpp b/src/gprs_coding_scheme.cpp index 04eb3b6f..a4601039 100644 --- a/src/gprs_coding_scheme.cpp +++ b/src/gprs_coding_scheme.cpp @@ -120,3 +120,59 @@ GprsCodingScheme::HeaderType GprsCodingScheme::headerTypeData() const { return mcs_info[m_scheme].data_hdr; } + +void GprsCodingScheme::inc(Mode mode) +{ + if (!isCompatible(mode)) + /* This should not happen. TODO: Use assert? */ + return; + + Scheme new_cs(Scheme(m_scheme + 1)); + if (!GprsCodingScheme(new_cs).isCompatible(mode)) + /* Clipping, do not change the value */ + return; + + m_scheme = new_cs; +} + +void GprsCodingScheme::dec(Mode mode) +{ + if (!isCompatible(mode)) + /* This should not happen. TODO: Use assert? */ + return; + + Scheme new_cs(Scheme(m_scheme - 1)); + if (!GprsCodingScheme(new_cs).isCompatible(mode)) + /* Clipping, do not change the value */ + return; + + m_scheme = new_cs; +} + +void GprsCodingScheme::inc() +{ + if (isGprs() && m_scheme == CS4) + return; + + if (isEgprs() && m_scheme == MCS9) + return; + + if (!isValid()) + return; + + m_scheme = Scheme(m_scheme + 1); +} + +void GprsCodingScheme::dec() +{ + if (isGprs() && m_scheme == CS1) + return; + + if (isEgprs() && m_scheme == MCS1) + return; + + if (!isValid()) + return; + + m_scheme = Scheme(m_scheme - 1); +} diff --git a/src/gprs_coding_scheme.h b/src/gprs_coding_scheme.h index a91d1bde..d1fc064f 100644 --- a/src/gprs_coding_scheme.h +++ b/src/gprs_coding_scheme.h @@ -53,16 +53,23 @@ public: operator bool() const {return m_scheme != UNKNOWN;} operator int() const {return (int)m_scheme;} - void operator =(Scheme s); - void operator =(GprsCodingScheme o); + operator Scheme() const {return m_scheme;} + unsigned int to_num() const; + + GprsCodingScheme& operator =(Scheme s); + GprsCodingScheme& operator =(GprsCodingScheme o); + bool isValid() const {return UNKNOWN <= m_scheme && m_scheme <= MCS9;} bool isGprs() const {return CS1 <= m_scheme && m_scheme <= CS4;} bool isEgprs() const {return m_scheme >= MCS1;} bool isEgprsGmsk() const {return isEgprs() && m_scheme <= MCS4;} bool isCompatible(Mode mode) const; + bool isCompatible(GprsCodingScheme o) const; void inc(Mode mode); void dec(Mode mode); + void inc(); + void dec(); unsigned int sizeUL() const; unsigned int sizeDL() const; @@ -77,11 +84,24 @@ public: HeaderType headerTypeControl() const; static GprsCodingScheme getBySizeUL(unsigned size); + static GprsCodingScheme getGprsByNum(unsigned num); + static GprsCodingScheme getEgprsByNum(unsigned num); private: enum Scheme m_scheme; }; +inline unsigned int GprsCodingScheme::to_num() const +{ + if (isGprs()) + return (m_scheme - CS1) + 1; + + if (isEgprs()) + return (m_scheme - MCS1) + 1; + + return 0; +} + inline bool GprsCodingScheme::isCompatible(Mode mode) const { switch (mode) { @@ -93,32 +113,9 @@ inline bool GprsCodingScheme::isCompatible(Mode mode) const return false; } -inline void GprsCodingScheme::inc(Mode mode) +inline bool GprsCodingScheme::isCompatible(GprsCodingScheme o) const { - if (!isCompatible(mode)) - /* This should not happen. TODO: Use assert? */ - return; - - Scheme new_cs(Scheme(m_scheme + 1)); - if (!GprsCodingScheme(new_cs).isCompatible(mode)) - /* Clipping, do not change the value */ - return; - - m_scheme = new_cs; -} - -inline void GprsCodingScheme::dec(Mode mode) -{ - if (!isCompatible(mode)) - /* This should not happen. TODO: Use assert? */ - return; - - Scheme new_cs(Scheme(m_scheme - 1)); - if (!GprsCodingScheme(new_cs).isCompatible(mode)) - /* Clipping, do not change the value */ - return; - - m_scheme = new_cs; + return (isGprs() && o.isGprs()) || (isEgprs() && o.isEgprs()); } inline GprsCodingScheme::HeaderType GprsCodingScheme::headerTypeControl() const @@ -133,15 +130,66 @@ inline GprsCodingScheme::GprsCodingScheme(Scheme s) m_scheme = UNKNOWN; } -inline void GprsCodingScheme::operator =(Scheme s) +inline GprsCodingScheme& GprsCodingScheme::operator =(Scheme s) { m_scheme = s; if (!isValid()) m_scheme = UNKNOWN; + + return *this; } -inline void GprsCodingScheme::operator =(GprsCodingScheme o) +inline GprsCodingScheme& GprsCodingScheme::operator =(GprsCodingScheme o) { m_scheme = o.m_scheme; + return *this; +} + +inline GprsCodingScheme GprsCodingScheme::getGprsByNum(unsigned num) +{ + if (num < 1 || num > 4) + return GprsCodingScheme(); + + return GprsCodingScheme(Scheme(CS1 + (num - 1))); +} + +inline GprsCodingScheme GprsCodingScheme::getEgprsByNum(unsigned num) +{ + if (num < 1 || num > 9) + return GprsCodingScheme(); + + return GprsCodingScheme(Scheme(MCS1 + (num - 1))); +} + +/* The coding schemes form a partial ordering */ +inline bool operator ==(GprsCodingScheme a, GprsCodingScheme b) +{ + return int(a) == int(b); +} + +inline bool operator !=(GprsCodingScheme a, GprsCodingScheme b) +{ + return !(a == b); +} + +inline bool operator <(GprsCodingScheme a, GprsCodingScheme b) +{ + return a.isCompatible(b) && int(a) < int(b); } + +inline bool operator >(GprsCodingScheme a, GprsCodingScheme b) +{ + return a.isCompatible(b) && int(a) > int(b); +} + +inline bool operator <=(GprsCodingScheme a, GprsCodingScheme b) +{ + return a == b || a < b; +} + +inline bool operator >=(GprsCodingScheme a, GprsCodingScheme b) +{ + return a == b || a > b; +} + diff --git a/src/tbf_dl.cpp b/src/tbf_dl.cpp index 8bac99f3..e8059929 100644 --- a/src/tbf_dl.cpp +++ b/src/tbf_dl.cpp @@ -749,7 +749,7 @@ int gprs_rlcmac_dl_tbf::analyse_errors(char *show_rbb, uint8_t ssn, /* Get statistics for current CS */ /* TODO: Use GprsCodingScheme everywhere and remove cast */ - if (rlc_data->cs != (GprsCodingScheme::Scheme)current_cs()) { + if (rlc_data->cs != GprsCodingScheme((GprsCodingScheme::Scheme)current_cs())) { /* This block has already been encoded with a different * CS, so it doesn't help us to decide, whether the * current CS is ok. Ignore it. */ diff --git a/tests/edge/EdgeTest.cpp b/tests/edge/EdgeTest.cpp index 57567741..21956593 100644 --- a/tests/edge/EdgeTest.cpp +++ b/tests/edge/EdgeTest.cpp @@ -113,7 +113,8 @@ static void test_coding_scheme() GprsCodingScheme cs; OSMO_ASSERT(!cs); - OSMO_ASSERT(cs == GprsCodingScheme::UNKNOWN); + OSMO_ASSERT(GprsCodingScheme::Scheme(cs) == GprsCodingScheme::UNKNOWN); + OSMO_ASSERT(cs == GprsCodingScheme(GprsCodingScheme::UNKNOWN)); OSMO_ASSERT(!cs.isCompatible(GprsCodingScheme::GPRS)); OSMO_ASSERT(!cs.isCompatible(GprsCodingScheme::EGPRS_GMSK)); OSMO_ASSERT(!cs.isCompatible(GprsCodingScheme::EGPRS)); @@ -126,7 +127,7 @@ static void test_coding_scheme() OSMO_ASSERT(current_cs.isGprs()); OSMO_ASSERT(!current_cs.isEgprs()); OSMO_ASSERT(!current_cs.isEgprsGmsk()); - OSMO_ASSERT(current_cs == gprs_schemes[i]); + OSMO_ASSERT(GprsCodingScheme::Scheme(current_cs) == gprs_schemes[i]); OSMO_ASSERT(current_cs == GprsCodingScheme(gprs_schemes[i])); /* Check strong monotonicity */ @@ -153,7 +154,7 @@ static void test_coding_scheme() OSMO_ASSERT(!current_cs.isGprs()); OSMO_ASSERT(current_cs.isEgprs()); OSMO_ASSERT(!!current_cs.isEgprsGmsk() == !!egprs_schemes[i].is_gmsk); - OSMO_ASSERT(current_cs == egprs_schemes[i].s); + OSMO_ASSERT(GprsCodingScheme::Scheme(current_cs) == egprs_schemes[i].s); OSMO_ASSERT(current_cs == GprsCodingScheme(egprs_schemes[i].s)); /* Check strong monotonicity */ -- cgit v1.2.3 From 96ccea8436f9a5bbd9f459c6c1bdb9a24dd2bed9 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Thu, 7 Jan 2016 15:00:43 +0100 Subject: edge: Add initial_mcs_dl and initial_mcs_ul config values Provide the initial MCS values for EGPRS data blocks. They are set to 1 (MCS-1) for each direction and there is no support to change these configuration values yet (the automatic adaption still works, so there is probably no need to set these values). Sponsored-by: On-Waves ehf --- src/bts.h | 1 + src/pcu_main.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/src/bts.h b/src/bts.h index 1498ced3..0928f8d7 100644 --- a/src/bts.h +++ b/src/bts.h @@ -155,6 +155,7 @@ struct gprs_rlcmac_bts { uint8_t cs3; uint8_t cs4; uint8_t initial_cs_dl, initial_cs_ul; + uint8_t initial_mcs_dl, initial_mcs_ul; uint8_t max_cs_dl, max_cs_ul; uint8_t max_mcs_dl, max_mcs_ul; uint8_t force_cs; /* 0=use from BTS 1=use from VTY */ diff --git a/src/pcu_main.cpp b/src/pcu_main.cpp index 4156c4b8..39de0555 100644 --- a/src/pcu_main.cpp +++ b/src/pcu_main.cpp @@ -163,6 +163,7 @@ int main(int argc, char *argv[]) bts = bts_main_data(); bts->fc_interval = 1; bts->initial_cs_dl = bts->initial_cs_ul = 1; + bts->initial_mcs_dl = bts->initial_mcs_ul = 1; bts->cs1 = 1; bts->t3142 = 20; bts->t3169 = 5; -- cgit v1.2.3 From cb7289094a40f179f6c538780f3117f7ad9688bd Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Tue, 5 Jan 2016 15:33:03 +0100 Subject: edge: Replace integer cs by GprsCodingScheme Currently the TBF and MS object use a plain integer value (current_cs) to manage the coding scheme. This makes it difficult to support the MCS schemes. GprsCodingScheme supports a partial ordering of these values (CS and MCS) and provides safe increment and decrement methods. Use the GprsCodingScheme type instead of integer for cs fields and variables. Add a 'mode' to GprsMs which can be set to either GPRS, EGPRS, or EGPRS_GMSK which also set the initial values of current_cs_ul/dl. Select the mode based on max_mcs_ul and max_mcs_dl. Sponsored-by: On-Waves ehf --- src/encoding.cpp | 6 +- src/gprs_ms.cpp | 218 ++++++++++++++++++++++++++++++++++------------ src/gprs_ms.h | 21 +++-- src/pcu_vty_functions.cpp | 12 +-- src/tbf.cpp | 28 +++--- src/tbf.h | 2 +- src/tbf_dl.cpp | 17 ++-- tests/ms/MsTest.cpp | 4 +- tests/tbf/TbfTest.err | 140 ++++++++++++++--------------- 9 files changed, 284 insertions(+), 164 deletions(-) diff --git a/src/encoding.cpp b/src/encoding.cpp index 158625e6..acd8f43d 100644 --- a/src/encoding.cpp +++ b/src/encoding.cpp @@ -193,7 +193,7 @@ void Encoding::write_packet_uplink_assignment( if (!use_egprs) { bitvec_write_field(dest, wp,0x0,1); // Message escape - bitvec_write_field(dest, wp,tbf->current_cs()-1, 2); // CHANNEL_CODING_COMMAND + bitvec_write_field(dest, wp,tbf->current_cs().to_num()-1, 2); // CHANNEL_CODING_COMMAND bitvec_write_field(dest, wp,0x1,1); // TLLI_BLOCK_CHANNEL_CODING bitvec_write_field(dest, wp,0x1,1); // switch TIMING_ADVANCE_VALUE = on bitvec_write_field(dest, wp,tbf->ta(),6); // TIMING_ADVANCE_VALUE @@ -209,7 +209,7 @@ void Encoding::write_packet_uplink_assignment( bitvec_write_field(dest, wp,0x0,2); // EGPRS message contents bitvec_write_field(dest, wp,0x0,1); // No CONTENTION_RESOLUTION_TLLI bitvec_write_field(dest, wp,0x0,1); // No COMPACT reduced MA - bitvec_write_field(dest, wp,tbf->current_cs()-1, 4); // EGPRS Modulation and Coding IE + bitvec_write_field(dest, wp,tbf->current_cs().to_num()-1, 4); // EGPRS Modulation and Coding IE bitvec_write_field(dest, wp,0x0,1); // No RESEGMENT bitvec_write_field(dest, wp,0x0,5); // EGPRS Window Size = 64 bitvec_write_field(dest, wp,0x0,1); // No Access Technologies Request @@ -426,7 +426,7 @@ static void write_packet_uplink_ack_gprs( struct gprs_rlcmac_ul_tbf *tbf, bool is_final) { - bitvec_write_field(dest, wp, tbf->current_cs() - 1, 2); // CHANNEL_CODING_COMMAND + bitvec_write_field(dest, wp, tbf->current_cs().to_num() - 1, 2); // CHANNEL_CODING_COMMAND write_packet_ack_nack_desc_gprs(bts, dest, wp, &tbf->m_window, is_final); bitvec_write_field(dest, wp, 1, 1); // 1: have CONTENTION_RESOLUTION_TLLI diff --git a/src/gprs_ms.cpp b/src/gprs_ms.cpp index 2d482846..187132f5 100644 --- a/src/gprs_ms.cpp +++ b/src/gprs_ms.cpp @@ -97,8 +97,6 @@ GprsMs::GprsMs(BTS *bts, uint32_t tlli) : m_ta(0), m_ms_class(0), m_egprs_ms_class(0), - m_current_cs_ul(1), - m_current_cs_dl(1), m_is_idle(true), m_ref(0), m_list(this), @@ -107,7 +105,8 @@ GprsMs::GprsMs(BTS *bts, uint32_t tlli) : m_reserved_dl_slots(0), m_reserved_ul_slots(0), m_current_trx(NULL), - m_codel_state(NULL) + m_codel_state(NULL), + m_mode(GprsCodingScheme::GPRS) { int codel_interval = LLC_CODEL_USE_DEFAULT; @@ -117,17 +116,11 @@ GprsMs::GprsMs(BTS *bts, uint32_t tlli) : memset(&m_timer, 0, sizeof(m_timer)); m_timer.cb = GprsMs::timeout; m_llc_queue.init(); - if (m_bts) { - m_current_cs_ul = m_bts->bts_data()->initial_cs_ul; - if (m_current_cs_ul < 1) - m_current_cs_ul = 1; - m_current_cs_dl = m_bts->bts_data()->initial_cs_dl; - if (m_current_cs_dl < 1) - m_current_cs_dl = 1; + set_mode(m_mode); + if (m_bts) codel_interval = m_bts->bts_data()->llc_codel_interval_msec; - } if (codel_interval) { if (codel_interval == LLC_CODEL_USE_DEFAULT) @@ -215,6 +208,42 @@ void GprsMs::stop_timer() unref(); } +void GprsMs::set_mode(GprsCodingScheme::Mode mode) +{ + m_mode = mode; + + switch (m_mode) { + case GprsCodingScheme::GPRS: + if (m_bts) { + m_current_cs_ul = GprsCodingScheme::getGprsByNum( + m_bts->bts_data()->initial_cs_ul); + m_current_cs_dl = GprsCodingScheme::getGprsByNum( + m_bts->bts_data()->initial_cs_dl); + } + if (!m_current_cs_ul.isGprs()) + m_current_cs_ul = GprsCodingScheme::CS1; + if (!m_current_cs_dl.isGprs()) + m_current_cs_dl = GprsCodingScheme::CS1; + + break; + + case GprsCodingScheme::EGPRS_GMSK: + case GprsCodingScheme::EGPRS: + if (m_bts) { + m_current_cs_ul = GprsCodingScheme::getEgprsByNum( + m_bts->bts_data()->initial_mcs_ul); + m_current_cs_dl = GprsCodingScheme::getEgprsByNum( + m_bts->bts_data()->initial_mcs_dl); + } + if (!m_current_cs_ul.isEgprs()) + m_current_cs_ul = GprsCodingScheme::MCS1; + if (!m_current_cs_dl.isEgprs()) + m_current_cs_dl = GprsCodingScheme::MCS1; + + break; + } +} + void GprsMs::attach_tbf(struct gprs_rlcmac_tbf *tbf) { if (tbf->direction == GPRS_RLCMAC_DL_TBF) @@ -464,9 +493,9 @@ void GprsMs::update_error_rate(gprs_rlcmac_tbf *tbf, int error_rate) { struct gprs_rlcmac_bts *bts_data; int64_t now; - uint8_t max_cs_dl = 4; + GprsCodingScheme max_cs_dl = this->max_cs_dl(); - OSMO_ASSERT(m_bts != NULL); + OSMO_ASSERT(max_cs_dl); bts_data = m_bts->bts_data(); if (error_rate < 0) @@ -474,32 +503,30 @@ void GprsMs::update_error_rate(gprs_rlcmac_tbf *tbf, int error_rate) now = now_msec(); - if (bts_data->max_cs_dl) - max_cs_dl = bts_data->max_cs_dl; - /* TODO: Check for TBF direction */ /* TODO: Support different CS values for UL and DL */ m_nack_rate_dl = error_rate; if (error_rate > bts_data->cs_adj_upper_limit) { - if (m_current_cs_dl > 1) { - m_current_cs_dl -= 1; + if (m_current_cs_dl.to_num() > 1) { + m_current_cs_dl.dec(mode()); LOGP(DRLCMACDL, LOGL_INFO, "MS (IMSI %s): High error rate %d%%, " - "reducing CS level to %d\n", - imsi(), error_rate, m_current_cs_dl); + "reducing CS level to %s\n", + imsi(), error_rate, m_current_cs_dl.name()); m_last_cs_not_low = now; } } else if (error_rate < bts_data->cs_adj_lower_limit) { if (m_current_cs_dl < max_cs_dl) { if (now - m_last_cs_not_low > 1000) { - m_current_cs_dl += 1; + m_current_cs_dl.inc(mode()); LOGP(DRLCMACDL, LOGL_INFO, "MS (IMSI %s): Low error rate %d%%, " - "increasing DL CS level to %d\n", - imsi(), error_rate, m_current_cs_dl); + "increasing DL CS level to %s\n", + imsi(), error_rate, + m_current_cs_dl.name()); m_last_cs_not_low = now; } else { LOGP(DRLCMACDL, LOGL_DEBUG, @@ -516,46 +543,125 @@ void GprsMs::update_error_rate(gprs_rlcmac_tbf *tbf, int error_rate) } } -void GprsMs::update_l1_meas(const pcu_l1_meas *meas) +GprsCodingScheme GprsMs::max_cs_ul() const { struct gprs_rlcmac_bts *bts_data; - uint8_t max_cs_ul = 4; - unsigned i; OSMO_ASSERT(m_bts != NULL); bts_data = m_bts->bts_data(); - if (bts_data->max_cs_ul) - max_cs_ul = bts_data->max_cs_ul; + if (m_current_cs_ul.isGprs()) { + if (!bts_data->max_cs_ul) + return GprsCodingScheme(GprsCodingScheme::CS4); - if (meas->have_link_qual) { - int old_link_qual = meas->link_qual; - int low = bts_data->cs_lqual_ranges[current_cs_ul()-1].low; - int high = bts_data->cs_lqual_ranges[current_cs_ul()-1].high; - uint8_t new_cs_ul = m_current_cs_ul; + return GprsCodingScheme::getGprsByNum(bts_data->max_cs_ul); + } - if (m_l1_meas.have_link_qual) - old_link_qual = m_l1_meas.link_qual; + if (!m_current_cs_ul.isEgprs()) + return GprsCodingScheme(); /* UNKNOWN */ - if (meas->link_qual < low && old_link_qual < low) - new_cs_ul = m_current_cs_ul - 1; - else if (meas->link_qual > high && old_link_qual > high && - m_current_cs_ul < max_cs_ul) - new_cs_ul = m_current_cs_ul + 1; + if (bts_data->max_mcs_ul) + return GprsCodingScheme::getEgprsByNum(bts_data->max_mcs_ul); + else if (bts_data->max_cs_ul) + return GprsCodingScheme::getEgprsByNum(bts_data->max_cs_ul); - if (m_current_cs_ul != new_cs_ul) { - LOGP(DRLCMACDL, LOGL_INFO, - "MS (IMSI %s): " - "Link quality %ddB (%ddB) left window [%d, %d], " - "modifying uplink CS level: %d -> %d\n", - imsi(), meas->link_qual, old_link_qual, - low, high, - m_current_cs_ul, new_cs_ul); - - m_current_cs_ul = new_cs_ul; - } + return GprsCodingScheme(GprsCodingScheme::MCS4); +} + +GprsCodingScheme GprsMs::max_cs_dl() const +{ + struct gprs_rlcmac_bts *bts_data; + + OSMO_ASSERT(m_bts != NULL); + bts_data = m_bts->bts_data(); + + if (m_current_cs_dl.isGprs()) { + if (!bts_data->max_cs_dl) + return GprsCodingScheme(GprsCodingScheme::CS4); + + return GprsCodingScheme::getGprsByNum(bts_data->max_cs_dl); + } + + if (!m_current_cs_dl.isEgprs()) + return GprsCodingScheme(); /* UNKNOWN */ + + if (bts_data->max_mcs_dl) + return GprsCodingScheme::getEgprsByNum(bts_data->max_mcs_dl); + else if (bts_data->max_cs_dl) + return GprsCodingScheme::getEgprsByNum(bts_data->max_cs_dl); + + return GprsCodingScheme(GprsCodingScheme::MCS4); +} + +void GprsMs::update_cs_ul(const pcu_l1_meas *meas) +{ + struct gprs_rlcmac_bts *bts_data; + GprsCodingScheme max_cs_ul = this->max_cs_ul(); + + int old_link_qual; + int low; + int high; + GprsCodingScheme new_cs_ul = m_current_cs_ul; + unsigned current_cs_num = m_current_cs_ul.to_num(); + + bts_data = m_bts->bts_data(); + + if (!max_cs_ul) { + LOGP(DRLCMACDL, LOGL_ERROR, + "max_cs_ul cannot be derived (current UL CS: %s)\n", + m_current_cs_ul.name()); + return; } + if (!m_current_cs_ul) + return; + + if (!meas->have_link_qual) + return; + + old_link_qual = meas->link_qual; + + if (m_current_cs_ul.isGprs()) { + low = bts_data->cs_lqual_ranges[current_cs_num-1].low; + high = bts_data->cs_lqual_ranges[current_cs_num-1].high; + } else if (m_current_cs_ul.isEgprs()) { + /* TODO, use separate table */ + if (current_cs_num > 4) + current_cs_num = 4; + low = bts_data->cs_lqual_ranges[current_cs_num-1].low; + high = bts_data->cs_lqual_ranges[current_cs_num-1].high; + } else { + return; + } + + if (m_l1_meas.have_link_qual) + old_link_qual = m_l1_meas.link_qual; + + if (meas->link_qual < low && old_link_qual < low) + new_cs_ul.dec(mode()); + else if (meas->link_qual > high && old_link_qual > high && + m_current_cs_ul < max_cs_ul) + new_cs_ul.inc(mode()); + + if (m_current_cs_ul != new_cs_ul) { + LOGP(DRLCMACDL, LOGL_INFO, + "MS (IMSI %s): " + "Link quality %ddB (%ddB) left window [%d, %d], " + "modifying uplink CS level: %s -> %s\n", + imsi(), meas->link_qual, old_link_qual, + low, high, + m_current_cs_ul.name(), new_cs_ul.name()); + + m_current_cs_ul = new_cs_ul; + } +} + +void GprsMs::update_l1_meas(const pcu_l1_meas *meas) +{ + unsigned i; + + update_cs_ul(meas); + if (meas->have_rssi) m_l1_meas.set_rssi(meas->rssi); if (meas->have_bto) @@ -582,9 +688,9 @@ void GprsMs::update_l1_meas(const pcu_l1_meas *meas) } } -uint8_t GprsMs::current_cs_dl() const +GprsCodingScheme GprsMs::current_cs_dl() const { - uint8_t cs = m_current_cs_dl; + GprsCodingScheme cs = m_current_cs_dl; size_t unencoded_octets; if (!m_bts) @@ -605,11 +711,11 @@ uint8_t GprsMs::current_cs_dl() const return cs; /* The throughput would probably be better if the CS level was reduced */ - cs -= 1; + cs.dec(mode()); /* CS-2 doesn't gain throughput with small packets, further reduce to CS-1 */ - if (cs == 2) - cs -= 1; + if (cs == GprsCodingScheme(GprsCodingScheme::CS2)) + cs.dec(mode()); return cs; } diff --git a/src/gprs_ms.h b/src/gprs_ms.h index f9b63f26..246f71e4 100644 --- a/src/gprs_ms.h +++ b/src/gprs_ms.h @@ -74,6 +74,8 @@ public: bool check_tlli(uint32_t tlli); void reset(); + GprsCodingScheme::Mode mode() const; + void set_mode(GprsCodingScheme::Mode mode); const char *imsi() const; void set_imsi(const char *imsi); @@ -85,8 +87,10 @@ public: void set_ms_class(uint8_t ms_class); void set_egprs_ms_class(uint8_t ms_class); - uint8_t current_cs_ul() const; - uint8_t current_cs_dl() const; + GprsCodingScheme current_cs_ul() const; + GprsCodingScheme current_cs_dl() const; + GprsCodingScheme max_cs_ul() const; + GprsCodingScheme max_cs_dl() const; int first_common_ts() const; uint8_t dl_slots() const; @@ -134,6 +138,7 @@ protected: void unref(); void start_timer(); void stop_timer(); + void update_cs_ul(const pcu_l1_meas*); private: BTS *m_bts; @@ -152,8 +157,8 @@ private: uint8_t m_ms_class; uint8_t m_egprs_ms_class; /* current coding scheme */ - uint8_t m_current_cs_ul; - uint8_t m_current_cs_dl; + GprsCodingScheme m_current_cs_ul; + GprsCodingScheme m_current_cs_dl; gprs_llc_queue m_llc_queue; @@ -172,6 +177,7 @@ private: gprs_rlcmac_trx *m_current_trx; struct gprs_codel *m_codel_state; + GprsCodingScheme::Mode m_mode; }; inline bool GprsMs::is_idle() const @@ -220,11 +226,16 @@ inline uint8_t GprsMs::egprs_ms_class() const return m_egprs_ms_class; } -inline uint8_t GprsMs::current_cs_ul() const +inline GprsCodingScheme GprsMs::current_cs_ul() const { return m_current_cs_ul; } +inline GprsCodingScheme::Mode GprsMs::mode() const +{ + return m_mode; +} + inline void GprsMs::set_timeout(unsigned secs) { m_delay = secs; diff --git a/src/pcu_vty_functions.cpp b/src/pcu_vty_functions.cpp index 7082d990..c0592338 100644 --- a/src/pcu_vty_functions.cpp +++ b/src/pcu_vty_functions.cpp @@ -55,7 +55,8 @@ static void tbf_print_vty_info(struct vty *vty, gprs_rlcmac_tbf *tbf) if (tbf->pdch[i]) vty_out(vty, "%d ", i); } - vty_out(vty, " CS=%d%s%s", tbf->ms() ? tbf->ms()->current_cs_dl() : 1, + vty_out(vty, " CS=%s%s%s", + tbf->ms() ? tbf->ms()->current_cs_dl().name() : "???", VTY_NEWLINE, VTY_NEWLINE); } @@ -83,10 +84,11 @@ int pcu_vty_show_ms_all(struct vty *vty, struct gprs_rlcmac_bts *bts_data) llist_for_each(ms_iter, &bts->ms_store().ms_list()) { GprsMs *ms = ms_iter->entry(); - vty_out(vty, "MS TLLI=%08x, TA=%d, CS-UL=%d, CS-DL=%d, LLC=%d, " + vty_out(vty, "MS TLLI=%08x, TA=%d, CS-UL=%s, CS-DL=%s, LLC=%d, " "IMSI=%s%s", ms->tlli(), - ms->ta(), ms->current_cs_ul(), ms->current_cs_dl(), + ms->ta(), ms->current_cs_ul().name(), + ms->current_cs_dl().name(), ms->llc_queue()->size(), ms->imsi(), VTY_NEWLINE); @@ -101,9 +103,9 @@ static int show_ms(struct vty *vty, GprsMs *ms) vty_out(vty, "MS TLLI=%08x, IMSI=%s%s", ms->tlli(), ms->imsi(), VTY_NEWLINE); vty_out(vty, " Timing advance (TA): %d%s", ms->ta(), VTY_NEWLINE); - vty_out(vty, " Coding scheme uplink: CS-%d%s", ms->current_cs_ul(), + vty_out(vty, " Coding scheme uplink: %s%s", ms->current_cs_ul().name(), VTY_NEWLINE); - vty_out(vty, " Coding scheme downlink: CS-%d%s", ms->current_cs_dl(), + vty_out(vty, " Coding scheme downlink: %s%s", ms->current_cs_dl().name(), VTY_NEWLINE); vty_out(vty, " MS class: %d%s", ms->ms_class(), VTY_NEWLINE); vty_out(vty, " EGPRS MS class: %d%s", ms->egprs_ms_class(), VTY_NEWLINE); diff --git a/src/tbf.cpp b/src/tbf.cpp index 185f0bd7..0da05573 100644 --- a/src/tbf.cpp +++ b/src/tbf.cpp @@ -165,15 +165,15 @@ void gprs_rlcmac_tbf::set_ms_class(uint8_t ms_class_) m_ms_class = ms_class_; } -uint8_t gprs_rlcmac_tbf::current_cs() const +GprsCodingScheme gprs_rlcmac_tbf::current_cs() const { - uint8_t cs; + GprsCodingScheme cs; if (direction == GPRS_RLCMAC_UL_TBF) - cs = m_ms ? m_ms->current_cs_ul() : bts->bts_data()->initial_cs_ul; + cs = m_ms ? m_ms->current_cs_ul() : GprsCodingScheme(); else - cs = m_ms ? m_ms->current_cs_dl() : bts->bts_data()->initial_cs_dl; + cs = m_ms ? m_ms->current_cs_dl() : GprsCodingScheme(); - return cs < 1 ? 1 : cs; + return cs; } gprs_llc_queue *gprs_rlcmac_tbf::llc_queue() @@ -543,10 +543,8 @@ static int setup_tbf(struct gprs_rlcmac_tbf *tbf, bts = tbf->bts->bts_data(); - if (tbf->is_egprs_enabled()) { - /* TODO: only for 8PSK, otherwise the GPRS MS class has to be used */ + if (ms->mode() == GprsCodingScheme::EGPRS) ms_class = egprs_ms_class; - } tbf->m_created_ts = time(NULL); tbf->set_ms_class(ms_class); @@ -592,6 +590,17 @@ static int ul_tbf_dtor(struct gprs_rlcmac_ul_tbf *tbf) return 0; } +static void setup_egprs_mode(gprs_rlcmac_bts *bts, GprsMs *ms) +{ + if (GprsCodingScheme::getEgprsByNum(bts->max_mcs_ul).isEgprsGmsk() && + GprsCodingScheme::getEgprsByNum(bts->max_mcs_dl).isEgprsGmsk() && + ms->mode() != GprsCodingScheme::EGPRS) + { + ms->set_mode(GprsCodingScheme::EGPRS_GMSK); + } else { + ms->set_mode(GprsCodingScheme::EGPRS); + } +} struct gprs_rlcmac_ul_tbf *tbf_alloc_ul_tbf(struct gprs_rlcmac_bts *bts, GprsMs *ms, int8_t use_trx, @@ -616,11 +625,10 @@ struct gprs_rlcmac_ul_tbf *tbf_alloc_ul_tbf(struct gprs_rlcmac_bts *bts, ms = bts->bts->ms_alloc(ms_class, egprs_ms_class); if (egprs_ms_class > 0 && bts->egprs_enabled) { - /* TODO: only for 8PSK, otherwise the GPRS MS class has to be used */ - ms_class = egprs_ms_class; tbf->enable_egprs(); tbf->m_window.set_sns(RLC_EGPRS_SNS); tbf->m_window.set_ws(RLC_EGPRS_MIN_WS); + setup_egprs_mode(bts, ms); } rc = setup_tbf(tbf, ms, use_trx, ms_class, egprs_ms_class, single_slot); diff --git a/src/tbf.h b/src/tbf.h index 8ba65756..b00f4d54 100644 --- a/src/tbf.h +++ b/src/tbf.h @@ -134,7 +134,7 @@ struct gprs_rlcmac_tbf { void set_ta(uint8_t); uint8_t ms_class() const; void set_ms_class(uint8_t); - uint8_t current_cs() const; + GprsCodingScheme current_cs() const; gprs_llc_queue *llc_queue(); const gprs_llc_queue *llc_queue() const; diff --git a/src/tbf_dl.cpp b/src/tbf_dl.cpp index e8059929..9e73a0e3 100644 --- a/src/tbf_dl.cpp +++ b/src/tbf_dl.cpp @@ -425,21 +425,15 @@ struct msgb *gprs_rlcmac_dl_tbf::create_new_bsn(const uint32_t fn, const uint8_t uint16_t space, chunk; gprs_rlc_data *rlc_data; const uint16_t bsn = m_window.v_s(); - uint8_t cs_n = 1; + GprsCodingScheme cs = current_cs(); if (m_llc.frame_length() == 0) schedule_next_frame(); - cs_n = current_cs(); + LOGP(DRLCMACDL, LOGL_DEBUG, "- Sending new block at BSN %d, CS=%s\n", + m_window.v_s(), cs.name()); - LOGP(DRLCMACDL, LOGL_DEBUG, "- Sending new block at BSN %d, CS=%d\n", - m_window.v_s(), cs_n); - - OSMO_ASSERT(cs_n >= 1); - OSMO_ASSERT(cs_n <= 4); - - /* TODO: Use GprsCodingScheme everywhere and remove cast */ - GprsCodingScheme cs((GprsCodingScheme::Scheme)cs_n); + OSMO_ASSERT(cs.isValid()); /* total length of block, including spare bits */ const uint8_t block_length = cs.sizeDL(); @@ -748,8 +742,7 @@ int gprs_rlcmac_dl_tbf::analyse_errors(char *show_rbb, uint8_t ssn, /* Get statistics for current CS */ - /* TODO: Use GprsCodingScheme everywhere and remove cast */ - if (rlc_data->cs != GprsCodingScheme((GprsCodingScheme::Scheme)current_cs())) { + if (rlc_data->cs != current_cs()) { /* This block has already been encoded with a different * CS, so it doesn't help us to decide, whether the * current CS is ok. Ignore it. */ diff --git a/tests/ms/MsTest.cpp b/tests/ms/MsTest.cpp index 344b0b4a..0930354d 100644 --- a/tests/ms/MsTest.cpp +++ b/tests/ms/MsTest.cpp @@ -503,11 +503,11 @@ static void test_ms_cs_selection() dl_tbf->set_ms(ms); OSMO_ASSERT(!ms->is_idle()); - OSMO_ASSERT(ms->current_cs_dl() == 4); + OSMO_ASSERT(ms->current_cs_dl().to_num() == 4); bts->cs_downgrade_threshold = 200; - OSMO_ASSERT(ms->current_cs_dl() == 3); + OSMO_ASSERT(ms->current_cs_dl().to_num() == 3); talloc_free(dl_tbf); diff --git a/tests/tbf/TbfTest.err b/tests/tbf/TbfTest.err index f5509d7e..69113619 100644 --- a/tests/tbf/TbfTest.err +++ b/tests/tbf/TbfTest.err @@ -67,14 +67,14 @@ Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=0 block=0 data=4f 08 20 00 44 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==0) - Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) (len=200) -- Sending new block at BSN 0, CS=1 +- Sending new block at BSN 0, CS=CS-1 -- Chunk with length 200 larger than space (20) left in block: copy only remaining space, and we are done data block: 07 00 01 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=4 block=1 data=07 00 01 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 Received RTS for PDCH: TRX=0 TS=4 FN=8 block_nr=2 scheduling free USF for polling at FN=13 of TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==1) -- Sending new block at BSN 1, CS=1 +- Sending new block at BSN 1, CS=CS-1 -- Chunk with length 180 larger than space (20) left in block: copy only remaining space, and we are done data block: 07 00 03 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=8 block=2 data=07 00 03 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 @@ -145,14 +145,14 @@ Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=0 block=0 data=4f 08 20 00 44 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==0) - Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) (len=200) -- Sending new block at BSN 0, CS=1 +- Sending new block at BSN 0, CS=CS-1 -- Chunk with length 200 larger than space (20) left in block: copy only remaining space, and we are done data block: 07 00 01 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=4 block=1 data=07 00 01 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 Received RTS for PDCH: TRX=0 TS=4 FN=8 block_nr=2 scheduling free USF for polling at FN=13 of TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==1) -- Sending new block at BSN 1, CS=1 +- Sending new block at BSN 1, CS=CS-1 -- Chunk with length 180 larger than space (20) left in block: copy only remaining space, and we are done data block: 07 00 03 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=8 block=2 data=07 00 03 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 @@ -223,68 +223,68 @@ Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=0 block=0 data=4f 08 20 00 44 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==0) - Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) (len=200) -- Sending new block at BSN 0, CS=1 +- Sending new block at BSN 0, CS=CS-1 -- Chunk with length 200 larger than space (20) left in block: copy only remaining space, and we are done data block: 07 00 01 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=4 block=1 data=07 00 01 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 Received RTS for PDCH: TRX=0 TS=4 FN=8 block_nr=2 scheduling free USF for polling at FN=13 of TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==1) -- Sending new block at BSN 1, CS=1 +- Sending new block at BSN 1, CS=CS-1 -- Chunk with length 180 larger than space (20) left in block: copy only remaining space, and we are done data block: 07 00 03 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=8 block=2 data=07 00 03 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==2) -- Sending new block at BSN 2, CS=1 +- Sending new block at BSN 2, CS=CS-1 -- Chunk with length 160 larger than space (20) left in block: copy only remaining space, and we are done data block: 07 00 05 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=13 block=3 data=07 00 05 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==3) -- Sending new block at BSN 3, CS=1 +- Sending new block at BSN 3, CS=CS-1 -- Chunk with length 140 larger than space (20) left in block: copy only remaining space, and we are done data block: 07 00 07 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=17 block=4 data=07 00 07 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==4) -- Sending new block at BSN 4, CS=1 +- Sending new block at BSN 4, CS=CS-1 -- Chunk with length 120 larger than space (20) left in block: copy only remaining space, and we are done data block: 07 00 09 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=21 block=5 data=07 00 09 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==5) -- Sending new block at BSN 5, CS=1 +- Sending new block at BSN 5, CS=CS-1 -- Chunk with length 100 larger than space (20) left in block: copy only remaining space, and we are done data block: 07 00 0b 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=26 block=6 data=07 00 0b 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==6) -- Sending new block at BSN 6, CS=1 +- Sending new block at BSN 6, CS=CS-1 -- Chunk with length 80 larger than space (20) left in block: copy only remaining space, and we are done data block: 07 00 0d 78 79 7a 7b 7c 7d 7e 7f 80 81 82 83 84 85 86 87 88 89 8a 8b Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=30 block=7 data=07 00 0d 78 79 7a 7b 7c 7d 7e 7f 80 81 82 83 84 85 86 87 88 89 8a 8b Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==7) -- Sending new block at BSN 7, CS=1 +- Sending new block at BSN 7, CS=CS-1 -- Chunk with length 60 larger than space (20) left in block: copy only remaining space, and we are done data block: 07 00 0f 8c 8d 8e 8f 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=34 block=8 data=07 00 0f 8c 8d 8e 8f 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==8) -- Sending new block at BSN 8, CS=1 +- Sending new block at BSN 8, CS=CS-1 -- Chunk with length 40 larger than space (20) left in block: copy only remaining space, and we are done data block: 07 00 11 a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af b0 b1 b2 b3 Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=39 block=9 data=07 00 11 a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af b0 b1 b2 b3 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==9) -- Sending new block at BSN 9, CS=1 +- Sending new block at BSN 9, CS=CS-1 -- Chunk with length 20 would exactly fit into space (20): add length header with LI=0, to make frame extend to next block, and we are done data block: 07 00 12 01 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf c0 c1 c2 c3 c4 c5 c6 Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=43 block=10 data=07 00 12 01 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf c0 c1 c2 c3 c4 c5 c6 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==10) -- Sending new block at BSN 10, CS=1 +- Sending new block at BSN 10, CS=CS-1 -- Chunk with length 1 is less than remaining space (20): add length header to to delimit LLC frame Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW)len=200 - Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) (len=200) @@ -293,61 +293,61 @@ data block: 07 00 14 07 c7 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=47 block=11 data=07 00 14 07 c7 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=4 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==11) -- Sending new block at BSN 11, CS=1 +- Sending new block at BSN 11, CS=CS-1 -- Chunk with length 182 larger than space (20) left in block: copy only remaining space, and we are done data block: 07 00 17 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=52 block=0 data=07 00 17 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=4 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==12) -- Sending new block at BSN 12, CS=1 +- Sending new block at BSN 12, CS=CS-1 -- Chunk with length 162 larger than space (20) left in block: copy only remaining space, and we are done data block: 07 00 19 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=56 block=1 data=07 00 19 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=4 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==13) -- Sending new block at BSN 13, CS=1 +- Sending new block at BSN 13, CS=CS-1 -- Chunk with length 142 larger than space (20) left in block: copy only remaining space, and we are done data block: 07 00 1b 3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=60 block=2 data=07 00 1b 3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=4 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==14) -- Sending new block at BSN 14, CS=1 +- Sending new block at BSN 14, CS=CS-1 -- Chunk with length 122 larger than space (20) left in block: copy only remaining space, and we are done data block: 07 00 1d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=65 block=3 data=07 00 1d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=4 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==15) -- Sending new block at BSN 15, CS=1 +- Sending new block at BSN 15, CS=CS-1 -- Chunk with length 102 larger than space (20) left in block: copy only remaining space, and we are done data block: 07 00 1f 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=69 block=4 data=07 00 1f 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=4 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==16) -- Sending new block at BSN 16, CS=1 +- Sending new block at BSN 16, CS=CS-1 -- Chunk with length 82 larger than space (20) left in block: copy only remaining space, and we are done data block: 07 00 21 76 77 78 79 7a 7b 7c 7d 7e 7f 80 81 82 83 84 85 86 87 88 89 Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=73 block=5 data=07 00 21 76 77 78 79 7a 7b 7c 7d 7e 7f 80 81 82 83 84 85 86 87 88 89 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=4 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==17) -- Sending new block at BSN 17, CS=1 +- Sending new block at BSN 17, CS=CS-1 -- Chunk with length 62 larger than space (20) left in block: copy only remaining space, and we are done data block: 07 00 23 8a 8b 8c 8d 8e 8f 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=78 block=6 data=07 00 23 8a 8b 8c 8d 8e 8f 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=4 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==18) -- Sending new block at BSN 18, CS=1 +- Sending new block at BSN 18, CS=CS-1 -- Chunk with length 42 larger than space (20) left in block: copy only remaining space, and we are done data block: 07 00 25 9e 9f a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af b0 b1 Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=82 block=7 data=07 00 25 9e 9f a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af b0 b1 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=4 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==19) -- Sending new block at BSN 19, CS=1 +- Sending new block at BSN 19, CS=CS-1 -- Chunk with length 22 larger than space (20) left in block: copy only remaining space, and we are done data block: 07 00 27 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf c0 c1 c2 c3 c4 c5 Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=86 block=8 data=07 00 27 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf c0 c1 c2 c3 c4 c5 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=4 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==20) -- Sending new block at BSN 20, CS=1 +- Sending new block at BSN 20, CS=CS-1 -- Chunk with length 2 is less than remaining space (20): add length header to to delimit LLC frame Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW)len=200 -- Empty chunk, added LLC dummy command of size 16, drained_since=0 @@ -385,7 +385,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) DL analysis, range=0:21, lost=0, re - V(B): (V(A)=21)""(V(S)-1=20) A=Acked N=Nacked U=Unacked X=Resend-Unacked I=Invalid Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=4 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==21 .. V(S)==21) -- Sending new block at BSN 21, CS=1 +- Sending new block at BSN 21, CS=CS-1 -- Empty chunk, added LLC dummy command of size 19, drained_since=4 -- Chunk with length 19 is less than remaining space (20): add length header to to delimit LLC frame Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW)len=19 @@ -401,7 +401,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) DL analysis, range=21:22, lost=0, r - V(B): (V(A)=22)""(V(S)-1=21) A=Acked N=Nacked U=Unacked X=Resend-Unacked I=Invalid Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=4 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==22 .. V(S)==22) -- Sending new block at BSN 22, CS=1 +- Sending new block at BSN 22, CS=CS-1 -- Empty chunk, added LLC dummy command of size 19, drained_since=112 -- Chunk with length 19 is less than remaining space (20): add length header to to delimit LLC frame Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW)len=19 @@ -1342,7 +1342,7 @@ Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=34 35 36 2d 06 TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN) append TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN) downlink (V(A)==0 .. V(S)==0) - Dequeue next LLC for TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN) (len=19) -- Sending new block at BSN 0, CS=1 +- Sending new block at BSN 0, CS=CS-1 -- Chunk with length 19 is less than remaining space (20): add length header to to delimit LLC frame Complete DL frame for TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN)len=19 - Dequeue next LLC for TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN) (len=19) @@ -1350,7 +1350,7 @@ Complete DL frame for TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN)len=19 data block: 07 00 00 4d 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 MSG = 07 00 00 4d 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN) downlink (V(A)==0 .. V(S)==1) -- Sending new block at BSN 1, CS=1 +- Sending new block at BSN 1, CS=CS-1 -- Chunk with length 19 is less than remaining space (20): add length header to to delimit LLC frame Complete DL frame for TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN)len=19 - Dequeue next LLC for TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN) (len=19) @@ -1358,7 +1358,7 @@ Complete DL frame for TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN)len=19 data block: 07 00 02 4d 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 MSG = 07 00 02 4d 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN) downlink (V(A)==0 .. V(S)==2) -- Sending new block at BSN 2, CS=1 +- Sending new block at BSN 2, CS=CS-1 -- Chunk with length 19 is less than remaining space (20): add length header to to delimit LLC frame Complete DL frame for TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN)len=19 -- Final block, so we done. @@ -1631,7 +1631,7 @@ Received RTS for PDCH: TRX=0 TS=7 FN=2654279 block_nr=10 scheduling USF=0 for re Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=7) prio=3 TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==0) - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=10) -- Sending new block at BSN 0, CS=4 +- Sending new block at BSN 0, CS=CS-4 -- Chunk with length 10 is less than remaining space (50): add length header to to delimit LLC frame Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=10 -- Final block, so we done. @@ -2183,7 +2183,7 @@ Received RTS for PDCH: TRX=0 TS=7 FN=2654279 block_nr=10 scheduling USF=0 for re Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=7) prio=3 TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==0) - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) -- Sending new block at BSN 0, CS=1 +- Sending new block at BSN 0, CS=CS-1 -- Chunk with length 13 is less than remaining space (20): add length header to to delimit LLC frame Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) @@ -2200,7 +2200,7 @@ Received RTS on disabled PDCH: TRX=0 TS=6 Received RTS for PDCH: TRX=0 TS=7 FN=2654283 block_nr=11 scheduling USF=0 for required uplink resource of UL TFI=0 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=7) prio=3 TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==1) -- Sending new block at BSN 1, CS=1 +- Sending new block at BSN 1, CS=CS-1 -- Chunk with length 7 is less than remaining space (20): add length header to to delimit LLC frame Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) @@ -2217,7 +2217,7 @@ Received RTS on disabled PDCH: TRX=0 TS=6 Received RTS for PDCH: TRX=0 TS=7 FN=2654288 block_nr=0 scheduling USF=0 for required uplink resource of UL TFI=0 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=7) prio=3 TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==2) -- Sending new block at BSN 2, CS=1 +- Sending new block at BSN 2, CS=CS-1 -- Chunk with length 1 is less than remaining space (20): add length header to to delimit LLC frame Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) @@ -2237,7 +2237,7 @@ Received RTS on disabled PDCH: TRX=0 TS=6 Received RTS for PDCH: TRX=0 TS=7 FN=2654292 block_nr=1 scheduling USF=0 for required uplink resource of UL TFI=0 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=7) prio=3 TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==3) -- Sending new block at BSN 3, CS=1 +- Sending new block at BSN 3, CS=CS-1 -- Chunk with length 9 is less than remaining space (20): add length header to to delimit LLC frame Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) @@ -2254,7 +2254,7 @@ Received RTS on disabled PDCH: TRX=0 TS=6 Received RTS for PDCH: TRX=0 TS=7 FN=2654296 block_nr=2 scheduling USF=0 for required uplink resource of UL TFI=0 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=7) prio=3 TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==4) -- Sending new block at BSN 4, CS=1 +- Sending new block at BSN 4, CS=CS-1 -- Chunk with length 3 is less than remaining space (20): add length header to to delimit LLC frame Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) @@ -2274,7 +2274,7 @@ Received RTS on disabled PDCH: TRX=0 TS=6 Received RTS for PDCH: TRX=0 TS=7 FN=2654301 block_nr=3 scheduling USF=0 for required uplink resource of UL TFI=0 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=7) prio=3 TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==5) -- Sending new block at BSN 5, CS=1 +- Sending new block at BSN 5, CS=CS-1 -- Chunk with length 11 is less than remaining space (20): add length header to to delimit LLC frame Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) @@ -2291,7 +2291,7 @@ Received RTS on disabled PDCH: TRX=0 TS=6 Received RTS for PDCH: TRX=0 TS=7 FN=2654305 block_nr=4 scheduling USF=0 for required uplink resource of UL TFI=0 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=7) prio=3 TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==6) -- Sending new block at BSN 6, CS=1 +- Sending new block at BSN 6, CS=CS-1 -- Chunk with length 5 is less than remaining space (20): add length header to to delimit LLC frame Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) @@ -2311,7 +2311,7 @@ Received RTS on disabled PDCH: TRX=0 TS=6 Received RTS for PDCH: TRX=0 TS=7 FN=2654309 block_nr=5 scheduling USF=0 for required uplink resource of UL TFI=0 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=7) prio=3 TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==7) -- Sending new block at BSN 7, CS=1 +- Sending new block at BSN 7, CS=CS-1 -- Chunk with length 13 is less than remaining space (20): add length header to to delimit LLC frame Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) @@ -2328,7 +2328,7 @@ Received RTS on disabled PDCH: TRX=0 TS=6 Received RTS for PDCH: TRX=0 TS=7 FN=2654314 block_nr=6 scheduling USF=0 for required uplink resource of UL TFI=0 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=7) prio=3 TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==8) -- Sending new block at BSN 8, CS=1 +- Sending new block at BSN 8, CS=CS-1 -- Chunk with length 7 is less than remaining space (20): add length header to to delimit LLC frame Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) @@ -2345,7 +2345,7 @@ Received RTS on disabled PDCH: TRX=0 TS=6 Received RTS for PDCH: TRX=0 TS=7 FN=2654318 block_nr=7 scheduling USF=0 for required uplink resource of UL TFI=0 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=7) prio=3 TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==9) -- Sending new block at BSN 9, CS=1 +- Sending new block at BSN 9, CS=CS-1 -- Chunk with length 1 is less than remaining space (20): add length header to to delimit LLC frame Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) @@ -2365,7 +2365,7 @@ Received RTS on disabled PDCH: TRX=0 TS=6 Received RTS for PDCH: TRX=0 TS=7 FN=2654322 block_nr=8 scheduling USF=0 for required uplink resource of UL TFI=0 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=7) prio=3 TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==10) -- Sending new block at BSN 10, CS=1 +- Sending new block at BSN 10, CS=CS-1 -- Chunk with length 9 is less than remaining space (20): add length header to to delimit LLC frame Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) @@ -2382,7 +2382,7 @@ Received RTS on disabled PDCH: TRX=0 TS=6 Received RTS for PDCH: TRX=0 TS=7 FN=2654327 block_nr=9 scheduling USF=0 for required uplink resource of UL TFI=0 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=7) prio=3 TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==11) -- Sending new block at BSN 11, CS=1 +- Sending new block at BSN 11, CS=CS-1 -- Chunk with length 3 is less than remaining space (20): add length header to to delimit LLC frame Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) @@ -2402,7 +2402,7 @@ Received RTS on disabled PDCH: TRX=0 TS=6 Received RTS for PDCH: TRX=0 TS=7 FN=2654331 block_nr=10 scheduling USF=0 for required uplink resource of UL TFI=0 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=7) prio=3 TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==12) -- Sending new block at BSN 12, CS=1 +- Sending new block at BSN 12, CS=CS-1 -- Chunk with length 11 is less than remaining space (20): add length header to to delimit LLC frame Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) @@ -2419,7 +2419,7 @@ Received RTS on disabled PDCH: TRX=0 TS=6 Received RTS for PDCH: TRX=0 TS=7 FN=2654335 block_nr=11 scheduling USF=0 for required uplink resource of UL TFI=0 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=7) prio=3 TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==13) -- Sending new block at BSN 13, CS=1 +- Sending new block at BSN 13, CS=CS-1 -- Chunk with length 5 is less than remaining space (20): add length header to to delimit LLC frame Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) @@ -2439,7 +2439,7 @@ Received RTS on disabled PDCH: TRX=0 TS=6 Received RTS for PDCH: TRX=0 TS=7 FN=2654340 block_nr=0 scheduling USF=0 for required uplink resource of UL TFI=0 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=7) prio=3 TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==14) -- Sending new block at BSN 14, CS=1 +- Sending new block at BSN 14, CS=CS-1 -- Chunk with length 13 is less than remaining space (20): add length header to to delimit LLC frame Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) @@ -2456,7 +2456,7 @@ Received RTS on disabled PDCH: TRX=0 TS=6 Received RTS for PDCH: TRX=0 TS=7 FN=2654344 block_nr=1 scheduling USF=0 for required uplink resource of UL TFI=0 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=7) prio=3 TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==15) -- Sending new block at BSN 15, CS=1 +- Sending new block at BSN 15, CS=CS-1 -- Chunk with length 7 is less than remaining space (20): add length header to to delimit LLC frame Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) @@ -2473,7 +2473,7 @@ Received RTS on disabled PDCH: TRX=0 TS=6 Received RTS for PDCH: TRX=0 TS=7 FN=2654348 block_nr=2 scheduling USF=0 for required uplink resource of UL TFI=0 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=7) prio=3 TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==16) -- Sending new block at BSN 16, CS=1 +- Sending new block at BSN 16, CS=CS-1 -- Chunk with length 1 is less than remaining space (20): add length header to to delimit LLC frame Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) @@ -2493,7 +2493,7 @@ Received RTS on disabled PDCH: TRX=0 TS=6 Received RTS for PDCH: TRX=0 TS=7 FN=2654353 block_nr=3 scheduling USF=0 for required uplink resource of UL TFI=0 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=7) prio=3 TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==17) -- Sending new block at BSN 17, CS=1 +- Sending new block at BSN 17, CS=CS-1 -- Chunk with length 9 is less than remaining space (20): add length header to to delimit LLC frame Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) @@ -2510,7 +2510,7 @@ Received RTS on disabled PDCH: TRX=0 TS=6 Received RTS for PDCH: TRX=0 TS=7 FN=2654357 block_nr=4 scheduling USF=0 for required uplink resource of UL TFI=0 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=7) prio=3 TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==18) -- Sending new block at BSN 18, CS=1 +- Sending new block at BSN 18, CS=CS-1 -- Chunk with length 3 is less than remaining space (20): add length header to to delimit LLC frame Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) @@ -2530,7 +2530,7 @@ Received RTS on disabled PDCH: TRX=0 TS=6 Received RTS for PDCH: TRX=0 TS=7 FN=2654361 block_nr=5 scheduling USF=0 for required uplink resource of UL TFI=0 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=7) prio=3 TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==19) -- Sending new block at BSN 19, CS=1 +- Sending new block at BSN 19, CS=CS-1 -- Chunk with length 11 is less than remaining space (20): add length header to to delimit LLC frame Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) @@ -2547,7 +2547,7 @@ Received RTS on disabled PDCH: TRX=0 TS=6 Received RTS for PDCH: TRX=0 TS=7 FN=2654366 block_nr=6 scheduling USF=0 for required uplink resource of UL TFI=0 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=7) prio=5 TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==20) -- Sending new block at BSN 20, CS=1 +- Sending new block at BSN 20, CS=CS-1 -- Chunk with length 5 is less than remaining space (20): add length header to to delimit LLC frame Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) @@ -2570,7 +2570,7 @@ Received RTS on disabled PDCH: TRX=0 TS=6 Received RTS for PDCH: TRX=0 TS=7 FN=2654370 block_nr=7 scheduling USF=0 for required uplink resource of UL TFI=0 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=7) prio=3 TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==21) -- Sending new block at BSN 21, CS=1 +- Sending new block at BSN 21, CS=CS-1 -- Chunk with length 13 is less than remaining space (20): add length header to to delimit LLC frame Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) @@ -2587,7 +2587,7 @@ Received RTS on disabled PDCH: TRX=0 TS=6 Received RTS for PDCH: TRX=0 TS=7 FN=2654374 block_nr=8 scheduling free USF for polling at FN=2654379 of TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=7) prio=3 TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==22) -- Sending new block at BSN 22, CS=1 +- Sending new block at BSN 22, CS=CS-1 -- Chunk with length 7 is less than remaining space (20): add length header to to delimit LLC frame Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) @@ -2604,7 +2604,7 @@ Received RTS on disabled PDCH: TRX=0 TS=6 Received RTS for PDCH: TRX=0 TS=7 FN=2654379 block_nr=9 scheduling USF=0 for required uplink resource of UL TFI=0 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=7) prio=3 TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==23) -- Sending new block at BSN 23, CS=1 +- Sending new block at BSN 23, CS=CS-1 -- Chunk with length 1 is less than remaining space (20): add length header to to delimit LLC frame Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) @@ -2624,7 +2624,7 @@ Received RTS on disabled PDCH: TRX=0 TS=6 Received RTS for PDCH: TRX=0 TS=7 FN=2654383 block_nr=10 scheduling USF=0 for required uplink resource of UL TFI=0 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=7) prio=3 TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==24) -- Sending new block at BSN 24, CS=1 +- Sending new block at BSN 24, CS=CS-1 -- Chunk with length 9 is less than remaining space (20): add length header to to delimit LLC frame Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) @@ -2641,7 +2641,7 @@ Received RTS on disabled PDCH: TRX=0 TS=6 Received RTS for PDCH: TRX=0 TS=7 FN=2654387 block_nr=11 scheduling USF=0 for required uplink resource of UL TFI=0 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=7) prio=3 TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==25) -- Sending new block at BSN 25, CS=1 +- Sending new block at BSN 25, CS=CS-1 -- Chunk with length 3 is less than remaining space (20): add length header to to delimit LLC frame Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) @@ -2661,7 +2661,7 @@ Received RTS on disabled PDCH: TRX=0 TS=6 Received RTS for PDCH: TRX=0 TS=7 FN=2654392 block_nr=0 scheduling USF=0 for required uplink resource of UL TFI=0 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=7) prio=3 TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==26) -- Sending new block at BSN 26, CS=1 +- Sending new block at BSN 26, CS=CS-1 -- Chunk with length 11 is less than remaining space (20): add length header to to delimit LLC frame Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) @@ -2678,7 +2678,7 @@ Received RTS on disabled PDCH: TRX=0 TS=6 Received RTS for PDCH: TRX=0 TS=7 FN=2654396 block_nr=1 scheduling USF=0 for required uplink resource of UL TFI=0 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=7) prio=3 TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==27) -- Sending new block at BSN 27, CS=1 +- Sending new block at BSN 27, CS=CS-1 -- Chunk with length 5 is less than remaining space (20): add length header to to delimit LLC frame Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) @@ -2758,7 +2758,7 @@ Received RTS for PDCH: TRX=0 TS=7 FN=2654405 block_nr=3 scheduling USF=0 for req Scheduling data message at RTS for DL TFI=1 (TRX=0, TS=7) prio=3 TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==0) - Dequeue next LLC for TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=21) -- Sending new block at BSN 0, CS=1 +- Sending new block at BSN 0, CS=CS-1 -- Chunk with length 21 larger than space (20) left in block: copy only remaining space, and we are done data block: 07 02 01 4c 4c 43 20 50 41 43 4b 45 54 20 30 30 20 28 54 42 46 20 32 Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654405 block=3 data=00 02 01 4c 4c 43 20 50 41 43 4b 45 54 20 30 30 20 28 54 42 46 20 32 @@ -2772,7 +2772,7 @@ Received RTS on disabled PDCH: TRX=0 TS=6 Received RTS for PDCH: TRX=0 TS=7 FN=2654409 block_nr=4 scheduling USF=0 for required uplink resource of UL TFI=0 Scheduling data message at RTS for DL TFI=1 (TRX=0, TS=7) prio=3 TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==1) -- Sending new block at BSN 1, CS=1 +- Sending new block at BSN 1, CS=CS-1 -- Chunk with length 1 is less than remaining space (20): add length header to to delimit LLC frame Complete DL frame for TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=21 - Dequeue next LLC for TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=21) @@ -2789,7 +2789,7 @@ Received RTS on disabled PDCH: TRX=0 TS=6 Received RTS for PDCH: TRX=0 TS=7 FN=2654413 block_nr=5 scheduling USF=0 for required uplink resource of UL TFI=0 Scheduling data message at RTS for DL TFI=1 (TRX=0, TS=7) prio=3 TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==2) -- Sending new block at BSN 2, CS=1 +- Sending new block at BSN 2, CS=CS-1 -- Chunk with length 3 is less than remaining space (20): add length header to to delimit LLC frame Complete DL frame for TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=21 - Dequeue next LLC for TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=21) @@ -2806,7 +2806,7 @@ Received RTS on disabled PDCH: TRX=0 TS=6 Received RTS for PDCH: TRX=0 TS=7 FN=2654418 block_nr=6 scheduling USF=0 for required uplink resource of UL TFI=0 Scheduling data message at RTS for DL TFI=1 (TRX=0, TS=7) prio=3 TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==3) -- Sending new block at BSN 3, CS=1 +- Sending new block at BSN 3, CS=CS-1 -- Chunk with length 5 is less than remaining space (20): add length header to to delimit LLC frame Complete DL frame for TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=21 - Dequeue next LLC for TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=21) @@ -2823,7 +2823,7 @@ Received RTS on disabled PDCH: TRX=0 TS=6 Received RTS for PDCH: TRX=0 TS=7 FN=2654422 block_nr=7 scheduling USF=0 for required uplink resource of UL TFI=0 Scheduling data message at RTS for DL TFI=1 (TRX=0, TS=7) prio=3 TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==4) -- Sending new block at BSN 4, CS=1 +- Sending new block at BSN 4, CS=CS-1 -- Chunk with length 7 is less than remaining space (20): add length header to to delimit LLC frame Complete DL frame for TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=21 - Dequeue next LLC for TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=21) @@ -2840,7 +2840,7 @@ Received RTS on disabled PDCH: TRX=0 TS=6 Received RTS for PDCH: TRX=0 TS=7 FN=2654426 block_nr=8 scheduling USF=0 for required uplink resource of UL TFI=0 Scheduling data message at RTS for DL TFI=1 (TRX=0, TS=7) prio=3 TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==5) -- Sending new block at BSN 5, CS=1 +- Sending new block at BSN 5, CS=CS-1 -- Chunk with length 9 is less than remaining space (20): add length header to to delimit LLC frame Complete DL frame for TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=21 - Dequeue next LLC for TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=21) @@ -2857,7 +2857,7 @@ Received RTS on disabled PDCH: TRX=0 TS=6 Received RTS for PDCH: TRX=0 TS=7 FN=2654431 block_nr=9 scheduling USF=0 for required uplink resource of UL TFI=0 Scheduling data message at RTS for DL TFI=1 (TRX=0, TS=7) prio=3 TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==6) -- Sending new block at BSN 6, CS=1 +- Sending new block at BSN 6, CS=CS-1 -- Chunk with length 11 is less than remaining space (20): add length header to to delimit LLC frame Complete DL frame for TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=21 - Dequeue next LLC for TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=21) @@ -2874,7 +2874,7 @@ Received RTS on disabled PDCH: TRX=0 TS=6 Received RTS for PDCH: TRX=0 TS=7 FN=2654435 block_nr=10 scheduling USF=0 for required uplink resource of UL TFI=0 Scheduling data message at RTS for DL TFI=1 (TRX=0, TS=7) prio=3 TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==7) -- Sending new block at BSN 7, CS=1 +- Sending new block at BSN 7, CS=CS-1 -- Chunk with length 13 is less than remaining space (20): add length header to to delimit LLC frame Complete DL frame for TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=21 - Dequeue next LLC for TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=21) @@ -2891,7 +2891,7 @@ Received RTS on disabled PDCH: TRX=0 TS=6 Received RTS for PDCH: TRX=0 TS=7 FN=2654439 block_nr=11 scheduling USF=0 for required uplink resource of UL TFI=0 Scheduling data message at RTS for DL TFI=1 (TRX=0, TS=7) prio=3 TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==8) -- Sending new block at BSN 8, CS=1 +- Sending new block at BSN 8, CS=CS-1 -- Chunk with length 15 is less than remaining space (20): add length header to to delimit LLC frame Complete DL frame for TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=21 - Dequeue next LLC for TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=21) @@ -2908,7 +2908,7 @@ Received RTS on disabled PDCH: TRX=0 TS=6 Received RTS for PDCH: TRX=0 TS=7 FN=2654444 block_nr=0 scheduling USF=0 for required uplink resource of UL TFI=0 Scheduling data message at RTS for DL TFI=1 (TRX=0, TS=7) prio=3 TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==9) -- Sending new block at BSN 9, CS=1 +- Sending new block at BSN 9, CS=CS-1 -- Chunk with length 17 is less than remaining space (20): add length header to to delimit LLC frame Complete DL frame for TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=21 - Dequeue next LLC for TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=21) @@ -2925,7 +2925,7 @@ Received RTS on disabled PDCH: TRX=0 TS=6 Received RTS for PDCH: TRX=0 TS=7 FN=2654448 block_nr=1 scheduling USF=0 for required uplink resource of UL TFI=0 Scheduling data message at RTS for DL TFI=1 (TRX=0, TS=7) prio=3 TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==10) -- Sending new block at BSN 10, CS=1 +- Sending new block at BSN 10, CS=CS-1 -- Chunk with length 19 is less than remaining space (20): add length header to to delimit LLC frame Complete DL frame for TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=21 -- Final block, so we done. -- cgit v1.2.3 From 7b579978749c4c21acd711b1b48b1579bc225d48 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Tue, 5 Jan 2016 15:54:24 +0100 Subject: edge: Show current mode in VTY Add the current mode to the output of the 'show ms imsi' and 'show ms tlli' commands. Sponsored-by: On-Waves ehf --- src/gprs_coding_scheme.cpp | 10 ++++++++++ src/gprs_coding_scheme.h | 1 + src/pcu_vty_functions.cpp | 2 ++ 3 files changed, 13 insertions(+) diff --git a/src/gprs_coding_scheme.cpp b/src/gprs_coding_scheme.cpp index a4601039..4ba55c30 100644 --- a/src/gprs_coding_scheme.cpp +++ b/src/gprs_coding_scheme.cpp @@ -176,3 +176,13 @@ void GprsCodingScheme::dec() m_scheme = Scheme(m_scheme - 1); } + +const char *GprsCodingScheme::modeName(Mode mode) +{ + switch (mode) { + case GPRS: return "GPRS"; + case EGPRS_GMSK: return "EGPRS_GMSK-only"; + case EGPRS: return "EGPRS"; + default: return "???"; + } +} diff --git a/src/gprs_coding_scheme.h b/src/gprs_coding_scheme.h index d1fc064f..f02ca51b 100644 --- a/src/gprs_coding_scheme.h +++ b/src/gprs_coding_scheme.h @@ -87,6 +87,7 @@ public: static GprsCodingScheme getGprsByNum(unsigned num); static GprsCodingScheme getEgprsByNum(unsigned num); + static const char *modeName(Mode mode); private: enum Scheme m_scheme; }; diff --git a/src/pcu_vty_functions.cpp b/src/pcu_vty_functions.cpp index c0592338..a5430f91 100644 --- a/src/pcu_vty_functions.cpp +++ b/src/pcu_vty_functions.cpp @@ -107,6 +107,8 @@ static int show_ms(struct vty *vty, GprsMs *ms) VTY_NEWLINE); vty_out(vty, " Coding scheme downlink: %s%s", ms->current_cs_dl().name(), VTY_NEWLINE); + vty_out(vty, " Mode: %s%s", + GprsCodingScheme::modeName(ms->mode()), VTY_NEWLINE); vty_out(vty, " MS class: %d%s", ms->ms_class(), VTY_NEWLINE); vty_out(vty, " EGPRS MS class: %d%s", ms->egprs_ms_class(), VTY_NEWLINE); vty_out(vty, " LLC queue length: %d%s", ms->llc_queue()->size(), -- cgit v1.2.3 From 166c9fc82708f1965265251225632d3e3b20f529 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Thu, 7 Jan 2016 16:04:29 +0100 Subject: edge: Support EGPRS in write_packet_downlink_assignment Add an use_egprs parameter to write_packet_downlink_assignment and add the EGPRS related fields if it is set to true. The window size is fixed at 64 blocks, link quality measurement reports have been disabled, and the other optional fields are not present. Sponsored-by: On-Waves ehf --- src/encoding.cpp | 22 ++++++++++++++++++---- src/encoding.h | 8 +++++--- src/tbf.cpp | 3 ++- 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/src/encoding.cpp b/src/encoding.cpp index acd8f43d..fdc8d0ae 100644 --- a/src/encoding.cpp +++ b/src/encoding.cpp @@ -269,12 +269,15 @@ void Encoding::write_packet_uplink_assignment( /* generate downlink assignment */ -void Encoding::write_packet_downlink_assignment(RlcMacDownlink_t * block, uint8_t old_tfi, - uint8_t old_downlink, struct gprs_rlcmac_tbf *tbf, uint8_t poll, - uint8_t alpha, uint8_t gamma, int8_t ta_idx, uint8_t ta_ts) +void Encoding::write_packet_downlink_assignment(RlcMacDownlink_t * block, + uint8_t old_tfi, uint8_t old_downlink, struct gprs_rlcmac_tbf *tbf, + uint8_t poll, uint8_t alpha, uint8_t gamma, int8_t ta_idx, uint8_t ta_ts, + bool use_egprs) { // Packet downlink assignment TS 44.060 11.2.7 + PDA_AdditionsR99_t *pda_r99; + uint8_t tn; block->PAYLOAD_TYPE = 0x1; // RLC/MAC control block that does not include the optional octets of the RLC/MAC control header @@ -338,7 +341,18 @@ void Encoding::write_packet_downlink_assignment(RlcMacDownlink_t * block, uint8_ block->u.Packet_Downlink_Assignment.Exist_TBF_Starting_Time = 0x0; // TBF Starting TIME = off block->u.Packet_Downlink_Assignment.Exist_Measurement_Mapping = 0x0; // Measurement_Mapping = off - block->u.Packet_Downlink_Assignment.Exist_AdditionsR99 = 0x0; // AdditionsR99 = off + if (!use_egprs) { + block->u.Packet_Downlink_Assignment.Exist_AdditionsR99 = 0x0; // AdditionsR99 = off + return; + } + block->u.Packet_Downlink_Assignment.Exist_AdditionsR99 = 0x1; // AdditionsR99 = on + pda_r99 = &block->u.Packet_Downlink_Assignment.AdditionsR99; + pda_r99->Exist_EGPRS_Params = 1; + pda_r99->EGPRS_WindowSize = 0; /* 64, see TS 44.060, table 12.5.2.1 */ + pda_r99->LINK_QUALITY_MEASUREMENT_MODE = 0x0; /* no meas, see TS 44.060, table 11.2.7.2 */ + pda_r99->Exist_BEP_PERIOD2 = 0; /* No extra EGPRS BEP PERIOD */ + pda_r99->Exist_Packet_Extended_Timing_Advance = 0; + pda_r99->Exist_COMPACT_ReducedMA = 0; } /* generate paging request */ diff --git a/src/encoding.h b/src/encoding.h index ce17d6f6..ff62bc90 100644 --- a/src/encoding.h +++ b/src/encoding.h @@ -50,9 +50,11 @@ public: struct gprs_rlcmac_ul_tbf *tbf, uint8_t poll, uint8_t alpha, uint8_t gamma, int8_t ta_idx, int8_t use_egprs); - static void write_packet_downlink_assignment(RlcMacDownlink_t * block, uint8_t old_tfi, - uint8_t old_downlink, struct gprs_rlcmac_tbf *tbf, uint8_t poll, - uint8_t alpha, uint8_t gamma, int8_t ta_idx, uint8_t ta_ts); + static void write_packet_downlink_assignment(RlcMacDownlink_t * block, + uint8_t old_tfi, uint8_t old_downlink, + struct gprs_rlcmac_tbf *tbf, uint8_t poll, uint8_t alpha, + uint8_t gamma, int8_t ta_idx, uint8_t ta_ts, + bool use_egprs); static void encode_rbb(const char *show_rbb, uint8_t *rbb); diff --git a/src/tbf.cpp b/src/tbf.cpp index 0da05573..8fac767b 100644 --- a/src/tbf.cpp +++ b/src/tbf.cpp @@ -871,7 +871,8 @@ struct msgb *gprs_rlcmac_tbf::create_dl_ass(uint32_t fn) RlcMacDownlink_t * mac_control_block = (RlcMacDownlink_t *)talloc_zero(tall_pcu_ctx, RlcMacDownlink_t); Encoding::write_packet_downlink_assignment(mac_control_block, m_tfi, (direction == GPRS_RLCMAC_DL_TBF), new_dl_tbf, - poll_ass_dl, bts_data()->alpha, bts_data()->gamma, -1, 0); + poll_ass_dl, bts_data()->alpha, bts_data()->gamma, -1, 0, + is_egprs_enabled()); LOGP(DRLCMAC, LOGL_DEBUG, "+++++++++++++++++++++++++ TX : Packet Downlink Assignment +++++++++++++++++++++++++\n"); encode_gsm_rlcmac_downlink(ass_vec, mac_control_block); LOGPC(DCSN1, LOGL_NOTICE, "\n"); -- cgit v1.2.3 From 369c2fb7b48652d812c4d085e42c01ff0348d3d0 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Thu, 7 Jan 2016 16:14:19 +0100 Subject: tbf: Remove bogus gprs_rlcmac_dl_tbf::enable_egprs This method is already present in gprs_rlcmac_tbf and should not be present in gprs_rlcmac_dl_tbf. Sponsored-by: On-Waves ehf --- src/tbf.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/tbf.h b/src/tbf.h index b00f4d54..fbf7c82e 100644 --- a/src/tbf.h +++ b/src/tbf.h @@ -353,7 +353,6 @@ struct gprs_rlcmac_dl_tbf : public gprs_rlcmac_tbf { int frames_since_last_drain(unsigned fn) const; bool keep_open(unsigned fn) const; int release(); - void enable_egprs(); bool is_control_ts(uint8_t ts) const { return ts == control_ts; -- cgit v1.2.3 From 08f631c1978a128bc516923d9c33bc3198e22a33 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Thu, 7 Jan 2016 16:15:58 +0100 Subject: edge: Enable EGPRS in downlink TBFs Currently GPRS is always used for downlink, which violates TS 44.060 (concurrent TBF must have the same mode). Enable EGPRS mode for downlink if the EGPRS MS class is != 0 and EGRPS has been enabled. Note that EGPRS Ack/Nack handling is not yet implemented, so enabling EGPRS will not work still. But we will now get EGPRS DL ACK/NACK messages now from the MS. Sponsored-by: On-Waves ehf --- src/tbf.cpp | 15 +++++++- tests/tbf/TbfTest.err | 102 +++++++++++++++++++++++++------------------------- 2 files changed, 64 insertions(+), 53 deletions(-) diff --git a/src/tbf.cpp b/src/tbf.cpp index 8fac767b..9c5502a8 100644 --- a/src/tbf.cpp +++ b/src/tbf.cpp @@ -629,6 +629,8 @@ struct gprs_rlcmac_ul_tbf *tbf_alloc_ul_tbf(struct gprs_rlcmac_bts *bts, tbf->m_window.set_sns(RLC_EGPRS_SNS); tbf->m_window.set_ws(RLC_EGPRS_MIN_WS); setup_egprs_mode(bts, ms); + LOGP(DRLCMAC, LOGL_INFO, "Enabled EGPRS for %s, mode %s\n", + tbf->name(), GprsCodingScheme::modeName(ms->mode())); } rc = setup_tbf(tbf, ms, use_trx, ms_class, egprs_ms_class, single_slot); @@ -678,8 +680,8 @@ struct gprs_rlcmac_dl_tbf *tbf_alloc_dl_tbf(struct gprs_rlcmac_bts *bts, int rc; LOGP(DRLCMAC, LOGL_DEBUG, "********** TBF starts here **********\n"); - LOGP(DRLCMAC, LOGL_INFO, "Allocating %s TBF: MS_CLASS=%d\n", - "DL", ms_class); + LOGP(DRLCMAC, LOGL_INFO, "Allocating %s TBF: MS_CLASS=%d/%d\n", + "DL", ms_class, egprs_ms_class); tbf = talloc(tall_pcu_ctx, struct gprs_rlcmac_dl_tbf); @@ -692,6 +694,15 @@ struct gprs_rlcmac_dl_tbf *tbf_alloc_dl_tbf(struct gprs_rlcmac_bts *bts, if (!ms) ms = bts->bts->ms_alloc(ms_class, egprs_ms_class); + if (egprs_ms_class > 0 && bts->egprs_enabled) { + tbf->enable_egprs(); + tbf->m_window.set_sns(RLC_EGPRS_SNS); + tbf->m_window.set_ws(RLC_EGPRS_MIN_WS); + setup_egprs_mode(bts, ms); + LOGP(DRLCMAC, LOGL_INFO, "Enabled EGPRS for %s, mode %s\n", + tbf->name(), GprsCodingScheme::modeName(ms->mode())); + } + rc = setup_tbf(tbf, ms, use_trx, ms_class, 0, single_slot); /* if no resource */ if (rc < 0) { diff --git a/tests/tbf/TbfTest.err b/tests/tbf/TbfTest.err index 69113619..74c88003 100644 --- a/tests/tbf/TbfTest.err +++ b/tests/tbf/TbfTest.err @@ -1,5 +1,5 @@ ********** TBF starts here ********** -Allocating DL TBF: MS_CLASS=0 +Allocating DL TBF: MS_CLASS=0/0 Creating MS object, TLLI = 0x00000000 Slot Allocation (Algorithm A) for class 0 - Skipping TS 0, because not enabled @@ -38,7 +38,7 @@ Modifying MS object, TLLI = 0x00004232, TA 4 -> 6 Searching for first unallocated TFI: TRX=0 Found TFI=0. ********** TBF starts here ********** -Allocating DL TBF: MS_CLASS=45 +Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 Modifying MS object, TLLI = 0x00000000, MS class 0 -> 45 Slot Allocation (Algorithm A) for class 45 @@ -83,7 +83,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink acknowledge TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) changes state from FLOW to WAIT RELEASE TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=WAIT RELEASE) starting timer 3193. ********** TBF starts here ********** -Allocating DL TBF: MS_CLASS=45 +Allocating DL TBF: MS_CLASS=45/0 Slot Allocation (Algorithm A) for class 45 - Skipping TS 0, because not enabled - Skipping TS 1, because not enabled @@ -116,7 +116,7 @@ Destroying MS object, TLLI = 0xffeeddcc Searching for first unallocated TFI: TRX=0 Found TFI=0. ********** TBF starts here ********** -Allocating DL TBF: MS_CLASS=45 +Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 Modifying MS object, TLLI = 0x00000000, MS class 0 -> 45 Slot Allocation (Algorithm A) for class 45 @@ -161,7 +161,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink acknowledge TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) changes state from FLOW to WAIT RELEASE TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=WAIT RELEASE) starting timer 3193. ********** TBF starts here ********** -Allocating DL TBF: MS_CLASS=45 +Allocating DL TBF: MS_CLASS=45/0 Slot Allocation (Algorithm A) for class 45 - Skipping TS 0, because not enabled - Skipping TS 1, because not enabled @@ -194,7 +194,7 @@ Destroying MS object, TLLI = 0xffeeddcc Searching for first unallocated TFI: TRX=0 Found TFI=0. ********** TBF starts here ********** -Allocating DL TBF: MS_CLASS=45 +Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 Modifying MS object, TLLI = 0x00000000, MS class 0 -> 45 Slot Allocation (Algorithm A) for class 45 @@ -425,7 +425,7 @@ Destroying MS object, TLLI = 0xffeeddcc Searching for first unallocated TFI: TRX=0 Found TFI=0. ********** TBF starts here ********** -Allocating DL TBF: MS_CLASS=45 +Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 Modifying MS object, TLLI = 0x00000000, MS class 0 -> 45 Slot Allocation (Algorithm A) for class 45 @@ -445,7 +445,7 @@ TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL) changes state from NULL to FLOW Searching for first unallocated TFI: TRX=0 Found TFI=1. ********** TBF starts here ********** -Allocating DL TBF: MS_CLASS=45 +Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 Modifying MS object, TLLI = 0x00000000, MS class 0 -> 45 Slot Allocation (Algorithm A) for class 45 @@ -482,7 +482,7 @@ Detaching TBF from MS object, TLLI = 0xf1000002, TBF = TBF(TFI=1 TLLI=0xf1000002 Destroying MS object, TLLI = 0xf1000002 ********** TBF ends here ********** ********** TBF starts here ********** -Allocating DL TBF: MS_CLASS=45 +Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 Modifying MS object, TLLI = 0x00000000, MS class 0 -> 45 Slot Allocation (Algorithm A) for class 45 @@ -507,7 +507,7 @@ TX: START TBF(TFI=0 TLLI=0xc0000000 DIR=DL STATE=ASSIGN) Immediate Assignment Do Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 30 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 00 08 00 23 2b 2b 2b 2b TBF(TFI=0 TLLI=0xc0000000 DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** -Allocating DL TBF: MS_CLASS=45 +Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 Modifying MS object, TLLI = 0x00000000, MS class 0 -> 45 Slot Allocation (Algorithm A) for class 45 @@ -532,7 +532,7 @@ TX: START TBF(TFI=1 TLLI=0xc0000001 DIR=DL STATE=ASSIGN) Immediate Assignment Do Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 31 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 00 18 40 23 2b 2b 2b 2b TBF(TFI=1 TLLI=0xc0000001 DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** -Allocating DL TBF: MS_CLASS=45 +Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 Modifying MS object, TLLI = 0x00000000, MS class 0 -> 45 Slot Allocation (Algorithm A) for class 45 @@ -557,7 +557,7 @@ TX: START TBF(TFI=2 TLLI=0xc0000002 DIR=DL STATE=ASSIGN) Immediate Assignment Do Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 32 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 00 28 80 23 2b 2b 2b 2b TBF(TFI=2 TLLI=0xc0000002 DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** -Allocating DL TBF: MS_CLASS=45 +Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 Modifying MS object, TLLI = 0x00000000, MS class 0 -> 45 Slot Allocation (Algorithm A) for class 45 @@ -582,7 +582,7 @@ TX: START TBF(TFI=3 TLLI=0xc0000003 DIR=DL STATE=ASSIGN) Immediate Assignment Do Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 33 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 00 38 c0 23 2b 2b 2b 2b TBF(TFI=3 TLLI=0xc0000003 DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** -Allocating DL TBF: MS_CLASS=45 +Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 Modifying MS object, TLLI = 0x00000000, MS class 0 -> 45 Slot Allocation (Algorithm A) for class 45 @@ -607,7 +607,7 @@ TX: START TBF(TFI=4 TLLI=0xc0000004 DIR=DL STATE=ASSIGN) Immediate Assignment Do Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 34 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 00 49 00 23 2b 2b 2b 2b TBF(TFI=4 TLLI=0xc0000004 DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** -Allocating DL TBF: MS_CLASS=45 +Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 Modifying MS object, TLLI = 0x00000000, MS class 0 -> 45 Slot Allocation (Algorithm A) for class 45 @@ -632,7 +632,7 @@ TX: START TBF(TFI=5 TLLI=0xc0000005 DIR=DL STATE=ASSIGN) Immediate Assignment Do Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 35 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 00 59 40 23 2b 2b 2b 2b TBF(TFI=5 TLLI=0xc0000005 DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** -Allocating DL TBF: MS_CLASS=45 +Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 Modifying MS object, TLLI = 0x00000000, MS class 0 -> 45 Slot Allocation (Algorithm A) for class 45 @@ -657,7 +657,7 @@ TX: START TBF(TFI=6 TLLI=0xc0000006 DIR=DL STATE=ASSIGN) Immediate Assignment Do Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 36 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 00 69 80 23 2b 2b 2b 2b TBF(TFI=6 TLLI=0xc0000006 DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** -Allocating DL TBF: MS_CLASS=45 +Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 Modifying MS object, TLLI = 0x00000000, MS class 0 -> 45 Slot Allocation (Algorithm A) for class 45 @@ -682,7 +682,7 @@ TX: START TBF(TFI=7 TLLI=0xc0000007 DIR=DL STATE=ASSIGN) Immediate Assignment Do Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 37 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 00 79 c0 23 2b 2b 2b 2b TBF(TFI=7 TLLI=0xc0000007 DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** -Allocating DL TBF: MS_CLASS=45 +Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 Modifying MS object, TLLI = 0x00000000, MS class 0 -> 45 Slot Allocation (Algorithm A) for class 45 @@ -707,7 +707,7 @@ TX: START TBF(TFI=8 TLLI=0xc0000008 DIR=DL STATE=ASSIGN) Immediate Assignment Do Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 38 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 00 8a 00 23 2b 2b 2b 2b TBF(TFI=8 TLLI=0xc0000008 DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** -Allocating DL TBF: MS_CLASS=45 +Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 Modifying MS object, TLLI = 0x00000000, MS class 0 -> 45 Slot Allocation (Algorithm A) for class 45 @@ -732,7 +732,7 @@ TX: START TBF(TFI=9 TLLI=0xc0000009 DIR=DL STATE=ASSIGN) Immediate Assignment Do Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 39 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 00 9a 40 23 2b 2b 2b 2b TBF(TFI=9 TLLI=0xc0000009 DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** -Allocating DL TBF: MS_CLASS=45 +Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 Modifying MS object, TLLI = 0x00000000, MS class 0 -> 45 Slot Allocation (Algorithm A) for class 45 @@ -757,7 +757,7 @@ TX: START TBF(TFI=10 TLLI=0xc000000a DIR=DL STATE=ASSIGN) Immediate Assignment D Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 30 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 00 aa 80 23 2b 2b 2b 2b TBF(TFI=10 TLLI=0xc000000a DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** -Allocating DL TBF: MS_CLASS=45 +Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 Modifying MS object, TLLI = 0x00000000, MS class 0 -> 45 Slot Allocation (Algorithm A) for class 45 @@ -782,7 +782,7 @@ TX: START TBF(TFI=11 TLLI=0xc000000b DIR=DL STATE=ASSIGN) Immediate Assignment D Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 31 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 00 ba c0 23 2b 2b 2b 2b TBF(TFI=11 TLLI=0xc000000b DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** -Allocating DL TBF: MS_CLASS=45 +Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 Modifying MS object, TLLI = 0x00000000, MS class 0 -> 45 Slot Allocation (Algorithm A) for class 45 @@ -807,7 +807,7 @@ TX: START TBF(TFI=12 TLLI=0xc000000c DIR=DL STATE=ASSIGN) Immediate Assignment D Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 32 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 00 cb 00 23 2b 2b 2b 2b TBF(TFI=12 TLLI=0xc000000c DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** -Allocating DL TBF: MS_CLASS=45 +Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 Modifying MS object, TLLI = 0x00000000, MS class 0 -> 45 Slot Allocation (Algorithm A) for class 45 @@ -832,7 +832,7 @@ TX: START TBF(TFI=13 TLLI=0xc000000d DIR=DL STATE=ASSIGN) Immediate Assignment D Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 33 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 00 db 40 23 2b 2b 2b 2b TBF(TFI=13 TLLI=0xc000000d DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** -Allocating DL TBF: MS_CLASS=45 +Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 Modifying MS object, TLLI = 0x00000000, MS class 0 -> 45 Slot Allocation (Algorithm A) for class 45 @@ -857,7 +857,7 @@ TX: START TBF(TFI=14 TLLI=0xc000000e DIR=DL STATE=ASSIGN) Immediate Assignment D Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 34 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 00 eb 80 23 2b 2b 2b 2b TBF(TFI=14 TLLI=0xc000000e DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** -Allocating DL TBF: MS_CLASS=45 +Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 Modifying MS object, TLLI = 0x00000000, MS class 0 -> 45 Slot Allocation (Algorithm A) for class 45 @@ -882,7 +882,7 @@ TX: START TBF(TFI=15 TLLI=0xc000000f DIR=DL STATE=ASSIGN) Immediate Assignment D Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 35 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 00 fb c0 23 2b 2b 2b 2b TBF(TFI=15 TLLI=0xc000000f DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** -Allocating DL TBF: MS_CLASS=45 +Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 Modifying MS object, TLLI = 0x00000000, MS class 0 -> 45 Slot Allocation (Algorithm A) for class 45 @@ -907,7 +907,7 @@ TX: START TBF(TFI=16 TLLI=0xc0000010 DIR=DL STATE=ASSIGN) Immediate Assignment D Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 36 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 01 0c 00 23 2b 2b 2b 2b TBF(TFI=16 TLLI=0xc0000010 DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** -Allocating DL TBF: MS_CLASS=45 +Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 Modifying MS object, TLLI = 0x00000000, MS class 0 -> 45 Slot Allocation (Algorithm A) for class 45 @@ -932,7 +932,7 @@ TX: START TBF(TFI=17 TLLI=0xc0000011 DIR=DL STATE=ASSIGN) Immediate Assignment D Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 37 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 01 1c 40 23 2b 2b 2b 2b TBF(TFI=17 TLLI=0xc0000011 DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** -Allocating DL TBF: MS_CLASS=45 +Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 Modifying MS object, TLLI = 0x00000000, MS class 0 -> 45 Slot Allocation (Algorithm A) for class 45 @@ -957,7 +957,7 @@ TX: START TBF(TFI=18 TLLI=0xc0000012 DIR=DL STATE=ASSIGN) Immediate Assignment D Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 38 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 01 2c 80 23 2b 2b 2b 2b TBF(TFI=18 TLLI=0xc0000012 DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** -Allocating DL TBF: MS_CLASS=45 +Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 Modifying MS object, TLLI = 0x00000000, MS class 0 -> 45 Slot Allocation (Algorithm A) for class 45 @@ -982,7 +982,7 @@ TX: START TBF(TFI=19 TLLI=0xc0000013 DIR=DL STATE=ASSIGN) Immediate Assignment D Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 39 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 01 3c c0 23 2b 2b 2b 2b TBF(TFI=19 TLLI=0xc0000013 DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** -Allocating DL TBF: MS_CLASS=45 +Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 Modifying MS object, TLLI = 0x00000000, MS class 0 -> 45 Slot Allocation (Algorithm A) for class 45 @@ -1007,7 +1007,7 @@ TX: START TBF(TFI=20 TLLI=0xc0000014 DIR=DL STATE=ASSIGN) Immediate Assignment D Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 30 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 01 4d 00 23 2b 2b 2b 2b TBF(TFI=20 TLLI=0xc0000014 DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** -Allocating DL TBF: MS_CLASS=45 +Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 Modifying MS object, TLLI = 0x00000000, MS class 0 -> 45 Slot Allocation (Algorithm A) for class 45 @@ -1032,7 +1032,7 @@ TX: START TBF(TFI=21 TLLI=0xc0000015 DIR=DL STATE=ASSIGN) Immediate Assignment D Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 31 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 01 5d 40 23 2b 2b 2b 2b TBF(TFI=21 TLLI=0xc0000015 DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** -Allocating DL TBF: MS_CLASS=45 +Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 Modifying MS object, TLLI = 0x00000000, MS class 0 -> 45 Slot Allocation (Algorithm A) for class 45 @@ -1057,7 +1057,7 @@ TX: START TBF(TFI=22 TLLI=0xc0000016 DIR=DL STATE=ASSIGN) Immediate Assignment D Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 32 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 01 6d 80 23 2b 2b 2b 2b TBF(TFI=22 TLLI=0xc0000016 DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** -Allocating DL TBF: MS_CLASS=45 +Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 Modifying MS object, TLLI = 0x00000000, MS class 0 -> 45 Slot Allocation (Algorithm A) for class 45 @@ -1082,7 +1082,7 @@ TX: START TBF(TFI=23 TLLI=0xc0000017 DIR=DL STATE=ASSIGN) Immediate Assignment D Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 33 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 01 7d c0 23 2b 2b 2b 2b TBF(TFI=23 TLLI=0xc0000017 DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** -Allocating DL TBF: MS_CLASS=45 +Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 Modifying MS object, TLLI = 0x00000000, MS class 0 -> 45 Slot Allocation (Algorithm A) for class 45 @@ -1107,7 +1107,7 @@ TX: START TBF(TFI=24 TLLI=0xc0000018 DIR=DL STATE=ASSIGN) Immediate Assignment D Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 34 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 01 8e 00 23 2b 2b 2b 2b TBF(TFI=24 TLLI=0xc0000018 DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** -Allocating DL TBF: MS_CLASS=45 +Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 Modifying MS object, TLLI = 0x00000000, MS class 0 -> 45 Slot Allocation (Algorithm A) for class 45 @@ -1132,7 +1132,7 @@ TX: START TBF(TFI=25 TLLI=0xc0000019 DIR=DL STATE=ASSIGN) Immediate Assignment D Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 35 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 01 9e 40 23 2b 2b 2b 2b TBF(TFI=25 TLLI=0xc0000019 DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** -Allocating DL TBF: MS_CLASS=45 +Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 Modifying MS object, TLLI = 0x00000000, MS class 0 -> 45 Slot Allocation (Algorithm A) for class 45 @@ -1157,7 +1157,7 @@ TX: START TBF(TFI=26 TLLI=0xc000001a DIR=DL STATE=ASSIGN) Immediate Assignment D Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 36 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 01 ae 80 23 2b 2b 2b 2b TBF(TFI=26 TLLI=0xc000001a DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** -Allocating DL TBF: MS_CLASS=45 +Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 Modifying MS object, TLLI = 0x00000000, MS class 0 -> 45 Slot Allocation (Algorithm A) for class 45 @@ -1182,7 +1182,7 @@ TX: START TBF(TFI=27 TLLI=0xc000001b DIR=DL STATE=ASSIGN) Immediate Assignment D Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 37 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 01 be c0 23 2b 2b 2b 2b TBF(TFI=27 TLLI=0xc000001b DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** -Allocating DL TBF: MS_CLASS=45 +Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 Modifying MS object, TLLI = 0x00000000, MS class 0 -> 45 Slot Allocation (Algorithm A) for class 45 @@ -1207,7 +1207,7 @@ TX: START TBF(TFI=28 TLLI=0xc000001c DIR=DL STATE=ASSIGN) Immediate Assignment D Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 38 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 01 cf 00 23 2b 2b 2b 2b TBF(TFI=28 TLLI=0xc000001c DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** -Allocating DL TBF: MS_CLASS=45 +Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 Modifying MS object, TLLI = 0x00000000, MS class 0 -> 45 Slot Allocation (Algorithm A) for class 45 @@ -1232,7 +1232,7 @@ TX: START TBF(TFI=29 TLLI=0xc000001d DIR=DL STATE=ASSIGN) Immediate Assignment D Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 39 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 01 df 40 23 2b 2b 2b 2b TBF(TFI=29 TLLI=0xc000001d DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** -Allocating DL TBF: MS_CLASS=45 +Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 Modifying MS object, TLLI = 0x00000000, MS class 0 -> 45 Slot Allocation (Algorithm A) for class 45 @@ -1257,7 +1257,7 @@ TX: START TBF(TFI=30 TLLI=0xc000001e DIR=DL STATE=ASSIGN) Immediate Assignment D Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 33 30 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 01 ef 80 23 2b 2b 2b 2b TBF(TFI=30 TLLI=0xc000001e DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** -Allocating DL TBF: MS_CLASS=45 +Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 Modifying MS object, TLLI = 0x00000000, MS class 0 -> 45 Slot Allocation (Algorithm A) for class 45 @@ -1282,7 +1282,7 @@ TX: START TBF(TFI=31 TLLI=0xc000001f DIR=DL STATE=ASSIGN) Immediate Assignment D Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 33 31 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 01 ff c0 23 2b 2b 2b 2b TBF(TFI=31 TLLI=0xc000001f DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** -Allocating DL TBF: MS_CLASS=45 +Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 Modifying MS object, TLLI = 0x00000000, MS class 0 -> 45 Slot Allocation (Algorithm A) for class 45 @@ -1290,7 +1290,7 @@ Slot Allocation (Algorithm A) for class 45 No PDCH resource Destroying MS object, TLLI = 0x00000000 ********** TBF starts here ********** -Allocating DL TBF: MS_CLASS=45 +Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 Modifying MS object, TLLI = 0x00000000, MS class 0 -> 45 Slot Allocation (Algorithm A) for class 45 @@ -1320,7 +1320,7 @@ PDCH(TS 4, TRX 0): Detaching TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN), 0 T Detaching TBF from MS object, TLLI = 0xc0123456, TBF = TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN) ********** TBF ends here ********** ********** TBF starts here ********** -Allocating DL TBF: MS_CLASS=45 +Allocating DL TBF: MS_CLASS=45/0 Slot Allocation (Algorithm A) for class 45 - Skipping TS 0, because not enabled - Skipping TS 1, because not enabled @@ -1418,7 +1418,7 @@ TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW) changes state from FLOW to FINISHED Got 'TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FINISHED)', TA=7 Got MS: TLLI = 0xf1223344, TA = 7 ********** TBF starts here ********** -Allocating DL TBF: MS_CLASS=0 +Allocating DL TBF: MS_CLASS=0/0 Slot Allocation (Algorithm A) for class 0 - Skipping TS 0, because not enabled - Skipping TS 1, because not enabled @@ -1502,7 +1502,7 @@ TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW): data_length=20, data=00 00 00 00 0 Got 'TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW)', TA=7 Got MS: TLLI = 0xf1223344, TA = 7 ********** TBF starts here ********** -Allocating DL TBF: MS_CLASS=0 +Allocating DL TBF: MS_CLASS=0/0 Slot Allocation (Algorithm A) for class 0 - Skipping TS 0, because not enabled - Skipping TS 1, because not enabled @@ -1584,7 +1584,7 @@ TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW): data_length=20, data=00 00 00 00 0 - No gaps in received block, last block: BSN=0 CV=15 Got 'TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW)', TA=7 ********** TBF starts here ********** -Allocating DL TBF: MS_CLASS=0 +Allocating DL TBF: MS_CLASS=0/0 Slot Allocation (Algorithm A) for class 0 - Skipping TS 0, because not enabled - Skipping TS 1, because not enabled @@ -1782,7 +1782,7 @@ TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW): data_length=20, data=00 00 00 00 0 - No gaps in received block, last block: BSN=0 CV=15 Got 'TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW)', TA=7 ********** TBF starts here ********** -Allocating DL TBF: MS_CLASS=0 +Allocating DL TBF: MS_CLASS=0/0 Slot Allocation (Algorithm A) for class 0 - Skipping TS 0, because not enabled - Skipping TS 1, because not enabled @@ -1858,7 +1858,7 @@ RX: [PCU <- BTS] TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) Packet Control A TBF: [DOWNLINK] UPLINK ASSIGNED TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) changes state from ASSIGN to FLOW ********** TBF starts here ********** -Allocating DL TBF: MS_CLASS=1 +Allocating DL TBF: MS_CLASS=1/0 Slot Allocation (Algorithm A) for class 1 - Skipping TS 0, because not enabled - Skipping TS 1, because not enabled @@ -1951,7 +1951,7 @@ TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW): data_length=20, data=00 00 00 00 0 - No gaps in received block, last block: BSN=0 CV=15 Got 'TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW)', TA=7 ********** TBF starts here ********** -Allocating DL TBF: MS_CLASS=0 +Allocating DL TBF: MS_CLASS=0/0 Slot Allocation (Algorithm A) for class 0 - Skipping TS 0, because not enabled - Skipping TS 1, because not enabled @@ -2097,7 +2097,7 @@ TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW): data_length=20, data=00 00 00 00 0 - No gaps in received block, last block: BSN=0 CV=15 Got 'TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW)', TA=7 ********** TBF starts here ********** -Allocating DL TBF: MS_CLASS=0 +Allocating DL TBF: MS_CLASS=0/0 Slot Allocation (Algorithm A) for class 0 - Skipping TS 0, because not enabled - Skipping TS 1, because not enabled @@ -2709,7 +2709,7 @@ TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FINISHED) downlink acknowledge TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FINISHED) changes state from FINISHED to WAIT RELEASE TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=WAIT RELEASE) starting timer 3193. ********** TBF starts here ********** -Allocating DL TBF: MS_CLASS=1 +Allocating DL TBF: MS_CLASS=1/0 Slot Allocation (Algorithm A) for class 1 - Skipping TS 0, because not enabled - Skipping TS 1, because not enabled -- cgit v1.2.3 From a47aaa4e7a833ab7ae3a2b995dd533f2402751b1 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Thu, 7 Jan 2016 16:47:34 +0100 Subject: edge: Add work-around to get DL EGPRS from MS object The EGPRS multi-slot class need to be parsed from the CSN.1 RA capability (see gprs_bssgp_pcu_rx_dl_ud). This commit adds a workaround to get the EGPRS MS class from the MS object if that is present. Sponsored-by: On-Waves ehf --- src/tbf_dl.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/tbf_dl.cpp b/src/tbf_dl.cpp index 9e73a0e3..73d8a3bc 100644 --- a/src/tbf_dl.cpp +++ b/src/tbf_dl.cpp @@ -180,7 +180,7 @@ static int tbf_new_dl_assignment(struct gprs_rlcmac_bts *bts, */ int gprs_rlcmac_dl_tbf::handle(struct gprs_rlcmac_bts *bts, const uint32_t tlli, const uint32_t tlli_old, const char *imsi, - const uint8_t ms_class, const uint8_t egprs_ms_class, + const uint8_t ms_class, uint8_t egprs_ms_class, const uint16_t delay_csec, const uint8_t *data, const uint16_t len) { @@ -193,6 +193,10 @@ int gprs_rlcmac_dl_tbf::handle(struct gprs_rlcmac_bts *bts, if (ms) dl_tbf = ms->dl_tbf(); + /* Work-around to get EGPRS MS class */ + if (ms && !egprs_ms_class) + egprs_ms_class = ms->egprs_ms_class(); + if (ms && strlen(ms->imsi()) == 0) { ms_old = bts->bts->ms_store().get_ms(0, 0, imsi); if (ms_old && ms_old != ms) { -- cgit v1.2.3 From 7e7a261de0751bf2361e86761c7eb9fa7dbcdf9a Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Thu, 7 Jan 2016 18:07:54 +0100 Subject: edge: Remove int casting operator from GprsCodingScheme This convenience operator rather hide implementation bugs and is thus removed. Sponsored-by: On-Waves ehf --- src/gprs_coding_scheme.h | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/gprs_coding_scheme.h b/src/gprs_coding_scheme.h index f02ca51b..c26d12a7 100644 --- a/src/gprs_coding_scheme.h +++ b/src/gprs_coding_scheme.h @@ -52,7 +52,6 @@ public: GprsCodingScheme(Scheme s = UNKNOWN); operator bool() const {return m_scheme != UNKNOWN;} - operator int() const {return (int)m_scheme;} operator Scheme() const {return m_scheme;} unsigned int to_num() const; @@ -89,6 +88,8 @@ public: static const char *modeName(Mode mode); private: + GprsCodingScheme(int s); /* fail on use */ + GprsCodingScheme& operator =(int s); /* fail on use */ enum Scheme m_scheme; }; @@ -166,7 +167,7 @@ inline GprsCodingScheme GprsCodingScheme::getEgprsByNum(unsigned num) /* The coding schemes form a partial ordering */ inline bool operator ==(GprsCodingScheme a, GprsCodingScheme b) { - return int(a) == int(b); + return GprsCodingScheme::Scheme(a) == GprsCodingScheme::Scheme(b); } inline bool operator !=(GprsCodingScheme a, GprsCodingScheme b) @@ -176,12 +177,13 @@ inline bool operator !=(GprsCodingScheme a, GprsCodingScheme b) inline bool operator <(GprsCodingScheme a, GprsCodingScheme b) { - return a.isCompatible(b) && int(a) < int(b); + return a.isCompatible(b) && + GprsCodingScheme::Scheme(a) < GprsCodingScheme::Scheme(b); } inline bool operator >(GprsCodingScheme a, GprsCodingScheme b) { - return a.isCompatible(b) && int(a) > int(b); + return b < a; } inline bool operator <=(GprsCodingScheme a, GprsCodingScheme b) -- cgit v1.2.3 From f2ba4cbf51ba5ec4183a9153ba2ce51df9050881 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Thu, 7 Jan 2016 18:59:28 +0100 Subject: edge: Rename gprs_rlc_ul_header_egprs and gprs_rlc_ul_data_block_info These struct names are more specific than necessary. They are used for GPRS (uplink) already. In downlink direction, only a few fields will be added to the header struct. Add addition, gprs_rlc_ul_header_egprs does not map directly to an encoded header, like many other 'header' structs do. Change the names to fit both modes and both directions: gprs_rlc_ul_header_egprs -> gprs_rlc_data_info gprs_rlc_ul_data_block_info -> gprs_rlc_data_block_info Sponsored-by: On-Waves ehf --- src/bts.cpp | 2 +- src/decoding.cpp | 10 +++++----- src/decoding.h | 8 ++++---- src/rlc.h | 8 ++++---- src/tbf.h | 4 ++-- src/tbf_ul.cpp | 10 +++++----- tests/edge/EdgeTest.cpp | 2 +- 7 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/bts.cpp b/src/bts.cpp index 52811c2c..1ef735b4 100644 --- a/src/bts.cpp +++ b/src/bts.cpp @@ -1156,7 +1156,7 @@ int gprs_rlcmac_pdch::rcv_data_block(uint8_t *data, uint32_t fn, struct pcu_l1_meas *meas, GprsCodingScheme cs) { int rc; - struct gprs_rlc_ul_header_egprs rlc_dec; + struct gprs_rlc_data_info rlc_dec; struct gprs_rlcmac_ul_tbf *tbf; unsigned len = cs.maxBytesUL(); diff --git a/src/decoding.cpp b/src/decoding.cpp index abaa97f4..45716413 100644 --- a/src/decoding.cpp +++ b/src/decoding.cpp @@ -180,7 +180,7 @@ static int parse_extensions_gprs(const uint8_t *data, unsigned int data_len, } int Decoding::rlc_data_from_ul_data( - const struct gprs_rlc_ul_data_block_info *rdbi, GprsCodingScheme cs, + const struct gprs_rlc_data_block_info *rdbi, GprsCodingScheme cs, const uint8_t *data, RlcData *chunks, unsigned int chunks_size, uint32_t *tlli) { @@ -369,7 +369,7 @@ void Decoding::extract_rbb(const uint8_t *rbb, char *show_rbb) show_rbb[64] = '\0'; } -int Decoding::rlc_parse_ul_data_header(struct gprs_rlc_ul_header_egprs *rlc, +int Decoding::rlc_parse_ul_data_header(struct gprs_rlc_data_info *rlc, const uint8_t *data, GprsCodingScheme cs) { const struct gprs_rlc_ul_header_egprs_3 *egprs3; @@ -464,7 +464,7 @@ int Decoding::rlc_parse_ul_data_header(struct gprs_rlc_ul_header_egprs *rlc, * \returns the number of bytes copied */ unsigned int Decoding::rlc_copy_to_aligned_buffer( - const struct gprs_rlc_ul_header_egprs *rlc, + const struct gprs_rlc_data_info *rlc, unsigned int data_block_idx, const uint8_t *src, uint8_t *buffer) { @@ -474,7 +474,7 @@ unsigned int Decoding::rlc_copy_to_aligned_buffer( uint8_t c, last_c; uint8_t *dst; - const struct gprs_rlc_ul_data_block_info *rdbi; + const struct gprs_rlc_data_block_info *rdbi; OSMO_ASSERT(data_block_idx < rlc->num_data_blocks); rdbi = &rlc->block_info[data_block_idx]; @@ -514,7 +514,7 @@ unsigned int Decoding::rlc_copy_to_aligned_buffer( * buffer otherwise. */ const uint8_t *Decoding::rlc_get_data_aligned( - const struct gprs_rlc_ul_header_egprs *rlc, + const struct gprs_rlc_data_info *rlc, unsigned int data_block_idx, const uint8_t *src, uint8_t *buffer) { diff --git a/src/decoding.h b/src/decoding.h index 1cda7b42..94926946 100644 --- a/src/decoding.h +++ b/src/decoding.h @@ -35,7 +35,7 @@ public: static int tlli_from_ul_data(const uint8_t *data, uint8_t len, uint32_t *tlli); static int rlc_data_from_ul_data( - const struct gprs_rlc_ul_data_block_info *rdbi, + const struct gprs_rlc_data_block_info *rdbi, GprsCodingScheme cs, const uint8_t *data, RlcData *chunks, unsigned int chunks_size, uint32_t *tlli); static uint8_t get_ms_class_by_capability(MS_Radio_Access_capability_t *cap); @@ -43,14 +43,14 @@ public: static void extract_rbb(const uint8_t *rbb, char *extracted_rbb); - static int rlc_parse_ul_data_header(struct gprs_rlc_ul_header_egprs *rlc, + static int rlc_parse_ul_data_header(struct gprs_rlc_data_info *rlc, const uint8_t *data, GprsCodingScheme cs); static unsigned int rlc_copy_to_aligned_buffer( - const struct gprs_rlc_ul_header_egprs *rlc, + const struct gprs_rlc_data_info *rlc, unsigned int data_block_idx, const uint8_t *src, uint8_t *buffer); static const uint8_t *rlc_get_data_aligned( - const struct gprs_rlc_ul_header_egprs *rlc, + const struct gprs_rlc_data_info *rlc, unsigned int data_block_idx, const uint8_t *src, uint8_t *buffer); }; diff --git a/src/rlc.h b/src/rlc.h index 46d821d3..42c13073 100644 --- a/src/rlc.h +++ b/src/rlc.h @@ -60,7 +60,7 @@ static inline uint16_t mod_sns_half() return (RLC_MAX_SNS / 2) - 1; } -struct gprs_rlc_ul_data_block_info { +struct gprs_rlc_data_block_info { unsigned int data_len; /* EGPRS: N2, GPRS: N2-2, N-2 */ unsigned int bsn; unsigned int ti; @@ -70,7 +70,7 @@ struct gprs_rlc_ul_data_block_info { unsigned int spb; }; -struct gprs_rlc_ul_header_egprs { +struct gprs_rlc_data_info { GprsCodingScheme cs; unsigned int r; unsigned int si; @@ -79,7 +79,7 @@ struct gprs_rlc_ul_header_egprs { unsigned int rsb; unsigned int num_data_blocks; unsigned int data_offs_bits[2]; - struct gprs_rlc_ul_data_block_info block_info[2]; + struct gprs_rlc_data_block_info block_info[2]; }; struct gprs_rlc_data { @@ -91,7 +91,7 @@ struct gprs_rlc_data { /* block len of history */ uint8_t len; - struct gprs_rlc_ul_data_block_info block_info; + struct gprs_rlc_data_block_info block_info; GprsCodingScheme cs; }; diff --git a/src/tbf.h b/src/tbf.h index fbf7c82e..c0fee0e9 100644 --- a/src/tbf.h +++ b/src/tbf.h @@ -413,7 +413,7 @@ struct gprs_rlcmac_ul_tbf : public gprs_rlcmac_tbf { /* blocks were acked */ int rcv_data_block_acknowledged( - const struct gprs_rlc_ul_header_egprs *rlc, + const struct gprs_rlc_data_info *rlc, uint8_t *data, uint8_t len, struct pcu_l1_meas *meas); @@ -434,7 +434,7 @@ struct gprs_rlcmac_ul_tbf : public gprs_rlcmac_tbf { uint8_t m_final_ack_sent; /* set if we sent final ack */ protected: - void maybe_schedule_uplink_acknack(const gprs_rlc_ul_header_egprs *rlc); + void maybe_schedule_uplink_acknack(const gprs_rlc_data_info *rlc); }; inline enum gprs_rlcmac_tbf_direction reverse(enum gprs_rlcmac_tbf_direction dir) diff --git a/src/tbf_ul.cpp b/src/tbf_ul.cpp index 4abfaaa0..e81cd4bd 100644 --- a/src/tbf_ul.cpp +++ b/src/tbf_ul.cpp @@ -50,7 +50,7 @@ int gprs_rlcmac_ul_tbf::assemble_forward_llc(const gprs_rlc_data *_data) { const uint8_t *data = _data->block; uint8_t len = _data->len; - const struct gprs_rlc_ul_data_block_info *rdbi = &_data->block_info; + const struct gprs_rlc_data_block_info *rdbi = &_data->block_info; GprsCodingScheme cs = _data->cs; Decoding::RlcData frames[16], *frame; @@ -137,7 +137,7 @@ struct msgb *gprs_rlcmac_ul_tbf::create_ul_ack(uint32_t fn) } int gprs_rlcmac_ul_tbf::rcv_data_block_acknowledged( - const struct gprs_rlc_ul_header_egprs *rlc, + const struct gprs_rlc_data_info *rlc, uint8_t *data, uint8_t len, struct pcu_l1_meas *meas) { int8_t rssi = meas->have_rssi ? meas->rssi : 0; @@ -170,7 +170,7 @@ int gprs_rlcmac_ul_tbf::rcv_data_block_acknowledged( for (block_idx = 0; block_idx < rlc->num_data_blocks; block_idx++) { int num_chunks; uint8_t *rlc_data; - const struct gprs_rlc_ul_data_block_info *rdbi = + const struct gprs_rlc_data_block_info *rdbi = &rlc->block_info[block_idx]; bool need_rlc_data = false; struct gprs_rlc_data *block; @@ -301,7 +301,7 @@ int gprs_rlcmac_ul_tbf::rcv_data_block_acknowledged( && this->m_window.v_q() == this->m_window.v_r()) { /* if complete */ struct gprs_rlc_data *block = m_rlc.block(m_window.mod_sns(m_window.v_r() - 1)); - const struct gprs_rlc_ul_data_block_info *rdbi = + const struct gprs_rlc_data_block_info *rdbi = &block->block_info; LOGP(DRLCMACUL, LOGL_DEBUG, "- No gaps in received block, " @@ -324,7 +324,7 @@ int gprs_rlcmac_ul_tbf::rcv_data_block_acknowledged( } void gprs_rlcmac_ul_tbf::maybe_schedule_uplink_acknack( - const gprs_rlc_ul_header_egprs *rlc) + const gprs_rlc_data_info *rlc) { bool have_ti = rlc->block_info[0].ti || (rlc->num_data_blocks > 1 && rlc->block_info[1].ti); diff --git a/tests/edge/EdgeTest.cpp b/tests/edge/EdgeTest.cpp index 21956593..dffd009d 100644 --- a/tests/edge/EdgeTest.cpp +++ b/tests/edge/EdgeTest.cpp @@ -174,7 +174,7 @@ static void test_coding_scheme() static void test_rlc_unit_decoder() { - struct gprs_rlc_ul_data_block_info rdbi = {0}; + struct gprs_rlc_data_block_info rdbi = {0}; GprsCodingScheme cs; uint8_t data[74]; Decoding::RlcData chunks[16]; -- cgit v1.2.3 From fc1b3e6c9076ddc38e07715b2cc30319bac19b9c Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Mon, 11 Jan 2016 09:58:11 +0100 Subject: edge: Fix RLC message size Currently the RLC message length that is obtained from the DSP is reduced by 1 if the last byte of the buffer includes spare bits. While this worked well with GPRS, these bits are being used to encode RLC blocks in EGPRS mode. Thus this last byte must not be chopped off. The functionality of the code is not affected by this, since the modified length value is not used. This commit adds GprsCodingScheme::usedSizeDL/UL to return the number of bytes needed to encode the message block. If there are single bits at the end that are to be used (EGPRS), the functions return the number of full bytes plus 1 (which is the buffer size reported by the DSP and returned by sizeUL/sizeDL). The commit also removes the len parameter from rcv_data_block_acknowledged. Sponsored-by: On-Waves ehf --- src/bts.cpp | 6 +++--- src/gprs_coding_scheme.cpp | 20 ++++++++++++++++++-- src/gprs_coding_scheme.h | 2 ++ src/tbf.h | 2 +- src/tbf_dl.cpp | 2 +- src/tbf_ul.cpp | 2 +- tests/edge/EdgeTest.cpp | 8 ++++---- 7 files changed, 30 insertions(+), 12 deletions(-) diff --git a/src/bts.cpp b/src/bts.cpp index 1ef735b4..18bee665 100644 --- a/src/bts.cpp +++ b/src/bts.cpp @@ -1138,7 +1138,7 @@ int gprs_rlcmac_pdch::rcv_block(uint8_t *data, uint8_t len, uint32_t fn, } LOGP(DRLCMACUL, LOGL_DEBUG, "Got RLC block, coding scheme: %s, " - "length: %d (%d))\n", cs.name(), len, cs.maxBytesUL()); + "length: %d (%d))\n", cs.name(), len, cs.usedSizeUL()); if (cs.isGprs()) return rcv_block_gprs(data, fn, meas, cs); @@ -1158,7 +1158,7 @@ int gprs_rlcmac_pdch::rcv_data_block(uint8_t *data, uint32_t fn, int rc; struct gprs_rlc_data_info rlc_dec; struct gprs_rlcmac_ul_tbf *tbf; - unsigned len = cs.maxBytesUL(); + unsigned len = cs.sizeUL(); /* These are always data blocks, since EGPRS still uses CS-1 for * control blocks (see 44.060, section 10.3, 1st par.) @@ -1208,7 +1208,7 @@ int gprs_rlcmac_pdch::rcv_data_block(uint8_t *data, uint32_t fn, return 0; } - return tbf->rcv_data_block_acknowledged(&rlc_dec, data, len, meas); + return tbf->rcv_data_block_acknowledged(&rlc_dec, data, meas); } int gprs_rlcmac_pdch::rcv_block_gprs(uint8_t *data, uint32_t fn, diff --git a/src/gprs_coding_scheme.cpp b/src/gprs_coding_scheme.cpp index 4ba55c30..629ba4a0 100644 --- a/src/gprs_coding_scheme.cpp +++ b/src/gprs_coding_scheme.cpp @@ -73,7 +73,15 @@ GprsCodingScheme GprsCodingScheme::getBySizeUL(unsigned size) unsigned int GprsCodingScheme::sizeUL() const { - return maxBytesUL() + (spareBitsUL() ? 1 : 0); + return mcs_info[m_scheme].uplink.bytes + (spareBitsUL() ? 1 : 0); +} + +unsigned int GprsCodingScheme::usedSizeUL() const +{ + if (mcs_info[m_scheme].data_hdr == HEADER_GPRS_DATA) + return mcs_info[m_scheme].uplink.bytes; + else + return sizeUL(); } unsigned int GprsCodingScheme::maxBytesUL() const @@ -88,7 +96,15 @@ unsigned int GprsCodingScheme::spareBitsUL() const unsigned int GprsCodingScheme::sizeDL() const { - return maxBytesDL() + (spareBitsDL() ? 1 : 0); + return mcs_info[m_scheme].downlink.bytes + (spareBitsDL() ? 1 : 0); +} + +unsigned int GprsCodingScheme::usedSizeDL() const +{ + if (mcs_info[m_scheme].data_hdr == HEADER_GPRS_DATA) + return mcs_info[m_scheme].downlink.bytes; + else + return sizeDL(); } unsigned int GprsCodingScheme::maxBytesDL() const diff --git a/src/gprs_coding_scheme.h b/src/gprs_coding_scheme.h index c26d12a7..854deb67 100644 --- a/src/gprs_coding_scheme.h +++ b/src/gprs_coding_scheme.h @@ -72,6 +72,8 @@ public: unsigned int sizeUL() const; unsigned int sizeDL() const; + unsigned int usedSizeUL() const; + unsigned int usedSizeDL() const; unsigned int maxBytesUL() const; unsigned int maxBytesDL() const; unsigned int spareBitsUL() const; diff --git a/src/tbf.h b/src/tbf.h index c0fee0e9..7c3fba8d 100644 --- a/src/tbf.h +++ b/src/tbf.h @@ -414,7 +414,7 @@ struct gprs_rlcmac_ul_tbf : public gprs_rlcmac_tbf { /* blocks were acked */ int rcv_data_block_acknowledged( const struct gprs_rlc_data_info *rlc, - uint8_t *data, uint8_t len, struct pcu_l1_meas *meas); + uint8_t *data, struct pcu_l1_meas *meas); /* TODO: extract LLC class? */ diff --git a/src/tbf_dl.cpp b/src/tbf_dl.cpp index 73d8a3bc..ac1c253f 100644 --- a/src/tbf_dl.cpp +++ b/src/tbf_dl.cpp @@ -441,7 +441,7 @@ struct msgb *gprs_rlcmac_dl_tbf::create_new_bsn(const uint32_t fn, const uint8_t /* total length of block, including spare bits */ const uint8_t block_length = cs.sizeDL(); - /* length of usable data of block, w/o spare bits, inc. MAC */ + /* length of usable data of block, w/o spare bits (GPRS), inc. MAC */ const uint8_t block_data_len = cs.maxBytesDL(); /* now we still have untransmitted LLC data, so we fill mac block */ diff --git a/src/tbf_ul.cpp b/src/tbf_ul.cpp index e81cd4bd..1d0b1681 100644 --- a/src/tbf_ul.cpp +++ b/src/tbf_ul.cpp @@ -138,7 +138,7 @@ struct msgb *gprs_rlcmac_ul_tbf::create_ul_ack(uint32_t fn) int gprs_rlcmac_ul_tbf::rcv_data_block_acknowledged( const struct gprs_rlc_data_info *rlc, - uint8_t *data, uint8_t len, struct pcu_l1_meas *meas) + uint8_t *data, struct pcu_l1_meas *meas) { int8_t rssi = meas->have_rssi ? meas->rssi : 0; diff --git a/tests/edge/EdgeTest.cpp b/tests/edge/EdgeTest.cpp index dffd009d..b26262ca 100644 --- a/tests/edge/EdgeTest.cpp +++ b/tests/edge/EdgeTest.cpp @@ -49,15 +49,15 @@ static void check_coding_scheme(GprsCodingScheme& cs, GprsCodingScheme::Mode mod OSMO_ASSERT(cs.isCompatible(mode)); /* Check static getBySizeUL() */ - expected_size = cs.maxBytesUL(); - if (cs.spareBitsUL() > 0) + expected_size = cs.usedSizeUL(); + if (cs.spareBitsUL() > 0 && cs.isGprs()) expected_size += 1; OSMO_ASSERT(expected_size == cs.sizeUL()); OSMO_ASSERT(cs == GprsCodingScheme::getBySizeUL(expected_size)); /* Check static sizeUL() */ - expected_size = cs.maxBytesDL(); - if (cs.spareBitsDL() > 0) + expected_size = cs.usedSizeDL(); + if (cs.spareBitsDL() > 0 && cs.isGprs()) expected_size += 1; OSMO_ASSERT(expected_size == cs.sizeDL()); -- cgit v1.2.3 From 22f8087b982af3e077311d5dbc4e1eebc7153ea3 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Mon, 11 Jan 2016 10:56:50 +0100 Subject: edge: Add numDataHeaderBitsUL/DL and numDataBlockHeaderBits methods These methods are added to GprsCodingScheme to avoid related switch statements in the RLC block encoder for EGPRS. Sponsored-by: On-Waves ehf --- src/gprs_coding_scheme.cpp | 66 +++++++++++++++++++++++++++++++++------------- src/gprs_coding_scheme.h | 4 +++ 2 files changed, 52 insertions(+), 18 deletions(-) diff --git a/src/gprs_coding_scheme.cpp b/src/gprs_coding_scheme.cpp index 629ba4a0..aaa8b205 100644 --- a/src/gprs_coding_scheme.cpp +++ b/src/gprs_coding_scheme.cpp @@ -25,30 +25,45 @@ static struct { struct { unsigned int bytes; unsigned int ext_bits; + unsigned int data_header_bits; } uplink, downlink; unsigned int data_bytes; - unsigned int num_blocks; const char *name; GprsCodingScheme::HeaderType data_hdr; } mcs_info[GprsCodingScheme::NUM_SCHEMES] = { - {{0, 0}, {0, 0}, 0, 0, "UNKNOWN", GprsCodingScheme::HEADER_INVALID}, - {{23, 0}, {23, 0}, 20, 1, "CS-1", GprsCodingScheme::HEADER_GPRS_DATA}, - {{33, 7}, {33, 7}, 30, 1, "CS-2", GprsCodingScheme::HEADER_GPRS_DATA}, - {{39, 3}, {39, 3}, 36, 1, "CS-3", GprsCodingScheme::HEADER_GPRS_DATA}, - {{53, 7}, {53, 7}, 50, 1, "CS-4", GprsCodingScheme::HEADER_GPRS_DATA}, - - {{26, 1}, {26, 1}, 22, 1, "MCS-1", GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_3}, - {{32, 1}, {32, 1}, 28, 1, "MCS-2", GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_3}, - {{41, 1}, {41, 1}, 37, 1, "MCS-3", GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_3}, - {{48, 1}, {48, 1}, 44, 1, "MCS-4", GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_3}, - - {{60, 7}, {59, 6}, 56, 1, "MCS-5", GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_2}, - {{78, 7}, {77, 6}, 74, 1, "MCS-6", GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_2}, - {{118, 2}, {117, 4}, 56, 2, "MCS-7", GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_1}, - {{142, 2}, {141, 4}, 68, 2, "MCS-8", GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_1}, - {{154, 2}, {153, 4}, 74, 2, "MCS-9", GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_1}, + {{0, 0}, {0, 0}, 0, "UNKNOWN", GprsCodingScheme::HEADER_INVALID}, + {{23, 0}, {23, 0}, 20, "CS-1", GprsCodingScheme::HEADER_GPRS_DATA}, + {{33, 7}, {33, 7}, 30, "CS-2", GprsCodingScheme::HEADER_GPRS_DATA}, + {{39, 3}, {39, 3}, 36, "CS-3", GprsCodingScheme::HEADER_GPRS_DATA}, + {{53, 7}, {53, 7}, 50, "CS-4", GprsCodingScheme::HEADER_GPRS_DATA}, + + {{26, 1}, {26, 1}, 22, "MCS-1", GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_3}, + {{32, 1}, {32, 1}, 28, "MCS-2", GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_3}, + {{41, 1}, {41, 1}, 37, "MCS-3", GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_3}, + {{48, 1}, {48, 1}, 44, "MCS-4", GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_3}, + + {{60, 7}, {59, 6}, 56, "MCS-5", GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_2}, + {{78, 7}, {77, 6}, 74, "MCS-6", GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_2}, + {{118, 2}, {117, 4}, 56, "MCS-7", GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_1}, + {{142, 2}, {141, 4}, 68, "MCS-8", GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_1}, + {{154, 2}, {153, 4}, 74, "MCS-9", GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_1}, }; +static struct { + struct { + int data_header_bits; + } uplink, downlink; + unsigned int data_block_header_bits; + unsigned int num_blocks; + const char *name; +} hdr_type_info[GprsCodingScheme::NUM_HEADER_TYPES] = { + {{0}, {0}, 0, 0, "INVALID"}, + {{1*8 + 0}, {1*8 + 0}, 0, 0, "CONTROL"}, + {{3*8 + 0}, {3*8 + 0}, 0, 1, "GPRS_DATA"}, + {{5*8 + 6}, {5*8 + 0}, 2, 2, "EGPRS_DATA_TYPE1"}, + {{4*8 + 5}, {3*8 + 4}, 2, 1, "EGPRS_DATA_TYPE2"}, + {{3*8 + 7}, {3*8 + 7}, 2, 1, "EGPRS_DATA_TYPE3"}, +}; GprsCodingScheme GprsCodingScheme::getBySizeUL(unsigned size) { @@ -124,7 +139,22 @@ unsigned int GprsCodingScheme::maxDataBlockBytes() const unsigned int GprsCodingScheme::numDataBlocks() const { - return mcs_info[m_scheme].num_blocks; + return hdr_type_info[headerTypeData()].num_blocks; +} + +unsigned int GprsCodingScheme::numDataHeaderBitsUL() const +{ + return hdr_type_info[headerTypeData()].uplink.data_header_bits; +} + +unsigned int GprsCodingScheme::numDataHeaderBitsDL() const +{ + return hdr_type_info[headerTypeData()].downlink.data_header_bits; +} + +unsigned int GprsCodingScheme::numDataBlockHeaderBits() const +{ + return hdr_type_info[headerTypeData()].data_block_header_bits; } const char *GprsCodingScheme::name() const diff --git a/src/gprs_coding_scheme.h b/src/gprs_coding_scheme.h index 854deb67..348aefbd 100644 --- a/src/gprs_coding_scheme.h +++ b/src/gprs_coding_scheme.h @@ -47,6 +47,7 @@ public: HEADER_EGPRS_DATA_TYPE_1, HEADER_EGPRS_DATA_TYPE_2, HEADER_EGPRS_DATA_TYPE_3, + NUM_HEADER_TYPES }; GprsCodingScheme(Scheme s = UNKNOWN); @@ -80,6 +81,9 @@ public: unsigned int spareBitsDL() const; unsigned int maxDataBlockBytes() const; unsigned int numDataBlocks() const; + unsigned int numDataHeaderBitsUL() const; + unsigned int numDataHeaderBitsDL() const; + unsigned int numDataBlockHeaderBits() const; const char *name() const; HeaderType headerTypeData() const; HeaderType headerTypeControl() const; -- cgit v1.2.3 From cc34a5b43f5542f2cc3866a0487915049d39df91 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Mon, 11 Jan 2016 12:53:08 +0100 Subject: rlc: Add info fields for downlink This commit extends gprs_rlc_data_info and gprs_rlc_data_block_info by the fields required for downlink RLC data messages. Sponsored-by: On-Waves ehf --- src/rlc.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/rlc.h b/src/rlc.h index 42c13073..0cd7593a 100644 --- a/src/rlc.h +++ b/src/rlc.h @@ -65,7 +65,7 @@ struct gprs_rlc_data_block_info { unsigned int bsn; unsigned int ti; unsigned int e; - unsigned int cv; + unsigned int cv; /* FBI == 1 <=> CV == 0 */ unsigned int pi; unsigned int spb; }; @@ -77,6 +77,10 @@ struct gprs_rlc_data_info { unsigned int tfi; unsigned int cps; unsigned int rsb; + unsigned int usf; + unsigned int es_p; + unsigned int rrbp; + unsigned int pr; unsigned int num_data_blocks; unsigned int data_offs_bits[2]; struct gprs_rlc_data_block_info block_info[2]; -- cgit v1.2.3 From 6e9f9c20e94e09fad5fa96ee233476b3ff16b045 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Mon, 11 Jan 2016 11:15:45 +0100 Subject: edge: Add init functions for gprs_rlc_data_info Add the functions gprs_rlc_data_info_init_dl/ul which initialise a gprs_rlc_data_info structure depending on the coding scheme. The fields num_data_blocks, data_offs_bits, cs, and the data_blocks are valid after this call. The other fields are set to 0. The data blocks are initialised to the correct data_len, e == 1 (no extension header field), cv == 15 (not a final block). The other data block fields are set to 0. The gprs_rlc_data_block_info can also be initialised separately by using the gprs_rlc_data_block_info_init function. Sponsored-by: On-Waves ehf --- src/rlc.cpp | 46 ++++++++++++++++++++++++++++++++++++++++++++++ src/rlc.h | 7 +++++++ tests/edge/EdgeTest.cpp | 18 ++++++++++++++++++ tests/edge/EdgeTest.ok | 2 ++ 4 files changed, 73 insertions(+) diff --git a/src/rlc.cpp b/src/rlc.cpp index 4f62f23c..44ce817b 100644 --- a/src/rlc.cpp +++ b/src/rlc.cpp @@ -265,3 +265,49 @@ bool gprs_rlc_ul_window::invalidate_bsn(const uint16_t bsn) return was_valid; } + +static void gprs_rlc_data_header_init(struct gprs_rlc_data_info *rlc, + GprsCodingScheme cs, unsigned int header_bits) +{ + unsigned int i; + + memset(rlc, 0, sizeof(*rlc)); + + rlc->cs = cs; + rlc->num_data_blocks = cs.numDataBlocks(); + + OSMO_ASSERT(rlc->num_data_blocks <= ARRAY_SIZE(rlc->block_info)); + + for (i = 0; i < rlc->num_data_blocks; i++) { + gprs_rlc_data_block_info_init(&rlc->block_info[i], cs); + + rlc->data_offs_bits[i] = + header_bits + + (i+1) * cs.numDataBlockHeaderBits() + + i * 8 * rlc->block_info[0].data_len; + } +} + +void gprs_rlc_data_info_init_dl(struct gprs_rlc_data_info *rlc, + GprsCodingScheme cs) +{ + return gprs_rlc_data_header_init(rlc, cs, cs.numDataHeaderBitsDL()); +} + +void gprs_rlc_data_info_init_ul(struct gprs_rlc_data_info *rlc, + GprsCodingScheme cs) +{ + return gprs_rlc_data_header_init(rlc, cs, cs.numDataHeaderBitsUL()); +} + +void gprs_rlc_data_block_info_init(struct gprs_rlc_data_block_info *rdbi, + GprsCodingScheme cs) +{ + rdbi->data_len = cs.maxDataBlockBytes(); + rdbi->bsn = 0; + rdbi->ti = 0; + rdbi->e = 1; + rdbi->cv = 15; + rdbi->pi = 0; + rdbi->spb = 0; +} diff --git a/src/rlc.h b/src/rlc.h index 0cd7593a..59176253 100644 --- a/src/rlc.h +++ b/src/rlc.h @@ -99,6 +99,13 @@ struct gprs_rlc_data { GprsCodingScheme cs; }; +void gprs_rlc_data_info_init_dl(struct gprs_rlc_data_info *rlc, + GprsCodingScheme cs); +void gprs_rlc_data_info_init_ul(struct gprs_rlc_data_info *rlc, + GprsCodingScheme cs); +void gprs_rlc_data_block_info_init(struct gprs_rlc_data_block_info *rdbi, + GprsCodingScheme cs); + /* * I hold the currently transferred blocks and will provide * the routines to manipulate these arrays. diff --git a/tests/edge/EdgeTest.cpp b/tests/edge/EdgeTest.cpp index b26262ca..7bb81e47 100644 --- a/tests/edge/EdgeTest.cpp +++ b/tests/edge/EdgeTest.cpp @@ -481,6 +481,23 @@ static void test_rlc_unit_decoder() printf("=== end %s ===\n", __func__); } +static void test_rlc_info_init() +{ + struct gprs_rlc_data_info rlc; + + printf("=== start %s ===\n", __func__); + gprs_rlc_data_info_init_dl(&rlc, GprsCodingScheme(GprsCodingScheme::CS1)); + OSMO_ASSERT(rlc.num_data_blocks == 1); + OSMO_ASSERT(rlc.data_offs_bits[0] == 24); + OSMO_ASSERT(rlc.block_info[0].data_len == 20); + + gprs_rlc_data_info_init_dl(&rlc, GprsCodingScheme(GprsCodingScheme::MCS1)); + OSMO_ASSERT(rlc.num_data_blocks == 1); + OSMO_ASSERT(rlc.data_offs_bits[0] == 33); + OSMO_ASSERT(rlc.block_info[0].data_len == 22); + + printf("=== end %s ===\n", __func__); +} static const struct log_info_cat default_categories[] = { {"DCSN1", "\033[1;31m", "Concrete Syntax Notation One (CSN1)", LOGL_INFO, 0}, @@ -525,6 +542,7 @@ int main(int argc, char **argv) pcu_vty_init(&debug_log_info); test_coding_scheme(); + test_rlc_info_init(); test_rlc_unit_decoder(); if (getenv("TALLOC_REPORT_FULL")) diff --git a/tests/edge/EdgeTest.ok b/tests/edge/EdgeTest.ok index 791f0d5e..95ec2b3a 100644 --- a/tests/edge/EdgeTest.ok +++ b/tests/edge/EdgeTest.ok @@ -1,4 +1,6 @@ === start test_coding_scheme === === end test_coding_scheme === +=== start test_rlc_info_init === +=== end test_rlc_info_init === === start test_rlc_unit_decoder === === end test_rlc_unit_decoder === -- cgit v1.2.3 From f0e403911d1f00d83b8080e2d70fd9fe02dd4ad1 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Fri, 8 Jan 2016 10:07:53 +0100 Subject: edge: Add encoder for downlink RLC data blocks Currently the (GPRS) RLC block encoding is done by setting the header fields directly in gprs_rlcmac_dl_tbf::create_new_bsn. This is much more complex with EGPRS, since the data fields are not byte aligned, the header formats depend on the header type, and the mapping of bits to bytes is LSB first. This commit adds Encoding::rlc_write_dl_data_header which writes the header according to the given gprs_rlc_data_header structure. Encoding::rlc_copy_from_aligned_buffer is also added to copy byte sequences into the message. Note that the actual encoding of data units is not yet present. Sponsored-by: On-Waves ehf --- src/encoding.cpp | 120 ++++++++++++++++++++++++++++++++++++++++++++++++ src/encoding.h | 8 ++++ src/rlc.h | 15 ++++++ tests/edge/EdgeTest.cpp | 70 ++++++++++++++++++++++++++++ 4 files changed, 213 insertions(+) diff --git a/src/encoding.cpp b/src/encoding.cpp index fdc8d0ae..0756ffcb 100644 --- a/src/encoding.cpp +++ b/src/encoding.cpp @@ -25,6 +25,9 @@ #include #include +#include +#include + // GSM 04.08 9.1.18 Immediate assignment int Encoding::write_immediate_assignment( struct gprs_rlcmac_bts *bts, @@ -631,3 +634,120 @@ unsigned Encoding::write_repeated_page_info(bitvec * dest, unsigned& wp, uint8_t return wp; } +int Encoding::rlc_write_dl_data_header(const struct gprs_rlc_data_info *rlc, + uint8_t *data) +{ + struct gprs_rlc_dl_header_egprs_3 *egprs3; + struct rlc_dl_header *gprs; + unsigned int e_fbi_header; + GprsCodingScheme cs = rlc->cs; + + switch(cs.headerTypeData()) { + case GprsCodingScheme::HEADER_GPRS_DATA: + gprs = static_cast + ((void *)data); + + gprs->usf = rlc->usf; + gprs->s_p = rlc->es_p != 0 ? 1 : 0; + gprs->rrbp = rlc->rrbp; + gprs->pt = 0; + gprs->tfi = rlc->tfi; + gprs->pr = rlc->pr; + + gprs->fbi = rlc->block_info[0].cv == 0; + gprs->e = rlc->block_info[0].e; + gprs->bsn = rlc->block_info[0].bsn; + break; + + case GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_3: + egprs3 = static_cast + ((void *)data); + + egprs3->usf = rlc->usf; + egprs3->es_p = rlc->es_p; + egprs3->rrbp = rlc->rrbp; + egprs3->tfi_a = rlc->tfi >> 0; /* 1 bit LSB */ + egprs3->tfi_b = rlc->tfi >> 1; /* 4 bits */ + egprs3->pr = rlc->pr; + egprs3->cps = rlc->cps; + + egprs3->bsn1_a = rlc->block_info[0].bsn >> 0; /* 2 bits LSB */ + egprs3->bsn1_b = rlc->block_info[0].bsn >> 2; /* 8 bits */ + egprs3->bsn1_c = rlc->block_info[0].bsn >> 10; /* 1 bit */ + + egprs3->spb = rlc->block_info[0].spb; + + e_fbi_header = rlc->block_info[0].e ? 0x01 : 0; + e_fbi_header |= rlc->block_info[0].cv == 0 ? 0x02 : 0; /* FBI */ + e_fbi_header <<= 7; + data[3] = (data[3] & 0b01111111) | (e_fbi_header >> 0); + data[4] = (data[4] & 0b11111110) | (e_fbi_header >> 8); + break; + + case GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_1: + case GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_2: + /* TODO: Support both header types */ + /* fall through */ + default: + LOGP(DRLCMACDL, LOGL_ERROR, + "Encoding of uplink %s data blocks not yet supported.\n", + cs.name()); + return -ENOTSUP; + }; + + return 0; +} + +/** + * \brief Copy LSB bitstream RLC data block from byte aligned buffer. + * + * Note that the bitstream is encoded in LSB first order, so the two octets + * 654321xx xxxxxx87 contain the octet 87654321 starting at bit position 3 + * (LSB has bit position 1). This is a different order than the one used by + * CSN.1. + * + * \param data_block_idx The block index, 0..1 for header type 1, 0 otherwise + * \param src A pointer to the start of the RLC block (incl. the header) + * \param buffer A data area of a least the size of the RLC block + * \returns the number of bytes copied + */ +unsigned int Encoding::rlc_copy_from_aligned_buffer( + const struct gprs_rlc_data_info *rlc, + unsigned int data_block_idx, + uint8_t *dst, const uint8_t *buffer) +{ + unsigned int hdr_bytes; + unsigned int extra_bits; + unsigned int i; + + uint8_t c, last_c; + const uint8_t *src; + const struct gprs_rlc_data_block_info *rdbi; + + OSMO_ASSERT(data_block_idx < rlc->num_data_blocks); + rdbi = &rlc->block_info[data_block_idx]; + + hdr_bytes = rlc->data_offs_bits[data_block_idx] / 8; + extra_bits = (rlc->data_offs_bits[data_block_idx] % 8); + + if (extra_bits == 0) { + /* It is aligned already */ + memmove(dst + hdr_bytes, buffer, rdbi->data_len); + return rdbi->data_len; + } + + src = buffer; + dst = dst + hdr_bytes; + last_c = *dst << (8 - extra_bits); + + for (i = 0; i < rdbi->data_len; i++) { + c = src[i]; + *(dst++) = (last_c >> (8 - extra_bits)) | (c << extra_bits); + last_c = c; + } + + /* overwrite the lower extra_bits */ + *dst = (*dst & (0xff << extra_bits)) | (last_c >> (8 - extra_bits)); + + return rdbi->data_len; +} diff --git a/src/encoding.h b/src/encoding.h index ff62bc90..6764ce41 100644 --- a/src/encoding.h +++ b/src/encoding.h @@ -68,4 +68,12 @@ public: uint8_t *identity, uint8_t chan_needed); static unsigned write_packet_paging_request(bitvec * dest); + + static int rlc_write_dl_data_header( + const struct gprs_rlc_data_info *rlc, + uint8_t *data); + static unsigned int rlc_copy_from_aligned_buffer( + const struct gprs_rlc_data_info *rlc, + unsigned int data_block_idx, + uint8_t *dst, const uint8_t *buffer); }; diff --git a/src/rlc.h b/src/rlc.h index 59176253..a11b4ce8 100644 --- a/src/rlc.h +++ b/src/rlc.h @@ -298,6 +298,21 @@ struct gprs_rlc_ul_header_egprs_3 { spare:1, dummy:1; } __attribute__ ((packed)); + +struct gprs_rlc_dl_header_egprs_3 { + uint8_t usf:3, + es_p:2, + rrbp:2, + tfi_a:1; + uint8_t tfi_b:4, + pr:2, + bsn1_a:2; + uint8_t bsn1_b:8; + uint8_t bsn1_c:1, + cps:4, + spb:2, + dummy:1; +} __attribute__ ((packed)); #else # error "Only little endian headers are supported yet. TODO: add missing structs" #endif diff --git a/tests/edge/EdgeTest.cpp b/tests/edge/EdgeTest.cpp index 7bb81e47..11459457 100644 --- a/tests/edge/EdgeTest.cpp +++ b/tests/edge/EdgeTest.cpp @@ -23,6 +23,7 @@ #include "gprs_debug.h" #include "gprs_coding_scheme.h" #include "decoding.h" +#include "encoding.h" #include "rlc.h" extern "C" { @@ -36,6 +37,7 @@ extern "C" { } #include +#include void *tall_pcu_ctx; int16_t spoof_mnc = 0, spoof_mcc = 0; @@ -481,6 +483,73 @@ static void test_rlc_unit_decoder() printf("=== end %s ===\n", __func__); } +static void test_rlc_unaligned_copy() +{ + uint8_t bits[256]; + uint8_t saved_block[256]; + uint8_t test_block[256]; + uint8_t out_block[256]; + GprsCodingScheme::Scheme scheme; + int pattern; + volatile unsigned int block_idx, i; + + for (scheme = GprsCodingScheme::CS1; + scheme < GprsCodingScheme::NUM_SCHEMES; + scheme = GprsCodingScheme::Scheme(scheme + 1)) + { + GprsCodingScheme cs(scheme); + + for (pattern = 0; pattern <= 0xff; pattern += 0xff) { + /* prepare test block */ + test_block[0] = pattern ^ 0xff; + for (i = 1; i + 1 < cs.maxDataBlockBytes(); i++) + test_block[i] = i; + test_block[cs.maxDataBlockBytes()-1] = pattern ^ 0xff; + + for (block_idx = 0; + block_idx < cs.numDataBlocks(); + block_idx++) + { + struct gprs_rlc_data_info rlc; + gprs_rlc_data_info_init_dl(&rlc, cs); + + memset(bits, pattern, sizeof(bits)); + Decoding::rlc_copy_to_aligned_buffer( + &rlc, block_idx, bits, saved_block); + + fprintf(stderr, + "Test data block: %s\n", + osmo_hexdump(test_block, cs.maxDataBlockBytes())); + + Encoding::rlc_copy_from_aligned_buffer( + &rlc, block_idx, bits, test_block); + + fprintf(stderr, + "Encoded message block, %s, idx %d, " + "pattern %02x: %s\n", + rlc.cs.name(), block_idx, pattern, + osmo_hexdump(bits, cs.sizeDL())); + + Decoding::rlc_copy_to_aligned_buffer( + &rlc, block_idx, bits, out_block); + + fprintf(stderr, + "Out data block: %s\n", + osmo_hexdump(out_block, cs.maxDataBlockBytes())); + /* restore original bits */ + Encoding::rlc_copy_from_aligned_buffer( + &rlc, block_idx, bits, saved_block); + + OSMO_ASSERT(memcmp(test_block, out_block, + rlc.cs.maxDataBlockBytes()) == 0); + + for (i = 0; i < sizeof(bits); i++) + OSMO_ASSERT(bits[i] == pattern); + } + } + } +} + static void test_rlc_info_init() { struct gprs_rlc_data_info rlc; @@ -544,6 +613,7 @@ int main(int argc, char **argv) test_coding_scheme(); test_rlc_info_init(); test_rlc_unit_decoder(); + test_rlc_unaligned_copy(); if (getenv("TALLOC_REPORT_FULL")) talloc_report_full(tall_pcu_ctx, stderr); -- cgit v1.2.3 From 314ec4db40d46634e38adcbe1be93986278b605a Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Mon, 11 Jan 2016 13:27:07 +0100 Subject: tbf: Remove obsolete TLLI functions This commit removes gprs_rlcmac_tbf::extract_tlli and Decoding::tlli_from_ul_data. Sponsored-by: On-Waves ehf --- src/decoding.cpp | 41 ----------------------------------------- src/decoding.h | 2 -- src/tbf.cpp | 27 --------------------------- src/tbf.h | 1 - 4 files changed, 71 deletions(-) diff --git a/src/decoding.cpp b/src/decoding.cpp index 45716413..cb1b34d4 100644 --- a/src/decoding.cpp +++ b/src/decoding.cpp @@ -281,47 +281,6 @@ int Decoding::rlc_data_from_ul_data( return num_chunks; } -int Decoding::tlli_from_ul_data(const uint8_t *data, uint8_t len, - uint32_t *tlli) -{ - struct rlc_ul_header *rh = (struct rlc_ul_header *)data; - struct rlc_li_field *li; - uint8_t e; - uint32_t _tlli; - - if (!rh->ti) - return -EINVAL; - - data += 3; - len -= 3; - e = rh->e; - /* if E is not set (LI follows) */ - while (!e) { - if (!len) { - LOGP(DRLCMACUL, LOGL_NOTICE, "UL DATA LI extended, " - "but no more data\n"); - return -EINVAL; - } - /* get new E */ - li = (struct rlc_li_field *)data; - if (li->e == 0) /* if LI==0, E is interpreted as '1' */ - e = 1; - else - e = li->e; - data++; - len--; - } - if (len < 4) { - LOGP(DRLCMACUL, LOGL_NOTICE, "UL DATA TLLI out of frame " - "border\n"); - return -EINVAL; - } - memcpy(&_tlli, data, 4); - *tlli = ntohl(_tlli); - - return 0; -} - uint8_t Decoding::get_ms_class_by_capability(MS_Radio_Access_capability_t *cap) { int i; diff --git a/src/decoding.h b/src/decoding.h index 94926946..c75b19a1 100644 --- a/src/decoding.h +++ b/src/decoding.h @@ -32,8 +32,6 @@ public: bool is_complete; }; - static int tlli_from_ul_data(const uint8_t *data, uint8_t len, - uint32_t *tlli); static int rlc_data_from_ul_data( const struct gprs_rlc_data_block_info *rdbi, GprsCodingScheme cs, const uint8_t *data, RlcData *chunks, diff --git a/src/tbf.cpp b/src/tbf.cpp index 9c5502a8..1f0576af 100644 --- a/src/tbf.cpp +++ b/src/tbf.cpp @@ -1060,33 +1060,6 @@ int gprs_rlcmac_tbf::set_tlli_from_ul(uint32_t new_tlli) return 1; } -int gprs_rlcmac_tbf::extract_tlli(const uint8_t *data, const size_t len) -{ - struct rlc_ul_header *rh = (struct rlc_ul_header *)data; - uint32_t new_tlli; - int rc; - - OSMO_ASSERT(direction == GPRS_RLCMAC_UL_TBF); - - /* no TLLI yet */ - if (!rh->ti) { - LOGP(DRLCMACUL, LOGL_NOTICE, "UL DATA TFI=%d without " - "TLLI, but no TLLI received yet\n", rh->tfi); - return 0; - } - rc = Decoding::tlli_from_ul_data(data, len, &new_tlli); - if (rc) { - bts->decode_error(); - LOGP(DRLCMACUL, LOGL_NOTICE, "Failed to decode TLLI " - "of UL DATA TFI=%d.\n", rh->tfi); - return 0; - } - LOGP(DRLCMACUL, LOGL_INFO, "Decoded premier TLLI=0x%08x of " - "UL DATA TFI=%d.\n", new_tlli, rh->tfi); - - return set_tlli_from_ul(new_tlli); -} - const char *tbf_name(gprs_rlcmac_tbf *tbf) { return tbf->name(); diff --git a/src/tbf.h b/src/tbf.h index 7c3fba8d..cd982739 100644 --- a/src/tbf.h +++ b/src/tbf.h @@ -218,7 +218,6 @@ struct gprs_rlcmac_tbf { protected: gprs_rlcmac_bts *bts_data() const; - int extract_tlli(const uint8_t *data, const size_t len); int set_tlli_from_ul(uint32_t new_tlli); void merge_and_clear_ms(GprsMs *old_ms); -- cgit v1.2.3 From 53efa3eeb64010c75210bb58aaed3fe8d6353e06 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Mon, 11 Jan 2016 16:12:01 +0100 Subject: tbf/test: Add missing function name printfs Some test function don't have the "=== start/end ===" printfs. Sponsored-by: On-Waves ehf --- tests/tbf/TbfTest.cpp | 8 ++++++++ tests/tbf/TbfTest.ok | 6 ++++++ 2 files changed, 14 insertions(+) diff --git a/tests/tbf/TbfTest.cpp b/tests/tbf/TbfTest.cpp index 66fa9825..f9431f60 100644 --- a/tests/tbf/TbfTest.cpp +++ b/tests/tbf/TbfTest.cpp @@ -81,6 +81,8 @@ static void test_tbf_tlli_update() BTS the_bts; GprsMs *ms, *ms_new; + printf("=== start %s ===\n", __func__); + the_bts.bts_data()->alloc_algorithm = alloc_algorithm_a; the_bts.bts_data()->trx[0].pdch[2].enable(); the_bts.bts_data()->trx[0].pdch[3].enable(); @@ -138,6 +140,8 @@ static void test_tbf_tlli_update() OSMO_ASSERT(ul_tbf->ta() == 6); OSMO_ASSERT(dl_tbf->ta() == 6); + + printf("=== end %s ===\n", __func__); } static uint8_t llc_data[200]; @@ -239,6 +243,8 @@ static void test_tbf_final_ack(enum test_tbf_final_ack_mode test_mode) uint8_t rbb[64/8]; + printf("=== start %s ===\n", __func__); + gprs_rlcmac_dl_tbf *dl_tbf; gprs_rlcmac_tbf *new_tbf; @@ -292,6 +298,8 @@ static void test_tbf_final_ack(enum test_tbf_final_ack_mode test_mode) tbf_free(new_tbf); OSMO_ASSERT(ms->dl_tbf() == NULL); } + + printf("=== end %s ===\n", __func__); } static void test_tbf_delayed_release() diff --git a/tests/tbf/TbfTest.ok b/tests/tbf/TbfTest.ok index 0ad9ad47..916ea52b 100644 --- a/tests/tbf/TbfTest.ok +++ b/tests/tbf/TbfTest.ok @@ -1,5 +1,11 @@ === start test_tbf_base === === end test_tbf_base === +=== start test_tbf_tlli_update === +=== end test_tbf_tlli_update === +=== start test_tbf_final_ack === +=== end test_tbf_final_ack === +=== start test_tbf_final_ack === +=== end test_tbf_final_ack === === start test_tbf_delayed_release === === end test_tbf_delayed_release === === start test_tbf_imsi === -- cgit v1.2.3 From 3a3b6a7e861d813894ae9fb35c973a60628ce58a Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Mon, 11 Jan 2016 16:15:45 +0100 Subject: edge: Use RLC data block encoding functions This commit removes the use of struct rlc_dl_header from gprs_rlcmac_dl_tbf::create_dl_acked_block and gprs_rlcmac_dl_tbf::create_new_bsn. Instead of patching the data area directly, the RLC block encoding functions are used. Note that the data unit encoding is still hard-coded to GPRS in create_new_bsn, so using MCS 1-4 (albeit being supported by the encoder) will not work yet. Sponsored-by: On-Waves ehf --- src/tbf_dl.cpp | 101 +++++++++++++++--------- tests/tbf/TbfTest.err | 213 +++++++++++++++++++++++++++++++++----------------- 2 files changed, 204 insertions(+), 110 deletions(-) diff --git a/src/tbf_dl.cpp b/src/tbf_dl.cpp index ac1c253f..a1f8b60a 100644 --- a/src/tbf_dl.cpp +++ b/src/tbf_dl.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include "pcu_utils.h" @@ -423,13 +424,13 @@ void gprs_rlcmac_dl_tbf::schedule_next_frame() struct msgb *gprs_rlcmac_dl_tbf::create_new_bsn(const uint32_t fn, const uint8_t ts) { - struct rlc_dl_header *rh; struct rlc_li_field *li; uint8_t *delimiter, *data, *e_pointer; uint16_t space, chunk; gprs_rlc_data *rlc_data; const uint16_t bsn = m_window.v_s(); GprsCodingScheme cs = current_cs(); + gprs_rlc_data_block_info *rdbi; if (m_llc.frame_length() == 0) schedule_next_frame(); @@ -439,29 +440,27 @@ struct msgb *gprs_rlcmac_dl_tbf::create_new_bsn(const uint32_t fn, const uint8_t OSMO_ASSERT(cs.isValid()); - /* total length of block, including spare bits */ - const uint8_t block_length = cs.sizeDL(); - /* length of usable data of block, w/o spare bits (GPRS), inc. MAC */ - const uint8_t block_data_len = cs.maxBytesDL(); + /* length of usable data block (single data unit w/o header) */ + const uint8_t block_data_len = cs.maxDataBlockBytes(); /* now we still have untransmitted LLC data, so we fill mac block */ rlc_data = m_rlc.block(bsn); data = rlc_data->prepare(block_data_len); rlc_data->cs = cs; + rlc_data->len = block_data_len; - rh = (struct rlc_dl_header *)data; - rh->pt = 0; /* Data Block */ - rh->rrbp = rh->s_p = 0; /* Polling, set later, if required */ - rh->usf = 7; /* will be set at scheduler */ - rh->pr = 0; /* FIXME: power reduction */ - rh->tfi = m_tfi; /* TFI */ - rh->fbi = 0; /* Final Block Indicator, set late, if true */ - rh->bsn = bsn; /* Block Sequence Number */ - rh->e = 0; /* Extension bit, maybe set later */ - e_pointer = data + 2; /* points to E of current chunk */ - data += sizeof(*rh); + rdbi = &(rlc_data->block_info); + memset(rdbi, 0, sizeof(*rdbi)); + rdbi->data_len = block_data_len; + + rdbi->cv = 15; /* Final Block Indicator, set late, if true */ + rdbi->bsn = bsn; /* Block Sequence Number */ + rdbi->e = 1; /* Extension bit, maybe set later (1: no extension) */ + + e_pointer = NULL; /* points to E of current chunk if it is stored in an + extension byte */ delimiter = data; /* where next length header would be stored */ - space = block_data_len - sizeof(*rh); + space = block_data_len; while (1) { if (m_llc.frame_length() == 0) { /* A header will need to by added, so we just need @@ -492,7 +491,8 @@ struct msgb *gprs_rlcmac_dl_tbf::create_new_bsn(const uint32_t fn, const uint8_t "only remaining space, and we are done\n", chunk, space); /* block is filled, so there is no extension */ - *e_pointer |= 0x01; + if (e_pointer) + *e_pointer |= 0x01; /* fill only space */ m_llc.consume(data, space); /* return data block as message */ @@ -510,12 +510,13 @@ struct msgb *gprs_rlcmac_dl_tbf::create_new_bsn(const uint32_t fn, const uint8_t "len=%d\n", tbf_name(this), m_llc.frame_length()); gprs_rlcmac_dl_bw(this, m_llc.frame_length()); /* block is filled, so there is no extension */ - *e_pointer |= 0x01; + if (e_pointer) + *e_pointer |= 0x01; /* fill space */ m_llc.consume(data, space); m_llc.reset(); /* final block */ - rh->fbi = 1; /* we indicate final block */ + rdbi->cv = 0; /* we indicate final block */ request_dl_ack(); set_state(GPRS_RLCMAC_FINISHED); /* return data block as message */ @@ -559,6 +560,7 @@ struct msgb *gprs_rlcmac_dl_tbf::create_new_bsn(const uint32_t fn, const uint8_t li->e = 0; /* Extension bit, maybe set later */ li->m = 0; /* will be set later, if there is more LLC data */ li->li = chunk; /* length of chunk */ + rdbi->e = 0; /* 0: extensions present */ e_pointer = delimiter; /* points to E of current delimiter */ delimiter++; /* copy (rest of) LLC frame to space and reset later */ @@ -582,7 +584,7 @@ struct msgb *gprs_rlcmac_dl_tbf::create_new_bsn(const uint32_t fn, const uint8_t "done.\n"); li->e = 1; /* we cannot extend */ - rh->fbi = 1; /* we indicate final block */ + rdbi->cv = 0; /* we indicate final block */ request_dl_ack(); set_state(GPRS_RLCMAC_FINISHED); break; @@ -593,10 +595,9 @@ struct msgb *gprs_rlcmac_dl_tbf::create_new_bsn(const uint32_t fn, const uint8_t li->e = 1; /* we cannot extend */ break; } - LOGP(DRLCMACDL, LOGL_DEBUG, "data block: %s\n", - osmo_hexdump(rlc_data->block, block_length)); -#warning "move this up?" - rlc_data->len = block_length; + LOGP(DRLCMACDL, LOGL_DEBUG, "data block (BSN %d, %s): %s\n", + bsn, rlc_data->cs.name(), + osmo_hexdump(rlc_data->block, block_data_len)); /* raise send state and set ack state array */ m_window.m_v_b.mark_unacked(bsn); m_window.increment_send(); @@ -608,16 +609,30 @@ struct msgb *gprs_rlcmac_dl_tbf::create_dl_acked_block( const uint32_t fn, const uint8_t ts, const int index) { - uint8_t *data; - struct rlc_dl_header *rh; + uint8_t *block_data, *msg_data; struct msgb *dl_msg; - uint8_t len; + unsigned msg_len; bool need_poll; + /* TODO: support MCS-7 - MCS-9, where data_block_idx can be 1 */ + unsigned int data_block_idx = 0; + + gprs_rlc_data_info rlc; + GprsCodingScheme cs; + gprs_rlc_data_block_info *rdbi; /* get data and header from current block */ - data = m_rlc.block(index)->block; - len = m_rlc.block(index)->len; - rh = (struct rlc_dl_header *)data; + block_data = m_rlc.block(index)->block; + + cs = m_rlc.block(index)->cs; + + gprs_rlc_data_info_init_dl(&rlc, cs); + + rlc.usf = 7; /* will be set at scheduler */ + rlc.pr = 0; /* FIXME: power reduction */ + rlc.tfi = m_tfi; /* TFI */ + + rlc.block_info[data_block_idx] = m_rlc.block(index)->block_info; + rdbi = &rlc.block_info[data_block_idx]; /* If the TBF has just started, relate frames_since_last_poll to the * current fn */ @@ -625,9 +640,7 @@ struct msgb *gprs_rlcmac_dl_tbf::create_dl_acked_block( m_last_dl_poll_fn = fn; need_poll = state_flags & (1 << GPRS_RLCMAC_FLAG_TO_DL_ACK); - /* Clear Polling, if still set in history buffer */ - rh->s_p = 0; - + /* poll after POLL_ACK_AFTER_FRAMES frames, or when final block is tx. */ if (m_tx_counter >= POLL_ACK_AFTER_FRAMES || m_dl_ack_requested || @@ -662,7 +675,7 @@ struct msgb *gprs_rlcmac_dl_tbf::create_dl_acked_block( "TS %d\n", ts); m_tx_counter = 0; /* start timer whenever we send the final block */ - if (rh->fbi == 1) + if (rdbi->cv == 0) tbf_timer_start(this, 3191, bts_data()->t3191, 0); /* schedule polling */ @@ -676,8 +689,8 @@ struct msgb *gprs_rlcmac_dl_tbf::create_dl_acked_block( m_dl_ack_requested = false; /* set polling in header */ - rh->rrbp = 0; /* N+13 */ - rh->s_p = 1; /* Polling */ + rlc.rrbp = 0; /* N+13 */ + rlc.es_p = 1; /* Polling */ m_last_dl_poll_fn = poll_fn; @@ -687,15 +700,25 @@ struct msgb *gprs_rlcmac_dl_tbf::create_dl_acked_block( } } + msg_len = cs.sizeDL(); + /* return data block as message */ - dl_msg = msgb_alloc(len, "rlcmac_dl_data"); + dl_msg = msgb_alloc(msg_len, "rlcmac_dl_data"); if (!dl_msg) return NULL; + msg_data = msgb_put(dl_msg, msg_len); + Encoding::rlc_write_dl_data_header(&rlc, msg_data); + Encoding::rlc_copy_from_aligned_buffer(&rlc, data_block_idx, msg_data, + block_data); + + LOGP(DRLCMACDL, LOGL_DEBUG, "msg block (BSN %d, %s): %s\n", + index, cs.name(), + msgb_hexdump(dl_msg)); + /* Increment TX-counter */ m_tx_counter++; - memcpy(msgb_put(dl_msg, len), data, len); bts->rlc_sent(); return dl_msg; diff --git a/tests/tbf/TbfTest.err b/tests/tbf/TbfTest.err index 74c88003..80aee605 100644 --- a/tests/tbf/TbfTest.err +++ b/tests/tbf/TbfTest.err @@ -69,14 +69,16 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==0) - Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) (len=200) - Sending new block at BSN 0, CS=CS-1 -- Chunk with length 200 larger than space (20) left in block: copy only remaining space, and we are done -data block: 07 00 01 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 +data block (BSN 0, CS-1): 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 +msg block (BSN 0, CS-1): 07 00 01 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=4 block=1 data=07 00 01 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 Received RTS for PDCH: TRX=0 TS=4 FN=8 block_nr=2 scheduling free USF for polling at FN=13 of TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==1) - Sending new block at BSN 1, CS=CS-1 -- Chunk with length 180 larger than space (20) left in block: copy only remaining space, and we are done -data block: 07 00 03 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 +data block (BSN 1, CS-1): 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 +msg block (BSN 1, CS-1): 07 00 03 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=8 block=2 data=07 00 03 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink acknowledge - Final ACK received. @@ -147,14 +149,16 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==0) - Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) (len=200) - Sending new block at BSN 0, CS=CS-1 -- Chunk with length 200 larger than space (20) left in block: copy only remaining space, and we are done -data block: 07 00 01 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 +data block (BSN 0, CS-1): 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 +msg block (BSN 0, CS-1): 07 00 01 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=4 block=1 data=07 00 01 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 Received RTS for PDCH: TRX=0 TS=4 FN=8 block_nr=2 scheduling free USF for polling at FN=13 of TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==1) - Sending new block at BSN 1, CS=CS-1 -- Chunk with length 180 larger than space (20) left in block: copy only remaining space, and we are done -data block: 07 00 03 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 +data block (BSN 1, CS-1): 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 +msg block (BSN 1, CS-1): 07 00 03 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=8 block=2 data=07 00 03 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink acknowledge - Final ACK received. @@ -225,63 +229,73 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==0) - Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) (len=200) - Sending new block at BSN 0, CS=CS-1 -- Chunk with length 200 larger than space (20) left in block: copy only remaining space, and we are done -data block: 07 00 01 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 +data block (BSN 0, CS-1): 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 +msg block (BSN 0, CS-1): 07 00 01 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=4 block=1 data=07 00 01 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 Received RTS for PDCH: TRX=0 TS=4 FN=8 block_nr=2 scheduling free USF for polling at FN=13 of TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==1) - Sending new block at BSN 1, CS=CS-1 -- Chunk with length 180 larger than space (20) left in block: copy only remaining space, and we are done -data block: 07 00 03 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 +data block (BSN 1, CS-1): 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 +msg block (BSN 1, CS-1): 07 00 03 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=8 block=2 data=07 00 03 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==2) - Sending new block at BSN 2, CS=CS-1 -- Chunk with length 160 larger than space (20) left in block: copy only remaining space, and we are done -data block: 07 00 05 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b +data block (BSN 2, CS-1): 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b +msg block (BSN 2, CS-1): 07 00 05 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=13 block=3 data=07 00 05 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==3) - Sending new block at BSN 3, CS=CS-1 -- Chunk with length 140 larger than space (20) left in block: copy only remaining space, and we are done -data block: 07 00 07 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f +data block (BSN 3, CS-1): 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f +msg block (BSN 3, CS-1): 07 00 07 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=17 block=4 data=07 00 07 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==4) - Sending new block at BSN 4, CS=CS-1 -- Chunk with length 120 larger than space (20) left in block: copy only remaining space, and we are done -data block: 07 00 09 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 +data block (BSN 4, CS-1): 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 +msg block (BSN 4, CS-1): 07 00 09 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=21 block=5 data=07 00 09 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==5) - Sending new block at BSN 5, CS=CS-1 -- Chunk with length 100 larger than space (20) left in block: copy only remaining space, and we are done -data block: 07 00 0b 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 +data block (BSN 5, CS-1): 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 +msg block (BSN 5, CS-1): 07 00 0b 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=26 block=6 data=07 00 0b 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==6) - Sending new block at BSN 6, CS=CS-1 -- Chunk with length 80 larger than space (20) left in block: copy only remaining space, and we are done -data block: 07 00 0d 78 79 7a 7b 7c 7d 7e 7f 80 81 82 83 84 85 86 87 88 89 8a 8b +data block (BSN 6, CS-1): 78 79 7a 7b 7c 7d 7e 7f 80 81 82 83 84 85 86 87 88 89 8a 8b +msg block (BSN 6, CS-1): 07 00 0d 78 79 7a 7b 7c 7d 7e 7f 80 81 82 83 84 85 86 87 88 89 8a 8b Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=30 block=7 data=07 00 0d 78 79 7a 7b 7c 7d 7e 7f 80 81 82 83 84 85 86 87 88 89 8a 8b Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==7) - Sending new block at BSN 7, CS=CS-1 -- Chunk with length 60 larger than space (20) left in block: copy only remaining space, and we are done -data block: 07 00 0f 8c 8d 8e 8f 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f +data block (BSN 7, CS-1): 8c 8d 8e 8f 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f +msg block (BSN 7, CS-1): 07 00 0f 8c 8d 8e 8f 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=34 block=8 data=07 00 0f 8c 8d 8e 8f 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==8) - Sending new block at BSN 8, CS=CS-1 -- Chunk with length 40 larger than space (20) left in block: copy only remaining space, and we are done -data block: 07 00 11 a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af b0 b1 b2 b3 +data block (BSN 8, CS-1): a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af b0 b1 b2 b3 +msg block (BSN 8, CS-1): 07 00 11 a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af b0 b1 b2 b3 Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=39 block=9 data=07 00 11 a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af b0 b1 b2 b3 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==9) - Sending new block at BSN 9, CS=CS-1 -- Chunk with length 20 would exactly fit into space (20): add length header with LI=0, to make frame extend to next block, and we are done -data block: 07 00 12 01 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf c0 c1 c2 c3 c4 c5 c6 -Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=43 block=10 data=07 00 12 01 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf c0 c1 c2 c3 c4 c5 c6 +data block (BSN 9, CS-1): 01 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf c0 c1 c2 c3 c4 c5 c6 +msg block (BSN 9, CS-1): 07 00 13 01 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf c0 c1 c2 c3 c4 c5 c6 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=43 block=10 data=07 00 13 01 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf c0 c1 c2 c3 c4 c5 c6 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==10) - Sending new block at BSN 10, CS=CS-1 @@ -289,61 +303,71 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==10) Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW)len=200 - Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) (len=200) -- Chunk with length 200 larger than space (18) left in block: copy only remaining space, and we are done -data block: 07 00 14 07 c7 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 +data block (BSN 10, CS-1): 07 c7 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 +msg block (BSN 10, CS-1): 07 00 14 07 c7 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=47 block=11 data=07 00 14 07 c7 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=4 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==11) - Sending new block at BSN 11, CS=CS-1 -- Chunk with length 182 larger than space (20) left in block: copy only remaining space, and we are done -data block: 07 00 17 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 +data block (BSN 11, CS-1): 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 +msg block (BSN 11, CS-1): 07 00 17 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=52 block=0 data=07 00 17 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=4 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==12) - Sending new block at BSN 12, CS=CS-1 -- Chunk with length 162 larger than space (20) left in block: copy only remaining space, and we are done -data block: 07 00 19 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 +data block (BSN 12, CS-1): 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 +msg block (BSN 12, CS-1): 07 00 19 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=56 block=1 data=07 00 19 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=4 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==13) - Sending new block at BSN 13, CS=CS-1 -- Chunk with length 142 larger than space (20) left in block: copy only remaining space, and we are done -data block: 07 00 1b 3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d +data block (BSN 13, CS-1): 3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d +msg block (BSN 13, CS-1): 07 00 1b 3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=60 block=2 data=07 00 1b 3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=4 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==14) - Sending new block at BSN 14, CS=CS-1 -- Chunk with length 122 larger than space (20) left in block: copy only remaining space, and we are done -data block: 07 00 1d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 +data block (BSN 14, CS-1): 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 +msg block (BSN 14, CS-1): 07 00 1d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=65 block=3 data=07 00 1d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=4 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==15) - Sending new block at BSN 15, CS=CS-1 -- Chunk with length 102 larger than space (20) left in block: copy only remaining space, and we are done -data block: 07 00 1f 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 +data block (BSN 15, CS-1): 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 +msg block (BSN 15, CS-1): 07 00 1f 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=69 block=4 data=07 00 1f 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=4 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==16) - Sending new block at BSN 16, CS=CS-1 -- Chunk with length 82 larger than space (20) left in block: copy only remaining space, and we are done -data block: 07 00 21 76 77 78 79 7a 7b 7c 7d 7e 7f 80 81 82 83 84 85 86 87 88 89 +data block (BSN 16, CS-1): 76 77 78 79 7a 7b 7c 7d 7e 7f 80 81 82 83 84 85 86 87 88 89 +msg block (BSN 16, CS-1): 07 00 21 76 77 78 79 7a 7b 7c 7d 7e 7f 80 81 82 83 84 85 86 87 88 89 Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=73 block=5 data=07 00 21 76 77 78 79 7a 7b 7c 7d 7e 7f 80 81 82 83 84 85 86 87 88 89 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=4 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==17) - Sending new block at BSN 17, CS=CS-1 -- Chunk with length 62 larger than space (20) left in block: copy only remaining space, and we are done -data block: 07 00 23 8a 8b 8c 8d 8e 8f 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d +data block (BSN 17, CS-1): 8a 8b 8c 8d 8e 8f 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d +msg block (BSN 17, CS-1): 07 00 23 8a 8b 8c 8d 8e 8f 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=78 block=6 data=07 00 23 8a 8b 8c 8d 8e 8f 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=4 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==18) - Sending new block at BSN 18, CS=CS-1 -- Chunk with length 42 larger than space (20) left in block: copy only remaining space, and we are done -data block: 07 00 25 9e 9f a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af b0 b1 +data block (BSN 18, CS-1): 9e 9f a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af b0 b1 +msg block (BSN 18, CS-1): 07 00 25 9e 9f a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af b0 b1 Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=82 block=7 data=07 00 25 9e 9f a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af b0 b1 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=4 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==19) - Sending new block at BSN 19, CS=CS-1 -- Chunk with length 22 larger than space (20) left in block: copy only remaining space, and we are done -data block: 07 00 27 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf c0 c1 c2 c3 c4 c5 +data block (BSN 19, CS-1): b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf c0 c1 c2 c3 c4 c5 +msg block (BSN 19, CS-1): 07 00 27 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf c0 c1 c2 c3 c4 c5 Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=86 block=8 data=07 00 27 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf c0 c1 c2 c3 c4 c5 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=4 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==20) @@ -354,9 +378,10 @@ Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW)len=200 -- Chunk with length 16 is less than remaining space (17): add length header to to delimit LLC frame Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW)len=16 -- No space left, so we are done. -data block: 07 00 28 0a 41 c6 c7 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +data block (BSN 20, CS-1): 0a 41 c6 c7 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already sheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW), so we must wait for requesting downlink ack +msg block (BSN 20, CS-1): 07 00 28 0a 41 c6 c7 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=91 block=9 data=07 00 28 0a 41 c6 c7 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink acknowledge - ack: (BSN=85)"RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR"(BSN=20) R=ACK I=NACK @@ -390,9 +415,10 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==21 .. V(S)==21) -- Chunk with length 19 is less than remaining space (20): add length header to to delimit LLC frame Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW)len=19 -- No space left, so we are done. -data block: 07 00 2a 4d 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +data block (BSN 21, CS-1): 4d 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already sheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW), so we must wait for requesting downlink ack +msg block (BSN 21, CS-1): 07 00 2a 4d 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=95 block=10 data=07 00 2a 4d 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink acknowledge - ack: (BSN=86)"RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR"(BSN=21) R=ACK I=NACK @@ -407,9 +433,10 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==22 .. V(S)==22) Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW)len=19 -- Final block, so we done. TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) changes state from FLOW to FINISHED -data block: 07 01 2c 4d 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +data block (BSN 22, CS-1): 4d 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already sheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FINISHED), so we must wait for requesting downlink ack +msg block (BSN 22, CS-1): 07 01 2c 4d 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=203 block=11 data=07 01 2c 4d 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FINISHED) downlink acknowledge - Final ACK received. @@ -1347,7 +1374,8 @@ TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN) downlink (V(A)==0 .. V(S)==0) Complete DL frame for TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN)len=19 - Dequeue next LLC for TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN) (len=19) -- No space left, so we are done. -data block: 07 00 00 4d 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +data block (BSN 0, CS-1): 4d 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +msg block (BSN 0, CS-1): 07 00 00 4d 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 MSG = 07 00 00 4d 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN) downlink (V(A)==0 .. V(S)==1) - Sending new block at BSN 1, CS=CS-1 @@ -1355,7 +1383,8 @@ TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN) downlink (V(A)==0 .. V(S)==1) Complete DL frame for TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN)len=19 - Dequeue next LLC for TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN) (len=19) -- No space left, so we are done. -data block: 07 00 02 4d 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 +data block (BSN 1, CS-1): 4d 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 +msg block (BSN 1, CS-1): 07 00 02 4d 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 MSG = 07 00 02 4d 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN) downlink (V(A)==0 .. V(S)==2) - Sending new block at BSN 2, CS=CS-1 @@ -1363,9 +1392,10 @@ TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN) downlink (V(A)==0 .. V(S)==2) Complete DL frame for TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN)len=19 -- Final block, so we done. TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN) changes state from ASSIGN to FINISHED -data block: 07 01 04 4d 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 +data block (BSN 2, CS-1): 4d 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling cannot be sheduled in this TS 7, waiting for TS 4 +msg block (BSN 2, CS-1): 07 01 04 4d 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 MSG = 07 01 04 4d 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 Searching for first unallocated TFI: TRX=0 Found TFI=0. @@ -1636,17 +1666,19 @@ TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==0) Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=10 -- Final block, so we done. TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) changes state from FLOW to FINISHED -data block: 07 01 00 29 52 41 55 5f 41 43 43 45 50 54 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 00 +data block (BSN 0, CS-4): 29 52 41 55 5f 41 43 43 45 50 54 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling sheduled in this TS 7 TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FINISHED) starting timer 3191. TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FINISHED) Scheduled Ack/Nack polling on FN=2654292, TS=7 +msg block (BSN 0, CS-4): 0f 01 00 29 52 41 55 5f 41 43 43 45 50 54 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 00 Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654279 block=10 data=08 01 00 29 52 41 55 5f 41 43 43 45 50 54 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 00 Received RTS for PDCH: TRX=0 TS=7 FN=2654283 block_nr=11 scheduling USF=0 for required uplink resource of UL TFI=0 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=7) prio=1 TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FINISHED) downlink (V(A)==0 .. V(S)==1) - Restarting at BSN 0, because all blocks have been transmitted. - Resending BSN 0 +msg block (BSN 0, CS-4): 07 01 00 29 52 41 55 5f 41 43 43 45 50 54 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 00 Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654283 block=11 data=00 01 00 29 52 41 55 5f 41 43 43 45 50 54 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 00 MS requests UL TBF on RACH, so we provide one: MS requests single block allocation @@ -2188,7 +2220,8 @@ TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==0) Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) -- Chunk with length 13 larger than space (6) left in block: copy only remaining space, and we are done -data block: 07 00 00 37 4c 4c 43 20 50 41 43 4b 45 54 20 30 30 4c 4c 43 20 50 41 +data block (BSN 0, CS-1): 37 4c 4c 43 20 50 41 43 4b 45 54 20 30 30 4c 4c 43 20 50 41 +msg block (BSN 0, CS-1): 07 00 00 37 4c 4c 43 20 50 41 43 4b 45 54 20 30 30 4c 4c 43 20 50 41 Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654279 block=10 data=00 00 00 37 4c 4c 43 20 50 41 43 4b 45 54 20 30 30 4c 4c 43 20 50 41 Received RTS on disabled PDCH: TRX=0 TS=0 Received RTS on disabled PDCH: TRX=0 TS=1 @@ -2205,7 +2238,8 @@ TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==1) Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) -- Chunk with length 13 larger than space (12) left in block: copy only remaining space, and we are done -data block: 07 00 02 1f 43 4b 45 54 20 30 31 4c 4c 43 20 50 41 43 4b 45 54 20 30 +data block (BSN 1, CS-1): 1f 43 4b 45 54 20 30 31 4c 4c 43 20 50 41 43 4b 45 54 20 30 +msg block (BSN 1, CS-1): 07 00 02 1f 43 4b 45 54 20 30 31 4c 4c 43 20 50 41 43 4b 45 54 20 30 Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654283 block=11 data=00 00 02 1f 43 4b 45 54 20 30 31 4c 4c 43 20 50 41 43 4b 45 54 20 30 Received RTS on disabled PDCH: TRX=0 TS=0 Received RTS on disabled PDCH: TRX=0 TS=1 @@ -2225,7 +2259,8 @@ Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) -- Chunk with length 13 larger than space (4) left in block: copy only remaining space, and we are done -data block: 07 00 04 06 37 32 4c 4c 43 20 50 41 43 4b 45 54 20 30 33 4c 4c 43 20 +data block (BSN 2, CS-1): 06 37 32 4c 4c 43 20 50 41 43 4b 45 54 20 30 33 4c 4c 43 20 +msg block (BSN 2, CS-1): 07 00 04 06 37 32 4c 4c 43 20 50 41 43 4b 45 54 20 30 33 4c 4c 43 20 Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654288 block=0 data=00 00 04 06 37 32 4c 4c 43 20 50 41 43 4b 45 54 20 30 33 4c 4c 43 20 Received RTS on disabled PDCH: TRX=0 TS=0 Received RTS on disabled PDCH: TRX=0 TS=1 @@ -2242,7 +2277,8 @@ TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==3) Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) -- Chunk with length 13 larger than space (10) left in block: copy only remaining space, and we are done -data block: 07 00 06 27 50 41 43 4b 45 54 20 30 34 4c 4c 43 20 50 41 43 4b 45 54 +data block (BSN 3, CS-1): 27 50 41 43 4b 45 54 20 30 34 4c 4c 43 20 50 41 43 4b 45 54 +msg block (BSN 3, CS-1): 07 00 06 27 50 41 43 4b 45 54 20 30 34 4c 4c 43 20 50 41 43 4b 45 54 Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654292 block=1 data=00 00 06 27 50 41 43 4b 45 54 20 30 34 4c 4c 43 20 50 41 43 4b 45 54 Received RTS on disabled PDCH: TRX=0 TS=0 Received RTS on disabled PDCH: TRX=0 TS=1 @@ -2262,7 +2298,8 @@ Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) -- Chunk with length 13 larger than space (2) left in block: copy only remaining space, and we are done -data block: 07 00 08 0e 37 20 30 35 4c 4c 43 20 50 41 43 4b 45 54 20 30 36 4c 4c +data block (BSN 4, CS-1): 0e 37 20 30 35 4c 4c 43 20 50 41 43 4b 45 54 20 30 36 4c 4c +msg block (BSN 4, CS-1): 07 00 08 0e 37 20 30 35 4c 4c 43 20 50 41 43 4b 45 54 20 30 36 4c 4c Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654296 block=2 data=00 00 08 0e 37 20 30 35 4c 4c 43 20 50 41 43 4b 45 54 20 30 36 4c 4c Received RTS on disabled PDCH: TRX=0 TS=0 Received RTS on disabled PDCH: TRX=0 TS=1 @@ -2279,7 +2316,8 @@ TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==5) Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) -- Chunk with length 13 larger than space (8) left in block: copy only remaining space, and we are done -data block: 07 00 0a 2f 43 20 50 41 43 4b 45 54 20 30 37 4c 4c 43 20 50 41 43 4b +data block (BSN 5, CS-1): 2f 43 20 50 41 43 4b 45 54 20 30 37 4c 4c 43 20 50 41 43 4b +msg block (BSN 5, CS-1): 07 00 0a 2f 43 20 50 41 43 4b 45 54 20 30 37 4c 4c 43 20 50 41 43 4b Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654301 block=3 data=00 00 0a 2f 43 20 50 41 43 4b 45 54 20 30 37 4c 4c 43 20 50 41 43 4b Received RTS on disabled PDCH: TRX=0 TS=0 Received RTS on disabled PDCH: TRX=0 TS=1 @@ -2299,7 +2337,8 @@ Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) -- No space left, so we are done. -data block: 07 00 0c 16 35 45 54 20 30 38 4c 4c 43 20 50 41 43 4b 45 54 20 30 39 +data block (BSN 6, CS-1): 16 35 45 54 20 30 38 4c 4c 43 20 50 41 43 4b 45 54 20 30 39 +msg block (BSN 6, CS-1): 07 00 0c 16 35 45 54 20 30 38 4c 4c 43 20 50 41 43 4b 45 54 20 30 39 Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654305 block=4 data=00 00 0c 16 35 45 54 20 30 38 4c 4c 43 20 50 41 43 4b 45 54 20 30 39 Received RTS on disabled PDCH: TRX=0 TS=0 Received RTS on disabled PDCH: TRX=0 TS=1 @@ -2316,7 +2355,8 @@ TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==7) Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) -- Chunk with length 13 larger than space (6) left in block: copy only remaining space, and we are done -data block: 07 00 0e 37 4c 4c 43 20 50 41 43 4b 45 54 20 31 30 4c 4c 43 20 50 41 +data block (BSN 7, CS-1): 37 4c 4c 43 20 50 41 43 4b 45 54 20 31 30 4c 4c 43 20 50 41 +msg block (BSN 7, CS-1): 07 00 0e 37 4c 4c 43 20 50 41 43 4b 45 54 20 31 30 4c 4c 43 20 50 41 Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654309 block=5 data=00 00 0e 37 4c 4c 43 20 50 41 43 4b 45 54 20 31 30 4c 4c 43 20 50 41 Received RTS on disabled PDCH: TRX=0 TS=0 Received RTS on disabled PDCH: TRX=0 TS=1 @@ -2333,7 +2373,8 @@ TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==8) Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) -- Chunk with length 13 larger than space (12) left in block: copy only remaining space, and we are done -data block: 07 00 10 1f 43 4b 45 54 20 31 31 4c 4c 43 20 50 41 43 4b 45 54 20 31 +data block (BSN 8, CS-1): 1f 43 4b 45 54 20 31 31 4c 4c 43 20 50 41 43 4b 45 54 20 31 +msg block (BSN 8, CS-1): 07 00 10 1f 43 4b 45 54 20 31 31 4c 4c 43 20 50 41 43 4b 45 54 20 31 Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654314 block=6 data=00 00 10 1f 43 4b 45 54 20 31 31 4c 4c 43 20 50 41 43 4b 45 54 20 31 Received RTS on disabled PDCH: TRX=0 TS=0 Received RTS on disabled PDCH: TRX=0 TS=1 @@ -2353,7 +2394,8 @@ Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) -- Chunk with length 13 larger than space (4) left in block: copy only remaining space, and we are done -data block: 07 00 12 06 37 32 4c 4c 43 20 50 41 43 4b 45 54 20 31 33 4c 4c 43 20 +data block (BSN 9, CS-1): 06 37 32 4c 4c 43 20 50 41 43 4b 45 54 20 31 33 4c 4c 43 20 +msg block (BSN 9, CS-1): 07 00 12 06 37 32 4c 4c 43 20 50 41 43 4b 45 54 20 31 33 4c 4c 43 20 Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654318 block=7 data=00 00 12 06 37 32 4c 4c 43 20 50 41 43 4b 45 54 20 31 33 4c 4c 43 20 Received RTS on disabled PDCH: TRX=0 TS=0 Received RTS on disabled PDCH: TRX=0 TS=1 @@ -2370,7 +2412,8 @@ TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==10) Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) -- Chunk with length 13 larger than space (10) left in block: copy only remaining space, and we are done -data block: 07 00 14 27 50 41 43 4b 45 54 20 31 34 4c 4c 43 20 50 41 43 4b 45 54 +data block (BSN 10, CS-1): 27 50 41 43 4b 45 54 20 31 34 4c 4c 43 20 50 41 43 4b 45 54 +msg block (BSN 10, CS-1): 07 00 14 27 50 41 43 4b 45 54 20 31 34 4c 4c 43 20 50 41 43 4b 45 54 Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654322 block=8 data=00 00 14 27 50 41 43 4b 45 54 20 31 34 4c 4c 43 20 50 41 43 4b 45 54 Received RTS on disabled PDCH: TRX=0 TS=0 Received RTS on disabled PDCH: TRX=0 TS=1 @@ -2390,7 +2433,8 @@ Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) -- Chunk with length 13 larger than space (2) left in block: copy only remaining space, and we are done -data block: 07 00 16 0e 37 20 31 35 4c 4c 43 20 50 41 43 4b 45 54 20 31 36 4c 4c +data block (BSN 11, CS-1): 0e 37 20 31 35 4c 4c 43 20 50 41 43 4b 45 54 20 31 36 4c 4c +msg block (BSN 11, CS-1): 07 00 16 0e 37 20 31 35 4c 4c 43 20 50 41 43 4b 45 54 20 31 36 4c 4c Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654327 block=9 data=00 00 16 0e 37 20 31 35 4c 4c 43 20 50 41 43 4b 45 54 20 31 36 4c 4c Received RTS on disabled PDCH: TRX=0 TS=0 Received RTS on disabled PDCH: TRX=0 TS=1 @@ -2407,7 +2451,8 @@ TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==12) Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) -- Chunk with length 13 larger than space (8) left in block: copy only remaining space, and we are done -data block: 07 00 18 2f 43 20 50 41 43 4b 45 54 20 31 37 4c 4c 43 20 50 41 43 4b +data block (BSN 12, CS-1): 2f 43 20 50 41 43 4b 45 54 20 31 37 4c 4c 43 20 50 41 43 4b +msg block (BSN 12, CS-1): 07 00 18 2f 43 20 50 41 43 4b 45 54 20 31 37 4c 4c 43 20 50 41 43 4b Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654331 block=10 data=00 00 18 2f 43 20 50 41 43 4b 45 54 20 31 37 4c 4c 43 20 50 41 43 4b Received RTS on disabled PDCH: TRX=0 TS=0 Received RTS on disabled PDCH: TRX=0 TS=1 @@ -2427,7 +2472,8 @@ Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) -- No space left, so we are done. -data block: 07 00 1a 16 35 45 54 20 31 38 4c 4c 43 20 50 41 43 4b 45 54 20 31 39 +data block (BSN 13, CS-1): 16 35 45 54 20 31 38 4c 4c 43 20 50 41 43 4b 45 54 20 31 39 +msg block (BSN 13, CS-1): 07 00 1a 16 35 45 54 20 31 38 4c 4c 43 20 50 41 43 4b 45 54 20 31 39 Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654335 block=11 data=00 00 1a 16 35 45 54 20 31 38 4c 4c 43 20 50 41 43 4b 45 54 20 31 39 Received RTS on disabled PDCH: TRX=0 TS=0 Received RTS on disabled PDCH: TRX=0 TS=1 @@ -2444,7 +2490,8 @@ TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==14) Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) -- Chunk with length 13 larger than space (6) left in block: copy only remaining space, and we are done -data block: 07 00 1c 37 4c 4c 43 20 50 41 43 4b 45 54 20 32 30 4c 4c 43 20 50 41 +data block (BSN 14, CS-1): 37 4c 4c 43 20 50 41 43 4b 45 54 20 32 30 4c 4c 43 20 50 41 +msg block (BSN 14, CS-1): 07 00 1c 37 4c 4c 43 20 50 41 43 4b 45 54 20 32 30 4c 4c 43 20 50 41 Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654340 block=0 data=00 00 1c 37 4c 4c 43 20 50 41 43 4b 45 54 20 32 30 4c 4c 43 20 50 41 Received RTS on disabled PDCH: TRX=0 TS=0 Received RTS on disabled PDCH: TRX=0 TS=1 @@ -2461,7 +2508,8 @@ TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==15) Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) -- Chunk with length 13 larger than space (12) left in block: copy only remaining space, and we are done -data block: 07 00 1e 1f 43 4b 45 54 20 32 31 4c 4c 43 20 50 41 43 4b 45 54 20 32 +data block (BSN 15, CS-1): 1f 43 4b 45 54 20 32 31 4c 4c 43 20 50 41 43 4b 45 54 20 32 +msg block (BSN 15, CS-1): 07 00 1e 1f 43 4b 45 54 20 32 31 4c 4c 43 20 50 41 43 4b 45 54 20 32 Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654344 block=1 data=00 00 1e 1f 43 4b 45 54 20 32 31 4c 4c 43 20 50 41 43 4b 45 54 20 32 Received RTS on disabled PDCH: TRX=0 TS=0 Received RTS on disabled PDCH: TRX=0 TS=1 @@ -2481,7 +2529,8 @@ Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) -- Chunk with length 13 larger than space (4) left in block: copy only remaining space, and we are done -data block: 07 00 20 06 37 32 4c 4c 43 20 50 41 43 4b 45 54 20 32 33 4c 4c 43 20 +data block (BSN 16, CS-1): 06 37 32 4c 4c 43 20 50 41 43 4b 45 54 20 32 33 4c 4c 43 20 +msg block (BSN 16, CS-1): 07 00 20 06 37 32 4c 4c 43 20 50 41 43 4b 45 54 20 32 33 4c 4c 43 20 Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654348 block=2 data=00 00 20 06 37 32 4c 4c 43 20 50 41 43 4b 45 54 20 32 33 4c 4c 43 20 Received RTS on disabled PDCH: TRX=0 TS=0 Received RTS on disabled PDCH: TRX=0 TS=1 @@ -2498,7 +2547,8 @@ TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==17) Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) -- Chunk with length 13 larger than space (10) left in block: copy only remaining space, and we are done -data block: 07 00 22 27 50 41 43 4b 45 54 20 32 34 4c 4c 43 20 50 41 43 4b 45 54 +data block (BSN 17, CS-1): 27 50 41 43 4b 45 54 20 32 34 4c 4c 43 20 50 41 43 4b 45 54 +msg block (BSN 17, CS-1): 07 00 22 27 50 41 43 4b 45 54 20 32 34 4c 4c 43 20 50 41 43 4b 45 54 Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654353 block=3 data=00 00 22 27 50 41 43 4b 45 54 20 32 34 4c 4c 43 20 50 41 43 4b 45 54 Received RTS on disabled PDCH: TRX=0 TS=0 Received RTS on disabled PDCH: TRX=0 TS=1 @@ -2518,7 +2568,8 @@ Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) -- Chunk with length 13 larger than space (2) left in block: copy only remaining space, and we are done -data block: 07 00 24 0e 37 20 32 35 4c 4c 43 20 50 41 43 4b 45 54 20 32 36 4c 4c +data block (BSN 18, CS-1): 0e 37 20 32 35 4c 4c 43 20 50 41 43 4b 45 54 20 32 36 4c 4c +msg block (BSN 18, CS-1): 07 00 24 0e 37 20 32 35 4c 4c 43 20 50 41 43 4b 45 54 20 32 36 4c 4c Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654357 block=4 data=00 00 24 0e 37 20 32 35 4c 4c 43 20 50 41 43 4b 45 54 20 32 36 4c 4c Received RTS on disabled PDCH: TRX=0 TS=0 Received RTS on disabled PDCH: TRX=0 TS=1 @@ -2535,7 +2586,8 @@ TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==19) Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) -- Chunk with length 13 larger than space (8) left in block: copy only remaining space, and we are done -data block: 07 00 26 2f 43 20 50 41 43 4b 45 54 20 32 37 4c 4c 43 20 50 41 43 4b +data block (BSN 19, CS-1): 2f 43 20 50 41 43 4b 45 54 20 32 37 4c 4c 43 20 50 41 43 4b +msg block (BSN 19, CS-1): 07 00 26 2f 43 20 50 41 43 4b 45 54 20 32 37 4c 4c 43 20 50 41 43 4b Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654361 block=5 data=00 00 26 2f 43 20 50 41 43 4b 45 54 20 32 37 4c 4c 43 20 50 41 43 4b Received RTS on disabled PDCH: TRX=0 TS=0 Received RTS on disabled PDCH: TRX=0 TS=1 @@ -2555,10 +2607,11 @@ Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) -- No space left, so we are done. -data block: 07 00 28 16 35 45 54 20 32 38 4c 4c 43 20 50 41 43 4b 45 54 20 32 39 +data block (BSN 20, CS-1): 16 35 45 54 20 32 38 4c 4c 43 20 50 41 43 4b 45 54 20 32 39 - Scheduling Ack/Nack polling, because 20 blocks sent. Polling sheduled in this TS 7 TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) Scheduled Ack/Nack polling on FN=2654379, TS=7 +msg block (BSN 20, CS-1): 0f 00 28 16 35 45 54 20 32 38 4c 4c 43 20 50 41 43 4b 45 54 20 32 39 Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654366 block=6 data=08 00 28 16 35 45 54 20 32 38 4c 4c 43 20 50 41 43 4b 45 54 20 32 39 Received RTS on disabled PDCH: TRX=0 TS=0 Received RTS on disabled PDCH: TRX=0 TS=1 @@ -2575,7 +2628,8 @@ TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==21) Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) -- Chunk with length 13 larger than space (6) left in block: copy only remaining space, and we are done -data block: 07 00 2a 37 4c 4c 43 20 50 41 43 4b 45 54 20 33 30 4c 4c 43 20 50 41 +data block (BSN 21, CS-1): 37 4c 4c 43 20 50 41 43 4b 45 54 20 33 30 4c 4c 43 20 50 41 +msg block (BSN 21, CS-1): 07 00 2a 37 4c 4c 43 20 50 41 43 4b 45 54 20 33 30 4c 4c 43 20 50 41 Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654370 block=7 data=00 00 2a 37 4c 4c 43 20 50 41 43 4b 45 54 20 33 30 4c 4c 43 20 50 41 Received RTS on disabled PDCH: TRX=0 TS=0 Received RTS on disabled PDCH: TRX=0 TS=1 @@ -2592,7 +2646,8 @@ TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==22) Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) -- Chunk with length 13 larger than space (12) left in block: copy only remaining space, and we are done -data block: 07 00 2c 1f 43 4b 45 54 20 33 31 4c 4c 43 20 50 41 43 4b 45 54 20 33 +data block (BSN 22, CS-1): 1f 43 4b 45 54 20 33 31 4c 4c 43 20 50 41 43 4b 45 54 20 33 +msg block (BSN 22, CS-1): 07 00 2c 1f 43 4b 45 54 20 33 31 4c 4c 43 20 50 41 43 4b 45 54 20 33 Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654374 block=8 data=07 00 2c 1f 43 4b 45 54 20 33 31 4c 4c 43 20 50 41 43 4b 45 54 20 33 Received RTS on disabled PDCH: TRX=0 TS=0 Received RTS on disabled PDCH: TRX=0 TS=1 @@ -2612,7 +2667,8 @@ Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) -- Chunk with length 13 larger than space (4) left in block: copy only remaining space, and we are done -data block: 07 00 2e 06 37 32 4c 4c 43 20 50 41 43 4b 45 54 20 33 33 4c 4c 43 20 +data block (BSN 23, CS-1): 06 37 32 4c 4c 43 20 50 41 43 4b 45 54 20 33 33 4c 4c 43 20 +msg block (BSN 23, CS-1): 07 00 2e 06 37 32 4c 4c 43 20 50 41 43 4b 45 54 20 33 33 4c 4c 43 20 Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654379 block=9 data=00 00 2e 06 37 32 4c 4c 43 20 50 41 43 4b 45 54 20 33 33 4c 4c 43 20 Received RTS on disabled PDCH: TRX=0 TS=0 Received RTS on disabled PDCH: TRX=0 TS=1 @@ -2629,7 +2685,8 @@ TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==24) Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) -- Chunk with length 13 larger than space (10) left in block: copy only remaining space, and we are done -data block: 07 00 30 27 50 41 43 4b 45 54 20 33 34 4c 4c 43 20 50 41 43 4b 45 54 +data block (BSN 24, CS-1): 27 50 41 43 4b 45 54 20 33 34 4c 4c 43 20 50 41 43 4b 45 54 +msg block (BSN 24, CS-1): 07 00 30 27 50 41 43 4b 45 54 20 33 34 4c 4c 43 20 50 41 43 4b 45 54 Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654383 block=10 data=00 00 30 27 50 41 43 4b 45 54 20 33 34 4c 4c 43 20 50 41 43 4b 45 54 Received RTS on disabled PDCH: TRX=0 TS=0 Received RTS on disabled PDCH: TRX=0 TS=1 @@ -2649,7 +2706,8 @@ Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) -- Chunk with length 13 larger than space (2) left in block: copy only remaining space, and we are done -data block: 07 00 32 0e 37 20 33 35 4c 4c 43 20 50 41 43 4b 45 54 20 33 36 4c 4c +data block (BSN 25, CS-1): 0e 37 20 33 35 4c 4c 43 20 50 41 43 4b 45 54 20 33 36 4c 4c +msg block (BSN 25, CS-1): 07 00 32 0e 37 20 33 35 4c 4c 43 20 50 41 43 4b 45 54 20 33 36 4c 4c Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654387 block=11 data=00 00 32 0e 37 20 33 35 4c 4c 43 20 50 41 43 4b 45 54 20 33 36 4c 4c Received RTS on disabled PDCH: TRX=0 TS=0 Received RTS on disabled PDCH: TRX=0 TS=1 @@ -2666,7 +2724,8 @@ TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==26) Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) -- Chunk with length 13 larger than space (8) left in block: copy only remaining space, and we are done -data block: 07 00 34 2f 43 20 50 41 43 4b 45 54 20 33 37 4c 4c 43 20 50 41 43 4b +data block (BSN 26, CS-1): 2f 43 20 50 41 43 4b 45 54 20 33 37 4c 4c 43 20 50 41 43 4b +msg block (BSN 26, CS-1): 07 00 34 2f 43 20 50 41 43 4b 45 54 20 33 37 4c 4c 43 20 50 41 43 4b Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654392 block=0 data=00 00 34 2f 43 20 50 41 43 4b 45 54 20 33 37 4c 4c 43 20 50 41 43 4b Received RTS on disabled PDCH: TRX=0 TS=0 Received RTS on disabled PDCH: TRX=0 TS=1 @@ -2686,9 +2745,10 @@ Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 -- Final block, so we done. TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) changes state from FLOW to FINISHED -data block: 07 01 36 16 35 45 54 20 33 38 4c 4c 43 20 50 41 43 4b 45 54 20 33 39 +data block (BSN 27, CS-1): 16 35 45 54 20 33 38 4c 4c 43 20 50 41 43 4b 45 54 20 33 39 - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already sheduled for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FINISHED), so we must wait for requesting downlink ack +msg block (BSN 27, CS-1): 07 01 36 16 35 45 54 20 33 38 4c 4c 43 20 50 41 43 4b 45 54 20 33 39 Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654396 block=1 data=00 01 36 16 35 45 54 20 33 38 4c 4c 43 20 50 41 43 4b 45 54 20 33 39 TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FINISHED) append TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FINISHED) append @@ -2760,7 +2820,8 @@ TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==0) - Dequeue next LLC for TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=21) - Sending new block at BSN 0, CS=CS-1 -- Chunk with length 21 larger than space (20) left in block: copy only remaining space, and we are done -data block: 07 02 01 4c 4c 43 20 50 41 43 4b 45 54 20 30 30 20 28 54 42 46 20 32 +data block (BSN 0, CS-1): 4c 4c 43 20 50 41 43 4b 45 54 20 30 30 20 28 54 42 46 20 32 +msg block (BSN 0, CS-1): 07 02 01 4c 4c 43 20 50 41 43 4b 45 54 20 30 30 20 28 54 42 46 20 32 Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654405 block=3 data=00 02 01 4c 4c 43 20 50 41 43 4b 45 54 20 30 30 20 28 54 42 46 20 32 Received RTS on disabled PDCH: TRX=0 TS=0 Received RTS on disabled PDCH: TRX=0 TS=1 @@ -2777,7 +2838,8 @@ TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==1) Complete DL frame for TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=21 - Dequeue next LLC for TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=21) -- Chunk with length 21 larger than space (18) left in block: copy only remaining space, and we are done -data block: 07 02 02 07 29 4c 4c 43 20 50 41 43 4b 45 54 20 30 31 20 28 54 42 46 +data block (BSN 1, CS-1): 07 29 4c 4c 43 20 50 41 43 4b 45 54 20 30 31 20 28 54 42 46 +msg block (BSN 1, CS-1): 07 02 02 07 29 4c 4c 43 20 50 41 43 4b 45 54 20 30 31 20 28 54 42 46 Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654409 block=4 data=00 02 02 07 29 4c 4c 43 20 50 41 43 4b 45 54 20 30 31 20 28 54 42 46 Received RTS on disabled PDCH: TRX=0 TS=0 Received RTS on disabled PDCH: TRX=0 TS=1 @@ -2794,7 +2856,8 @@ TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==2) Complete DL frame for TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=21 - Dequeue next LLC for TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=21) -- Chunk with length 21 larger than space (16) left in block: copy only remaining space, and we are done -data block: 07 02 04 0f 20 32 29 4c 4c 43 20 50 41 43 4b 45 54 20 30 32 20 28 54 +data block (BSN 2, CS-1): 0f 20 32 29 4c 4c 43 20 50 41 43 4b 45 54 20 30 32 20 28 54 +msg block (BSN 2, CS-1): 07 02 04 0f 20 32 29 4c 4c 43 20 50 41 43 4b 45 54 20 30 32 20 28 54 Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654413 block=5 data=00 02 04 0f 20 32 29 4c 4c 43 20 50 41 43 4b 45 54 20 30 32 20 28 54 Received RTS on disabled PDCH: TRX=0 TS=0 Received RTS on disabled PDCH: TRX=0 TS=1 @@ -2811,7 +2874,8 @@ TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==3) Complete DL frame for TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=21 - Dequeue next LLC for TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=21) -- Chunk with length 21 larger than space (14) left in block: copy only remaining space, and we are done -data block: 07 02 06 17 42 46 20 32 29 4c 4c 43 20 50 41 43 4b 45 54 20 30 33 20 +data block (BSN 3, CS-1): 17 42 46 20 32 29 4c 4c 43 20 50 41 43 4b 45 54 20 30 33 20 +msg block (BSN 3, CS-1): 07 02 06 17 42 46 20 32 29 4c 4c 43 20 50 41 43 4b 45 54 20 30 33 20 Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654418 block=6 data=00 02 06 17 42 46 20 32 29 4c 4c 43 20 50 41 43 4b 45 54 20 30 33 20 Received RTS on disabled PDCH: TRX=0 TS=0 Received RTS on disabled PDCH: TRX=0 TS=1 @@ -2828,7 +2892,8 @@ TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==4) Complete DL frame for TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=21 - Dequeue next LLC for TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=21) -- Chunk with length 21 larger than space (12) left in block: copy only remaining space, and we are done -data block: 07 02 08 1f 28 54 42 46 20 32 29 4c 4c 43 20 50 41 43 4b 45 54 20 30 +data block (BSN 4, CS-1): 1f 28 54 42 46 20 32 29 4c 4c 43 20 50 41 43 4b 45 54 20 30 +msg block (BSN 4, CS-1): 07 02 08 1f 28 54 42 46 20 32 29 4c 4c 43 20 50 41 43 4b 45 54 20 30 Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654422 block=7 data=00 02 08 1f 28 54 42 46 20 32 29 4c 4c 43 20 50 41 43 4b 45 54 20 30 Received RTS on disabled PDCH: TRX=0 TS=0 Received RTS on disabled PDCH: TRX=0 TS=1 @@ -2845,7 +2910,8 @@ TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==5) Complete DL frame for TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=21 - Dequeue next LLC for TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=21) -- Chunk with length 21 larger than space (10) left in block: copy only remaining space, and we are done -data block: 07 02 0a 27 34 20 28 54 42 46 20 32 29 4c 4c 43 20 50 41 43 4b 45 54 +data block (BSN 5, CS-1): 27 34 20 28 54 42 46 20 32 29 4c 4c 43 20 50 41 43 4b 45 54 +msg block (BSN 5, CS-1): 07 02 0a 27 34 20 28 54 42 46 20 32 29 4c 4c 43 20 50 41 43 4b 45 54 Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654426 block=8 data=00 02 0a 27 34 20 28 54 42 46 20 32 29 4c 4c 43 20 50 41 43 4b 45 54 Received RTS on disabled PDCH: TRX=0 TS=0 Received RTS on disabled PDCH: TRX=0 TS=1 @@ -2862,7 +2928,8 @@ TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==6) Complete DL frame for TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=21 - Dequeue next LLC for TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=21) -- Chunk with length 21 larger than space (8) left in block: copy only remaining space, and we are done -data block: 07 02 0c 2f 20 30 35 20 28 54 42 46 20 32 29 4c 4c 43 20 50 41 43 4b +data block (BSN 6, CS-1): 2f 20 30 35 20 28 54 42 46 20 32 29 4c 4c 43 20 50 41 43 4b +msg block (BSN 6, CS-1): 07 02 0c 2f 20 30 35 20 28 54 42 46 20 32 29 4c 4c 43 20 50 41 43 4b Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654431 block=9 data=00 02 0c 2f 20 30 35 20 28 54 42 46 20 32 29 4c 4c 43 20 50 41 43 4b Received RTS on disabled PDCH: TRX=0 TS=0 Received RTS on disabled PDCH: TRX=0 TS=1 @@ -2879,7 +2946,8 @@ TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==7) Complete DL frame for TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=21 - Dequeue next LLC for TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=21) -- Chunk with length 21 larger than space (6) left in block: copy only remaining space, and we are done -data block: 07 02 0e 37 45 54 20 30 36 20 28 54 42 46 20 32 29 4c 4c 43 20 50 41 +data block (BSN 7, CS-1): 37 45 54 20 30 36 20 28 54 42 46 20 32 29 4c 4c 43 20 50 41 +msg block (BSN 7, CS-1): 07 02 0e 37 45 54 20 30 36 20 28 54 42 46 20 32 29 4c 4c 43 20 50 41 Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654435 block=10 data=00 02 0e 37 45 54 20 30 36 20 28 54 42 46 20 32 29 4c 4c 43 20 50 41 Received RTS on disabled PDCH: TRX=0 TS=0 Received RTS on disabled PDCH: TRX=0 TS=1 @@ -2896,7 +2964,8 @@ TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==8) Complete DL frame for TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=21 - Dequeue next LLC for TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=21) -- Chunk with length 21 larger than space (4) left in block: copy only remaining space, and we are done -data block: 07 02 10 3f 43 4b 45 54 20 30 37 20 28 54 42 46 20 32 29 4c 4c 43 20 +data block (BSN 8, CS-1): 3f 43 4b 45 54 20 30 37 20 28 54 42 46 20 32 29 4c 4c 43 20 +msg block (BSN 8, CS-1): 07 02 10 3f 43 4b 45 54 20 30 37 20 28 54 42 46 20 32 29 4c 4c 43 20 Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654439 block=11 data=00 02 10 3f 43 4b 45 54 20 30 37 20 28 54 42 46 20 32 29 4c 4c 43 20 Received RTS on disabled PDCH: TRX=0 TS=0 Received RTS on disabled PDCH: TRX=0 TS=1 @@ -2913,7 +2982,8 @@ TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==9) Complete DL frame for TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=21 - Dequeue next LLC for TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=21) -- Chunk with length 21 larger than space (2) left in block: copy only remaining space, and we are done -data block: 07 02 12 47 50 41 43 4b 45 54 20 30 38 20 28 54 42 46 20 32 29 4c 4c +data block (BSN 9, CS-1): 47 50 41 43 4b 45 54 20 30 38 20 28 54 42 46 20 32 29 4c 4c +msg block (BSN 9, CS-1): 07 02 12 47 50 41 43 4b 45 54 20 30 38 20 28 54 42 46 20 32 29 4c 4c Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654444 block=0 data=00 02 12 47 50 41 43 4b 45 54 20 30 38 20 28 54 42 46 20 32 29 4c 4c Received RTS on disabled PDCH: TRX=0 TS=0 Received RTS on disabled PDCH: TRX=0 TS=1 @@ -2930,9 +3000,10 @@ TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==10) Complete DL frame for TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=21 -- Final block, so we done. TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW) changes state from FLOW to FINISHED -data block: 07 03 14 4d 43 20 50 41 43 4b 45 54 20 30 39 20 28 54 42 46 20 32 29 +data block (BSN 10, CS-1): 4d 43 20 50 41 43 4b 45 54 20 30 39 20 28 54 42 46 20 32 29 - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling sheduled in this TS 7 TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FINISHED) starting timer 3191. TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FINISHED) Scheduled Ack/Nack polling on FN=2654461, TS=7 +msg block (BSN 10, CS-1): 0f 03 14 4d 43 20 50 41 43 4b 45 54 20 30 39 20 28 54 42 46 20 32 29 Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654448 block=1 data=08 03 14 4d 43 20 50 41 43 4b 45 54 20 30 39 20 28 54 42 46 20 32 29 -- cgit v1.2.3 From 14bb0947b49e7f936f3ff0708e5891a873362d3b Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Tue, 12 Jan 2016 11:58:13 +0100 Subject: edge: Add Encoding::rlc_data_to_dl_append This function appends a single chunk to an RLC downlink data block. The implementation is basically taken from the gprs_rlcmac_dl_tbf::create_new_bsn method without the TBF related functionality and any side effects. Note that it still only supports GRPS. Sponsored-by: On-Waves ehf --- src/encoding.cpp | 121 +++++++++++++++++++++++ src/encoding.h | 14 +++ tests/edge/EdgeTest.cpp | 251 ++++++++++++++++++++++++++++++++++++++++++++++++ tests/edge/EdgeTest.ok | 2 + 4 files changed, 388 insertions(+) diff --git a/src/encoding.cpp b/src/encoding.cpp index 0756ffcb..eb424cb7 100644 --- a/src/encoding.cpp +++ b/src/encoding.cpp @@ -751,3 +751,124 @@ unsigned int Encoding::rlc_copy_from_aligned_buffer( return rdbi->data_len; } + +Encoding::AppendResult Encoding::rlc_data_to_dl_append( + struct gprs_rlc_data_block_info *rdbi, + gprs_llc *llc, int *offset, int *num_chunks, + uint8_t *data_block, + bool is_final) +{ + int chunk; + int space; + struct rlc_li_field *li; + uint8_t *delimiter, *data, *e_pointer; + + data = data_block + *offset; + delimiter = data_block + *num_chunks; + e_pointer = (*num_chunks ? delimiter - 1 : NULL); + + chunk = llc->chunk_size(); + space = rdbi->data_len - *offset; + + /* if chunk will exceed block limit */ + if (chunk > space) { + LOGP(DRLCMACDL, LOGL_DEBUG, "-- Chunk with length %d " + "larger than space (%d) left in block: copy " + "only remaining space, and we are done\n", + chunk, space); + /* block is filled, so there is no extension */ + if (e_pointer) + *e_pointer |= 0x01; + /* fill only space */ + llc->consume(data, space); + /* return data block as message */ + *offset = rdbi->data_len; + (*num_chunks)++; + return AR_NEED_MORE_BLOCKS; + } + /* if FINAL chunk would fit precisely in space left */ + if (chunk == space && is_final) + { + LOGP(DRLCMACDL, LOGL_DEBUG, "-- Chunk with length %d " + "would exactly fit into space (%d): because " + "this is a final block, we don't add length " + "header, and we are done\n", chunk, space); + /* block is filled, so there is no extension */ + if (e_pointer) + *e_pointer |= 0x01; + /* fill space */ + llc->consume(data, space); + *offset = rdbi->data_len; + (*num_chunks)++; + rdbi->cv = 0; + return AR_COMPLETED_BLOCK_FILLED; + } + /* if chunk would fit exactly in space left */ + if (chunk == space) { + LOGP(DRLCMACDL, LOGL_DEBUG, "-- Chunk with length %d " + "would exactly fit into space (%d): add length " + "header with LI=0, to make frame extend to " + "next block, and we are done\n", chunk, space); + /* make space for delimiter */ + if (delimiter != data) + memmove(delimiter + 1, delimiter, + data - delimiter); + data++; + (*offset)++; + space--; + /* add LI with 0 length */ + li = (struct rlc_li_field *)delimiter; + li->e = 1; /* not more extension */ + li->m = 0; /* shall be set to 0, in case of li = 0 */ + li->li = 0; /* chunk fills the complete space */ + rdbi->e = 0; /* 0: extensions present */ + // no need to set e_pointer nor increase delimiter + /* fill only space, which is 1 octet less than chunk */ + llc->consume(data, space); + /* return data block as message */ + *offset = rdbi->data_len; + (*num_chunks)++; + return AR_NEED_MORE_BLOCKS; + } + + LOGP(DRLCMACDL, LOGL_DEBUG, "-- Chunk with length %d is less " + "than remaining space (%d): add length header to " + "to delimit LLC frame\n", chunk, space); + /* the LLC frame chunk ends in this block */ + /* make space for delimiter */ + if (delimiter != data) + memmove(delimiter + 1, delimiter, data - delimiter); + data++; + (*offset)++; + space--; + /* add LI to delimit frame */ + li = (struct rlc_li_field *)delimiter; + li->e = 0; /* Extension bit, maybe set later */ + li->m = 0; /* will be set later, if there is more LLC data */ + li->li = chunk; /* length of chunk */ + rdbi->e = 0; /* 0: extensions present */ + (*num_chunks)++; + /* copy (rest of) LLC frame to space and reset later */ + llc->consume(data, chunk); + data += chunk; + space -= chunk; + (*offset) += chunk; + /* if we have more data and we have space left */ + if (space > 0 && !is_final) { + li->m = 1; /* we indicate more frames to follow */ + return AR_COMPLETED_SPACE_LEFT; + } + /* if we don't have more LLC frames */ + if (is_final) { + LOGP(DRLCMACDL, LOGL_DEBUG, "-- Final block, so we " + "done.\n"); + li->e = 1; /* we cannot extend */ + rdbi->cv = 0; + return AR_COMPLETED_BLOCK_FILLED; + } + /* we have no space left */ + LOGP(DRLCMACDL, LOGL_DEBUG, "-- No space left, so we are " + "done.\n"); + li->e = 1; /* we cannot extend */ + return AR_COMPLETED_BLOCK_FILLED; +} diff --git a/src/encoding.h b/src/encoding.h index 6764ce41..9b4b09ee 100644 --- a/src/encoding.h +++ b/src/encoding.h @@ -26,6 +26,8 @@ struct gprs_rlcmac_bts; struct gprs_rlcmac_tbf; struct bitvec; +struct gprs_llc; +struct gprs_rlc_data_block_info; /** * I help with encoding data into CSN1 messages. @@ -76,4 +78,16 @@ public: const struct gprs_rlc_data_info *rlc, unsigned int data_block_idx, uint8_t *dst, const uint8_t *buffer); + + enum AppendResult { + AR_NEED_MORE_BLOCKS, + AR_COMPLETED_SPACE_LEFT, + AR_COMPLETED_BLOCK_FILLED, + }; + + static AppendResult rlc_data_to_dl_append( + struct gprs_rlc_data_block_info *rdbi, + gprs_llc *llc, int *offset, int *num_chunks, + uint8_t *data, + bool is_final); }; diff --git a/tests/edge/EdgeTest.cpp b/tests/edge/EdgeTest.cpp index 11459457..70e99d53 100644 --- a/tests/edge/EdgeTest.cpp +++ b/tests/edge/EdgeTest.cpp @@ -25,6 +25,7 @@ #include "decoding.h" #include "encoding.h" #include "rlc.h" +#include "llc.h" extern "C" { #include "pcu_vty.h" @@ -483,6 +484,255 @@ static void test_rlc_unit_decoder() printf("=== end %s ===\n", __func__); } +static void test_rlc_unit_encoder() +{ + struct gprs_rlc_data_block_info rdbi = {0}; + GprsCodingScheme cs; + uint8_t data[74]; + uint8_t llc_data[1500] = {0,}; + int num_chunks = 0; + int write_offset; + struct gprs_llc llc; + Encoding::AppendResult ar; + + printf("=== start %s ===\n", __func__); + + llc.init(); + + /* TS 44.060, B.1 */ + cs = GprsCodingScheme::CS4; + gprs_rlc_data_block_info_init(&rdbi, cs); + num_chunks = 0; + write_offset = 0; + memset(data, 0, sizeof(data)); + + llc.reset(); + llc.put_frame(llc_data, 11); + + ar = Encoding::rlc_data_to_dl_append(&rdbi, + &llc, &write_offset, &num_chunks, data, false); + + OSMO_ASSERT(ar == Encoding::AR_COMPLETED_SPACE_LEFT); + OSMO_ASSERT(rdbi.e == 0); + OSMO_ASSERT(write_offset == 1 + 11); + OSMO_ASSERT(num_chunks == 1); + + llc.reset(); + llc.put_frame(llc_data, 26); + + ar = Encoding::rlc_data_to_dl_append(&rdbi, + &llc, &write_offset, &num_chunks, data, false); + + OSMO_ASSERT(ar == Encoding::AR_COMPLETED_SPACE_LEFT); + OSMO_ASSERT(rdbi.e == 0); + OSMO_ASSERT(write_offset == 2 + 11 + 26); + OSMO_ASSERT(num_chunks == 2); + + llc.reset(); + llc.put_frame(llc_data, 99); + + ar = Encoding::rlc_data_to_dl_append(&rdbi, + &llc, &write_offset, &num_chunks, data, false); + + OSMO_ASSERT(ar == Encoding::AR_NEED_MORE_BLOCKS); + OSMO_ASSERT(rdbi.e == 0); + OSMO_ASSERT(rdbi.cv != 0); + OSMO_ASSERT(write_offset == (int)rdbi.data_len); + OSMO_ASSERT(num_chunks == 3); + + OSMO_ASSERT(data[0] == ((11 << 2) | (1 << 1) | (0 << 0))); + OSMO_ASSERT(data[1] == ((26 << 2) | (1 << 1) | (1 << 0))); + OSMO_ASSERT(data[2] == 0); + + /* TS 44.060, B.2 */ + cs = GprsCodingScheme::CS1; + + /* Block 1 */ + gprs_rlc_data_block_info_init(&rdbi, cs); + num_chunks = 0; + write_offset = 0; + memset(data, 0, sizeof(data)); + + llc.reset(); + llc.put_frame(llc_data, 20); + + ar = Encoding::rlc_data_to_dl_append(&rdbi, + &llc, &write_offset, &num_chunks, data, false); + + OSMO_ASSERT(ar == Encoding::AR_NEED_MORE_BLOCKS); + OSMO_ASSERT(rdbi.e == 0); + OSMO_ASSERT(write_offset == 1 + 19); + OSMO_ASSERT(num_chunks == 1); + + OSMO_ASSERT(data[0] == ((0 << 2) | (0 << 1) | (1 << 0))); + OSMO_ASSERT(data[1] == 0); + + /* Block 2 */ + gprs_rlc_data_block_info_init(&rdbi, cs); + num_chunks = 0; + write_offset = 0; + memset(data, 0, sizeof(data)); + + OSMO_ASSERT(llc.chunk_size() == 1); + + ar = Encoding::rlc_data_to_dl_append(&rdbi, + &llc, &write_offset, &num_chunks, data, false); + + OSMO_ASSERT(ar == Encoding::AR_COMPLETED_SPACE_LEFT); + OSMO_ASSERT(rdbi.e == 0); + OSMO_ASSERT(write_offset == 1 + 1); + OSMO_ASSERT(num_chunks == 1); + + llc.reset(); + llc.put_frame(llc_data, 99); + + ar = Encoding::rlc_data_to_dl_append(&rdbi, + &llc, &write_offset, &num_chunks, data, false); + + OSMO_ASSERT(ar == Encoding::AR_NEED_MORE_BLOCKS); + OSMO_ASSERT(rdbi.e == 0); + OSMO_ASSERT(write_offset == 1 + 1 + 18); + OSMO_ASSERT(num_chunks == 2); + + OSMO_ASSERT(data[0] == ((1 << 2) | (1 << 1) | (1 << 0))); + OSMO_ASSERT(data[1] == 0); + + /* TS 44.060, B.3 */ + cs = GprsCodingScheme::CS1; + + /* Block 1 */ + gprs_rlc_data_block_info_init(&rdbi, cs); + num_chunks = 0; + write_offset = 0; + memset(data, 0, sizeof(data)); + + llc.reset(); + llc.put_frame(llc_data, 7); + + ar = Encoding::rlc_data_to_dl_append(&rdbi, + &llc, &write_offset, &num_chunks, data, false); + + OSMO_ASSERT(ar == Encoding::AR_COMPLETED_SPACE_LEFT); + OSMO_ASSERT(rdbi.e == 0); + OSMO_ASSERT(write_offset == 1 + 7); + OSMO_ASSERT(num_chunks == 1); + + llc.reset(); + llc.put_frame(llc_data, 11); + + ar = Encoding::rlc_data_to_dl_append(&rdbi, + &llc, &write_offset, &num_chunks, data, false); + + OSMO_ASSERT(ar == Encoding::AR_COMPLETED_BLOCK_FILLED); + OSMO_ASSERT(rdbi.e == 0); + OSMO_ASSERT(write_offset == 2 + 7 + 11); + OSMO_ASSERT(num_chunks == 2); + + OSMO_ASSERT(data[0] == ((7 << 2) | (1 << 1) | (0 << 0))); + OSMO_ASSERT(data[1] == ((11 << 2) | (0 << 1) | (1 << 0))); + OSMO_ASSERT(data[2] == 0); + + /* TS 44.060, B.4 */ + cs = GprsCodingScheme::CS1; + + /* Block 1 */ + gprs_rlc_data_block_info_init(&rdbi, cs); + num_chunks = 0; + write_offset = 0; + memset(data, 0, sizeof(data)); + + llc.reset(); + llc.put_frame(llc_data, 99); + + ar = Encoding::rlc_data_to_dl_append(&rdbi, + &llc, &write_offset, &num_chunks, data, false); + + OSMO_ASSERT(ar == Encoding::AR_NEED_MORE_BLOCKS); + OSMO_ASSERT(rdbi.e == 1); + OSMO_ASSERT(write_offset == 20); + OSMO_ASSERT(num_chunks == 1); + OSMO_ASSERT(rdbi.cv != 0); + + OSMO_ASSERT(data[0] == 0); + + /* TS 44.060, B.5 */ + cs = GprsCodingScheme::CS1; + + /* Block 1 */ + gprs_rlc_data_block_info_init(&rdbi, cs); + num_chunks = 0; + write_offset = 0; + memset(data, 0, sizeof(data)); + + llc.reset(); + llc.put_frame(llc_data, 20); + + ar = Encoding::rlc_data_to_dl_append(&rdbi, + &llc, &write_offset, &num_chunks, data, true); + + OSMO_ASSERT(ar == Encoding::AR_COMPLETED_BLOCK_FILLED); + OSMO_ASSERT(rdbi.e == 1); + OSMO_ASSERT(write_offset == 20); + OSMO_ASSERT(num_chunks == 1); + OSMO_ASSERT(rdbi.cv == 0); + + OSMO_ASSERT(data[0] == 0); + + /* TS 44.060, B.7 */ + cs = GprsCodingScheme::CS1; + + /* Block 1 */ + gprs_rlc_data_block_info_init(&rdbi, cs); + num_chunks = 0; + write_offset = 0; + memset(data, 0, sizeof(data)); + + llc.reset(); + llc.put_frame(llc_data, 30); + + ar = Encoding::rlc_data_to_dl_append(&rdbi, + &llc, &write_offset, &num_chunks, data, false); + + OSMO_ASSERT(ar == Encoding::AR_NEED_MORE_BLOCKS); + OSMO_ASSERT(rdbi.e == 1); + OSMO_ASSERT(write_offset == 20); + OSMO_ASSERT(num_chunks == 1); + + OSMO_ASSERT(data[0] == 0); + + /* Block 2 */ + gprs_rlc_data_block_info_init(&rdbi, cs); + num_chunks = 0; + write_offset = 0; + memset(data, 0, sizeof(data)); + + OSMO_ASSERT(llc.chunk_size() == 10); + + ar = Encoding::rlc_data_to_dl_append(&rdbi, + &llc, &write_offset, &num_chunks, data, false); + + OSMO_ASSERT(ar == Encoding::AR_COMPLETED_SPACE_LEFT); + OSMO_ASSERT(rdbi.e == 0); + OSMO_ASSERT(write_offset == 1 + 10); + OSMO_ASSERT(num_chunks == 1); + + llc.reset(); + llc.put_frame(llc_data, 99); + + ar = Encoding::rlc_data_to_dl_append(&rdbi, + &llc, &write_offset, &num_chunks, data, false); + + OSMO_ASSERT(ar == Encoding::AR_NEED_MORE_BLOCKS); + OSMO_ASSERT(rdbi.e == 0); + OSMO_ASSERT(write_offset == 1 + 10 + 9); + OSMO_ASSERT(num_chunks == 2); + + OSMO_ASSERT(data[0] == ((10 << 2) | (1 << 1) | (1 << 0))); + OSMO_ASSERT(data[1] == 0); + + printf("=== end %s ===\n", __func__); +} + static void test_rlc_unaligned_copy() { uint8_t bits[256]; @@ -614,6 +864,7 @@ int main(int argc, char **argv) test_rlc_info_init(); test_rlc_unit_decoder(); test_rlc_unaligned_copy(); + test_rlc_unit_encoder(); if (getenv("TALLOC_REPORT_FULL")) talloc_report_full(tall_pcu_ctx, stderr); diff --git a/tests/edge/EdgeTest.ok b/tests/edge/EdgeTest.ok index 95ec2b3a..9554df35 100644 --- a/tests/edge/EdgeTest.ok +++ b/tests/edge/EdgeTest.ok @@ -4,3 +4,5 @@ === end test_rlc_info_init === === start test_rlc_unit_decoder === === end test_rlc_unit_decoder === +=== start test_rlc_unit_encoder === +=== end test_rlc_unit_encoder === -- cgit v1.2.3 From fec94d1c5c57e328e27a9b0208706a0a54d3da56 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Tue, 12 Jan 2016 17:02:49 +0100 Subject: edge: Use rlc_data_to_dl_append in create_new_bsn Currently TBF related tasks (status changes, counter updates, LLC dummy command insertion) as well as RLC data block generation are done within create_new_bsn. The data block creation part has already been copied to the stateless Encoding::rlc_data_to_dl_append function. This commit changes create_new_bsn to use the encoder function and just care about the TBF related stuff. Since the rlc_data_to_dl_append function has been validated against the test cases being described in annex B of TS 44.060, this commit fixes an encoder bug which leads to broken LLC frames in a special case (see example B.2, the main header's E bit was erroneously set to 1 in that case). When this happens, the LLC frame will get discarded after reassembly, so that TCP will have to retransmit the lost packet. Sponsored-by: On-Waves ehf --- src/tbf_dl.cpp | 131 ++++++++------------------------------------------ tests/tbf/TbfTest.err | 28 +++++------ 2 files changed, 34 insertions(+), 125 deletions(-) diff --git a/src/tbf_dl.cpp b/src/tbf_dl.cpp index a1f8b60a..35c3ccb6 100644 --- a/src/tbf_dl.cpp +++ b/src/tbf_dl.cpp @@ -424,13 +424,14 @@ void gprs_rlcmac_dl_tbf::schedule_next_frame() struct msgb *gprs_rlcmac_dl_tbf::create_new_bsn(const uint32_t fn, const uint8_t ts) { - struct rlc_li_field *li; - uint8_t *delimiter, *data, *e_pointer; - uint16_t space, chunk; + uint8_t *data; gprs_rlc_data *rlc_data; const uint16_t bsn = m_window.v_s(); GprsCodingScheme cs = current_cs(); gprs_rlc_data_block_info *rdbi; + int num_chunks = 0; + int write_offset = 0; + Encoding::AppendResult ar; if (m_llc.frame_length() == 0) schedule_next_frame(); @@ -457,12 +458,11 @@ struct msgb *gprs_rlcmac_dl_tbf::create_new_bsn(const uint32_t fn, const uint8_t rdbi->bsn = bsn; /* Block Sequence Number */ rdbi->e = 1; /* Extension bit, maybe set later (1: no extension) */ - e_pointer = NULL; /* points to E of current chunk if it is stored in an - extension byte */ - delimiter = data; /* where next length header would be stored */ - space = block_data_len; - while (1) { + do { + bool is_final; + if (m_llc.frame_length() == 0) { + int space = block_data_len - write_offset; /* A header will need to by added, so we just need * space-1 octets */ m_llc.put_dummy_frame(space - 1); @@ -482,119 +482,28 @@ struct msgb *gprs_rlcmac_dl_tbf::create_new_bsn(const uint32_t fn, const uint8_t m_llc.frame_length(), frames_since_last_drain(fn)); } - chunk = m_llc.chunk_size(); - - /* if chunk will exceed block limit */ - if (chunk > space) { - LOGP(DRLCMACDL, LOGL_DEBUG, "-- Chunk with length %d " - "larger than space (%d) left in block: copy " - "only remaining space, and we are done\n", - chunk, space); - /* block is filled, so there is no extension */ - if (e_pointer) - *e_pointer |= 0x01; - /* fill only space */ - m_llc.consume(data, space); - /* return data block as message */ - break; - } - /* if FINAL chunk would fit precisely in space left */ - if (chunk == space && llc_queue()->size() == 0 && !keep_open(fn)) - { - LOGP(DRLCMACDL, LOGL_DEBUG, "-- Chunk with length %d " - "would exactly fit into space (%d): because " - "this is a final block, we don't add length " - "header, and we are done\n", chunk, space); - LOGP(DRLCMACDL, LOGL_INFO, "Complete DL frame for " - "%s that fits precisely in last block: " - "len=%d\n", tbf_name(this), m_llc.frame_length()); - gprs_rlcmac_dl_bw(this, m_llc.frame_length()); - /* block is filled, so there is no extension */ - if (e_pointer) - *e_pointer |= 0x01; - /* fill space */ - m_llc.consume(data, space); - m_llc.reset(); - /* final block */ - rdbi->cv = 0; /* we indicate final block */ - request_dl_ack(); - set_state(GPRS_RLCMAC_FINISHED); - /* return data block as message */ - break; - } - /* if chunk would fit exactly in space left */ - if (chunk == space) { - LOGP(DRLCMACDL, LOGL_DEBUG, "-- Chunk with length %d " - "would exactly fit into space (%d): add length " - "header with LI=0, to make frame extend to " - "next block, and we are done\n", chunk, space); - /* make space for delimiter */ - if (delimiter != data) - memmove(delimiter + 1, delimiter, - data - delimiter); - data++; - space--; - /* add LI with 0 length */ - li = (struct rlc_li_field *)delimiter; - li->e = 1; /* not more extension */ - li->m = 0; /* shall be set to 0, in case of li = 0 */ - li->li = 0; /* chunk fills the complete space */ - // no need to set e_pointer nor increase delimiter - /* fill only space, which is 1 octet less than chunk */ - m_llc.consume(data, space); - /* return data block as message */ + is_final = llc_queue()->size() == 0 && !keep_open(fn); + + ar = Encoding::rlc_data_to_dl_append(rdbi, + &m_llc, &write_offset, &num_chunks, data, is_final); + + if (ar == Encoding::AR_NEED_MORE_BLOCKS) break; - } - LOGP(DRLCMACDL, LOGL_DEBUG, "-- Chunk with length %d is less " - "than remaining space (%d): add length header to " - "to delimit LLC frame\n", chunk, space); - /* the LLC frame chunk ends in this block */ - /* make space for delimiter */ - if (delimiter != data) - memmove(delimiter + 1, delimiter, data - delimiter); - data++; - space--; - /* add LI to delimit frame */ - li = (struct rlc_li_field *)delimiter; - li->e = 0; /* Extension bit, maybe set later */ - li->m = 0; /* will be set later, if there is more LLC data */ - li->li = chunk; /* length of chunk */ - rdbi->e = 0; /* 0: extensions present */ - e_pointer = delimiter; /* points to E of current delimiter */ - delimiter++; - /* copy (rest of) LLC frame to space and reset later */ - m_llc.consume(data, chunk); - data += chunk; - space -= chunk; LOGP(DRLCMACDL, LOGL_INFO, "Complete DL frame for %s" "len=%d\n", tbf_name(this), m_llc.frame_length()); gprs_rlcmac_dl_bw(this, m_llc.frame_length()); m_llc.reset(); - /* dequeue next LLC frame, if any */ - schedule_next_frame(); - /* if we have more data and we have space left */ - if (space > 0 && (m_llc.frame_length() || keep_open(fn))) { - li->m = 1; /* we indicate more frames to follow */ - continue; - } - /* if we don't have more LLC frames */ - if (!m_llc.frame_length() && !keep_open(fn)) { - LOGP(DRLCMACDL, LOGL_DEBUG, "-- Final block, so we " - "done.\n"); - li->e = 1; /* we cannot extend */ - rdbi->cv = 0; /* we indicate final block */ + if (is_final) { request_dl_ack(); set_state(GPRS_RLCMAC_FINISHED); - break; } - /* we have no space left */ - LOGP(DRLCMACDL, LOGL_DEBUG, "-- No space left, so we are " - "done.\n"); - li->e = 1; /* we cannot extend */ - break; - } + + /* dequeue next LLC frame, if any */ + schedule_next_frame(); + } while (ar == Encoding::AR_COMPLETED_SPACE_LEFT); + LOGP(DRLCMACDL, LOGL_DEBUG, "data block (BSN %d, %s): %s\n", bsn, rlc_data->cs.name(), osmo_hexdump(rlc_data->block, block_data_len)); diff --git a/tests/tbf/TbfTest.err b/tests/tbf/TbfTest.err index 80aee605..ad0b69bb 100644 --- a/tests/tbf/TbfTest.err +++ b/tests/tbf/TbfTest.err @@ -294,8 +294,8 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==9) - Sending new block at BSN 9, CS=CS-1 -- Chunk with length 20 would exactly fit into space (20): add length header with LI=0, to make frame extend to next block, and we are done data block (BSN 9, CS-1): 01 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf c0 c1 c2 c3 c4 c5 c6 -msg block (BSN 9, CS-1): 07 00 13 01 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf c0 c1 c2 c3 c4 c5 c6 -Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=43 block=10 data=07 00 13 01 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf c0 c1 c2 c3 c4 c5 c6 +msg block (BSN 9, CS-1): 07 00 12 01 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf c0 c1 c2 c3 c4 c5 c6 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=43 block=10 data=07 00 12 01 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf c0 c1 c2 c3 c4 c5 c6 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==10) - Sending new block at BSN 10, CS=CS-1 @@ -376,8 +376,8 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==20) Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW)len=200 -- Empty chunk, added LLC dummy command of size 16, drained_since=0 -- Chunk with length 16 is less than remaining space (17): add length header to to delimit LLC frame -Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW)len=16 -- No space left, so we are done. +Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW)len=16 data block (BSN 20, CS-1): 0a 41 c6 c7 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already sheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW), so we must wait for requesting downlink ack @@ -413,8 +413,8 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==21 .. V(S)==21) - Sending new block at BSN 21, CS=CS-1 -- Empty chunk, added LLC dummy command of size 19, drained_since=4 -- Chunk with length 19 is less than remaining space (20): add length header to to delimit LLC frame -Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW)len=19 -- No space left, so we are done. +Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW)len=19 data block (BSN 21, CS-1): 4d 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already sheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW), so we must wait for requesting downlink ack @@ -430,8 +430,8 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==22 .. V(S)==22) - Sending new block at BSN 22, CS=CS-1 -- Empty chunk, added LLC dummy command of size 19, drained_since=112 -- Chunk with length 19 is less than remaining space (20): add length header to to delimit LLC frame -Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW)len=19 -- Final block, so we done. +Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW)len=19 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) changes state from FLOW to FINISHED data block (BSN 22, CS-1): 4d 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). @@ -1371,26 +1371,26 @@ TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN) downlink (V(A)==0 .. V(S)==0) - Dequeue next LLC for TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN) (len=19) - Sending new block at BSN 0, CS=CS-1 -- Chunk with length 19 is less than remaining space (20): add length header to to delimit LLC frame +-- No space left, so we are done. Complete DL frame for TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN)len=19 - Dequeue next LLC for TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN) (len=19) --- No space left, so we are done. data block (BSN 0, CS-1): 4d 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 msg block (BSN 0, CS-1): 07 00 00 4d 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 MSG = 07 00 00 4d 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN) downlink (V(A)==0 .. V(S)==1) - Sending new block at BSN 1, CS=CS-1 -- Chunk with length 19 is less than remaining space (20): add length header to to delimit LLC frame +-- No space left, so we are done. Complete DL frame for TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN)len=19 - Dequeue next LLC for TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN) (len=19) --- No space left, so we are done. data block (BSN 1, CS-1): 4d 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 msg block (BSN 1, CS-1): 07 00 02 4d 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 MSG = 07 00 02 4d 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN) downlink (V(A)==0 .. V(S)==2) - Sending new block at BSN 2, CS=CS-1 -- Chunk with length 19 is less than remaining space (20): add length header to to delimit LLC frame -Complete DL frame for TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN)len=19 -- Final block, so we done. +Complete DL frame for TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN)len=19 TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN) changes state from ASSIGN to FINISHED data block (BSN 2, CS-1): 4d 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). @@ -1663,8 +1663,8 @@ TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==0) - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=10) - Sending new block at BSN 0, CS=CS-4 -- Chunk with length 10 is less than remaining space (50): add length header to to delimit LLC frame -Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=10 -- Final block, so we done. +Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=10 TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) changes state from FLOW to FINISHED data block (BSN 0, CS-4): 29 52 41 55 5f 41 43 43 45 50 54 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). @@ -2334,9 +2334,9 @@ TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==6) Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) -- Chunk with length 13 is less than remaining space (14): add length header to to delimit LLC frame +-- No space left, so we are done. Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) --- No space left, so we are done. data block (BSN 6, CS-1): 16 35 45 54 20 30 38 4c 4c 43 20 50 41 43 4b 45 54 20 30 39 msg block (BSN 6, CS-1): 07 00 0c 16 35 45 54 20 30 38 4c 4c 43 20 50 41 43 4b 45 54 20 30 39 Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654305 block=4 data=00 00 0c 16 35 45 54 20 30 38 4c 4c 43 20 50 41 43 4b 45 54 20 30 39 @@ -2469,9 +2469,9 @@ TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==13) Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) -- Chunk with length 13 is less than remaining space (14): add length header to to delimit LLC frame +-- No space left, so we are done. Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) --- No space left, so we are done. data block (BSN 13, CS-1): 16 35 45 54 20 31 38 4c 4c 43 20 50 41 43 4b 45 54 20 31 39 msg block (BSN 13, CS-1): 07 00 1a 16 35 45 54 20 31 38 4c 4c 43 20 50 41 43 4b 45 54 20 31 39 Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654335 block=11 data=00 00 1a 16 35 45 54 20 31 38 4c 4c 43 20 50 41 43 4b 45 54 20 31 39 @@ -2604,9 +2604,9 @@ TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==20) Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) -- Chunk with length 13 is less than remaining space (14): add length header to to delimit LLC frame +-- No space left, so we are done. Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) --- No space left, so we are done. data block (BSN 20, CS-1): 16 35 45 54 20 32 38 4c 4c 43 20 50 41 43 4b 45 54 20 32 39 - Scheduling Ack/Nack polling, because 20 blocks sent. Polling sheduled in this TS 7 @@ -2742,8 +2742,8 @@ TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==27) Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) -- Chunk with length 13 is less than remaining space (14): add length header to to delimit LLC frame -Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 -- Final block, so we done. +Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) changes state from FLOW to FINISHED data block (BSN 27, CS-1): 16 35 45 54 20 33 38 4c 4c 43 20 50 41 43 4b 45 54 20 33 39 - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). @@ -2997,8 +2997,8 @@ Scheduling data message at RTS for DL TFI=1 (TRX=0, TS=7) prio=3 TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==10) - Sending new block at BSN 10, CS=CS-1 -- Chunk with length 19 is less than remaining space (20): add length header to to delimit LLC frame -Complete DL frame for TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=21 -- Final block, so we done. +Complete DL frame for TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=21 TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW) changes state from FLOW to FINISHED data block (BSN 10, CS-1): 4d 43 20 50 41 43 4b 45 54 20 30 39 20 28 54 42 46 20 32 29 - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). -- cgit v1.2.3 From 5058bd6e9e8335ca5cd8ad586de3843447c859bf Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Wed, 13 Jan 2016 10:51:25 +0100 Subject: edge: Select implementation by mode in rlc_data_to_dl_append Currently the GPRS data block encoding is applied to every coding scheme, even if an MCS is selected. This commit renames the actual encoding function to rlc_data_to_dl_append_gprs (not exported) and puts selection code into Encoding::rlc_data_to_dl_append. This requires an additional cs argument. Sponsored-by: On-Waves ehf --- src/encoding.cpp | 30 +++++++++++++++++++++++------- src/encoding.h | 3 ++- src/tbf_dl.cpp | 2 +- tests/edge/EdgeTest.cpp | 26 +++++++++++++------------- 4 files changed, 39 insertions(+), 22 deletions(-) diff --git a/src/encoding.cpp b/src/encoding.cpp index eb424cb7..4c0ecf98 100644 --- a/src/encoding.cpp +++ b/src/encoding.cpp @@ -752,7 +752,7 @@ unsigned int Encoding::rlc_copy_from_aligned_buffer( return rdbi->data_len; } -Encoding::AppendResult Encoding::rlc_data_to_dl_append( +static Encoding::AppendResult rlc_data_to_dl_append_gprs( struct gprs_rlc_data_block_info *rdbi, gprs_llc *llc, int *offset, int *num_chunks, uint8_t *data_block, @@ -784,7 +784,7 @@ Encoding::AppendResult Encoding::rlc_data_to_dl_append( /* return data block as message */ *offset = rdbi->data_len; (*num_chunks)++; - return AR_NEED_MORE_BLOCKS; + return Encoding::AR_NEED_MORE_BLOCKS; } /* if FINAL chunk would fit precisely in space left */ if (chunk == space && is_final) @@ -801,7 +801,7 @@ Encoding::AppendResult Encoding::rlc_data_to_dl_append( *offset = rdbi->data_len; (*num_chunks)++; rdbi->cv = 0; - return AR_COMPLETED_BLOCK_FILLED; + return Encoding::AR_COMPLETED_BLOCK_FILLED; } /* if chunk would fit exactly in space left */ if (chunk == space) { @@ -828,7 +828,7 @@ Encoding::AppendResult Encoding::rlc_data_to_dl_append( /* return data block as message */ *offset = rdbi->data_len; (*num_chunks)++; - return AR_NEED_MORE_BLOCKS; + return Encoding::AR_NEED_MORE_BLOCKS; } LOGP(DRLCMACDL, LOGL_DEBUG, "-- Chunk with length %d is less " @@ -856,7 +856,7 @@ Encoding::AppendResult Encoding::rlc_data_to_dl_append( /* if we have more data and we have space left */ if (space > 0 && !is_final) { li->m = 1; /* we indicate more frames to follow */ - return AR_COMPLETED_SPACE_LEFT; + return Encoding::AR_COMPLETED_SPACE_LEFT; } /* if we don't have more LLC frames */ if (is_final) { @@ -864,11 +864,27 @@ Encoding::AppendResult Encoding::rlc_data_to_dl_append( "done.\n"); li->e = 1; /* we cannot extend */ rdbi->cv = 0; - return AR_COMPLETED_BLOCK_FILLED; + return Encoding::AR_COMPLETED_BLOCK_FILLED; } /* we have no space left */ LOGP(DRLCMACDL, LOGL_DEBUG, "-- No space left, so we are " "done.\n"); li->e = 1; /* we cannot extend */ - return AR_COMPLETED_BLOCK_FILLED; + return Encoding::AR_COMPLETED_BLOCK_FILLED; +} + +Encoding::AppendResult Encoding::rlc_data_to_dl_append( + struct gprs_rlc_data_block_info *rdbi, GprsCodingScheme cs, + gprs_llc *llc, int *offset, int *num_chunks, + uint8_t *data_block, + bool is_final) +{ + if (cs.isGprs()) + return rlc_data_to_dl_append_gprs(rdbi, + llc, offset, num_chunks, data_block, is_final); + + LOGP(DRLCMACDL, LOGL_ERROR, "%s data block encoding not implemented\n", + cs.name()); + + return AR_NEED_MORE_BLOCKS; } diff --git a/src/encoding.h b/src/encoding.h index 9b4b09ee..4c357578 100644 --- a/src/encoding.h +++ b/src/encoding.h @@ -22,6 +22,7 @@ #include #include +#include struct gprs_rlcmac_bts; struct gprs_rlcmac_tbf; @@ -86,7 +87,7 @@ public: }; static AppendResult rlc_data_to_dl_append( - struct gprs_rlc_data_block_info *rdbi, + struct gprs_rlc_data_block_info *rdbi, GprsCodingScheme cs, gprs_llc *llc, int *offset, int *num_chunks, uint8_t *data, bool is_final); diff --git a/src/tbf_dl.cpp b/src/tbf_dl.cpp index 35c3ccb6..5607e9e3 100644 --- a/src/tbf_dl.cpp +++ b/src/tbf_dl.cpp @@ -484,7 +484,7 @@ struct msgb *gprs_rlcmac_dl_tbf::create_new_bsn(const uint32_t fn, const uint8_t is_final = llc_queue()->size() == 0 && !keep_open(fn); - ar = Encoding::rlc_data_to_dl_append(rdbi, + ar = Encoding::rlc_data_to_dl_append(rdbi, cs, &m_llc, &write_offset, &num_chunks, data, is_final); if (ar == Encoding::AR_NEED_MORE_BLOCKS) diff --git a/tests/edge/EdgeTest.cpp b/tests/edge/EdgeTest.cpp index 70e99d53..c405b4bc 100644 --- a/tests/edge/EdgeTest.cpp +++ b/tests/edge/EdgeTest.cpp @@ -509,7 +509,7 @@ static void test_rlc_unit_encoder() llc.reset(); llc.put_frame(llc_data, 11); - ar = Encoding::rlc_data_to_dl_append(&rdbi, + ar = Encoding::rlc_data_to_dl_append(&rdbi, cs, &llc, &write_offset, &num_chunks, data, false); OSMO_ASSERT(ar == Encoding::AR_COMPLETED_SPACE_LEFT); @@ -520,7 +520,7 @@ static void test_rlc_unit_encoder() llc.reset(); llc.put_frame(llc_data, 26); - ar = Encoding::rlc_data_to_dl_append(&rdbi, + ar = Encoding::rlc_data_to_dl_append(&rdbi, cs, &llc, &write_offset, &num_chunks, data, false); OSMO_ASSERT(ar == Encoding::AR_COMPLETED_SPACE_LEFT); @@ -531,7 +531,7 @@ static void test_rlc_unit_encoder() llc.reset(); llc.put_frame(llc_data, 99); - ar = Encoding::rlc_data_to_dl_append(&rdbi, + ar = Encoding::rlc_data_to_dl_append(&rdbi, cs, &llc, &write_offset, &num_chunks, data, false); OSMO_ASSERT(ar == Encoding::AR_NEED_MORE_BLOCKS); @@ -556,7 +556,7 @@ static void test_rlc_unit_encoder() llc.reset(); llc.put_frame(llc_data, 20); - ar = Encoding::rlc_data_to_dl_append(&rdbi, + ar = Encoding::rlc_data_to_dl_append(&rdbi, cs, &llc, &write_offset, &num_chunks, data, false); OSMO_ASSERT(ar == Encoding::AR_NEED_MORE_BLOCKS); @@ -575,7 +575,7 @@ static void test_rlc_unit_encoder() OSMO_ASSERT(llc.chunk_size() == 1); - ar = Encoding::rlc_data_to_dl_append(&rdbi, + ar = Encoding::rlc_data_to_dl_append(&rdbi, cs, &llc, &write_offset, &num_chunks, data, false); OSMO_ASSERT(ar == Encoding::AR_COMPLETED_SPACE_LEFT); @@ -586,7 +586,7 @@ static void test_rlc_unit_encoder() llc.reset(); llc.put_frame(llc_data, 99); - ar = Encoding::rlc_data_to_dl_append(&rdbi, + ar = Encoding::rlc_data_to_dl_append(&rdbi, cs, &llc, &write_offset, &num_chunks, data, false); OSMO_ASSERT(ar == Encoding::AR_NEED_MORE_BLOCKS); @@ -609,7 +609,7 @@ static void test_rlc_unit_encoder() llc.reset(); llc.put_frame(llc_data, 7); - ar = Encoding::rlc_data_to_dl_append(&rdbi, + ar = Encoding::rlc_data_to_dl_append(&rdbi, cs, &llc, &write_offset, &num_chunks, data, false); OSMO_ASSERT(ar == Encoding::AR_COMPLETED_SPACE_LEFT); @@ -620,7 +620,7 @@ static void test_rlc_unit_encoder() llc.reset(); llc.put_frame(llc_data, 11); - ar = Encoding::rlc_data_to_dl_append(&rdbi, + ar = Encoding::rlc_data_to_dl_append(&rdbi, cs, &llc, &write_offset, &num_chunks, data, false); OSMO_ASSERT(ar == Encoding::AR_COMPLETED_BLOCK_FILLED); @@ -644,7 +644,7 @@ static void test_rlc_unit_encoder() llc.reset(); llc.put_frame(llc_data, 99); - ar = Encoding::rlc_data_to_dl_append(&rdbi, + ar = Encoding::rlc_data_to_dl_append(&rdbi, cs, &llc, &write_offset, &num_chunks, data, false); OSMO_ASSERT(ar == Encoding::AR_NEED_MORE_BLOCKS); @@ -667,7 +667,7 @@ static void test_rlc_unit_encoder() llc.reset(); llc.put_frame(llc_data, 20); - ar = Encoding::rlc_data_to_dl_append(&rdbi, + ar = Encoding::rlc_data_to_dl_append(&rdbi, cs, &llc, &write_offset, &num_chunks, data, true); OSMO_ASSERT(ar == Encoding::AR_COMPLETED_BLOCK_FILLED); @@ -690,7 +690,7 @@ static void test_rlc_unit_encoder() llc.reset(); llc.put_frame(llc_data, 30); - ar = Encoding::rlc_data_to_dl_append(&rdbi, + ar = Encoding::rlc_data_to_dl_append(&rdbi, cs, &llc, &write_offset, &num_chunks, data, false); OSMO_ASSERT(ar == Encoding::AR_NEED_MORE_BLOCKS); @@ -708,7 +708,7 @@ static void test_rlc_unit_encoder() OSMO_ASSERT(llc.chunk_size() == 10); - ar = Encoding::rlc_data_to_dl_append(&rdbi, + ar = Encoding::rlc_data_to_dl_append(&rdbi, cs, &llc, &write_offset, &num_chunks, data, false); OSMO_ASSERT(ar == Encoding::AR_COMPLETED_SPACE_LEFT); @@ -719,7 +719,7 @@ static void test_rlc_unit_encoder() llc.reset(); llc.put_frame(llc_data, 99); - ar = Encoding::rlc_data_to_dl_append(&rdbi, + ar = Encoding::rlc_data_to_dl_append(&rdbi, cs, &llc, &write_offset, &num_chunks, data, false); OSMO_ASSERT(ar == Encoding::AR_NEED_MORE_BLOCKS); -- cgit v1.2.3 From a88d065606a29f5cd7d140fbacb49d78428ceb98 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Wed, 13 Jan 2016 11:28:10 +0100 Subject: edge: Support MCS data block encoding Currently only GPRS data block encoding is supported. This commit adds rlc_data_to_dl_append_egprs which does the EGPRS specific extension and chunk handling. It extends Encoding::rlc_data_to_dl_append to use that function for MCS coding schemes. Sponsored-by: On-Waves ehf --- src/encoding.cpp | 146 +++++++++++++++++++++++++++++ tests/edge/EdgeTest.cpp | 243 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 389 insertions(+) diff --git a/src/encoding.cpp b/src/encoding.cpp index 4c0ecf98..9def2831 100644 --- a/src/encoding.cpp +++ b/src/encoding.cpp @@ -873,6 +873,148 @@ static Encoding::AppendResult rlc_data_to_dl_append_gprs( return Encoding::AR_COMPLETED_BLOCK_FILLED; } +static Encoding::AppendResult rlc_data_to_dl_append_egprs( + struct gprs_rlc_data_block_info *rdbi, + gprs_llc *llc, int *offset, int *num_chunks, + uint8_t *data_block, + bool is_final) +{ + int chunk; + int space; + struct rlc_li_field_egprs *li; + struct rlc_li_field_egprs *prev_li; + uint8_t *delimiter, *data; + + data = data_block + *offset; + delimiter = data_block + *num_chunks; + prev_li = (struct rlc_li_field_egprs *) + (*num_chunks ? delimiter - 1 : NULL); + + chunk = llc->chunk_size(); + space = rdbi->data_len - *offset; + + /* if chunk will exceed block limit */ + if (chunk > space) { + LOGP(DRLCMACDL, LOGL_DEBUG, "-- Chunk with length %d " + "larger than space (%d) left in block: copy " + "only remaining space, and we are done\n", + chunk, space); + /* fill only space */ + llc->consume(data, space); + /* return data block as message */ + *offset = rdbi->data_len; + (*num_chunks)++; + return Encoding::AR_NEED_MORE_BLOCKS; + } + /* if FINAL chunk would fit precisely in space left */ + if (chunk == space && is_final) + { + LOGP(DRLCMACDL, LOGL_DEBUG, "-- Chunk with length %d " + "would exactly fit into space (%d): because " + "this is a final block, we don't add length " + "header, and we are done\n", chunk, space); + /* fill space */ + llc->consume(data, space); + *offset = rdbi->data_len; + (*num_chunks)++; + rdbi->cv = 0; + return Encoding::AR_COMPLETED_BLOCK_FILLED; + } + /* if chunk would fit exactly in space left */ + if (chunk == space) { + LOGP(DRLCMACDL, LOGL_DEBUG, "-- Chunk with length %d " + "would exactly fit into space (%d): just copy " + "it, and we are done. The next block will have " + "to start with an empty chunk\n", + chunk, space); + /* fill space */ + llc->consume(data, space); + *offset = rdbi->data_len; + (*num_chunks)++; + return Encoding::AR_NEED_MORE_BLOCKS; + } + + LOGP(DRLCMACDL, LOGL_DEBUG, "-- Chunk with length %d is less " + "than remaining space (%d): add length header to " + "to delimit LLC frame\n", chunk, space); + /* the LLC frame chunk ends in this block */ + /* make space for delimiter */ + + if (delimiter != data) + memmove(delimiter + 1, delimiter, data - delimiter); + + data += 1; + (*offset) += 1; + space -= 1; + /* add LI to delimit frame */ + li = (struct rlc_li_field_egprs *)delimiter; + li->e = 1; /* Extension bit, maybe set later */ + li->li = chunk; /* length of chunk */ + /* tell previous extension header about the new one */ + if (prev_li) + prev_li->e = 0; + rdbi->e = 0; /* 0: extensions present */ + delimiter++; + prev_li = li; + (*num_chunks)++; + /* copy (rest of) LLC frame to space and reset later */ + llc->consume(data, chunk); + data += chunk; + space -= chunk; + (*offset) += chunk; + /* if we have more data and we have space left */ + if (space > 0) { + if (!is_final) + return Encoding::AR_COMPLETED_SPACE_LEFT; + + /* we don't have more LLC frames */ + /* We will have to add another chunk with filling octets */ + LOGP(DRLCMACDL, LOGL_DEBUG, + "-- There is remaining space (%d): add filling byte chunk\n", + space); + + if (delimiter != data) + memmove(delimiter + 1, delimiter, data - delimiter); + + data += 1; + (*offset) += 1; + space -= 1; + + /* set filling bytes extension */ + li = (struct rlc_li_field_egprs *)delimiter; + li->e = 1; + li->li = 127; + + /* tell previous extension header about the new one */ + if (prev_li) + prev_li->e = 0; + + delimiter++; + (*num_chunks)++; + + rdbi->cv = 0; + + LOGP(DRLCMACDL, LOGL_DEBUG, "-- Final block, so we " + "are done.\n"); + + *offset = rdbi->data_len; + return Encoding::AR_COMPLETED_BLOCK_FILLED; + } + + if (is_final) { + /* we don't have more LLC frames */ + LOGP(DRLCMACDL, LOGL_DEBUG, "-- Final block, so we " + "are done.\n"); + rdbi->cv = 0; + return Encoding::AR_COMPLETED_BLOCK_FILLED; + } + + /* we have no space left */ + LOGP(DRLCMACDL, LOGL_DEBUG, "-- No space left, so we are " + "done.\n"); + return Encoding::AR_COMPLETED_BLOCK_FILLED; +} + Encoding::AppendResult Encoding::rlc_data_to_dl_append( struct gprs_rlc_data_block_info *rdbi, GprsCodingScheme cs, gprs_llc *llc, int *offset, int *num_chunks, @@ -883,6 +1025,10 @@ Encoding::AppendResult Encoding::rlc_data_to_dl_append( return rlc_data_to_dl_append_gprs(rdbi, llc, offset, num_chunks, data_block, is_final); + if (cs.isEgprs()) + return rlc_data_to_dl_append_egprs(rdbi, + llc, offset, num_chunks, data_block, is_final); + LOGP(DRLCMACDL, LOGL_ERROR, "%s data block encoding not implemented\n", cs.name()); diff --git a/tests/edge/EdgeTest.cpp b/tests/edge/EdgeTest.cpp index c405b4bc..704a7355 100644 --- a/tests/edge/EdgeTest.cpp +++ b/tests/edge/EdgeTest.cpp @@ -730,6 +730,249 @@ static void test_rlc_unit_encoder() OSMO_ASSERT(data[0] == ((10 << 2) | (1 << 1) | (1 << 0))); OSMO_ASSERT(data[1] == 0); + /* TS 44.060, B.8.1 */ + cs = GprsCodingScheme::MCS4; + + /* Block 1 */ + gprs_rlc_data_block_info_init(&rdbi, cs); + num_chunks = 0; + write_offset = 0; + memset(data, 0, sizeof(data)); + + llc.reset(); + llc.put_frame(llc_data, 11); + + ar = Encoding::rlc_data_to_dl_append(&rdbi, cs, + &llc, &write_offset, &num_chunks, data, false); + + OSMO_ASSERT(ar == Encoding::AR_COMPLETED_SPACE_LEFT); + OSMO_ASSERT(rdbi.e == 0); + OSMO_ASSERT(write_offset == 1 + 11); + OSMO_ASSERT(num_chunks == 1); + + llc.reset(); + llc.put_frame(llc_data, 26); + + ar = Encoding::rlc_data_to_dl_append(&rdbi, cs, + &llc, &write_offset, &num_chunks, data, false); + + OSMO_ASSERT(ar == Encoding::AR_COMPLETED_SPACE_LEFT); + OSMO_ASSERT(rdbi.e == 0); + OSMO_ASSERT(write_offset == 2 + 11 + 26); + OSMO_ASSERT(num_chunks == 2); + + llc.reset(); + llc.put_frame(llc_data, 99); + + ar = Encoding::rlc_data_to_dl_append(&rdbi, cs, + &llc, &write_offset, &num_chunks, data, false); + + OSMO_ASSERT(ar == Encoding::AR_NEED_MORE_BLOCKS); + OSMO_ASSERT(rdbi.e == 0); + OSMO_ASSERT(rdbi.cv != 0); + OSMO_ASSERT(write_offset == (int)rdbi.data_len); + OSMO_ASSERT(num_chunks == 3); + + OSMO_ASSERT(data[0] == ((11 << 1) | (0 << 0))); + OSMO_ASSERT(data[1] == ((26 << 1) | (1 << 0))); + OSMO_ASSERT(data[2] == 0); + + /* TS 44.060, B.8.2 */ + + /* Note that the spec confuses the byte numbering here, since it + * includes the FBI/E header bits into the N2 octet count which + * is not consistent with Section 10.3a.1 & 10.3a.2. */ + + cs = GprsCodingScheme::MCS2; + + /* Block 1 */ + gprs_rlc_data_block_info_init(&rdbi, cs); + num_chunks = 0; + write_offset = 0; + memset(data, 0, sizeof(data)); + + llc.reset(); + llc.put_frame(llc_data, 15); + + ar = Encoding::rlc_data_to_dl_append(&rdbi, cs, + &llc, &write_offset, &num_chunks, data, false); + + OSMO_ASSERT(ar == Encoding::AR_COMPLETED_SPACE_LEFT); + OSMO_ASSERT(rdbi.e == 0); + OSMO_ASSERT(write_offset == 1 + 15); + OSMO_ASSERT(num_chunks == 1); + + llc.reset(); + llc.put_frame(llc_data, 12); + + ar = Encoding::rlc_data_to_dl_append(&rdbi, cs, + &llc, &write_offset, &num_chunks, data, false); + + OSMO_ASSERT(ar == Encoding::AR_NEED_MORE_BLOCKS); + OSMO_ASSERT(rdbi.e == 0); + OSMO_ASSERT(rdbi.cv != 0); + OSMO_ASSERT(write_offset == (int)rdbi.data_len); + OSMO_ASSERT(num_chunks == 2); + + OSMO_ASSERT(data[0] == ((15 << 1) | (1 << 0))); + OSMO_ASSERT(data[1] == 0); + + /* Block 2 */ + gprs_rlc_data_block_info_init(&rdbi, cs); + num_chunks = 0; + write_offset = 0; + memset(data, 0, sizeof(data)); + + OSMO_ASSERT(llc.chunk_size() == 0); + + ar = Encoding::rlc_data_to_dl_append(&rdbi, cs, + &llc, &write_offset, &num_chunks, data, false); + + OSMO_ASSERT(ar == Encoding::AR_COMPLETED_SPACE_LEFT); + OSMO_ASSERT(rdbi.e == 0); + OSMO_ASSERT(write_offset == 1 + 0); + OSMO_ASSERT(num_chunks == 1); + + llc.reset(); + llc.put_frame(llc_data, 7); + + ar = Encoding::rlc_data_to_dl_append(&rdbi, cs, + &llc, &write_offset, &num_chunks, data, false); + + OSMO_ASSERT(ar == Encoding::AR_COMPLETED_SPACE_LEFT); + OSMO_ASSERT(rdbi.e == 0); + OSMO_ASSERT(rdbi.cv != 0); + OSMO_ASSERT(write_offset == 2 + 0 + 7); + OSMO_ASSERT(num_chunks == 2); + + llc.reset(); + llc.put_frame(llc_data, 18); + + ar = Encoding::rlc_data_to_dl_append(&rdbi, cs, + &llc, &write_offset, &num_chunks, data, false); + + OSMO_ASSERT(ar == Encoding::AR_COMPLETED_BLOCK_FILLED); + OSMO_ASSERT(rdbi.e == 0); + OSMO_ASSERT(rdbi.cv != 0); + OSMO_ASSERT(write_offset == (int)rdbi.data_len); + OSMO_ASSERT(num_chunks == 3); + + OSMO_ASSERT(data[0] == ((0 << 1) | (0 << 0))); + OSMO_ASSERT(data[1] == ((7 << 1) | (0 << 0))); + OSMO_ASSERT(data[2] == ((18 << 1) | (1 << 0))); + OSMO_ASSERT(data[3] == 0); + + /* Block 3 */ + gprs_rlc_data_block_info_init(&rdbi, cs); + num_chunks = 0; + write_offset = 0; + memset(data, 0, sizeof(data)); + + llc.reset(); + llc.put_frame(llc_data, 6); + + ar = Encoding::rlc_data_to_dl_append(&rdbi, cs, + &llc, &write_offset, &num_chunks, data, false); + + OSMO_ASSERT(ar == Encoding::AR_COMPLETED_SPACE_LEFT); + OSMO_ASSERT(rdbi.e == 0); + OSMO_ASSERT(write_offset == 1 + 6); + OSMO_ASSERT(num_chunks == 1); + + llc.reset(); + llc.put_frame(llc_data, 12); + + ar = Encoding::rlc_data_to_dl_append(&rdbi, cs, + &llc, &write_offset, &num_chunks, data, true); + + OSMO_ASSERT(ar == Encoding::AR_COMPLETED_BLOCK_FILLED); + OSMO_ASSERT(rdbi.e == 0); + OSMO_ASSERT(rdbi.cv == 0); + OSMO_ASSERT(write_offset == (int)rdbi.data_len); + OSMO_ASSERT(num_chunks == 3); + + OSMO_ASSERT(data[0] == ((6 << 1) | (0 << 0))); + OSMO_ASSERT(data[1] == ((12 << 1) | (0 << 0))); + OSMO_ASSERT(data[2] == ((127 << 1) | (1 << 0))); + OSMO_ASSERT(data[3] == 0); + + /* TS 44.060, B.8.3 */ + + /* Note that the spec confuses the byte numbering here, too (see above) */ + + cs = GprsCodingScheme::MCS2; + + /* Block 1 */ + gprs_rlc_data_block_info_init(&rdbi, cs); + num_chunks = 0; + write_offset = 0; + memset(data, 0, sizeof(data)); + + llc.reset(); + llc.put_frame(llc_data, rdbi.data_len); + + ar = Encoding::rlc_data_to_dl_append(&rdbi, cs, + &llc, &write_offset, &num_chunks, data, true); + + OSMO_ASSERT(ar == Encoding::AR_COMPLETED_BLOCK_FILLED); + OSMO_ASSERT(rdbi.e == 1); + OSMO_ASSERT(rdbi.cv == 0); + OSMO_ASSERT(write_offset == (int)rdbi.data_len); + OSMO_ASSERT(num_chunks == 1); + + OSMO_ASSERT(data[0] == 0); + + /* Final block with an LLC of size data_len-1 */ + + cs = GprsCodingScheme::MCS2; + + /* Block 1 */ + gprs_rlc_data_block_info_init(&rdbi, cs); + num_chunks = 0; + write_offset = 0; + memset(data, 0, sizeof(data)); + + llc.reset(); + llc.put_frame(llc_data, rdbi.data_len - 1); + + ar = Encoding::rlc_data_to_dl_append(&rdbi, cs, + &llc, &write_offset, &num_chunks, data, true); + + OSMO_ASSERT(ar == Encoding::AR_COMPLETED_BLOCK_FILLED); + OSMO_ASSERT(rdbi.e == 0); + OSMO_ASSERT(rdbi.cv == 0); + OSMO_ASSERT(write_offset == (int)rdbi.data_len); + OSMO_ASSERT(num_chunks == 1); + + OSMO_ASSERT(data[0] == (((rdbi.data_len-1) << 1) | (1 << 0))); + OSMO_ASSERT(data[1] == 0); + + /* Final block with an LLC of size data_len-2 */ + + cs = GprsCodingScheme::MCS2; + + /* Block 1 */ + gprs_rlc_data_block_info_init(&rdbi, cs); + num_chunks = 0; + write_offset = 0; + memset(data, 0, sizeof(data)); + + llc.reset(); + llc.put_frame(llc_data, rdbi.data_len - 2); + + ar = Encoding::rlc_data_to_dl_append(&rdbi, cs, + &llc, &write_offset, &num_chunks, data, true); + + OSMO_ASSERT(ar == Encoding::AR_COMPLETED_BLOCK_FILLED); + OSMO_ASSERT(rdbi.e == 0); + OSMO_ASSERT(rdbi.cv == 0); + OSMO_ASSERT(write_offset == (int)rdbi.data_len); + OSMO_ASSERT(num_chunks == 2); + + OSMO_ASSERT(data[0] == (((rdbi.data_len-2) << 1) | (0 << 0))); + OSMO_ASSERT(data[1] == ((127 << 1) | (1 << 0))); + OSMO_ASSERT(data[2] == 0); + printf("=== end %s ===\n", __func__); } -- cgit v1.2.3 From 70955c765cbd7d58f8e9fec134becfd53ea395e1 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Wed, 13 Jan 2016 13:09:09 +0100 Subject: edge: Provide and use CS -> CPS conversion The MS' RLC receiver needs a valid CPS field to decode the block. Add the function gprs_rlc_mcs_cps to generate the CPS value based on coding scheme, puncturing, and padding. Sponsored-by: On-Waves ehf --- src/rlc.cpp | 15 +++++++++++++++ src/rlc.h | 1 + src/tbf_dl.cpp | 1 + 3 files changed, 17 insertions(+) diff --git a/src/rlc.cpp b/src/rlc.cpp index 44ce817b..1a8efdf6 100644 --- a/src/rlc.cpp +++ b/src/rlc.cpp @@ -311,3 +311,18 @@ void gprs_rlc_data_block_info_init(struct gprs_rlc_data_block_info *rdbi, rdbi->pi = 0; rdbi->spb = 0; } + +unsigned int gprs_rlc_mcs_cps(GprsCodingScheme cs, int punct, int with_padding) +{ + switch (GprsCodingScheme::Scheme(cs)) { + case GprsCodingScheme::MCS1: return 0b1011 + punct % 2; + case GprsCodingScheme::MCS2: return 0b1001 + punct % 2; + case GprsCodingScheme::MCS3: return (with_padding ? 0b0110 : 0b0011) + + punct % 3; + case GprsCodingScheme::MCS4: return 0b0000 + punct % 3; + /* TODO: Add missing MCS */ + default: ; + } + + return -1; +} diff --git a/src/rlc.h b/src/rlc.h index a11b4ce8..76af4e10 100644 --- a/src/rlc.h +++ b/src/rlc.h @@ -105,6 +105,7 @@ void gprs_rlc_data_info_init_ul(struct gprs_rlc_data_info *rlc, GprsCodingScheme cs); void gprs_rlc_data_block_info_init(struct gprs_rlc_data_block_info *rdbi, GprsCodingScheme cs); +unsigned int gprs_rlc_mcs_cps(GprsCodingScheme cs, int punct, int with_padding); /* * I hold the currently transferred blocks and will provide diff --git a/src/tbf_dl.cpp b/src/tbf_dl.cpp index 5607e9e3..e742c799 100644 --- a/src/tbf_dl.cpp +++ b/src/tbf_dl.cpp @@ -539,6 +539,7 @@ struct msgb *gprs_rlcmac_dl_tbf::create_dl_acked_block( rlc.usf = 7; /* will be set at scheduler */ rlc.pr = 0; /* FIXME: power reduction */ rlc.tfi = m_tfi; /* TFI */ + rlc.cps = gprs_rlc_mcs_cps(cs, 0, 0); rlc.block_info[data_block_idx] = m_rlc.block(index)->block_info; rdbi = &rlc.block_info[data_block_idx]; -- cgit v1.2.3 From c2141c6064ddf5283937c7f77468bf2396787804 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Wed, 13 Jan 2016 15:55:01 +0100 Subject: edge: Workaround to fix decoding of EGPRS_AckNack_w_len_t The presence of the LENGTH field adds an additional offset which breaks the related M_SERIALIZE in gsm_rlcmac.cpp. In that case, the Desc in EGPRS_AckNack_t is being cast to EGPRS_AckNack_w_len_t and then ((EGPRS_AckNack_w_len_t *)Desc)->Desc is filled with the parsed data, which is a platform dependant number of bytes apart the real Desc struct. Remove LENGTH field from EGPRS_AckNack_w_len_t so that the Desc field is the first field. Note that this is not a real fix. The rlcmac wireshark dissector still has the same declaration but doesn't seem to suffer from this problem. Sponsored-by: On-Waves ehf --- src/gsm_rlcmac.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gsm_rlcmac.h b/src/gsm_rlcmac.h index 017b3112..49c596dc 100644 --- a/src/gsm_rlcmac.h +++ b/src/gsm_rlcmac.h @@ -476,7 +476,7 @@ typedef struct typedef struct { - guint8 LENGTH; + /* guint8 LENGTH; */ EGPRS_AckNack_Desc_t Desc; } EGPRS_AckNack_w_len_t; -- cgit v1.2.3 From ae9c575d2c2e7f906c41d28682445e6c8cb53f03 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Wed, 13 Jan 2016 13:55:44 +0100 Subject: edge: Handle EGPRS PACKET DOWNLINK ACK NACK Currently this message is ignored. Support decoding and handling of this message. Use a bitvec for the decoder that just represents a BSN sequence without any encoding details (first bit -> first BSN). Return the corresponding BSN range (snsmod(bsn_begin + bits_in_bitvec) = bsn_end), so snsmod(bsn_end-1) is the last BSN if there is at least 1. If bsn_begin == bsn_end, no BSNs has been added. Note that this bitvec is not yet used for RBB handling. It just calls the old rcvd_dl_ack with a faked (all bits are 1) RBB map. Sponsored-by: On-Waves ehf --- src/bts.cpp | 120 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/bts.h | 1 + src/csn1.cpp | 1 + src/decoding.cpp | 91 +++++++++++++++++++++++++++++++++++++++++ src/decoding.h | 6 +++ 5 files changed, 219 insertions(+) diff --git a/src/bts.cpp b/src/bts.cpp index 18bee665..16961454 100644 --- a/src/bts.cpp +++ b/src/bts.cpp @@ -946,6 +946,123 @@ void gprs_rlcmac_pdch::rcv_control_dl_ack_nack(Packet_Downlink_Ack_Nack_t *ack_n } } +void gprs_rlcmac_pdch::rcv_control_egprs_dl_ack_nack(EGPRS_PD_AckNack_t *ack_nack, uint32_t fn) +{ + int8_t tfi = 0; /* must be signed */ + struct gprs_rlcmac_dl_tbf *tbf; + struct pcu_l1_meas meas; + int rc; + int num_blocks; + uint8_t bits_data[RLC_EGPRS_MAX_WS/8]; + char show_bits[RLC_EGPRS_MAX_WS + 1]; + bitvec bits; + int bsn_begin, bsn_end; + + tfi = ack_nack->DOWNLINK_TFI; + tbf = bts()->dl_tbf_by_poll_fn(fn, trx_no(), ts_no); + if (!tbf) { + LOGP(DRLCMAC, LOGL_NOTICE, "EGPRS PACKET DOWNLINK ACK with " + "unknown FN=%u TFI=%d (TRX %d TS %d)\n", + fn, tfi, trx_no(), ts_no); + return; + } + if (tbf->tfi() != tfi) { + LOGP(DRLCMAC, LOGL_NOTICE, "EGPRS PACKET DOWNLINK ACK with " + "wrong TFI=%d, ignoring!\n", tfi); + return; + } + tbf->state_flags |= (1 << GPRS_RLCMAC_FLAG_DL_ACK); + if ((tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_TO_DL_ACK))) { + tbf->state_flags &= ~(1 << GPRS_RLCMAC_FLAG_TO_DL_ACK); + LOGP(DRLCMAC, LOGL_NOTICE, "Recovered EGPRS downlink ack " + "for %s\n", tbf_name(tbf)); + } + /* reset N3105 */ + tbf->n3105 = 0; + tbf->stop_t3191(); + LOGP(DRLCMAC, LOGL_DEBUG, + "RX: [PCU <- BTS] %s EGPRS Packet Downlink Ack/Nack\n", + tbf_name(tbf)); + tbf->poll_state = GPRS_RLCMAC_POLL_NONE; + + LOGP(DRLCMAC, LOGL_DEBUG, "EGPRS ACK/NACK: " + "ut: %d, final: %d, bow: %d, eow: %d, ssn: %d, have_crbb: %d, " + "urbb_len:%d, %p, %p, %d, %d, win: %d-%d, urbb: %s\n", + (int)ack_nack->EGPRS_AckNack.UnionType, + (int)ack_nack->EGPRS_AckNack.Desc.FINAL_ACK_INDICATION, + (int)ack_nack->EGPRS_AckNack.Desc.BEGINNING_OF_WINDOW, + (int)ack_nack->EGPRS_AckNack.Desc.END_OF_WINDOW, + (int)ack_nack->EGPRS_AckNack.Desc.STARTING_SEQUENCE_NUMBER, + (int)ack_nack->EGPRS_AckNack.Desc.Exist_CRBB, + (int)ack_nack->EGPRS_AckNack.Desc.URBB_LENGTH, + (void *)&ack_nack->EGPRS_AckNack.UnionType, + (void *)&ack_nack->EGPRS_AckNack.Desc, + (int)offsetof(EGPRS_AckNack_t, Desc), + (int)offsetof(EGPRS_AckNack_w_len_t, Desc), + tbf->m_window.v_a(), + tbf->m_window.v_s(), + osmo_hexdump((const uint8_t *)&ack_nack->EGPRS_AckNack.Desc.URBB, + sizeof(ack_nack->EGPRS_AckNack.Desc.URBB))); + + bits.data = bits_data; + bits.data_len = sizeof(bits_data); + bits.cur_bit = 0; + + num_blocks = Decoding::decode_egprs_acknack_bits( + &ack_nack->EGPRS_AckNack.Desc, &bits, + &bsn_begin, &bsn_end, &tbf->m_window); + + for (int i = 0; i < num_blocks; i++) { + show_bits[i] = bitvec_get_bit_pos(&bits, i) ? 'R' : 'I'; + } + show_bits[num_blocks] = 0; + + LOGP(DRLCMAC, LOGL_DEBUG, + "EGPRS DL ACK bitmap: BSN %d to %d - 1 (%d blocks): %s\n", + bsn_begin, bsn_end, num_blocks, show_bits); + + if (ack_nack->EGPRS_AckNack.Desc.URBB_LENGTH == 0 && + !ack_nack->EGPRS_AckNack.Desc.Exist_CRBB) + { + /* Everything has been received successfully */ + /* Fake a GPRS type ack */ + uint64_t fake_map = -1; + + rc = tbf->rcvd_dl_ack( + ack_nack->EGPRS_AckNack.Desc.FINAL_ACK_INDICATION, + tbf->m_window.mod_sns(ack_nack->EGPRS_AckNack.Desc.STARTING_SEQUENCE_NUMBER-1), + (uint8_t *)&fake_map); + + if (rc == 1) { + tbf_free(tbf); + return; + } + } + + /* check for channel request */ + if (ack_nack->Exist_ChannelRequestDescription) { + LOGP(DRLCMAC, LOGL_DEBUG, "MS requests UL TBF in ack " + "message, so we provide one:\n"); + + /* This call will register the new TBF with the MS on success */ + tbf_alloc_ul(bts_data(), tbf->trx->trx_no, + tbf->ms_class(), tbf->ms()->egprs_ms_class(), + tbf->tlli(), tbf->ta(), tbf->ms()); + + /* schedule uplink assignment */ + tbf->ul_ass_state = GPRS_RLCMAC_UL_ASS_SEND_ASS; + } + + /* get measurements */ + if (tbf->ms()) { + /* TODO: Implement Measurements parsing for EGPRS */ + /* + get_meas(&meas, &ack_nack->Channel_Quality_Report); + tbf->ms()->update_l1_meas(&meas); + */ + } +} + void gprs_rlcmac_pdch::rcv_resource_request(Packet_Resource_Request_t *request, uint32_t fn) { struct gprs_rlcmac_sba *sba; @@ -1105,6 +1222,9 @@ int gprs_rlcmac_pdch::rcv_control_block( case MT_PACKET_DOWNLINK_ACK_NACK: rcv_control_dl_ack_nack(&ul_control_block->u.Packet_Downlink_Ack_Nack, fn); break; + case MT_EGPRS_PACKET_DOWNLINK_ACK_NACK: + rcv_control_egprs_dl_ack_nack(&ul_control_block->u.Egprs_Packet_Downlink_Ack_Nack, fn); + break; case MT_PACKET_RESOURCE_REQUEST: rcv_resource_request(&ul_control_block->u.Packet_Resource_Request, fn); break; diff --git a/src/bts.h b/src/bts.h index 0928f8d7..52154cb2 100644 --- a/src/bts.h +++ b/src/bts.h @@ -107,6 +107,7 @@ private: void rcv_control_ack(Packet_Control_Acknowledgement_t *, uint32_t fn); void rcv_control_dl_ack_nack(Packet_Downlink_Ack_Nack_t *, uint32_t fn); + void rcv_control_egprs_dl_ack_nack(EGPRS_PD_AckNack_t *, uint32_t fn); void rcv_resource_request(Packet_Resource_Request_t *t, uint32_t fn); void rcv_measurement_report(Packet_Measurement_Report_t *t, uint32_t fn); gprs_rlcmac_tbf *tbf_from_list_by_tfi( diff --git a/src/csn1.cpp b/src/csn1.cpp index 377c50f4..54cc411c 100644 --- a/src/csn1.cpp +++ b/src/csn1.cpp @@ -549,6 +549,7 @@ csnStreamDecoder(csnStream_t* ar, const CSN_DESCR* pDescr, bitvec *vector, unsig csnStreamInit(&arT, bit_offset, length); arT.direction = 1; + LOGPC(DCSN1, LOGL_NOTICE, "ptr = %p | offset = %d | ", (void *)data, (int)pDescr->offset); Status = serialize(&arT, vector, readIndex, pvDATA(data, pDescr->offset)); if (Status >= 0) diff --git a/src/decoding.cpp b/src/decoding.cpp index cb1b34d4..f4cd8802 100644 --- a/src/decoding.cpp +++ b/src/decoding.cpp @@ -493,3 +493,94 @@ const uint8_t *Decoding::rlc_get_data_aligned( Decoding::rlc_copy_to_aligned_buffer(rlc, data_block_idx, src, buffer); return buffer; } + +static int handle_final_ack(bitvec *bits, int *bsn_begin, int *bsn_end, + gprs_rlc_dl_window *window) +{ + int num_blocks, i; + + num_blocks = window->mod_sns(window->v_s() - window->v_a()); + for (i = 0; i < num_blocks; i++) + bitvec_set_bit(bits, ONE); + + *bsn_begin = window->v_a(); + *bsn_end = window->mod_sns(*bsn_begin + num_blocks); + return num_blocks; +} + +int Decoding::decode_egprs_acknack_bits(const EGPRS_AckNack_Desc_t *desc, + bitvec *bits, int *bsn_begin, int *bsn_end, gprs_rlc_dl_window *window) +{ + int urbb_len = desc->URBB_LENGTH; + int crbb_len = 0; + int num_blocks = 0; + struct bitvec urbb; + int i; + bool have_bitmap; + int implicitly_acked_blocks; + int ssn = desc->STARTING_SEQUENCE_NUMBER; + + if (desc->FINAL_ACK_INDICATION) + return handle_final_ack(bits, bsn_begin, bsn_end, window); + + if (desc->Exist_CRBB) + crbb_len = desc->CRBB_LENGTH; + + have_bitmap = (urbb_len + crbb_len) > 0; + + /* + * bow & bitmap present: + * V(A)-> [ 11111...11111 0 SSN-> BBBBB...BBBBB ] (SSN+Nbits) .... V(S) + * bow & not bitmap present: + * V(A)-> [ 11111...11111 ] . SSN .... V(S) + * not bow & bitmap present: + * V(A)-> ... [ 0 SSN-> BBBBB...BBBBB ](SSN+N) .... V(S) + * not bow & not bitmap present: + * V(A)-> ... [] . SSN .... V(S) + */ + + if (desc->BEGINNING_OF_WINDOW) { + implicitly_acked_blocks = window->mod_sns(ssn - 1 - window->v_a()); + + for (i = 0; i < implicitly_acked_blocks; i++) + bitvec_set_bit(bits, ONE); + + num_blocks += implicitly_acked_blocks; + } + + if (have_bitmap) { + /* next bit refers to V(Q) and thus is always zero (and not + * transmitted) */ + bitvec_set_bit(bits, ZERO); + num_blocks += 1; + + if (crbb_len > 0) { + int old_len = bits->cur_bit; + /* + decode_t4_rle(bits, desc->CRBB, desc->CRBB_LENGTH, + desc->CRBB_STARTING_COLOR_CODE); + */ + + num_blocks += (bits->cur_bit - old_len); + } + + urbb.cur_bit = 0; + urbb.data = (uint8_t *)desc->URBB; + urbb.data_len = sizeof(desc->URBB); + + for (i = urbb_len; i > 0; i--) { + /* + * Set bit at the appropriate position (see 3GPP TS + * 44.060 12.3.1) + */ + int is_ack = bitvec_get_bit_pos(&urbb, i-1); + bitvec_set_bit(bits, is_ack == 1 ? ONE : ZERO); + } + num_blocks += urbb_len; + } + + *bsn_begin = window->v_a(); + *bsn_end = window->mod_sns(*bsn_begin + num_blocks); + + return num_blocks; +} diff --git a/src/decoding.h b/src/decoding.h index c75b19a1..99cb3187 100644 --- a/src/decoding.h +++ b/src/decoding.h @@ -24,6 +24,8 @@ #include +struct bitvec; + class Decoding { public: struct RlcData { @@ -51,4 +53,8 @@ public: const struct gprs_rlc_data_info *rlc, unsigned int data_block_idx, const uint8_t *src, uint8_t *buffer); + static int decode_egprs_acknack_bits( + const EGPRS_AckNack_Desc_t *desc, + struct bitvec *bits, int *bsn_begin, int *bsn_end, + struct gprs_rlc_dl_window *window); }; -- cgit v1.2.3 From 3fdcb2b84e1397f0a46bada134f5122357871e75 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Mon, 18 Jan 2016 16:51:59 +0100 Subject: edge: Add experimental support for uplink CRBB Currently only uncompressed bitmaps (URBB) are supported in PACKET UPLINK ACK/NACK messages. Extend decode_egprs_acknack_bits to decode compressed bitmaps (CRBB), too. Note that this code is only active, if the macro WITH_CRBB_DECODING is defined. Sponsored-by: On-Waves ehf --- src/decoding.cpp | 94 ++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 67 insertions(+), 27 deletions(-) diff --git a/src/decoding.cpp b/src/decoding.cpp index f4cd8802..7c20c488 100644 --- a/src/decoding.cpp +++ b/src/decoding.cpp @@ -23,6 +23,9 @@ extern "C" { #include +#if WITH_CRBB_DECODING +#include +#endif } #include @@ -548,37 +551,74 @@ int Decoding::decode_egprs_acknack_bits(const EGPRS_AckNack_Desc_t *desc, num_blocks += implicitly_acked_blocks; } - if (have_bitmap) { - /* next bit refers to V(Q) and thus is always zero (and not - * transmitted) */ - bitvec_set_bit(bits, ZERO); - num_blocks += 1; - - if (crbb_len > 0) { - int old_len = bits->cur_bit; - /* - decode_t4_rle(bits, desc->CRBB, desc->CRBB_LENGTH, - desc->CRBB_STARTING_COLOR_CODE); - */ - - num_blocks += (bits->cur_bit - old_len); + if (!have_bitmap) + goto aborted; + + /* next bit refers to V(Q) and thus is always zero (and not + * transmitted) */ + bitvec_set_bit(bits, ZERO); + num_blocks += 1; + + if (crbb_len > 0) { + int old_len = bits->cur_bit; +#if WITH_CRBB_DECODING +#warning "Experimental CRBB decoding enabled" + struct bitvec crbb; + int rc; + + crbb.data = (uint8_t *)desc->CRBB; + crbb.data_len = sizeof(desc->CRBB); + crbb.cur_bit = desc->CRBB_LENGTH; + + rc = osmo_t4_decode(&crbb, desc->CRBB_STARTING_COLOR_CODE, + bits); + + if (rc < 0) { + LOGP(DRLCMACUL, LOGL_NOTICE, + "Failed to decode CRBB: " + "length %d, data '%s'\n", + desc->CRBB_LENGTH, + osmo_hexdump(crbb.data, crbb.data_len)); + /* We don't know the SSN offset for the URBB, + * return what we have so far and assume the + * bitmap has stopped here */ + goto aborted; } +#else + LOGP(DRLCMACUL, LOGL_ERROR, "ERROR: CRBB not supported, " + "please set window size to 64\n"); + + /* We don't know the SSN offset for the URBB, return + * what we have so far and assume the bitmap has + * stopped here */ + goto aborted; +#endif + LOGP(DRLCMACDL, LOGL_DEBUG, + "CRBB len: %d, decoded len: %d, cc: %d, crbb: '%s'\n", + desc->CRBB_LENGTH, bits->cur_bit - old_len, + desc->CRBB_STARTING_COLOR_CODE, + osmo_hexdump( + desc->CRBB, (desc->CRBB_LENGTH + 7)/8) + ); + + num_blocks += (bits->cur_bit - old_len); + } - urbb.cur_bit = 0; - urbb.data = (uint8_t *)desc->URBB; - urbb.data_len = sizeof(desc->URBB); - - for (i = urbb_len; i > 0; i--) { - /* - * Set bit at the appropriate position (see 3GPP TS - * 44.060 12.3.1) - */ - int is_ack = bitvec_get_bit_pos(&urbb, i-1); - bitvec_set_bit(bits, is_ack == 1 ? ONE : ZERO); - } - num_blocks += urbb_len; + urbb.cur_bit = 0; + urbb.data = (uint8_t *)desc->URBB; + urbb.data_len = sizeof(desc->URBB); + + for (i = urbb_len; i > 0; i--) { + /* + * Set bit at the appropriate position (see 3GPP TS + * 44.060 12.3.1) + */ + int is_ack = bitvec_get_bit_pos(&urbb, i-1); + bitvec_set_bit(bits, is_ack == 1 ? ONE : ZERO); } + num_blocks += urbb_len; +aborted: *bsn_begin = window->v_a(); *bsn_end = window->mod_sns(*bsn_begin + num_blocks); -- cgit v1.2.3 From 2bef4dbd431150dddadd52221d7e238ca49ea4a3 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Wed, 20 Jan 2016 14:33:11 +0100 Subject: edge: Enable CRBB decoding Currently CRBB bitmaps are ignored if they are present. This commit enables the decoding. Note that this requires osmo_t4_decode in libosmocore. Sponsored-by: On-Waves ehf --- src/decoding.cpp | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/src/decoding.cpp b/src/decoding.cpp index 7c20c488..0623bef2 100644 --- a/src/decoding.cpp +++ b/src/decoding.cpp @@ -23,9 +23,7 @@ extern "C" { #include -#if WITH_CRBB_DECODING #include -#endif } #include @@ -522,6 +520,7 @@ int Decoding::decode_egprs_acknack_bits(const EGPRS_AckNack_Desc_t *desc, bool have_bitmap; int implicitly_acked_blocks; int ssn = desc->STARTING_SEQUENCE_NUMBER; + int rc; if (desc->FINAL_ACK_INDICATION) return handle_final_ack(bits, bsn_begin, bsn_end, window); @@ -561,10 +560,7 @@ int Decoding::decode_egprs_acknack_bits(const EGPRS_AckNack_Desc_t *desc, if (crbb_len > 0) { int old_len = bits->cur_bit; -#if WITH_CRBB_DECODING -#warning "Experimental CRBB decoding enabled" struct bitvec crbb; - int rc; crbb.data = (uint8_t *)desc->CRBB; crbb.data_len = sizeof(desc->CRBB); @@ -584,15 +580,7 @@ int Decoding::decode_egprs_acknack_bits(const EGPRS_AckNack_Desc_t *desc, * bitmap has stopped here */ goto aborted; } -#else - LOGP(DRLCMACUL, LOGL_ERROR, "ERROR: CRBB not supported, " - "please set window size to 64\n"); - /* We don't know the SSN offset for the URBB, return - * what we have so far and assume the bitmap has - * stopped here */ - goto aborted; -#endif LOGP(DRLCMACDL, LOGL_DEBUG, "CRBB len: %d, decoded len: %d, cc: %d, crbb: '%s'\n", desc->CRBB_LENGTH, bits->cur_bit - old_len, -- cgit v1.2.3 From 192bf33ffb14de601451343cae53838d8e7feeb7 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Fri, 5 Feb 2016 13:10:29 +0100 Subject: decode: Add bitvec based GPRS DL ACK/NACK decoder Currently the RBB is used and passed directly to the window handling methods. For EGPRS a more abstract bitvec is derived from the messages and will passed around instead. Add a similar function for GPRS so that the same window handling can be used for GPRS and EGPRS. Sponsored-by: On-Waves ehf --- src/decoding.cpp | 47 +++++++++++++++++++++++++++++++++++++++++++++++ src/decoding.h | 4 ++++ 2 files changed, 51 insertions(+) diff --git a/src/decoding.cpp b/src/decoding.cpp index 0623bef2..4c79c83b 100644 --- a/src/decoding.cpp +++ b/src/decoding.cpp @@ -612,3 +612,50 @@ aborted: return num_blocks; } + +int Decoding::decode_gprs_acknack_bits(const Ack_Nack_Description_t *desc, + bitvec *bits, int *bsn_begin, int *bsn_end, gprs_rlc_dl_window *window) +{ + int urbb_len = RLC_GPRS_WS; + int num_blocks; + struct bitvec urbb; + + if (desc->FINAL_ACK_INDICATION) + return handle_final_ack(bits, bsn_begin, bsn_end, window); + + *bsn_begin = window->v_a(); + *bsn_end = desc->STARTING_SEQUENCE_NUMBER; + + num_blocks = window->mod_sns(*bsn_end - *bsn_begin); + + if (num_blocks < 0 || num_blocks > urbb_len) { + *bsn_end = *bsn_begin; + LOGP(DRLCMACUL, LOGL_NOTICE, + "Invalid GPRS Ack/Nack window %d:%d (length %d)\n", + *bsn_begin, *bsn_end, num_blocks); + return -EINVAL; + } + + urbb.cur_bit = 0; + urbb.data = (uint8_t *)desc->RECEIVED_BLOCK_BITMAP; + urbb.data_len = sizeof(desc->RECEIVED_BLOCK_BITMAP); + + /* + * TS 44.060, 12.3: + * BSN = (SSN - bit_number) modulo 128, for bit_number = 1 to 64. + * The BSN values represented range from (SSN - 1) mod 128 to (SSN - 64) mod 128. + * + * We are only interested in the range from V(A) to SSN-1 which is + * num_blocks large. The RBB is laid out as + * [SSN-1] [SSN-2] ... [V(A)] ... [SSN-64] + * so we want to start with [V(A)] and go backwards until we reach + * [SSN-1] to get the needed BSNs in an increasing order. Note that + * the bit numbers are counted from the end of the buffer. + */ + for (int i = num_blocks; i > 0; i--) { + int is_ack = bitvec_get_bit_pos(&urbb, urbb_len - i); + bitvec_set_bit(bits, is_ack == 1 ? ONE : ZERO); + } + + return num_blocks; +} diff --git a/src/decoding.h b/src/decoding.h index 99cb3187..af0bb13a 100644 --- a/src/decoding.h +++ b/src/decoding.h @@ -57,4 +57,8 @@ public: const EGPRS_AckNack_Desc_t *desc, struct bitvec *bits, int *bsn_begin, int *bsn_end, struct gprs_rlc_dl_window *window); + static int decode_gprs_acknack_bits( + const Ack_Nack_Description_t *desc, + bitvec *bits, int *bsn_begin, int *bsn_end, + gprs_rlc_dl_window *window); }; -- cgit v1.2.3 From f2f24b09593bb91e84538e7f6c9e51dd642bf5e0 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Fri, 5 Feb 2016 13:16:24 +0100 Subject: edge: Add a bitvec based Decoding::extract_rbb function This shall replace the old one after the transition to bitvec based RBBs. Sponsored-by: On-Waves ehf --- src/decoding.cpp | 12 ++++++++++++ src/decoding.h | 1 + 2 files changed, 13 insertions(+) diff --git a/src/decoding.cpp b/src/decoding.cpp index 4c79c83b..f4b539b1 100644 --- a/src/decoding.cpp +++ b/src/decoding.cpp @@ -329,6 +329,18 @@ void Decoding::extract_rbb(const uint8_t *rbb, char *show_rbb) show_rbb[64] = '\0'; } +void Decoding::extract_rbb(const struct bitvec *rbb, char *show_rbb) +{ + unsigned int i; + for (i = 0; i < rbb->cur_bit; i++) { + uint8_t bit; + bit = bitvec_get_bit_pos(rbb, i); + show_rbb[i] = bit == 1 ? 'R' : 'I'; + } + + show_rbb[i] = '\0'; +} + int Decoding::rlc_parse_ul_data_header(struct gprs_rlc_data_info *rlc, const uint8_t *data, GprsCodingScheme cs) { diff --git a/src/decoding.h b/src/decoding.h index af0bb13a..58ecd18e 100644 --- a/src/decoding.h +++ b/src/decoding.h @@ -42,6 +42,7 @@ public: static uint8_t get_egprs_ms_class_by_capability(MS_Radio_Access_capability_t *cap); static void extract_rbb(const uint8_t *rbb, char *extracted_rbb); + static void extract_rbb(const struct bitvec *rbb, char *show_rbb); static int rlc_parse_ul_data_header(struct gprs_rlc_data_info *rlc, const uint8_t *data, GprsCodingScheme cs); -- cgit v1.2.3 From eb08f86c0278bc6c6d1ba42c82c66d564a5f7c06 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Fri, 5 Feb 2016 17:07:12 +0100 Subject: edge: Add bitvec based DL window updating methods The current methods are based on the GRPS specific RBB and SSN values and formats which are not compatible with EGPRS. Add a second set of similar methods with the same semantics but which are based on a bitvec and the first BSN instead. The following methods are affected: - gprs_rlc_dl_window::update - gprs_rlcmac_dl_tbf::rcvd_dl_ack - gprs_rlcmac_dl_tbf::update_window Sponsored-by: On-Waves ehf --- src/rlc.cpp | 31 ++++++++++++++++++++++ src/rlc.h | 4 +++ src/tbf.h | 2 ++ src/tbf_dl.cpp | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 118 insertions(+) diff --git a/src/rlc.cpp b/src/rlc.cpp index 1a8efdf6..6d3cfd59 100644 --- a/src/rlc.cpp +++ b/src/rlc.cpp @@ -114,6 +114,37 @@ static uint16_t bitnum_to_bsn(int bitnum, uint16_t ssn) return (ssn - 1 - bitnum); } +void gprs_rlc_dl_window::update(BTS *bts, const struct bitvec *rbb, + uint16_t first_bsn, uint16_t *lost, + uint16_t *received) +{ + unsigned num_blocks = rbb->cur_bit; + unsigned bsn; + + /* first_bsn is in range V(A)..V(S) */ + + for (unsigned int bitpos = 0; bitpos < num_blocks; bitpos++) { + bool is_ack; + bsn = mod_sns(first_bsn + bitpos); + if (bsn == mod_sns(v_a() - 1)) + break; + + is_ack = bitvec_get_bit_pos(rbb, bitpos) == 1; + + if (is_ack) { + LOGP(DRLCMACDL, LOGL_DEBUG, "- got ack for BSN=%d\n", bsn); + if (!m_v_b.is_acked(bsn)) + *received += 1; + m_v_b.mark_acked(bsn); + } else { + LOGP(DRLCMACDL, LOGL_DEBUG, "- got NACK for BSN=%d\n", bsn); + m_v_b.mark_nacked(bsn); + bts->rlc_nacked(); + *lost += 1; + } + } +} + void gprs_rlc_dl_window::update(BTS *bts, char *show_rbb, uint16_t ssn, uint16_t *lost, uint16_t *received) { diff --git a/src/rlc.h b/src/rlc.h index 76af4e10..3f599d47 100644 --- a/src/rlc.h +++ b/src/rlc.h @@ -32,6 +32,7 @@ #define RLC_EGPRS_MAX_WS 1024 /* min window size */ #define RLC_EGPRS_SNS 2048 /* EGPRS, must be power of 2 */ #define RLC_MAX_SNS RLC_EGPRS_SNS +#define RLC_MAX_WS RLC_EGPRS_MAX_WS #define RLC_MAX_LEN 74 /* MCS-9 data unit */ struct BTS; @@ -173,6 +174,9 @@ struct gprs_rlc_dl_window { int mark_for_resend(); void update(BTS *bts, char *show_rbb, uint16_t ssn, uint16_t *lost, uint16_t *received); + void update(BTS *bts, const struct bitvec *rbb, + uint16_t first_bsn, uint16_t *lost, + uint16_t *received); int move_window(); void show_state(char *show_rbb); int count_unacked(); diff --git a/src/tbf.h b/src/tbf.h index cd982739..11e1fc73 100644 --- a/src/tbf.h +++ b/src/tbf.h @@ -344,6 +344,7 @@ struct gprs_rlcmac_dl_tbf : public gprs_rlcmac_tbf { const uint8_t *data, const uint16_t len); int rcvd_dl_ack(uint8_t final, uint8_t ssn, uint8_t *rbb); + int rcvd_dl_ack(uint8_t final_ack, unsigned first_bsn, struct bitvec *rbb); struct msgb *create_dl_acked_block(uint32_t fn, uint8_t ts); void request_dl_ack(); bool need_control_ts() const; @@ -395,6 +396,7 @@ protected: struct msgb *create_dl_acked_block(const uint32_t fn, const uint8_t ts, const int index); int update_window(const uint8_t ssn, const uint8_t *rbb); + int update_window(unsigned first_bsn, const struct bitvec *rbb); int maybe_start_new_window(); bool dl_window_stalled() const; void reuse_tbf(); diff --git a/src/tbf_dl.cpp b/src/tbf_dl.cpp index e742c799..161ec26f 100644 --- a/src/tbf_dl.cpp +++ b/src/tbf_dl.cpp @@ -717,6 +717,75 @@ int gprs_rlcmac_dl_tbf::analyse_errors(char *show_rbb, uint8_t ssn, return lost * 100 / (lost + received); } +int gprs_rlcmac_dl_tbf::update_window(unsigned first_bsn, + const struct bitvec *rbb) +{ + int16_t dist; /* must be signed */ + uint16_t lost = 0, received = 0; + char show_v_b[RLC_MAX_SNS + 1]; + char show_rbb[RLC_MAX_SNS + 1]; + int error_rate; + struct ana_result ana_res; + unsigned num_blocks = rbb->cur_bit; + unsigned behind_last_bsn = m_window.mod_sns(first_bsn + num_blocks); + + Decoding::extract_rbb(rbb, show_rbb); + /* show received array in debug */ + LOGP(DRLCMACDL, LOGL_DEBUG, "- ack: (BSN=%d)\"%s\"" + "(BSN=%d) R=ACK I=NACK\n", first_bsn, + show_rbb, m_window.mod_sns(behind_last_bsn - 1)); + + /* apply received array to receive state (first_bsn..behind_last_bsn-1) */ + if (num_blocks > 0) { + /* calculate distance of ssn from V(S) */ + dist = m_window.mod_sns(m_window.v_s() - behind_last_bsn); + /* check if distance is less than distance V(A)..V(S) */ + if (dist >= m_window.distance()) { + /* this might happpen, if the downlink assignment + * was not received by ms and the ack refers + * to previous TBF + * FIXME: we should implement polling for + * control ack! + * TODO: check whether this FIXME still makes sense + */ + LOGP(DRLCMACDL, LOGL_NOTICE, "- ack range is out of " + "V(A)..V(S) range %s Free TBF!\n", tbf_name(this)); + return 1; /* indicate to free TBF */ + } + } + + error_rate = analyse_errors(show_rbb, behind_last_bsn, &ana_res); + + if (bts_data()->cs_adj_enabled && ms()) + ms()->update_error_rate(this, error_rate); + + m_window.update(bts, rbb, first_bsn, &lost, &received); + + /* report lost and received packets */ + gprs_rlcmac_received_lost(this, received, lost); + + /* Used to measure the leak rate */ + gprs_bssgp_update_bytes_received(ana_res.received_bytes, + ana_res.received_packets + ana_res.lost_packets); + + /* raise V(A), if possible */ + m_window.raise(m_window.move_window()); + + /* show receive state array in debug (V(A)..V(S)-1) */ + m_window.show_state(show_v_b); + LOGP(DRLCMACDL, LOGL_DEBUG, "- V(B): (V(A)=%d)\"%s\"" + "(V(S)-1=%d) A=Acked N=Nacked U=Unacked " + "X=Resend-Unacked I=Invalid\n", + m_window.v_a(), show_v_b, + m_window.v_s_mod(-1)); + + if (state_is(GPRS_RLCMAC_FINISHED) && m_window.window_empty()) { + LOGP(DRLCMACDL, LOGL_NOTICE, "Received acknowledge of " + "all blocks, but without final ack " + "inidcation (don't worry)\n"); + } + return 0; +} int gprs_rlcmac_dl_tbf::update_window(const uint8_t ssn, const uint8_t *rbb) { @@ -825,6 +894,18 @@ int gprs_rlcmac_dl_tbf::release() } +int gprs_rlcmac_dl_tbf::rcvd_dl_ack(uint8_t final_ack, unsigned first_bsn, + struct bitvec *rbb) +{ + LOGP(DRLCMACDL, LOGL_DEBUG, "%s downlink acknowledge\n", tbf_name(this)); + + if (!final_ack) + return update_window(first_bsn, rbb); + + LOGP(DRLCMACDL, LOGL_DEBUG, "- Final ACK received.\n"); + return maybe_start_new_window(); +} + int gprs_rlcmac_dl_tbf::rcvd_dl_ack(uint8_t final_ack, uint8_t ssn, uint8_t *rbb) { LOGP(DRLCMACDL, LOGL_DEBUG, "%s downlink acknowledge\n", tbf_name(this)); -- cgit v1.2.3 From b41262fa0bc7edb64e518839923933a3480d1d48 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Fri, 5 Feb 2016 17:13:24 +0100 Subject: edge: Use num_blocks in gprs_rlcmac_dl_tbf::analyse_errors Currently a window size of 64 is being hard coded. Use the length of the show_rbb string instead. Sponsored-by: On-Waves ehf --- src/tbf_dl.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/tbf_dl.cpp b/src/tbf_dl.cpp index 161ec26f..80ea7419 100644 --- a/src/tbf_dl.cpp +++ b/src/tbf_dl.cpp @@ -644,16 +644,20 @@ int gprs_rlcmac_dl_tbf::analyse_errors(char *show_rbb, uint8_t ssn, { gprs_rlc_data *rlc_data; uint16_t lost = 0, received = 0, skipped = 0; - char info[65]; - memset(info, '.', sizeof(info)); - info[64] = 0; + char info[RLC_MAX_WS + 1]; + memset(info, '.', m_window.ws()); + info[m_window.ws()] = 0; uint16_t bsn = 0; unsigned received_bytes = 0, lost_bytes = 0; unsigned received_packets = 0, lost_packets = 0; + unsigned num_blocks = strlen(show_rbb); /* SSN - 1 is in range V(A)..V(S)-1 */ - for (int bitpos = 0; bitpos < m_window.ws(); bitpos++) { - bool is_received = show_rbb[m_window.ws() - 1 - bitpos] == 'R'; + for (unsigned int bitpos = 0; bitpos < num_blocks; bitpos++) { + bool is_received; + int index = num_blocks - 1 - bitpos; + + is_received = (index >= 0 && show_rbb[index] == 'R'); bsn = m_window.mod_sns(bitnum_to_bsn(bitpos, ssn)); -- cgit v1.2.3 From 419b03497555eec53bc5759f6838d6a464987b99 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Thu, 14 Jan 2016 13:40:01 +0100 Subject: tbf: Use bitvec based window methods for GPRS Currently the old fixed 64 bit RBB based implementation is used for GPRS. Use the new bitvec based methods instead. Sponsored-by: On-Waves ehf --- src/bts.cpp | 23 +++++++++++++++++-- tests/tbf/TbfTest.err | 1 + tests/types/TypesTest.cpp | 56 +++++++++++++++++++++++++++++++++++++++++++++-- tests/types/TypesTest.ok | 3 ++- 4 files changed, 78 insertions(+), 5 deletions(-) diff --git a/src/bts.cpp b/src/bts.cpp index 16961454..d95dd869 100644 --- a/src/bts.cpp +++ b/src/bts.cpp @@ -892,6 +892,11 @@ void gprs_rlcmac_pdch::rcv_control_dl_ack_nack(Packet_Downlink_Ack_Nack_t *ack_n struct gprs_rlcmac_dl_tbf *tbf; int rc; struct pcu_l1_meas meas; + int num_blocks; + uint8_t bits_data[RLC_GPRS_WS/8]; + bitvec bits; + int bsn_begin, bsn_end; + char show_bits[RLC_GPRS_WS + 1]; tfi = ack_nack->DOWNLINK_TFI; tbf = bts()->dl_tbf_by_poll_fn(fn, trx_no(), ts_no); @@ -918,10 +923,24 @@ void gprs_rlcmac_pdch::rcv_control_dl_ack_nack(Packet_Downlink_Ack_Nack_t *ack_n LOGP(DRLCMAC, LOGL_DEBUG, "RX: [PCU <- BTS] %s Packet Downlink Ack/Nack\n", tbf_name(tbf)); tbf->poll_state = GPRS_RLCMAC_POLL_NONE; + bits.data = bits_data; + bits.data_len = sizeof(bits_data); + bits.cur_bit = 0; + + num_blocks = Decoding::decode_gprs_acknack_bits( + &ack_nack->Ack_Nack_Description, &bits, + &bsn_begin, &bsn_end, &tbf->m_window); + + LOGP(DRLCMAC, LOGL_DEBUG, + "Got GPRS DL ACK bitmap: SSN: %d, BSN %d to %d - 1 (%d blocks), " + "\"%s\"\n", + ack_nack->Ack_Nack_Description.STARTING_SEQUENCE_NUMBER, + bsn_begin, bsn_end, num_blocks, + (Decoding::extract_rbb(&bits, show_bits), show_bits)); + rc = tbf->rcvd_dl_ack( ack_nack->Ack_Nack_Description.FINAL_ACK_INDICATION, - ack_nack->Ack_Nack_Description.STARTING_SEQUENCE_NUMBER, - ack_nack->Ack_Nack_Description.RECEIVED_BLOCK_BITMAP); + bsn_begin, &bits); if (rc == 1) { tbf_free(tbf); return; diff --git a/tests/tbf/TbfTest.err b/tests/tbf/TbfTest.err index ad0b69bb..5f493954 100644 --- a/tests/tbf/TbfTest.err +++ b/tests/tbf/TbfTest.err @@ -2764,6 +2764,7 @@ Got RLC block, coding scheme: CS-1, length: 23 (23)) +++++++++++++++++++++++++ RX : Uplink Control Block +++++++++++++++++++++++++ ------------------------- RX : Uplink Control Block ------------------------- RX: [PCU <- BTS] TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FINISHED) Packet Downlink Ack/Nack +Got GPRS DL ACK bitmap: SSN: 0, BSN 0 to 28 - 1 (28 blocks), "RRRRRRRRRRRRRRRRRRRRRRRRRRRR" TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FINISHED) downlink acknowledge - Final ACK received. TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FINISHED) changes state from FINISHED to WAIT RELEASE diff --git a/tests/types/TypesTest.cpp b/tests/types/TypesTest.cpp index 3447f695..c56b125a 100644 --- a/tests/types/TypesTest.cpp +++ b/tests/types/TypesTest.cpp @@ -327,8 +327,12 @@ static void test_rlc_dl_ul_basic() { uint16_t lost = 0, recv = 0; char show_rbb[65]; + uint8_t bits_data[8]; BTS dummy_bts; gprs_rlc_dl_window dl_win; + bitvec bits; + int bsn_begin, bsn_end, num_blocks; + Ack_Nack_Description_t desc; dl_win.m_v_b.reset(); @@ -348,13 +352,61 @@ static void test_rlc_dl_ul_basic() } uint8_t rbb_cmp[8] = { 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff }; - Decoding::extract_rbb(rbb_cmp, show_rbb); + bits.data = bits_data; + bits.data_len = sizeof(bits_data); + bits.cur_bit = 0; + + memcpy(desc.RECEIVED_BLOCK_BITMAP, rbb_cmp, + sizeof(desc.RECEIVED_BLOCK_BITMAP)); + desc.FINAL_ACK_INDICATION = 0; + desc.STARTING_SEQUENCE_NUMBER = 35; + + num_blocks = Decoding::decode_gprs_acknack_bits( + &desc, &bits, + &bsn_begin, &bsn_end, &dl_win); + Decoding::extract_rbb(&bits, show_rbb); printf("show_rbb: %s\n", show_rbb); - dl_win.update(&dummy_bts, show_rbb, 35, &lost, &recv); + dl_win.update(&dummy_bts, &bits, 0, &lost, &recv); OSMO_ASSERT(lost == 0); OSMO_ASSERT(recv == 35); + OSMO_ASSERT(bsn_begin == 0); + OSMO_ASSERT(bsn_end == 35); + OSMO_ASSERT(num_blocks == 35); + dl_win.raise(dl_win.move_window()); + + for (int i = 0; i < 8; ++i) { + dl_win.increment_send(); + OSMO_ASSERT(!dl_win.window_empty()); + OSMO_ASSERT(dl_win.distance() == 2 + i); + } + + uint8_t rbb_cmp2[8] = { 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0x31 }; + bits.data = bits_data; + bits.data_len = sizeof(bits_data); + bits.cur_bit = 0; + + memcpy(desc.RECEIVED_BLOCK_BITMAP, rbb_cmp2, + sizeof(desc.RECEIVED_BLOCK_BITMAP)); + desc.FINAL_ACK_INDICATION = 0; + desc.STARTING_SEQUENCE_NUMBER = 35 + 8; + + num_blocks = Decoding::decode_gprs_acknack_bits( + &desc, &bits, + &bsn_begin, &bsn_end, &dl_win); + Decoding::extract_rbb(&bits, show_rbb); + printf("show_rbb: %s\n", show_rbb); + + lost = recv = 0; + dl_win.update(&dummy_bts, &bits, 0, &lost, &recv); + OSMO_ASSERT(lost == 5); + OSMO_ASSERT(recv == 3); + OSMO_ASSERT(bitvec_get_bit_pos(&bits, 0) == 0); + OSMO_ASSERT(bitvec_get_bit_pos(&bits, 7) == 1); + OSMO_ASSERT(bsn_begin == 35); + OSMO_ASSERT(bsn_end == 43); + OSMO_ASSERT(num_blocks == 8); } } diff --git a/tests/types/TypesTest.ok b/tests/types/TypesTest.ok index 6ca2717c..cb40d398 100644 --- a/tests/types/TypesTest.ok +++ b/tests/types/TypesTest.ok @@ -4,4 +4,5 @@ rbb: 00 00 00 00 00 00 00 01 rbb: 00 00 00 00 00 00 00 03 rbb: 00 00 00 00 00 00 00 31 rbb: 10 00 00 00 00 00 00 01 -show_rbb: IIIIIIIIIIIIIIIIIIIIIIIIIIIIIRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR +show_rbb: RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR +show_rbb: IIRRIIIR -- cgit v1.2.3 From d7630f2256f7e99240c214b5c3310cf650e393d5 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Thu, 14 Jan 2016 18:05:44 +0100 Subject: edge: Use bitvec based window methods for EGPRS Currently a faked 'old' RBB with 64 ACKs is being used. Use the new bitvec based methods instead. Sponsored-by: On-Waves ehf --- src/bts.cpp | 35 ++++++++++++----------------------- 1 file changed, 12 insertions(+), 23 deletions(-) diff --git a/src/bts.cpp b/src/bts.cpp index d95dd869..eb079186 100644 --- a/src/bts.cpp +++ b/src/bts.cpp @@ -1031,31 +1031,20 @@ void gprs_rlcmac_pdch::rcv_control_egprs_dl_ack_nack(EGPRS_PD_AckNack_t *ack_nac &ack_nack->EGPRS_AckNack.Desc, &bits, &bsn_begin, &bsn_end, &tbf->m_window); - for (int i = 0; i < num_blocks; i++) { - show_bits[i] = bitvec_get_bit_pos(&bits, i) ? 'R' : 'I'; - } - show_bits[num_blocks] = 0; - LOGP(DRLCMAC, LOGL_DEBUG, - "EGPRS DL ACK bitmap: BSN %d to %d - 1 (%d blocks): %s\n", - bsn_begin, bsn_end, num_blocks, show_bits); - - if (ack_nack->EGPRS_AckNack.Desc.URBB_LENGTH == 0 && - !ack_nack->EGPRS_AckNack.Desc.Exist_CRBB) - { - /* Everything has been received successfully */ - /* Fake a GPRS type ack */ - uint64_t fake_map = -1; - - rc = tbf->rcvd_dl_ack( - ack_nack->EGPRS_AckNack.Desc.FINAL_ACK_INDICATION, - tbf->m_window.mod_sns(ack_nack->EGPRS_AckNack.Desc.STARTING_SEQUENCE_NUMBER-1), - (uint8_t *)&fake_map); + "Got EGPRS DL ACK bitmap: SSN: %d, BSN %d to %d - 1 (%d blocks), " + "\"%s\"\n", + ack_nack->EGPRS_AckNack.Desc.STARTING_SEQUENCE_NUMBER, + bsn_begin, bsn_end, num_blocks, + (Decoding::extract_rbb(&bits, show_bits), show_bits) + ); - if (rc == 1) { - tbf_free(tbf); - return; - } + rc = tbf->rcvd_dl_ack( + ack_nack->EGPRS_AckNack.Desc.FINAL_ACK_INDICATION, + bsn_begin, &bits); + if (rc == 1) { + tbf_free(tbf); + return; } /* check for channel request */ -- cgit v1.2.3 From b4beb545f7751f598e520707a6358bd515282869 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Fri, 15 Jan 2016 13:38:31 +0100 Subject: edge: Call update_window even if FINAL_ACK_INDICATION is set The bitvec RBB is always valid, even when FINAL_ACK_INDICATION is set. This is done by the ack/nack decoder function which fake a bitmap starting with V(A) up to V(S)-1 in that case (see Decoding::handle_final_ack). Call gprs_rlcmac_dl_tbf::update_window unconditionally and only use is_final for logging and TBF state changes in gprs_rlcmac_dl_tbf::rcvd_dl_ack. Sponsored-by: On-Waves ehf --- src/tbf_dl.cpp | 22 ++++++++++++---------- tests/tbf/TbfTest.err | 31 +++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 10 deletions(-) diff --git a/src/tbf_dl.cpp b/src/tbf_dl.cpp index 80ea7419..1827469b 100644 --- a/src/tbf_dl.cpp +++ b/src/tbf_dl.cpp @@ -782,12 +782,6 @@ int gprs_rlcmac_dl_tbf::update_window(unsigned first_bsn, "X=Resend-Unacked I=Invalid\n", m_window.v_a(), show_v_b, m_window.v_s_mod(-1)); - - if (state_is(GPRS_RLCMAC_FINISHED) && m_window.window_empty()) { - LOGP(DRLCMACDL, LOGL_NOTICE, "Received acknowledge of " - "all blocks, but without final ack " - "inidcation (don't worry)\n"); - } return 0; } @@ -901,13 +895,21 @@ int gprs_rlcmac_dl_tbf::release() int gprs_rlcmac_dl_tbf::rcvd_dl_ack(uint8_t final_ack, unsigned first_bsn, struct bitvec *rbb) { + int rc; LOGP(DRLCMACDL, LOGL_DEBUG, "%s downlink acknowledge\n", tbf_name(this)); - if (!final_ack) - return update_window(first_bsn, rbb); + rc = update_window(first_bsn, rbb); - LOGP(DRLCMACDL, LOGL_DEBUG, "- Final ACK received.\n"); - return maybe_start_new_window(); + if (final_ack) { + LOGP(DRLCMACDL, LOGL_DEBUG, "- Final ACK received.\n"); + rc = maybe_start_new_window(); + } else if (state_is(GPRS_RLCMAC_FINISHED) && m_window.window_empty()) { + LOGP(DRLCMACDL, LOGL_NOTICE, "Received acknowledge of " + "all blocks, but without final ack " + "indication (don't worry)\n"); + } + + return rc; } int gprs_rlcmac_dl_tbf::rcvd_dl_ack(uint8_t final_ack, uint8_t ssn, uint8_t *rbb) diff --git a/tests/tbf/TbfTest.err b/tests/tbf/TbfTest.err index 5f493954..7b36b310 100644 --- a/tests/tbf/TbfTest.err +++ b/tests/tbf/TbfTest.err @@ -2766,6 +2766,37 @@ Got RLC block, coding scheme: CS-1, length: 23 (23)) RX: [PCU <- BTS] TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FINISHED) Packet Downlink Ack/Nack Got GPRS DL ACK bitmap: SSN: 0, BSN 0 to 28 - 1 (28 blocks), "RRRRRRRRRRRRRRRRRRRRRRRRRRRR" TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FINISHED) downlink acknowledge +- ack: (BSN=0)"RRRRRRRRRRRRRRRRRRRRRRRRRRRR"(BSN=27) R=ACK I=NACK +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FINISHED) DL analysis, range=0:28, lost=0, recv=28, skipped=0, bsn=0, info='RRRRRRRRRRRRRRRRRRRRRRRRRRRR....................................' +- got ack for BSN=0 +- got ack for BSN=1 +- got ack for BSN=2 +- got ack for BSN=3 +- got ack for BSN=4 +- got ack for BSN=5 +- got ack for BSN=6 +- got ack for BSN=7 +- got ack for BSN=8 +- got ack for BSN=9 +- got ack for BSN=10 +- got ack for BSN=11 +- got ack for BSN=12 +- got ack for BSN=13 +- got ack for BSN=14 +- got ack for BSN=15 +- got ack for BSN=16 +- got ack for BSN=17 +- got ack for BSN=18 +- got ack for BSN=19 +- got ack for BSN=20 +- got ack for BSN=21 +- got ack for BSN=22 +- got ack for BSN=23 +- got ack for BSN=24 +- got ack for BSN=25 +- got ack for BSN=26 +- got ack for BSN=27 +- V(B): (V(A)=28)""(V(S)-1=27) A=Acked N=Nacked U=Unacked X=Resend-Unacked I=Invalid - Final ACK received. TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FINISHED) changes state from FINISHED to WAIT RELEASE TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=WAIT RELEASE) starting timer 3193. -- cgit v1.2.3 From 53bc1861c4b6197bfc6715f8d4c08add473f7c6f Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Mon, 18 Jan 2016 17:23:09 +0100 Subject: edge: Fix initial coding scheme selection Currently the coding scheme gets reset when GprsMs::set_mode() is called even if the mode did not change. Make sure, that the CS is only reset, if it is not compliant to the new mode. Sponsored-by: On-Waves ehf --- src/gprs_ms.cpp | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/src/gprs_ms.cpp b/src/gprs_ms.cpp index 187132f5..9126543e 100644 --- a/src/gprs_ms.cpp +++ b/src/gprs_ms.cpp @@ -212,34 +212,39 @@ void GprsMs::set_mode(GprsCodingScheme::Mode mode) { m_mode = mode; + if (!m_bts) + return; + switch (m_mode) { case GprsCodingScheme::GPRS: - if (m_bts) { + if (!m_current_cs_ul.isGprs()) { m_current_cs_ul = GprsCodingScheme::getGprsByNum( m_bts->bts_data()->initial_cs_ul); + if (!m_current_cs_ul.isValid()) + m_current_cs_ul = GprsCodingScheme::CS1; + } + if (!m_current_cs_dl.isGprs()) { m_current_cs_dl = GprsCodingScheme::getGprsByNum( m_bts->bts_data()->initial_cs_dl); + if (!m_current_cs_dl.isValid()) + m_current_cs_dl = GprsCodingScheme::CS1; } - if (!m_current_cs_ul.isGprs()) - m_current_cs_ul = GprsCodingScheme::CS1; - if (!m_current_cs_dl.isGprs()) - m_current_cs_dl = GprsCodingScheme::CS1; - break; case GprsCodingScheme::EGPRS_GMSK: case GprsCodingScheme::EGPRS: - if (m_bts) { + if (!m_current_cs_ul.isEgprs()) { m_current_cs_ul = GprsCodingScheme::getEgprsByNum( m_bts->bts_data()->initial_mcs_ul); + if (!m_current_cs_dl.isValid()) + m_current_cs_ul = GprsCodingScheme::MCS1; + } + if (!m_current_cs_dl.isEgprs()) { m_current_cs_dl = GprsCodingScheme::getEgprsByNum( m_bts->bts_data()->initial_mcs_dl); + if (!m_current_cs_dl.isValid()) + m_current_cs_dl = GprsCodingScheme::MCS1; } - if (!m_current_cs_ul.isEgprs()) - m_current_cs_ul = GprsCodingScheme::MCS1; - if (!m_current_cs_dl.isEgprs()) - m_current_cs_dl = GprsCodingScheme::MCS1; - break; } } -- cgit v1.2.3 From f9940ca8d7d93e143da375c0775e852bd20e4c52 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Tue, 19 Jan 2016 10:32:33 +0100 Subject: edge: Fix MCS range in VTY Change the range from MCS 1-4 to MCS 1-9. Sponsored-by: On-Waves ehf --- src/pcu_vty.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pcu_vty.c b/src/pcu_vty.c index ee3116fd..fe3009b1 100644 --- a/src/pcu_vty.c +++ b/src/pcu_vty.c @@ -408,7 +408,7 @@ DEFUN(cfg_pcu_no_cs_max, DEFUN(cfg_pcu_mcs_max, cfg_pcu_mcs_max_cmd, - "mcs max <1-4> [<1-4>]", + "mcs max <1-9> [<1-9>]", MCS_STR CS_MAX_STR "Maximum MCS value to be used\n" -- cgit v1.2.3 From 9b3d7e015968bdb0a9f1a3642c1047d875d7049f Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Tue, 19 Jan 2016 10:44:42 +0100 Subject: edge: Disable GPRS/EGPRS mixed mode Currently the plain 'egprs' command enables EGPRS but doesn't prevent phones from being served in GPRS mode if they do not support EGPRS. This involves complex frame allocation implementations in dynamic mode, especially if 8PSK is being used. This is due to the inability of non-EGPRS phone to decode 8PSK USF and ES/P altogether. Since polling has a higher priority than USF, collisions will have to be prevented by the PCU by never using an GPRS USF if it refers to a FN that is already being used for polling. This commit just disables mixed usage by ignoring GPRS-only request if EGPRS is enabled. The following VTY command (config-pcu node) is changed: egprs -> egprs only Sponsored-by: On-Waves ehf --- src/bts.cpp | 1 + src/bts.h | 3 +++ src/pcu_vty.c | 8 +++----- src/tbf.cpp | 14 ++++++++++++++ tests/tbf/TbfTest.cpp | 34 ++++++++++++++++++++++++++++++++++ tests/tbf/TbfTest.err | 2 ++ tests/tbf/TbfTest.ok | 2 ++ 7 files changed, 59 insertions(+), 5 deletions(-) diff --git a/src/bts.cpp b/src/bts.cpp index eb079186..1c10596c 100644 --- a/src/bts.cpp +++ b/src/bts.cpp @@ -57,6 +57,7 @@ static const struct rate_ctr_desc bts_ctr_description[] = { { "tbf.reused", "TBF Reused "}, { "tbf.alloc.algo-a", "TBF Alloc Algo A "}, { "tbf.alloc.algo-b", "TBF Alloc Algo B "}, + { "tbf.failed.egprs-only", "TBF Failed EGPRS-only"}, { "rlc.sent", "RLC Sent "}, { "rlc.resent", "RLC Resent "}, { "rlc.restarted", "RLC Restarted "}, diff --git a/src/bts.h b/src/bts.h index 52154cb2..e467c1ed 100644 --- a/src/bts.h +++ b/src/bts.h @@ -215,6 +215,7 @@ public: CTR_TBF_REUSED, CTR_TBF_ALLOC_ALGO_A, CTR_TBF_ALLOC_ALGO_B, + CTR_TBF_FAILED_EGPRS_ONLY, CTR_RLC_SENT, CTR_RLC_RESENT, CTR_RLC_RESTARTED, @@ -288,6 +289,7 @@ public: void tbf_reused(); void tbf_alloc_algo_a(); void tbf_alloc_algo_b(); + void tbf_failed_egprs_only(); void rlc_sent(); void rlc_resent(); void rlc_restarted(); @@ -425,6 +427,7 @@ CREATE_COUNT_INLINE(tbf_ul_freed, CTR_TBF_UL_FREED) CREATE_COUNT_INLINE(tbf_reused, CTR_TBF_REUSED) CREATE_COUNT_INLINE(tbf_alloc_algo_a, CTR_TBF_ALLOC_ALGO_A) CREATE_COUNT_INLINE(tbf_alloc_algo_b, CTR_TBF_ALLOC_ALGO_B) +CREATE_COUNT_INLINE(tbf_failed_egprs_only, CTR_TBF_FAILED_EGPRS_ONLY) CREATE_COUNT_INLINE(rlc_sent, CTR_RLC_SENT) CREATE_COUNT_INLINE(rlc_resent, CTR_RLC_RESENT) CREATE_COUNT_INLINE(rlc_restarted, CTR_RLC_RESTARTED) diff --git a/src/pcu_vty.c b/src/pcu_vty.c index fe3009b1..97be4c72 100644 --- a/src/pcu_vty.c +++ b/src/pcu_vty.c @@ -55,9 +55,7 @@ static int config_write_pcu(struct vty *vty) vty_out(vty, "pcu%s", VTY_NEWLINE); if (bts->egprs_enabled) - vty_out(vty, " egprs%s", VTY_NEWLINE); - else - vty_out(vty, " no egprs%s", VTY_NEWLINE); + vty_out(vty, " egprs only%s", VTY_NEWLINE); vty_out(vty, " flow-control-interval %d%s", bts->fc_interval, VTY_NEWLINE); @@ -171,8 +169,8 @@ DEFUN(cfg_pcu, DEFUN(cfg_pcu_egprs, cfg_pcu_egprs_cmd, - "egprs", - EGPRS_STR) + "egprs only", + EGPRS_STR "Use EGPRS and disable plain GPRS\n") { struct gprs_rlcmac_bts *bts = bts_main_data(); diff --git a/src/tbf.cpp b/src/tbf.cpp index 1f0576af..db63a08d 100644 --- a/src/tbf.cpp +++ b/src/tbf.cpp @@ -609,6 +609,13 @@ struct gprs_rlcmac_ul_tbf *tbf_alloc_ul_tbf(struct gprs_rlcmac_bts *bts, struct gprs_rlcmac_ul_tbf *tbf; int rc; + if (egprs_ms_class == 0 && bts->egprs_enabled) { + LOGP(DRLCMAC, LOGL_NOTICE, + "Not accepting non-EGPRS phone in EGPRS-only mode\n"); + bts->bts->tbf_failed_egprs_only(); + return NULL; + } + LOGP(DRLCMAC, LOGL_DEBUG, "********** TBF starts here **********\n"); LOGP(DRLCMAC, LOGL_INFO, "Allocating %s TBF: MS_CLASS=%d/%d\n", "UL", ms_class, egprs_ms_class); @@ -679,6 +686,13 @@ struct gprs_rlcmac_dl_tbf *tbf_alloc_dl_tbf(struct gprs_rlcmac_bts *bts, struct gprs_rlcmac_dl_tbf *tbf; int rc; + if (egprs_ms_class == 0 && bts->egprs_enabled) { + LOGP(DRLCMAC, LOGL_NOTICE, + "Not accepting non-EGPRS phone in EGPRS-only mode\n"); + bts->bts->tbf_failed_egprs_only(); + return NULL; + } + LOGP(DRLCMAC, LOGL_DEBUG, "********** TBF starts here **********\n"); LOGP(DRLCMAC, LOGL_INFO, "Allocating %s TBF: MS_CLASS=%d/%d\n", "DL", ms_class, egprs_ms_class); diff --git a/tests/tbf/TbfTest.cpp b/tests/tbf/TbfTest.cpp index f9431f60..895ba8e5 100644 --- a/tests/tbf/TbfTest.cpp +++ b/tests/tbf/TbfTest.cpp @@ -1071,6 +1071,39 @@ static void test_tbf_dl_reuse() printf("=== end %s ===\n", __func__); } +static void test_tbf_gprs_egprs() +{ + BTS the_bts; + gprs_rlcmac_bts *bts; + uint8_t ts_no = 4; + uint8_t ms_class = 45; + int rc = 0; + uint32_t tlli = 0xc0006789; + const char *imsi = "001001123456789"; + unsigned delay_csec = 1000; + + uint8_t buf[256] = {0}; + + printf("=== start %s ===\n", __func__); + + bts = the_bts.bts_data(); + setup_bts(&the_bts, ts_no); + + /* EGPRS-only */ + bts->egprs_enabled = 1; + + gprs_bssgp_create_and_connect(bts, 33001, 0, 33001, + 1234, 1234, 1234, 1, 1, 0, 0, 0); + + /* Does not support EGPRS */ + rc = gprs_rlcmac_dl_tbf::handle(bts, tlli, 0, imsi, ms_class, 0, + delay_csec, buf, sizeof(buf)); + + OSMO_ASSERT(rc == -EBUSY); + printf("=== end %s ===\n", __func__); + + gprs_bssgp_destroy(); +} static const struct log_info_cat default_categories[] = { {"DCSN1", "\033[1;31m", "Concrete Syntax Notation One (CSN1)", LOGL_INFO, 0}, @@ -1129,6 +1162,7 @@ int main(int argc, char **argv) test_tbf_dl_flow_and_rach_two_phase(); test_tbf_dl_flow_and_rach_single_phase(); test_tbf_dl_reuse(); + test_tbf_gprs_egprs(); if (getenv("TALLOC_REPORT_FULL")) talloc_report_full(tall_pcu_ctx, stderr); diff --git a/tests/tbf/TbfTest.err b/tests/tbf/TbfTest.err index 7b36b310..0ca4b829 100644 --- a/tests/tbf/TbfTest.err +++ b/tests/tbf/TbfTest.err @@ -3039,3 +3039,5 @@ TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FINISHED) starting timer 3191. TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FINISHED) Scheduled Ack/Nack polling on FN=2654461, TS=7 msg block (BSN 10, CS-1): 0f 03 14 4d 43 20 50 41 43 4b 45 54 20 30 39 20 28 54 42 46 20 32 29 Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654448 block=1 data=08 03 14 4d 43 20 50 41 43 4b 45 54 20 30 39 20 28 54 42 46 20 32 29 +Not accepting non-EGPRS phone in EGPRS-only mode +No PDCH resource diff --git a/tests/tbf/TbfTest.ok b/tests/tbf/TbfTest.ok index 916ea52b..c4bc8705 100644 --- a/tests/tbf/TbfTest.ok +++ b/tests/tbf/TbfTest.ok @@ -26,3 +26,5 @@ === end test_tbf_dl_flow_and_rach_single_phase === === start test_tbf_dl_reuse === === end test_tbf_dl_reuse === +=== start test_tbf_gprs_egprs === +=== end test_tbf_gprs_egprs === -- cgit v1.2.3 From 3b1c5537731cc63125f1b82c0e6149372a7fe0da Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Wed, 20 Jan 2016 12:30:46 +0100 Subject: edge: Work-around to use EGPRS if there was no DL RA Cap If the downlink BSSGP didn't contain a RA Capabilities IE, both MS class values are 0. The phone will send valid RA Caps later on. Currently in that case, the downlink TBF is not established if EGPRS is enabled. Just force egprs_ms_class to 1 if EGPRS (only) is enabled. Sponsored-by: On-Waves ehf --- src/tbf.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/tbf.cpp b/src/tbf.cpp index db63a08d..9f19c9b7 100644 --- a/src/tbf.cpp +++ b/src/tbf.cpp @@ -687,10 +687,13 @@ struct gprs_rlcmac_dl_tbf *tbf_alloc_dl_tbf(struct gprs_rlcmac_bts *bts, int rc; if (egprs_ms_class == 0 && bts->egprs_enabled) { - LOGP(DRLCMAC, LOGL_NOTICE, - "Not accepting non-EGPRS phone in EGPRS-only mode\n"); - bts->bts->tbf_failed_egprs_only(); - return NULL; + if (ms_class > 0) { + LOGP(DRLCMAC, LOGL_NOTICE, + "Not accepting non-EGPRS phone in EGPRS-only mode\n"); + bts->bts->tbf_failed_egprs_only(); + return NULL; + } + egprs_ms_class = 1; } LOGP(DRLCMAC, LOGL_DEBUG, "********** TBF starts here **********\n"); -- cgit v1.2.3 From db88380b76e70db4ab3d895102b3e164bf8efe3d Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Tue, 19 Jan 2016 14:07:33 +0100 Subject: rlc: Add unified gprs_rlc_window parent class Currently gprs_rlc_ul_window and gprs_rlc_dl_window are completely separate classes, containing several identical members and methods. This commit add a shared parent class containing WS and SNS handling. Sponsored-by: On-Waves ehf --- src/bts.h | 2 ++ src/rlc.cpp | 20 ++-------------- src/rlc.h | 78 ++++++++++++++++++++++--------------------------------------- 3 files changed, 32 insertions(+), 68 deletions(-) diff --git a/src/bts.h b/src/bts.h index e467c1ed..c6247be9 100644 --- a/src/bts.h +++ b/src/bts.h @@ -188,6 +188,8 @@ struct gprs_rlcmac_bts { uint8_t cs_adj_lower_limit; struct {int16_t low; int16_t high;} cs_lqual_ranges[4]; uint16_t cs_downgrade_threshold; /* downgrade if less packets left (DL) */ + uint16_t egprs_ws_base; + uint16_t egprs_ws_lin; /* State for dynamic algorithm selection */ int multislot_disabled; diff --git a/src/rlc.cpp b/src/rlc.cpp index 6d3cfd59..e4a9563a 100644 --- a/src/rlc.cpp +++ b/src/rlc.cpp @@ -55,22 +55,6 @@ void gprs_rlc_dl_window::reset() m_v_b.reset(); } -void gprs_rlc_dl_window::set_sns(uint16_t sns) -{ - OSMO_ASSERT(sns >= RLC_GPRS_SNS); - OSMO_ASSERT(sns <= RLC_MAX_SNS); - /* check for 2^n */ - OSMO_ASSERT((sns & (-sns)) == sns); - m_sns = sns; -} - -void gprs_rlc_dl_window::set_ws(uint16_t ws) -{ - OSMO_ASSERT(ws >= RLC_GPRS_SNS/2); - OSMO_ASSERT(ws <= RLC_MAX_SNS/2); - m_ws = ws; -} - int gprs_rlc_dl_window::resend_needed() { for (uint16_t bsn = v_a(); bsn != v_s(); bsn = mod_sns(bsn + 1)) { @@ -219,7 +203,7 @@ void gprs_rlc_v_n::reset() m_v_n[i] = GPRS_RLC_UL_BSN_INVALID; } -void gprs_rlc_ul_window::set_sns(uint16_t sns) +void gprs_rlc_window::set_sns(uint16_t sns) { OSMO_ASSERT(sns >= RLC_GPRS_SNS); OSMO_ASSERT(sns <= RLC_MAX_SNS); @@ -228,7 +212,7 @@ void gprs_rlc_ul_window::set_sns(uint16_t sns) m_sns = sns; } -void gprs_rlc_ul_window::set_ws(uint16_t ws) +void gprs_rlc_window::set_ws(uint16_t ws) { OSMO_ASSERT(ws >= RLC_GPRS_SNS/2); OSMO_ASSERT(ws <= RLC_MAX_SNS/2); diff --git a/src/rlc.h b/src/rlc.h index 3f599d47..3a7f1a1a 100644 --- a/src/rlc.h +++ b/src/rlc.h @@ -151,13 +151,26 @@ private: /** * TODO: The UL/DL code could/should share a base class. */ -struct gprs_rlc_dl_window { - void reset(); +class gprs_rlc_window { +public: + gprs_rlc_window(); + const uint16_t mod_sns() const; const uint16_t mod_sns(uint16_t bsn) const; const uint16_t sns() const; const uint16_t ws() const; + void set_sns(uint16_t sns); + void set_ws(uint16_t ws); + +protected: + uint16_t m_sns; + uint16_t m_ws; +}; + +struct gprs_rlc_dl_window: public gprs_rlc_window { + void reset(); + bool window_stalled() const; bool window_empty() const; @@ -186,13 +199,7 @@ struct gprs_rlc_dl_window { gprs_rlc_v_b m_v_b; - void set_sns(uint16_t sns); - void set_ws(uint16_t ws); - gprs_rlc_dl_window(); -private: - uint16_t m_sns; - uint16_t m_ws; }; struct gprs_rlc_v_n { @@ -210,12 +217,7 @@ private: gprs_rlc_ul_bsn_state m_v_n[RLC_MAX_SNS/2]; /* receive state array */ }; -struct gprs_rlc_ul_window { - const uint16_t mod_sns() const; - const uint16_t mod_sns(uint16_t bsn) const; - const uint16_t sns() const; - const uint16_t ws() const; - +struct gprs_rlc_ul_window: public gprs_rlc_window { const uint16_t v_r() const; const uint16_t v_q() const; @@ -239,13 +241,7 @@ struct gprs_rlc_ul_window { gprs_rlc_v_n m_v_n; - void set_sns(uint16_t sns); - void set_ws(uint16_t ws); - gprs_rlc_ul_window(); -private: - uint16_t m_sns; - uint16_t m_ws; }; extern "C" { @@ -388,34 +384,38 @@ inline void gprs_rlc_v_b::mark_invalid(int bsn) return mark(bsn, GPRS_RLC_DL_BSN_INVALID); } -inline gprs_rlc_dl_window::gprs_rlc_dl_window() - : m_v_s(0) - , m_v_a(0) - , m_sns(RLC_GPRS_SNS) +inline gprs_rlc_window::gprs_rlc_window() + : m_sns(RLC_GPRS_SNS) , m_ws(RLC_GPRS_WS) { } -inline const uint16_t gprs_rlc_dl_window::sns() const +inline const uint16_t gprs_rlc_window::sns() const { return m_sns; } -inline const uint16_t gprs_rlc_dl_window::ws() const +inline const uint16_t gprs_rlc_window::ws() const { return m_ws; } -inline const uint16_t gprs_rlc_dl_window::mod_sns() const +inline const uint16_t gprs_rlc_window::mod_sns() const { return sns() - 1; } -inline const uint16_t gprs_rlc_dl_window::mod_sns(uint16_t bsn) const +inline const uint16_t gprs_rlc_window::mod_sns(uint16_t bsn) const { return bsn & mod_sns(); } +inline gprs_rlc_dl_window::gprs_rlc_dl_window() + : m_v_s(0) + , m_v_a(0) +{ +} + inline const uint16_t gprs_rlc_dl_window::v_s() const { return m_v_s; @@ -459,8 +459,6 @@ inline const int16_t gprs_rlc_dl_window::distance() const inline gprs_rlc_ul_window::gprs_rlc_ul_window() : m_v_r(0) , m_v_q(0) - , m_sns(RLC_GPRS_SNS) - , m_ws(RLC_GPRS_WS) { } @@ -484,26 +482,6 @@ inline bool gprs_rlc_ul_window::is_received(uint16_t bsn) const return is_in_window(bsn) && m_v_n.is_received(bsn) && offset_v_r < ws(); } -inline const uint16_t gprs_rlc_ul_window::sns() const -{ - return m_sns; -} - -inline const uint16_t gprs_rlc_ul_window::ws() const -{ - return m_ws; -} - -inline const uint16_t gprs_rlc_ul_window::mod_sns() const -{ - return sns() - 1; -} - -inline const uint16_t gprs_rlc_ul_window::mod_sns(uint16_t bsn) const -{ - return bsn & mod_sns(); -} - inline const uint16_t gprs_rlc_ul_window::v_r() const { return m_v_r; -- cgit v1.2.3 From 13965aed74ae1c59cfd4f52275ac3e98f9aa9e3a Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Tue, 19 Jan 2016 14:10:40 +0100 Subject: tbf: Add gprs_rlcmac_tbf::window() method This method returns a gprs_rlc_window independently of the TBF's direction. Sponsored-by: On-Waves ehf --- src/tbf.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/tbf.h b/src/tbf.h index 11e1fc73..ab4145c2 100644 --- a/src/tbf.h +++ b/src/tbf.h @@ -107,6 +107,8 @@ struct gprs_rlcmac_tbf { GprsMs *ms() const; void set_ms(GprsMs *ms); + gprs_rlc_window *window(); + uint8_t tsc() const; int rlcmac_diag(); @@ -460,4 +462,14 @@ inline gprs_rlcmac_dl_tbf *as_dl_tbf(gprs_rlcmac_tbf *tbf) return NULL; } +inline gprs_rlc_window *gprs_rlcmac_tbf::window() +{ + switch (direction) + { + case GPRS_RLCMAC_UL_TBF: return &as_ul_tbf(this)->m_window; + case GPRS_RLCMAC_DL_TBF: return &as_dl_tbf(this)->m_window; + } + return NULL; +} + #endif -- cgit v1.2.3 From 8cba7e9b6d11918c9865006b41f768943e1e44df Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Tue, 19 Jan 2016 15:48:03 +0100 Subject: utils: Add pcu_bitcount and pcu_lsb These functions are currently defined in src/gprs_rlcmac_ts_alloc.cpp but will be needed elsewhere. Turn them into template functions to support different types and move them to pcu_utils.h. Sponsored-by: On-Waves ehf --- src/gprs_rlcmac_ts_alloc.cpp | 29 ++++++++--------------------- src/pcu_utils.h | 16 ++++++++++++++++ 2 files changed, 24 insertions(+), 21 deletions(-) diff --git a/src/gprs_rlcmac_ts_alloc.cpp b/src/gprs_rlcmac_ts_alloc.cpp index e6c8ad4c..57197b22 100644 --- a/src/gprs_rlcmac_ts_alloc.cpp +++ b/src/gprs_rlcmac_ts_alloc.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -80,20 +81,6 @@ static const struct gprs_ms_multislot_class gprs_ms_multislot_class[32] = { /* N/A */ { MS_NA,MS_NA, MS_NA, MS_NA, MS_NA, MS_NA, MS_NA, MS_NA }, }; -static unsigned lsb(unsigned x) -{ - return x & -x; -} - -static unsigned bitcount(unsigned x) -{ - unsigned count = 0; - for (count = 0; x; count += 1) - x &= x - 1; - - return count; -} - static char *set_flag_chars(char *buf, uint8_t val, char set_char, char unset_char = 0) { int i; @@ -640,7 +627,7 @@ static int find_multi_slots(struct gprs_rlcmac_bts *bts, if ((tx_window & (1 << ((ul_ts+num_tx-1) % 8))) == 0) continue; - tx_slot_count = bitcount(tx_window); + tx_slot_count = pcu_bitcount(tx_window); max_rx = OSMO_MIN(ms_class->rx, ms_class->sum - num_tx); rx_valid_win = (1 << max_rx) - 1; @@ -669,7 +656,7 @@ static int find_multi_slots(struct gprs_rlcmac_bts *bts, * testing */ rx_window = rx_good & rx_valid_win; - rx_slot_count = bitcount(rx_window); + rx_slot_count = pcu_bitcount(rx_window); #if 0 LOGP(DRLCMAC, LOGL_DEBUG, "n_tx=%d, n_rx=%d, mask_sel=%d, " @@ -734,7 +721,7 @@ static int find_multi_slots(struct gprs_rlcmac_bts *bts, continue; /* Check number of common slots according to TS 54.002, 6.4.2.2 */ - common_slot_count = bitcount(tx_window & rx_window); + common_slot_count = pcu_bitcount(tx_window & rx_window); req_common_slots = OSMO_MIN(tx_slot_count, rx_slot_count); if (ms_class->type == 1) req_common_slots = OSMO_MIN(req_common_slots, 2); @@ -891,7 +878,7 @@ int alloc_algorithm_b(struct gprs_rlcmac_bts *bts, dl_slots & ul_slots, compute_usage_by_num_tbfs, NULL, NULL); if (ts < 0) - ul_slots = dl_slots = lsb(dl_slots & ul_slots); + ul_slots = dl_slots = pcu_lsb(dl_slots & ul_slots); else ul_slots = dl_slots = (dl_slots & ul_slots) & (1<tv_sec = csecs / 100; tv->tv_usec = (csecs % 100) * 10000; } + +template +inline unsigned int pcu_bitcount(T x) +{ + unsigned int count = 0; + for (count = 0; x; count += 1) + x &= x - 1; + + return count; +} + +template +inline T pcu_lsb(T x) +{ + return x & -x; +} -- cgit v1.2.3 From 08c72fb4a91c267410535be26d2bb399914ff6d4 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Tue, 19 Jan 2016 16:04:30 +0100 Subject: tbf/vty: Fix the CS output and show the EGPRS MS class Currently only the GPRS MS class and the DL CS (even for UL TBFs) are shown. Add the EGPRS MS class and use the TBF's real CS. Sponsored-by: On-Waves ehf --- src/pcu_vty_functions.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pcu_vty_functions.cpp b/src/pcu_vty_functions.cpp index a5430f91..2f7cb02a 100644 --- a/src/pcu_vty_functions.cpp +++ b/src/pcu_vty_functions.cpp @@ -46,17 +46,17 @@ static void tbf_print_vty_info(struct vty *vty, gprs_rlcmac_tbf *tbf) tbf->direction == GPRS_RLCMAC_UL_TBF ? "UL" : "DL", tbf->imsi(), VTY_NEWLINE); vty_out(vty, " created=%lu state=%08x 1st_TS=%d 1st_cTS=%d ctrl_TS=%d " - "MS_CLASS=%d%s", + "MS_CLASS=%d/%d%s", tbf->created_ts(), tbf->state_flags, tbf->first_ts, tbf->first_common_ts, tbf->control_ts, tbf->ms_class(), + tbf->ms() ? tbf->ms()->egprs_ms_class() : -1, VTY_NEWLINE); vty_out(vty, " TS_alloc="); for (int i = 0; i < 8; i++) { if (tbf->pdch[i]) vty_out(vty, "%d ", i); } - vty_out(vty, " CS=%s%s%s", - tbf->ms() ? tbf->ms()->current_cs_dl().name() : "???", + vty_out(vty, " CS=%s%s%s", tbf->current_cs().name(), VTY_NEWLINE, VTY_NEWLINE); } -- cgit v1.2.3 From 36df7740dd7f81fe36d35e808cc53f518f4e360e Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Tue, 19 Jan 2016 15:53:30 +0100 Subject: edge: Make window size configurable Currently the window size is fixed to 64 even for EGPRS. Support dynamic window sizes depending on the number of PDCH. The WS can be set to b + f * N_PDCH. If the result is not valid according to TS 44.060, Table 9.1.9.2.1, the value will be corrected to use the next lower valid value (or 64). The following VTY commands are added (config-pcu node): window-size <0-1024> set base (b) value and leave f unchanged window-size <0-1024> <0-256> set base (b) and factor (f) Sponsored-by: On-Waves ehf --- src/bts.h | 4 +-- src/encoding.cpp | 9 ++++-- src/pcu_main.cpp | 4 +++ src/pcu_vty.c | 24 +++++++++++++++ src/pcu_vty_functions.cpp | 3 +- src/tbf.cpp | 18 +++++++++++- tests/tbf/TbfTest.cpp | 56 +++++++++++++++++++++++++++++++++++ tests/tbf/TbfTest.err | 75 +++++++++++++++++++++++++++++++++++++++++++++++ tests/tbf/TbfTest.ok | 2 ++ 9 files changed, 189 insertions(+), 6 deletions(-) diff --git a/src/bts.h b/src/bts.h index c6247be9..14b6c1f8 100644 --- a/src/bts.h +++ b/src/bts.h @@ -188,8 +188,8 @@ struct gprs_rlcmac_bts { uint8_t cs_adj_lower_limit; struct {int16_t low; int16_t high;} cs_lqual_ranges[4]; uint16_t cs_downgrade_threshold; /* downgrade if less packets left (DL) */ - uint16_t egprs_ws_base; - uint16_t egprs_ws_lin; + uint16_t ws_base; + uint16_t ws_pdch; /* increase WS by this value per PDCH */ /* State for dynamic algorithm selection */ int multislot_disabled; diff --git a/src/encoding.cpp b/src/encoding.cpp index 9def2831..a26a5db4 100644 --- a/src/encoding.cpp +++ b/src/encoding.cpp @@ -208,13 +208,14 @@ void Encoding::write_packet_uplink_assignment( } } else { /* EPGRS */ + unsigned int ws_enc = (tbf->m_window.ws() - 64) / 32; bitvec_write_field(dest, wp,0x1,1); // Message escape bitvec_write_field(dest, wp,0x0,2); // EGPRS message contents bitvec_write_field(dest, wp,0x0,1); // No CONTENTION_RESOLUTION_TLLI bitvec_write_field(dest, wp,0x0,1); // No COMPACT reduced MA bitvec_write_field(dest, wp,tbf->current_cs().to_num()-1, 4); // EGPRS Modulation and Coding IE bitvec_write_field(dest, wp,0x0,1); // No RESEGMENT - bitvec_write_field(dest, wp,0x0,5); // EGPRS Window Size = 64 + bitvec_write_field(dest, wp,ws_enc,5); // EGPRS Window Size bitvec_write_field(dest, wp,0x0,1); // No Access Technologies Request bitvec_write_field(dest, wp,0x0,1); // No ARAC RETRANSMISSION REQUEST bitvec_write_field(dest, wp,0x1,1); // TLLI_BLOCK_CHANNEL_CODING @@ -282,6 +283,7 @@ void Encoding::write_packet_downlink_assignment(RlcMacDownlink_t * block, PDA_AdditionsR99_t *pda_r99; uint8_t tn; + unsigned int ws_enc; block->PAYLOAD_TYPE = 0x1; // RLC/MAC control block that does not include the optional octets of the RLC/MAC control header block->RRBP = 0x0; // N+13 @@ -348,10 +350,13 @@ void Encoding::write_packet_downlink_assignment(RlcMacDownlink_t * block, block->u.Packet_Downlink_Assignment.Exist_AdditionsR99 = 0x0; // AdditionsR99 = off return; } + + ws_enc = (tbf->window()->ws() - 64) / 32; + block->u.Packet_Downlink_Assignment.Exist_AdditionsR99 = 0x1; // AdditionsR99 = on pda_r99 = &block->u.Packet_Downlink_Assignment.AdditionsR99; pda_r99->Exist_EGPRS_Params = 1; - pda_r99->EGPRS_WindowSize = 0; /* 64, see TS 44.060, table 12.5.2.1 */ + pda_r99->EGPRS_WindowSize = ws_enc; /* see TS 44.060, table 12.5.2.1 */ pda_r99->LINK_QUALITY_MEASUREMENT_MODE = 0x0; /* no meas, see TS 44.060, table 11.2.7.2 */ pda_r99->Exist_BEP_PERIOD2 = 0; /* No extra EGPRS BEP PERIOD */ pda_r99->Exist_Packet_Extended_Timing_Advance = 0; diff --git a/src/pcu_main.cpp b/src/pcu_main.cpp index 39de0555..51a4eeec 100644 --- a/src/pcu_main.cpp +++ b/src/pcu_main.cpp @@ -193,6 +193,10 @@ int main(int argc, char *argv[]) bts->cs_lqual_ranges[3].high = 256; bts->cs_downgrade_threshold = 200; + /* TODO: increase them when CRBB decoding is implemented */ + bts->ws_base = 64; + bts->ws_pdch = 0; + bts->llc_codel_interval_msec = LLC_CODEL_USE_DEFAULT; bts->dl_tbf_idle_msec = 2000; bts->llc_idle_ack_csec = 10; diff --git a/src/pcu_vty.c b/src/pcu_vty.c index 97be4c72..b5ee1b55 100644 --- a/src/pcu_vty.c +++ b/src/pcu_vty.c @@ -118,6 +118,9 @@ static int config_write_pcu(struct vty *vty) bts->max_mcs_ul, VTY_NEWLINE); } + vty_out(vty, " window-size %d %d%s", bts->ws_base, bts->ws_pdch, + VTY_NEWLINE); + if (bts->force_llc_lifetime == 0xffff) vty_out(vty, " queue lifetime infinite%s", VTY_NEWLINE); else if (bts->force_llc_lifetime) @@ -437,6 +440,26 @@ DEFUN(cfg_pcu_no_mcs_max, return CMD_SUCCESS; } +DEFUN(cfg_pcu_window_size, + cfg_pcu_window_size_cmd, + "window-size <0-1024> [<0-256>]", + "Window size configuration (b + N_PDCH * f)\n" + "Base value (b)\n" + "Factor for number of PDCH (f)") +{ + struct gprs_rlcmac_bts *bts = bts_main_data(); + uint16_t b = atoi(argv[0]); + + bts->ws_base = b; + if (argc > 1) { + uint16_t f = atoi(argv[1]); + bts->ws_pdch = f; + } + + return CMD_SUCCESS; +} + + #define QUEUE_STR "Packet queue options\n" #define LIFETIME_STR "Set lifetime limit of LLC frame in centi-seconds " \ "(overrides the value given by SGSN)\n" @@ -892,6 +915,7 @@ int pcu_vty_init(const struct log_info *cat) install_element(PCU_NODE, &cfg_pcu_cs_lqual_ranges_cmd); install_element(PCU_NODE, &cfg_pcu_mcs_max_cmd); install_element(PCU_NODE, &cfg_pcu_no_mcs_max_cmd); + install_element(PCU_NODE, &cfg_pcu_window_size_cmd); install_element(PCU_NODE, &cfg_pcu_queue_lifetime_cmd); install_element(PCU_NODE, &cfg_pcu_queue_lifetime_inf_cmd); install_element(PCU_NODE, &cfg_pcu_no_queue_lifetime_cmd); diff --git a/src/pcu_vty_functions.cpp b/src/pcu_vty_functions.cpp index 2f7cb02a..66994ded 100644 --- a/src/pcu_vty_functions.cpp +++ b/src/pcu_vty_functions.cpp @@ -56,7 +56,8 @@ static void tbf_print_vty_info(struct vty *vty, gprs_rlcmac_tbf *tbf) if (tbf->pdch[i]) vty_out(vty, "%d ", i); } - vty_out(vty, " CS=%s%s%s", tbf->current_cs().name(), + vty_out(vty, " CS=%s WS=%d%s%s", + tbf->current_cs().name(), tbf->window()->ws(), VTY_NEWLINE, VTY_NEWLINE); } diff --git a/src/tbf.cpp b/src/tbf.cpp index 9f19c9b7..c852d665 100644 --- a/src/tbf.cpp +++ b/src/tbf.cpp @@ -28,6 +28,7 @@ #include #include #include +#include extern "C" { #include @@ -634,6 +635,7 @@ struct gprs_rlcmac_ul_tbf *tbf_alloc_ul_tbf(struct gprs_rlcmac_bts *bts, if (egprs_ms_class > 0 && bts->egprs_enabled) { tbf->enable_egprs(); tbf->m_window.set_sns(RLC_EGPRS_SNS); + /* TODO: Allow bigger UL windows when CRBB encoding is supported */ tbf->m_window.set_ws(RLC_EGPRS_MIN_WS); setup_egprs_mode(bts, ms); LOGP(DRLCMAC, LOGL_INFO, "Enabled EGPRS for %s, mode %s\n", @@ -714,7 +716,6 @@ struct gprs_rlcmac_dl_tbf *tbf_alloc_dl_tbf(struct gprs_rlcmac_bts *bts, if (egprs_ms_class > 0 && bts->egprs_enabled) { tbf->enable_egprs(); tbf->m_window.set_sns(RLC_EGPRS_SNS); - tbf->m_window.set_ws(RLC_EGPRS_MIN_WS); setup_egprs_mode(bts, ms); LOGP(DRLCMAC, LOGL_INFO, "Enabled EGPRS for %s, mode %s\n", tbf->name(), GprsCodingScheme::modeName(ms->mode())); @@ -727,6 +728,21 @@ struct gprs_rlcmac_dl_tbf *tbf_alloc_dl_tbf(struct gprs_rlcmac_bts *bts, return NULL; } + if (tbf->is_egprs_enabled()) { + unsigned int num_pdch = pcu_bitcount(tbf->dl_slots()); + unsigned int ws = bts->ws_base + num_pdch * bts->ws_pdch; + ws = (ws / 32) * 32; + ws = OSMO_MAX(64, ws); + if (num_pdch == 1) + ws = OSMO_MIN(192, ws); + else + ws = OSMO_MIN(128 * num_pdch, ws); + + LOGP(DRLCMAC, LOGL_INFO, "%s: Setting EGPRS window size to %d\n", + tbf->name(), ws); + tbf->m_window.set_ws(ws); + } + llist_add(&tbf->list(), &bts->bts->dl_tbfs()); tbf->bts->tbf_dl_created(); diff --git a/tests/tbf/TbfTest.cpp b/tests/tbf/TbfTest.cpp index 895ba8e5..c868ca2d 100644 --- a/tests/tbf/TbfTest.cpp +++ b/tests/tbf/TbfTest.cpp @@ -1105,6 +1105,61 @@ static void test_tbf_gprs_egprs() gprs_bssgp_destroy(); } +static void test_tbf_ws() +{ + BTS the_bts; + gprs_rlcmac_bts *bts; + uint8_t ts_no = 4; + uint8_t ms_class = 12; + gprs_rlcmac_dl_tbf *dl_tbf; + + printf("=== start %s ===\n", __func__); + + bts = the_bts.bts_data(); + setup_bts(&the_bts, ts_no); + + bts->ws_base = 128; + bts->ws_pdch = 64; + bts->alloc_algorithm = alloc_algorithm_b; + bts->trx[0].pdch[2].enable(); + bts->trx[0].pdch[3].enable(); + bts->trx[0].pdch[4].enable(); + bts->trx[0].pdch[5].enable(); + + gprs_bssgp_create_and_connect(bts, 33001, 0, 33001, + 1234, 1234, 1234, 1, 1, 0, 0, 0); + + /* Does no support EGPRS */ + dl_tbf = tbf_alloc_dl_tbf(bts, NULL, 0, ms_class, 0, 0); + OSMO_ASSERT(dl_tbf != NULL); + fprintf(stderr, "DL TBF slots: 0x%02x, N: %d, WS: %d\n", + dl_tbf->dl_slots(), + pcu_bitcount(dl_tbf->dl_slots()), + dl_tbf->window()->ws()); + OSMO_ASSERT(pcu_bitcount(dl_tbf->dl_slots()) == 4); + OSMO_ASSERT(dl_tbf->window()->ws() == 64); + tbf_free(dl_tbf); + + /* EGPRS-only */ + bts->egprs_enabled = 1; + + /* Does support EGPRS */ + dl_tbf = tbf_alloc_dl_tbf(bts, NULL, 0, ms_class, ms_class, 0); + + OSMO_ASSERT(dl_tbf != NULL); + fprintf(stderr, "DL TBF slots: 0x%02x, N: %d, WS: %d\n", + dl_tbf->dl_slots(), + pcu_bitcount(dl_tbf->dl_slots()), + dl_tbf->window()->ws()); + OSMO_ASSERT(pcu_bitcount(dl_tbf->dl_slots()) == 4); + OSMO_ASSERT(dl_tbf->window()->ws() == 128 + 4 * 64); + tbf_free(dl_tbf); + + printf("=== end %s ===\n", __func__); + + gprs_bssgp_destroy(); +} + static const struct log_info_cat default_categories[] = { {"DCSN1", "\033[1;31m", "Concrete Syntax Notation One (CSN1)", LOGL_INFO, 0}, {"DL1IF", "\033[1;32m", "GPRS PCU L1 interface (L1IF)", LOGL_DEBUG, 1}, @@ -1163,6 +1218,7 @@ int main(int argc, char **argv) test_tbf_dl_flow_and_rach_single_phase(); test_tbf_dl_reuse(); test_tbf_gprs_egprs(); + test_tbf_ws(); if (getenv("TALLOC_REPORT_FULL")) talloc_report_full(tall_pcu_ctx, stderr); diff --git a/tests/tbf/TbfTest.err b/tests/tbf/TbfTest.err index 0ca4b829..a93d959b 100644 --- a/tests/tbf/TbfTest.err +++ b/tests/tbf/TbfTest.err @@ -3041,3 +3041,78 @@ msg block (BSN 10, CS-1): 0f 03 14 4d 43 20 50 41 43 4b 45 54 20 30 39 20 28 54 Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654448 block=1 data=08 03 14 4d 43 20 50 41 43 4b 45 54 20 30 39 20 28 54 42 46 20 32 29 Not accepting non-EGPRS phone in EGPRS-only mode No PDCH resource +********** TBF starts here ********** +Allocating DL TBF: MS_CLASS=12/0 +Creating MS object, TLLI = 0x00000000 +Modifying MS object, TLLI = 0x00000000, MS class 0 -> 12 +Searching for first unallocated TFI: TRX=0 + Found TFI=0. +Slot Allocation (Algorithm B) for class 12 +- Rx=4 Tx=4 Sum Rx+Tx=5 Tta=2 Ttb=1 Tra=2 Trb=1 Type=1 +- Skipping TS 0, because not enabled +- Skipping TS 1, because not enabled +- Skipping TS 6, because not enabled +- Skipping TS 7, because not enabled +- Possible DL/UL slots: (TS=0)"..CCCC.."(TS=7) +- Selected DL slots: (TS=0)"..DDDD.."(TS=7) +Using 4 slots for DL +- Reserved DL/UL slots: (TS=0)"..DDCD.."(TS=7) +- Assigning DL TS 2 +PDCH(TS 2, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL), 1 TBFs, USFs = 00, TFIs = 00000001. +- Assigning DL TS 3 +PDCH(TS 3, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL), 1 TBFs, USFs = 00, TFIs = 00000001. +- Assigning DL TS 4 +PDCH(TS 4, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL), 1 TBFs, USFs = 00, TFIs = 00000001. +- Assigning DL TS 5 +PDCH(TS 5, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL), 1 TBFs, USFs = 00, TFIs = 00000001. +- Setting Control TS 4 +Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL) +Allocated TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL): trx = 0, ul_slots = 10, dl_slots = 3c +DL TBF slots: 0x3c, N: 4, WS: 64 +TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL) free +PDCH(TS 2, TRX 0): Detaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL), 0 TBFs, USFs = 00, TFIs = 00000000. +PDCH(TS 3, TRX 0): Detaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL), 0 TBFs, USFs = 00, TFIs = 00000000. +PDCH(TS 4, TRX 0): Detaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL), 0 TBFs, USFs = 00, TFIs = 00000000. +PDCH(TS 5, TRX 0): Detaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL), 0 TBFs, USFs = 00, TFIs = 00000000. +Detaching TBF from MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL) +Destroying MS object, TLLI = 0x00000000 +********** TBF ends here ********** +********** TBF starts here ********** +Allocating DL TBF: MS_CLASS=12/12 +Creating MS object, TLLI = 0x00000000 +Modifying MS object, TLLI = 0x00000000, MS class 0 -> 12 +Modifying MS object, TLLI = 0x00000000, EGPRS MS class 0 -> 12 +Enabled EGPRS for TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), mode EGPRS +Searching for first unallocated TFI: TRX=0 + Found TFI=0. +Slot Allocation (Algorithm B) for class 12 +- Rx=4 Tx=4 Sum Rx+Tx=5 Tta=2 Ttb=1 Tra=2 Trb=1 Type=1 +- Skipping TS 0, because not enabled +- Skipping TS 1, because not enabled +- Skipping TS 6, because not enabled +- Skipping TS 7, because not enabled +- Possible DL/UL slots: (TS=0)"..CCCC.."(TS=7) +- Selected DL slots: (TS=0)"..DDDD.."(TS=7) +Using 4 slots for DL +- Reserved DL/UL slots: (TS=0)"..DDCD.."(TS=7) +- Assigning DL TS 2 +PDCH(TS 2, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), 1 TBFs, USFs = 00, TFIs = 00000001. +- Assigning DL TS 3 +PDCH(TS 3, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), 1 TBFs, USFs = 00, TFIs = 00000001. +- Assigning DL TS 4 +PDCH(TS 4, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), 1 TBFs, USFs = 00, TFIs = 00000001. +- Assigning DL TS 5 +PDCH(TS 5, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), 1 TBFs, USFs = 00, TFIs = 00000001. +- Setting Control TS 4 +Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) +Allocated TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 10, dl_slots = 3c +TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 384 +DL TBF slots: 0x3c, N: 4, WS: 384 +TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) free +PDCH(TS 2, TRX 0): Detaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), 0 TBFs, USFs = 00, TFIs = 00000000. +PDCH(TS 3, TRX 0): Detaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), 0 TBFs, USFs = 00, TFIs = 00000000. +PDCH(TS 4, TRX 0): Detaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), 0 TBFs, USFs = 00, TFIs = 00000000. +PDCH(TS 5, TRX 0): Detaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), 0 TBFs, USFs = 00, TFIs = 00000000. +Detaching TBF from MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) +Destroying MS object, TLLI = 0x00000000 +********** TBF ends here ********** diff --git a/tests/tbf/TbfTest.ok b/tests/tbf/TbfTest.ok index c4bc8705..c6c4aea2 100644 --- a/tests/tbf/TbfTest.ok +++ b/tests/tbf/TbfTest.ok @@ -28,3 +28,5 @@ === end test_tbf_dl_reuse === === start test_tbf_gprs_egprs === === end test_tbf_gprs_egprs === +=== start test_tbf_ws === +=== end test_tbf_ws === -- cgit v1.2.3 From 9f6867033f19dd8d1e33100c5b80e9b70bddbe2a Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Tue, 19 Jan 2016 17:10:07 +0100 Subject: tbf: Show window parameters in VTY Add V(Q), V(R), V(A), V(S) to the output of the "show tbf" command. Sponsored-by: On-Waves ehf --- src/pcu_vty_functions.cpp | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/src/pcu_vty_functions.cpp b/src/pcu_vty_functions.cpp index 66994ded..a8b5ddd7 100644 --- a/src/pcu_vty_functions.cpp +++ b/src/pcu_vty_functions.cpp @@ -41,6 +41,9 @@ int pcu_vty_config_write_pcu_ext(struct vty *vty) static void tbf_print_vty_info(struct vty *vty, gprs_rlcmac_tbf *tbf) { + gprs_rlcmac_ul_tbf *ul_tbf = as_ul_tbf(tbf); + gprs_rlcmac_dl_tbf *dl_tbf = as_dl_tbf(tbf); + vty_out(vty, "TBF: TFI=%d TLLI=0x%08x (%s) DIR=%s IMSI=%s%s", tbf->tfi(), tbf->tlli(), tbf->is_tlli_valid() ? "valid" : "invalid", tbf->direction == GPRS_RLCMAC_UL_TBF ? "UL" : "DL", @@ -56,9 +59,21 @@ static void tbf_print_vty_info(struct vty *vty, gprs_rlcmac_tbf *tbf) if (tbf->pdch[i]) vty_out(vty, "%d ", i); } - vty_out(vty, " CS=%s WS=%d%s%s", - tbf->current_cs().name(), tbf->window()->ws(), - VTY_NEWLINE, VTY_NEWLINE); + vty_out(vty, " CS=%s WS=%d", + tbf->current_cs().name(), tbf->window()->ws()); + + if (ul_tbf) { + gprs_rlc_ul_window *win = &ul_tbf->m_window; + vty_out(vty, " V(Q)=%d V(R)=%d", + win->v_q(), win->v_r()); + } + if (dl_tbf) { + gprs_rlc_dl_window *win = &dl_tbf->m_window; + vty_out(vty, " V(A)=%d V(S)=%d nBSN=%d%s", + win->v_a(), win->v_s(), win->resend_needed(), + win->window_stalled() ? " STALLED" : ""); + } + vty_out(vty, "%s%s", VTY_NEWLINE, VTY_NEWLINE); } int pcu_vty_show_tbf_all(struct vty *vty, struct gprs_rlcmac_bts *bts_data) -- cgit v1.2.3 From a35122c496e153fbec8c943953aa7b78de8d154f Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Wed, 20 Jan 2016 12:30:07 +0100 Subject: bssgp: Add hand-coded extended RA Cap parser Add an extended parse_ra_cap function based on the existing parse_ra_cap_ms_class which also parses up to the EGPRS related fields. Sponsored-by: On-Waves ehf --- src/gprs_bssgp_pcu.cpp | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/src/gprs_bssgp_pcu.cpp b/src/gprs_bssgp_pcu.cpp index 838c667d..07d610c0 100644 --- a/src/gprs_bssgp_pcu.cpp +++ b/src/gprs_bssgp_pcu.cpp @@ -113,6 +113,72 @@ static int parse_ra_cap_ms_class(struct tlv_parsed *tp) return ms_class; } +struct gprs_ra_cap +{ + uint8_t ms_class; + uint8_t exist_egprs_ms_class; + uint8_t egprs_ms_class; + uint8_t support_8psk_uplink; +}; + +static int parse_ra_cap(struct tlv_parsed *tp, struct gprs_ra_cap *rac) __attribute__((__unused__)); +static int parse_ra_cap(struct tlv_parsed *tp, struct gprs_ra_cap *rac) +{ + bitvec *block; + unsigned rp = 0; + uint8_t ms_class = 0; + uint8_t cap_len; + uint8_t *cap; + + memset(rac, 0, sizeof(gprs_ra_cap)); + + if (!TLVP_PRESENT(tp, BSSGP_IE_MS_RADIO_ACCESS_CAP)) + return -EINVAL; + + cap_len = TLVP_LEN(tp, BSSGP_IE_MS_RADIO_ACCESS_CAP); + cap = (uint8_t *) TLVP_VAL(tp, BSSGP_IE_MS_RADIO_ACCESS_CAP); + + block = bitvec_alloc(cap_len); + bitvec_unpack(block, cap); + bitvec_read_field(block, rp, 4); // Access Technology Type + bitvec_read_field(block, rp, 7); // Length of Access Capabilities + bitvec_read_field(block, rp, 3); // RF Power Capability + if (bitvec_read_field(block, rp, 1)) // A5 Bits Present + bitvec_read_field(block, rp, 7); // A5 Bits + bitvec_read_field(block, rp, 1); // ES IND + bitvec_read_field(block, rp, 1); // PS + bitvec_read_field(block, rp, 1); // VGCS + bitvec_read_field(block, rp, 1); // VBS + if (bitvec_read_field(block, rp, 1)) { // Multislot Cap Present + if (bitvec_read_field(block, rp, 1)) // HSCSD Present + bitvec_read_field(block, rp, 5); // Class + if (bitvec_read_field(block, rp, 1)) { // GPRS Present + rac->ms_class = bitvec_read_field(block, rp, 5); // Class + bitvec_read_field(block, rp, 1); // Ext. + } + if (bitvec_read_field(block, rp, 1)) // SMS Present + bitvec_read_field(block, rp, 4); // SMS Value + /* Additions in release 99 */ + if (bitvec_read_field(block, rp, 1)) // ECSD multislot class Present + bitvec_read_field(block, rp, 5); // Class + if (bitvec_read_field(block, rp, 1)) { // EGPRS Present + rac->egprs_ms_class = bitvec_read_field(block, rp, 5); // Class + bitvec_read_field(block, rp, 1); // Ext. + } + if (bitvec_read_field(block, rp, 1)) { // DTM Present + bitvec_read_field(block, rp, 2); // GPRS Class + bitvec_read_field(block, rp, 1); // Single Slot DTM + if (bitvec_read_field(block, rp, 1)) // EGPRS Present + bitvec_read_field(block, rp, 2); // EGPRS Class + } + } + if (bitvec_read_field(block, rp, 1)) // 8PSK Power Cap Present + rac->support_8psk_uplink = bitvec_read_field(block, rp, 2); // Power Cap + + bitvec_free(block); + return ms_class; +} + static int gprs_bssgp_pcu_rx_dl_ud(struct msgb *msg, struct tlv_parsed *tp) { struct bssgp_ud_hdr *budh; -- cgit v1.2.3 From acf66fb45612888c1eac3f03707a2928103fb1f3 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Fri, 5 Feb 2016 18:59:00 +0100 Subject: Revert "bssgp: Add hand-coded extended RA Cap parser" Just keep this for later reference, since a CSN.1 decoder based implementation will be used. This reverts commit b37ab36bb14d2d2c1363fbe521cd19984d0c3d4c. --- src/gprs_bssgp_pcu.cpp | 66 -------------------------------------------------- 1 file changed, 66 deletions(-) diff --git a/src/gprs_bssgp_pcu.cpp b/src/gprs_bssgp_pcu.cpp index 07d610c0..838c667d 100644 --- a/src/gprs_bssgp_pcu.cpp +++ b/src/gprs_bssgp_pcu.cpp @@ -113,72 +113,6 @@ static int parse_ra_cap_ms_class(struct tlv_parsed *tp) return ms_class; } -struct gprs_ra_cap -{ - uint8_t ms_class; - uint8_t exist_egprs_ms_class; - uint8_t egprs_ms_class; - uint8_t support_8psk_uplink; -}; - -static int parse_ra_cap(struct tlv_parsed *tp, struct gprs_ra_cap *rac) __attribute__((__unused__)); -static int parse_ra_cap(struct tlv_parsed *tp, struct gprs_ra_cap *rac) -{ - bitvec *block; - unsigned rp = 0; - uint8_t ms_class = 0; - uint8_t cap_len; - uint8_t *cap; - - memset(rac, 0, sizeof(gprs_ra_cap)); - - if (!TLVP_PRESENT(tp, BSSGP_IE_MS_RADIO_ACCESS_CAP)) - return -EINVAL; - - cap_len = TLVP_LEN(tp, BSSGP_IE_MS_RADIO_ACCESS_CAP); - cap = (uint8_t *) TLVP_VAL(tp, BSSGP_IE_MS_RADIO_ACCESS_CAP); - - block = bitvec_alloc(cap_len); - bitvec_unpack(block, cap); - bitvec_read_field(block, rp, 4); // Access Technology Type - bitvec_read_field(block, rp, 7); // Length of Access Capabilities - bitvec_read_field(block, rp, 3); // RF Power Capability - if (bitvec_read_field(block, rp, 1)) // A5 Bits Present - bitvec_read_field(block, rp, 7); // A5 Bits - bitvec_read_field(block, rp, 1); // ES IND - bitvec_read_field(block, rp, 1); // PS - bitvec_read_field(block, rp, 1); // VGCS - bitvec_read_field(block, rp, 1); // VBS - if (bitvec_read_field(block, rp, 1)) { // Multislot Cap Present - if (bitvec_read_field(block, rp, 1)) // HSCSD Present - bitvec_read_field(block, rp, 5); // Class - if (bitvec_read_field(block, rp, 1)) { // GPRS Present - rac->ms_class = bitvec_read_field(block, rp, 5); // Class - bitvec_read_field(block, rp, 1); // Ext. - } - if (bitvec_read_field(block, rp, 1)) // SMS Present - bitvec_read_field(block, rp, 4); // SMS Value - /* Additions in release 99 */ - if (bitvec_read_field(block, rp, 1)) // ECSD multislot class Present - bitvec_read_field(block, rp, 5); // Class - if (bitvec_read_field(block, rp, 1)) { // EGPRS Present - rac->egprs_ms_class = bitvec_read_field(block, rp, 5); // Class - bitvec_read_field(block, rp, 1); // Ext. - } - if (bitvec_read_field(block, rp, 1)) { // DTM Present - bitvec_read_field(block, rp, 2); // GPRS Class - bitvec_read_field(block, rp, 1); // Single Slot DTM - if (bitvec_read_field(block, rp, 1)) // EGPRS Present - bitvec_read_field(block, rp, 2); // EGPRS Class - } - } - if (bitvec_read_field(block, rp, 1)) // 8PSK Power Cap Present - rac->support_8psk_uplink = bitvec_read_field(block, rp, 2); // Power Cap - - bitvec_free(block); - return ms_class; -} - static int gprs_bssgp_pcu_rx_dl_ud(struct msgb *msg, struct tlv_parsed *tp) { struct bssgp_ud_hdr *budh; -- cgit v1.2.3 From 0df80be95e3604656ff36024f793ef3c36455051 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Wed, 20 Jan 2016 12:14:55 +0100 Subject: rlc: Add decode_gsm_ra_cap to decode Radio Access Caps This uses the CSN.1 decoder to fully parse the radio access capabilities as defined by TS 24.008, 10.5.5.12a. Sponsored-by: On-Waves ehf --- src/gsm_rlcmac.cpp | 8 ++++++++ src/gsm_rlcmac.h | 1 + 2 files changed, 9 insertions(+) diff --git a/src/gsm_rlcmac.cpp b/src/gsm_rlcmac.cpp index 44bc5e13..6b43aa6d 100644 --- a/src/gsm_rlcmac.cpp +++ b/src/gsm_rlcmac.cpp @@ -5509,3 +5509,11 @@ void encode_gsm_rlcmac_downlink_data(bitvec * vector, RlcMacDownlinkDataBlock_t LOGPC(DRLCMACDATA, LOGL_NOTICE, "\n"); } } + +void decode_gsm_ra_cap(bitvec * vector, MS_Radio_Access_capability_t *data) +{ + csnStream_t ar; + unsigned readIndex = 0; + csnStreamInit(&ar, 0, 8 * vector->data_len); + /*ret =*/ csnStreamDecoder(&ar, CSNDESCR(MS_Radio_Access_capability_t), vector, readIndex, data); +} diff --git a/src/gsm_rlcmac.h b/src/gsm_rlcmac.h index 49c596dc..8f4039c5 100644 --- a/src/gsm_rlcmac.h +++ b/src/gsm_rlcmac.h @@ -5136,4 +5136,5 @@ typedef struct void encode_gsm_rlcmac_uplink(bitvec * vector, RlcMacUplink_t * data); void decode_gsm_rlcmac_uplink_data(bitvec * vector, RlcMacUplinkDataBlock_t * data); void encode_gsm_rlcmac_downlink_data(bitvec * vector, RlcMacDownlinkDataBlock_t * data); + void decode_gsm_ra_cap(bitvec * vector, MS_Radio_Access_capability_t * data); #endif /* __PACKET_GSM_RLCMAC_H__ */ -- cgit v1.2.3 From 4a07a3be11e7366b557bab795aa23b42725ec23e Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Wed, 20 Jan 2016 12:22:07 +0100 Subject: edge: Get EGPRS MS class from downlink BSSGP In case there is no MS object present that matches a DL UNITDATA, the EGPRS class is currently assumed to be 0, since the Radio Access Capabilities IE is not fully decoded if present. This commit uses the CSN.1 decoder to parse the IE and uses the same functions like the uplink related code does to get the GPRS and EGPRS multislot classes. Remove the old parse_ra_cap_ms_class function. Sponsored-by: On-Waves ehf --- src/gprs_bssgp_pcu.cpp | 49 ++++++++++++++++++++++--------------------------- 1 file changed, 22 insertions(+), 27 deletions(-) diff --git a/src/gprs_bssgp_pcu.cpp b/src/gprs_bssgp_pcu.cpp index 838c667d..c66dbae4 100644 --- a/src/gprs_bssgp_pcu.cpp +++ b/src/gprs_bssgp_pcu.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #define BSSGP_TIMER_T1 30 /* Guards the (un)blocking procedures */ #define BSSGP_TIMER_T2 30 /* Guards the reset procedure */ @@ -73,44 +74,30 @@ static int parse_imsi(struct tlv_parsed *tp, char *imsi) return 0; } -static int parse_ra_cap_ms_class(struct tlv_parsed *tp) +static int parse_ra_cap(struct tlv_parsed *tp, MS_Radio_Access_capability_t *rac) { bitvec *block; - unsigned rp = 0; - uint8_t ms_class = 0; uint8_t cap_len; uint8_t *cap; + memset(rac, 0, sizeof(*rac)); + if (!TLVP_PRESENT(tp, BSSGP_IE_MS_RADIO_ACCESS_CAP)) - return ms_class; + return -EINVAL; cap_len = TLVP_LEN(tp, BSSGP_IE_MS_RADIO_ACCESS_CAP); cap = (uint8_t *) TLVP_VAL(tp, BSSGP_IE_MS_RADIO_ACCESS_CAP); + LOGP(DBSSGP, LOGL_DEBUG, "Got BSSGP RA Capability of size %d\n", cap_len); + block = bitvec_alloc(cap_len); bitvec_unpack(block, cap); - bitvec_read_field(block, rp, 4); // Access Technology Type - bitvec_read_field(block, rp, 7); // Length of Access Capabilities - bitvec_read_field(block, rp, 3); // RF Power Capability - if (bitvec_read_field(block, rp, 1)) // A5 Bits Present - bitvec_read_field(block, rp, 7); // A5 Bits - bitvec_read_field(block, rp, 1); // ES IND - bitvec_read_field(block, rp, 1); // PS - bitvec_read_field(block, rp, 1); // VGCS - bitvec_read_field(block, rp, 1); // VBS - if (bitvec_read_field(block, rp, 1)) { // Multislot Cap Present - if (bitvec_read_field(block, rp, 1)) // HSCSD Present - bitvec_read_field(block, rp, 5); // Class - if (bitvec_read_field(block, rp, 1)) { // GPRS Present - ms_class = bitvec_read_field(block, rp, 5); // Class - bitvec_read_field(block, rp, 1); // Ext. - } - if (bitvec_read_field(block, rp, 1)) // SMS Present - bitvec_read_field(block, rp, 4); // SMS Value - } + + /* TS 24.008, 10.5.5.12a */ + decode_gsm_ra_cap(block, rac); bitvec_free(block); - return ms_class; + return 0; } static int gprs_bssgp_pcu_rx_dl_ud(struct msgb *msg, struct tlv_parsed *tp) @@ -122,6 +109,9 @@ static int gprs_bssgp_pcu_rx_dl_ud(struct msgb *msg, struct tlv_parsed *tp) uint8_t *data; uint16_t len; char imsi[16] = "000"; + uint8_t ms_class = 0; + uint8_t egprs_ms_class = 0; + MS_Radio_Access_capability_t rac; budh = (struct bssgp_ud_hdr *)msgb_bssgph(msg); tlli = ntohl(budh->tlli); @@ -147,9 +137,14 @@ static int gprs_bssgp_pcu_rx_dl_ud(struct msgb *msg, struct tlv_parsed *tp) parse_imsi(tp, imsi); /* parse ms radio access capability */ - uint8_t ms_class = parse_ra_cap_ms_class(tp); - /* TODO: Get the EGPRS class from the CSN.1 RA capability */ - uint8_t egprs_ms_class = 0; + if (parse_ra_cap(tp, &rac) >= 0) { + /* Get the EGPRS class from the RA capability */ + ms_class = Decoding::get_ms_class_by_capability(&rac); + egprs_ms_class = + Decoding::get_egprs_ms_class_by_capability(&rac); + LOGP(DBSSGP, LOGL_DEBUG, "Got downlink MS class %d/%d\n", + ms_class, egprs_ms_class); + } /* get lifetime */ uint16_t delay_csec = 0xffff; -- cgit v1.2.3 From f4bb42459ca4f3e18f9ee3d3a27389b85c7692e8 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Wed, 20 Jan 2016 13:30:34 +0100 Subject: tbf: Low prio for BSSPG values for GPRS/EGPRS MS class Currently the values in the BSSGP RA Cap IE are eventually use overwrite the 'good' values obtained from the MS earlier. Use the 'good' values when the are present, which is assumed if at least one of ms->ms_class() or ms->egprs_ms_class() is set. Sponsored-by: On-Waves ehf --- src/tbf_dl.cpp | 13 ++++++++----- tests/tbf/TbfTest.err | 20 ++++++++++---------- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/src/tbf_dl.cpp b/src/tbf_dl.cpp index 1827469b..a55f179e 100644 --- a/src/tbf_dl.cpp +++ b/src/tbf_dl.cpp @@ -181,7 +181,7 @@ static int tbf_new_dl_assignment(struct gprs_rlcmac_bts *bts, */ int gprs_rlcmac_dl_tbf::handle(struct gprs_rlcmac_bts *bts, const uint32_t tlli, const uint32_t tlli_old, const char *imsi, - const uint8_t ms_class, uint8_t egprs_ms_class, + uint8_t ms_class, uint8_t egprs_ms_class, const uint16_t delay_csec, const uint8_t *data, const uint16_t len) { @@ -191,12 +191,15 @@ int gprs_rlcmac_dl_tbf::handle(struct gprs_rlcmac_bts *bts, /* check for existing TBF */ ms = bts->bts->ms_store().get_ms(tlli, tlli_old, imsi); - if (ms) + if (ms) { dl_tbf = ms->dl_tbf(); - /* Work-around to get EGPRS MS class */ - if (ms && !egprs_ms_class) - egprs_ms_class = ms->egprs_ms_class(); + /* If we known the GPRS/EGPRS MS class, use it */ + if (ms->ms_class() || ms->egprs_ms_class()) { + ms_class = ms->ms_class(); + egprs_ms_class = ms->egprs_ms_class(); + } + } if (ms && strlen(ms->imsi()) == 0) { ms_old = bts->bts->ms_store().get_ms(0, 0, imsi); diff --git a/tests/tbf/TbfTest.err b/tests/tbf/TbfTest.err index a93d959b..36410149 100644 --- a/tests/tbf/TbfTest.err +++ b/tests/tbf/TbfTest.err @@ -1532,8 +1532,8 @@ TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW): data_length=20, data=00 00 00 00 0 Got 'TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW)', TA=7 Got MS: TLLI = 0xf1223344, TA = 7 ********** TBF starts here ********** -Allocating DL TBF: MS_CLASS=0/0 -Slot Allocation (Algorithm A) for class 0 +Allocating DL TBF: MS_CLASS=1/0 +Slot Allocation (Algorithm A) for class 1 - Skipping TS 0, because not enabled - Skipping TS 1, because not enabled - Skipping TS 2, because not enabled @@ -1614,8 +1614,8 @@ TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW): data_length=20, data=00 00 00 00 0 - No gaps in received block, last block: BSN=0 CV=15 Got 'TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW)', TA=7 ********** TBF starts here ********** -Allocating DL TBF: MS_CLASS=0/0 -Slot Allocation (Algorithm A) for class 0 +Allocating DL TBF: MS_CLASS=1/0 +Slot Allocation (Algorithm A) for class 1 - Skipping TS 0, because not enabled - Skipping TS 1, because not enabled - Skipping TS 2, because not enabled @@ -1814,8 +1814,8 @@ TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW): data_length=20, data=00 00 00 00 0 - No gaps in received block, last block: BSN=0 CV=15 Got 'TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW)', TA=7 ********** TBF starts here ********** -Allocating DL TBF: MS_CLASS=0/0 -Slot Allocation (Algorithm A) for class 0 +Allocating DL TBF: MS_CLASS=1/0 +Slot Allocation (Algorithm A) for class 1 - Skipping TS 0, because not enabled - Skipping TS 1, because not enabled - Skipping TS 2, because not enabled @@ -1983,8 +1983,8 @@ TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW): data_length=20, data=00 00 00 00 0 - No gaps in received block, last block: BSN=0 CV=15 Got 'TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW)', TA=7 ********** TBF starts here ********** -Allocating DL TBF: MS_CLASS=0/0 -Slot Allocation (Algorithm A) for class 0 +Allocating DL TBF: MS_CLASS=1/0 +Slot Allocation (Algorithm A) for class 1 - Skipping TS 0, because not enabled - Skipping TS 1, because not enabled - Skipping TS 2, because not enabled @@ -2129,8 +2129,8 @@ TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW): data_length=20, data=00 00 00 00 0 - No gaps in received block, last block: BSN=0 CV=15 Got 'TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW)', TA=7 ********** TBF starts here ********** -Allocating DL TBF: MS_CLASS=0/0 -Slot Allocation (Algorithm A) for class 0 +Allocating DL TBF: MS_CLASS=1/0 +Slot Allocation (Algorithm A) for class 1 - Skipping TS 0, because not enabled - Skipping TS 1, because not enabled - Skipping TS 2, because not enabled -- cgit v1.2.3 From 741d25cb6f8c0c1522cf6d1be2fea49356ecd4bd Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Wed, 20 Jan 2016 13:38:15 +0100 Subject: bssgp: Ignore downlink BSSGP RA Cap IE That IE may contain inaccurate or completely bogus data. This commit disables the parsing. Note that this should be replaced by a config option. Sponsored-by: On-Waves ehf --- src/gprs_bssgp_pcu.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/gprs_bssgp_pcu.cpp b/src/gprs_bssgp_pcu.cpp index c66dbae4..5eefdefd 100644 --- a/src/gprs_bssgp_pcu.cpp +++ b/src/gprs_bssgp_pcu.cpp @@ -111,7 +111,9 @@ static int gprs_bssgp_pcu_rx_dl_ud(struct msgb *msg, struct tlv_parsed *tp) char imsi[16] = "000"; uint8_t ms_class = 0; uint8_t egprs_ms_class = 0; +#if 0 MS_Radio_Access_capability_t rac; +#endif budh = (struct bssgp_ud_hdr *)msgb_bssgph(msg); tlli = ntohl(budh->tlli); @@ -136,6 +138,7 @@ static int gprs_bssgp_pcu_rx_dl_ud(struct msgb *msg, struct tlv_parsed *tp) * will listen to all paging blocks. */ parse_imsi(tp, imsi); +#if 0 /* Do not rely on this IE. TODO: make this configurable */ /* parse ms radio access capability */ if (parse_ra_cap(tp, &rac) >= 0) { /* Get the EGPRS class from the RA capability */ @@ -145,6 +148,7 @@ static int gprs_bssgp_pcu_rx_dl_ud(struct msgb *msg, struct tlv_parsed *tp) LOGP(DBSSGP, LOGL_DEBUG, "Got downlink MS class %d/%d\n", ms_class, egprs_ms_class); } +#endif /* get lifetime */ uint16_t delay_csec = 0xffff; -- cgit v1.2.3 From 2ca86afdecd49d20fb8cd262a5540e9b4b8c0215 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Wed, 20 Jan 2016 18:26:13 +0100 Subject: tbf: Refactor calls to write_immediate_assignment Make use of variables, log them to LOGL_DEBUG, and reduce code duplication. This should help to narrow down the cause why snd_dl_ass are not answered by the MS sometimes. Sponsored-by: On-Waves ehf --- src/bts.cpp | 45 +++++++++++++++++++++++++++++++-------------- tests/tbf/TbfTest.err | 44 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+), 14 deletions(-) diff --git a/src/bts.cpp b/src/bts.cpp index 1c10596c..0d3e32a8 100644 --- a/src/bts.cpp +++ b/src/bts.cpp @@ -465,6 +465,10 @@ int BTS::rcv_rach(uint8_t ra, uint32_t Fn, int16_t qta) uint32_t sb_fn = 0; int rc; uint8_t plen; + uint8_t tfi = 0; + uint8_t usf = 7; + uint8_t tsc; + uint16_t ta; rach_frame(); @@ -483,8 +487,11 @@ int BTS::rcv_rach(uint8_t ra, uint32_t Fn, int16_t qta) qta = 0; if (qta > 252) qta = 252; + + ta = qta >> 2; + if (sb) { - rc = sba()->alloc(&trx_no, &ts_no, &sb_fn, qta >> 2); + rc = sba()->alloc(&trx_no, &ts_no, &sb_fn, ta); if (rc < 0) return rc; LOGP(DRLCMAC, LOGL_DEBUG, "RX: [PCU <- BTS] RACH qbit-ta=%d " @@ -494,6 +501,7 @@ int BTS::rcv_rach(uint8_t ra, uint32_t Fn, int16_t qta) sb_fn); LOGP(DRLCMAC, LOGL_INFO, "TX: Immediate Assignment Uplink " "(AGCH)\n"); + tsc = m_bts.trx[trx_no].pdch[ts_no].tsc; } else { // Create new TBF #warning "Copy and pate with other routines.." @@ -504,7 +512,7 @@ int BTS::rcv_rach(uint8_t ra, uint32_t Fn, int16_t qta) /* FIXME: send reject */ return -EBUSY; } - tbf->set_ta(qta >> 2); + tbf->set_ta(ta); tbf->set_state(GPRS_RLCMAC_FLOW); tbf->state_flags |= (1 << GPRS_RLCMAC_FLAG_CCCH); tbf_timer_start(tbf, 3169, m_bts.t3169, 0); @@ -516,20 +524,25 @@ int BTS::rcv_rach(uint8_t ra, uint32_t Fn, int16_t qta) qta, ra, Fn, (Fn / (26 * 51)) % 32, Fn % 51, Fn % 26); LOGP(DRLCMAC, LOGL_INFO, "%s TX: START Immediate " "Assignment Uplink (AGCH)\n", tbf_name(tbf)); + trx_no = tbf->trx->trx_no; + ts_no = tbf->first_ts; + tfi = tbf->tfi(); + usf = tbf->m_usf[ts_no]; + tsc = tbf->tsc(); } bitvec *immediate_assignment = bitvec_alloc(22) /* without plen */; bitvec_unhex(immediate_assignment, "2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b"); - if (sb) - plen = Encoding::write_immediate_assignment(&m_bts, immediate_assignment, 0, ra, - Fn, qta >> 2, m_bts.trx[trx_no].arfcn, ts_no, - m_bts.trx[trx_no].pdch[ts_no].tsc, 0, 0, 0, 0, sb_fn, 1, - m_bts.alpha, m_bts.gamma, -1); - else - plen = Encoding::write_immediate_assignment(&m_bts, immediate_assignment, 0, ra, - Fn, tbf->ta(), tbf->trx->arfcn, tbf->first_ts, tbf->tsc(), - tbf->tfi(), tbf->m_usf[tbf->first_ts], 0, 0, 0, 0, - m_bts.alpha, m_bts.gamma, -1); + + LOGP(DRLCMAC, LOGL_DEBUG, + " - TRX=%d (%d) TS=%d TA=%d TSC=%d TFI=%d USF=%d\n", + trx_no, m_bts.trx[trx_no].arfcn, ts_no, ta, tsc, tfi, usf); + + plen = Encoding::write_immediate_assignment( + &m_bts, immediate_assignment, 0, ra, Fn, ta, + m_bts.trx[trx_no].arfcn, ts_no, tsc, tfi, usf, 0, 0, sb_fn, sb, + m_bts.alpha, m_bts.gamma, -1); + pcu_l1if_tx_agch(immediate_assignment, plen); bitvec_free(immediate_assignment); @@ -572,15 +585,19 @@ void BTS::trigger_dl_ass( void BTS::snd_dl_ass(gprs_rlcmac_tbf *tbf, uint8_t poll, const char *imsi) { int plen; + unsigned int ts = tbf->first_ts; LOGP(DRLCMAC, LOGL_INFO, "TX: START %s Immediate Assignment Downlink (PCH)\n", tbf_name(tbf)); bitvec *immediate_assignment = bitvec_alloc(22); /* without plen */ bitvec_unhex(immediate_assignment, "2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b"); /* use request reference that has maximum distance to current time, * so the assignment will not conflict with possible RACH requests. */ + LOGP(DRLCMAC, LOGL_DEBUG, " - TRX=%d (%d) TS=%d TA=%d pollFN=%d\n", + tbf->trx->trx_no, tbf->trx->arfcn, + ts, tbf->ta(), poll ? tbf->poll_fn : -1); plen = Encoding::write_immediate_assignment(&m_bts, immediate_assignment, 1, 125, - (tbf->pdch[tbf->first_ts]->last_rts_fn + 21216) % 2715648, tbf->ta(), - tbf->trx->arfcn, tbf->first_ts, tbf->tsc(), tbf->tfi(), 0, tbf->tlli(), poll, + (tbf->pdch[ts]->last_rts_fn + 21216) % 2715648, tbf->ta(), + tbf->trx->arfcn, ts, tbf->tsc(), tbf->tfi(), 7, tbf->tlli(), poll, tbf->poll_fn, 0, m_bts.alpha, m_bts.gamma, -1); pcu_l1if_tx_pch(immediate_assignment, plen, imsi); bitvec_free(immediate_assignment); diff --git a/tests/tbf/TbfTest.err b/tests/tbf/TbfTest.err index 36410149..bbd5a82c 100644 --- a/tests/tbf/TbfTest.err +++ b/tests/tbf/TbfTest.err @@ -531,6 +531,7 @@ Modifying MS object, TLLI = 0xc0000000, IMSI '' -> '001001000000000' Send dowlink assignment for TBF(TFI=0 TLLI=0xc0000000 DIR=DL STATE=NULL) on PCH, no TBF exist (IMSI=001001000000000) TBF(TFI=0 TLLI=0xc0000000 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=0 TLLI=0xc0000000 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) + - TRX=0 (0) TS=4 TA=0 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 30 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 00 08 00 23 2b 2b 2b 2b TBF(TFI=0 TLLI=0xc0000000 DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** @@ -556,6 +557,7 @@ Modifying MS object, TLLI = 0xc0000001, IMSI '' -> '001001000000001' Send dowlink assignment for TBF(TFI=1 TLLI=0xc0000001 DIR=DL STATE=NULL) on PCH, no TBF exist (IMSI=001001000000001) TBF(TFI=1 TLLI=0xc0000001 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=1 TLLI=0xc0000001 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) + - TRX=0 (0) TS=4 TA=0 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 31 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 00 18 40 23 2b 2b 2b 2b TBF(TFI=1 TLLI=0xc0000001 DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** @@ -581,6 +583,7 @@ Modifying MS object, TLLI = 0xc0000002, IMSI '' -> '001001000000002' Send dowlink assignment for TBF(TFI=2 TLLI=0xc0000002 DIR=DL STATE=NULL) on PCH, no TBF exist (IMSI=001001000000002) TBF(TFI=2 TLLI=0xc0000002 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=2 TLLI=0xc0000002 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) + - TRX=0 (0) TS=4 TA=0 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 32 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 00 28 80 23 2b 2b 2b 2b TBF(TFI=2 TLLI=0xc0000002 DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** @@ -606,6 +609,7 @@ Modifying MS object, TLLI = 0xc0000003, IMSI '' -> '001001000000003' Send dowlink assignment for TBF(TFI=3 TLLI=0xc0000003 DIR=DL STATE=NULL) on PCH, no TBF exist (IMSI=001001000000003) TBF(TFI=3 TLLI=0xc0000003 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=3 TLLI=0xc0000003 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) + - TRX=0 (0) TS=4 TA=0 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 33 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 00 38 c0 23 2b 2b 2b 2b TBF(TFI=3 TLLI=0xc0000003 DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** @@ -631,6 +635,7 @@ Modifying MS object, TLLI = 0xc0000004, IMSI '' -> '001001000000004' Send dowlink assignment for TBF(TFI=4 TLLI=0xc0000004 DIR=DL STATE=NULL) on PCH, no TBF exist (IMSI=001001000000004) TBF(TFI=4 TLLI=0xc0000004 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=4 TLLI=0xc0000004 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) + - TRX=0 (0) TS=4 TA=0 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 34 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 00 49 00 23 2b 2b 2b 2b TBF(TFI=4 TLLI=0xc0000004 DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** @@ -656,6 +661,7 @@ Modifying MS object, TLLI = 0xc0000005, IMSI '' -> '001001000000005' Send dowlink assignment for TBF(TFI=5 TLLI=0xc0000005 DIR=DL STATE=NULL) on PCH, no TBF exist (IMSI=001001000000005) TBF(TFI=5 TLLI=0xc0000005 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=5 TLLI=0xc0000005 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) + - TRX=0 (0) TS=4 TA=0 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 35 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 00 59 40 23 2b 2b 2b 2b TBF(TFI=5 TLLI=0xc0000005 DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** @@ -681,6 +687,7 @@ Modifying MS object, TLLI = 0xc0000006, IMSI '' -> '001001000000006' Send dowlink assignment for TBF(TFI=6 TLLI=0xc0000006 DIR=DL STATE=NULL) on PCH, no TBF exist (IMSI=001001000000006) TBF(TFI=6 TLLI=0xc0000006 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=6 TLLI=0xc0000006 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) + - TRX=0 (0) TS=4 TA=0 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 36 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 00 69 80 23 2b 2b 2b 2b TBF(TFI=6 TLLI=0xc0000006 DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** @@ -706,6 +713,7 @@ Modifying MS object, TLLI = 0xc0000007, IMSI '' -> '001001000000007' Send dowlink assignment for TBF(TFI=7 TLLI=0xc0000007 DIR=DL STATE=NULL) on PCH, no TBF exist (IMSI=001001000000007) TBF(TFI=7 TLLI=0xc0000007 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=7 TLLI=0xc0000007 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) + - TRX=0 (0) TS=4 TA=0 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 37 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 00 79 c0 23 2b 2b 2b 2b TBF(TFI=7 TLLI=0xc0000007 DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** @@ -731,6 +739,7 @@ Modifying MS object, TLLI = 0xc0000008, IMSI '' -> '001001000000008' Send dowlink assignment for TBF(TFI=8 TLLI=0xc0000008 DIR=DL STATE=NULL) on PCH, no TBF exist (IMSI=001001000000008) TBF(TFI=8 TLLI=0xc0000008 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=8 TLLI=0xc0000008 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) + - TRX=0 (0) TS=4 TA=0 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 38 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 00 8a 00 23 2b 2b 2b 2b TBF(TFI=8 TLLI=0xc0000008 DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** @@ -756,6 +765,7 @@ Modifying MS object, TLLI = 0xc0000009, IMSI '' -> '001001000000009' Send dowlink assignment for TBF(TFI=9 TLLI=0xc0000009 DIR=DL STATE=NULL) on PCH, no TBF exist (IMSI=001001000000009) TBF(TFI=9 TLLI=0xc0000009 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=9 TLLI=0xc0000009 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) + - TRX=0 (0) TS=4 TA=0 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 39 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 00 9a 40 23 2b 2b 2b 2b TBF(TFI=9 TLLI=0xc0000009 DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** @@ -781,6 +791,7 @@ Modifying MS object, TLLI = 0xc000000a, IMSI '' -> '001001000000010' Send dowlink assignment for TBF(TFI=10 TLLI=0xc000000a DIR=DL STATE=NULL) on PCH, no TBF exist (IMSI=001001000000010) TBF(TFI=10 TLLI=0xc000000a DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=10 TLLI=0xc000000a DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) + - TRX=0 (0) TS=4 TA=0 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 30 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 00 aa 80 23 2b 2b 2b 2b TBF(TFI=10 TLLI=0xc000000a DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** @@ -806,6 +817,7 @@ Modifying MS object, TLLI = 0xc000000b, IMSI '' -> '001001000000011' Send dowlink assignment for TBF(TFI=11 TLLI=0xc000000b DIR=DL STATE=NULL) on PCH, no TBF exist (IMSI=001001000000011) TBF(TFI=11 TLLI=0xc000000b DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=11 TLLI=0xc000000b DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) + - TRX=0 (0) TS=4 TA=0 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 31 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 00 ba c0 23 2b 2b 2b 2b TBF(TFI=11 TLLI=0xc000000b DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** @@ -831,6 +843,7 @@ Modifying MS object, TLLI = 0xc000000c, IMSI '' -> '001001000000012' Send dowlink assignment for TBF(TFI=12 TLLI=0xc000000c DIR=DL STATE=NULL) on PCH, no TBF exist (IMSI=001001000000012) TBF(TFI=12 TLLI=0xc000000c DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=12 TLLI=0xc000000c DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) + - TRX=0 (0) TS=4 TA=0 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 32 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 00 cb 00 23 2b 2b 2b 2b TBF(TFI=12 TLLI=0xc000000c DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** @@ -856,6 +869,7 @@ Modifying MS object, TLLI = 0xc000000d, IMSI '' -> '001001000000013' Send dowlink assignment for TBF(TFI=13 TLLI=0xc000000d DIR=DL STATE=NULL) on PCH, no TBF exist (IMSI=001001000000013) TBF(TFI=13 TLLI=0xc000000d DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=13 TLLI=0xc000000d DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) + - TRX=0 (0) TS=4 TA=0 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 33 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 00 db 40 23 2b 2b 2b 2b TBF(TFI=13 TLLI=0xc000000d DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** @@ -881,6 +895,7 @@ Modifying MS object, TLLI = 0xc000000e, IMSI '' -> '001001000000014' Send dowlink assignment for TBF(TFI=14 TLLI=0xc000000e DIR=DL STATE=NULL) on PCH, no TBF exist (IMSI=001001000000014) TBF(TFI=14 TLLI=0xc000000e DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=14 TLLI=0xc000000e DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) + - TRX=0 (0) TS=4 TA=0 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 34 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 00 eb 80 23 2b 2b 2b 2b TBF(TFI=14 TLLI=0xc000000e DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** @@ -906,6 +921,7 @@ Modifying MS object, TLLI = 0xc000000f, IMSI '' -> '001001000000015' Send dowlink assignment for TBF(TFI=15 TLLI=0xc000000f DIR=DL STATE=NULL) on PCH, no TBF exist (IMSI=001001000000015) TBF(TFI=15 TLLI=0xc000000f DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=15 TLLI=0xc000000f DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) + - TRX=0 (0) TS=4 TA=0 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 35 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 00 fb c0 23 2b 2b 2b 2b TBF(TFI=15 TLLI=0xc000000f DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** @@ -931,6 +947,7 @@ Modifying MS object, TLLI = 0xc0000010, IMSI '' -> '001001000000016' Send dowlink assignment for TBF(TFI=16 TLLI=0xc0000010 DIR=DL STATE=NULL) on PCH, no TBF exist (IMSI=001001000000016) TBF(TFI=16 TLLI=0xc0000010 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=16 TLLI=0xc0000010 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) + - TRX=0 (0) TS=4 TA=0 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 36 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 01 0c 00 23 2b 2b 2b 2b TBF(TFI=16 TLLI=0xc0000010 DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** @@ -956,6 +973,7 @@ Modifying MS object, TLLI = 0xc0000011, IMSI '' -> '001001000000017' Send dowlink assignment for TBF(TFI=17 TLLI=0xc0000011 DIR=DL STATE=NULL) on PCH, no TBF exist (IMSI=001001000000017) TBF(TFI=17 TLLI=0xc0000011 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=17 TLLI=0xc0000011 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) + - TRX=0 (0) TS=4 TA=0 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 37 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 01 1c 40 23 2b 2b 2b 2b TBF(TFI=17 TLLI=0xc0000011 DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** @@ -981,6 +999,7 @@ Modifying MS object, TLLI = 0xc0000012, IMSI '' -> '001001000000018' Send dowlink assignment for TBF(TFI=18 TLLI=0xc0000012 DIR=DL STATE=NULL) on PCH, no TBF exist (IMSI=001001000000018) TBF(TFI=18 TLLI=0xc0000012 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=18 TLLI=0xc0000012 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) + - TRX=0 (0) TS=4 TA=0 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 38 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 01 2c 80 23 2b 2b 2b 2b TBF(TFI=18 TLLI=0xc0000012 DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** @@ -1006,6 +1025,7 @@ Modifying MS object, TLLI = 0xc0000013, IMSI '' -> '001001000000019' Send dowlink assignment for TBF(TFI=19 TLLI=0xc0000013 DIR=DL STATE=NULL) on PCH, no TBF exist (IMSI=001001000000019) TBF(TFI=19 TLLI=0xc0000013 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=19 TLLI=0xc0000013 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) + - TRX=0 (0) TS=4 TA=0 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 39 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 01 3c c0 23 2b 2b 2b 2b TBF(TFI=19 TLLI=0xc0000013 DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** @@ -1031,6 +1051,7 @@ Modifying MS object, TLLI = 0xc0000014, IMSI '' -> '001001000000020' Send dowlink assignment for TBF(TFI=20 TLLI=0xc0000014 DIR=DL STATE=NULL) on PCH, no TBF exist (IMSI=001001000000020) TBF(TFI=20 TLLI=0xc0000014 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=20 TLLI=0xc0000014 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) + - TRX=0 (0) TS=4 TA=0 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 30 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 01 4d 00 23 2b 2b 2b 2b TBF(TFI=20 TLLI=0xc0000014 DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** @@ -1056,6 +1077,7 @@ Modifying MS object, TLLI = 0xc0000015, IMSI '' -> '001001000000021' Send dowlink assignment for TBF(TFI=21 TLLI=0xc0000015 DIR=DL STATE=NULL) on PCH, no TBF exist (IMSI=001001000000021) TBF(TFI=21 TLLI=0xc0000015 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=21 TLLI=0xc0000015 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) + - TRX=0 (0) TS=4 TA=0 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 31 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 01 5d 40 23 2b 2b 2b 2b TBF(TFI=21 TLLI=0xc0000015 DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** @@ -1081,6 +1103,7 @@ Modifying MS object, TLLI = 0xc0000016, IMSI '' -> '001001000000022' Send dowlink assignment for TBF(TFI=22 TLLI=0xc0000016 DIR=DL STATE=NULL) on PCH, no TBF exist (IMSI=001001000000022) TBF(TFI=22 TLLI=0xc0000016 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=22 TLLI=0xc0000016 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) + - TRX=0 (0) TS=4 TA=0 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 32 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 01 6d 80 23 2b 2b 2b 2b TBF(TFI=22 TLLI=0xc0000016 DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** @@ -1106,6 +1129,7 @@ Modifying MS object, TLLI = 0xc0000017, IMSI '' -> '001001000000023' Send dowlink assignment for TBF(TFI=23 TLLI=0xc0000017 DIR=DL STATE=NULL) on PCH, no TBF exist (IMSI=001001000000023) TBF(TFI=23 TLLI=0xc0000017 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=23 TLLI=0xc0000017 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) + - TRX=0 (0) TS=4 TA=0 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 33 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 01 7d c0 23 2b 2b 2b 2b TBF(TFI=23 TLLI=0xc0000017 DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** @@ -1131,6 +1155,7 @@ Modifying MS object, TLLI = 0xc0000018, IMSI '' -> '001001000000024' Send dowlink assignment for TBF(TFI=24 TLLI=0xc0000018 DIR=DL STATE=NULL) on PCH, no TBF exist (IMSI=001001000000024) TBF(TFI=24 TLLI=0xc0000018 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=24 TLLI=0xc0000018 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) + - TRX=0 (0) TS=4 TA=0 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 34 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 01 8e 00 23 2b 2b 2b 2b TBF(TFI=24 TLLI=0xc0000018 DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** @@ -1156,6 +1181,7 @@ Modifying MS object, TLLI = 0xc0000019, IMSI '' -> '001001000000025' Send dowlink assignment for TBF(TFI=25 TLLI=0xc0000019 DIR=DL STATE=NULL) on PCH, no TBF exist (IMSI=001001000000025) TBF(TFI=25 TLLI=0xc0000019 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=25 TLLI=0xc0000019 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) + - TRX=0 (0) TS=4 TA=0 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 35 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 01 9e 40 23 2b 2b 2b 2b TBF(TFI=25 TLLI=0xc0000019 DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** @@ -1181,6 +1207,7 @@ Modifying MS object, TLLI = 0xc000001a, IMSI '' -> '001001000000026' Send dowlink assignment for TBF(TFI=26 TLLI=0xc000001a DIR=DL STATE=NULL) on PCH, no TBF exist (IMSI=001001000000026) TBF(TFI=26 TLLI=0xc000001a DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=26 TLLI=0xc000001a DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) + - TRX=0 (0) TS=4 TA=0 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 36 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 01 ae 80 23 2b 2b 2b 2b TBF(TFI=26 TLLI=0xc000001a DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** @@ -1206,6 +1233,7 @@ Modifying MS object, TLLI = 0xc000001b, IMSI '' -> '001001000000027' Send dowlink assignment for TBF(TFI=27 TLLI=0xc000001b DIR=DL STATE=NULL) on PCH, no TBF exist (IMSI=001001000000027) TBF(TFI=27 TLLI=0xc000001b DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=27 TLLI=0xc000001b DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) + - TRX=0 (0) TS=4 TA=0 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 37 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 01 be c0 23 2b 2b 2b 2b TBF(TFI=27 TLLI=0xc000001b DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** @@ -1231,6 +1259,7 @@ Modifying MS object, TLLI = 0xc000001c, IMSI '' -> '001001000000028' Send dowlink assignment for TBF(TFI=28 TLLI=0xc000001c DIR=DL STATE=NULL) on PCH, no TBF exist (IMSI=001001000000028) TBF(TFI=28 TLLI=0xc000001c DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=28 TLLI=0xc000001c DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) + - TRX=0 (0) TS=4 TA=0 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 38 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 01 cf 00 23 2b 2b 2b 2b TBF(TFI=28 TLLI=0xc000001c DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** @@ -1256,6 +1285,7 @@ Modifying MS object, TLLI = 0xc000001d, IMSI '' -> '001001000000029' Send dowlink assignment for TBF(TFI=29 TLLI=0xc000001d DIR=DL STATE=NULL) on PCH, no TBF exist (IMSI=001001000000029) TBF(TFI=29 TLLI=0xc000001d DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=29 TLLI=0xc000001d DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) + - TRX=0 (0) TS=4 TA=0 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 39 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 01 df 40 23 2b 2b 2b 2b TBF(TFI=29 TLLI=0xc000001d DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** @@ -1281,6 +1311,7 @@ Modifying MS object, TLLI = 0xc000001e, IMSI '' -> '001001000000030' Send dowlink assignment for TBF(TFI=30 TLLI=0xc000001e DIR=DL STATE=NULL) on PCH, no TBF exist (IMSI=001001000000030) TBF(TFI=30 TLLI=0xc000001e DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=30 TLLI=0xc000001e DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) + - TRX=0 (0) TS=4 TA=0 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 33 30 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 01 ef 80 23 2b 2b 2b 2b TBF(TFI=30 TLLI=0xc000001e DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** @@ -1306,6 +1337,7 @@ Modifying MS object, TLLI = 0xc000001f, IMSI '' -> '001001000000031' Send dowlink assignment for TBF(TFI=31 TLLI=0xc000001f DIR=DL STATE=NULL) on PCH, no TBF exist (IMSI=001001000000031) TBF(TFI=31 TLLI=0xc000001f DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=31 TLLI=0xc000001f DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) + - TRX=0 (0) TS=4 TA=0 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 33 31 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 01 ff c0 23 2b 2b 2b 2b TBF(TFI=31 TLLI=0xc000001f DIR=DL STATE=ASSIGN) append ********** TBF starts here ********** @@ -1339,6 +1371,7 @@ Modifying MS object, TLLI = 0xc0123456, IMSI '' -> '001001000123456' Send dowlink assignment for TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=NULL) on PCH, no TBF exist (IMSI=001001000123456) TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) + - TRX=0 (0) TS=4 TA=0 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=34 35 36 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 01 23 45 68 00 23 2b 2b 2b 2b TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN) append TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN) append @@ -1365,6 +1398,7 @@ TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=NULL) [DOWNLINK] START Send dowlink assignment for TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=NULL) on PCH, no TBF exist (IMSI=001001000123456) TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) + - TRX=0 (0) TS=4 TA=0 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=34 35 36 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 01 23 45 68 00 23 2b 2b 2b 2b TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN) append TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN) downlink (V(A)==0 .. V(S)==0) @@ -1422,6 +1456,7 @@ TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=FLOW) starting timer 3169. TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=FLOW) [UPLINK] START TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=FLOW) RX: [PCU <- BTS] RACH qbit-ta=31 ra=0x03, Fn=2654167 (17,25,9) TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=FLOW) TX: START Immediate Assignment Uplink (AGCH) + - TRX=0 (0) TS=7 TA=7 TSC=0 TFI=0 USF=0 Sending data request: trx=0 ts=0 sapi=2 arfcn=0 fn=0 block=0 data=2d 06 3f 10 0f 00 00 03 8b 29 07 00 c8 00 10 0b 2b 2b 2b 2b 2b 2b 2b Got RLC block, coding scheme: CS-1, length: 23 (23)) UL data: 00 01 01 f1 22 33 44 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 @@ -1468,6 +1503,7 @@ Modifying MS object, TLLI = 0xf1223344, IMSI '' -> '0011223344' Send dowlink assignment for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL) on PCH, no TBF exist (IMSI=0011223344) TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) + - TRX=0 (0) TS=7 TA=7 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=33 34 34 2d 06 3f 30 0f 00 00 7d 80 00 07 00 df 12 23 34 48 00 23 2b 2b 2b 2b TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=ASSIGN) append Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654218 block=8 data=47 94 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b @@ -1475,6 +1511,7 @@ MS requests UL TBF on RACH, so we provide one: MS requests single block allocation RX: [PCU <- BTS] RACH qbit-ta=31 ra=0x73, Fn=2654167 (17,25,9), SBFn=2654270 TX: Immediate Assignment Uplink (AGCH) + - TRX=0 (0) TS=7 TA=7 TSC=0 TFI=0 USF=7 Sending data request: trx=0 ts=0 sapi=2 arfcn=0 fn=0 block=0 data=2d 06 3f 10 0f 00 00 73 8b 29 07 00 c0 0c 5a 43 2b 2b 2b 2b 2b 2b 2b Searching for first unallocated TFI: TRX=0 Found TFI=0. @@ -1558,6 +1595,7 @@ MS requests UL TBF on RACH, so we provide one: MS requests single block allocation RX: [PCU <- BTS] RACH qbit-ta=31 ra=0x73, Fn=2654167 (17,25,9), SBFn=2654270 TX: Immediate Assignment Uplink (AGCH) + - TRX=0 (0) TS=7 TA=7 TSC=0 TFI=0 USF=7 Sending data request: trx=0 ts=0 sapi=2 arfcn=0 fn=0 block=0 data=2d 06 3f 10 0f 00 00 73 8b 29 07 00 c0 0c 5a 43 2b 2b 2b 2b 2b 2b 2b Searching for first unallocated TFI: TRX=0 Found TFI=0. @@ -1684,6 +1722,7 @@ MS requests UL TBF on RACH, so we provide one: MS requests single block allocation RX: [PCU <- BTS] RACH qbit-ta=31 ra=0x73, Fn=2654232 (17,39,22), SBFn=2654335 TX: Immediate Assignment Uplink (AGCH) + - TRX=0 (0) TS=7 TA=7 TSC=0 TFI=0 USF=7 Sending data request: trx=0 ts=0 sapi=2 arfcn=0 fn=0 block=0 data=2d 06 3f 10 0f 00 00 73 8c f6 07 00 c0 0c 68 ab 2b 2b 2b 2b 2b 2b 2b Searching for first unallocated TFI: TRX=0 Found TFI=1. @@ -1758,6 +1797,7 @@ MS requests UL TBF on RACH, so we provide one: MS requests single block allocation RX: [PCU <- BTS] RACH qbit-ta=31 ra=0x73, Fn=2654167 (17,25,9), SBFn=2654270 TX: Immediate Assignment Uplink (AGCH) + - TRX=0 (0) TS=7 TA=7 TSC=0 TFI=0 USF=7 Sending data request: trx=0 ts=0 sapi=2 arfcn=0 fn=0 block=0 data=2d 06 3f 10 0f 00 00 73 8b 29 07 00 c0 0c 5a 43 2b 2b 2b 2b 2b 2b 2b Searching for first unallocated TFI: TRX=0 Found TFI=0. @@ -1849,6 +1889,7 @@ MS requests UL TBF on RACH, so we provide one: MS requests single block allocation RX: [PCU <- BTS] RACH qbit-ta=31 ra=0x73, Fn=2654224 (17,31,14), SBFn=2654327 TX: Immediate Assignment Uplink (AGCH) + - TRX=0 (0) TS=7 TA=7 TSC=0 TFI=0 USF=7 Sending data request: trx=0 ts=0 sapi=2 arfcn=0 fn=0 block=0 data=2d 06 3f 10 0f 00 00 73 8b ee 07 00 c0 0c 60 6b 2b 2b 2b 2b 2b 2b 2b Searching for first unallocated TFI: TRX=0 Found TFI=0. @@ -1927,6 +1968,7 @@ MS requests UL TBF on RACH, so we provide one: MS requests single block allocation RX: [PCU <- BTS] RACH qbit-ta=31 ra=0x73, Fn=2654167 (17,25,9), SBFn=2654270 TX: Immediate Assignment Uplink (AGCH) + - TRX=0 (0) TS=7 TA=7 TSC=0 TFI=0 USF=7 Sending data request: trx=0 ts=0 sapi=2 arfcn=0 fn=0 block=0 data=2d 06 3f 10 0f 00 00 73 8b 29 07 00 c0 0c 5a 43 2b 2b 2b 2b 2b 2b 2b Searching for first unallocated TFI: TRX=0 Found TFI=0. @@ -2038,6 +2080,7 @@ TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=FLOW) starting timer 3169. TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=FLOW) [UPLINK] START TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=FLOW) RX: [PCU <- BTS] RACH qbit-ta=31 ra=0x03, Fn=2654275 (17,31,13) TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=FLOW) TX: START Immediate Assignment Uplink (AGCH) + - TRX=0 (0) TS=7 TA=7 TSC=0 TFI=0 USF=0 Sending data request: trx=0 ts=0 sapi=2 arfcn=0 fn=0 block=0 data=2d 06 3f 10 0f 00 00 03 8b ed 07 00 c8 00 10 0b 2b 2b 2b 2b 2b 2b 2b Got RLC block, coding scheme: CS-1, length: 23 (23)) UL data: 00 01 01 f1 22 33 44 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 @@ -2073,6 +2116,7 @@ MS requests UL TBF on RACH, so we provide one: MS requests single block allocation RX: [PCU <- BTS] RACH qbit-ta=31 ra=0x73, Fn=2654167 (17,25,9), SBFn=2654270 TX: Immediate Assignment Uplink (AGCH) + - TRX=0 (0) TS=7 TA=7 TSC=0 TFI=0 USF=7 Sending data request: trx=0 ts=0 sapi=2 arfcn=0 fn=0 block=0 data=2d 06 3f 10 0f 00 00 73 8b 29 07 00 c0 0c 5a 43 2b 2b 2b 2b 2b 2b 2b Searching for first unallocated TFI: TRX=0 Found TFI=0. -- cgit v1.2.3 From 56d06f3e1eb3ffb99defd6d8c3df0a938113ddb9 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Wed, 20 Jan 2016 18:36:30 +0100 Subject: tbf: Use the control TS for Immediate Assignments Currently the first TS is used, which can be different from the control TS on downlink TBFs. Use the control TS instead. Sponsored-by: On-Waves ehf --- src/bts.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/bts.cpp b/src/bts.cpp index 0d3e32a8..12f4e726 100644 --- a/src/bts.cpp +++ b/src/bts.cpp @@ -525,7 +525,7 @@ int BTS::rcv_rach(uint8_t ra, uint32_t Fn, int16_t qta) LOGP(DRLCMAC, LOGL_INFO, "%s TX: START Immediate " "Assignment Uplink (AGCH)\n", tbf_name(tbf)); trx_no = tbf->trx->trx_no; - ts_no = tbf->first_ts; + ts_no = tbf->control_ts; tfi = tbf->tfi(); usf = tbf->m_usf[ts_no]; tsc = tbf->tsc(); @@ -585,7 +585,7 @@ void BTS::trigger_dl_ass( void BTS::snd_dl_ass(gprs_rlcmac_tbf *tbf, uint8_t poll, const char *imsi) { int plen; - unsigned int ts = tbf->first_ts; + unsigned int ts = tbf->control_ts; LOGP(DRLCMAC, LOGL_INFO, "TX: START %s Immediate Assignment Downlink (PCH)\n", tbf_name(tbf)); bitvec *immediate_assignment = bitvec_alloc(22); /* without plen */ -- cgit v1.2.3 From 29e3a2f0f3d3cacdb741d406e43b0c725fffd81e Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Fri, 5 Feb 2016 19:04:23 +0100 Subject: Revert "tbf: Use the control TS for Immediate Assignments" According to spec, the lowest numbered PDCH of the TBF shall be used for the PACCH, only when concurrent TBF are active, the lowest common PDCH shall be used. An immediate assigment is in general only sent, if no TBF is active, so the latter case never applies. This reverts commit fdd8a1ba2312be3f33576ee994c0b5da6272e815. --- src/bts.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/bts.cpp b/src/bts.cpp index 12f4e726..0d3e32a8 100644 --- a/src/bts.cpp +++ b/src/bts.cpp @@ -525,7 +525,7 @@ int BTS::rcv_rach(uint8_t ra, uint32_t Fn, int16_t qta) LOGP(DRLCMAC, LOGL_INFO, "%s TX: START Immediate " "Assignment Uplink (AGCH)\n", tbf_name(tbf)); trx_no = tbf->trx->trx_no; - ts_no = tbf->control_ts; + ts_no = tbf->first_ts; tfi = tbf->tfi(); usf = tbf->m_usf[ts_no]; tsc = tbf->tsc(); @@ -585,7 +585,7 @@ void BTS::trigger_dl_ass( void BTS::snd_dl_ass(gprs_rlcmac_tbf *tbf, uint8_t poll, const char *imsi) { int plen; - unsigned int ts = tbf->control_ts; + unsigned int ts = tbf->first_ts; LOGP(DRLCMAC, LOGL_INFO, "TX: START %s Immediate Assignment Downlink (PCH)\n", tbf_name(tbf)); bitvec *immediate_assignment = bitvec_alloc(22); /* without plen */ -- cgit v1.2.3 From 0316dc6e4808d0413a4edf3738edea44193228e4 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Thu, 21 Jan 2016 20:12:04 +0100 Subject: tbf: Add counters for aborted TBF in state FLOW Increment CTR_TBF_DL_ABORTED/CTR_TBF_UL_ABORTED if a TBF gets freed that is still in state GPRS_RLCMAC_FLOW. Sponsored-by: On-Waves ehf --- src/bts.cpp | 2 ++ src/bts.h | 6 ++++++ src/tbf.cpp | 16 +++++++++++----- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/bts.cpp b/src/bts.cpp index 0d3e32a8..c0918dd1 100644 --- a/src/bts.cpp +++ b/src/bts.cpp @@ -52,8 +52,10 @@ static BTS s_bts; static const struct rate_ctr_desc bts_ctr_description[] = { { "tbf.dl.alloc", "TBF DL Allocated "}, { "tbf.dl.freed", "TBF DL Freed "}, + { "tbf.dl.aborted", "TBF DL Aborted "}, { "tbf.ul.alloc", "TBF UL Allocated "}, { "tbf.ul.freed", "TBF UL Freed "}, + { "tbf.ul.aborted", "TBF UL Aborted "}, { "tbf.reused", "TBF Reused "}, { "tbf.alloc.algo-a", "TBF Alloc Algo A "}, { "tbf.alloc.algo-b", "TBF Alloc Algo B "}, diff --git a/src/bts.h b/src/bts.h index 14b6c1f8..119f6b2c 100644 --- a/src/bts.h +++ b/src/bts.h @@ -212,8 +212,10 @@ public: enum { CTR_TBF_DL_ALLOCATED, CTR_TBF_DL_FREED, + CTR_TBF_DL_ABORTED, CTR_TBF_UL_ALLOCATED, CTR_TBF_UL_FREED, + CTR_TBF_UL_ABORTED, CTR_TBF_REUSED, CTR_TBF_ALLOC_ALGO_A, CTR_TBF_ALLOC_ALGO_B, @@ -286,8 +288,10 @@ public: */ void tbf_dl_created(); void tbf_dl_freed(); + void tbf_dl_aborted(); void tbf_ul_created(); void tbf_ul_freed(); + void tbf_ul_aborted(); void tbf_reused(); void tbf_alloc_algo_a(); void tbf_alloc_algo_b(); @@ -424,8 +428,10 @@ inline struct osmo_stat_item_group *BTS::stat_items() const CREATE_COUNT_INLINE(tbf_dl_created, CTR_TBF_DL_ALLOCATED) CREATE_COUNT_INLINE(tbf_dl_freed, CTR_TBF_DL_FREED) +CREATE_COUNT_INLINE(tbf_dl_aborted, CTR_TBF_DL_ABORTED) CREATE_COUNT_INLINE(tbf_ul_created, CTR_TBF_UL_ALLOCATED) CREATE_COUNT_INLINE(tbf_ul_freed, CTR_TBF_UL_FREED) +CREATE_COUNT_INLINE(tbf_ul_aborted, CTR_TBF_UL_ABORTED) CREATE_COUNT_INLINE(tbf_reused, CTR_TBF_REUSED) CREATE_COUNT_INLINE(tbf_alloc_algo_a, CTR_TBF_ALLOC_ALGO_A) CREATE_COUNT_INLINE(tbf_alloc_algo_b, CTR_TBF_ALLOC_ALGO_B) diff --git a/src/tbf.cpp b/src/tbf.cpp index c852d665..e8a9e3e9 100644 --- a/src/tbf.cpp +++ b/src/tbf.cpp @@ -310,6 +310,17 @@ static void tbf_unlink_pdch(struct gprs_rlcmac_tbf *tbf) void tbf_free(struct gprs_rlcmac_tbf *tbf) { + /* update counters */ + if (tbf->direction == GPRS_RLCMAC_UL_TBF) { + tbf->bts->tbf_ul_freed(); + if (tbf->state_is(GPRS_RLCMAC_FLOW)) + tbf->bts->tbf_ul_aborted(); + } else { + tbf->bts->tbf_dl_freed(); + if (tbf->state_is(GPRS_RLCMAC_FLOW)) + tbf->bts->tbf_dl_aborted(); + } + /* Give final measurement report */ gprs_rlcmac_rssi_rep(tbf); if (tbf->direction == GPRS_RLCMAC_DL_TBF) { @@ -336,11 +347,6 @@ void tbf_free(struct gprs_rlcmac_tbf *tbf) tbf_unlink_pdch(tbf); llist_del(&tbf->list()); - if (tbf->direction == GPRS_RLCMAC_UL_TBF) - tbf->bts->tbf_ul_freed(); - else - tbf->bts->tbf_dl_freed(); - if (tbf->ms()) tbf->set_ms(NULL); -- cgit v1.2.3 From f04a5b33ecf01a9bdbd7e971cddb0a87608d04a6 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Thu, 21 Jan 2016 20:42:40 +0100 Subject: tbf: Add abort method for downlink TBF Currently the is a release() function which takes care of statistics and shutdown of properly finished TBFs, but which cannot be used for aborted TBFs. This commit add an abort() method which handles unacked RLC blocks as lost and doesn't start a release timer. This method will be invoked by tbf_free() for downlink TBF. Sponsored-by: On-Waves ehf --- src/tbf.cpp | 3 +- src/tbf.h | 1 + src/tbf_dl.cpp | 27 +++++++++++++ tests/tbf/TbfTest.err | 109 +++++++++++++++++++++++++++----------------------- 4 files changed, 88 insertions(+), 52 deletions(-) diff --git a/src/tbf.cpp b/src/tbf.cpp index e8a9e3e9..93c932b5 100644 --- a/src/tbf.cpp +++ b/src/tbf.cpp @@ -325,7 +325,8 @@ void tbf_free(struct gprs_rlcmac_tbf *tbf) gprs_rlcmac_rssi_rep(tbf); if (tbf->direction == GPRS_RLCMAC_DL_TBF) { gprs_rlcmac_dl_tbf *dl_tbf = as_dl_tbf(tbf); - gprs_rlcmac_lost_rep(dl_tbf); + + dl_tbf->abort(); dl_tbf->cleanup(); } diff --git a/src/tbf.h b/src/tbf.h index ab4145c2..957baedf 100644 --- a/src/tbf.h +++ b/src/tbf.h @@ -355,6 +355,7 @@ struct gprs_rlcmac_dl_tbf : public gprs_rlcmac_tbf { int frames_since_last_drain(unsigned fn) const; bool keep_open(unsigned fn) const; int release(); + int abort(); bool is_control_ts(uint8_t ts) const { return ts == control_ts; diff --git a/src/tbf_dl.cpp b/src/tbf_dl.cpp index a55f179e..64ebea4f 100644 --- a/src/tbf_dl.cpp +++ b/src/tbf_dl.cpp @@ -894,6 +894,33 @@ int gprs_rlcmac_dl_tbf::release() return 0; } +int gprs_rlcmac_dl_tbf::abort() +{ + uint16_t lost; + + if (state_is(GPRS_RLCMAC_FLOW)) { + /* range V(A)..V(S)-1 */ + lost = m_window.count_unacked(); + + /* report all outstanding packets as lost */ + gprs_rlcmac_received_lost(this, 0, lost); + gprs_rlcmac_lost_rep(this); + + /* TODO: Reschedule all LLC frames starting with the one that is + * (partly) encoded in chunk 1 of block V(A). (optional) */ + } + + set_state(GPRS_RLCMAC_RELEASING); + + /* reset rlc states */ + m_window.reset(); + + /* keep to flags */ + state_flags &= GPRS_RLCMAC_FLAG_TO_MASK; + state_flags &= ~(1 << GPRS_RLCMAC_FLAG_CCCH); + + return 0; +} int gprs_rlcmac_dl_tbf::rcvd_dl_ack(uint8_t final_ack, unsigned first_bsn, struct bitvec *rbb) diff --git a/tests/tbf/TbfTest.err b/tests/tbf/TbfTest.err index bbd5a82c..8f920ca0 100644 --- a/tests/tbf/TbfTest.err +++ b/tests/tbf/TbfTest.err @@ -103,16 +103,17 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=WAIT RELEASE) Trigger downlink assignment Send dowlink assignment on PACCH, because TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=WAIT RELEASE) exists TBF(TFI=1 TLLI=0xffeeddcc DIR=DL STATE=NULL) changes state from NULL to ASSIGN TBF(TFI=1 TLLI=0xffeeddcc DIR=DL STATE=ASSIGN) starting timer 0. -DL packet loss of IMSI= / TLLI=0xffeeddcc: 0% -TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=WAIT RELEASE) free -TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=WAIT RELEASE) stopping timer 3193. -PDCH(TS 4, TRX 0): Detaching TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=WAIT RELEASE), 1 TBFs, USFs = 00, TFIs = 00000002. -Detaching TBF from MS object, TLLI = 0xffeeddcc, TBF = TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=WAIT RELEASE) +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=WAIT RELEASE) changes state from WAIT RELEASE to RELEASING +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=RELEASING) free +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=RELEASING) stopping timer 3193. +PDCH(TS 4, TRX 0): Detaching TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=RELEASING), 1 TBFs, USFs = 00, TFIs = 00000002. +Detaching TBF from MS object, TLLI = 0xffeeddcc, TBF = TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=RELEASING) ********** TBF ends here ********** -TBF(TFI=1 TLLI=0xffeeddcc DIR=DL STATE=ASSIGN) free -TBF(TFI=1 TLLI=0xffeeddcc DIR=DL STATE=ASSIGN) stopping timer 0. -PDCH(TS 4, TRX 0): Detaching TBF(TFI=1 TLLI=0xffeeddcc DIR=DL STATE=ASSIGN), 0 TBFs, USFs = 00, TFIs = 00000000. -Detaching TBF from MS object, TLLI = 0xffeeddcc, TBF = TBF(TFI=1 TLLI=0xffeeddcc DIR=DL STATE=ASSIGN) +TBF(TFI=1 TLLI=0xffeeddcc DIR=DL STATE=ASSIGN) changes state from ASSIGN to RELEASING +TBF(TFI=1 TLLI=0xffeeddcc DIR=DL STATE=RELEASING) free +TBF(TFI=1 TLLI=0xffeeddcc DIR=DL STATE=RELEASING) stopping timer 0. +PDCH(TS 4, TRX 0): Detaching TBF(TFI=1 TLLI=0xffeeddcc DIR=DL STATE=RELEASING), 0 TBFs, USFs = 00, TFIs = 00000000. +Detaching TBF from MS object, TLLI = 0xffeeddcc, TBF = TBF(TFI=1 TLLI=0xffeeddcc DIR=DL STATE=RELEASING) ********** TBF ends here ********** Destroying MS object, TLLI = 0xffeeddcc Searching for first unallocated TFI: TRX=0 @@ -183,16 +184,17 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=WAIT RELEASE) Trigger downlink assignment Send dowlink assignment on PACCH, because TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=WAIT RELEASE) exists TBF(TFI=1 TLLI=0xffeeddcc DIR=DL STATE=NULL) changes state from NULL to ASSIGN TBF(TFI=1 TLLI=0xffeeddcc DIR=DL STATE=ASSIGN) starting timer 0. -TBF(TFI=1 TLLI=0xffeeddcc DIR=DL STATE=ASSIGN) free -TBF(TFI=1 TLLI=0xffeeddcc DIR=DL STATE=ASSIGN) stopping timer 0. -PDCH(TS 4, TRX 0): Detaching TBF(TFI=1 TLLI=0xffeeddcc DIR=DL STATE=ASSIGN), 1 TBFs, USFs = 00, TFIs = 00000001. -Detaching TBF from MS object, TLLI = 0xffeeddcc, TBF = TBF(TFI=1 TLLI=0xffeeddcc DIR=DL STATE=ASSIGN) +TBF(TFI=1 TLLI=0xffeeddcc DIR=DL STATE=ASSIGN) changes state from ASSIGN to RELEASING +TBF(TFI=1 TLLI=0xffeeddcc DIR=DL STATE=RELEASING) free +TBF(TFI=1 TLLI=0xffeeddcc DIR=DL STATE=RELEASING) stopping timer 0. +PDCH(TS 4, TRX 0): Detaching TBF(TFI=1 TLLI=0xffeeddcc DIR=DL STATE=RELEASING), 1 TBFs, USFs = 00, TFIs = 00000001. +Detaching TBF from MS object, TLLI = 0xffeeddcc, TBF = TBF(TFI=1 TLLI=0xffeeddcc DIR=DL STATE=RELEASING) ********** TBF ends here ********** -DL packet loss of IMSI= / TLLI=0xffeeddcc: 0% -TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=WAIT RELEASE) free -TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=WAIT RELEASE) stopping timer 3193. -PDCH(TS 4, TRX 0): Detaching TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=WAIT RELEASE), 0 TBFs, USFs = 00, TFIs = 00000000. -Detaching TBF from MS object, TLLI = 0xffeeddcc, TBF = TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=WAIT RELEASE) +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=WAIT RELEASE) changes state from WAIT RELEASE to RELEASING +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=RELEASING) free +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=RELEASING) stopping timer 3193. +PDCH(TS 4, TRX 0): Detaching TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=RELEASING), 0 TBFs, USFs = 00, TFIs = 00000000. +Detaching TBF from MS object, TLLI = 0xffeeddcc, TBF = TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=RELEASING) ********** TBF ends here ********** Destroying MS object, TLLI = 0xffeeddcc Searching for first unallocated TFI: TRX=0 @@ -442,11 +444,11 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FINISHED) downlink acknowledge - Final ACK received. TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FINISHED) changes state from FINISHED to WAIT RELEASE TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=WAIT RELEASE) starting timer 3193. -DL packet loss of IMSI= / TLLI=0xffeeddcc: 0% -TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=WAIT RELEASE) free -TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=WAIT RELEASE) stopping timer 3193. -PDCH(TS 4, TRX 0): Detaching TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=WAIT RELEASE), 0 TBFs, USFs = 00, TFIs = 00000000. -Detaching TBF from MS object, TLLI = 0xffeeddcc, TBF = TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=WAIT RELEASE) +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=WAIT RELEASE) changes state from WAIT RELEASE to RELEASING +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=RELEASING) free +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=RELEASING) stopping timer 3193. +PDCH(TS 4, TRX 0): Detaching TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=RELEASING), 0 TBFs, USFs = 00, TFIs = 00000000. +Detaching TBF from MS object, TLLI = 0xffeeddcc, TBF = TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=RELEASING) Destroying MS object, TLLI = 0xffeeddcc ********** TBF ends here ********** Searching for first unallocated TFI: TRX=0 @@ -494,18 +496,20 @@ The MS object cannot fully confirm an unexpected TLLI: 0xf1000002, partly confir Modifying MS object, TLLI = 0xf1000001, IMSI '' -> '001001000000001' Modifying MS object, TLLI = 0xf1000001, IMSI '001001000000001' -> '001001000000002' TBF(TFI=1 TLLI=0xf1000002 DIR=DL STATE=FLOW) the IMSI '001001000000002' was already assigned to another MS object: TLLI = 0xf1000001, that IMSI will be removed -TBF(TFI=0 TLLI=0xf1000001 DIR=DL STATE=FLOW) free -TBF(TFI=0 TLLI=0xf1000001 DIR=DL STATE=FLOW) Software error: Pending downlink assignment. This may not happen, because the assignment message never gets transmitted. Please be sure not to free in this state. PLEASE FIX! -PDCH(TS 4, TRX 0): Detaching TBF(TFI=0 TLLI=0xf1000001 DIR=DL STATE=FLOW), 1 TBFs, USFs = 00, TFIs = 00000002. -Detaching TBF from MS object, TLLI = 0xf1000001, TBF = TBF(TFI=0 TLLI=0xf1000001 DIR=DL STATE=FLOW) +TBF(TFI=0 TLLI=0xf1000001 DIR=DL STATE=FLOW) changes state from FLOW to RELEASING +TBF(TFI=0 TLLI=0xf1000001 DIR=DL STATE=RELEASING) free +TBF(TFI=0 TLLI=0xf1000001 DIR=DL STATE=RELEASING) Software error: Pending downlink assignment. This may not happen, because the assignment message never gets transmitted. Please be sure not to free in this state. PLEASE FIX! +PDCH(TS 4, TRX 0): Detaching TBF(TFI=0 TLLI=0xf1000001 DIR=DL STATE=RELEASING), 1 TBFs, USFs = 00, TFIs = 00000002. +Detaching TBF from MS object, TLLI = 0xf1000001, TBF = TBF(TFI=0 TLLI=0xf1000001 DIR=DL STATE=RELEASING) ********** TBF ends here ********** Modifying MS object, TLLI = 0xf1000002, IMSI '' -> '001001000000002' Clearing MS object, TLLI: 0xf1000001, IMSI: '001001000000002' Destroying MS object, TLLI = 0x00000000 -TBF(TFI=1 TLLI=0xf1000002 DIR=DL STATE=FLOW) free -TBF(TFI=1 TLLI=0xf1000002 DIR=DL STATE=FLOW) Software error: Pending downlink assignment. This may not happen, because the assignment message never gets transmitted. Please be sure not to free in this state. PLEASE FIX! -PDCH(TS 4, TRX 0): Detaching TBF(TFI=1 TLLI=0xf1000002 DIR=DL STATE=FLOW), 0 TBFs, USFs = 00, TFIs = 00000000. -Detaching TBF from MS object, TLLI = 0xf1000002, TBF = TBF(TFI=1 TLLI=0xf1000002 DIR=DL STATE=FLOW) +TBF(TFI=1 TLLI=0xf1000002 DIR=DL STATE=FLOW) changes state from FLOW to RELEASING +TBF(TFI=1 TLLI=0xf1000002 DIR=DL STATE=RELEASING) free +TBF(TFI=1 TLLI=0xf1000002 DIR=DL STATE=RELEASING) Software error: Pending downlink assignment. This may not happen, because the assignment message never gets transmitted. Please be sure not to free in this state. PLEASE FIX! +PDCH(TS 4, TRX 0): Detaching TBF(TFI=1 TLLI=0xf1000002 DIR=DL STATE=RELEASING), 0 TBFs, USFs = 00, TFIs = 00000000. +Detaching TBF from MS object, TLLI = 0xf1000002, TBF = TBF(TFI=1 TLLI=0xf1000002 DIR=DL STATE=RELEASING) Destroying MS object, TLLI = 0xf1000002 ********** TBF ends here ********** ********** TBF starts here ********** @@ -1375,9 +1379,10 @@ TX: START TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN) Immediate Assignment Do Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=34 35 36 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 01 23 45 68 00 23 2b 2b 2b 2b TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN) append TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN) append -TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN) free -PDCH(TS 4, TRX 0): Detaching TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN), 0 TBFs, USFs = 00, TFIs = 00000000. -Detaching TBF from MS object, TLLI = 0xc0123456, TBF = TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN) +TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN) changes state from ASSIGN to RELEASING +TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=RELEASING) free +PDCH(TS 4, TRX 0): Detaching TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=RELEASING), 0 TBFs, USFs = 00, TFIs = 00000000. +Detaching TBF from MS object, TLLI = 0xc0123456, TBF = TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=RELEASING) ********** TBF ends here ********** ********** TBF starts here ********** Allocating DL TBF: MS_CLASS=45/0 @@ -2875,11 +2880,11 @@ Got RLC block, coding scheme: CS-1, length: 23 (23)) ------------------------- RX : Uplink Control Block ------------------------- RX: [PCU <- BTS] TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=WAIT RELEASE) Packet Control Ack TBF: [UPLINK] DOWNLINK ASSIGNED TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=WAIT RELEASE) -DL packet loss of IMSI=0011223344 / TLLI=0xf1223344: 0% -TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=WAIT RELEASE) free -TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=WAIT RELEASE) stopping timer 3193. -PDCH(TS 7, TRX 0): Detaching TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=WAIT RELEASE), 1 TBFs, USFs = 01, TFIs = 00000002. -Detaching TBF from MS object, TLLI = 0xf1223344, TBF = TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=WAIT RELEASE) +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=WAIT RELEASE) changes state from WAIT RELEASE to RELEASING +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=RELEASING) free +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=RELEASING) stopping timer 3193. +PDCH(TS 7, TRX 0): Detaching TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=RELEASING), 1 TBFs, USFs = 01, TFIs = 00000002. +Detaching TBF from MS object, TLLI = 0xf1223344, TBF = TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=RELEASING) ********** TBF ends here ********** TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=ASSIGN) changes state from ASSIGN to FLOW TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW) stopping timer 0. @@ -3113,12 +3118,13 @@ PDCH(TS 5, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL), 1 TBF Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL) Allocated TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL): trx = 0, ul_slots = 10, dl_slots = 3c DL TBF slots: 0x3c, N: 4, WS: 64 -TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL) free -PDCH(TS 2, TRX 0): Detaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL), 0 TBFs, USFs = 00, TFIs = 00000000. -PDCH(TS 3, TRX 0): Detaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL), 0 TBFs, USFs = 00, TFIs = 00000000. -PDCH(TS 4, TRX 0): Detaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL), 0 TBFs, USFs = 00, TFIs = 00000000. -PDCH(TS 5, TRX 0): Detaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL), 0 TBFs, USFs = 00, TFIs = 00000000. -Detaching TBF from MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL) +TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL) changes state from NULL to RELEASING +TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=RELEASING) free +PDCH(TS 2, TRX 0): Detaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=RELEASING), 0 TBFs, USFs = 00, TFIs = 00000000. +PDCH(TS 3, TRX 0): Detaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=RELEASING), 0 TBFs, USFs = 00, TFIs = 00000000. +PDCH(TS 4, TRX 0): Detaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=RELEASING), 0 TBFs, USFs = 00, TFIs = 00000000. +PDCH(TS 5, TRX 0): Detaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=RELEASING), 0 TBFs, USFs = 00, TFIs = 00000000. +Detaching TBF from MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=RELEASING) Destroying MS object, TLLI = 0x00000000 ********** TBF ends here ********** ********** TBF starts here ********** @@ -3152,11 +3158,12 @@ Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 D Allocated TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 10, dl_slots = 3c TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 384 DL TBF slots: 0x3c, N: 4, WS: 384 -TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) free -PDCH(TS 2, TRX 0): Detaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), 0 TBFs, USFs = 00, TFIs = 00000000. -PDCH(TS 3, TRX 0): Detaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), 0 TBFs, USFs = 00, TFIs = 00000000. -PDCH(TS 4, TRX 0): Detaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), 0 TBFs, USFs = 00, TFIs = 00000000. -PDCH(TS 5, TRX 0): Detaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), 0 TBFs, USFs = 00, TFIs = 00000000. -Detaching TBF from MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) +TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) changes state from NULL to RELEASING +TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=RELEASING EGPRS) free +PDCH(TS 2, TRX 0): Detaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=RELEASING EGPRS), 0 TBFs, USFs = 00, TFIs = 00000000. +PDCH(TS 3, TRX 0): Detaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=RELEASING EGPRS), 0 TBFs, USFs = 00, TFIs = 00000000. +PDCH(TS 4, TRX 0): Detaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=RELEASING EGPRS), 0 TBFs, USFs = 00, TFIs = 00000000. +PDCH(TS 5, TRX 0): Detaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=RELEASING EGPRS), 0 TBFs, USFs = 00, TFIs = 00000000. +Detaching TBF from MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=RELEASING EGPRS) Destroying MS object, TLLI = 0x00000000 ********** TBF ends here ********** -- cgit v1.2.3 From 5f93f855a77928bb77f47f104e6e3ff0bfac74d1 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Thu, 21 Jan 2016 20:48:39 +0100 Subject: tbf: Do not reuse old TBF after RACH requests Currently existing TBF can be reused after an MS has sent a RACH request. Since the MS can be or most probably is in packet idle mode in that case, the TBF are no longer usable even if they share the PDCHs and the control TS with the new one. There are occasional freezes where the MS does no longer react to messages sent on the PACCH. This change aborts all pending TBFs if a new TBF is or has been established via RACH. Sponsored-by: On-Waves ehf --- src/bts.cpp | 12 ++++-------- src/tbf.cpp | 15 ++++++++------- tests/tbf/TbfTest.cpp | 5 ++--- tests/tbf/TbfTest.err | 29 +++++++++++++++++++---------- 4 files changed, 33 insertions(+), 28 deletions(-) diff --git a/src/bts.cpp b/src/bts.cpp index c0918dd1..61dfc87b 100644 --- a/src/bts.cpp +++ b/src/bts.cpp @@ -1114,28 +1114,24 @@ void gprs_rlcmac_pdch::rcv_resource_request(Packet_Resource_Request_t *request, ta = ms->ta(); } + /* We got a RACH so the MS was in packet idle mode and thus + * didn't have any active TBFs */ if (ul_tbf) { LOGP(DRLCMACUL, LOGL_NOTICE, "Got RACH from " "TLLI=0x%08x while %s still " "exists. Killing pending UL TBF\n", tlli, tbf_name(ul_tbf)); - /* The MS will not use the old TBF again, so we can - * safely throw it away immediately */ tbf_free(ul_tbf); ul_tbf = NULL; } if (dl_tbf) { - /* TODO: There a chance that releasing dl_tbf can be - * avoided if this PDCH is the control TS of dl_tbf, - * but this needs to be checked with the spec. If an MS - * losed the DL TBF because of PDCH mismatches only, - * this check would make sense. */ LOGP(DRLCMACUL, LOGL_NOTICE, "Got RACH from " "TLLI=0x%08x while %s still exists. " "Release pending DL TBF\n", tlli, tbf_name(dl_tbf)); - dl_tbf->release(); + tbf_free(dl_tbf); + dl_tbf = NULL; } LOGP(DRLCMAC, LOGL_DEBUG, "MS requests UL TBF " "in packet resource request of single " diff --git a/src/tbf.cpp b/src/tbf.cpp index 93c932b5..80183474 100644 --- a/src/tbf.cpp +++ b/src/tbf.cpp @@ -1072,15 +1072,8 @@ int gprs_rlcmac_tbf::set_tlli_from_ul(uint32_t new_tlli) if (!ms()) set_ms(old_ms); - - /* there might be an active and valid downlink TBF */ - if (!ms()->dl_tbf() && dl_tbf) - /* Move it to the current MS (see the guard above) */ - dl_tbf->set_ms(ms()); } - /* The TLLI has been taken from an UL message */ - update_ms(new_tlli, GPRS_RLCMAC_UL_TBF); if (dl_tbf && dl_tbf->ms() != ms()) { LOGP(DRLCMACUL, LOGL_NOTICE, "Got RACH from " "TLLI=0x%08x while %s still exists. " @@ -1097,6 +1090,14 @@ int gprs_rlcmac_tbf::set_tlli_from_ul(uint32_t new_tlli) tbf_free(ul_tbf); ul_tbf = NULL; } + + /* The TLLI has been taken from an UL message */ + update_ms(new_tlli, GPRS_RLCMAC_UL_TBF); + +#if 0 /* REMOVEME ??? */ + if (ms()->need_dl_tbf()) + establish_dl_tbf_on_pacch(); +#endif return 1; } diff --git a/tests/tbf/TbfTest.cpp b/tests/tbf/TbfTest.cpp index c868ca2d..d2b4cfc9 100644 --- a/tests/tbf/TbfTest.cpp +++ b/tests/tbf/TbfTest.cpp @@ -963,9 +963,8 @@ static void test_tbf_dl_flow_and_rach_single_phase() OSMO_ASSERT(ms2 == ms); OSMO_ASSERT(ms1 != ms); - /* DL TBF should be the same */ - OSMO_ASSERT(ms->dl_tbf()); - OSMO_ASSERT(ms->dl_tbf() == dl_tbf); + /* DL TBF should be removed */ + OSMO_ASSERT(!ms->dl_tbf()); /* No queued packets should be lost */ OSMO_ASSERT(ms->llc_queue()->size() == 2); diff --git a/tests/tbf/TbfTest.err b/tests/tbf/TbfTest.err index 8f920ca0..350966ea 100644 --- a/tests/tbf/TbfTest.err +++ b/tests/tbf/TbfTest.err @@ -1902,8 +1902,12 @@ Got RLC block, coding scheme: CS-1, length: 23 (23)) +++++++++++++++++++++++++ RX : Uplink Control Block +++++++++++++++++++++++++ ------------------------- RX : Uplink Control Block ------------------------- Got RACH from TLLI=0xf1223344 while TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=ASSIGN) still exists. Release pending DL TBF -TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT RELEASE -TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=WAIT RELEASE) restarting timer 3193 while old timer 0 pending +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=ASSIGN) changes state from ASSIGN to RELEASING +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=RELEASING) free +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=RELEASING) stopping timer 0. +PDCH(TS 7, TRX 0): Detaching TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=RELEASING), 0 TBFs, USFs = 00, TFIs = 00000000. +Detaching TBF from MS object, TLLI = 0xf1223344, TBF = TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=RELEASING) +********** TBF ends here ********** MS requests UL TBF in packet resource request of single block, so we provide one: ********** TBF starts here ********** Allocating UL TBF: MS_CLASS=1/0 @@ -1945,15 +1949,15 @@ Slot Allocation (Algorithm A) for class 1 - Skipping TS 4, because not enabled - Skipping TS 5, because not enabled - Skipping TS 6, because not enabled -- Assign downlink TS=7 TFI=1 -PDCH(TS 7, TRX 0): Attaching TBF(TFI=1 TLLI=0x00000000 DIR=DL STATE=NULL), 2 TBFs, USFs = 01, TFIs = 00000003. +- Assign downlink TS=7 TFI=0 +PDCH(TS 7, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL), 1 TBFs, USFs = 01, TFIs = 00000001. - Setting Control TS 7 -Attaching TBF to MS object, TLLI = 0xf1223344, TBF = TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=NULL) -Allocated TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=NULL): trx = 0, ul_slots = 80, dl_slots = 80 +Attaching TBF to MS object, TLLI = 0xf1223344, TBF = TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL) +Allocated TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL): trx = 0, ul_slots = 80, dl_slots = 80 TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW) Trigger downlink assignment on PACCH Send dowlink assignment on PACCH, because TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW) exists -TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=NULL) changes state from NULL to ASSIGN -TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=ASSIGN) starting timer 0. +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL) changes state from NULL to ASSIGN +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=ASSIGN) starting timer 0. Got RLC block, coding scheme: CS-1, length: 23 (23)) UL data: 3c 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Got CS-1 RLC block: R=0, SI=0, TFI=0, CPS=0, RSB=0, rc=184 @@ -2096,8 +2100,13 @@ TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=FLOW): Got CS-1 RLC data block: CV=0, BSN - BSN 0 storing in window (0..63) TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=FLOW): data_length=20, data=f1 22 33 44 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Decoded premier TLLI=0x00000000 of UL DATA TFI=0. -Detaching TBF from MS object, TLLI = 0xf1223344, TBF = TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=ASSIGN) -Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=ASSIGN) +Got RACH from TLLI=0x00000000 while TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=ASSIGN) still exists. Killing pending DL TBF +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=ASSIGN) changes state from ASSIGN to RELEASING +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=RELEASING) free +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=RELEASING) stopping timer 0. +PDCH(TS 7, TRX 0): Detaching TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=RELEASING), 0 TBFs, USFs = 01, TFIs = 00000000. +Detaching TBF from MS object, TLLI = 0xf1223344, TBF = TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=RELEASING) +********** TBF ends here ********** Modifying MS object, TLLI = 0x00000000, IMSI '' -> '0011223344' Modifying MS object, TLLI = 0x00000000, MS class 0 -> 1 Clearing MS object, TLLI: 0xf1223344, IMSI: '0011223344' -- cgit v1.2.3 From 5a3c84d0fd41a2477463e6f1df108b5b4369a434 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Fri, 22 Jan 2016 17:25:38 +0100 Subject: sched: Pass the current TS to the control create functions Currently the checks in that function are based on the different internal TS values of a TBF. It is assumed that they match the TS that the current RTS refers to. This commit adds a TS parameter to create_ul_ass, create_dl_ass, and create_ul_ack to make this more explicit. Sponsored-by: On-Waves ehf --- src/gprs_rlcmac_sched.cpp | 6 +++--- src/tbf.cpp | 14 +++++++------- src/tbf.h | 6 +++--- src/tbf_ul.cpp | 4 ++-- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/gprs_rlcmac_sched.cpp b/src/gprs_rlcmac_sched.cpp index 4939efd8..140a0be7 100644 --- a/src/gprs_rlcmac_sched.cpp +++ b/src/gprs_rlcmac_sched.cpp @@ -131,11 +131,11 @@ static struct msgb *sched_select_ctrl_msg( continue; if (tbf == ul_ass_tbf) - msg = ul_ass_tbf->create_ul_ass(fn); + msg = ul_ass_tbf->create_ul_ass(fn, ts); else if (tbf == dl_ass_tbf) - msg = dl_ass_tbf->create_dl_ass(fn); + msg = dl_ass_tbf->create_dl_ass(fn, ts); else if (tbf == ul_ack_tbf) - msg = ul_ack_tbf->create_ul_ack(fn); + msg = ul_ack_tbf->create_ul_ack(fn, ts); else abort(); diff --git a/src/tbf.cpp b/src/tbf.cpp index 80183474..f73f1e07 100644 --- a/src/tbf.cpp +++ b/src/tbf.cpp @@ -855,16 +855,16 @@ int gprs_rlcmac_tbf::rlcmac_diag() return 0; } -struct msgb *gprs_rlcmac_tbf::create_dl_ass(uint32_t fn) +struct msgb *gprs_rlcmac_tbf::create_dl_ass(uint32_t fn, uint8_t ts) { struct msgb *msg; struct gprs_rlcmac_dl_tbf *new_dl_tbf = NULL; int poll_ass_dl = 1; - if (direction == GPRS_RLCMAC_DL_TBF && control_ts != first_common_ts) { + if (direction == GPRS_RLCMAC_DL_TBF && ts != first_common_ts) { LOGP(DRLCMAC, LOGL_NOTICE, "Cannot poll for downlink " - "assigment, because MS cannot reply. (control TS=%d, " - "first common TS=%d)\n", control_ts, + "assigment, because MS cannot reply. (TS=%d, " + "first common TS=%d)\n", ts, first_common_ts); poll_ass_dl = 0; } @@ -875,7 +875,7 @@ struct msgb *gprs_rlcmac_tbf::create_dl_ass(uint32_t fn) "assignment...\n", tbf_name(this)); return NULL; } - if (bts->sba()->find(trx->trx_no, control_ts, (fn + 13) % 2715648)) { + if (bts->sba()->find(trx->trx_no, ts, (fn + 13) % 2715648)) { LOGP(DRLCMACUL, LOGL_DEBUG, "Polling is already " "scheduled for single block allocation...\n"); return NULL; @@ -951,7 +951,7 @@ struct msgb *gprs_rlcmac_tbf::create_dl_ass(uint32_t fn) return msg; } -struct msgb *gprs_rlcmac_tbf::create_ul_ass(uint32_t fn) +struct msgb *gprs_rlcmac_tbf::create_ul_ass(uint32_t fn, uint8_t ts) { struct msgb *msg; struct gprs_rlcmac_ul_tbf *new_tbf = NULL; @@ -962,7 +962,7 @@ struct msgb *gprs_rlcmac_tbf::create_ul_ass(uint32_t fn) "assignment...\n", tbf_name(this)); return NULL; } - if (bts->sba()->find(trx->trx_no, control_ts, (fn + 13) % 2715648)) { + if (bts->sba()->find(trx->trx_no, ts, (fn + 13) % 2715648)) { LOGP(DRLCMACUL, LOGL_DEBUG, "Polling is already scheduled for " "single block allocation...\n"); return NULL; diff --git a/src/tbf.h b/src/tbf.h index 957baedf..835d2c48 100644 --- a/src/tbf.h +++ b/src/tbf.h @@ -101,8 +101,8 @@ struct gprs_rlcmac_tbf { const char *name() const; - struct msgb *create_dl_ass(uint32_t fn); - struct msgb *create_ul_ass(uint32_t fn); + struct msgb *create_dl_ass(uint32_t fn, uint8_t ts); + struct msgb *create_ul_ass(uint32_t fn, uint8_t ts); GprsMs *ms() const; void set_ms(GprsMs *ms); @@ -413,7 +413,7 @@ protected: struct gprs_rlcmac_ul_tbf : public gprs_rlcmac_tbf { gprs_rlcmac_ul_tbf(BTS *bts); - struct msgb *create_ul_ack(uint32_t fn); + struct msgb *create_ul_ack(uint32_t fn, uint8_t ts); /* blocks were acked */ int rcv_data_block_acknowledged( diff --git a/src/tbf_ul.cpp b/src/tbf_ul.cpp index 1d0b1681..1ccfa27b 100644 --- a/src/tbf_ul.cpp +++ b/src/tbf_ul.cpp @@ -87,7 +87,7 @@ int gprs_rlcmac_ul_tbf::assemble_forward_llc(const gprs_rlc_data *_data) } -struct msgb *gprs_rlcmac_ul_tbf::create_ul_ack(uint32_t fn) +struct msgb *gprs_rlcmac_ul_tbf::create_ul_ack(uint32_t fn, uint8_t ts) { int final = (state_is(GPRS_RLCMAC_FINISHED)); struct msgb *msg; @@ -99,7 +99,7 @@ struct msgb *gprs_rlcmac_ul_tbf::create_ul_ack(uint32_t fn) "final uplink ack...\n", tbf_name(this)); return NULL; } - if (bts->sba()->find(trx->trx_no, control_ts, (fn + 13) % 2715648)) { + if (bts->sba()->find(trx->trx_no, ts, (fn + 13) % 2715648)) { LOGP(DRLCMACUL, LOGL_DEBUG, "Polling is already " "scheduled for single block allocation...\n"); return NULL; -- cgit v1.2.3 From 646da1ba8dea43035c5ade1949b1876e5e1cbfa0 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Fri, 22 Jan 2016 17:41:33 +0100 Subject: tbf: Use is_control_ts() instead of comparing TS values directly Currently there are some places where tbf->control_ts != ts is evaluated to check, whether ts is a control slot. Replace these expressions by tbf->is_control_ts(ts) which does the same whitout exposing internal fields. Sponsored-by: On-Waves ehf --- src/gprs_rlcmac_sched.cpp | 4 ++-- src/tbf.cpp | 7 ++++++- src/tbf.h | 6 ++---- src/tbf_dl.cpp | 2 +- 4 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/gprs_rlcmac_sched.cpp b/src/gprs_rlcmac_sched.cpp index 140a0be7..e03f84be 100644 --- a/src/gprs_rlcmac_sched.cpp +++ b/src/gprs_rlcmac_sched.cpp @@ -46,7 +46,7 @@ static uint32_t sched_poll(BTS *bts, ul_tbf = as_ul_tbf(pos->entry()); OSMO_ASSERT(ul_tbf); /* this trx, this ts */ - if (ul_tbf->trx->trx_no != trx || ul_tbf->control_ts != ts) + if (ul_tbf->trx->trx_no != trx || !ul_tbf->is_control_ts(ts)) continue; /* polling for next uplink block */ if (ul_tbf->poll_state == GPRS_RLCMAC_POLL_SCHED @@ -64,7 +64,7 @@ static uint32_t sched_poll(BTS *bts, dl_tbf = as_dl_tbf(pos->entry()); OSMO_ASSERT(dl_tbf); /* this trx, this ts */ - if (dl_tbf->trx->trx_no != trx || dl_tbf->control_ts != ts) + if (dl_tbf->trx->trx_no != trx || !dl_tbf->is_control_ts(ts)) continue; /* polling for next uplink block */ if (dl_tbf->poll_state == GPRS_RLCMAC_POLL_SCHED diff --git a/src/tbf.cpp b/src/tbf.cpp index f73f1e07..35a004cf 100644 --- a/src/tbf.cpp +++ b/src/tbf.cpp @@ -861,7 +861,7 @@ struct msgb *gprs_rlcmac_tbf::create_dl_ass(uint32_t fn, uint8_t ts) struct gprs_rlcmac_dl_tbf *new_dl_tbf = NULL; int poll_ass_dl = 1; - if (direction == GPRS_RLCMAC_DL_TBF && ts != first_common_ts) { + if (direction == GPRS_RLCMAC_DL_TBF && !is_control_ts(ts)) { LOGP(DRLCMAC, LOGL_NOTICE, "Cannot poll for downlink " "assigment, because MS cannot reply. (TS=%d, " "first common TS=%d)\n", ts, @@ -1171,3 +1171,8 @@ uint8_t gprs_rlcmac_tbf::ul_slots() const return slots; } + +bool gprs_rlcmac_tbf::is_control_ts(uint8_t ts) const +{ + return ts == control_ts; +} diff --git a/src/tbf.h b/src/tbf.h index 835d2c48..f3487c6e 100644 --- a/src/tbf.h +++ b/src/tbf.h @@ -144,6 +144,8 @@ struct gprs_rlcmac_tbf { uint8_t dl_slots() const; uint8_t ul_slots() const; + bool is_control_ts(uint8_t ts) const; + /* EGPRS */ bool is_egprs_enabled() const; void enable_egprs(); @@ -357,10 +359,6 @@ struct gprs_rlcmac_dl_tbf : public gprs_rlcmac_tbf { int release(); int abort(); - bool is_control_ts(uint8_t ts) const { - return ts == control_ts; - } - /* TODO: add the gettimeofday as parameter */ struct msgb *llc_dequeue(bssgp_bvc_ctx *bctx); diff --git a/src/tbf_dl.cpp b/src/tbf_dl.cpp index 64ebea4f..21a042ed 100644 --- a/src/tbf_dl.cpp +++ b/src/tbf_dl.cpp @@ -575,7 +575,7 @@ struct msgb *gprs_rlcmac_dl_tbf::create_dl_acked_block( LOGP(DRLCMACDL, LOGL_DEBUG, "Polling is already " "sheduled for %s, so we must wait for " "requesting downlink ack\n", tbf_name(this)); - else if (control_ts != ts) + else if (!is_control_ts(ts)) LOGP(DRLCMACDL, LOGL_DEBUG, "Polling cannot be " "sheduled in this TS %d, waiting for " "TS %d\n", ts, control_ts); -- cgit v1.2.3 From 81a04f7d79ab290028074cfa626498abfdb09937 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Thu, 28 Jan 2016 16:14:58 +0100 Subject: tbf: Mark control slots in VTY TBF out Put an '!' after the PDCH number in the output of the 'show tbf' command, if is_control_ts() yields true. Sponsored-by: On-Waves ehf --- src/pcu_vty_functions.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/pcu_vty_functions.cpp b/src/pcu_vty_functions.cpp index a8b5ddd7..6567962d 100644 --- a/src/pcu_vty_functions.cpp +++ b/src/pcu_vty_functions.cpp @@ -56,8 +56,9 @@ static void tbf_print_vty_info(struct vty *vty, gprs_rlcmac_tbf *tbf) VTY_NEWLINE); vty_out(vty, " TS_alloc="); for (int i = 0; i < 8; i++) { + bool is_ctrl = tbf->is_control_ts(i); if (tbf->pdch[i]) - vty_out(vty, "%d ", i); + vty_out(vty, "%d%s ", i, is_ctrl ? "!" : ""); } vty_out(vty, " CS=%s WS=%d", tbf->current_cs().name(), tbf->window()->ws()); -- cgit v1.2.3 From 8eb17143f2b3ab5d96c46d698722de9dc83ac5f4 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Fri, 22 Jan 2016 17:58:17 +0100 Subject: tbf: Add and use tbf->poll_ts Currently tbf->control_ts is used to look up an incoming poll response. Since that may eventually change, poll timeouts could theoretically happen in that case. Store the real poll TS in tbf->poll_ts at all places where tbf->poll_fn is set. Do not use tbf->control_ts to look up outstanding polls. Sponsored-by: On-Waves ehf --- src/bts.cpp | 4 ++-- src/tbf.cpp | 15 +++++++++------ src/tbf.h | 1 + src/tbf_dl.cpp | 3 ++- src/tbf_ul.cpp | 1 + tests/tbf/TbfTest.cpp | 5 +++-- tests/tbf/TbfTest.err | 28 ++++++++++++++-------------- 7 files changed, 32 insertions(+), 25 deletions(-) diff --git a/src/bts.cpp b/src/bts.cpp index 61dfc87b..0356718f 100644 --- a/src/bts.cpp +++ b/src/bts.cpp @@ -307,7 +307,7 @@ gprs_rlcmac_dl_tbf *BTS::dl_tbf_by_poll_fn(uint32_t fn, uint8_t trx, uint8_t ts) if (tbf->state_is_not(GPRS_RLCMAC_RELEASING) && tbf->poll_state == GPRS_RLCMAC_POLL_SCHED && tbf->poll_fn == fn && tbf->trx->trx_no == trx - && tbf->control_ts == ts) { + && tbf->poll_ts == ts) { return tbf; } } @@ -325,7 +325,7 @@ gprs_rlcmac_ul_tbf *BTS::ul_tbf_by_poll_fn(uint32_t fn, uint8_t trx, uint8_t ts) if (tbf->state_is_not(GPRS_RLCMAC_RELEASING) && tbf->poll_state == GPRS_RLCMAC_POLL_SCHED && tbf->poll_fn == fn && tbf->trx->trx_no == trx - && tbf->control_ts == ts) { + && tbf->poll_ts == ts) { return tbf; } } diff --git a/src/tbf.cpp b/src/tbf.cpp index 35a004cf..6e516280 100644 --- a/src/tbf.cpp +++ b/src/tbf.cpp @@ -61,6 +61,7 @@ gprs_rlcmac_tbf::gprs_rlcmac_tbf(BTS *bts_, gprs_rlcmac_tbf_direction dir) : ul_ack_state(GPRS_RLCMAC_UL_ACK_NONE), poll_state(GPRS_RLCMAC_POLL_NONE), poll_fn(0), + poll_ts(0), n3105(0), T(0), num_T_exp(0), @@ -436,8 +437,8 @@ void gprs_rlcmac_tbf::stop_timer() void gprs_rlcmac_tbf::poll_timeout() { - LOGP(DRLCMAC, LOGL_NOTICE, "%s poll timeout for FN=%d (curr FN %d)\n", - tbf_name(this), poll_fn, bts->current_frame_number()); + LOGP(DRLCMAC, LOGL_NOTICE, "%s poll timeout for FN=%d, TS=%d (curr FN %d)\n", + tbf_name(this), poll_fn, poll_ts, bts->current_frame_number()); poll_state = GPRS_RLCMAC_POLL_NONE; @@ -935,10 +936,11 @@ struct msgb *gprs_rlcmac_tbf::create_dl_ass(uint32_t fn, uint8_t ts) if (poll_ass_dl) { poll_state = GPRS_RLCMAC_POLL_SCHED; poll_fn = (fn + 13) % 2715648; + poll_ts = ts; dl_ass_state = GPRS_RLCMAC_DL_ASS_WAIT_ACK; LOGP(DRLCMACDL, LOGL_INFO, - "%s Scheduled DL Assignment polling on FN=%d\n", - name(), poll_fn); + "%s Scheduled DL Assignment polling on FN=%d, TS=%d\n", + name(), poll_fn, poll_ts); } else { dl_ass_state = GPRS_RLCMAC_DL_ASS_NONE; new_dl_tbf->set_state(GPRS_RLCMAC_FLOW); @@ -1004,10 +1006,11 @@ struct msgb *gprs_rlcmac_tbf::create_ul_ass(uint32_t fn, uint8_t ts) poll_state = GPRS_RLCMAC_POLL_SCHED; poll_fn = (fn + 13) % 2715648; + poll_ts = ts; ul_ass_state = GPRS_RLCMAC_UL_ASS_WAIT_ACK; LOGP(DRLCMACDL, LOGL_INFO, - "%s Scheduled UL Assignment polling on FN=%d\n", - name(), poll_fn); + "%s Scheduled UL Assignment polling on FN=%d, TS=%d\n", + name(), poll_fn, poll_ts); return msg; } diff --git a/src/tbf.h b/src/tbf.h index f3487c6e..d23cf933 100644 --- a/src/tbf.h +++ b/src/tbf.h @@ -177,6 +177,7 @@ struct gprs_rlcmac_tbf { enum gprs_rlcmac_tbf_poll_state poll_state; uint32_t poll_fn; /* frame number to poll */ + uint8_t poll_ts; /* TS to poll */ gprs_rlc m_rlc; diff --git a/src/tbf_dl.cpp b/src/tbf_dl.cpp index 21a042ed..10b376ff 100644 --- a/src/tbf_dl.cpp +++ b/src/tbf_dl.cpp @@ -594,6 +594,7 @@ struct msgb *gprs_rlcmac_dl_tbf::create_dl_acked_block( /* schedule polling */ poll_state = GPRS_RLCMAC_POLL_SCHED; poll_fn = (fn + 13) % 2715648; + poll_ts = ts; /* Clear poll timeout flag */ state_flags &= ~(1 << GPRS_RLCMAC_FLAG_TO_DL_ACK); @@ -609,7 +610,7 @@ struct msgb *gprs_rlcmac_dl_tbf::create_dl_acked_block( LOGP(DRLCMACDL, LOGL_INFO, "%s Scheduled Ack/Nack polling on FN=%d, TS=%d\n", - name(), poll_fn, ts); + name(), poll_fn, poll_ts); } } diff --git a/src/tbf_ul.cpp b/src/tbf_ul.cpp index 1ccfa27b..4754e11f 100644 --- a/src/tbf_ul.cpp +++ b/src/tbf_ul.cpp @@ -127,6 +127,7 @@ struct msgb *gprs_rlcmac_ul_tbf::create_ul_ack(uint32_t fn, uint8_t ts) if (final) { poll_state = GPRS_RLCMAC_POLL_SCHED; poll_fn = (fn + 13) % 2715648; + poll_ts = ts; /* waiting for final acknowledge */ ul_ack_state = GPRS_RLCMAC_UL_ACK_WAIT_ACK; m_final_ack_sent = 1; diff --git a/tests/tbf/TbfTest.cpp b/tests/tbf/TbfTest.cpp index d2b4cfc9..0ff4f98c 100644 --- a/tests/tbf/TbfTest.cpp +++ b/tests/tbf/TbfTest.cpp @@ -605,6 +605,7 @@ static void send_control_ack(gprs_rlcmac_tbf *tbf) RlcMacUplink_t ulreq = {0}; OSMO_ASSERT(tbf->poll_fn != 0); + OSMO_ASSERT(tbf->is_control_ts(tbf->poll_ts)); ulreq.u.MESSAGE_TYPE = MT_PACKET_CONTROL_ACK; Packet_Control_Acknowledgement_t *ctrl_ack = @@ -612,7 +613,7 @@ static void send_control_ack(gprs_rlcmac_tbf *tbf) ctrl_ack->PayloadType = GPRS_RLCMAC_CONTROL_BLOCK; ctrl_ack->TLLI = tbf->tlli(); - send_ul_mac_block(tbf->bts, tbf->trx->trx_no, tbf->control_ts, + send_ul_mac_block(tbf->bts, tbf->trx->trx_no, tbf->poll_ts, &ulreq, tbf->poll_fn); } @@ -1043,7 +1044,7 @@ static void test_tbf_dl_reuse() ack->DOWNLINK_TFI = dl_tbf1->tfi(); ack->Ack_Nack_Description.FINAL_ACK_INDICATION = 1; - send_ul_mac_block(&the_bts, 0, ts_no, &ulreq, dl_tbf1->poll_fn); + send_ul_mac_block(&the_bts, 0, dl_tbf1->poll_ts, &ulreq, dl_tbf1->poll_fn); OSMO_ASSERT(dl_tbf1->state_is(GPRS_RLCMAC_WAIT_RELEASE)); diff --git a/tests/tbf/TbfTest.err b/tests/tbf/TbfTest.err index 350966ea..80f3f854 100644 --- a/tests/tbf/TbfTest.err +++ b/tests/tbf/TbfTest.err @@ -61,7 +61,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) append TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) start Packet Downlink Assignment (PACCH) +++++++++++++++++++++++++ TX : Packet Downlink Assignment +++++++++++++++++++++++++ ------------------------- TX : Packet Downlink Assignment ------------------------- -TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) Scheduled DL Assignment polling on FN=13 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) Scheduled DL Assignment polling on FN=13, TS=4 Scheduling control message at RTS for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) (TRX=0, TS=4) Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=0 block=0 data=4f 08 20 00 44 02 00 02 08 04 00 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 @@ -142,7 +142,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) append TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) start Packet Downlink Assignment (PACCH) +++++++++++++++++++++++++ TX : Packet Downlink Assignment +++++++++++++++++++++++++ ------------------------- TX : Packet Downlink Assignment ------------------------- -TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) Scheduled DL Assignment polling on FN=13 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) Scheduled DL Assignment polling on FN=13, TS=4 Scheduling control message at RTS for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) (TRX=0, TS=4) Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=0 block=0 data=4f 08 20 00 44 02 00 02 08 04 00 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 @@ -223,7 +223,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) append TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) start Packet Downlink Assignment (PACCH) +++++++++++++++++++++++++ TX : Packet Downlink Assignment +++++++++++++++++++++++++ ------------------------- TX : Packet Downlink Assignment ------------------------- -TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) Scheduled DL Assignment polling on FN=13 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) Scheduled DL Assignment polling on FN=13, TS=4 Scheduling control message at RTS for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) (TRX=0, TS=4) Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=0 block=0 data=4f 08 20 00 44 02 00 02 08 04 00 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 @@ -1549,7 +1549,7 @@ Change control TS to 7 until assinment is complete. TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN)s start Packet Uplink Assignment (PACCH) +++++++++++++++++++++++++ TX : Packet Uplink Assignment +++++++++++++++++++++++++ ------------------------- TX : Packet Uplink Assignment ------------------------- -TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) Scheduled UL Assignment polling on FN=2654283 +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) Scheduled UL Assignment polling on FN=2654283, TS=7 Scheduling control message at RTS for TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) (TRX=0, TS=7) Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654270 block=8 data=4f 28 5e 24 46 68 8f 1d 00 00 88 00 08 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b Got RLC block, coding scheme: CS-1, length: 23 (23)) @@ -1633,7 +1633,7 @@ Change control TS to 7 until assinment is complete. TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN)s start Packet Uplink Assignment (PACCH) +++++++++++++++++++++++++ TX : Packet Uplink Assignment +++++++++++++++++++++++++ ------------------------- TX : Packet Uplink Assignment ------------------------- -TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) Scheduled UL Assignment polling on FN=2654283 +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) Scheduled UL Assignment polling on FN=2654283, TS=7 Scheduling control message at RTS for TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) (TRX=0, TS=7) Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654270 block=8 data=4f 28 5e 24 46 68 8f 1d 00 00 88 00 08 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b Got RLC block, coding scheme: CS-1, length: 23 (23)) @@ -1683,7 +1683,7 @@ Received RTS for PDCH: TRX=0 TS=7 FN=2654275 block_nr=9 scheduling USF=0 for req TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=ASSIGN) start Packet Downlink Assignment (PACCH) +++++++++++++++++++++++++ TX : Packet Downlink Assignment +++++++++++++++++++++++++ ------------------------- TX : Packet Downlink Assignment ------------------------- -TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW) Scheduled DL Assignment polling on FN=2654288 +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW) Scheduled DL Assignment polling on FN=2654288, TS=7 Scheduling control message at RTS for TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW) (TRX=0, TS=7) Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654275 block=9 data=48 08 00 00 0c 72 00 02 08 00 80 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b Got RLC block, coding scheme: CS-1, length: 23 (23)) @@ -1731,7 +1731,7 @@ TX: Immediate Assignment Uplink (AGCH) Sending data request: trx=0 ts=0 sapi=2 arfcn=0 fn=0 block=0 data=2d 06 3f 10 0f 00 00 73 8c f6 07 00 c0 0c 68 ab 2b 2b 2b 2b 2b 2b 2b Searching for first unallocated TFI: TRX=0 Found TFI=1. -TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FINISHED) poll timeout for FN=2654292 (curr FN 2654335) +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FINISHED) poll timeout for FN=2654292, TS=7 (curr FN 2654335) - Timeout for polling PACKET DOWNLINK ACK. - Assignment was on PACCH - No downlink ACK received yet @@ -1765,7 +1765,7 @@ Received RTS for PDCH: TRX=0 TS=7 FN=2654335 block_nr=11 scheduling USF=0 for re TBF(TFI=1 TLLI=0xf5667788 DIR=UL STATE=ASSIGN)s start Packet Uplink Assignment (PACCH) +++++++++++++++++++++++++ TX : Packet Uplink Assignment +++++++++++++++++++++++++ ------------------------- TX : Packet Uplink Assignment ------------------------- -TBF(TFI=1 TLLI=0xf5667788 DIR=UL STATE=ASSIGN) Scheduled UL Assignment polling on FN=2654348 +TBF(TFI=1 TLLI=0xf5667788 DIR=UL STATE=ASSIGN) Scheduled UL Assignment polling on FN=2654348, TS=7 Scheduling control message at RTS for TBF(TFI=1 TLLI=0xf5667788 DIR=UL STATE=ASSIGN) (TRX=0, TS=7) Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654335 block=11 data=48 28 5e ac ce f1 0f 1d 00 00 88 40 09 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b Got RLC block, coding scheme: CS-1, length: 23 (23)) @@ -1835,7 +1835,7 @@ Change control TS to 7 until assinment is complete. TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN)s start Packet Uplink Assignment (PACCH) +++++++++++++++++++++++++ TX : Packet Uplink Assignment +++++++++++++++++++++++++ ------------------------- TX : Packet Uplink Assignment ------------------------- -TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) Scheduled UL Assignment polling on FN=2654283 +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) Scheduled UL Assignment polling on FN=2654283, TS=7 Scheduling control message at RTS for TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) (TRX=0, TS=7) Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654270 block=8 data=4f 28 5e 24 46 68 83 1d 00 00 88 00 08 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b Got RLC block, coding scheme: CS-1, length: 23 (23)) @@ -1930,7 +1930,7 @@ Change control TS to 7 until assinment is complete. TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN)s start Packet Uplink Assignment (PACCH) +++++++++++++++++++++++++ TX : Packet Uplink Assignment +++++++++++++++++++++++++ ------------------------- TX : Packet Uplink Assignment ------------------------- -TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) Scheduled UL Assignment polling on FN=2654340 +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) Scheduled UL Assignment polling on FN=2654340, TS=7 Scheduling control message at RTS for TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) (TRX=0, TS=7) Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654327 block=9 data=4f 28 5e 24 46 68 83 1d 00 00 88 00 08 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b Got RLC block, coding scheme: CS-1, length: 23 (23)) @@ -2010,7 +2010,7 @@ Change control TS to 7 until assinment is complete. TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN)s start Packet Uplink Assignment (PACCH) +++++++++++++++++++++++++ TX : Packet Uplink Assignment +++++++++++++++++++++++++ ------------------------- TX : Packet Uplink Assignment ------------------------- -TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) Scheduled UL Assignment polling on FN=2654283 +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) Scheduled UL Assignment polling on FN=2654283, TS=7 Scheduling control message at RTS for TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) (TRX=0, TS=7) Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654270 block=8 data=4f 28 5e 24 46 68 83 1d 00 00 88 00 08 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b Got RLC block, coding scheme: CS-1, length: 23 (23)) @@ -2163,7 +2163,7 @@ Change control TS to 7 until assinment is complete. TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN)s start Packet Uplink Assignment (PACCH) +++++++++++++++++++++++++ TX : Packet Uplink Assignment +++++++++++++++++++++++++ ------------------------- TX : Packet Uplink Assignment ------------------------- -TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) Scheduled UL Assignment polling on FN=2654283 +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) Scheduled UL Assignment polling on FN=2654283, TS=7 Scheduling control message at RTS for TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) (TRX=0, TS=7) Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654270 block=8 data=4f 28 5e 24 46 68 83 1d 00 00 88 00 08 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b Got RLC block, coding scheme: CS-1, length: 23 (23)) @@ -2252,7 +2252,7 @@ Received RTS for PDCH: TRX=0 TS=7 FN=2654275 block_nr=9 scheduling USF=0 for req TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=ASSIGN) start Packet Downlink Assignment (PACCH) +++++++++++++++++++++++++ TX : Packet Downlink Assignment +++++++++++++++++++++++++ ------------------------- TX : Packet Downlink Assignment ------------------------- -TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW) Scheduled DL Assignment polling on FN=2654288 +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW) Scheduled DL Assignment polling on FN=2654288, TS=7 Scheduling control message at RTS for TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW) (TRX=0, TS=7) Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654275 block=9 data=48 08 00 00 0c 72 00 02 08 00 80 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b Got RLC block, coding scheme: CS-1, length: 23 (23)) @@ -2881,7 +2881,7 @@ Received RTS for PDCH: TRX=0 TS=7 FN=2654400 block_nr=2 scheduling USF=0 for req TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=ASSIGN) start Packet Downlink Assignment (PACCH) +++++++++++++++++++++++++ TX : Packet Downlink Assignment +++++++++++++++++++++++++ ------------------------- TX : Packet Downlink Assignment ------------------------- -TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=WAIT RELEASE) Scheduled DL Assignment polling on FN=2654413 +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=WAIT RELEASE) Scheduled DL Assignment polling on FN=2654413, TS=7 Scheduling control message at RTS for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=WAIT RELEASE) (TRX=0, TS=7) Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654400 block=2 data=48 08 20 08 0c 72 00 02 18 00 80 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b Got RLC block, coding scheme: CS-1, length: 23 (23)) -- cgit v1.2.3 From f2694b74c9af6e308d3886cd3c75864d101de8d4 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Tue, 26 Jan 2016 21:46:26 +0100 Subject: tbf: Add check_polling/set_polling Currently the checks for and the actual polling is done in several places by copy & paste of several lines of code. This hinders changes of they polling is handled internally and also is likely source of programming mistakes. Separate this into a check_polling function, that checks whether polling is possible and returns the FN and the RRBP to be used in that case. Otherwise the cause is logged (LOGL_DEBUG) and a negative error value is returned. There are no other side effect beside the logging. If the call is successful, the set_polling method can be used to actually register the polling. Extend the encoder functions' parameters lists by an rrbp parameter. Sponsored-by: On-Waves ehf --- src/encoding.cpp | 13 +++---- src/encoding.h | 16 +++++---- src/pcu_vty_functions.cpp | 3 +- src/tbf.cpp | 91 +++++++++++++++++++++++++++++++++++------------ src/tbf.h | 3 ++ src/tbf_dl.cpp | 31 ++++++---------- src/tbf_ul.cpp | 23 ++++++------ tests/tbf/TbfTest.err | 32 ++++++++++++----- 8 files changed, 135 insertions(+), 77 deletions(-) diff --git a/src/encoding.cpp b/src/encoding.cpp index a26a5db4..a5e50646 100644 --- a/src/encoding.cpp +++ b/src/encoding.cpp @@ -169,7 +169,7 @@ void Encoding::write_packet_uplink_assignment( struct gprs_rlcmac_bts *bts, bitvec * dest, uint8_t old_tfi, uint8_t old_downlink, uint32_t tlli, uint8_t use_tlli, - struct gprs_rlcmac_ul_tbf *tbf, uint8_t poll, uint8_t alpha, + struct gprs_rlcmac_ul_tbf *tbf, uint8_t poll, uint8_t rrbp, uint8_t alpha, uint8_t gamma, int8_t ta_idx, int8_t use_egprs) { // TODO We should use our implementation of encode RLC/MAC Control messages. @@ -275,8 +275,8 @@ void Encoding::write_packet_uplink_assignment( /* generate downlink assignment */ void Encoding::write_packet_downlink_assignment(RlcMacDownlink_t * block, uint8_t old_tfi, uint8_t old_downlink, struct gprs_rlcmac_tbf *tbf, - uint8_t poll, uint8_t alpha, uint8_t gamma, int8_t ta_idx, uint8_t ta_ts, - bool use_egprs) + uint8_t poll, uint8_t rrbp, uint8_t alpha, uint8_t gamma, int8_t ta_idx, + uint8_t ta_ts, bool use_egprs) { // Packet downlink assignment TS 44.060 11.2.7 @@ -286,7 +286,7 @@ void Encoding::write_packet_downlink_assignment(RlcMacDownlink_t * block, unsigned int ws_enc; block->PAYLOAD_TYPE = 0x1; // RLC/MAC control block that does not include the optional octets of the RLC/MAC control header - block->RRBP = 0x0; // N+13 + block->RRBP = rrbp; // 0: N+13 block->SP = poll; // RRBP field is valid block->USF = 0x0; // Uplink state flag @@ -564,7 +564,8 @@ static void write_packet_uplink_ack_egprs( void Encoding::write_packet_uplink_ack( struct gprs_rlcmac_bts *bts, bitvec * dest, - struct gprs_rlcmac_ul_tbf *tbf, bool is_final) + struct gprs_rlcmac_ul_tbf *tbf, bool is_final, + uint8_t rrbp) { unsigned wp = 0; @@ -572,7 +573,7 @@ void Encoding::write_packet_uplink_ack( "(final=%d)\n", tbf_name(tbf), is_final); bitvec_write_field(dest, wp, 0x1, 2); // Payload Type - bitvec_write_field(dest, wp, 0x0, 2); // Uplink block with TDMA framenumber (N+13) + bitvec_write_field(dest, wp, rrbp, 2); // Uplink block with TDMA framenumber bitvec_write_field(dest, wp, is_final, 1); // Suppl/Polling Bit bitvec_write_field(dest, wp, 0x0, 3); // Uplink state flag bitvec_write_field(dest, wp, 0x9, 6); // MESSAGE TYPE Uplink Ack/Nack diff --git a/src/encoding.h b/src/encoding.h index 4c357578..6ee30ac8 100644 --- a/src/encoding.h +++ b/src/encoding.h @@ -49,21 +49,23 @@ public: static void write_packet_uplink_assignment( struct gprs_rlcmac_bts *bts, bitvec * dest, uint8_t old_tfi, - uint8_t old_downlink, uint32_t tlli, uint8_t use_tlli, - struct gprs_rlcmac_ul_tbf *tbf, uint8_t poll, uint8_t alpha, - uint8_t gamma, int8_t ta_idx, int8_t use_egprs); + uint8_t old_downlink, uint32_t tlli, uint8_t use_tlli, + struct gprs_rlcmac_ul_tbf *tbf, uint8_t poll, uint8_t rrbp, + uint8_t alpha, uint8_t gamma, int8_t ta_idx, + int8_t use_egprs); static void write_packet_downlink_assignment(RlcMacDownlink_t * block, uint8_t old_tfi, uint8_t old_downlink, - struct gprs_rlcmac_tbf *tbf, uint8_t poll, uint8_t alpha, - uint8_t gamma, int8_t ta_idx, uint8_t ta_ts, - bool use_egprs); + struct gprs_rlcmac_tbf *tbf, uint8_t poll, uint8_t rrbp, + uint8_t alpha, uint8_t gamma, + int8_t ta_idx, uint8_t ta_ts, bool use_egprs); static void encode_rbb(const char *show_rbb, uint8_t *rbb); static void write_packet_uplink_ack( struct gprs_rlcmac_bts *bts, bitvec * dest, - struct gprs_rlcmac_ul_tbf *tbf, bool is_final); + struct gprs_rlcmac_ul_tbf *tbf, bool is_final, + uint8_t rrbp); static int write_paging_request(bitvec * dest, uint8_t *ptmsi, uint16_t ptmsi_len); diff --git a/src/pcu_vty_functions.cpp b/src/pcu_vty_functions.cpp index 6567962d..3fcd3e60 100644 --- a/src/pcu_vty_functions.cpp +++ b/src/pcu_vty_functions.cpp @@ -51,7 +51,8 @@ static void tbf_print_vty_info(struct vty *vty, gprs_rlcmac_tbf *tbf) vty_out(vty, " created=%lu state=%08x 1st_TS=%d 1st_cTS=%d ctrl_TS=%d " "MS_CLASS=%d/%d%s", tbf->created_ts(), tbf->state_flags, tbf->first_ts, - tbf->first_common_ts, tbf->control_ts, tbf->ms_class(), + tbf->first_common_ts, tbf->control_ts, + tbf->ms_class(), tbf->ms() ? tbf->ms()->egprs_ms_class() : -1, VTY_NEWLINE); vty_out(vty, " TS_alloc="); diff --git a/src/tbf.cpp b/src/tbf.cpp index 6e516280..1694bbbc 100644 --- a/src/tbf.cpp +++ b/src/tbf.cpp @@ -435,6 +435,49 @@ void gprs_rlcmac_tbf::stop_timer() } } +int gprs_rlcmac_tbf::check_polling(uint32_t fn, uint8_t ts, + uint32_t *poll_fn_, unsigned int *rrbp_) +{ + uint32_t fn_offs = 13; + uint32_t new_poll_fn = (fn + fn_offs) % 2715648; + + if (!is_control_ts(ts)) { + LOGP(DRLCMAC, LOGL_DEBUG, "Polling cannot be " + "scheduled in this TS %d (first control TS %d)\n", + ts, control_ts); + return -EINVAL; + } + if (poll_state != GPRS_RLCMAC_POLL_NONE) { + LOGP(DRLCMAC, LOGL_DEBUG, + "Polling is already scheduled for %s\n", + name()); + return -EBUSY; + } + if (bts->sba()->find(trx->trx_no, ts, (fn + 13) % 2715648)) { + LOGP(DRLCMAC, LOGL_DEBUG, "%s: Polling is already scheduled " + "for single block allocation at FN %d TS %d ...\n", + name(), new_poll_fn, ts); + return -EBUSY; + } + + *poll_fn_ = new_poll_fn; + *rrbp_ = 0; + + return 0; +} + +void gprs_rlcmac_tbf::set_polling(uint32_t new_poll_fn, uint8_t ts) +{ + LOGP(DRLCMAC, LOGL_DEBUG, + "%s: Scheduling polling at FN %d TS %d\n", + name(), new_poll_fn, ts); + + /* schedule polling */ + poll_state = GPRS_RLCMAC_POLL_SCHED; + poll_fn = new_poll_fn; + poll_ts = ts; +} + void gprs_rlcmac_tbf::poll_timeout() { LOGP(DRLCMAC, LOGL_NOTICE, "%s poll timeout for FN=%d, TS=%d (curr FN %d)\n", @@ -861,6 +904,9 @@ struct msgb *gprs_rlcmac_tbf::create_dl_ass(uint32_t fn, uint8_t ts) struct msgb *msg; struct gprs_rlcmac_dl_tbf *new_dl_tbf = NULL; int poll_ass_dl = 1; + unsigned int rrbp = 0; + uint32_t new_poll_fn = 0; + int rc; if (direction == GPRS_RLCMAC_DL_TBF && !is_control_ts(ts)) { LOGP(DRLCMAC, LOGL_NOTICE, "Cannot poll for downlink " @@ -870,17 +916,17 @@ struct msgb *gprs_rlcmac_tbf::create_dl_ass(uint32_t fn, uint8_t ts) poll_ass_dl = 0; } if (poll_ass_dl) { - if (poll_state != GPRS_RLCMAC_POLL_NONE) { - LOGP(DRLCMAC, LOGL_DEBUG, "Polling is already sheduled " - "for %s, so we must wait for downlink " - "assignment...\n", tbf_name(this)); - return NULL; - } - if (bts->sba()->find(trx->trx_no, ts, (fn + 13) % 2715648)) { + if (poll_state == GPRS_RLCMAC_POLL_SCHED && + ul_ass_state == GPRS_RLCMAC_UL_ASS_WAIT_ACK) + { LOGP(DRLCMACUL, LOGL_DEBUG, "Polling is already " - "scheduled for single block allocation...\n"); + "scheduled for %s, so we must wait for the uplink " + "assignment...\n", tbf_name(this)); return NULL; } + rc = check_polling(fn, ts, &new_poll_fn, &rrbp); + if (rc < 0) + return NULL; } /* on uplink TBF we get the downlink TBF to be assigned. */ @@ -923,7 +969,7 @@ struct msgb *gprs_rlcmac_tbf::create_dl_ass(uint32_t fn, uint8_t ts) RlcMacDownlink_t * mac_control_block = (RlcMacDownlink_t *)talloc_zero(tall_pcu_ctx, RlcMacDownlink_t); Encoding::write_packet_downlink_assignment(mac_control_block, m_tfi, (direction == GPRS_RLCMAC_DL_TBF), new_dl_tbf, - poll_ass_dl, bts_data()->alpha, bts_data()->gamma, -1, 0, + poll_ass_dl, rrbp, bts_data()->alpha, bts_data()->gamma, -1, 0, is_egprs_enabled()); LOGP(DRLCMAC, LOGL_DEBUG, "+++++++++++++++++++++++++ TX : Packet Downlink Assignment +++++++++++++++++++++++++\n"); encode_gsm_rlcmac_downlink(ass_vec, mac_control_block); @@ -934,9 +980,7 @@ struct msgb *gprs_rlcmac_tbf::create_dl_ass(uint32_t fn, uint8_t ts) talloc_free(mac_control_block); if (poll_ass_dl) { - poll_state = GPRS_RLCMAC_POLL_SCHED; - poll_fn = (fn + 13) % 2715648; - poll_ts = ts; + set_polling(new_poll_fn, ts); dl_ass_state = GPRS_RLCMAC_DL_ASS_WAIT_ACK; LOGP(DRLCMACDL, LOGL_INFO, "%s Scheduled DL Assignment polling on FN=%d, TS=%d\n", @@ -957,18 +1001,21 @@ struct msgb *gprs_rlcmac_tbf::create_ul_ass(uint32_t fn, uint8_t ts) { struct msgb *msg; struct gprs_rlcmac_ul_tbf *new_tbf = NULL; + int rc; + unsigned int rrbp; + uint32_t new_poll_fn; - if (poll_state != GPRS_RLCMAC_POLL_NONE) { + if (poll_state == GPRS_RLCMAC_POLL_SCHED && + ul_ass_state == GPRS_RLCMAC_UL_ASS_WAIT_ACK) { LOGP(DRLCMACUL, LOGL_DEBUG, "Polling is already " - "sheduled for %s, so we must wait for uplink " + "scheduled for %s, so we must wait for the uplink " "assignment...\n", tbf_name(this)); return NULL; } - if (bts->sba()->find(trx->trx_no, ts, (fn + 13) % 2715648)) { - LOGP(DRLCMACUL, LOGL_DEBUG, "Polling is already scheduled for " - "single block allocation...\n"); - return NULL; - } + + rc = check_polling(fn, ts, &new_poll_fn, &rrbp); + if (rc < 0) + return NULL; if (ms()) new_tbf = ms()->ul_tbf(); @@ -993,7 +1040,7 @@ struct msgb *gprs_rlcmac_tbf::create_ul_ass(uint32_t fn, uint8_t ts) "2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b"); Encoding::write_packet_uplink_assignment(bts_data(), ass_vec, m_tfi, (direction == GPRS_RLCMAC_DL_TBF), tlli(), - is_tlli_valid(), new_tbf, 1, bts_data()->alpha, + is_tlli_valid(), new_tbf, 1, rrbp, bts_data()->alpha, bts_data()->gamma, -1, is_egprs_enabled()); bitvec_pack(ass_vec, msgb_put(msg, 23)); RlcMacDownlink_t * mac_control_block = (RlcMacDownlink_t *)talloc_zero(tall_pcu_ctx, RlcMacDownlink_t); @@ -1004,9 +1051,7 @@ struct msgb *gprs_rlcmac_tbf::create_ul_ass(uint32_t fn, uint8_t ts) bitvec_free(ass_vec); talloc_free(mac_control_block); - poll_state = GPRS_RLCMAC_POLL_SCHED; - poll_fn = (fn + 13) % 2715648; - poll_ts = ts; + set_polling(new_poll_fn, ts); ul_ass_state = GPRS_RLCMAC_UL_ASS_WAIT_ACK; LOGP(DRLCMACDL, LOGL_INFO, "%s Scheduled UL Assignment polling on FN=%d, TS=%d\n", diff --git a/src/tbf.h b/src/tbf.h index d23cf933..edb8280e 100644 --- a/src/tbf.h +++ b/src/tbf.h @@ -119,6 +119,9 @@ struct gprs_rlcmac_tbf { void stop_t3191(); int establish_dl_tbf_on_pacch(); + int check_polling(uint32_t fn, uint8_t ts, + uint32_t *poll_fn, unsigned int *rrbp); + void set_polling(uint32_t poll_fn, uint8_t ts); void poll_timeout(); /** tlli handling */ diff --git a/src/tbf_dl.cpp b/src/tbf_dl.cpp index 10b376ff..03f0cc4d 100644 --- a/src/tbf_dl.cpp +++ b/src/tbf_dl.cpp @@ -527,6 +527,9 @@ struct msgb *gprs_rlcmac_dl_tbf::create_dl_acked_block( bool need_poll; /* TODO: support MCS-7 - MCS-9, where data_block_idx can be 1 */ unsigned int data_block_idx = 0; + unsigned int rrbp; + uint32_t new_poll_fn; + int rc; gprs_rlc_data_info rlc; GprsCodingScheme cs; @@ -570,32 +573,18 @@ struct msgb *gprs_rlcmac_dl_tbf::create_dl_acked_block( "polling, because %d blocks sent.\n", POLL_ACK_AFTER_FRAMES); } - /* scheduling not possible, because: */ - if (poll_state != GPRS_RLCMAC_POLL_NONE) - LOGP(DRLCMACDL, LOGL_DEBUG, "Polling is already " - "sheduled for %s, so we must wait for " - "requesting downlink ack\n", tbf_name(this)); - else if (!is_control_ts(ts)) - LOGP(DRLCMACDL, LOGL_DEBUG, "Polling cannot be " - "sheduled in this TS %d, waiting for " - "TS %d\n", ts, control_ts); - else if (bts->sba()->find(trx->trx_no, ts, (fn + 13) % 2715648)) - LOGP(DRLCMACDL, LOGL_DEBUG, "Polling cannot be " - "sheduled, because single block alllocation " - "already exists\n"); - else { - LOGP(DRLCMACDL, LOGL_DEBUG, "Polling sheduled in this " + + rc = check_polling(fn, ts, &new_poll_fn, &rrbp); + if (rc >= 0) { + set_polling(new_poll_fn, ts); + + LOGP(DRLCMACDL, LOGL_DEBUG, "Polling scheduled in this " "TS %d\n", ts); m_tx_counter = 0; /* start timer whenever we send the final block */ if (rdbi->cv == 0) tbf_timer_start(this, 3191, bts_data()->t3191, 0); - /* schedule polling */ - poll_state = GPRS_RLCMAC_POLL_SCHED; - poll_fn = (fn + 13) % 2715648; - poll_ts = ts; - /* Clear poll timeout flag */ state_flags &= ~(1 << GPRS_RLCMAC_FLAG_TO_DL_ACK); @@ -603,7 +592,7 @@ struct msgb *gprs_rlcmac_dl_tbf::create_dl_acked_block( m_dl_ack_requested = false; /* set polling in header */ - rlc.rrbp = 0; /* N+13 */ + rlc.rrbp = rrbp; rlc.es_p = 1; /* Polling */ m_last_dl_poll_fn = poll_fn; diff --git a/src/tbf_ul.cpp b/src/tbf_ul.cpp index 4754e11f..9e763f4c 100644 --- a/src/tbf_ul.cpp +++ b/src/tbf_ul.cpp @@ -91,19 +91,22 @@ struct msgb *gprs_rlcmac_ul_tbf::create_ul_ack(uint32_t fn, uint8_t ts) { int final = (state_is(GPRS_RLCMAC_FINISHED)); struct msgb *msg; + int rc; + unsigned int rrbp = 0; + uint32_t new_poll_fn = 0; if (final) { - if (poll_state != GPRS_RLCMAC_POLL_NONE) { + if (poll_state == GPRS_RLCMAC_POLL_SCHED && + ul_ack_state == GPRS_RLCMAC_UL_ACK_WAIT_ACK) { LOGP(DRLCMACUL, LOGL_DEBUG, "Polling is already " - "sheduled for %s, so we must wait for " - "final uplink ack...\n", tbf_name(this)); + "scheduled for %s, so we must wait for " + "the final uplink ack...\n", tbf_name(this)); return NULL; } - if (bts->sba()->find(trx->trx_no, ts, (fn + 13) % 2715648)) { - LOGP(DRLCMACUL, LOGL_DEBUG, "Polling is already " - "scheduled for single block allocation...\n"); + + rc = check_polling(fn, ts, &new_poll_fn, &rrbp); + if (rc < 0) return NULL; - } } msg = msgb_alloc(23, "rlcmac_ul_ack"); @@ -116,7 +119,7 @@ struct msgb *gprs_rlcmac_ul_tbf::create_ul_ack(uint32_t fn, uint8_t ts) } bitvec_unhex(ack_vec, "2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b"); - Encoding::write_packet_uplink_ack(bts_data(), ack_vec, this, final); + Encoding::write_packet_uplink_ack(bts_data(), ack_vec, this, final, rrbp); bitvec_pack(ack_vec, msgb_put(msg, 23)); bitvec_free(ack_vec); @@ -125,9 +128,7 @@ struct msgb *gprs_rlcmac_ul_tbf::create_ul_ack(uint32_t fn, uint8_t ts) m_contention_resolution_done = 1; if (final) { - poll_state = GPRS_RLCMAC_POLL_SCHED; - poll_fn = (fn + 13) % 2715648; - poll_ts = ts; + set_polling(new_poll_fn, ts); /* waiting for final acknowledge */ ul_ack_state = GPRS_RLCMAC_UL_ACK_WAIT_ACK; m_final_ack_sent = 1; diff --git a/tests/tbf/TbfTest.err b/tests/tbf/TbfTest.err index 80f3f854..177a5b58 100644 --- a/tests/tbf/TbfTest.err +++ b/tests/tbf/TbfTest.err @@ -61,6 +61,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) append TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) start Packet Downlink Assignment (PACCH) +++++++++++++++++++++++++ TX : Packet Downlink Assignment +++++++++++++++++++++++++ ------------------------- TX : Packet Downlink Assignment ------------------------- +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW): Scheduling polling at FN 13 TS 4 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) Scheduled DL Assignment polling on FN=13, TS=4 Scheduling control message at RTS for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) (TRX=0, TS=4) Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=0 block=0 data=4f 08 20 00 44 02 00 02 08 04 00 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b @@ -142,6 +143,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) append TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) start Packet Downlink Assignment (PACCH) +++++++++++++++++++++++++ TX : Packet Downlink Assignment +++++++++++++++++++++++++ ------------------------- TX : Packet Downlink Assignment ------------------------- +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW): Scheduling polling at FN 13 TS 4 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) Scheduled DL Assignment polling on FN=13, TS=4 Scheduling control message at RTS for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) (TRX=0, TS=4) Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=0 block=0 data=4f 08 20 00 44 02 00 02 08 04 00 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b @@ -223,6 +225,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) append TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) start Packet Downlink Assignment (PACCH) +++++++++++++++++++++++++ TX : Packet Downlink Assignment +++++++++++++++++++++++++ ------------------------- TX : Packet Downlink Assignment ------------------------- +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW): Scheduling polling at FN 13 TS 4 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) Scheduled DL Assignment polling on FN=13, TS=4 Scheduling control message at RTS for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) (TRX=0, TS=4) Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=0 block=0 data=4f 08 20 00 44 02 00 02 08 04 00 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b @@ -382,7 +385,7 @@ Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW)len=200 Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW)len=16 data block (BSN 20, CS-1): 0a 41 c6 c7 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). -Polling is already sheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW), so we must wait for requesting downlink ack +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) msg block (BSN 20, CS-1): 07 00 28 0a 41 c6 c7 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=91 block=9 data=07 00 28 0a 41 c6 c7 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink acknowledge @@ -419,7 +422,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==21 .. V(S)==21) Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW)len=19 data block (BSN 21, CS-1): 4d 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). -Polling is already sheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW), so we must wait for requesting downlink ack +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) msg block (BSN 21, CS-1): 07 00 2a 4d 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=95 block=10 data=07 00 2a 4d 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink acknowledge @@ -437,7 +440,7 @@ Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW)len=19 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) changes state from FLOW to FINISHED data block (BSN 22, CS-1): 4d 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). -Polling is already sheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FINISHED), so we must wait for requesting downlink ack +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FINISHED) msg block (BSN 22, CS-1): 07 01 2c 4d 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=203 block=11 data=07 01 2c 4d 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FINISHED) downlink acknowledge @@ -1433,7 +1436,7 @@ Complete DL frame for TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN)len=19 TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN) changes state from ASSIGN to FINISHED data block (BSN 2, CS-1): 4d 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). -Polling cannot be sheduled in this TS 7, waiting for TS 4 +Polling cannot be scheduled in this TS 7 (first control TS 4) msg block (BSN 2, CS-1): 07 01 04 4d 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 MSG = 07 01 04 4d 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 Searching for first unallocated TFI: TRX=0 @@ -1549,6 +1552,7 @@ Change control TS to 7 until assinment is complete. TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN)s start Packet Uplink Assignment (PACCH) +++++++++++++++++++++++++ TX : Packet Uplink Assignment +++++++++++++++++++++++++ ------------------------- TX : Packet Uplink Assignment ------------------------- +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN): Scheduling polling at FN 2654283 TS 7 TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) Scheduled UL Assignment polling on FN=2654283, TS=7 Scheduling control message at RTS for TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) (TRX=0, TS=7) Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654270 block=8 data=4f 28 5e 24 46 68 8f 1d 00 00 88 00 08 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b @@ -1633,6 +1637,7 @@ Change control TS to 7 until assinment is complete. TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN)s start Packet Uplink Assignment (PACCH) +++++++++++++++++++++++++ TX : Packet Uplink Assignment +++++++++++++++++++++++++ ------------------------- TX : Packet Uplink Assignment ------------------------- +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN): Scheduling polling at FN 2654283 TS 7 TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) Scheduled UL Assignment polling on FN=2654283, TS=7 Scheduling control message at RTS for TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) (TRX=0, TS=7) Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654270 block=8 data=4f 28 5e 24 46 68 8f 1d 00 00 88 00 08 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b @@ -1683,6 +1688,7 @@ Received RTS for PDCH: TRX=0 TS=7 FN=2654275 block_nr=9 scheduling USF=0 for req TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=ASSIGN) start Packet Downlink Assignment (PACCH) +++++++++++++++++++++++++ TX : Packet Downlink Assignment +++++++++++++++++++++++++ ------------------------- TX : Packet Downlink Assignment ------------------------- +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW): Scheduling polling at FN 2654288 TS 7 TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW) Scheduled DL Assignment polling on FN=2654288, TS=7 Scheduling control message at RTS for TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW) (TRX=0, TS=7) Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654275 block=9 data=48 08 00 00 0c 72 00 02 08 00 80 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b @@ -1711,7 +1717,8 @@ Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=10 TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) changes state from FLOW to FINISHED data block (BSN 0, CS-4): 29 52 41 55 5f 41 43 43 45 50 54 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). -Polling sheduled in this TS 7 +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FINISHED): Scheduling polling at FN 2654292 TS 7 +Polling scheduled in this TS 7 TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FINISHED) starting timer 3191. TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FINISHED) Scheduled Ack/Nack polling on FN=2654292, TS=7 msg block (BSN 0, CS-4): 0f 01 00 29 52 41 55 5f 41 43 43 45 50 54 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 00 @@ -1765,6 +1772,7 @@ Received RTS for PDCH: TRX=0 TS=7 FN=2654335 block_nr=11 scheduling USF=0 for re TBF(TFI=1 TLLI=0xf5667788 DIR=UL STATE=ASSIGN)s start Packet Uplink Assignment (PACCH) +++++++++++++++++++++++++ TX : Packet Uplink Assignment +++++++++++++++++++++++++ ------------------------- TX : Packet Uplink Assignment ------------------------- +TBF(TFI=1 TLLI=0xf5667788 DIR=UL STATE=ASSIGN): Scheduling polling at FN 2654348 TS 7 TBF(TFI=1 TLLI=0xf5667788 DIR=UL STATE=ASSIGN) Scheduled UL Assignment polling on FN=2654348, TS=7 Scheduling control message at RTS for TBF(TFI=1 TLLI=0xf5667788 DIR=UL STATE=ASSIGN) (TRX=0, TS=7) Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654335 block=11 data=48 28 5e ac ce f1 0f 1d 00 00 88 40 09 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b @@ -1835,6 +1843,7 @@ Change control TS to 7 until assinment is complete. TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN)s start Packet Uplink Assignment (PACCH) +++++++++++++++++++++++++ TX : Packet Uplink Assignment +++++++++++++++++++++++++ ------------------------- TX : Packet Uplink Assignment ------------------------- +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN): Scheduling polling at FN 2654283 TS 7 TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) Scheduled UL Assignment polling on FN=2654283, TS=7 Scheduling control message at RTS for TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) (TRX=0, TS=7) Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654270 block=8 data=4f 28 5e 24 46 68 83 1d 00 00 88 00 08 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b @@ -1930,6 +1939,7 @@ Change control TS to 7 until assinment is complete. TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN)s start Packet Uplink Assignment (PACCH) +++++++++++++++++++++++++ TX : Packet Uplink Assignment +++++++++++++++++++++++++ ------------------------- TX : Packet Uplink Assignment ------------------------- +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN): Scheduling polling at FN 2654340 TS 7 TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) Scheduled UL Assignment polling on FN=2654340, TS=7 Scheduling control message at RTS for TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) (TRX=0, TS=7) Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654327 block=9 data=4f 28 5e 24 46 68 83 1d 00 00 88 00 08 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b @@ -2010,6 +2020,7 @@ Change control TS to 7 until assinment is complete. TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN)s start Packet Uplink Assignment (PACCH) +++++++++++++++++++++++++ TX : Packet Uplink Assignment +++++++++++++++++++++++++ ------------------------- TX : Packet Uplink Assignment ------------------------- +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN): Scheduling polling at FN 2654283 TS 7 TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) Scheduled UL Assignment polling on FN=2654283, TS=7 Scheduling control message at RTS for TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) (TRX=0, TS=7) Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654270 block=8 data=4f 28 5e 24 46 68 83 1d 00 00 88 00 08 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b @@ -2163,6 +2174,7 @@ Change control TS to 7 until assinment is complete. TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN)s start Packet Uplink Assignment (PACCH) +++++++++++++++++++++++++ TX : Packet Uplink Assignment +++++++++++++++++++++++++ ------------------------- TX : Packet Uplink Assignment ------------------------- +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN): Scheduling polling at FN 2654283 TS 7 TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) Scheduled UL Assignment polling on FN=2654283, TS=7 Scheduling control message at RTS for TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) (TRX=0, TS=7) Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654270 block=8 data=4f 28 5e 24 46 68 83 1d 00 00 88 00 08 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b @@ -2252,6 +2264,7 @@ Received RTS for PDCH: TRX=0 TS=7 FN=2654275 block_nr=9 scheduling USF=0 for req TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=ASSIGN) start Packet Downlink Assignment (PACCH) +++++++++++++++++++++++++ TX : Packet Downlink Assignment +++++++++++++++++++++++++ ------------------------- TX : Packet Downlink Assignment ------------------------- +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW): Scheduling polling at FN 2654288 TS 7 TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW) Scheduled DL Assignment polling on FN=2654288, TS=7 Scheduling control message at RTS for TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW) (TRX=0, TS=7) Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654275 block=9 data=48 08 00 00 0c 72 00 02 08 00 80 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b @@ -2667,7 +2680,8 @@ Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) data block (BSN 20, CS-1): 16 35 45 54 20 32 38 4c 4c 43 20 50 41 43 4b 45 54 20 32 39 - Scheduling Ack/Nack polling, because 20 blocks sent. -Polling sheduled in this TS 7 +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW): Scheduling polling at FN 2654379 TS 7 +Polling scheduled in this TS 7 TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) Scheduled Ack/Nack polling on FN=2654379, TS=7 msg block (BSN 20, CS-1): 0f 00 28 16 35 45 54 20 32 38 4c 4c 43 20 50 41 43 4b 45 54 20 32 39 Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654366 block=6 data=08 00 28 16 35 45 54 20 32 38 4c 4c 43 20 50 41 43 4b 45 54 20 32 39 @@ -2805,7 +2819,7 @@ Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) changes state from FLOW to FINISHED data block (BSN 27, CS-1): 16 35 45 54 20 33 38 4c 4c 43 20 50 41 43 4b 45 54 20 33 39 - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). -Polling is already sheduled for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FINISHED), so we must wait for requesting downlink ack +Polling is already scheduled for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FINISHED) msg block (BSN 27, CS-1): 07 01 36 16 35 45 54 20 33 38 4c 4c 43 20 50 41 43 4b 45 54 20 33 39 Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654396 block=1 data=00 01 36 16 35 45 54 20 33 38 4c 4c 43 20 50 41 43 4b 45 54 20 33 39 TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FINISHED) append @@ -2881,6 +2895,7 @@ Received RTS for PDCH: TRX=0 TS=7 FN=2654400 block_nr=2 scheduling USF=0 for req TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=ASSIGN) start Packet Downlink Assignment (PACCH) +++++++++++++++++++++++++ TX : Packet Downlink Assignment +++++++++++++++++++++++++ ------------------------- TX : Packet Downlink Assignment ------------------------- +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=WAIT RELEASE): Scheduling polling at FN 2654413 TS 7 TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=WAIT RELEASE) Scheduled DL Assignment polling on FN=2654413, TS=7 Scheduling control message at RTS for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=WAIT RELEASE) (TRX=0, TS=7) Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654400 block=2 data=48 08 20 08 0c 72 00 02 18 00 80 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b @@ -3092,7 +3107,8 @@ Complete DL frame for TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=21 TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW) changes state from FLOW to FINISHED data block (BSN 10, CS-1): 4d 43 20 50 41 43 4b 45 54 20 30 39 20 28 54 42 46 20 32 29 - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). -Polling sheduled in this TS 7 +TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FINISHED): Scheduling polling at FN 2654461 TS 7 +Polling scheduled in this TS 7 TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FINISHED) starting timer 3191. TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FINISHED) Scheduled Ack/Nack polling on FN=2654461, TS=7 msg block (BSN 10, CS-1): 0f 03 14 4d 43 20 50 41 43 4b 45 54 20 30 39 20 28 54 42 46 20 32 29 -- cgit v1.2.3 From 6b356a58d1269fe4ad449bc868cbc734c6d2a28e Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Fri, 29 Jan 2016 16:39:21 +0100 Subject: tbf: Use TLLI as ID if TFI not yet assigned Currently the old TFI is always used as ID when a PACKET DOWNLINK ASSIGNMENT is generated. This fails if the old TBF has not been fully assigned yet. The MS will then ignore the PDA. This commit changes write_packet_downlink_assignment to accept an additional parameter old_tfi_is_valid and uses the new TBF's TLLI instead of the olf TFI if that parameter is set to false. Sponsored-by: On-Waves ehf --- src/encoding.cpp | 16 +++++++++++----- src/encoding.h | 2 +- src/tbf.cpp | 21 ++++++++++++++++++--- src/tbf.h | 11 +++++++++++ tests/tbf/TbfTest.err | 3 +++ 5 files changed, 44 insertions(+), 9 deletions(-) diff --git a/src/encoding.cpp b/src/encoding.cpp index a5e50646..9471fff5 100644 --- a/src/encoding.cpp +++ b/src/encoding.cpp @@ -274,8 +274,9 @@ void Encoding::write_packet_uplink_assignment( /* generate downlink assignment */ void Encoding::write_packet_downlink_assignment(RlcMacDownlink_t * block, - uint8_t old_tfi, uint8_t old_downlink, struct gprs_rlcmac_tbf *tbf, - uint8_t poll, uint8_t rrbp, uint8_t alpha, uint8_t gamma, int8_t ta_idx, + bool old_tfi_is_valid, uint8_t old_tfi, uint8_t old_downlink, + struct gprs_rlcmac_tbf *tbf, uint8_t poll, uint8_t rrbp, + uint8_t alpha, uint8_t gamma, int8_t ta_idx, uint8_t ta_ts, bool use_egprs) { // Packet downlink assignment TS 44.060 11.2.7 @@ -295,9 +296,14 @@ void Encoding::write_packet_downlink_assignment(RlcMacDownlink_t * block, block->u.Packet_Downlink_Assignment.Exist_PERSISTENCE_LEVEL = 0x0; // PERSISTENCE_LEVEL: off - block->u.Packet_Downlink_Assignment.ID.UnionType = 0x0; // TFI = on - block->u.Packet_Downlink_Assignment.ID.u.Global_TFI.UnionType = old_downlink; // 0=UPLINK TFI, 1=DL TFI - block->u.Packet_Downlink_Assignment.ID.u.Global_TFI.u.UPLINK_TFI = old_tfi; // TFI + if (old_tfi_is_valid) { + block->u.Packet_Downlink_Assignment.ID.UnionType = 0x0; // TFI = on + block->u.Packet_Downlink_Assignment.ID.u.Global_TFI.UnionType = old_downlink; // 0=UPLINK TFI, 1=DL TFI + block->u.Packet_Downlink_Assignment.ID.u.Global_TFI.u.UPLINK_TFI = old_tfi; // TFI + } else { + block->u.Packet_Downlink_Assignment.ID.UnionType = 0x1; // TLLI + block->u.Packet_Downlink_Assignment.ID.u.TLLI = tbf->tlli(); + } block->u.Packet_Downlink_Assignment.MAC_MODE = 0x0; // Dynamic Allocation block->u.Packet_Downlink_Assignment.RLC_MODE = 0x0; // RLC acknowledged mode diff --git a/src/encoding.h b/src/encoding.h index 6ee30ac8..12487258 100644 --- a/src/encoding.h +++ b/src/encoding.h @@ -55,7 +55,7 @@ public: int8_t use_egprs); static void write_packet_downlink_assignment(RlcMacDownlink_t * block, - uint8_t old_tfi, uint8_t old_downlink, + bool old_tfi_is_valid, uint8_t old_tfi, uint8_t old_downlink, struct gprs_rlcmac_tbf *tbf, uint8_t poll, uint8_t rrbp, uint8_t alpha, uint8_t gamma, int8_t ta_idx, uint8_t ta_ts, bool use_egprs); diff --git a/src/tbf.cpp b/src/tbf.cpp index 1694bbbc..04c72724 100644 --- a/src/tbf.cpp +++ b/src/tbf.cpp @@ -907,6 +907,7 @@ struct msgb *gprs_rlcmac_tbf::create_dl_ass(uint32_t fn, uint8_t ts) unsigned int rrbp = 0; uint32_t new_poll_fn = 0; int rc; + bool old_tfi_is_valid = is_tfi_assigned(); if (direction == GPRS_RLCMAC_DL_TBF && !is_control_ts(ts)) { LOGP(DRLCMAC, LOGL_NOTICE, "Cannot poll for downlink " @@ -954,6 +955,19 @@ struct msgb *gprs_rlcmac_tbf::create_dl_ass(uint32_t fn, uint8_t ts) return NULL; } + if (new_dl_tbf == as_dl_tbf(this)) + LOGP(DRLCMAC, LOGL_DEBUG, + "New and old TBF are the same %s\n", name()); + + if (old_tfi_is_valid && !new_dl_tbf->is_tlli_valid()) { + LOGP(DRLCMACDL, LOGL_ERROR, + "The old TFI is not assigned and there is no " + "TLLI. Old TBF %s, new TBF %s\n", + name(), new_dl_tbf->name()); + dl_ass_state = GPRS_RLCMAC_DL_ASS_NONE; + return NULL; + } + new_dl_tbf->was_releasing = was_releasing; msg = msgb_alloc(23, "rlcmac_dl_ass"); if (!msg) @@ -967,9 +981,10 @@ struct msgb *gprs_rlcmac_tbf::create_dl_ass(uint32_t fn, uint8_t ts) "2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b"); LOGP(DRLCMAC, LOGL_INFO, "%s start Packet Downlink Assignment (PACCH)\n", tbf_name(new_dl_tbf)); RlcMacDownlink_t * mac_control_block = (RlcMacDownlink_t *)talloc_zero(tall_pcu_ctx, RlcMacDownlink_t); - Encoding::write_packet_downlink_assignment(mac_control_block, m_tfi, - (direction == GPRS_RLCMAC_DL_TBF), new_dl_tbf, - poll_ass_dl, rrbp, bts_data()->alpha, bts_data()->gamma, -1, 0, + Encoding::write_packet_downlink_assignment(mac_control_block, + old_tfi_is_valid, m_tfi, (direction == GPRS_RLCMAC_DL_TBF), + new_dl_tbf, poll_ass_dl, rrbp, + bts_data()->alpha, bts_data()->gamma, -1, 0, is_egprs_enabled()); LOGP(DRLCMAC, LOGL_DEBUG, "+++++++++++++++++++++++++ TX : Packet Downlink Assignment +++++++++++++++++++++++++\n"); encode_gsm_rlcmac_downlink(ass_vec, mac_control_block); diff --git a/src/tbf.h b/src/tbf.h index edb8280e..d1b286cb 100644 --- a/src/tbf.h +++ b/src/tbf.h @@ -132,6 +132,7 @@ struct gprs_rlcmac_tbf { void update_ms(uint32_t tlli, enum gprs_rlcmac_tbf_direction); uint8_t tfi() const; + bool is_tfi_assigned() const; const char *imsi() const; void assign_imsi(const char *imsi); @@ -310,6 +311,16 @@ inline bool gprs_rlcmac_tbf::is_tlli_valid() const return tlli() != 0; } +inline bool gprs_rlcmac_tbf::is_tfi_assigned() const +{ + /* The TBF is established or has been assigned by a IMM.ASS for + * download */ + return state > GPRS_RLCMAC_ASSIGN || + (direction == GPRS_RLCMAC_DL_TBF && + state == GPRS_RLCMAC_ASSIGN && + (state_flags & (1 << GPRS_RLCMAC_FLAG_CCCH))); +} + inline uint8_t gprs_rlcmac_tbf::tfi() const { return m_tfi; diff --git a/tests/tbf/TbfTest.err b/tests/tbf/TbfTest.err index 177a5b58..02b6a3d7 100644 --- a/tests/tbf/TbfTest.err +++ b/tests/tbf/TbfTest.err @@ -58,6 +58,7 @@ TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL) changes state from NULL to FLOW The MS object cannot fully confirm an unexpected TLLI: 0xffeeddcc, partly confirmed TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) append TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) append +New and old TBF are the same TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) start Packet Downlink Assignment (PACCH) +++++++++++++++++++++++++ TX : Packet Downlink Assignment +++++++++++++++++++++++++ ------------------------- TX : Packet Downlink Assignment ------------------------- @@ -140,6 +141,7 @@ TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL) changes state from NULL to FLOW The MS object cannot fully confirm an unexpected TLLI: 0xffeeddcc, partly confirmed TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) append TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) append +New and old TBF are the same TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) start Packet Downlink Assignment (PACCH) +++++++++++++++++++++++++ TX : Packet Downlink Assignment +++++++++++++++++++++++++ ------------------------- TX : Packet Downlink Assignment ------------------------- @@ -222,6 +224,7 @@ TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL) changes state from NULL to FLOW The MS object cannot fully confirm an unexpected TLLI: 0xffeeddcc, partly confirmed TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) append TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) append +New and old TBF are the same TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) start Packet Downlink Assignment (PACCH) +++++++++++++++++++++++++ TX : Packet Downlink Assignment +++++++++++++++++++++++++ ------------------------- TX : Packet Downlink Assignment ------------------------- -- cgit v1.2.3 From 9876a3ba5dd1f51bb56d340d709b0d2db7891a26 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Fri, 29 Jan 2016 18:51:04 +0100 Subject: tbf: Don't change type from CCCH to PACCH without ack Currently the CCCH flag is cleared and the PACCH flag is set when a multislot upgrade is scheduled for a downlink TBF, even if the MS has never confirmed in any way that the PACCH really exists. This can happen if the MS did not receive the DL IMM.ASS. Since the CCCH flags gets cleared in that case, the IMM.ASSS is never retried and all subsequent PACKET DOWNLINK ASSIGNMENTS will fail. This commit delays the update of these flags until the MS has responded with a corresponding CONTROL ACK. Sponsored-by: On-Waves ehf --- src/bts.cpp | 12 +++++++++++- src/tbf.cpp | 1 - 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/bts.cpp b/src/bts.cpp index 0356718f..47dc1d1c 100644 --- a/src/bts.cpp +++ b/src/bts.cpp @@ -569,7 +569,8 @@ void BTS::trigger_dl_ass( /* change state */ dl_tbf->set_state(GPRS_RLCMAC_ASSIGN); - dl_tbf->state_flags |= (1 << GPRS_RLCMAC_FLAG_PACCH); + if (!(dl_tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_CCCH))) + dl_tbf->state_flags |= (1 << GPRS_RLCMAC_FLAG_PACCH); /* start timer */ tbf_timer_start(dl_tbf, 0, Tassign_pacch); } else { @@ -799,6 +800,15 @@ void gprs_rlcmac_pdch::rcv_control_ack(Packet_Control_Acknowledgement_t *packet, if (tbf->state_is(GPRS_RLCMAC_WAIT_RELEASE)) tbf_free(tbf); + if ((new_tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_CCCH))) { + /* We now know that the PACCH really existed */ + LOGP(DRLCMAC, LOGL_INFO, + "The TBF has been confirmed on the PACCH, " + "changed type from CCCH to PACCH for %s\n", + tbf_name(new_tbf)); + new_tbf->state_flags &= ~(1 << GPRS_RLCMAC_FLAG_CCCH); + new_tbf->state_flags |= (1 << GPRS_RLCMAC_FLAG_PACCH); + } new_tbf->set_state(GPRS_RLCMAC_FLOW); /* stop pending assignment timer */ new_tbf->stop_timer(); diff --git a/src/tbf.cpp b/src/tbf.cpp index 04c72724..c07f379e 100644 --- a/src/tbf.cpp +++ b/src/tbf.cpp @@ -851,7 +851,6 @@ void gprs_rlcmac_tbf::handle_timeout() /* keep to flags */ dl_tbf->state_flags &= GPRS_RLCMAC_FLAG_TO_MASK; - dl_tbf->state_flags &= ~(1 << GPRS_RLCMAC_FLAG_CCCH); dl_tbf->update(); -- cgit v1.2.3 From 4e7424d47bf15b3d7a902fbd020838540117292a Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Mon, 1 Feb 2016 13:26:22 +0100 Subject: pcu: Add bitvec_write_field_lh While the bitvec functions from libosmocore support LH encoding, the C++ wrapper does not. Add a bitvec_write_field_lh function that is similar to bitvec_write_field, but writes L and H instead of ZERO and ONE. Sponsored-by: On-Waves ehf --- src/bitvector.cpp | 18 ++++++++++++++++++ src/bitvector.h | 1 + 2 files changed, 19 insertions(+) diff --git a/src/bitvector.cpp b/src/bitvector.cpp index 43feebc5..10284073 100644 --- a/src/bitvector.cpp +++ b/src/bitvector.cpp @@ -117,3 +117,21 @@ int bitvec_write_field(struct bitvec *bv, unsigned& write_index, uint64_t val, u write_index += len; return 0; } + +int bitvec_write_field_lh(struct bitvec *bv, unsigned& write_index, + uint64_t val, unsigned len) +{ + unsigned int i; + int rc; + bv->cur_bit = write_index; + for (i = 0; i < len; i++) { + bit_value bit = L; + if (val & ((uint64_t)1 << (len - i - 1))) + bit = H; + rc = bitvec_set_bit(bv, bit); + if (rc) + return rc; + } + write_index += len; + return 0; +} diff --git a/src/bitvector.h b/src/bitvector.h index 36bdbaba..b14d2040 100644 --- a/src/bitvector.h +++ b/src/bitvector.h @@ -39,6 +39,7 @@ unsigned int bitvec_pack(struct bitvec *bv, uint8_t *buffer); unsigned int bitvec_unpack(struct bitvec *bv, uint8_t *buffer); uint64_t bitvec_read_field(struct bitvec *bv, unsigned& read_index, unsigned len); int bitvec_write_field(struct bitvec *bv, unsigned& write_index, uint64_t val, unsigned len); +int bitvec_write_field_lh(struct bitvec *bv, unsigned& write_index, uint64_t val, unsigned len); /*! }@ */ -- cgit v1.2.3 From 7505f1d63613892a29c3bfb503d3f6f185fb1016 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Mon, 1 Feb 2016 15:05:42 +0100 Subject: encoding: Use explicit LH encoding in write_immediate_assignment Currently bitvec_write_field is used which just sets the bits as given, while the spec 44.018 assumes LH encoding. Use the bitvec_write_field_lh function instead. Sponsored-by: On-Waves ehf --- src/encoding.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/encoding.cpp b/src/encoding.cpp index 9471fff5..4da533ac 100644 --- a/src/encoding.cpp +++ b/src/encoding.cpp @@ -83,7 +83,7 @@ int Encoding::write_immediate_assignment( if (downlink) { // GSM 04.08 10.5.2.16 IA Rest Octets - bitvec_write_field(dest, wp, 3, 2); // "HH" + bitvec_write_field_lh(dest, wp, 3, 2); // "HH" bitvec_write_field(dest, wp, 1, 2); // "01" Packet Downlink Assignment bitvec_write_field(dest, wp,tlli,32); // TLLI bitvec_write_field(dest, wp,0x1,1); // switch TFI : on @@ -119,7 +119,7 @@ int Encoding::write_immediate_assignment( else { // GMS 04.08 10.5.2.37b 10.5.2.16 - bitvec_write_field(dest, wp, 3, 2); // "HH" + bitvec_write_field_lh(dest, wp, 3, 2); // "HH" bitvec_write_field(dest, wp, 0, 2); // "0" Packet Uplink Assignment if (single_block) { bitvec_write_field(dest, wp, 0, 1); // Block Allocation : Single Block Allocation -- cgit v1.2.3 From 18831c3ca94b8cfcdb64a883d88d22404d7c28bd Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Mon, 1 Feb 2016 15:23:35 +0100 Subject: encoding: Refactor write_immediate_assignment Move the IA rest encoding into separate functions fpr uplink and downlink. Sponsored-by: On-Waves ehf --- src/encoding.cpp | 177 ++++++++++++++++++++++++++++++------------------------- 1 file changed, 98 insertions(+), 79 deletions(-) diff --git a/src/encoding.cpp b/src/encoding.cpp index 4da533ac..b558a4a0 100644 --- a/src/encoding.cpp +++ b/src/encoding.cpp @@ -28,7 +28,98 @@ #include #include -// GSM 04.08 9.1.18 Immediate assignment +static void write_ia_rest_downlink( + bitvec * dest, unsigned& wp, + uint8_t tfi, uint32_t tlli, uint8_t polling, + uint32_t fn, uint8_t alpha, uint8_t gamma, int8_t ta_idx) +{ + // GSM 04.08 10.5.2.16 IA Rest Octets + bitvec_write_field_lh(dest, wp, 3, 2); // "HH" + bitvec_write_field(dest, wp, 1, 2); // "01" Packet Downlink Assignment + bitvec_write_field(dest, wp,tlli,32); // TLLI + bitvec_write_field(dest, wp,0x1,1); // switch TFI : on + bitvec_write_field(dest, wp,tfi,5); // TFI + bitvec_write_field(dest, wp,0x0,1); // RLC acknowledged mode + if (alpha) { + bitvec_write_field(dest, wp,0x1,1); // ALPHA = present + bitvec_write_field(dest, wp,alpha,4); // ALPHA + } else { + bitvec_write_field(dest, wp,0x0,1); // ALPHA = not present + } + bitvec_write_field(dest, wp,gamma,5); // GAMMA power control parameter + bitvec_write_field(dest, wp,polling,1); // Polling Bit + bitvec_write_field(dest, wp,!polling,1); // TA_VALID ??? + if (ta_idx < 0) { + bitvec_write_field(dest, wp,0x0,1); // switch TIMING_ADVANCE_INDEX = off + } else { + bitvec_write_field(dest, wp,0x1,1); // switch TIMING_ADVANCE_INDEX = on + bitvec_write_field(dest, wp,ta_idx,4); // TIMING_ADVANCE_INDEX + } + if (polling) { + bitvec_write_field(dest, wp,0x1,1); // TBF Starting TIME present + bitvec_write_field(dest, wp,(fn / (26 * 51)) % 32,5); // T1' + bitvec_write_field(dest, wp,fn % 51,6); // T3 + bitvec_write_field(dest, wp,fn % 26,5); // T2 + } else { + bitvec_write_field(dest, wp,0x0,1); // TBF Starting TIME present + } + bitvec_write_field(dest, wp,0x0,1); // P0 not present + // bitvec_write_field(dest, wp,0x1,1); // P0 not present + // bitvec_write_field(dest, wp,0xb,4); +} + +static void write_ia_rest_uplink( + struct gprs_rlcmac_bts *bts, bitvec * dest, unsigned& wp, + uint8_t tfi, uint8_t usf, uint32_t fn, uint8_t single_block, + uint8_t alpha, uint8_t gamma, int8_t ta_idx) +{ + // GMS 04.08 10.5.2.37b 10.5.2.16 + bitvec_write_field_lh(dest, wp, 3, 2); // "HH" + bitvec_write_field(dest, wp, 0, 2); // "0" Packet Uplink Assignment + if (single_block) { + bitvec_write_field(dest, wp, 0, 1); // Block Allocation : Single Block Allocation + if (alpha) { + bitvec_write_field(dest, wp,0x1,1); // ALPHA = present + bitvec_write_field(dest, wp,alpha,4); // ALPHA = present + } else + bitvec_write_field(dest, wp,0x0,1); // ALPHA = not present + bitvec_write_field(dest, wp,gamma,5); // GAMMA power control parameter + if (ta_idx < 0) { + bitvec_write_field(dest, wp,0x0,1); // switch TIMING_ADVANCE_INDEX = off + } else { + bitvec_write_field(dest, wp,0x1,1); // switch TIMING_ADVANCE_INDEX = on + bitvec_write_field(dest, wp,ta_idx,4); // TIMING_ADVANCE_INDEX + } + bitvec_write_field(dest, wp, 1, 1); // TBF_STARTING_TIME_FLAG + bitvec_write_field(dest, wp,(fn / (26 * 51)) % 32,5); // T1' + bitvec_write_field(dest, wp,fn % 51,6); // T3 + bitvec_write_field(dest, wp,fn % 26,5); // T2 + } else { + bitvec_write_field(dest, wp, 1, 1); // Block Allocation : Not Single Block Allocation + bitvec_write_field(dest, wp, tfi, 5); // TFI_ASSIGNMENT Temporary Flow Identity + bitvec_write_field(dest, wp, 0, 1); // POLLING + bitvec_write_field(dest, wp, 0, 1); // ALLOCATION_TYPE: dynamic + bitvec_write_field(dest, wp, usf, 3); // USF + bitvec_write_field(dest, wp, 0, 1); // USF_GRANULARITY + bitvec_write_field(dest, wp, 0, 1); // "0" power control: Not Present + bitvec_write_field(dest, wp, bts->initial_cs_ul-1, 2); // CHANNEL_CODING_COMMAND + bitvec_write_field(dest, wp, 1, 1); // TLLI_BLOCK_CHANNEL_CODING + if (alpha) { + bitvec_write_field(dest, wp,0x1,1); // ALPHA = present + bitvec_write_field(dest, wp,alpha,4); // ALPHA + } else + bitvec_write_field(dest, wp,0x0,1); // ALPHA = not present + bitvec_write_field(dest, wp,gamma,5); // GAMMA power control parameter + /* note: there is no choise for TAI and no starting time */ + bitvec_write_field(dest, wp, 0, 1); // switch TIMING_ADVANCE_INDEX = off + bitvec_write_field(dest, wp, 0, 1); // TBF_STARTING_TIME_FLAG + } +} + +/* + * Immediate assignment, sent on the CCCH/AGCH + * see GSM 04.08, 9.1.18 and GSM 44.018, 9.1.18 + 10.5.2.16 + */ int Encoding::write_immediate_assignment( struct gprs_rlcmac_bts *bts, bitvec * dest, uint8_t downlink, uint8_t ra, @@ -81,85 +172,13 @@ int Encoding::write_immediate_assignment( plen = wp / 8; if (downlink) - { - // GSM 04.08 10.5.2.16 IA Rest Octets - bitvec_write_field_lh(dest, wp, 3, 2); // "HH" - bitvec_write_field(dest, wp, 1, 2); // "01" Packet Downlink Assignment - bitvec_write_field(dest, wp,tlli,32); // TLLI - bitvec_write_field(dest, wp,0x1,1); // switch TFI : on - bitvec_write_field(dest, wp,tfi,5); // TFI - bitvec_write_field(dest, wp,0x0,1); // RLC acknowledged mode - if (alpha) { - bitvec_write_field(dest, wp,0x1,1); // ALPHA = present - bitvec_write_field(dest, wp,alpha,4); // ALPHA - } else { - bitvec_write_field(dest, wp,0x0,1); // ALPHA = not present - } - bitvec_write_field(dest, wp,gamma,5); // GAMMA power control parameter - bitvec_write_field(dest, wp,polling,1); // Polling Bit - bitvec_write_field(dest, wp,!polling,1); // TA_VALID ??? - if (ta_idx < 0) { - bitvec_write_field(dest, wp,0x0,1); // switch TIMING_ADVANCE_INDEX = off - } else { - bitvec_write_field(dest, wp,0x1,1); // switch TIMING_ADVANCE_INDEX = on - bitvec_write_field(dest, wp,ta_idx,4); // TIMING_ADVANCE_INDEX - } - if (polling) { - bitvec_write_field(dest, wp,0x1,1); // TBF Starting TIME present - bitvec_write_field(dest, wp,(fn / (26 * 51)) % 32,5); // T1' - bitvec_write_field(dest, wp,fn % 51,6); // T3 - bitvec_write_field(dest, wp,fn % 26,5); // T2 - } else { - bitvec_write_field(dest, wp,0x0,1); // TBF Starting TIME present - } - bitvec_write_field(dest, wp,0x0,1); // P0 not present -// bitvec_write_field(dest, wp,0x1,1); // P0 not present -// bitvec_write_field(dest, wp,0xb,4); - } + write_ia_rest_downlink(dest, wp, + tfi, tlli, polling, fn, + alpha, gamma, ta_idx); else - { - // GMS 04.08 10.5.2.37b 10.5.2.16 - bitvec_write_field_lh(dest, wp, 3, 2); // "HH" - bitvec_write_field(dest, wp, 0, 2); // "0" Packet Uplink Assignment - if (single_block) { - bitvec_write_field(dest, wp, 0, 1); // Block Allocation : Single Block Allocation - if (alpha) { - bitvec_write_field(dest, wp,0x1,1); // ALPHA = present - bitvec_write_field(dest, wp,alpha,4); // ALPHA = present - } else - bitvec_write_field(dest, wp,0x0,1); // ALPHA = not present - bitvec_write_field(dest, wp,gamma,5); // GAMMA power control parameter - if (ta_idx < 0) { - bitvec_write_field(dest, wp,0x0,1); // switch TIMING_ADVANCE_INDEX = off - } else { - bitvec_write_field(dest, wp,0x1,1); // switch TIMING_ADVANCE_INDEX = on - bitvec_write_field(dest, wp,ta_idx,4); // TIMING_ADVANCE_INDEX - } - bitvec_write_field(dest, wp, 1, 1); // TBF_STARTING_TIME_FLAG - bitvec_write_field(dest, wp,(fn / (26 * 51)) % 32,5); // T1' - bitvec_write_field(dest, wp,fn % 51,6); // T3 - bitvec_write_field(dest, wp,fn % 26,5); // T2 - } else { - bitvec_write_field(dest, wp, 1, 1); // Block Allocation : Not Single Block Allocation - bitvec_write_field(dest, wp, tfi, 5); // TFI_ASSIGNMENT Temporary Flow Identity - bitvec_write_field(dest, wp, 0, 1); // POLLING - bitvec_write_field(dest, wp, 0, 1); // ALLOCATION_TYPE: dynamic - bitvec_write_field(dest, wp, usf, 3); // USF - bitvec_write_field(dest, wp, 0, 1); // USF_GRANULARITY - bitvec_write_field(dest, wp, 0, 1); // "0" power control: Not Present - bitvec_write_field(dest, wp, bts->initial_cs_ul-1, 2); // CHANNEL_CODING_COMMAND - bitvec_write_field(dest, wp, 1, 1); // TLLI_BLOCK_CHANNEL_CODING - if (alpha) { - bitvec_write_field(dest, wp,0x1,1); // ALPHA = present - bitvec_write_field(dest, wp,alpha,4); // ALPHA - } else - bitvec_write_field(dest, wp,0x0,1); // ALPHA = not present - bitvec_write_field(dest, wp,gamma,5); // GAMMA power control parameter - /* note: there is no choise for TAI and no starting time */ - bitvec_write_field(dest, wp, 0, 1); // switch TIMING_ADVANCE_INDEX = off - bitvec_write_field(dest, wp, 0, 1); // TBF_STARTING_TIME_FLAG - } - } + write_ia_rest_uplink(bts, dest, wp, + tfi, usf, fn, single_block, + alpha, gamma, ta_idx); return plen; } -- cgit v1.2.3 From 2647a337a8343ab1cbb9bb17f918df2db98864e7 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Mon, 1 Feb 2016 16:13:38 +0100 Subject: encoding: Redesign Encoding::write_immediate_assignment API The EGPRS support will need more information to encode the IMMEDIATE ASSIGMENT. Instead of adding more parameters pass a pointer to the TBF unless an SBA shall be done (indicated by tbf == NULL). All values that can be derived from the TBF and are not needed for an SBA are removed from the parameter list. Return a negative value on error. Sponsored-by: On-Waves ehf --- src/bts.cpp | 24 ++++++++++++---------- src/encoding.cpp | 56 ++++++++++++++++++++++++++++++++++----------------- src/encoding.h | 10 ++++----- tests/tbf/TbfTest.err | 14 ++++++------- 4 files changed, 62 insertions(+), 42 deletions(-) diff --git a/src/bts.cpp b/src/bts.cpp index 47dc1d1c..8337b068 100644 --- a/src/bts.cpp +++ b/src/bts.cpp @@ -466,8 +466,7 @@ int BTS::rcv_rach(uint8_t ra, uint32_t Fn, int16_t qta) uint8_t sb = 0; uint32_t sb_fn = 0; int rc; - uint8_t plen; - uint8_t tfi = 0; + int plen; uint8_t usf = 7; uint8_t tsc; uint16_t ta; @@ -528,7 +527,6 @@ int BTS::rcv_rach(uint8_t ra, uint32_t Fn, int16_t qta) "Assignment Uplink (AGCH)\n", tbf_name(tbf)); trx_no = tbf->trx->trx_no; ts_no = tbf->first_ts; - tfi = tbf->tfi(); usf = tbf->m_usf[ts_no]; tsc = tbf->tsc(); } @@ -538,14 +536,17 @@ int BTS::rcv_rach(uint8_t ra, uint32_t Fn, int16_t qta) LOGP(DRLCMAC, LOGL_DEBUG, " - TRX=%d (%d) TS=%d TA=%d TSC=%d TFI=%d USF=%d\n", - trx_no, m_bts.trx[trx_no].arfcn, ts_no, ta, tsc, tfi, usf); + trx_no, m_bts.trx[trx_no].arfcn, ts_no, ta, tsc, + tbf ? tbf->tfi() : -1, usf); plen = Encoding::write_immediate_assignment( - &m_bts, immediate_assignment, 0, ra, Fn, ta, - m_bts.trx[trx_no].arfcn, ts_no, tsc, tfi, usf, 0, 0, sb_fn, sb, + tbf, immediate_assignment, 0, ra, Fn, ta, + m_bts.trx[trx_no].arfcn, ts_no, tsc, usf, 0, sb_fn, m_bts.alpha, m_bts.gamma, -1); - pcu_l1if_tx_agch(immediate_assignment, plen); + if (plen >= 0) + pcu_l1if_tx_agch(immediate_assignment, plen); + bitvec_free(immediate_assignment); return 0; @@ -598,11 +599,12 @@ void BTS::snd_dl_ass(gprs_rlcmac_tbf *tbf, uint8_t poll, const char *imsi) LOGP(DRLCMAC, LOGL_DEBUG, " - TRX=%d (%d) TS=%d TA=%d pollFN=%d\n", tbf->trx->trx_no, tbf->trx->arfcn, ts, tbf->ta(), poll ? tbf->poll_fn : -1); - plen = Encoding::write_immediate_assignment(&m_bts, immediate_assignment, 1, 125, + plen = Encoding::write_immediate_assignment(tbf, immediate_assignment, 1, 125, (tbf->pdch[ts]->last_rts_fn + 21216) % 2715648, tbf->ta(), - tbf->trx->arfcn, ts, tbf->tsc(), tbf->tfi(), 7, tbf->tlli(), poll, - tbf->poll_fn, 0, m_bts.alpha, m_bts.gamma, -1); - pcu_l1if_tx_pch(immediate_assignment, plen, imsi); + tbf->trx->arfcn, ts, tbf->tsc(), 7, poll, + tbf->poll_fn, m_bts.alpha, m_bts.gamma, -1); + if (plen >= 0) + pcu_l1if_tx_pch(immediate_assignment, plen, imsi); bitvec_free(immediate_assignment); } diff --git a/src/encoding.cpp b/src/encoding.cpp index b558a4a0..7cabb714 100644 --- a/src/encoding.cpp +++ b/src/encoding.cpp @@ -28,17 +28,23 @@ #include #include -static void write_ia_rest_downlink( +static int write_ia_rest_downlink( + gprs_rlcmac_dl_tbf *tbf, bitvec * dest, unsigned& wp, - uint8_t tfi, uint32_t tlli, uint8_t polling, - uint32_t fn, uint8_t alpha, uint8_t gamma, int8_t ta_idx) + uint8_t polling, uint32_t fn, + uint8_t alpha, uint8_t gamma, int8_t ta_idx) { + if (!tbf) { + LOGP(DRLCMACDL, LOGL_ERROR, + "Cannot encode DL IMMEDIATE ASSIGNMENT without TBF\n"); + return -EINVAL; + } // GSM 04.08 10.5.2.16 IA Rest Octets bitvec_write_field_lh(dest, wp, 3, 2); // "HH" bitvec_write_field(dest, wp, 1, 2); // "01" Packet Downlink Assignment - bitvec_write_field(dest, wp,tlli,32); // TLLI + bitvec_write_field(dest, wp,tbf->tlli(),32); // TLLI bitvec_write_field(dest, wp,0x1,1); // switch TFI : on - bitvec_write_field(dest, wp,tfi,5); // TFI + bitvec_write_field(dest, wp,tbf->tfi(),5); // TFI bitvec_write_field(dest, wp,0x0,1); // RLC acknowledged mode if (alpha) { bitvec_write_field(dest, wp,0x1,1); // ALPHA = present @@ -66,17 +72,20 @@ static void write_ia_rest_downlink( bitvec_write_field(dest, wp,0x0,1); // P0 not present // bitvec_write_field(dest, wp,0x1,1); // P0 not present // bitvec_write_field(dest, wp,0xb,4); + + return 0; } -static void write_ia_rest_uplink( - struct gprs_rlcmac_bts *bts, bitvec * dest, unsigned& wp, - uint8_t tfi, uint8_t usf, uint32_t fn, uint8_t single_block, +static int write_ia_rest_uplink( + gprs_rlcmac_ul_tbf *tbf, + bitvec * dest, unsigned& wp, + uint8_t usf, uint32_t fn, uint8_t alpha, uint8_t gamma, int8_t ta_idx) { // GMS 04.08 10.5.2.37b 10.5.2.16 bitvec_write_field_lh(dest, wp, 3, 2); // "HH" bitvec_write_field(dest, wp, 0, 2); // "0" Packet Uplink Assignment - if (single_block) { + if (tbf == NULL) { bitvec_write_field(dest, wp, 0, 1); // Block Allocation : Single Block Allocation if (alpha) { bitvec_write_field(dest, wp,0x1,1); // ALPHA = present @@ -96,13 +105,13 @@ static void write_ia_rest_uplink( bitvec_write_field(dest, wp,fn % 26,5); // T2 } else { bitvec_write_field(dest, wp, 1, 1); // Block Allocation : Not Single Block Allocation - bitvec_write_field(dest, wp, tfi, 5); // TFI_ASSIGNMENT Temporary Flow Identity + bitvec_write_field(dest, wp, tbf->tfi(), 5); // TFI_ASSIGNMENT Temporary Flow Identity bitvec_write_field(dest, wp, 0, 1); // POLLING bitvec_write_field(dest, wp, 0, 1); // ALLOCATION_TYPE: dynamic bitvec_write_field(dest, wp, usf, 3); // USF bitvec_write_field(dest, wp, 0, 1); // USF_GRANULARITY bitvec_write_field(dest, wp, 0, 1); // "0" power control: Not Present - bitvec_write_field(dest, wp, bts->initial_cs_ul-1, 2); // CHANNEL_CODING_COMMAND + bitvec_write_field(dest, wp, tbf->current_cs().to_num()-1, 2); // CHANNEL_CODING_COMMAND bitvec_write_field(dest, wp, 1, 1); // TLLI_BLOCK_CHANNEL_CODING if (alpha) { bitvec_write_field(dest, wp,0x1,1); // ALPHA = present @@ -114,6 +123,7 @@ static void write_ia_rest_uplink( bitvec_write_field(dest, wp, 0, 1); // switch TIMING_ADVANCE_INDEX = off bitvec_write_field(dest, wp, 0, 1); // TBF_STARTING_TIME_FLAG } + return 0; } /* @@ -121,15 +131,15 @@ static void write_ia_rest_uplink( * see GSM 04.08, 9.1.18 and GSM 44.018, 9.1.18 + 10.5.2.16 */ int Encoding::write_immediate_assignment( - struct gprs_rlcmac_bts *bts, + struct gprs_rlcmac_tbf *tbf, bitvec * dest, uint8_t downlink, uint8_t ra, uint32_t ref_fn, uint8_t ta, uint16_t arfcn, uint8_t ts, uint8_t tsc, - uint8_t tfi, uint8_t usf, uint32_t tlli, - uint8_t polling, uint32_t fn, uint8_t single_block, uint8_t alpha, + uint8_t usf, uint8_t polling, uint32_t fn, uint8_t alpha, uint8_t gamma, int8_t ta_idx) { unsigned wp = 0; - uint8_t plen; + int plen; + int rc; bitvec_write_field(dest, wp,0x0,4); // Skip Indicator bitvec_write_field(dest, wp,0x6,4); // Protocol Discriminator @@ -172,14 +182,22 @@ int Encoding::write_immediate_assignment( plen = wp / 8; if (downlink) - write_ia_rest_downlink(dest, wp, - tfi, tlli, polling, fn, + rc = write_ia_rest_downlink(as_dl_tbf(tbf), dest, wp, + polling, fn, alpha, gamma, ta_idx); else - write_ia_rest_uplink(bts, dest, wp, - tfi, usf, fn, single_block, + rc = write_ia_rest_uplink(as_ul_tbf(tbf), dest, wp, + usf, fn, alpha, gamma, ta_idx); + if (rc < 0) { + LOGP(DRLCMAC, LOGL_ERROR, + "Failed to create IMMEDIATE ASSIGMENT (%s) for %s\n", + downlink ? "downlink" : "uplink", + tbf ? tbf->name() : "single block allocation"); + return rc; + } + return plen; } diff --git a/src/encoding.h b/src/encoding.h index 12487258..94e9a02f 100644 --- a/src/encoding.h +++ b/src/encoding.h @@ -39,11 +39,11 @@ struct gprs_rlc_data_block_info; class Encoding { public: static int write_immediate_assignment( - struct gprs_rlcmac_bts *bts, - bitvec * dest, uint8_t downlink, uint8_t ra, - uint32_t ref_fn, uint8_t ta, uint16_t arfcn, uint8_t ts, uint8_t tsc, - uint8_t tfi, uint8_t usf, uint32_t tlli, uint8_t polling, - uint32_t fn, uint8_t single_block, uint8_t alpha, uint8_t gamma, + struct gprs_rlcmac_tbf *tbf, + bitvec * dest, uint8_t downlink, uint8_t ra, + uint32_t ref_fn, uint8_t ta, uint16_t arfcn, uint8_t ts, + uint8_t tsc, uint8_t usf, uint8_t polling, + uint32_t fn, uint8_t alpha, uint8_t gamma, int8_t ta_idx); static void write_packet_uplink_assignment( diff --git a/tests/tbf/TbfTest.err b/tests/tbf/TbfTest.err index 02b6a3d7..d215196f 100644 --- a/tests/tbf/TbfTest.err +++ b/tests/tbf/TbfTest.err @@ -1522,7 +1522,7 @@ MS requests UL TBF on RACH, so we provide one: MS requests single block allocation RX: [PCU <- BTS] RACH qbit-ta=31 ra=0x73, Fn=2654167 (17,25,9), SBFn=2654270 TX: Immediate Assignment Uplink (AGCH) - - TRX=0 (0) TS=7 TA=7 TSC=0 TFI=0 USF=7 + - TRX=0 (0) TS=7 TA=7 TSC=0 TFI=-1 USF=7 Sending data request: trx=0 ts=0 sapi=2 arfcn=0 fn=0 block=0 data=2d 06 3f 10 0f 00 00 73 8b 29 07 00 c0 0c 5a 43 2b 2b 2b 2b 2b 2b 2b Searching for first unallocated TFI: TRX=0 Found TFI=0. @@ -1607,7 +1607,7 @@ MS requests UL TBF on RACH, so we provide one: MS requests single block allocation RX: [PCU <- BTS] RACH qbit-ta=31 ra=0x73, Fn=2654167 (17,25,9), SBFn=2654270 TX: Immediate Assignment Uplink (AGCH) - - TRX=0 (0) TS=7 TA=7 TSC=0 TFI=0 USF=7 + - TRX=0 (0) TS=7 TA=7 TSC=0 TFI=-1 USF=7 Sending data request: trx=0 ts=0 sapi=2 arfcn=0 fn=0 block=0 data=2d 06 3f 10 0f 00 00 73 8b 29 07 00 c0 0c 5a 43 2b 2b 2b 2b 2b 2b 2b Searching for first unallocated TFI: TRX=0 Found TFI=0. @@ -1737,7 +1737,7 @@ MS requests UL TBF on RACH, so we provide one: MS requests single block allocation RX: [PCU <- BTS] RACH qbit-ta=31 ra=0x73, Fn=2654232 (17,39,22), SBFn=2654335 TX: Immediate Assignment Uplink (AGCH) - - TRX=0 (0) TS=7 TA=7 TSC=0 TFI=0 USF=7 + - TRX=0 (0) TS=7 TA=7 TSC=0 TFI=-1 USF=7 Sending data request: trx=0 ts=0 sapi=2 arfcn=0 fn=0 block=0 data=2d 06 3f 10 0f 00 00 73 8c f6 07 00 c0 0c 68 ab 2b 2b 2b 2b 2b 2b 2b Searching for first unallocated TFI: TRX=0 Found TFI=1. @@ -1813,7 +1813,7 @@ MS requests UL TBF on RACH, so we provide one: MS requests single block allocation RX: [PCU <- BTS] RACH qbit-ta=31 ra=0x73, Fn=2654167 (17,25,9), SBFn=2654270 TX: Immediate Assignment Uplink (AGCH) - - TRX=0 (0) TS=7 TA=7 TSC=0 TFI=0 USF=7 + - TRX=0 (0) TS=7 TA=7 TSC=0 TFI=-1 USF=7 Sending data request: trx=0 ts=0 sapi=2 arfcn=0 fn=0 block=0 data=2d 06 3f 10 0f 00 00 73 8b 29 07 00 c0 0c 5a 43 2b 2b 2b 2b 2b 2b 2b Searching for first unallocated TFI: TRX=0 Found TFI=0. @@ -1906,7 +1906,7 @@ MS requests UL TBF on RACH, so we provide one: MS requests single block allocation RX: [PCU <- BTS] RACH qbit-ta=31 ra=0x73, Fn=2654224 (17,31,14), SBFn=2654327 TX: Immediate Assignment Uplink (AGCH) - - TRX=0 (0) TS=7 TA=7 TSC=0 TFI=0 USF=7 + - TRX=0 (0) TS=7 TA=7 TSC=0 TFI=-1 USF=7 Sending data request: trx=0 ts=0 sapi=2 arfcn=0 fn=0 block=0 data=2d 06 3f 10 0f 00 00 73 8b ee 07 00 c0 0c 60 6b 2b 2b 2b 2b 2b 2b 2b Searching for first unallocated TFI: TRX=0 Found TFI=0. @@ -1990,7 +1990,7 @@ MS requests UL TBF on RACH, so we provide one: MS requests single block allocation RX: [PCU <- BTS] RACH qbit-ta=31 ra=0x73, Fn=2654167 (17,25,9), SBFn=2654270 TX: Immediate Assignment Uplink (AGCH) - - TRX=0 (0) TS=7 TA=7 TSC=0 TFI=0 USF=7 + - TRX=0 (0) TS=7 TA=7 TSC=0 TFI=-1 USF=7 Sending data request: trx=0 ts=0 sapi=2 arfcn=0 fn=0 block=0 data=2d 06 3f 10 0f 00 00 73 8b 29 07 00 c0 0c 5a 43 2b 2b 2b 2b 2b 2b 2b Searching for first unallocated TFI: TRX=0 Found TFI=0. @@ -2144,7 +2144,7 @@ MS requests UL TBF on RACH, so we provide one: MS requests single block allocation RX: [PCU <- BTS] RACH qbit-ta=31 ra=0x73, Fn=2654167 (17,25,9), SBFn=2654270 TX: Immediate Assignment Uplink (AGCH) - - TRX=0 (0) TS=7 TA=7 TSC=0 TFI=0 USF=7 + - TRX=0 (0) TS=7 TA=7 TSC=0 TFI=-1 USF=7 Sending data request: trx=0 ts=0 sapi=2 arfcn=0 fn=0 block=0 data=2d 06 3f 10 0f 00 00 73 8b 29 07 00 c0 0c 5a 43 2b 2b 2b 2b 2b 2b 2b Searching for first unallocated TFI: TRX=0 Found TFI=0. -- cgit v1.2.3 From be80c3670ec03f9fd15a8a2b82b77398751910b1 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Mon, 1 Feb 2016 16:39:52 +0100 Subject: edge: Support EGPRS in IMM ASSIGNMENT Tell the MS to use EGPRS if EGPRS is enabled on the TBF. Note that only downlink TBF will be supported so far. Thus single-phase uplink assignments may not work properly. Sponsored-by: On-Waves ehf --- src/encoding.cpp | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/encoding.cpp b/src/encoding.cpp index 7cabb714..e3e1245e 100644 --- a/src/encoding.cpp +++ b/src/encoding.cpp @@ -72,6 +72,14 @@ static int write_ia_rest_downlink( bitvec_write_field(dest, wp,0x0,1); // P0 not present // bitvec_write_field(dest, wp,0x1,1); // P0 not present // bitvec_write_field(dest, wp,0xb,4); + if (tbf->is_egprs_enabled()) { + /* see GMS 44.018, 10.5.2.16 */ + unsigned int ws_enc = (tbf->m_window.ws() - 64) / 32; + bitvec_write_field_lh(dest, wp, 1, 1); // "H" + bitvec_write_field(dest, wp, ws_enc,5); // EGPRS Window Size + bitvec_write_field(dest, wp, 0x0,2); // LINK_QUALITY_MEASUREMENT_MODE + bitvec_write_field(dest, wp, 0,1); // BEP_PERIOD2 not present + } return 0; } @@ -82,6 +90,8 @@ static int write_ia_rest_uplink( uint8_t usf, uint32_t fn, uint8_t alpha, uint8_t gamma, int8_t ta_idx) { + OSMO_ASSERT(!tbf || !tbf->is_egprs_enabled()); + // GMS 04.08 10.5.2.37b 10.5.2.16 bitvec_write_field_lh(dest, wp, 3, 2); // "HH" bitvec_write_field(dest, wp, 0, 2); // "0" Packet Uplink Assignment @@ -126,6 +136,17 @@ static int write_ia_rest_uplink( return 0; } +static int write_ia_rest_egprs_uplink( + gprs_rlcmac_ul_tbf *tbf, + bitvec * dest, unsigned& wp, + uint8_t usf, uint32_t fn, + uint8_t alpha, uint8_t gamma, int8_t ta_idx) +{ + LOGP(DRLCMACUL, LOGL_ERROR, + "EGPRS Packet Uplink Assignment is not yet implemented\n"); + return -EINVAL; +} + /* * Immediate assignment, sent on the CCCH/AGCH * see GSM 04.08, 9.1.18 and GSM 44.018, 9.1.18 + 10.5.2.16 @@ -185,6 +206,10 @@ int Encoding::write_immediate_assignment( rc = write_ia_rest_downlink(as_dl_tbf(tbf), dest, wp, polling, fn, alpha, gamma, ta_idx); + else if (as_ul_tbf(tbf) && as_ul_tbf(tbf)->is_egprs_enabled()) + rc = write_ia_rest_egprs_uplink(as_ul_tbf(tbf), dest, wp, + usf, fn, + alpha, gamma, ta_idx); else rc = write_ia_rest_uplink(as_ul_tbf(tbf), dest, wp, usf, fn, -- cgit v1.2.3 From 7d5157ee17f60ab1455bc61e514803916201c444 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Mon, 1 Feb 2016 18:15:35 +0100 Subject: tbf: Only free TBF if it was replaced in rcv_control_ack Currently the TBF whose PACCH has been used to send an assigment is freed if it is in state WAIT_RELEASE. Sometimes this TBF could be used for several assignments (e.g. an 'old' DL TBF is used to assign an UL and then a DL TBF). The second of these assigments will never be sent in that case. On the other hand, the MS replaces a TBF of the same direction, so the old one can be freed in that case. Only free the TBF if it is in state WAIT_RELEASE and has the same direction like the new one. Sponsored-by: On-Waves ehf --- src/bts.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/bts.cpp b/src/bts.cpp index 8337b068..5cadda1b 100644 --- a/src/bts.cpp +++ b/src/bts.cpp @@ -799,7 +799,8 @@ void gprs_rlcmac_pdch::rcv_control_ack(Packet_Control_Acknowledgement_t *packet, "TBF is gone TLLI=0x%08x\n", tlli); return; } - if (tbf->state_is(GPRS_RLCMAC_WAIT_RELEASE)) + if (tbf->state_is(GPRS_RLCMAC_WAIT_RELEASE) && + tbf->direction == new_tbf->direction) tbf_free(tbf); if ((new_tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_CCCH))) { @@ -836,7 +837,8 @@ void gprs_rlcmac_pdch::rcv_control_ack(Packet_Control_Acknowledgement_t *packet, "TBF is gone TLLI=0x%08x\n", tlli); return; } - if (tbf->state_is(GPRS_RLCMAC_WAIT_RELEASE)) + if (tbf->state_is(GPRS_RLCMAC_WAIT_RELEASE) && + tbf->direction == new_tbf->direction) tbf_free(tbf); new_tbf->set_state(GPRS_RLCMAC_FLOW); -- cgit v1.2.3 From 1ff70c26e3a79aa583f5da8f595364efdebbfa06 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Mon, 1 Feb 2016 19:42:09 +0100 Subject: sched: Do PACCH assignments for the same direction last Currently the selection of a pending control message is done round robin. It can possibly happen, that a DL assigment is sent on a DL TBF while an UL assignment is pending. The MS will replace the old DL TBF in that case, so that it can no longer be used for the PACCH so that the UL assignment is lost. Give assigment requests for the same direction a lower priority. Sponsored-by: On-Waves ehf --- src/gprs_rlcmac_sched.cpp | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/src/gprs_rlcmac_sched.cpp b/src/gprs_rlcmac_sched.cpp index e03f84be..313e23f4 100644 --- a/src/gprs_rlcmac_sched.cpp +++ b/src/gprs_rlcmac_sched.cpp @@ -130,14 +130,18 @@ static struct msgb *sched_select_ctrl_msg( if (!tbf) continue; - if (tbf == ul_ass_tbf) + /* + * Assignments for the same direction have lower precedence, + * because they may kill the TBF when the CONTOL ACK is + * received, thus preventing the others from being processed. + */ + + if (tbf == ul_ass_tbf && tbf->direction == GPRS_RLCMAC_DL_TBF) msg = ul_ass_tbf->create_ul_ass(fn, ts); - else if (tbf == dl_ass_tbf) + else if (tbf == dl_ass_tbf && tbf->direction == GPRS_RLCMAC_UL_TBF) msg = dl_ass_tbf->create_dl_ass(fn, ts); else if (tbf == ul_ack_tbf) msg = ul_ack_tbf->create_ul_ack(fn, ts); - else - abort(); if (!msg) { tbf = NULL; @@ -149,6 +153,21 @@ static struct msgb *sched_select_ctrl_msg( break; } + if (!msg) { + /* + * If one of these is left, the response (CONTROL ACK) from the + * MS will kill the current TBF, only one of them can be + * non-NULL + */ + if (dl_ass_tbf) { + tbf = dl_ass_tbf; + msg = dl_ass_tbf->create_dl_ass(fn, ts); + } else if (ul_ass_tbf) { + tbf = ul_ass_tbf; + msg = ul_ass_tbf->create_ul_ass(fn, ts); + } + } + /* any message */ if (msg) { tbf->rotate_in_list(); -- cgit v1.2.3 From 7c72acaa941fd7f3663b0f9b36fe30f4974f1979 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Fri, 22 Jan 2016 17:06:14 +0100 Subject: ms: Add current_pacch_slots method The PACCH is specific to an MS and may change when a TBF is established or removed (see TS 44.060, 8.1.1.2.2). For multislot class type 2 phones, more than one timeslot may be used to transmit RLC/MAC control messages. Add a method that returns a set of TS which can be used for the PACCH. Sponsored-by: On-Waves ehf --- src/gprs_ms.cpp | 26 ++++++++++++++++++++++++++ src/gprs_ms.h | 1 + src/pcu_vty_functions.cpp | 7 +++++++ 3 files changed, 34 insertions(+) diff --git a/src/gprs_ms.cpp b/src/gprs_ms.cpp index 9126543e..f522586b 100644 --- a/src/gprs_ms.cpp +++ b/src/gprs_ms.cpp @@ -25,6 +25,7 @@ #include "tbf.h" #include "gprs_debug.h" #include "gprs_codel.h" +#include "pcu_utils.h" #include @@ -762,6 +763,31 @@ uint8_t GprsMs::ul_slots() const return slots; } +uint8_t GprsMs::current_pacch_slots() const +{ + uint8_t slots = 0; + + bool is_dl_active = m_dl_tbf && m_dl_tbf->is_tfi_assigned(); + bool is_ul_active = m_ul_tbf && m_ul_tbf->is_tfi_assigned(); + + if (!is_dl_active && !is_ul_active) + return 0; + + /* see TS 44.060, 8.1.1.2.2 */ + if (is_dl_active && !is_ul_active) + slots = m_dl_tbf->dl_slots(); + else if (!is_dl_active && is_ul_active) + slots = m_ul_tbf->ul_slots(); + else + slots = m_ul_tbf->ul_slots() & m_dl_tbf->dl_slots(); + + /* Assume a multislot class 1 device */ + /* TODO: For class 2 devices, this could be removed */ + slots = pcu_lsb(slots); + + return slots; +} + void GprsMs::set_reserved_slots(gprs_rlcmac_trx *trx, uint8_t ul_slots, uint8_t dl_slots) { diff --git a/src/gprs_ms.h b/src/gprs_ms.h index 246f71e4..b07f1757 100644 --- a/src/gprs_ms.h +++ b/src/gprs_ms.h @@ -97,6 +97,7 @@ public: uint8_t ul_slots() const; uint8_t reserved_dl_slots() const; uint8_t reserved_ul_slots() const; + uint8_t current_pacch_slots() const; gprs_rlcmac_trx *current_trx() const; void set_reserved_slots(gprs_rlcmac_trx *trx, uint8_t ul_slots, uint8_t dl_slots); diff --git a/src/pcu_vty_functions.cpp b/src/pcu_vty_functions.cpp index 3fcd3e60..166b15eb 100644 --- a/src/pcu_vty_functions.cpp +++ b/src/pcu_vty_functions.cpp @@ -118,6 +118,7 @@ static int show_ms(struct vty *vty, GprsMs *ms) { unsigned i; LListHead *i_tbf; + uint8_t slots; vty_out(vty, "MS TLLI=%08x, IMSI=%s%s", ms->tlli(), ms->imsi(), VTY_NEWLINE); vty_out(vty, " Timing advance (TA): %d%s", ms->ta(), VTY_NEWLINE); @@ -129,6 +130,12 @@ static int show_ms(struct vty *vty, GprsMs *ms) GprsCodingScheme::modeName(ms->mode()), VTY_NEWLINE); vty_out(vty, " MS class: %d%s", ms->ms_class(), VTY_NEWLINE); vty_out(vty, " EGPRS MS class: %d%s", ms->egprs_ms_class(), VTY_NEWLINE); + vty_out(vty, " PACCH: "); + slots = ms->current_pacch_slots(); + for (int i = 0; i < 8; i++) + if (slots & (1 << i)) + vty_out(vty, "%d ", i); + vty_out(vty, "%s", VTY_NEWLINE); vty_out(vty, " LLC queue length: %d%s", ms->llc_queue()->size(), VTY_NEWLINE); vty_out(vty, " LLC queue octets: %d%s", ms->llc_queue()->octets(), -- cgit v1.2.3 From f1a7b8fc6651f92a8b7f3f27b7ca05d07f4e44e0 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Mon, 1 Feb 2016 20:59:04 +0100 Subject: tbf: Add state WAIT_ASSIGN Currently the state on the TBF is set to ASSIGN when it is created and in general changed to FLOW when it is acknowledged by the MS. The moment when the assignment is really transmitted to the MS (which can take some time) is not reflected by the state. A TBF can considered to be valid, when the assignment is received by the MS. Add the state WAIT_ASSIGN that is entered when the assigment has been send to the MS (more precisely: when the corresponding RTS has been processed or the message has been sent to the BTS). The TBF, its PDCH(s), and its TFI can be assumed to be valid, when the TBF has a state of WAIT_ASSIGN or higher (assuming that the TBF starting time has not been set, which is currently only done for SBA, which are not associated with a TBF). Note that due to queuing in the BTS there can still be a invalid time period for immediate assignments, when the request is lingering in the AGCH or PCH queues. Sponsored-by: On-Waves ehf --- src/bts.cpp | 9 +- src/tbf.cpp | 13 ++- src/tbf.h | 10 +- tests/tbf/TbfTest.cpp | 2 +- tests/tbf/TbfTest.err | 247 +++++++++++++++++++++++++++++--------------------- 5 files changed, 167 insertions(+), 114 deletions(-) diff --git a/src/bts.cpp b/src/bts.cpp index 5cadda1b..715fb515 100644 --- a/src/bts.cpp +++ b/src/bts.cpp @@ -544,8 +544,11 @@ int BTS::rcv_rach(uint8_t ra, uint32_t Fn, int16_t qta) m_bts.trx[trx_no].arfcn, ts_no, tsc, usf, 0, sb_fn, m_bts.alpha, m_bts.gamma, -1); - if (plen >= 0) + if (plen >= 0) { pcu_l1if_tx_agch(immediate_assignment, plen); + if (tbf) + tbf->set_state(GPRS_RLCMAC_WAIT_ASSIGN); + } bitvec_free(immediate_assignment); @@ -603,8 +606,10 @@ void BTS::snd_dl_ass(gprs_rlcmac_tbf *tbf, uint8_t poll, const char *imsi) (tbf->pdch[ts]->last_rts_fn + 21216) % 2715648, tbf->ta(), tbf->trx->arfcn, ts, tbf->tsc(), 7, poll, tbf->poll_fn, m_bts.alpha, m_bts.gamma, -1); - if (plen >= 0) + if (plen >= 0) { pcu_l1if_tx_pch(immediate_assignment, plen, imsi); + tbf->set_state(GPRS_RLCMAC_WAIT_ASSIGN); + } bitvec_free(immediate_assignment); } diff --git a/src/tbf.cpp b/src/tbf.cpp index c07f379e..69b9e3a0 100644 --- a/src/tbf.cpp +++ b/src/tbf.cpp @@ -394,6 +394,7 @@ int tbf_assign_control_ts(struct gprs_rlcmac_tbf *tbf) const char *gprs_rlcmac_tbf::tbf_state_name[] = { "NULL", "ASSIGN", + "WAIT ASSIGN", "FLOW", "FINISHED", "WAIT RELEASE", @@ -823,6 +824,12 @@ void gprs_rlcmac_tbf::handle_timeout() case 0: /* assignment */ if ((state_flags & (1 << GPRS_RLCMAC_FLAG_PACCH))) { if (state_is(GPRS_RLCMAC_ASSIGN)) { + LOGP(DRLCMAC, LOGL_NOTICE, "%s releasing due to " + "PACCH assignment timeout (not yet sent).\n", + tbf_name(this)); + tbf_free(this); + return; + } else if (state_is(GPRS_RLCMAC_WAIT_ASSIGN)) { LOGP(DRLCMAC, LOGL_NOTICE, "%s releasing due to " "PACCH assignment timeout.\n", tbf_name(this)); tbf_free(this); @@ -834,7 +841,7 @@ void gprs_rlcmac_tbf::handle_timeout() if ((state_flags & (1 << GPRS_RLCMAC_FLAG_CCCH))) { gprs_rlcmac_dl_tbf *dl_tbf = as_dl_tbf(this); dl_tbf->m_wait_confirm = 0; - if (dl_tbf->state_is(GPRS_RLCMAC_ASSIGN)) { + if (dl_tbf->state_is(GPRS_RLCMAC_WAIT_ASSIGN)) { tbf_assign_control_ts(dl_tbf); if (!dl_tbf->upgrade_to_multislot) { @@ -995,6 +1002,8 @@ struct msgb *gprs_rlcmac_tbf::create_dl_ass(uint32_t fn, uint8_t ts) if (poll_ass_dl) { set_polling(new_poll_fn, ts); + if (new_dl_tbf->state_is(GPRS_RLCMAC_ASSIGN)) + new_dl_tbf->set_state(GPRS_RLCMAC_WAIT_ASSIGN); dl_ass_state = GPRS_RLCMAC_DL_ASS_WAIT_ACK; LOGP(DRLCMACDL, LOGL_INFO, "%s Scheduled DL Assignment polling on FN=%d, TS=%d\n", @@ -1067,6 +1076,8 @@ struct msgb *gprs_rlcmac_tbf::create_ul_ass(uint32_t fn, uint8_t ts) set_polling(new_poll_fn, ts); ul_ass_state = GPRS_RLCMAC_UL_ASS_WAIT_ACK; + if (new_tbf->state_is(GPRS_RLCMAC_ASSIGN)) + new_tbf->set_state(GPRS_RLCMAC_WAIT_ASSIGN); LOGP(DRLCMACDL, LOGL_INFO, "%s Scheduled UL Assignment polling on FN=%d, TS=%d\n", name(), poll_fn, poll_ts); diff --git a/src/tbf.h b/src/tbf.h index d1b286cb..443f85fc 100644 --- a/src/tbf.h +++ b/src/tbf.h @@ -43,7 +43,8 @@ class GprsMs; enum gprs_rlcmac_tbf_state { GPRS_RLCMAC_NULL = 0, /* new created TBF */ - GPRS_RLCMAC_ASSIGN, /* wait for downlink assignment */ + GPRS_RLCMAC_ASSIGN, /* wait for DL transmission */ + GPRS_RLCMAC_WAIT_ASSIGN,/* wait for confirmation */ GPRS_RLCMAC_FLOW, /* RLC/MAC flow, resource needed */ GPRS_RLCMAC_FINISHED, /* flow finished, wait for release */ GPRS_RLCMAC_WAIT_RELEASE,/* wait for release or restart of DL TBF */ @@ -230,7 +231,7 @@ protected: int set_tlli_from_ul(uint32_t new_tlli); void merge_and_clear_ms(GprsMs *old_ms); - static const char *tbf_state_name[6]; + static const char *tbf_state_name[7]; class GprsMs *m_ms; @@ -315,10 +316,7 @@ inline bool gprs_rlcmac_tbf::is_tfi_assigned() const { /* The TBF is established or has been assigned by a IMM.ASS for * download */ - return state > GPRS_RLCMAC_ASSIGN || - (direction == GPRS_RLCMAC_DL_TBF && - state == GPRS_RLCMAC_ASSIGN && - (state_flags & (1 << GPRS_RLCMAC_FLAG_CCCH))); + return state > GPRS_RLCMAC_ASSIGN; } inline uint8_t gprs_rlcmac_tbf::tfi() const diff --git a/tests/tbf/TbfTest.cpp b/tests/tbf/TbfTest.cpp index 0ff4f98c..54269c1e 100644 --- a/tests/tbf/TbfTest.cpp +++ b/tests/tbf/TbfTest.cpp @@ -1053,7 +1053,7 @@ static void test_tbf_dl_reuse() ms2 = the_bts.ms_by_tlli(tlli1); OSMO_ASSERT(ms2 == ms1); OSMO_ASSERT(ms2->dl_tbf()); - OSMO_ASSERT(ms2->dl_tbf()->state_is(GPRS_RLCMAC_ASSIGN)); + OSMO_ASSERT(ms2->dl_tbf()->state_is(GPRS_RLCMAC_WAIT_ASSIGN)); dl_tbf2 = ms2->dl_tbf(); diff --git a/tests/tbf/TbfTest.err b/tests/tbf/TbfTest.err index d215196f..ed0ed987 100644 --- a/tests/tbf/TbfTest.err +++ b/tests/tbf/TbfTest.err @@ -543,7 +543,8 @@ TBF(TFI=0 TLLI=0xc0000000 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=0 TLLI=0xc0000000 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=0 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 30 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 00 08 00 23 2b 2b 2b 2b -TBF(TFI=0 TLLI=0xc0000000 DIR=DL STATE=ASSIGN) append +TBF(TFI=0 TLLI=0xc0000000 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN +TBF(TFI=0 TLLI=0xc0000000 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 @@ -569,7 +570,8 @@ TBF(TFI=1 TLLI=0xc0000001 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=1 TLLI=0xc0000001 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=0 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 31 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 00 18 40 23 2b 2b 2b 2b -TBF(TFI=1 TLLI=0xc0000001 DIR=DL STATE=ASSIGN) append +TBF(TFI=1 TLLI=0xc0000001 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN +TBF(TFI=1 TLLI=0xc0000001 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 @@ -595,7 +597,8 @@ TBF(TFI=2 TLLI=0xc0000002 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=2 TLLI=0xc0000002 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=0 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 32 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 00 28 80 23 2b 2b 2b 2b -TBF(TFI=2 TLLI=0xc0000002 DIR=DL STATE=ASSIGN) append +TBF(TFI=2 TLLI=0xc0000002 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN +TBF(TFI=2 TLLI=0xc0000002 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 @@ -621,7 +624,8 @@ TBF(TFI=3 TLLI=0xc0000003 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=3 TLLI=0xc0000003 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=0 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 33 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 00 38 c0 23 2b 2b 2b 2b -TBF(TFI=3 TLLI=0xc0000003 DIR=DL STATE=ASSIGN) append +TBF(TFI=3 TLLI=0xc0000003 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN +TBF(TFI=3 TLLI=0xc0000003 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 @@ -647,7 +651,8 @@ TBF(TFI=4 TLLI=0xc0000004 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=4 TLLI=0xc0000004 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=0 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 34 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 00 49 00 23 2b 2b 2b 2b -TBF(TFI=4 TLLI=0xc0000004 DIR=DL STATE=ASSIGN) append +TBF(TFI=4 TLLI=0xc0000004 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN +TBF(TFI=4 TLLI=0xc0000004 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 @@ -673,7 +678,8 @@ TBF(TFI=5 TLLI=0xc0000005 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=5 TLLI=0xc0000005 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=0 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 35 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 00 59 40 23 2b 2b 2b 2b -TBF(TFI=5 TLLI=0xc0000005 DIR=DL STATE=ASSIGN) append +TBF(TFI=5 TLLI=0xc0000005 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN +TBF(TFI=5 TLLI=0xc0000005 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 @@ -699,7 +705,8 @@ TBF(TFI=6 TLLI=0xc0000006 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=6 TLLI=0xc0000006 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=0 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 36 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 00 69 80 23 2b 2b 2b 2b -TBF(TFI=6 TLLI=0xc0000006 DIR=DL STATE=ASSIGN) append +TBF(TFI=6 TLLI=0xc0000006 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN +TBF(TFI=6 TLLI=0xc0000006 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 @@ -725,7 +732,8 @@ TBF(TFI=7 TLLI=0xc0000007 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=7 TLLI=0xc0000007 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=0 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 37 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 00 79 c0 23 2b 2b 2b 2b -TBF(TFI=7 TLLI=0xc0000007 DIR=DL STATE=ASSIGN) append +TBF(TFI=7 TLLI=0xc0000007 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN +TBF(TFI=7 TLLI=0xc0000007 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 @@ -751,7 +759,8 @@ TBF(TFI=8 TLLI=0xc0000008 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=8 TLLI=0xc0000008 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=0 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 38 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 00 8a 00 23 2b 2b 2b 2b -TBF(TFI=8 TLLI=0xc0000008 DIR=DL STATE=ASSIGN) append +TBF(TFI=8 TLLI=0xc0000008 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN +TBF(TFI=8 TLLI=0xc0000008 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 @@ -777,7 +786,8 @@ TBF(TFI=9 TLLI=0xc0000009 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=9 TLLI=0xc0000009 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=0 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 30 39 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 00 9a 40 23 2b 2b 2b 2b -TBF(TFI=9 TLLI=0xc0000009 DIR=DL STATE=ASSIGN) append +TBF(TFI=9 TLLI=0xc0000009 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN +TBF(TFI=9 TLLI=0xc0000009 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 @@ -803,7 +813,8 @@ TBF(TFI=10 TLLI=0xc000000a DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=10 TLLI=0xc000000a DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=0 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 30 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 00 aa 80 23 2b 2b 2b 2b -TBF(TFI=10 TLLI=0xc000000a DIR=DL STATE=ASSIGN) append +TBF(TFI=10 TLLI=0xc000000a DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN +TBF(TFI=10 TLLI=0xc000000a DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 @@ -829,7 +840,8 @@ TBF(TFI=11 TLLI=0xc000000b DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=11 TLLI=0xc000000b DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=0 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 31 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 00 ba c0 23 2b 2b 2b 2b -TBF(TFI=11 TLLI=0xc000000b DIR=DL STATE=ASSIGN) append +TBF(TFI=11 TLLI=0xc000000b DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN +TBF(TFI=11 TLLI=0xc000000b DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 @@ -855,7 +867,8 @@ TBF(TFI=12 TLLI=0xc000000c DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=12 TLLI=0xc000000c DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=0 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 32 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 00 cb 00 23 2b 2b 2b 2b -TBF(TFI=12 TLLI=0xc000000c DIR=DL STATE=ASSIGN) append +TBF(TFI=12 TLLI=0xc000000c DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN +TBF(TFI=12 TLLI=0xc000000c DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 @@ -881,7 +894,8 @@ TBF(TFI=13 TLLI=0xc000000d DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=13 TLLI=0xc000000d DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=0 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 33 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 00 db 40 23 2b 2b 2b 2b -TBF(TFI=13 TLLI=0xc000000d DIR=DL STATE=ASSIGN) append +TBF(TFI=13 TLLI=0xc000000d DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN +TBF(TFI=13 TLLI=0xc000000d DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 @@ -907,7 +921,8 @@ TBF(TFI=14 TLLI=0xc000000e DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=14 TLLI=0xc000000e DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=0 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 34 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 00 eb 80 23 2b 2b 2b 2b -TBF(TFI=14 TLLI=0xc000000e DIR=DL STATE=ASSIGN) append +TBF(TFI=14 TLLI=0xc000000e DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN +TBF(TFI=14 TLLI=0xc000000e DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 @@ -933,7 +948,8 @@ TBF(TFI=15 TLLI=0xc000000f DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=15 TLLI=0xc000000f DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=0 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 35 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 00 fb c0 23 2b 2b 2b 2b -TBF(TFI=15 TLLI=0xc000000f DIR=DL STATE=ASSIGN) append +TBF(TFI=15 TLLI=0xc000000f DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN +TBF(TFI=15 TLLI=0xc000000f DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 @@ -959,7 +975,8 @@ TBF(TFI=16 TLLI=0xc0000010 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=16 TLLI=0xc0000010 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=0 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 36 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 01 0c 00 23 2b 2b 2b 2b -TBF(TFI=16 TLLI=0xc0000010 DIR=DL STATE=ASSIGN) append +TBF(TFI=16 TLLI=0xc0000010 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN +TBF(TFI=16 TLLI=0xc0000010 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 @@ -985,7 +1002,8 @@ TBF(TFI=17 TLLI=0xc0000011 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=17 TLLI=0xc0000011 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=0 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 37 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 01 1c 40 23 2b 2b 2b 2b -TBF(TFI=17 TLLI=0xc0000011 DIR=DL STATE=ASSIGN) append +TBF(TFI=17 TLLI=0xc0000011 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN +TBF(TFI=17 TLLI=0xc0000011 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 @@ -1011,7 +1029,8 @@ TBF(TFI=18 TLLI=0xc0000012 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=18 TLLI=0xc0000012 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=0 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 38 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 01 2c 80 23 2b 2b 2b 2b -TBF(TFI=18 TLLI=0xc0000012 DIR=DL STATE=ASSIGN) append +TBF(TFI=18 TLLI=0xc0000012 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN +TBF(TFI=18 TLLI=0xc0000012 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 @@ -1037,7 +1056,8 @@ TBF(TFI=19 TLLI=0xc0000013 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=19 TLLI=0xc0000013 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=0 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 31 39 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 01 3c c0 23 2b 2b 2b 2b -TBF(TFI=19 TLLI=0xc0000013 DIR=DL STATE=ASSIGN) append +TBF(TFI=19 TLLI=0xc0000013 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN +TBF(TFI=19 TLLI=0xc0000013 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 @@ -1063,7 +1083,8 @@ TBF(TFI=20 TLLI=0xc0000014 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=20 TLLI=0xc0000014 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=0 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 30 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 01 4d 00 23 2b 2b 2b 2b -TBF(TFI=20 TLLI=0xc0000014 DIR=DL STATE=ASSIGN) append +TBF(TFI=20 TLLI=0xc0000014 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN +TBF(TFI=20 TLLI=0xc0000014 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 @@ -1089,7 +1110,8 @@ TBF(TFI=21 TLLI=0xc0000015 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=21 TLLI=0xc0000015 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=0 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 31 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 01 5d 40 23 2b 2b 2b 2b -TBF(TFI=21 TLLI=0xc0000015 DIR=DL STATE=ASSIGN) append +TBF(TFI=21 TLLI=0xc0000015 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN +TBF(TFI=21 TLLI=0xc0000015 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 @@ -1115,7 +1137,8 @@ TBF(TFI=22 TLLI=0xc0000016 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=22 TLLI=0xc0000016 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=0 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 32 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 01 6d 80 23 2b 2b 2b 2b -TBF(TFI=22 TLLI=0xc0000016 DIR=DL STATE=ASSIGN) append +TBF(TFI=22 TLLI=0xc0000016 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN +TBF(TFI=22 TLLI=0xc0000016 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 @@ -1141,7 +1164,8 @@ TBF(TFI=23 TLLI=0xc0000017 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=23 TLLI=0xc0000017 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=0 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 33 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 01 7d c0 23 2b 2b 2b 2b -TBF(TFI=23 TLLI=0xc0000017 DIR=DL STATE=ASSIGN) append +TBF(TFI=23 TLLI=0xc0000017 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN +TBF(TFI=23 TLLI=0xc0000017 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 @@ -1167,7 +1191,8 @@ TBF(TFI=24 TLLI=0xc0000018 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=24 TLLI=0xc0000018 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=0 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 34 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 01 8e 00 23 2b 2b 2b 2b -TBF(TFI=24 TLLI=0xc0000018 DIR=DL STATE=ASSIGN) append +TBF(TFI=24 TLLI=0xc0000018 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN +TBF(TFI=24 TLLI=0xc0000018 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 @@ -1193,7 +1218,8 @@ TBF(TFI=25 TLLI=0xc0000019 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=25 TLLI=0xc0000019 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=0 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 35 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 01 9e 40 23 2b 2b 2b 2b -TBF(TFI=25 TLLI=0xc0000019 DIR=DL STATE=ASSIGN) append +TBF(TFI=25 TLLI=0xc0000019 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN +TBF(TFI=25 TLLI=0xc0000019 DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 @@ -1219,7 +1245,8 @@ TBF(TFI=26 TLLI=0xc000001a DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=26 TLLI=0xc000001a DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=0 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 36 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 01 ae 80 23 2b 2b 2b 2b -TBF(TFI=26 TLLI=0xc000001a DIR=DL STATE=ASSIGN) append +TBF(TFI=26 TLLI=0xc000001a DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN +TBF(TFI=26 TLLI=0xc000001a DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 @@ -1245,7 +1272,8 @@ TBF(TFI=27 TLLI=0xc000001b DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=27 TLLI=0xc000001b DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=0 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 37 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 01 be c0 23 2b 2b 2b 2b -TBF(TFI=27 TLLI=0xc000001b DIR=DL STATE=ASSIGN) append +TBF(TFI=27 TLLI=0xc000001b DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN +TBF(TFI=27 TLLI=0xc000001b DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 @@ -1271,7 +1299,8 @@ TBF(TFI=28 TLLI=0xc000001c DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=28 TLLI=0xc000001c DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=0 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 38 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 01 cf 00 23 2b 2b 2b 2b -TBF(TFI=28 TLLI=0xc000001c DIR=DL STATE=ASSIGN) append +TBF(TFI=28 TLLI=0xc000001c DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN +TBF(TFI=28 TLLI=0xc000001c DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 @@ -1297,7 +1326,8 @@ TBF(TFI=29 TLLI=0xc000001d DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=29 TLLI=0xc000001d DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=0 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 32 39 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 01 df 40 23 2b 2b 2b 2b -TBF(TFI=29 TLLI=0xc000001d DIR=DL STATE=ASSIGN) append +TBF(TFI=29 TLLI=0xc000001d DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN +TBF(TFI=29 TLLI=0xc000001d DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 @@ -1323,7 +1353,8 @@ TBF(TFI=30 TLLI=0xc000001e DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=30 TLLI=0xc000001e DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=0 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 33 30 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 01 ef 80 23 2b 2b 2b 2b -TBF(TFI=30 TLLI=0xc000001e DIR=DL STATE=ASSIGN) append +TBF(TFI=30 TLLI=0xc000001e DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN +TBF(TFI=30 TLLI=0xc000001e DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 @@ -1349,7 +1380,8 @@ TBF(TFI=31 TLLI=0xc000001f DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=31 TLLI=0xc000001f DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=0 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=30 33 31 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 00 00 01 ff c0 23 2b 2b 2b 2b -TBF(TFI=31 TLLI=0xc000001f DIR=DL STATE=ASSIGN) append +TBF(TFI=31 TLLI=0xc000001f DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN +TBF(TFI=31 TLLI=0xc000001f DIR=DL STATE=WAIT ASSIGN) append ********** TBF starts here ********** Allocating DL TBF: MS_CLASS=45/0 Creating MS object, TLLI = 0x00000000 @@ -1383,9 +1415,10 @@ TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=0 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=34 35 36 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 01 23 45 68 00 23 2b 2b 2b 2b -TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN) append -TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN) append -TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN) changes state from ASSIGN to RELEASING +TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN +TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=WAIT ASSIGN) append +TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=WAIT ASSIGN) append +TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=WAIT ASSIGN) changes state from WAIT ASSIGN to RELEASING TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=RELEASING) free PDCH(TS 4, TRX 0): Detaching TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=RELEASING), 0 TBFs, USFs = 00, TFIs = 00000000. Detaching TBF from MS object, TLLI = 0xc0123456, TBF = TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=RELEASING) @@ -1411,32 +1444,33 @@ TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=4 TA=0 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=34 35 36 2d 06 3f 30 0c 00 00 7d 80 00 00 00 dc 01 23 45 68 00 23 2b 2b 2b 2b -TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN) append -TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN) downlink (V(A)==0 .. V(S)==0) -- Dequeue next LLC for TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN) (len=19) +TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN +TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=WAIT ASSIGN) append +TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=WAIT ASSIGN) downlink (V(A)==0 .. V(S)==0) +- Dequeue next LLC for TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=WAIT ASSIGN) (len=19) - Sending new block at BSN 0, CS=CS-1 -- Chunk with length 19 is less than remaining space (20): add length header to to delimit LLC frame -- No space left, so we are done. -Complete DL frame for TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN)len=19 -- Dequeue next LLC for TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN) (len=19) +Complete DL frame for TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=WAIT ASSIGN)len=19 +- Dequeue next LLC for TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=WAIT ASSIGN) (len=19) data block (BSN 0, CS-1): 4d 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 msg block (BSN 0, CS-1): 07 00 00 4d 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 MSG = 07 00 00 4d 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 -TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN) downlink (V(A)==0 .. V(S)==1) +TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=WAIT ASSIGN) downlink (V(A)==0 .. V(S)==1) - Sending new block at BSN 1, CS=CS-1 -- Chunk with length 19 is less than remaining space (20): add length header to to delimit LLC frame -- No space left, so we are done. -Complete DL frame for TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN)len=19 -- Dequeue next LLC for TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN) (len=19) +Complete DL frame for TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=WAIT ASSIGN)len=19 +- Dequeue next LLC for TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=WAIT ASSIGN) (len=19) data block (BSN 1, CS-1): 4d 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 msg block (BSN 1, CS-1): 07 00 02 4d 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 MSG = 07 00 02 4d 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 -TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN) downlink (V(A)==0 .. V(S)==2) +TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=WAIT ASSIGN) downlink (V(A)==0 .. V(S)==2) - Sending new block at BSN 2, CS=CS-1 -- Chunk with length 19 is less than remaining space (20): add length header to to delimit LLC frame -- Final block, so we done. -Complete DL frame for TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN)len=19 -TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN) changes state from ASSIGN to FINISHED +Complete DL frame for TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=WAIT ASSIGN)len=19 +TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=WAIT ASSIGN) changes state from WAIT ASSIGN to FINISHED data block (BSN 2, CS-1): 4d 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling cannot be scheduled in this TS 7 (first control TS 4) @@ -1469,29 +1503,26 @@ TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=FLOW) RX: [PCU <- BTS] RACH qbit-ta=31 ra TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=FLOW) TX: START Immediate Assignment Uplink (AGCH) - TRX=0 (0) TS=7 TA=7 TSC=0 TFI=0 USF=0 Sending data request: trx=0 ts=0 sapi=2 arfcn=0 fn=0 block=0 data=2d 06 3f 10 0f 00 00 03 8b 29 07 00 c8 00 10 0b 2b 2b 2b 2b 2b 2b 2b +TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=FLOW) changes state from FLOW to WAIT ASSIGN Got RLC block, coding scheme: CS-1, length: 23 (23)) UL data: 00 01 01 f1 22 33 44 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Got CS-1 RLC block: R=0, SI=0, TFI=0, CPS=0, RSB=0, rc=184 UL DATA TFI=0 received (V(Q)=0 .. V(R)=0) -TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=FLOW) restarting timer 3169 while old timer 3169 pending -TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=FLOW): Got CS-1 RLC data block: CV=0, BSN=0, SPB=0, PI=0, E=1, TI=1, bitoffs=24 +TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=WAIT ASSIGN) restarting timer 3169 while old timer 3169 pending +TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=WAIT ASSIGN): Got CS-1 RLC data block: CV=0, BSN=0, SPB=0, PI=0, E=1, TI=1, bitoffs=24 - BSN 0 storing in window (0..63) -TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=FLOW): data_length=20, data=f1 22 33 44 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=WAIT ASSIGN): data_length=20, data=f1 22 33 44 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Decoded premier TLLI=0x00000000 of UL DATA TFI=0. Modifying MS object, UL TLLI: 0x00000000 -> 0xf1223344, not yet confirmed - Raising V(R) to 1 - Taking block 0 out, raising V(Q) to 1 - Assembling frames: (len=20) -- Frame 1 starts at offset 4, length=16, is_complete=1 -TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW) complete UL frame len=16 -LLC [PCU -> SGSN] TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW) len=16 +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN) complete UL frame len=16 +LLC [PCU -> SGSN] TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN) len=16 No bctx -- No gaps in received block, last block: BSN=0 CV=0 -- Finished with UL TBF -TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW) changes state from FLOW to FINISHED - Scheduling Ack/Nack, because TLLI is included. -- Scheduling Ack/Nack, because last block has CV==0. -Got 'TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FINISHED)', TA=7 +Got 'TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN)', TA=7 Got MS: TLLI = 0xf1223344, TA = 7 ********** TBF starts here ********** Allocating DL TBF: MS_CLASS=0/0 @@ -1516,7 +1547,8 @@ TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL) changes state from NULL to ASSIGN TX: START TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=ASSIGN) Immediate Assignment Downlink (PCH) - TRX=0 (0) TS=7 TA=7 pollFN=-1 Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=33 34 34 2d 06 3f 30 0f 00 00 7d 80 00 07 00 df 12 23 34 48 00 23 2b 2b 2b 2b -TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=ASSIGN) append +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=WAIT ASSIGN) append Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654218 block=8 data=47 94 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b MS requests UL TBF on RACH, so we provide one: MS requests single block allocation @@ -1556,15 +1588,16 @@ TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN)s start Packet Uplink Assignment ( +++++++++++++++++++++++++ TX : Packet Uplink Assignment +++++++++++++++++++++++++ ------------------------- TX : Packet Uplink Assignment ------------------------- TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN): Scheduling polling at FN 2654283 TS 7 -TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) Scheduled UL Assignment polling on FN=2654283, TS=7 -Scheduling control message at RTS for TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) (TRX=0, TS=7) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN) Scheduled UL Assignment polling on FN=2654283, TS=7 +Scheduling control message at RTS for TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN) (TRX=0, TS=7) Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654270 block=8 data=4f 28 5e 24 46 68 8f 1d 00 00 88 00 08 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b Got RLC block, coding scheme: CS-1, length: 23 (23)) +++++++++++++++++++++++++ RX : Uplink Control Block +++++++++++++++++++++++++ ------------------------- RX : Uplink Control Block ------------------------- -RX: [PCU <- BTS] TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) Packet Control Ack -TBF: [DOWNLINK] UPLINK ASSIGNED TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) -TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) changes state from ASSIGN to FLOW +RX: [PCU <- BTS] TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN) Packet Control Ack +TBF: [DOWNLINK] UPLINK ASSIGNED TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN) changes state from WAIT ASSIGN to FLOW Got RLC block, coding scheme: CS-1, length: 23 (23)) UL data: 3c 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Got CS-1 RLC block: R=0, SI=0, TFI=0, CPS=0, RSB=0, rc=184 @@ -1641,15 +1674,16 @@ TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN)s start Packet Uplink Assignment ( +++++++++++++++++++++++++ TX : Packet Uplink Assignment +++++++++++++++++++++++++ ------------------------- TX : Packet Uplink Assignment ------------------------- TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN): Scheduling polling at FN 2654283 TS 7 -TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) Scheduled UL Assignment polling on FN=2654283, TS=7 -Scheduling control message at RTS for TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) (TRX=0, TS=7) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN) Scheduled UL Assignment polling on FN=2654283, TS=7 +Scheduling control message at RTS for TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN) (TRX=0, TS=7) Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654270 block=8 data=4f 28 5e 24 46 68 8f 1d 00 00 88 00 08 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b Got RLC block, coding scheme: CS-1, length: 23 (23)) +++++++++++++++++++++++++ RX : Uplink Control Block +++++++++++++++++++++++++ ------------------------- RX : Uplink Control Block ------------------------- -RX: [PCU <- BTS] TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) Packet Control Ack -TBF: [DOWNLINK] UPLINK ASSIGNED TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) -TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) changes state from ASSIGN to FLOW +RX: [PCU <- BTS] TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN) Packet Control Ack +TBF: [DOWNLINK] UPLINK ASSIGNED TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN) changes state from WAIT ASSIGN to FLOW Got RLC block, coding scheme: CS-1, length: 23 (23)) UL data: 3c 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Got CS-1 RLC block: R=0, SI=0, TFI=0, CPS=0, RSB=0, rc=184 @@ -1692,6 +1726,7 @@ TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=ASSIGN) start Packet Downlink Assignment +++++++++++++++++++++++++ TX : Packet Downlink Assignment +++++++++++++++++++++++++ ------------------------- TX : Packet Downlink Assignment ------------------------- TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW): Scheduling polling at FN 2654288 TS 7 +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW) Scheduled DL Assignment polling on FN=2654288, TS=7 Scheduling control message at RTS for TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW) (TRX=0, TS=7) Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654275 block=9 data=48 08 00 00 0c 72 00 02 08 00 80 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b @@ -1700,7 +1735,7 @@ Got RLC block, coding scheme: CS-1, length: 23 (23)) ------------------------- RX : Uplink Control Block ------------------------- RX: [PCU <- BTS] TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW) Packet Control Ack TBF: [UPLINK] DOWNLINK ASSIGNED TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW) -TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=ASSIGN) changes state from ASSIGN to FLOW +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=WAIT ASSIGN) changes state from WAIT ASSIGN to FLOW TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) stopping timer 0. Received RTS on disabled PDCH: TRX=0 TS=0 Received RTS on disabled PDCH: TRX=0 TS=1 @@ -1776,15 +1811,16 @@ TBF(TFI=1 TLLI=0xf5667788 DIR=UL STATE=ASSIGN)s start Packet Uplink Assignment ( +++++++++++++++++++++++++ TX : Packet Uplink Assignment +++++++++++++++++++++++++ ------------------------- TX : Packet Uplink Assignment ------------------------- TBF(TFI=1 TLLI=0xf5667788 DIR=UL STATE=ASSIGN): Scheduling polling at FN 2654348 TS 7 -TBF(TFI=1 TLLI=0xf5667788 DIR=UL STATE=ASSIGN) Scheduled UL Assignment polling on FN=2654348, TS=7 -Scheduling control message at RTS for TBF(TFI=1 TLLI=0xf5667788 DIR=UL STATE=ASSIGN) (TRX=0, TS=7) +TBF(TFI=1 TLLI=0xf5667788 DIR=UL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN +TBF(TFI=1 TLLI=0xf5667788 DIR=UL STATE=WAIT ASSIGN) Scheduled UL Assignment polling on FN=2654348, TS=7 +Scheduling control message at RTS for TBF(TFI=1 TLLI=0xf5667788 DIR=UL STATE=WAIT ASSIGN) (TRX=0, TS=7) Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654335 block=11 data=48 28 5e ac ce f1 0f 1d 00 00 88 40 09 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b Got RLC block, coding scheme: CS-1, length: 23 (23)) +++++++++++++++++++++++++ RX : Uplink Control Block +++++++++++++++++++++++++ ------------------------- RX : Uplink Control Block ------------------------- -RX: [PCU <- BTS] TBF(TFI=1 TLLI=0xf5667788 DIR=UL STATE=ASSIGN) Packet Control Ack -TBF: [DOWNLINK] UPLINK ASSIGNED TBF(TFI=1 TLLI=0xf5667788 DIR=UL STATE=ASSIGN) -TBF(TFI=1 TLLI=0xf5667788 DIR=UL STATE=ASSIGN) changes state from ASSIGN to FLOW +RX: [PCU <- BTS] TBF(TFI=1 TLLI=0xf5667788 DIR=UL STATE=WAIT ASSIGN) Packet Control Ack +TBF: [DOWNLINK] UPLINK ASSIGNED TBF(TFI=1 TLLI=0xf5667788 DIR=UL STATE=WAIT ASSIGN) +TBF(TFI=1 TLLI=0xf5667788 DIR=UL STATE=WAIT ASSIGN) changes state from WAIT ASSIGN to FLOW Got RLC block, coding scheme: CS-1, length: 23 (23)) UL data: 3c 02 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Got CS-1 RLC block: R=0, SI=0, TFI=1, CPS=0, RSB=0, rc=184 @@ -1847,15 +1883,16 @@ TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN)s start Packet Uplink Assignment ( +++++++++++++++++++++++++ TX : Packet Uplink Assignment +++++++++++++++++++++++++ ------------------------- TX : Packet Uplink Assignment ------------------------- TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN): Scheduling polling at FN 2654283 TS 7 -TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) Scheduled UL Assignment polling on FN=2654283, TS=7 -Scheduling control message at RTS for TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) (TRX=0, TS=7) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN) Scheduled UL Assignment polling on FN=2654283, TS=7 +Scheduling control message at RTS for TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN) (TRX=0, TS=7) Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654270 block=8 data=4f 28 5e 24 46 68 83 1d 00 00 88 00 08 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b Got RLC block, coding scheme: CS-1, length: 23 (23)) +++++++++++++++++++++++++ RX : Uplink Control Block +++++++++++++++++++++++++ ------------------------- RX : Uplink Control Block ------------------------- -RX: [PCU <- BTS] TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) Packet Control Ack -TBF: [DOWNLINK] UPLINK ASSIGNED TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) -TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) changes state from ASSIGN to FLOW +RX: [PCU <- BTS] TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN) Packet Control Ack +TBF: [DOWNLINK] UPLINK ASSIGNED TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN) changes state from WAIT ASSIGN to FLOW Got RLC block, coding scheme: CS-1, length: 23 (23)) UL data: 3c 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Got CS-1 RLC block: R=0, SI=0, TFI=0, CPS=0, RSB=0, rc=184 @@ -1943,15 +1980,16 @@ TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN)s start Packet Uplink Assignment ( +++++++++++++++++++++++++ TX : Packet Uplink Assignment +++++++++++++++++++++++++ ------------------------- TX : Packet Uplink Assignment ------------------------- TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN): Scheduling polling at FN 2654340 TS 7 -TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) Scheduled UL Assignment polling on FN=2654340, TS=7 -Scheduling control message at RTS for TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) (TRX=0, TS=7) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN) Scheduled UL Assignment polling on FN=2654340, TS=7 +Scheduling control message at RTS for TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN) (TRX=0, TS=7) Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654327 block=9 data=4f 28 5e 24 46 68 83 1d 00 00 88 00 08 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b Got RLC block, coding scheme: CS-1, length: 23 (23)) +++++++++++++++++++++++++ RX : Uplink Control Block +++++++++++++++++++++++++ ------------------------- RX : Uplink Control Block ------------------------- -RX: [PCU <- BTS] TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) Packet Control Ack -TBF: [DOWNLINK] UPLINK ASSIGNED TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) -TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) changes state from ASSIGN to FLOW +RX: [PCU <- BTS] TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN) Packet Control Ack +TBF: [DOWNLINK] UPLINK ASSIGNED TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN) changes state from WAIT ASSIGN to FLOW ********** TBF starts here ********** Allocating DL TBF: MS_CLASS=1/0 Slot Allocation (Algorithm A) for class 1 @@ -2024,15 +2062,16 @@ TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN)s start Packet Uplink Assignment ( +++++++++++++++++++++++++ TX : Packet Uplink Assignment +++++++++++++++++++++++++ ------------------------- TX : Packet Uplink Assignment ------------------------- TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN): Scheduling polling at FN 2654283 TS 7 -TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) Scheduled UL Assignment polling on FN=2654283, TS=7 -Scheduling control message at RTS for TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) (TRX=0, TS=7) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN) Scheduled UL Assignment polling on FN=2654283, TS=7 +Scheduling control message at RTS for TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN) (TRX=0, TS=7) Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654270 block=8 data=4f 28 5e 24 46 68 83 1d 00 00 88 00 08 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b Got RLC block, coding scheme: CS-1, length: 23 (23)) +++++++++++++++++++++++++ RX : Uplink Control Block +++++++++++++++++++++++++ ------------------------- RX : Uplink Control Block ------------------------- -RX: [PCU <- BTS] TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) Packet Control Ack -TBF: [DOWNLINK] UPLINK ASSIGNED TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) -TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) changes state from ASSIGN to FLOW +RX: [PCU <- BTS] TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN) Packet Control Ack +TBF: [DOWNLINK] UPLINK ASSIGNED TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN) changes state from WAIT ASSIGN to FLOW Got RLC block, coding scheme: CS-1, length: 23 (23)) UL data: 3c 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Got CS-1 RLC block: R=0, SI=0, TFI=0, CPS=0, RSB=0, rc=184 @@ -2105,14 +2144,15 @@ TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=FLOW) RX: [PCU <- BTS] RACH qbit-ta=31 ra TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=FLOW) TX: START Immediate Assignment Uplink (AGCH) - TRX=0 (0) TS=7 TA=7 TSC=0 TFI=0 USF=0 Sending data request: trx=0 ts=0 sapi=2 arfcn=0 fn=0 block=0 data=2d 06 3f 10 0f 00 00 03 8b ed 07 00 c8 00 10 0b 2b 2b 2b 2b 2b 2b 2b +TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=FLOW) changes state from FLOW to WAIT ASSIGN Got RLC block, coding scheme: CS-1, length: 23 (23)) UL data: 00 01 01 f1 22 33 44 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Got CS-1 RLC block: R=0, SI=0, TFI=0, CPS=0, RSB=0, rc=184 UL DATA TFI=0 received (V(Q)=0 .. V(R)=0) -TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=FLOW) restarting timer 3169 while old timer 3169 pending -TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=FLOW): Got CS-1 RLC data block: CV=0, BSN=0, SPB=0, PI=0, E=1, TI=1, bitoffs=24 +TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=WAIT ASSIGN) restarting timer 3169 while old timer 3169 pending +TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=WAIT ASSIGN): Got CS-1 RLC data block: CV=0, BSN=0, SPB=0, PI=0, E=1, TI=1, bitoffs=24 - BSN 0 storing in window (0..63) -TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=FLOW): data_length=20, data=f1 22 33 44 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=WAIT ASSIGN): data_length=20, data=f1 22 33 44 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Decoded premier TLLI=0x00000000 of UL DATA TFI=0. Got RACH from TLLI=0x00000000 while TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=ASSIGN) still exists. Killing pending DL TBF TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=ASSIGN) changes state from ASSIGN to RELEASING @@ -2130,14 +2170,10 @@ Destroying MS object, TLLI = 0x00000000 - Taking block 0 out, raising V(Q) to 1 - Assembling frames: (len=20) -- Frame 1 starts at offset 4, length=16, is_complete=1 -TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW) complete UL frame len=16 -LLC [PCU -> SGSN] TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW) len=16 +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN) complete UL frame len=16 +LLC [PCU -> SGSN] TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN) len=16 No bctx -- No gaps in received block, last block: BSN=0 CV=0 -- Finished with UL TBF -TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW) changes state from FLOW to FINISHED - Scheduling Ack/Nack, because TLLI is included. -- Scheduling Ack/Nack, because last block has CV==0. New MS: TLLI = 0xf1223344, TA = 7, IMSI = 0011223344, LLC = 2 Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654218 block=8 data=47 94 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b MS requests UL TBF on RACH, so we provide one: @@ -2178,15 +2214,16 @@ TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN)s start Packet Uplink Assignment ( +++++++++++++++++++++++++ TX : Packet Uplink Assignment +++++++++++++++++++++++++ ------------------------- TX : Packet Uplink Assignment ------------------------- TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN): Scheduling polling at FN 2654283 TS 7 -TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) Scheduled UL Assignment polling on FN=2654283, TS=7 -Scheduling control message at RTS for TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) (TRX=0, TS=7) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN) Scheduled UL Assignment polling on FN=2654283, TS=7 +Scheduling control message at RTS for TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN) (TRX=0, TS=7) Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654270 block=8 data=4f 28 5e 24 46 68 83 1d 00 00 88 00 08 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b Got RLC block, coding scheme: CS-1, length: 23 (23)) +++++++++++++++++++++++++ RX : Uplink Control Block +++++++++++++++++++++++++ ------------------------- RX : Uplink Control Block ------------------------- -RX: [PCU <- BTS] TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) Packet Control Ack -TBF: [DOWNLINK] UPLINK ASSIGNED TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) -TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN) changes state from ASSIGN to FLOW +RX: [PCU <- BTS] TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN) Packet Control Ack +TBF: [DOWNLINK] UPLINK ASSIGNED TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN) changes state from WAIT ASSIGN to FLOW Got RLC block, coding scheme: CS-1, length: 23 (23)) UL data: 3c 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Got CS-1 RLC block: R=0, SI=0, TFI=0, CPS=0, RSB=0, rc=184 @@ -2268,6 +2305,7 @@ TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=ASSIGN) start Packet Downlink Assignment +++++++++++++++++++++++++ TX : Packet Downlink Assignment +++++++++++++++++++++++++ ------------------------- TX : Packet Downlink Assignment ------------------------- TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW): Scheduling polling at FN 2654288 TS 7 +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW) Scheduled DL Assignment polling on FN=2654288, TS=7 Scheduling control message at RTS for TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW) (TRX=0, TS=7) Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654275 block=9 data=48 08 00 00 0c 72 00 02 08 00 80 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b @@ -2276,7 +2314,7 @@ Got RLC block, coding scheme: CS-1, length: 23 (23)) ------------------------- RX : Uplink Control Block ------------------------- RX: [PCU <- BTS] TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW) Packet Control Ack TBF: [UPLINK] DOWNLINK ASSIGNED TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW) -TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=ASSIGN) changes state from ASSIGN to FLOW +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=WAIT ASSIGN) changes state from WAIT ASSIGN to FLOW TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) stopping timer 0. Received RTS on disabled PDCH: TRX=0 TS=0 Received RTS on disabled PDCH: TRX=0 TS=1 @@ -2899,6 +2937,7 @@ TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=ASSIGN) start Packet Downlink Assignment +++++++++++++++++++++++++ TX : Packet Downlink Assignment +++++++++++++++++++++++++ ------------------------- TX : Packet Downlink Assignment ------------------------- TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=WAIT RELEASE): Scheduling polling at FN 2654413 TS 7 +TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=WAIT RELEASE) Scheduled DL Assignment polling on FN=2654413, TS=7 Scheduling control message at RTS for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=WAIT RELEASE) (TRX=0, TS=7) Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654400 block=2 data=48 08 20 08 0c 72 00 02 18 00 80 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b @@ -2913,7 +2952,7 @@ TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=RELEASING) stopping timer 3193. PDCH(TS 7, TRX 0): Detaching TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=RELEASING), 1 TBFs, USFs = 01, TFIs = 00000002. Detaching TBF from MS object, TLLI = 0xf1223344, TBF = TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=RELEASING) ********** TBF ends here ********** -TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=ASSIGN) changes state from ASSIGN to FLOW +TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=WAIT ASSIGN) changes state from WAIT ASSIGN to FLOW TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW) stopping timer 0. Received RTS on disabled PDCH: TRX=0 TS=0 Received RTS on disabled PDCH: TRX=0 TS=1 -- cgit v1.2.3 From 9e8593917f3e301c3487f73430ce416a08360ce8 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Tue, 2 Feb 2016 11:48:37 +0100 Subject: rlc: Support encoding of EGPRS header type 1 + 2 Currently only header type 3 (MCS-1 to MCS-4) is supported. Add header structs to rlc.h and extend Encoding::rlc_write_dl_data_header accordingly. Sponsored-by: On-Waves ehf --- src/encoding.cpp | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++---- src/rlc.cpp | 10 +++++++-- src/rlc.h | 32 ++++++++++++++++++++++++++- src/tbf_dl.cpp | 3 ++- 4 files changed, 104 insertions(+), 8 deletions(-) diff --git a/src/encoding.cpp b/src/encoding.cpp index e3e1245e..a7d7b169 100644 --- a/src/encoding.cpp +++ b/src/encoding.cpp @@ -711,10 +711,14 @@ unsigned Encoding::write_repeated_page_info(bitvec * dest, unsigned& wp, uint8_t int Encoding::rlc_write_dl_data_header(const struct gprs_rlc_data_info *rlc, uint8_t *data) { + struct gprs_rlc_dl_header_egprs_1 *egprs1; + struct gprs_rlc_dl_header_egprs_2 *egprs2; struct gprs_rlc_dl_header_egprs_3 *egprs3; struct rlc_dl_header *gprs; unsigned int e_fbi_header; GprsCodingScheme cs = rlc->cs; + unsigned int offs; + unsigned int bsn_delta; switch(cs.headerTypeData()) { case GprsCodingScheme::HEADER_GPRS_DATA: @@ -733,6 +737,65 @@ int Encoding::rlc_write_dl_data_header(const struct gprs_rlc_data_info *rlc, gprs->bsn = rlc->block_info[0].bsn; break; + case GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_1: + egprs1 = static_cast + ((void *)data); + + egprs1->usf = rlc->usf; + egprs1->es_p = rlc->es_p; + egprs1->rrbp = rlc->rrbp; + egprs1->tfi_a = rlc->tfi >> 0; /* 1 bit LSB */ + egprs1->tfi_b = rlc->tfi >> 1; /* 4 bits */ + egprs1->pr = rlc->pr; + egprs1->cps = rlc->cps; + + egprs1->bsn1_a = rlc->block_info[0].bsn >> 0; /* 2 bits LSB */ + egprs1->bsn1_b = rlc->block_info[0].bsn >> 2; /* 8 bits */ + egprs1->bsn1_c = rlc->block_info[0].bsn >> 10; /* 1 bit */ + + bsn_delta = (rlc->block_info[1].bsn - rlc->block_info[0].bsn) & + (RLC_EGPRS_SNS - 1); + + egprs1->bsn2_a = bsn_delta >> 0; /* 7 bits LSB */ + egprs1->bsn2_b = bsn_delta >> 7; /* 3 bits */ + + /* first FBI/E header */ + e_fbi_header = rlc->block_info[0].e ? 0x01 : 0; + e_fbi_header |= rlc->block_info[0].cv == 0 ? 0x02 : 0; /* FBI */ + e_fbi_header <<= 0; + data[5] = (data[5] & 0b11111100) | e_fbi_header; + + /* second FBI/E header */ + e_fbi_header = rlc->block_info[1].e ? 0x01 : 0; + e_fbi_header |= rlc->block_info[1].cv == 0 ? 0x02 : 0; /* FBI */ + offs = rlc->data_offs_bits[1] / 8; + OSMO_ASSERT(rlc->data_offs_bits[1] % 8 == 4); + e_fbi_header <<= 2; + data[offs] = (data[offs] & 0b11110011) | e_fbi_header; + break; + + case GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_2: + egprs2 = static_cast + ((void *)data); + + egprs2->usf = rlc->usf; + egprs2->es_p = rlc->es_p; + egprs2->rrbp = rlc->rrbp; + egprs2->tfi_a = rlc->tfi >> 0; /* 1 bit LSB */ + egprs2->tfi_b = rlc->tfi >> 1; /* 4 bits */ + egprs2->pr = rlc->pr; + egprs2->cps = rlc->cps; + + egprs2->bsn1_a = rlc->block_info[0].bsn >> 0; /* 2 bits LSB */ + egprs2->bsn1_b = rlc->block_info[0].bsn >> 2; /* 8 bits */ + egprs2->bsn1_c = rlc->block_info[0].bsn >> 10; /* 1 bit */ + + e_fbi_header = rlc->block_info[0].e ? 0x01 : 0; + e_fbi_header |= rlc->block_info[0].cv == 0 ? 0x02 : 0; /* FBI */ + e_fbi_header <<= 4; + data[3] = (data[3] & 0b11001111) | e_fbi_header; + break; + case GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_3: egprs3 = static_cast ((void *)data); @@ -758,10 +821,6 @@ int Encoding::rlc_write_dl_data_header(const struct gprs_rlc_data_info *rlc, data[4] = (data[4] & 0b11111110) | (e_fbi_header >> 8); break; - case GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_1: - case GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_2: - /* TODO: Support both header types */ - /* fall through */ default: LOGP(DRLCMACDL, LOGL_ERROR, "Encoding of uplink %s data blocks not yet supported.\n", diff --git a/src/rlc.cpp b/src/rlc.cpp index e4a9563a..efe42614 100644 --- a/src/rlc.cpp +++ b/src/rlc.cpp @@ -327,7 +327,8 @@ void gprs_rlc_data_block_info_init(struct gprs_rlc_data_block_info *rdbi, rdbi->spb = 0; } -unsigned int gprs_rlc_mcs_cps(GprsCodingScheme cs, int punct, int with_padding) +unsigned int gprs_rlc_mcs_cps(GprsCodingScheme cs, int punct, int punct2, + int with_padding) { switch (GprsCodingScheme::Scheme(cs)) { case GprsCodingScheme::MCS1: return 0b1011 + punct % 2; @@ -335,7 +336,12 @@ unsigned int gprs_rlc_mcs_cps(GprsCodingScheme cs, int punct, int with_padding) case GprsCodingScheme::MCS3: return (with_padding ? 0b0110 : 0b0011) + punct % 3; case GprsCodingScheme::MCS4: return 0b0000 + punct % 3; - /* TODO: Add missing MCS */ + case GprsCodingScheme::MCS5: return 0b100 + punct % 2; + case GprsCodingScheme::MCS6: return (with_padding ? 0b010 : 0b000) + + punct % 2; + case GprsCodingScheme::MCS7: return 0b10100 + 3 * (punct % 3) + punct2 % 3; + case GprsCodingScheme::MCS8: return 0b01011 + 3 * (punct % 3) + punct2 % 3; + case GprsCodingScheme::MCS9: return 0b00000 + 4 * (punct % 3) + punct2 % 3; default: ; } diff --git a/src/rlc.h b/src/rlc.h index 3a7f1a1a..8c3a4124 100644 --- a/src/rlc.h +++ b/src/rlc.h @@ -106,7 +106,8 @@ void gprs_rlc_data_info_init_ul(struct gprs_rlc_data_info *rlc, GprsCodingScheme cs); void gprs_rlc_data_block_info_init(struct gprs_rlc_data_block_info *rdbi, GprsCodingScheme cs); -unsigned int gprs_rlc_mcs_cps(GprsCodingScheme cs, int punct, int with_padding); +unsigned int gprs_rlc_mcs_cps(GprsCodingScheme cs, int punct, int punct2, + int with_padding); /* * I hold the currently transferred blocks and will provide @@ -300,6 +301,35 @@ struct gprs_rlc_ul_header_egprs_3 { dummy:1; } __attribute__ ((packed)); +struct gprs_rlc_dl_header_egprs_1 { + uint8_t usf:3, + es_p:2, + rrbp:2, + tfi_a:1; + uint8_t tfi_b:4, + pr:2, + bsn1_a:2; + uint8_t bsn1_b:8; + uint8_t bsn1_c:1, + bsn2_a:7; + uint8_t bsn2_b:3, + cps:5; +} __attribute__ ((packed)); + +struct gprs_rlc_dl_header_egprs_2 { + uint8_t usf:3, + es_p:2, + rrbp:2, + tfi_a:1; + uint8_t tfi_b:4, + pr:2, + bsn1_a:2; + uint8_t bsn1_b:8; + uint8_t bsn1_c:1, + cps:3, + dummy:4; +} __attribute__ ((packed)); + struct gprs_rlc_dl_header_egprs_3 { uint8_t usf:3, es_p:2, diff --git a/src/tbf_dl.cpp b/src/tbf_dl.cpp index 03f0cc4d..e567f57d 100644 --- a/src/tbf_dl.cpp +++ b/src/tbf_dl.cpp @@ -545,7 +545,8 @@ struct msgb *gprs_rlcmac_dl_tbf::create_dl_acked_block( rlc.usf = 7; /* will be set at scheduler */ rlc.pr = 0; /* FIXME: power reduction */ rlc.tfi = m_tfi; /* TFI */ - rlc.cps = gprs_rlc_mcs_cps(cs, 0, 0); + /* TODO: Use real puncturing values */ + rlc.cps = gprs_rlc_mcs_cps(cs, 0, 0, 0); rlc.block_info[data_block_idx] = m_rlc.block(index)->block_info; rdbi = &rlc.block_info[data_block_idx]; -- cgit v1.2.3 From 4cc46d3e2ab3762733d1e496d4d4a6f749faba47 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Tue, 2 Feb 2016 16:02:16 +0100 Subject: edge/vty: Set initial MCS This adds the following VTY command (config-pcu node): - mcs <1-9> sets initial DL and UL MCS to the same value - mcs <1-9> <1-9> sets initial DL and UL MCS separately - no mcs sets the default values Sponsored-by: On-Waves ehf --- src/pcu_vty.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/src/pcu_vty.c b/src/pcu_vty.c index b5ee1b55..58fea993 100644 --- a/src/pcu_vty.c +++ b/src/pcu_vty.c @@ -109,6 +109,14 @@ static int config_write_pcu(struct vty *vty) bts->cs_lqual_ranges[3].low, VTY_NEWLINE); + if (bts->initial_mcs_dl != 1 && bts->initial_mcs_ul != 1) { + if (bts->initial_mcs_ul == bts->initial_mcs_dl) + vty_out(vty, " mcs %d%s", bts->initial_mcs_dl, + VTY_NEWLINE); + else + vty_out(vty, " mcs %d %d%s", bts->initial_mcs_dl, + bts->initial_mcs_ul, VTY_NEWLINE); + } if (bts->max_mcs_dl && bts->max_mcs_ul) { if (bts->max_mcs_ul == bts->max_mcs_dl) vty_out(vty, " mcs max %d%s", bts->max_mcs_dl, @@ -407,6 +415,38 @@ DEFUN(cfg_pcu_no_cs_max, #define MCS_STR "Modulation and Coding Scheme configuration (EGPRS)\n" +DEFUN(cfg_pcu_mcs, + cfg_pcu_mcs_cmd, + "mcs <1-9> [<1-9>]", + MCS_STR + "Initial MCS value to be used (default 1)\n" + "Use a different initial MCS value for the uplink") +{ + struct gprs_rlcmac_bts *bts = bts_main_data(); + uint8_t cs = atoi(argv[0]); + + bts->initial_mcs_dl = cs; + if (argc > 1) + bts->initial_mcs_ul = atoi(argv[1]); + else + bts->initial_mcs_ul = cs; + + return CMD_SUCCESS; +} + +DEFUN(cfg_pcu_no_mcs, + cfg_pcu_no_mcs_cmd, + "no mcs", + NO_STR MCS_STR) +{ + struct gprs_rlcmac_bts *bts = bts_main_data(); + + bts->initial_mcs_dl = 1; + bts->initial_mcs_ul = 1; + + return CMD_SUCCESS; +} + DEFUN(cfg_pcu_mcs_max, cfg_pcu_mcs_max_cmd, "mcs max <1-9> [<1-9>]", @@ -913,6 +953,8 @@ int pcu_vty_init(const struct log_info *cat) install_element(PCU_NODE, &cfg_pcu_cs_downgrade_thrsh_cmd); install_element(PCU_NODE, &cfg_pcu_no_cs_downgrade_thrsh_cmd); install_element(PCU_NODE, &cfg_pcu_cs_lqual_ranges_cmd); + install_element(PCU_NODE, &cfg_pcu_mcs_cmd); + install_element(PCU_NODE, &cfg_pcu_no_mcs_cmd); install_element(PCU_NODE, &cfg_pcu_mcs_max_cmd); install_element(PCU_NODE, &cfg_pcu_no_mcs_max_cmd); install_element(PCU_NODE, &cfg_pcu_window_size_cmd); -- cgit v1.2.3 From 2305afd86c3d3541d01fee0dee408a4510f96d4e Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Wed, 3 Feb 2016 15:25:04 +0100 Subject: cs: Add family related methods Add family handling and the related methods family, isFamilyCompatible, isCombinable, decToSingleBlock to GprsCodingScheme. Sponsored-by: On-Waves ehf --- src/gprs_coding_scheme.cpp | 78 ++++++++++++++++++++++++++++++++++++---------- src/gprs_coding_scheme.h | 11 +++++++ tests/edge/EdgeTest.cpp | 13 ++++++++ 3 files changed, 86 insertions(+), 16 deletions(-) diff --git a/src/gprs_coding_scheme.cpp b/src/gprs_coding_scheme.cpp index aaa8b205..4f1db1df 100644 --- a/src/gprs_coding_scheme.cpp +++ b/src/gprs_coding_scheme.cpp @@ -30,23 +30,38 @@ static struct { unsigned int data_bytes; const char *name; GprsCodingScheme::HeaderType data_hdr; + GprsCodingScheme::Family family; } mcs_info[GprsCodingScheme::NUM_SCHEMES] = { - {{0, 0}, {0, 0}, 0, "UNKNOWN", GprsCodingScheme::HEADER_INVALID}, - {{23, 0}, {23, 0}, 20, "CS-1", GprsCodingScheme::HEADER_GPRS_DATA}, - {{33, 7}, {33, 7}, 30, "CS-2", GprsCodingScheme::HEADER_GPRS_DATA}, - {{39, 3}, {39, 3}, 36, "CS-3", GprsCodingScheme::HEADER_GPRS_DATA}, - {{53, 7}, {53, 7}, 50, "CS-4", GprsCodingScheme::HEADER_GPRS_DATA}, - - {{26, 1}, {26, 1}, 22, "MCS-1", GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_3}, - {{32, 1}, {32, 1}, 28, "MCS-2", GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_3}, - {{41, 1}, {41, 1}, 37, "MCS-3", GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_3}, - {{48, 1}, {48, 1}, 44, "MCS-4", GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_3}, - - {{60, 7}, {59, 6}, 56, "MCS-5", GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_2}, - {{78, 7}, {77, 6}, 74, "MCS-6", GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_2}, - {{118, 2}, {117, 4}, 56, "MCS-7", GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_1}, - {{142, 2}, {141, 4}, 68, "MCS-8", GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_1}, - {{154, 2}, {153, 4}, 74, "MCS-9", GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_1}, + {{0, 0}, {0, 0}, 0, "UNKNOWN", + GprsCodingScheme::HEADER_INVALID, GprsCodingScheme::FAMILY_INVALID}, + {{23, 0}, {23, 0}, 20, "CS-1", + GprsCodingScheme::HEADER_GPRS_DATA, GprsCodingScheme::FAMILY_INVALID}, + {{33, 7}, {33, 7}, 30, "CS-2", + GprsCodingScheme::HEADER_GPRS_DATA, GprsCodingScheme::FAMILY_INVALID}, + {{39, 3}, {39, 3}, 36, "CS-3", + GprsCodingScheme::HEADER_GPRS_DATA, GprsCodingScheme::FAMILY_INVALID}, + {{53, 7}, {53, 7}, 50, "CS-4", + GprsCodingScheme::HEADER_GPRS_DATA, GprsCodingScheme::FAMILY_INVALID}, + + {{26, 1}, {26, 1}, 22, "MCS-1", + GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_3, GprsCodingScheme::FAMILY_C}, + {{32, 1}, {32, 1}, 28, "MCS-2", + GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_3, GprsCodingScheme::FAMILY_B}, + {{41, 1}, {41, 1}, 37, "MCS-3", + GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_3, GprsCodingScheme::FAMILY_A}, + {{48, 1}, {48, 1}, 44, "MCS-4", + GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_3, GprsCodingScheme::FAMILY_C}, + + {{60, 7}, {59, 6}, 56, "MCS-5", + GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_2, GprsCodingScheme::FAMILY_B}, + {{78, 7}, {77, 6}, 74, "MCS-6", + GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_2, GprsCodingScheme::FAMILY_A}, + {{118, 2}, {117, 4}, 56, "MCS-7", + GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_1, GprsCodingScheme::FAMILY_B}, + {{142, 2}, {141, 4}, 68, "MCS-8", + GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_1, GprsCodingScheme::FAMILY_A}, + {{154, 2}, {153, 4}, 74, "MCS-9", + GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_1, GprsCodingScheme::FAMILY_A}, }; static struct { @@ -167,6 +182,11 @@ GprsCodingScheme::HeaderType GprsCodingScheme::headerTypeData() const return mcs_info[m_scheme].data_hdr; } +GprsCodingScheme::Family GprsCodingScheme::family() const +{ + return mcs_info[m_scheme].family; +} + void GprsCodingScheme::inc(Mode mode) { if (!isCompatible(mode)) @@ -232,3 +252,29 @@ const char *GprsCodingScheme::modeName(Mode mode) default: return "???"; } } + +bool GprsCodingScheme::isFamilyCompatible(GprsCodingScheme o) const +{ + if (*this == o) + return true; + + if (family() == FAMILY_INVALID) + return false; + + return family() == o.family(); +} + +bool GprsCodingScheme::isCombinable(GprsCodingScheme o) const +{ + return numDataBlocks() == o.numDataBlocks(); +} + +void GprsCodingScheme::decToSingleBlock(bool *needStuffing) +{ + switch (m_scheme) { + case MCS7: *needStuffing = false; m_scheme = MCS5; break; + case MCS8: *needStuffing = true; m_scheme = MCS6; break; + case MCS9: *needStuffing = false; m_scheme = MCS6; break; + default: *needStuffing = false; break; + } +} diff --git a/src/gprs_coding_scheme.h b/src/gprs_coding_scheme.h index 348aefbd..e9a06a53 100644 --- a/src/gprs_coding_scheme.h +++ b/src/gprs_coding_scheme.h @@ -50,6 +50,13 @@ public: NUM_HEADER_TYPES }; + enum Family { + FAMILY_INVALID, + FAMILY_A, + FAMILY_B, + FAMILY_C, + }; + GprsCodingScheme(Scheme s = UNKNOWN); operator bool() const {return m_scheme != UNKNOWN;} @@ -65,11 +72,14 @@ public: bool isEgprsGmsk() const {return isEgprs() && m_scheme <= MCS4;} bool isCompatible(Mode mode) const; bool isCompatible(GprsCodingScheme o) const; + bool isFamilyCompatible(GprsCodingScheme o) const; + bool isCombinable(GprsCodingScheme o) const; void inc(Mode mode); void dec(Mode mode); void inc(); void dec(); + void decToSingleBlock(bool *needStuffing); unsigned int sizeUL() const; unsigned int sizeDL() const; @@ -87,6 +97,7 @@ public: const char *name() const; HeaderType headerTypeData() const; HeaderType headerTypeControl() const; + Family family() const; static GprsCodingScheme getBySizeUL(unsigned size); static GprsCodingScheme getGprsByNum(unsigned num); diff --git a/tests/edge/EdgeTest.cpp b/tests/edge/EdgeTest.cpp index 704a7355..02e9bc20 100644 --- a/tests/edge/EdgeTest.cpp +++ b/tests/edge/EdgeTest.cpp @@ -46,6 +46,7 @@ int16_t spoof_mnc = 0, spoof_mcc = 0; static void check_coding_scheme(GprsCodingScheme& cs, GprsCodingScheme::Mode mode) { volatile unsigned expected_size; + bool need_padding; GprsCodingScheme new_cs; OSMO_ASSERT(cs.isValid()); @@ -84,6 +85,18 @@ static void check_coding_scheme(GprsCodingScheme& cs, GprsCodingScheme::Mode mod OSMO_ASSERT(new_cs.isCompatible(mode)); OSMO_ASSERT(new_cs == cs); } + + new_cs = cs; + new_cs.decToSingleBlock(&need_padding); + OSMO_ASSERT(new_cs.isFamilyCompatible(cs)); + OSMO_ASSERT(cs.isFamilyCompatible(new_cs)); + OSMO_ASSERT(cs.isCompatible(new_cs)); + if (need_padding) { + OSMO_ASSERT(new_cs.maxDataBlockBytes() > cs.maxDataBlockBytes()); + } else { + OSMO_ASSERT(new_cs.maxDataBlockBytes() == cs.maxDataBlockBytes()); + } + } static void test_coding_scheme() -- cgit v1.2.3 From 215e18c9d45cdaa43705ae7c8f8cb43c0db28225 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Wed, 3 Feb 2016 18:22:34 +0100 Subject: cs: Add GprsCodingScheme::optionalPaddingBits Return the amount of optional padding bits, which is 6*8 for MCS-3 and MCS-6 and 0 for all other coding schemes. The padding is needed the encode 68 byte data blocks (MCS-8) with these schemes. See TS 44.060, 9.3.2.1 and Annex J for details. Sponsored-by: On-Waves ehf --- src/gprs_coding_scheme.cpp | 34 ++++++++++++++++++++-------------- src/gprs_coding_scheme.h | 1 + tests/edge/EdgeTest.cpp | 3 ++- 3 files changed, 23 insertions(+), 15 deletions(-) diff --git a/src/gprs_coding_scheme.cpp b/src/gprs_coding_scheme.cpp index 4f1db1df..8601d4f5 100644 --- a/src/gprs_coding_scheme.cpp +++ b/src/gprs_coding_scheme.cpp @@ -28,39 +28,40 @@ static struct { unsigned int data_header_bits; } uplink, downlink; unsigned int data_bytes; + unsigned int optional_padding_bits; const char *name; GprsCodingScheme::HeaderType data_hdr; GprsCodingScheme::Family family; } mcs_info[GprsCodingScheme::NUM_SCHEMES] = { - {{0, 0}, {0, 0}, 0, "UNKNOWN", + {{0, 0}, {0, 0}, 0, 0, "UNKNOWN", GprsCodingScheme::HEADER_INVALID, GprsCodingScheme::FAMILY_INVALID}, - {{23, 0}, {23, 0}, 20, "CS-1", + {{23, 0}, {23, 0}, 20, 0, "CS-1", GprsCodingScheme::HEADER_GPRS_DATA, GprsCodingScheme::FAMILY_INVALID}, - {{33, 7}, {33, 7}, 30, "CS-2", + {{33, 7}, {33, 7}, 30, 0, "CS-2", GprsCodingScheme::HEADER_GPRS_DATA, GprsCodingScheme::FAMILY_INVALID}, - {{39, 3}, {39, 3}, 36, "CS-3", + {{39, 3}, {39, 3}, 36, 0, "CS-3", GprsCodingScheme::HEADER_GPRS_DATA, GprsCodingScheme::FAMILY_INVALID}, - {{53, 7}, {53, 7}, 50, "CS-4", + {{53, 7}, {53, 7}, 50, 0, "CS-4", GprsCodingScheme::HEADER_GPRS_DATA, GprsCodingScheme::FAMILY_INVALID}, - {{26, 1}, {26, 1}, 22, "MCS-1", + {{26, 1}, {26, 1}, 22, 0, "MCS-1", GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_3, GprsCodingScheme::FAMILY_C}, - {{32, 1}, {32, 1}, 28, "MCS-2", + {{32, 1}, {32, 1}, 28, 0, "MCS-2", GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_3, GprsCodingScheme::FAMILY_B}, - {{41, 1}, {41, 1}, 37, "MCS-3", + {{41, 1}, {41, 1}, 37, 48, "MCS-3", GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_3, GprsCodingScheme::FAMILY_A}, - {{48, 1}, {48, 1}, 44, "MCS-4", + {{48, 1}, {48, 1}, 44, 0, "MCS-4", GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_3, GprsCodingScheme::FAMILY_C}, - {{60, 7}, {59, 6}, 56, "MCS-5", + {{60, 7}, {59, 6}, 56, 0, "MCS-5", GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_2, GprsCodingScheme::FAMILY_B}, - {{78, 7}, {77, 6}, 74, "MCS-6", + {{78, 7}, {77, 6}, 74, 48, "MCS-6", GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_2, GprsCodingScheme::FAMILY_A}, - {{118, 2}, {117, 4}, 56, "MCS-7", + {{118, 2}, {117, 4}, 56, 0, "MCS-7", GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_1, GprsCodingScheme::FAMILY_B}, - {{142, 2}, {141, 4}, 68, "MCS-8", + {{142, 2}, {141, 4}, 68, 0, "MCS-8", GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_1, GprsCodingScheme::FAMILY_A}, - {{154, 2}, {153, 4}, 74, "MCS-9", + {{154, 2}, {153, 4}, 74, 0, "MCS-9", GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_1, GprsCodingScheme::FAMILY_A}, }; @@ -152,6 +153,11 @@ unsigned int GprsCodingScheme::maxDataBlockBytes() const return mcs_info[m_scheme].data_bytes; } +unsigned int GprsCodingScheme::optionalPaddingBits() const +{ + return mcs_info[m_scheme].optional_padding_bits; +} + unsigned int GprsCodingScheme::numDataBlocks() const { return hdr_type_info[headerTypeData()].num_blocks; diff --git a/src/gprs_coding_scheme.h b/src/gprs_coding_scheme.h index e9a06a53..aec37623 100644 --- a/src/gprs_coding_scheme.h +++ b/src/gprs_coding_scheme.h @@ -94,6 +94,7 @@ public: unsigned int numDataHeaderBitsUL() const; unsigned int numDataHeaderBitsDL() const; unsigned int numDataBlockHeaderBits() const; + unsigned int optionalPaddingBits() const; const char *name() const; HeaderType headerTypeData() const; HeaderType headerTypeControl() const; diff --git a/tests/edge/EdgeTest.cpp b/tests/edge/EdgeTest.cpp index 02e9bc20..80997a4b 100644 --- a/tests/edge/EdgeTest.cpp +++ b/tests/edge/EdgeTest.cpp @@ -92,7 +92,8 @@ static void check_coding_scheme(GprsCodingScheme& cs, GprsCodingScheme::Mode mod OSMO_ASSERT(cs.isFamilyCompatible(new_cs)); OSMO_ASSERT(cs.isCompatible(new_cs)); if (need_padding) { - OSMO_ASSERT(new_cs.maxDataBlockBytes() > cs.maxDataBlockBytes()); + OSMO_ASSERT(new_cs.maxDataBlockBytes() == + new_cs.optionalPaddingBits()/8 + cs.maxDataBlockBytes()); } else { OSMO_ASSERT(new_cs.maxDataBlockBytes() == cs.maxDataBlockBytes()); } -- cgit v1.2.3 From b55f31373554394092bb923acca723cc7808cd49 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Wed, 3 Feb 2016 18:28:04 +0100 Subject: rlc: Add with_padding argument to gprs_rlc_data_info_init_dl/ul The offsets of the data areas change when padding is used (see TS 44.060, 9.3.2.1 and Annex J for details). Extend the parameter lists to pass the with_padding flag and use that information to compute the correct offsets. Sponsored-by: On-Waves ehf --- src/rlc.cpp | 27 ++++++++++++++++++--------- src/rlc.h | 7 ++++--- src/tbf_dl.cpp | 2 +- tests/edge/EdgeTest.cpp | 36 ++++++++++++++++++------------------ 4 files changed, 41 insertions(+), 31 deletions(-) diff --git a/src/rlc.cpp b/src/rlc.cpp index efe42614..ca12e919 100644 --- a/src/rlc.cpp +++ b/src/rlc.cpp @@ -282,43 +282,52 @@ bool gprs_rlc_ul_window::invalidate_bsn(const uint16_t bsn) } static void gprs_rlc_data_header_init(struct gprs_rlc_data_info *rlc, - GprsCodingScheme cs, unsigned int header_bits) + GprsCodingScheme cs, bool with_padding, unsigned int header_bits) { unsigned int i; + unsigned int padding_bits = with_padding ? cs.optionalPaddingBits() : 0; memset(rlc, 0, sizeof(*rlc)); rlc->cs = cs; + rlc->with_padding = with_padding; rlc->num_data_blocks = cs.numDataBlocks(); OSMO_ASSERT(rlc->num_data_blocks <= ARRAY_SIZE(rlc->block_info)); for (i = 0; i < rlc->num_data_blocks; i++) { - gprs_rlc_data_block_info_init(&rlc->block_info[i], cs); + gprs_rlc_data_block_info_init(&rlc->block_info[i], cs, + with_padding); rlc->data_offs_bits[i] = - header_bits + + header_bits + padding_bits + (i+1) * cs.numDataBlockHeaderBits() + i * 8 * rlc->block_info[0].data_len; } } void gprs_rlc_data_info_init_dl(struct gprs_rlc_data_info *rlc, - GprsCodingScheme cs) + GprsCodingScheme cs, bool with_padding) { - return gprs_rlc_data_header_init(rlc, cs, cs.numDataHeaderBitsDL()); + return gprs_rlc_data_header_init(rlc, cs, with_padding, + cs.numDataHeaderBitsDL()); } void gprs_rlc_data_info_init_ul(struct gprs_rlc_data_info *rlc, - GprsCodingScheme cs) + GprsCodingScheme cs, bool with_padding) { - return gprs_rlc_data_header_init(rlc, cs, cs.numDataHeaderBitsUL()); + return gprs_rlc_data_header_init(rlc, cs, with_padding, + cs.numDataHeaderBitsUL()); } void gprs_rlc_data_block_info_init(struct gprs_rlc_data_block_info *rdbi, - GprsCodingScheme cs) + GprsCodingScheme cs, bool with_padding) { - rdbi->data_len = cs.maxDataBlockBytes(); + unsigned int data_len = cs.maxDataBlockBytes(); + if (with_padding) + data_len -= cs.optionalPaddingBits() / 8; + + rdbi->data_len = data_len; rdbi->bsn = 0; rdbi->ti = 0; rdbi->e = 1; diff --git a/src/rlc.h b/src/rlc.h index 8c3a4124..f6415b76 100644 --- a/src/rlc.h +++ b/src/rlc.h @@ -83,6 +83,7 @@ struct gprs_rlc_data_info { unsigned int rrbp; unsigned int pr; unsigned int num_data_blocks; + unsigned int with_padding; unsigned int data_offs_bits[2]; struct gprs_rlc_data_block_info block_info[2]; }; @@ -101,11 +102,11 @@ struct gprs_rlc_data { }; void gprs_rlc_data_info_init_dl(struct gprs_rlc_data_info *rlc, - GprsCodingScheme cs); + GprsCodingScheme cs, bool with_padding); void gprs_rlc_data_info_init_ul(struct gprs_rlc_data_info *rlc, - GprsCodingScheme cs); + GprsCodingScheme cs, bool with_padding); void gprs_rlc_data_block_info_init(struct gprs_rlc_data_block_info *rdbi, - GprsCodingScheme cs); + GprsCodingScheme cs, bool with_padding); unsigned int gprs_rlc_mcs_cps(GprsCodingScheme cs, int punct, int punct2, int with_padding); diff --git a/src/tbf_dl.cpp b/src/tbf_dl.cpp index e567f57d..6208b601 100644 --- a/src/tbf_dl.cpp +++ b/src/tbf_dl.cpp @@ -540,7 +540,7 @@ struct msgb *gprs_rlcmac_dl_tbf::create_dl_acked_block( cs = m_rlc.block(index)->cs; - gprs_rlc_data_info_init_dl(&rlc, cs); + gprs_rlc_data_info_init_dl(&rlc, cs, false); rlc.usf = 7; /* will be set at scheduler */ rlc.pr = 0; /* FIXME: power reduction */ diff --git a/tests/edge/EdgeTest.cpp b/tests/edge/EdgeTest.cpp index 80997a4b..96ea0c12 100644 --- a/tests/edge/EdgeTest.cpp +++ b/tests/edge/EdgeTest.cpp @@ -515,7 +515,7 @@ static void test_rlc_unit_encoder() /* TS 44.060, B.1 */ cs = GprsCodingScheme::CS4; - gprs_rlc_data_block_info_init(&rdbi, cs); + gprs_rlc_data_block_info_init(&rdbi, cs, false); num_chunks = 0; write_offset = 0; memset(data, 0, sizeof(data)); @@ -562,7 +562,7 @@ static void test_rlc_unit_encoder() cs = GprsCodingScheme::CS1; /* Block 1 */ - gprs_rlc_data_block_info_init(&rdbi, cs); + gprs_rlc_data_block_info_init(&rdbi, cs, false); num_chunks = 0; write_offset = 0; memset(data, 0, sizeof(data)); @@ -582,7 +582,7 @@ static void test_rlc_unit_encoder() OSMO_ASSERT(data[1] == 0); /* Block 2 */ - gprs_rlc_data_block_info_init(&rdbi, cs); + gprs_rlc_data_block_info_init(&rdbi, cs, false); num_chunks = 0; write_offset = 0; memset(data, 0, sizeof(data)); @@ -615,7 +615,7 @@ static void test_rlc_unit_encoder() cs = GprsCodingScheme::CS1; /* Block 1 */ - gprs_rlc_data_block_info_init(&rdbi, cs); + gprs_rlc_data_block_info_init(&rdbi, cs, false); num_chunks = 0; write_offset = 0; memset(data, 0, sizeof(data)); @@ -650,7 +650,7 @@ static void test_rlc_unit_encoder() cs = GprsCodingScheme::CS1; /* Block 1 */ - gprs_rlc_data_block_info_init(&rdbi, cs); + gprs_rlc_data_block_info_init(&rdbi, cs, false); num_chunks = 0; write_offset = 0; memset(data, 0, sizeof(data)); @@ -673,7 +673,7 @@ static void test_rlc_unit_encoder() cs = GprsCodingScheme::CS1; /* Block 1 */ - gprs_rlc_data_block_info_init(&rdbi, cs); + gprs_rlc_data_block_info_init(&rdbi, cs, false); num_chunks = 0; write_offset = 0; memset(data, 0, sizeof(data)); @@ -696,7 +696,7 @@ static void test_rlc_unit_encoder() cs = GprsCodingScheme::CS1; /* Block 1 */ - gprs_rlc_data_block_info_init(&rdbi, cs); + gprs_rlc_data_block_info_init(&rdbi, cs, false); num_chunks = 0; write_offset = 0; memset(data, 0, sizeof(data)); @@ -715,7 +715,7 @@ static void test_rlc_unit_encoder() OSMO_ASSERT(data[0] == 0); /* Block 2 */ - gprs_rlc_data_block_info_init(&rdbi, cs); + gprs_rlc_data_block_info_init(&rdbi, cs, false); num_chunks = 0; write_offset = 0; memset(data, 0, sizeof(data)); @@ -748,7 +748,7 @@ static void test_rlc_unit_encoder() cs = GprsCodingScheme::MCS4; /* Block 1 */ - gprs_rlc_data_block_info_init(&rdbi, cs); + gprs_rlc_data_block_info_init(&rdbi, cs, false); num_chunks = 0; write_offset = 0; memset(data, 0, sizeof(data)); @@ -800,7 +800,7 @@ static void test_rlc_unit_encoder() cs = GprsCodingScheme::MCS2; /* Block 1 */ - gprs_rlc_data_block_info_init(&rdbi, cs); + gprs_rlc_data_block_info_init(&rdbi, cs, false); num_chunks = 0; write_offset = 0; memset(data, 0, sizeof(data)); @@ -832,7 +832,7 @@ static void test_rlc_unit_encoder() OSMO_ASSERT(data[1] == 0); /* Block 2 */ - gprs_rlc_data_block_info_init(&rdbi, cs); + gprs_rlc_data_block_info_init(&rdbi, cs, false); num_chunks = 0; write_offset = 0; memset(data, 0, sizeof(data)); @@ -877,7 +877,7 @@ static void test_rlc_unit_encoder() OSMO_ASSERT(data[3] == 0); /* Block 3 */ - gprs_rlc_data_block_info_init(&rdbi, cs); + gprs_rlc_data_block_info_init(&rdbi, cs, false); num_chunks = 0; write_offset = 0; memset(data, 0, sizeof(data)); @@ -917,7 +917,7 @@ static void test_rlc_unit_encoder() cs = GprsCodingScheme::MCS2; /* Block 1 */ - gprs_rlc_data_block_info_init(&rdbi, cs); + gprs_rlc_data_block_info_init(&rdbi, cs, false); num_chunks = 0; write_offset = 0; memset(data, 0, sizeof(data)); @@ -941,7 +941,7 @@ static void test_rlc_unit_encoder() cs = GprsCodingScheme::MCS2; /* Block 1 */ - gprs_rlc_data_block_info_init(&rdbi, cs); + gprs_rlc_data_block_info_init(&rdbi, cs, false); num_chunks = 0; write_offset = 0; memset(data, 0, sizeof(data)); @@ -966,7 +966,7 @@ static void test_rlc_unit_encoder() cs = GprsCodingScheme::MCS2; /* Block 1 */ - gprs_rlc_data_block_info_init(&rdbi, cs); + gprs_rlc_data_block_info_init(&rdbi, cs, false); num_chunks = 0; write_offset = 0; memset(data, 0, sizeof(data)); @@ -1018,7 +1018,7 @@ static void test_rlc_unaligned_copy() block_idx++) { struct gprs_rlc_data_info rlc; - gprs_rlc_data_info_init_dl(&rlc, cs); + gprs_rlc_data_info_init_dl(&rlc, cs, false); memset(bits, pattern, sizeof(bits)); Decoding::rlc_copy_to_aligned_buffer( @@ -1062,12 +1062,12 @@ static void test_rlc_info_init() struct gprs_rlc_data_info rlc; printf("=== start %s ===\n", __func__); - gprs_rlc_data_info_init_dl(&rlc, GprsCodingScheme(GprsCodingScheme::CS1)); + gprs_rlc_data_info_init_dl(&rlc, GprsCodingScheme(GprsCodingScheme::CS1), false); OSMO_ASSERT(rlc.num_data_blocks == 1); OSMO_ASSERT(rlc.data_offs_bits[0] == 24); OSMO_ASSERT(rlc.block_info[0].data_len == 20); - gprs_rlc_data_info_init_dl(&rlc, GprsCodingScheme(GprsCodingScheme::MCS1)); + gprs_rlc_data_info_init_dl(&rlc, GprsCodingScheme(GprsCodingScheme::MCS1), false); OSMO_ASSERT(rlc.num_data_blocks == 1); OSMO_ASSERT(rlc.data_offs_bits[0] == 33); OSMO_ASSERT(rlc.block_info[0].data_len == 22); -- cgit v1.2.3 From fbd82e4e9f38ed6885e94ccf8d0297bba65b50de Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Wed, 3 Feb 2016 18:31:19 +0100 Subject: rlc: Add gprs_rlc_mcs_cps_decode To access EGPRS data blocks, the optional padding must be taken into account. Whether padding has been used must be dervied from the CPS field in the header of the RLC EGPRS data message. Add this function to decode the CPS value and extract that information. Sponsored-by: On-Waves ehf --- src/rlc.cpp | 29 +++++++++++++++++++++++++++++ src/rlc.h | 2 ++ 2 files changed, 31 insertions(+) diff --git a/src/rlc.cpp b/src/rlc.cpp index ca12e919..79d8f48a 100644 --- a/src/rlc.cpp +++ b/src/rlc.cpp @@ -356,3 +356,32 @@ unsigned int gprs_rlc_mcs_cps(GprsCodingScheme cs, int punct, int punct2, return -1; } + +void gprs_rlc_mcs_cps_decode(unsigned int cps, + GprsCodingScheme cs, int *punct, int *punct2, int *with_padding) +{ + *punct2 = -1; + *with_padding = 0; + + switch (GprsCodingScheme::Scheme(cs)) { + case GprsCodingScheme::MCS1: + cps -= 0b1011; *punct = cps % 2; break; + case GprsCodingScheme::MCS2: + cps -= 0b1001; *punct = cps % 2; break; + case GprsCodingScheme::MCS3: + cps -= 0b0011; *punct = cps % 3; *with_padding = cps >= 3; break; + case GprsCodingScheme::MCS4: + cps -= 0b0000; *punct = cps % 3; break; + case GprsCodingScheme::MCS5: + cps -= 0b100; *punct = cps % 2; break; + case GprsCodingScheme::MCS6: + cps -= 0b000; *punct = cps % 2; *with_padding = cps >= 2; break; + case GprsCodingScheme::MCS7: + cps -= 0b10100; *punct = cps / 3; *punct2 = cps % 3; break; + case GprsCodingScheme::MCS8: + cps -= 0b01011; *punct = cps / 3; *punct2 = cps % 3; break; + case GprsCodingScheme::MCS9: + cps -= 0b00000; *punct = cps / 4; *punct2 = cps % 3; break; + default: ; + } +} diff --git a/src/rlc.h b/src/rlc.h index f6415b76..28913bd0 100644 --- a/src/rlc.h +++ b/src/rlc.h @@ -109,6 +109,8 @@ void gprs_rlc_data_block_info_init(struct gprs_rlc_data_block_info *rdbi, GprsCodingScheme cs, bool with_padding); unsigned int gprs_rlc_mcs_cps(GprsCodingScheme cs, int punct, int punct2, int with_padding); +void gprs_rlc_mcs_cps_decode(unsigned int cps, GprsCodingScheme cs, + int *punct, int *punct2, int *with_padding); /* * I hold the currently transferred blocks and will provide -- cgit v1.2.3 From 0f5c6956dd3ab09ddda72c186fb80b8b0d44f9e4 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Wed, 3 Feb 2016 18:35:27 +0100 Subject: rlc: Use the rlc structure to access the data unit in the RLC message Currently most offsets are hard-coded which makes it difficult to access the data units and their headers when padding has to be taken into account. These offset are already provided by the gprs_rlc_data_info_init_ul/dl functions. Change the encoder/decoder to use these values. Note that some assumptions (bit alignment) are still present in the code and checked by assertions. Sponsored-by: On-Waves ehf --- src/decoding.cpp | 38 +++++++++++++++++++++----------------- src/encoding.cpp | 14 ++++++++++---- 2 files changed, 31 insertions(+), 21 deletions(-) diff --git a/src/decoding.cpp b/src/decoding.cpp index f4b539b1..f2b548c1 100644 --- a/src/decoding.cpp +++ b/src/decoding.cpp @@ -348,16 +348,16 @@ int Decoding::rlc_parse_ul_data_header(struct gprs_rlc_data_info *rlc, const struct rlc_ul_header *gprs; unsigned int e_ti_header; unsigned int cur_bit = 0; - unsigned int data_len = 0; - - rlc->cs = cs; - - data_len = cs.maxDataBlockBytes(); + int punct, punct2, with_padding, cps; + unsigned int offs; switch(cs.headerTypeData()) { case GprsCodingScheme::HEADER_GPRS_DATA: gprs = static_cast ((void *)data); + + gprs_rlc_data_info_init_ul(rlc, cs, false); + rlc->r = gprs->r; rlc->si = gprs->si; rlc->tfi = gprs->tfi; @@ -372,20 +372,23 @@ int Decoding::rlc_parse_ul_data_header(struct gprs_rlc_data_info *rlc, rlc->block_info[0].ti = gprs->ti; rlc->block_info[0].spb = 0; - cur_bit += 3 * 8; - - rlc->data_offs_bits[0] = cur_bit; - rlc->block_info[0].data_len = data_len; - cur_bit += data_len * 8; + cur_bit += rlc->data_offs_bits[0]; + /* skip data area */ + cur_bit += cs.maxDataBlockBytes() * 8; break; case GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_3: egprs3 = static_cast ((void *)data); + + cps = (egprs3->cps_a << 0) | (egprs3->cps_b << 2); + gprs_rlc_mcs_cps_decode(cps, cs, &punct, &punct2, &with_padding); + gprs_rlc_data_info_init_ul(rlc, cs, with_padding); + rlc->r = egprs3->r; rlc->si = egprs3->si; rlc->tfi = (egprs3->tfi_a << 0) | (egprs3->tfi_b << 2); - rlc->cps = (egprs3->cps_a << 0) | (egprs3->cps_b << 2); + rlc->cps = cps; rlc->rsb = egprs3->rsb; rlc->num_data_blocks = 1; @@ -395,17 +398,18 @@ int Decoding::rlc_parse_ul_data_header(struct gprs_rlc_data_info *rlc, rlc->block_info[0].bsn = (egprs3->bsn1_a << 0) | (egprs3->bsn1_b << 5); - cur_bit += 3 * 8 + 7; + cur_bit += rlc->data_offs_bits[0] - 2; - e_ti_header = (data[3] + (data[4] << 8)) >> 7; + offs = rlc->data_offs_bits[0] / 8; + OSMO_ASSERT(rlc->data_offs_bits[0] % 8 == 1); + + e_ti_header = (data[offs-1] + (data[offs] << 8)) >> 7; rlc->block_info[0].e = !!(e_ti_header & 0x01); rlc->block_info[0].ti = !!(e_ti_header & 0x02); cur_bit += 2; - rlc->data_offs_bits[0] = cur_bit; - rlc->block_info[0].data_len = data_len; - cur_bit += data_len * 8; - + /* skip data area */ + cur_bit += cs.maxDataBlockBytes() * 8; break; case GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_1: diff --git a/src/encoding.cpp b/src/encoding.cpp index a7d7b169..6c50abe3 100644 --- a/src/encoding.cpp +++ b/src/encoding.cpp @@ -762,8 +762,10 @@ int Encoding::rlc_write_dl_data_header(const struct gprs_rlc_data_info *rlc, /* first FBI/E header */ e_fbi_header = rlc->block_info[0].e ? 0x01 : 0; e_fbi_header |= rlc->block_info[0].cv == 0 ? 0x02 : 0; /* FBI */ + offs = rlc->data_offs_bits[0] / 8; + OSMO_ASSERT(rlc->data_offs_bits[0] % 8 == 2); e_fbi_header <<= 0; - data[5] = (data[5] & 0b11111100) | e_fbi_header; + data[offs] = (data[offs] & 0b11111100) | e_fbi_header; /* second FBI/E header */ e_fbi_header = rlc->block_info[1].e ? 0x01 : 0; @@ -792,8 +794,10 @@ int Encoding::rlc_write_dl_data_header(const struct gprs_rlc_data_info *rlc, e_fbi_header = rlc->block_info[0].e ? 0x01 : 0; e_fbi_header |= rlc->block_info[0].cv == 0 ? 0x02 : 0; /* FBI */ + offs = rlc->data_offs_bits[0] / 8; + OSMO_ASSERT(rlc->data_offs_bits[0] % 8 == 6); e_fbi_header <<= 4; - data[3] = (data[3] & 0b11001111) | e_fbi_header; + data[offs] = (data[offs] & 0b11001111) | e_fbi_header; break; case GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_3: @@ -816,9 +820,11 @@ int Encoding::rlc_write_dl_data_header(const struct gprs_rlc_data_info *rlc, e_fbi_header = rlc->block_info[0].e ? 0x01 : 0; e_fbi_header |= rlc->block_info[0].cv == 0 ? 0x02 : 0; /* FBI */ + offs = rlc->data_offs_bits[0] / 8; + OSMO_ASSERT(rlc->data_offs_bits[0] % 8 == 1); e_fbi_header <<= 7; - data[3] = (data[3] & 0b01111111) | (e_fbi_header >> 0); - data[4] = (data[4] & 0b11111110) | (e_fbi_header >> 8); + data[offs-1] = (data[offs-1] & 0b01111111) | (e_fbi_header >> 0); + data[offs] = (data[offs] & 0b11111110) | (e_fbi_header >> 8); break; default: -- cgit v1.2.3 From 2d2efb13e7232bd1f1dc5ccc1633b01ceb256c0b Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Thu, 4 Feb 2016 11:09:19 +0100 Subject: tbf/tests: Add tests for EGPRS TBF establishment Add a test for EGPRS two phase access based on RA caps. Add a test for DL TBFs where data block are encoded with each MCS. Sponsored-by: On-Waves ehf --- tests/tbf/TbfTest.cpp | 169 ++++- tests/tbf/TbfTest.err | 1731 +++++++++++++++++++++++++++++++++++++++++++++++++ tests/tbf/TbfTest.ok | 13 + 3 files changed, 1897 insertions(+), 16 deletions(-) diff --git a/tests/tbf/TbfTest.cpp b/tests/tbf/TbfTest.cpp index 54269c1e..e1be8448 100644 --- a/tests/tbf/TbfTest.cpp +++ b/tests/tbf/TbfTest.cpp @@ -166,7 +166,7 @@ static void setup_bts(BTS *the_bts, uint8_t ts_no, uint8_t cs = 1) } static gprs_rlcmac_dl_tbf *create_dl_tbf(BTS *the_bts, uint8_t ms_class, - uint8_t *trx_no_) + uint8_t egprs_ms_class, uint8_t *trx_no_) { gprs_rlcmac_bts *bts; int tfi; @@ -178,7 +178,7 @@ static gprs_rlcmac_dl_tbf *create_dl_tbf(BTS *the_bts, uint8_t ms_class, tfi = the_bts->tfi_find_free(GPRS_RLCMAC_DL_TBF, &trx_no, -1); OSMO_ASSERT(tfi >= 0); - dl_tbf = tbf_alloc_dl_tbf(bts, NULL, trx_no, ms_class, 0, 1); + dl_tbf = tbf_alloc_dl_tbf(bts, NULL, trx_no, ms_class, egprs_ms_class, 1); check_tbf(dl_tbf); /* "Establish" the DL TBF */ @@ -249,7 +249,7 @@ static void test_tbf_final_ack(enum test_tbf_final_ack_mode test_mode) gprs_rlcmac_tbf *new_tbf; setup_bts(&the_bts, ts_no); - dl_tbf = create_dl_tbf(&the_bts, ms_class, &trx_no); + dl_tbf = create_dl_tbf(&the_bts, ms_class, 0, &trx_no); dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF); ms = dl_tbf->ms(); @@ -324,7 +324,7 @@ static void test_tbf_delayed_release() setup_bts(&the_bts, ts_no); bts->dl_tbf_idle_msec = 200; - dl_tbf = create_dl_tbf(&the_bts, ms_class, &trx_no); + dl_tbf = create_dl_tbf(&the_bts, ms_class, 0, &trx_no); dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF); for (i = 0; i < sizeof(llc_data); i++) @@ -389,8 +389,8 @@ static void test_tbf_imsi() setup_bts(&the_bts, ts_no); - dl_tbf[0] = create_dl_tbf(&the_bts, ms_class, &trx_no); - dl_tbf[1] = create_dl_tbf(&the_bts, ms_class, &trx_no); + dl_tbf[0] = create_dl_tbf(&the_bts, ms_class, 0, &trx_no); + dl_tbf[1] = create_dl_tbf(&the_bts, ms_class, 0, &trx_no); dl_tbf[0]->update_ms(0xf1000001, GPRS_RLCMAC_DL_TBF); dl_tbf[1]->update_ms(0xf1000002, GPRS_RLCMAC_DL_TBF); @@ -619,7 +619,7 @@ static void send_control_ack(gprs_rlcmac_tbf *tbf) static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase(BTS *the_bts, uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta, - uint8_t ms_class) + uint8_t ms_class, uint8_t egprs_ms_class) { GprsMs *ms; uint32_t rach_fn = *fn - 51; @@ -660,6 +660,14 @@ static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase(BTS *the_bts, ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability. MS_RA_capability_value[0].u.Content.Multislot_capability. GPRS_multislot_class = ms_class; + if (egprs_ms_class) { + ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability. + MS_RA_capability_value[0].u.Content.Multislot_capability. + Exist_EGPRS_multislot_class = 1; + ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability. + MS_RA_capability_value[0].u.Content.Multislot_capability. + EGPRS_multislot_class = ms_class; + } send_ul_mac_block(the_bts, trx_no, ts_no, &ulreq, sba_fn); @@ -715,7 +723,8 @@ static void send_dl_data(BTS *the_bts, uint32_t tlli, const char *imsi, } } -static void transmit_dl_data(BTS *the_bts, uint32_t tlli, uint32_t *fn) +static void transmit_dl_data(BTS *the_bts, uint32_t tlli, uint32_t *fn, + uint8_t slots = 0xff) { gprs_rlcmac_dl_tbf *dl_tbf; GprsMs *ms; @@ -728,10 +737,13 @@ static void transmit_dl_data(BTS *the_bts, uint32_t tlli, uint32_t *fn) while (dl_tbf->have_data()) { uint8_t bn = fn2bn(*fn); - for (ts_no = 0 ; ts_no < 8; ts_no += 1) + for (ts_no = 0 ; ts_no < 8; ts_no += 1) { + if (!(slots & (1 << ts_no))) + continue; gprs_rlcmac_rcv_rts_block(the_bts->bts_data(), dl_tbf->trx->trx_no, ts_no, 0, *fn, bn); + } *fn = fn_add_blocks(*fn, 1); } } @@ -778,7 +790,8 @@ static void test_tbf_two_phase() setup_bts(&the_bts, ts_no, 4); - ul_tbf = establish_ul_tbf_two_phase(&the_bts, ts_no, tlli, &fn, qta, ms_class); + ul_tbf = establish_ul_tbf_two_phase(&the_bts, ts_no, tlli, &fn, qta, + ms_class, 0); ms = ul_tbf->ms(); fprintf(stderr, "Got '%s', TA=%d\n", ul_tbf->name(), ul_tbf->ta()); @@ -806,7 +819,8 @@ static void test_tbf_ra_update_rach() setup_bts(&the_bts, ts_no, 4); - ul_tbf = establish_ul_tbf_two_phase(&the_bts, ts_no, tlli1, &fn, qta, ms_class); + ul_tbf = establish_ul_tbf_two_phase(&the_bts, ts_no, tlli1, &fn, qta, + ms_class, 0); ms1 = ul_tbf->ms(); fprintf(stderr, "Got '%s', TA=%d\n", ul_tbf->name(), ul_tbf->ta()); @@ -827,7 +841,8 @@ static void test_tbf_ra_update_rach() OSMO_ASSERT(ms1->llc_queue()->size() == 0); /* Now establish a new TBF for the RA UPDATE COMPLETE (new TLLI) */ - ul_tbf = establish_ul_tbf_two_phase(&the_bts, ts_no, tlli2, &fn, qta, ms_class); + ul_tbf = establish_ul_tbf_two_phase(&the_bts, ts_no, tlli2, &fn, qta, + ms_class, 0); ms2 = ul_tbf->ms(); @@ -872,7 +887,8 @@ static void test_tbf_dl_flow_and_rach_two_phase() setup_bts(&the_bts, ts_no, 1); - ul_tbf = establish_ul_tbf_two_phase(&the_bts, ts_no, tlli1, &fn, qta, ms_class); + ul_tbf = establish_ul_tbf_two_phase(&the_bts, ts_no, tlli1, &fn, qta, + ms_class, 0); ms1 = ul_tbf->ms(); fprintf(stderr, "Got '%s', TA=%d\n", ul_tbf->name(), ul_tbf->ta()); @@ -892,7 +908,8 @@ static void test_tbf_dl_flow_and_rach_two_phase() OSMO_ASSERT(ms1 == ms); /* Now establish a new UL TBF, this will consume one LLC packet */ - ul_tbf = establish_ul_tbf_two_phase(&the_bts, ts_no, tlli1, &fn, qta, ms_class); + ul_tbf = establish_ul_tbf_two_phase(&the_bts, ts_no, tlli1, &fn, qta, + ms_class, 0); ms2 = ul_tbf->ms(); fprintf(stderr, "New MS: TLLI = 0x%08x, TA = %d, IMSI = %s, LLC = %d\n", @@ -931,7 +948,8 @@ static void test_tbf_dl_flow_and_rach_single_phase() setup_bts(&the_bts, ts_no, 1); - ul_tbf = establish_ul_tbf_two_phase(&the_bts, ts_no, tlli1, &fn, qta, ms_class); + ul_tbf = establish_ul_tbf_two_phase(&the_bts, ts_no, tlli1, &fn, qta, + ms_class, 0); ms1 = ul_tbf->ms(); fprintf(stderr, "Got '%s', TA=%d\n", ul_tbf->name(), ul_tbf->ta()); @@ -992,7 +1010,8 @@ static void test_tbf_dl_reuse() setup_bts(&the_bts, ts_no, 1); - ul_tbf = establish_ul_tbf_two_phase(&the_bts, ts_no, tlli1, &fn, qta, ms_class); + ul_tbf = establish_ul_tbf_two_phase(&the_bts, ts_no, tlli1, &fn, qta, + ms_class, 0); ms1 = ul_tbf->ms(); fprintf(stderr, "Got '%s', TA=%d\n", ul_tbf->name(), ul_tbf->ta()); @@ -1160,6 +1179,122 @@ static void test_tbf_ws() gprs_bssgp_destroy(); } +static void test_tbf_egprs_two_phase() +{ + BTS the_bts; + int ts_no = 7; + uint32_t fn = 2654218; + uint16_t qta = 31; + uint32_t tlli = 0xf1223344; + const char *imsi = "0011223344"; + uint8_t ms_class = 1; + uint8_t egprs_ms_class = 1; + gprs_rlcmac_ul_tbf *ul_tbf; + GprsMs *ms; + uint8_t test_data[256]; + + printf("=== start %s ===\n", __func__); + + memset(test_data, 1, sizeof(test_data)); + + setup_bts(&the_bts, ts_no, 4); + the_bts.bts_data()->initial_mcs_dl = 9; + the_bts.bts_data()->egprs_enabled = 1; + + ul_tbf = establish_ul_tbf_two_phase(&the_bts, ts_no, tlli, &fn, qta, + ms_class, egprs_ms_class); + + ms = ul_tbf->ms(); + fprintf(stderr, "Got '%s', TA=%d\n", ul_tbf->name(), ul_tbf->ta()); + fprintf(stderr, "Got MS: TLLI = 0x%08x, TA = %d\n", ms->tlli(), ms->ta()); + + send_dl_data(&the_bts, tlli, imsi, test_data, sizeof(test_data)); + + printf("=== end %s ===\n", __func__); +} + +static void establish_and_use_egprs_dl_tbf(BTS *the_bts, int mcs) +{ + unsigned i; + uint8_t ms_class = 11; + uint8_t egprs_ms_class = 11; + uint32_t fn = 0; + uint8_t trx_no; + uint32_t tlli = 0xffeeddcc; + uint8_t test_data[512]; + + uint8_t rbb[64/8]; + + gprs_rlcmac_dl_tbf *dl_tbf; + + printf("Testing MCS-%d\n", mcs); + + memset(test_data, 1, sizeof(test_data)); + the_bts->bts_data()->initial_mcs_dl = mcs; + + dl_tbf = create_dl_tbf(the_bts, ms_class, egprs_ms_class, &trx_no); + dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF); + + for (i = 0; i < sizeof(llc_data); i++) + llc_data[i] = i%256; + + OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW)); + + /* Schedule a small LLC frame */ + dl_tbf->append_data(ms_class, 1000, test_data, 10); + + OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW)); + + /* Drain the queue */ + while (dl_tbf->have_data()) + /* Request to send one RLC/MAC block */ + request_dl_rlc_block(dl_tbf, &fn); + + /* Schedule a large LLC frame */ + dl_tbf->append_data(ms_class, 1000, test_data, sizeof(test_data)); + + OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW)); + + /* Drain the queue */ + while (dl_tbf->have_data()) + /* Request to send one RLC/MAC block */ + request_dl_rlc_block(dl_tbf, &fn); + + OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW)); + + /* Receive a final ACK */ + dl_tbf->rcvd_dl_ack(1, dl_tbf->m_window.v_s(), rbb); + + /* Clean up and ensure tbfs are in the correct state */ + OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_WAIT_RELEASE)); + dl_tbf->dl_ass_state = GPRS_RLCMAC_DL_ASS_NONE; + check_tbf(dl_tbf); + tbf_free(dl_tbf); +} + +static void test_tbf_egprs_dl() +{ + BTS the_bts; + gprs_rlcmac_bts *bts; + uint8_t ts_no = 4; + int i; + + printf("=== start %s ===\n", __func__); + + bts = the_bts.bts_data(); + + setup_bts(&the_bts, ts_no); + bts->dl_tbf_idle_msec = 200; + bts->egprs_enabled = 1; + + for (i = 1; i <= 9; i++) + establish_and_use_egprs_dl_tbf(&the_bts, i); + + printf("=== end %s ===\n", __func__); +} + + + static const struct log_info_cat default_categories[] = { {"DCSN1", "\033[1;31m", "Concrete Syntax Notation One (CSN1)", LOGL_INFO, 0}, {"DL1IF", "\033[1;32m", "GPRS PCU L1 interface (L1IF)", LOGL_DEBUG, 1}, @@ -1219,6 +1354,8 @@ int main(int argc, char **argv) test_tbf_dl_reuse(); test_tbf_gprs_egprs(); test_tbf_ws(); + test_tbf_egprs_two_phase(); + test_tbf_egprs_dl(); if (getenv("TALLOC_REPORT_FULL")) talloc_report_full(tall_pcu_ctx, stderr); diff --git a/tests/tbf/TbfTest.err b/tests/tbf/TbfTest.err index ed0ed987..724d9db7 100644 --- a/tests/tbf/TbfTest.err +++ b/tests/tbf/TbfTest.err @@ -3234,3 +3234,1734 @@ PDCH(TS 5, TRX 0): Detaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=RELEASING EG Detaching TBF from MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=RELEASING EGPRS) Destroying MS object, TLLI = 0x00000000 ********** TBF ends here ********** +Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654218 block=8 data=47 94 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +MS requests UL TBF on RACH, so we provide one: +MS requests single block allocation +RX: [PCU <- BTS] RACH qbit-ta=31 ra=0x73, Fn=2654167 (17,25,9), SBFn=2654270 +TX: Immediate Assignment Uplink (AGCH) + - TRX=0 (0) TS=7 TA=7 TSC=0 TFI=-1 USF=7 +Sending data request: trx=0 ts=0 sapi=2 arfcn=0 fn=0 block=0 data=2d 06 3f 10 0f 00 00 73 8b 29 07 00 c0 0c 5a 43 2b 2b 2b 2b 2b 2b 2b +Searching for first unallocated TFI: TRX=0 + Found TFI=0. +Got RLC block, coding scheme: CS-1, length: 23 (23)) ++++++++++++++++++++++++++ RX : Uplink Control Block +++++++++++++++++++++++++ +------------------------- RX : Uplink Control Block ------------------------- +MS requests UL TBF in packet resource request of single block, so we provide one: +MS supports EGPRS multislot class 1. +********** TBF starts here ********** +Allocating UL TBF: MS_CLASS=1/1 +Creating MS object, TLLI = 0x00000000 +Modifying MS object, TLLI = 0x00000000, MS class 0 -> 1 +Modifying MS object, TLLI = 0x00000000, EGPRS MS class 0 -> 1 +Enabled EGPRS for TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS), mode EGPRS +Slot Allocation (Algorithm A) for class 1 +- Skipping TS 0, because not enabled +- Skipping TS 1, because not enabled +- Skipping TS 2, because not enabled +- Skipping TS 3, because not enabled +- Skipping TS 4, because not enabled +- Skipping TS 5, because not enabled +- Skipping TS 6, because not enabled +- Assign uplink TS=7 TFI=0 USF=0 +PDCH(TS 7, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS), 1 TBFs, USFs = 01, TFIs = 00000001. +- Setting Control TS 7 +Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS) +Allocated TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS): trx = 0, ul_slots = 80, dl_slots = 00 +TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL EGPRS) changes state from NULL to ASSIGN +TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=ASSIGN EGPRS) starting timer 3169. +Modifying MS object, UL TLLI: 0x00000000 -> 0xf1223344, not yet confirmed +Modifying MS object, TLLI = 0xf1223344, TA 0 -> 7 +Change control TS to 7 until assinment is complete. +max_cs_ul cannot be derived (current UL CS: UNKNOWN) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS)s start Packet Uplink Assignment (PACCH) ++++++++++++++++++++++++++ TX : Packet Uplink Assignment +++++++++++++++++++++++++ +------------------------- TX : Packet Uplink Assignment ------------------------- +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS): Scheduling polling at FN 2654283 TS 7 +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=ASSIGN EGPRS) changes state from ASSIGN to WAIT ASSIGN +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) Scheduled UL Assignment polling on FN=2654283, TS=7 +Scheduling control message at RTS for TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) (TRX=0, TS=7) +Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654270 block=8 data=4f 28 5e 24 46 68 90 f0 0a 39 00 00 88 00 08 2b 2b 2b 2b 2b 2b 2b 2b +Got RLC block, coding scheme: CS-1, length: 23 (23)) ++++++++++++++++++++++++++ RX : Uplink Control Block +++++++++++++++++++++++++ +------------------------- RX : Uplink Control Block ------------------------- +RX: [PCU <- BTS] TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) Packet Control Ack +TBF: [DOWNLINK] UPLINK ASSIGNED TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=WAIT ASSIGN EGPRS) changes state from WAIT ASSIGN to FLOW +Got RLC block, coding scheme: CS-1, length: 23 (23)) + UL data: 3c 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Got CS-1 RLC block: R=0, SI=0, TFI=0, CPS=0, RSB=0, rc=184 +UL DATA TFI=0 received (V(Q)=0 .. V(R)=0) +max_cs_ul cannot be derived (current UL CS: UNKNOWN) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS) restarting timer 3169 while old timer 3169 pending +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): Got CS-1 RLC data block: CV=15, BSN=0, SPB=0, PI=0, E=1, TI=0, bitoffs=24 +- BSN 0 storing in window (0..63) +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS): data_length=20, data=00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +- Raising V(R) to 1 +- Taking block 0 out, raising V(Q) to 1 +- Assembling frames: (len=20) +-- Frame 1 starts at offset 0, length=20, is_complete=0 +- No gaps in received block, last block: BSN=0 CV=15 +Got 'TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS)', TA=7 +Got MS: TLLI = 0xf1223344, TA = 7 +********** TBF starts here ********** +Allocating DL TBF: MS_CLASS=1/1 +Enabled EGPRS for TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), mode EGPRS +Slot Allocation (Algorithm A) for class 0 +- Skipping TS 0, because not enabled +- Skipping TS 1, because not enabled +- Skipping TS 2, because not enabled +- Skipping TS 3, because not enabled +- Skipping TS 4, because not enabled +- Skipping TS 5, because not enabled +- Skipping TS 6, because not enabled +- Assign downlink TS=7 TFI=0 +PDCH(TS 7, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), 1 TBFs, USFs = 01, TFIs = 00000001. +- Setting Control TS 7 +Attaching TBF to MS object, TLLI = 0xf1223344, TBF = TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS) +Allocated TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 80, dl_slots = 80 +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 64 +Modifying MS object, TLLI: 0xf1223344 confirmed +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS) [DOWNLINK] START +Modifying MS object, TLLI = 0xf1223344, IMSI '' -> '0011223344' +Send dowlink assignment on PACCH, because TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS) exists +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=NULL EGPRS) changes state from NULL to ASSIGN +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=ASSIGN EGPRS) starting timer 0. +TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=ASSIGN EGPRS) append +Searching for first unallocated TFI: TRX=0 + Found TFI=0. +********** TBF starts here ********** +Allocating DL TBF: MS_CLASS=11/11 +Creating MS object, TLLI = 0x00000000 +Modifying MS object, TLLI = 0x00000000, MS class 0 -> 11 +Modifying MS object, TLLI = 0x00000000, EGPRS MS class 0 -> 11 +Enabled EGPRS for TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), mode EGPRS +Slot Allocation (Algorithm A) for class 0 +- Skipping TS 0, because not enabled +- Skipping TS 1, because not enabled +- Skipping TS 2, because not enabled +- Skipping TS 3, because not enabled +- Skipping TS 5, because not enabled +- Skipping TS 6, because not enabled +- Skipping TS 7, because not enabled +- Assign downlink TS=4 TFI=0 +PDCH(TS 4, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), 1 TBFs, USFs = 00, TFIs = 00000001. +- Setting Control TS 4 +Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) +Allocated TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 10, dl_slots = 10 +TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 64 +TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) changes state from NULL to FLOW +The MS object cannot fully confirm an unexpected TLLI: 0xffeeddcc, partly confirmed +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) append +New and old TBF are the same TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) start Packet Downlink Assignment (PACCH) ++++++++++++++++++++++++++ TX : Packet Downlink Assignment +++++++++++++++++++++++++ +------------------------- TX : Packet Downlink Assignment ------------------------- +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS): Scheduling polling at FN 13 TS 4 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) Scheduled DL Assignment polling on FN=13, TS=4 +Scheduling control message at RTS for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (TRX=0, TS=4) +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=0 block=0 data=4f 08 20 00 44 02 00 02 08 04 00 c0 0b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==0) +- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (len=10) +- Sending new block at BSN 0, CS=MCS-1 +-- Chunk with length 10 is less than remaining space (22): add length header to to delimit LLC frame +Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=10 +-- Empty chunk, added LLC dummy command of size 10, drained_since=0 +-- Chunk with length 10 is less than remaining space (11): add length header to to delimit LLC frame +-- No space left, so we are done. +Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=10 +data block (BSN 0, MCS-1): 14 15 01 01 01 01 01 01 01 01 01 01 43 c0 01 2b 2b 2b 2b 2b 2b 2b +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 0, MCS-1): 07 00 00 16 28 2a 02 02 02 02 02 02 02 02 02 02 86 80 03 56 56 56 56 56 56 56 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=4 block=1 data=07 00 00 16 28 2a 02 02 02 02 02 02 02 02 02 02 86 80 03 56 56 56 56 56 56 56 00 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) append +Received RTS for PDCH: TRX=0 TS=4 FN=8 block_nr=2 scheduling free USF for polling at FN=13 of TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==1) +- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (len=512) +- Sending new block at BSN 1, CS=MCS-1 +-- Chunk with length 512 larger than space (22) left in block: copy only remaining space, and we are done +data block (BSN 1, MCS-1): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 1, MCS-1): 07 40 00 96 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=8 block=2 data=07 40 00 96 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==2) +- Sending new block at BSN 2, CS=MCS-1 +-- Chunk with length 490 larger than space (22) left in block: copy only remaining space, and we are done +data block (BSN 2, MCS-1): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 2, MCS-1): 07 80 00 96 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=13 block=3 data=07 80 00 96 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==3) +- Sending new block at BSN 3, CS=MCS-1 +-- Chunk with length 468 larger than space (22) left in block: copy only remaining space, and we are done +data block (BSN 3, MCS-1): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 3, MCS-1): 07 c0 00 96 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=17 block=4 data=07 c0 00 96 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==4) +- Sending new block at BSN 4, CS=MCS-1 +-- Chunk with length 446 larger than space (22) left in block: copy only remaining space, and we are done +data block (BSN 4, MCS-1): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 4, MCS-1): 07 00 01 96 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=21 block=5 data=07 00 01 96 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==5) +- Sending new block at BSN 5, CS=MCS-1 +-- Chunk with length 424 larger than space (22) left in block: copy only remaining space, and we are done +data block (BSN 5, MCS-1): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 5, MCS-1): 07 40 01 96 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=26 block=6 data=07 40 01 96 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==6) +- Sending new block at BSN 6, CS=MCS-1 +-- Chunk with length 402 larger than space (22) left in block: copy only remaining space, and we are done +data block (BSN 6, MCS-1): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 6, MCS-1): 07 80 01 96 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=30 block=7 data=07 80 01 96 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==7) +- Sending new block at BSN 7, CS=MCS-1 +-- Chunk with length 380 larger than space (22) left in block: copy only remaining space, and we are done +data block (BSN 7, MCS-1): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 7, MCS-1): 07 c0 01 96 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=34 block=8 data=07 c0 01 96 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==8) +- Sending new block at BSN 8, CS=MCS-1 +-- Chunk with length 358 larger than space (22) left in block: copy only remaining space, and we are done +data block (BSN 8, MCS-1): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 8, MCS-1): 07 00 02 96 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=39 block=9 data=07 00 02 96 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==9) +- Sending new block at BSN 9, CS=MCS-1 +-- Chunk with length 336 larger than space (22) left in block: copy only remaining space, and we are done +data block (BSN 9, MCS-1): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 9, MCS-1): 07 40 02 96 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=43 block=10 data=07 40 02 96 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==10) +- Sending new block at BSN 10, CS=MCS-1 +-- Chunk with length 314 larger than space (22) left in block: copy only remaining space, and we are done +data block (BSN 10, MCS-1): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 10, MCS-1): 07 80 02 96 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=47 block=11 data=07 80 02 96 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=4 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==11) +- Sending new block at BSN 11, CS=MCS-1 +-- Chunk with length 292 larger than space (22) left in block: copy only remaining space, and we are done +data block (BSN 11, MCS-1): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 11, MCS-1): 07 c0 02 96 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=52 block=0 data=07 c0 02 96 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=4 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==12) +- Sending new block at BSN 12, CS=MCS-1 +-- Chunk with length 270 larger than space (22) left in block: copy only remaining space, and we are done +data block (BSN 12, MCS-1): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 12, MCS-1): 07 00 03 96 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=56 block=1 data=07 00 03 96 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=4 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==13) +- Sending new block at BSN 13, CS=MCS-1 +-- Chunk with length 248 larger than space (22) left in block: copy only remaining space, and we are done +data block (BSN 13, MCS-1): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 13, MCS-1): 07 40 03 96 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=60 block=2 data=07 40 03 96 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=4 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==14) +- Sending new block at BSN 14, CS=MCS-1 +-- Chunk with length 226 larger than space (22) left in block: copy only remaining space, and we are done +data block (BSN 14, MCS-1): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 14, MCS-1): 07 80 03 96 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=65 block=3 data=07 80 03 96 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=4 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==15) +- Sending new block at BSN 15, CS=MCS-1 +-- Chunk with length 204 larger than space (22) left in block: copy only remaining space, and we are done +data block (BSN 15, MCS-1): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 15, MCS-1): 07 c0 03 96 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=69 block=4 data=07 c0 03 96 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=4 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==16) +- Sending new block at BSN 16, CS=MCS-1 +-- Chunk with length 182 larger than space (22) left in block: copy only remaining space, and we are done +data block (BSN 16, MCS-1): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 16, MCS-1): 07 00 04 96 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=73 block=5 data=07 00 04 96 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=4 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==17) +- Sending new block at BSN 17, CS=MCS-1 +-- Chunk with length 160 larger than space (22) left in block: copy only remaining space, and we are done +data block (BSN 17, MCS-1): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 17, MCS-1): 07 40 04 96 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=78 block=6 data=07 40 04 96 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=4 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==18) +- Sending new block at BSN 18, CS=MCS-1 +-- Chunk with length 138 larger than space (22) left in block: copy only remaining space, and we are done +data block (BSN 18, MCS-1): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 18, MCS-1): 07 80 04 96 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=82 block=7 data=07 80 04 96 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=4 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==19) +- Sending new block at BSN 19, CS=MCS-1 +-- Chunk with length 116 larger than space (22) left in block: copy only remaining space, and we are done +data block (BSN 19, MCS-1): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 19, MCS-1): 07 c0 04 96 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=86 block=8 data=07 c0 04 96 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=4 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==20) +- Sending new block at BSN 20, CS=MCS-1 +-- Chunk with length 94 larger than space (22) left in block: copy only remaining space, and we are done +data block (BSN 20, MCS-1): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 20, MCS-1): 07 00 05 96 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=91 block=9 data=07 00 05 96 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=4 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==21) +- Sending new block at BSN 21, CS=MCS-1 +-- Chunk with length 72 larger than space (22) left in block: copy only remaining space, and we are done +data block (BSN 21, MCS-1): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 21, MCS-1): 07 40 05 96 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=95 block=10 data=07 40 05 96 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=4 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==22) +- Sending new block at BSN 22, CS=MCS-1 +-- Chunk with length 50 larger than space (22) left in block: copy only remaining space, and we are done +data block (BSN 22, MCS-1): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 22, MCS-1): 07 80 05 96 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=99 block=11 data=07 80 05 96 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=4 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==23) +- Sending new block at BSN 23, CS=MCS-1 +-- Chunk with length 28 larger than space (22) left in block: copy only remaining space, and we are done +data block (BSN 23, MCS-1): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 23, MCS-1): 07 c0 05 96 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=104 block=0 data=07 c0 05 96 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=4 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==24) +- Sending new block at BSN 24, CS=MCS-1 +-- Chunk with length 6 is less than remaining space (22): add length header to to delimit LLC frame +Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=512 +-- Empty chunk, added LLC dummy command of size 14, drained_since=0 +-- Chunk with length 14 is less than remaining space (15): add length header to to delimit LLC frame +-- No space left, so we are done. +Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=14 +data block (BSN 24, MCS-1): 0c 1d 01 01 01 01 01 01 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 24, MCS-1): 07 00 06 16 18 3a 02 02 02 02 02 02 86 80 03 56 56 56 56 56 56 56 56 56 56 56 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=108 block=1 data=07 00 06 16 18 3a 02 02 02 02 02 02 86 80 03 56 56 56 56 56 56 56 56 56 56 56 00 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink acknowledge +- Final ACK received. +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) changes state from FLOW to WAIT RELEASE +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=WAIT RELEASE EGPRS) starting timer 3193. +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=WAIT RELEASE EGPRS) changes state from WAIT RELEASE to RELEASING +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=RELEASING EGPRS) free +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=RELEASING EGPRS) stopping timer 3193. +PDCH(TS 4, TRX 0): Detaching TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=RELEASING EGPRS), 0 TBFs, USFs = 00, TFIs = 00000000. +Detaching TBF from MS object, TLLI = 0xffeeddcc, TBF = TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=RELEASING EGPRS) +Destroying MS object, TLLI = 0xffeeddcc +********** TBF ends here ********** +Searching for first unallocated TFI: TRX=0 + Found TFI=0. +********** TBF starts here ********** +Allocating DL TBF: MS_CLASS=11/11 +Creating MS object, TLLI = 0x00000000 +Modifying MS object, TLLI = 0x00000000, MS class 0 -> 11 +Modifying MS object, TLLI = 0x00000000, EGPRS MS class 0 -> 11 +Enabled EGPRS for TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), mode EGPRS +Slot Allocation (Algorithm A) for class 0 +- Skipping TS 0, because not enabled +- Skipping TS 1, because not enabled +- Skipping TS 2, because not enabled +- Skipping TS 3, because not enabled +- Skipping TS 5, because not enabled +- Skipping TS 6, because not enabled +- Skipping TS 7, because not enabled +- Assign downlink TS=4 TFI=0 +PDCH(TS 4, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), 1 TBFs, USFs = 00, TFIs = 00000001. +- Setting Control TS 4 +Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) +Allocated TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 10, dl_slots = 10 +TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 64 +TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) changes state from NULL to FLOW +The MS object cannot fully confirm an unexpected TLLI: 0xffeeddcc, partly confirmed +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) append +New and old TBF are the same TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) start Packet Downlink Assignment (PACCH) ++++++++++++++++++++++++++ TX : Packet Downlink Assignment +++++++++++++++++++++++++ +------------------------- TX : Packet Downlink Assignment ------------------------- +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS): Scheduling polling at FN 13 TS 4 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) Scheduled DL Assignment polling on FN=13, TS=4 +Scheduling control message at RTS for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (TRX=0, TS=4) +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=0 block=0 data=4f 08 20 00 44 02 00 02 08 04 00 c0 0b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==0) +- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (len=10) +- Sending new block at BSN 0, CS=MCS-2 +-- Chunk with length 10 is less than remaining space (28): add length header to to delimit LLC frame +Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=10 +-- Empty chunk, added LLC dummy command of size 16, drained_since=0 +-- Chunk with length 16 is less than remaining space (17): add length header to to delimit LLC frame +-- No space left, so we are done. +Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=16 +data block (BSN 0, MCS-2): 14 21 01 01 01 01 01 01 01 01 01 01 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 0, MCS-2): 07 00 00 12 28 42 02 02 02 02 02 02 02 02 02 02 86 80 03 56 56 56 56 56 56 56 56 56 56 56 56 56 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=4 block=1 data=07 00 00 12 28 42 02 02 02 02 02 02 02 02 02 02 86 80 03 56 56 56 56 56 56 56 56 56 56 56 56 56 00 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) append +Received RTS for PDCH: TRX=0 TS=4 FN=8 block_nr=2 scheduling free USF for polling at FN=13 of TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==1) +- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (len=512) +- Sending new block at BSN 1, CS=MCS-2 +-- Chunk with length 512 larger than space (28) left in block: copy only remaining space, and we are done +data block (BSN 1, MCS-2): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 1, MCS-2): 07 40 00 92 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=8 block=2 data=07 40 00 92 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==2) +- Sending new block at BSN 2, CS=MCS-2 +-- Chunk with length 484 larger than space (28) left in block: copy only remaining space, and we are done +data block (BSN 2, MCS-2): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 2, MCS-2): 07 80 00 92 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=13 block=3 data=07 80 00 92 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==3) +- Sending new block at BSN 3, CS=MCS-2 +-- Chunk with length 456 larger than space (28) left in block: copy only remaining space, and we are done +data block (BSN 3, MCS-2): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 3, MCS-2): 07 c0 00 92 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=17 block=4 data=07 c0 00 92 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==4) +- Sending new block at BSN 4, CS=MCS-2 +-- Chunk with length 428 larger than space (28) left in block: copy only remaining space, and we are done +data block (BSN 4, MCS-2): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 4, MCS-2): 07 00 01 92 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=21 block=5 data=07 00 01 92 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==5) +- Sending new block at BSN 5, CS=MCS-2 +-- Chunk with length 400 larger than space (28) left in block: copy only remaining space, and we are done +data block (BSN 5, MCS-2): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 5, MCS-2): 07 40 01 92 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=26 block=6 data=07 40 01 92 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==6) +- Sending new block at BSN 6, CS=MCS-2 +-- Chunk with length 372 larger than space (28) left in block: copy only remaining space, and we are done +data block (BSN 6, MCS-2): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 6, MCS-2): 07 80 01 92 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=30 block=7 data=07 80 01 92 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==7) +- Sending new block at BSN 7, CS=MCS-2 +-- Chunk with length 344 larger than space (28) left in block: copy only remaining space, and we are done +data block (BSN 7, MCS-2): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 7, MCS-2): 07 c0 01 92 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=34 block=8 data=07 c0 01 92 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==8) +- Sending new block at BSN 8, CS=MCS-2 +-- Chunk with length 316 larger than space (28) left in block: copy only remaining space, and we are done +data block (BSN 8, MCS-2): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 8, MCS-2): 07 00 02 92 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=39 block=9 data=07 00 02 92 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==9) +- Sending new block at BSN 9, CS=MCS-2 +-- Chunk with length 288 larger than space (28) left in block: copy only remaining space, and we are done +data block (BSN 9, MCS-2): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 9, MCS-2): 07 40 02 92 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=43 block=10 data=07 40 02 92 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==10) +- Sending new block at BSN 10, CS=MCS-2 +-- Chunk with length 260 larger than space (28) left in block: copy only remaining space, and we are done +data block (BSN 10, MCS-2): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 10, MCS-2): 07 80 02 92 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=47 block=11 data=07 80 02 92 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=4 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==11) +- Sending new block at BSN 11, CS=MCS-2 +-- Chunk with length 232 larger than space (28) left in block: copy only remaining space, and we are done +data block (BSN 11, MCS-2): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 11, MCS-2): 07 c0 02 92 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=52 block=0 data=07 c0 02 92 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=4 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==12) +- Sending new block at BSN 12, CS=MCS-2 +-- Chunk with length 204 larger than space (28) left in block: copy only remaining space, and we are done +data block (BSN 12, MCS-2): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 12, MCS-2): 07 00 03 92 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=56 block=1 data=07 00 03 92 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=4 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==13) +- Sending new block at BSN 13, CS=MCS-2 +-- Chunk with length 176 larger than space (28) left in block: copy only remaining space, and we are done +data block (BSN 13, MCS-2): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 13, MCS-2): 07 40 03 92 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=60 block=2 data=07 40 03 92 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=4 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==14) +- Sending new block at BSN 14, CS=MCS-2 +-- Chunk with length 148 larger than space (28) left in block: copy only remaining space, and we are done +data block (BSN 14, MCS-2): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 14, MCS-2): 07 80 03 92 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=65 block=3 data=07 80 03 92 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=4 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==15) +- Sending new block at BSN 15, CS=MCS-2 +-- Chunk with length 120 larger than space (28) left in block: copy only remaining space, and we are done +data block (BSN 15, MCS-2): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 15, MCS-2): 07 c0 03 92 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=69 block=4 data=07 c0 03 92 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=4 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==16) +- Sending new block at BSN 16, CS=MCS-2 +-- Chunk with length 92 larger than space (28) left in block: copy only remaining space, and we are done +data block (BSN 16, MCS-2): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 16, MCS-2): 07 00 04 92 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=73 block=5 data=07 00 04 92 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=4 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==17) +- Sending new block at BSN 17, CS=MCS-2 +-- Chunk with length 64 larger than space (28) left in block: copy only remaining space, and we are done +data block (BSN 17, MCS-2): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 17, MCS-2): 07 40 04 92 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=78 block=6 data=07 40 04 92 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=4 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==18) +- Sending new block at BSN 18, CS=MCS-2 +-- Chunk with length 36 larger than space (28) left in block: copy only remaining space, and we are done +data block (BSN 18, MCS-2): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 18, MCS-2): 07 80 04 92 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=82 block=7 data=07 80 04 92 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=4 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==19) +- Sending new block at BSN 19, CS=MCS-2 +-- Chunk with length 8 is less than remaining space (28): add length header to to delimit LLC frame +Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=512 +-- Empty chunk, added LLC dummy command of size 18, drained_since=0 +-- Chunk with length 18 is less than remaining space (19): add length header to to delimit LLC frame +-- No space left, so we are done. +Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=18 +data block (BSN 19, MCS-2): 10 25 01 01 01 01 01 01 01 01 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 19, MCS-2): 07 c0 04 12 20 4a 02 02 02 02 02 02 02 02 86 80 03 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=86 block=8 data=07 c0 04 12 20 4a 02 02 02 02 02 02 02 02 86 80 03 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 00 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink acknowledge +- Final ACK received. +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) changes state from FLOW to WAIT RELEASE +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=WAIT RELEASE EGPRS) starting timer 3193. +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=WAIT RELEASE EGPRS) changes state from WAIT RELEASE to RELEASING +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=RELEASING EGPRS) free +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=RELEASING EGPRS) stopping timer 3193. +PDCH(TS 4, TRX 0): Detaching TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=RELEASING EGPRS), 0 TBFs, USFs = 00, TFIs = 00000000. +Detaching TBF from MS object, TLLI = 0xffeeddcc, TBF = TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=RELEASING EGPRS) +Destroying MS object, TLLI = 0xffeeddcc +********** TBF ends here ********** +Searching for first unallocated TFI: TRX=0 + Found TFI=0. +********** TBF starts here ********** +Allocating DL TBF: MS_CLASS=11/11 +Creating MS object, TLLI = 0x00000000 +Modifying MS object, TLLI = 0x00000000, MS class 0 -> 11 +Modifying MS object, TLLI = 0x00000000, EGPRS MS class 0 -> 11 +Enabled EGPRS for TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), mode EGPRS +Slot Allocation (Algorithm A) for class 0 +- Skipping TS 0, because not enabled +- Skipping TS 1, because not enabled +- Skipping TS 2, because not enabled +- Skipping TS 3, because not enabled +- Skipping TS 5, because not enabled +- Skipping TS 6, because not enabled +- Skipping TS 7, because not enabled +- Assign downlink TS=4 TFI=0 +PDCH(TS 4, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), 1 TBFs, USFs = 00, TFIs = 00000001. +- Setting Control TS 4 +Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) +Allocated TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 10, dl_slots = 10 +TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 64 +TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) changes state from NULL to FLOW +The MS object cannot fully confirm an unexpected TLLI: 0xffeeddcc, partly confirmed +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) append +New and old TBF are the same TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) start Packet Downlink Assignment (PACCH) ++++++++++++++++++++++++++ TX : Packet Downlink Assignment +++++++++++++++++++++++++ +------------------------- TX : Packet Downlink Assignment ------------------------- +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS): Scheduling polling at FN 13 TS 4 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) Scheduled DL Assignment polling on FN=13, TS=4 +Scheduling control message at RTS for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (TRX=0, TS=4) +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=0 block=0 data=4f 08 20 00 44 02 00 02 08 04 00 c0 0b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==0) +- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (len=10) +- Sending new block at BSN 0, CS=MCS-3 +-- Chunk with length 10 is less than remaining space (37): add length header to to delimit LLC frame +Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=10 +-- Empty chunk, added LLC dummy command of size 25, drained_since=0 +-- Chunk with length 25 is less than remaining space (26): add length header to to delimit LLC frame +-- No space left, so we are done. +Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=25 +data block (BSN 0, MCS-3): 14 33 01 01 01 01 01 01 01 01 01 01 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 0, MCS-3): 07 00 00 06 28 66 02 02 02 02 02 02 02 02 02 02 86 80 03 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=4 block=1 data=07 00 00 06 28 66 02 02 02 02 02 02 02 02 02 02 86 80 03 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 00 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) append +Received RTS for PDCH: TRX=0 TS=4 FN=8 block_nr=2 scheduling free USF for polling at FN=13 of TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==1) +- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (len=512) +- Sending new block at BSN 1, CS=MCS-3 +-- Chunk with length 512 larger than space (37) left in block: copy only remaining space, and we are done +data block (BSN 1, MCS-3): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 1, MCS-3): 07 40 00 86 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=8 block=2 data=07 40 00 86 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==2) +- Sending new block at BSN 2, CS=MCS-3 +-- Chunk with length 475 larger than space (37) left in block: copy only remaining space, and we are done +data block (BSN 2, MCS-3): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 2, MCS-3): 07 80 00 86 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=13 block=3 data=07 80 00 86 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==3) +- Sending new block at BSN 3, CS=MCS-3 +-- Chunk with length 438 larger than space (37) left in block: copy only remaining space, and we are done +data block (BSN 3, MCS-3): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 3, MCS-3): 07 c0 00 86 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=17 block=4 data=07 c0 00 86 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==4) +- Sending new block at BSN 4, CS=MCS-3 +-- Chunk with length 401 larger than space (37) left in block: copy only remaining space, and we are done +data block (BSN 4, MCS-3): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 4, MCS-3): 07 00 01 86 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=21 block=5 data=07 00 01 86 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==5) +- Sending new block at BSN 5, CS=MCS-3 +-- Chunk with length 364 larger than space (37) left in block: copy only remaining space, and we are done +data block (BSN 5, MCS-3): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 5, MCS-3): 07 40 01 86 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=26 block=6 data=07 40 01 86 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==6) +- Sending new block at BSN 6, CS=MCS-3 +-- Chunk with length 327 larger than space (37) left in block: copy only remaining space, and we are done +data block (BSN 6, MCS-3): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 6, MCS-3): 07 80 01 86 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=30 block=7 data=07 80 01 86 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==7) +- Sending new block at BSN 7, CS=MCS-3 +-- Chunk with length 290 larger than space (37) left in block: copy only remaining space, and we are done +data block (BSN 7, MCS-3): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 7, MCS-3): 07 c0 01 86 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=34 block=8 data=07 c0 01 86 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==8) +- Sending new block at BSN 8, CS=MCS-3 +-- Chunk with length 253 larger than space (37) left in block: copy only remaining space, and we are done +data block (BSN 8, MCS-3): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 8, MCS-3): 07 00 02 86 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=39 block=9 data=07 00 02 86 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==9) +- Sending new block at BSN 9, CS=MCS-3 +-- Chunk with length 216 larger than space (37) left in block: copy only remaining space, and we are done +data block (BSN 9, MCS-3): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 9, MCS-3): 07 40 02 86 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=43 block=10 data=07 40 02 86 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==10) +- Sending new block at BSN 10, CS=MCS-3 +-- Chunk with length 179 larger than space (37) left in block: copy only remaining space, and we are done +data block (BSN 10, MCS-3): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 10, MCS-3): 07 80 02 86 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=47 block=11 data=07 80 02 86 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=4 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==11) +- Sending new block at BSN 11, CS=MCS-3 +-- Chunk with length 142 larger than space (37) left in block: copy only remaining space, and we are done +data block (BSN 11, MCS-3): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 11, MCS-3): 07 c0 02 86 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=52 block=0 data=07 c0 02 86 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=4 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==12) +- Sending new block at BSN 12, CS=MCS-3 +-- Chunk with length 105 larger than space (37) left in block: copy only remaining space, and we are done +data block (BSN 12, MCS-3): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 12, MCS-3): 07 00 03 86 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=56 block=1 data=07 00 03 86 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=4 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==13) +- Sending new block at BSN 13, CS=MCS-3 +-- Chunk with length 68 larger than space (37) left in block: copy only remaining space, and we are done +data block (BSN 13, MCS-3): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 13, MCS-3): 07 40 03 86 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=60 block=2 data=07 40 03 86 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=4 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==14) +- Sending new block at BSN 14, CS=MCS-3 +-- Chunk with length 31 is less than remaining space (37): add length header to to delimit LLC frame +Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=512 +-- Empty chunk, added LLC dummy command of size 6, drained_since=0 +-- Chunk with length 6 larger than space (5) left in block: copy only remaining space, and we are done +data block (BSN 14, MCS-3): 3f 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 43 c0 01 2b 2b +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 14, MCS-3): 07 80 03 06 7e 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 86 80 03 56 56 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=65 block=3 data=07 80 03 06 7e 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 86 80 03 56 56 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=4 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==15) +- Sending new block at BSN 15, CS=MCS-3 +-- Chunk with length 1 is less than remaining space (37): add length header to to delimit LLC frame +Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=6 +-- Empty chunk, added LLC dummy command of size 34, drained_since=4 +-- Chunk with length 34 is less than remaining space (35): add length header to to delimit LLC frame +-- No space left, so we are done. +Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=34 +data block (BSN 15, MCS-3): 02 45 2b 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 15, MCS-3): 07 c0 03 06 04 8a 56 86 80 03 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=69 block=4 data=07 c0 03 06 04 8a 56 86 80 03 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 00 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink acknowledge +- Final ACK received. +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) changes state from FLOW to WAIT RELEASE +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=WAIT RELEASE EGPRS) starting timer 3193. +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=WAIT RELEASE EGPRS) changes state from WAIT RELEASE to RELEASING +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=RELEASING EGPRS) free +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=RELEASING EGPRS) stopping timer 3193. +PDCH(TS 4, TRX 0): Detaching TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=RELEASING EGPRS), 0 TBFs, USFs = 00, TFIs = 00000000. +Detaching TBF from MS object, TLLI = 0xffeeddcc, TBF = TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=RELEASING EGPRS) +Destroying MS object, TLLI = 0xffeeddcc +********** TBF ends here ********** +Searching for first unallocated TFI: TRX=0 + Found TFI=0. +********** TBF starts here ********** +Allocating DL TBF: MS_CLASS=11/11 +Creating MS object, TLLI = 0x00000000 +Modifying MS object, TLLI = 0x00000000, MS class 0 -> 11 +Modifying MS object, TLLI = 0x00000000, EGPRS MS class 0 -> 11 +Enabled EGPRS for TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), mode EGPRS +Slot Allocation (Algorithm A) for class 0 +- Skipping TS 0, because not enabled +- Skipping TS 1, because not enabled +- Skipping TS 2, because not enabled +- Skipping TS 3, because not enabled +- Skipping TS 5, because not enabled +- Skipping TS 6, because not enabled +- Skipping TS 7, because not enabled +- Assign downlink TS=4 TFI=0 +PDCH(TS 4, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), 1 TBFs, USFs = 00, TFIs = 00000001. +- Setting Control TS 4 +Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) +Allocated TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 10, dl_slots = 10 +TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 64 +TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) changes state from NULL to FLOW +The MS object cannot fully confirm an unexpected TLLI: 0xffeeddcc, partly confirmed +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) append +New and old TBF are the same TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) start Packet Downlink Assignment (PACCH) ++++++++++++++++++++++++++ TX : Packet Downlink Assignment +++++++++++++++++++++++++ +------------------------- TX : Packet Downlink Assignment ------------------------- +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS): Scheduling polling at FN 13 TS 4 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) Scheduled DL Assignment polling on FN=13, TS=4 +Scheduling control message at RTS for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (TRX=0, TS=4) +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=0 block=0 data=4f 08 20 00 44 02 00 02 08 04 00 c0 0b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==0) +- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (len=10) +- Sending new block at BSN 0, CS=MCS-4 +-- Chunk with length 10 is less than remaining space (44): add length header to to delimit LLC frame +Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=10 +-- Empty chunk, added LLC dummy command of size 32, drained_since=0 +-- Chunk with length 32 is less than remaining space (33): add length header to to delimit LLC frame +-- No space left, so we are done. +Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=32 +data block (BSN 0, MCS-4): 14 41 01 01 01 01 01 01 01 01 01 01 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 0, MCS-4): 07 00 00 00 28 82 02 02 02 02 02 02 02 02 02 02 86 80 03 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=4 block=1 data=07 00 00 00 28 82 02 02 02 02 02 02 02 02 02 02 86 80 03 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 00 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) append +Received RTS for PDCH: TRX=0 TS=4 FN=8 block_nr=2 scheduling free USF for polling at FN=13 of TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==1) +- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (len=512) +- Sending new block at BSN 1, CS=MCS-4 +-- Chunk with length 512 larger than space (44) left in block: copy only remaining space, and we are done +data block (BSN 1, MCS-4): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 1, MCS-4): 07 40 00 80 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=8 block=2 data=07 40 00 80 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==2) +- Sending new block at BSN 2, CS=MCS-4 +-- Chunk with length 468 larger than space (44) left in block: copy only remaining space, and we are done +data block (BSN 2, MCS-4): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 2, MCS-4): 07 80 00 80 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=13 block=3 data=07 80 00 80 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==3) +- Sending new block at BSN 3, CS=MCS-4 +-- Chunk with length 424 larger than space (44) left in block: copy only remaining space, and we are done +data block (BSN 3, MCS-4): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 3, MCS-4): 07 c0 00 80 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=17 block=4 data=07 c0 00 80 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==4) +- Sending new block at BSN 4, CS=MCS-4 +-- Chunk with length 380 larger than space (44) left in block: copy only remaining space, and we are done +data block (BSN 4, MCS-4): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 4, MCS-4): 07 00 01 80 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=21 block=5 data=07 00 01 80 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==5) +- Sending new block at BSN 5, CS=MCS-4 +-- Chunk with length 336 larger than space (44) left in block: copy only remaining space, and we are done +data block (BSN 5, MCS-4): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 5, MCS-4): 07 40 01 80 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=26 block=6 data=07 40 01 80 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==6) +- Sending new block at BSN 6, CS=MCS-4 +-- Chunk with length 292 larger than space (44) left in block: copy only remaining space, and we are done +data block (BSN 6, MCS-4): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 6, MCS-4): 07 80 01 80 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=30 block=7 data=07 80 01 80 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==7) +- Sending new block at BSN 7, CS=MCS-4 +-- Chunk with length 248 larger than space (44) left in block: copy only remaining space, and we are done +data block (BSN 7, MCS-4): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 7, MCS-4): 07 c0 01 80 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=34 block=8 data=07 c0 01 80 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==8) +- Sending new block at BSN 8, CS=MCS-4 +-- Chunk with length 204 larger than space (44) left in block: copy only remaining space, and we are done +data block (BSN 8, MCS-4): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 8, MCS-4): 07 00 02 80 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=39 block=9 data=07 00 02 80 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==9) +- Sending new block at BSN 9, CS=MCS-4 +-- Chunk with length 160 larger than space (44) left in block: copy only remaining space, and we are done +data block (BSN 9, MCS-4): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 9, MCS-4): 07 40 02 80 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=43 block=10 data=07 40 02 80 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==10) +- Sending new block at BSN 10, CS=MCS-4 +-- Chunk with length 116 larger than space (44) left in block: copy only remaining space, and we are done +data block (BSN 10, MCS-4): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 10, MCS-4): 07 80 02 80 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=47 block=11 data=07 80 02 80 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=4 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==11) +- Sending new block at BSN 11, CS=MCS-4 +-- Chunk with length 72 larger than space (44) left in block: copy only remaining space, and we are done +data block (BSN 11, MCS-4): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 11, MCS-4): 07 c0 02 80 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=52 block=0 data=07 c0 02 80 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=4 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==12) +- Sending new block at BSN 12, CS=MCS-4 +-- Chunk with length 28 is less than remaining space (44): add length header to to delimit LLC frame +Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=512 +-- Empty chunk, added LLC dummy command of size 14, drained_since=0 +-- Chunk with length 14 is less than remaining space (15): add length header to to delimit LLC frame +-- No space left, so we are done. +Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=14 +data block (BSN 12, MCS-4): 38 1d 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 12, MCS-4): 07 00 03 00 70 3a 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 86 80 03 56 56 56 56 56 56 56 56 56 56 56 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=56 block=1 data=07 00 03 00 70 3a 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 86 80 03 56 56 56 56 56 56 56 56 56 56 56 00 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink acknowledge +- Final ACK received. +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) changes state from FLOW to WAIT RELEASE +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=WAIT RELEASE EGPRS) starting timer 3193. +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=WAIT RELEASE EGPRS) changes state from WAIT RELEASE to RELEASING +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=RELEASING EGPRS) free +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=RELEASING EGPRS) stopping timer 3193. +PDCH(TS 4, TRX 0): Detaching TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=RELEASING EGPRS), 0 TBFs, USFs = 00, TFIs = 00000000. +Detaching TBF from MS object, TLLI = 0xffeeddcc, TBF = TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=RELEASING EGPRS) +Destroying MS object, TLLI = 0xffeeddcc +********** TBF ends here ********** +Searching for first unallocated TFI: TRX=0 + Found TFI=0. +********** TBF starts here ********** +Allocating DL TBF: MS_CLASS=11/11 +Creating MS object, TLLI = 0x00000000 +Modifying MS object, TLLI = 0x00000000, MS class 0 -> 11 +Modifying MS object, TLLI = 0x00000000, EGPRS MS class 0 -> 11 +Enabled EGPRS for TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), mode EGPRS +Slot Allocation (Algorithm A) for class 0 +- Skipping TS 0, because not enabled +- Skipping TS 1, because not enabled +- Skipping TS 2, because not enabled +- Skipping TS 3, because not enabled +- Skipping TS 5, because not enabled +- Skipping TS 6, because not enabled +- Skipping TS 7, because not enabled +- Assign downlink TS=4 TFI=0 +PDCH(TS 4, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), 1 TBFs, USFs = 00, TFIs = 00000001. +- Setting Control TS 4 +Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) +Allocated TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 10, dl_slots = 10 +TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 64 +TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) changes state from NULL to FLOW +The MS object cannot fully confirm an unexpected TLLI: 0xffeeddcc, partly confirmed +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) append +New and old TBF are the same TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) start Packet Downlink Assignment (PACCH) ++++++++++++++++++++++++++ TX : Packet Downlink Assignment +++++++++++++++++++++++++ +------------------------- TX : Packet Downlink Assignment ------------------------- +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS): Scheduling polling at FN 13 TS 4 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) Scheduled DL Assignment polling on FN=13, TS=4 +Scheduling control message at RTS for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (TRX=0, TS=4) +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=0 block=0 data=4f 08 20 00 44 02 00 02 08 04 00 c0 0b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==0) +- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (len=10) +- Sending new block at BSN 0, CS=MCS-5 +-- Chunk with length 10 is less than remaining space (56): add length header to to delimit LLC frame +Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=10 +-- Empty chunk, added LLC dummy command of size 44, drained_since=0 +-- Chunk with length 44 is less than remaining space (45): add length header to to delimit LLC frame +-- No space left, so we are done. +Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=44 +data block (BSN 0, MCS-5): 14 59 01 01 01 01 01 01 01 01 01 01 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 0, MCS-5): 07 00 00 08 45 56 40 40 40 40 40 40 40 40 40 c0 10 70 c0 ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca 0a +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=4 block=1 data=07 00 00 08 45 56 40 40 40 40 40 40 40 40 40 c0 10 70 c0 ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca 0a +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) append +Received RTS for PDCH: TRX=0 TS=4 FN=8 block_nr=2 scheduling free USF for polling at FN=13 of TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==1) +- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (len=512) +- Sending new block at BSN 1, CS=MCS-5 +-- Chunk with length 512 larger than space (56) left in block: copy only remaining space, and we are done +data block (BSN 1, MCS-5): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 1, MCS-5): 07 40 00 58 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=8 block=2 data=07 40 00 58 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==2) +- Sending new block at BSN 2, CS=MCS-5 +-- Chunk with length 456 larger than space (56) left in block: copy only remaining space, and we are done +data block (BSN 2, MCS-5): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 2, MCS-5): 07 80 00 58 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=13 block=3 data=07 80 00 58 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==3) +- Sending new block at BSN 3, CS=MCS-5 +-- Chunk with length 400 larger than space (56) left in block: copy only remaining space, and we are done +data block (BSN 3, MCS-5): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 3, MCS-5): 07 c0 00 58 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=17 block=4 data=07 c0 00 58 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==4) +- Sending new block at BSN 4, CS=MCS-5 +-- Chunk with length 344 larger than space (56) left in block: copy only remaining space, and we are done +data block (BSN 4, MCS-5): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 4, MCS-5): 07 00 01 58 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=21 block=5 data=07 00 01 58 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==5) +- Sending new block at BSN 5, CS=MCS-5 +-- Chunk with length 288 larger than space (56) left in block: copy only remaining space, and we are done +data block (BSN 5, MCS-5): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 5, MCS-5): 07 40 01 58 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=26 block=6 data=07 40 01 58 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==6) +- Sending new block at BSN 6, CS=MCS-5 +-- Chunk with length 232 larger than space (56) left in block: copy only remaining space, and we are done +data block (BSN 6, MCS-5): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 6, MCS-5): 07 80 01 58 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=30 block=7 data=07 80 01 58 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==7) +- Sending new block at BSN 7, CS=MCS-5 +-- Chunk with length 176 larger than space (56) left in block: copy only remaining space, and we are done +data block (BSN 7, MCS-5): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 7, MCS-5): 07 c0 01 58 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=34 block=8 data=07 c0 01 58 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==8) +- Sending new block at BSN 8, CS=MCS-5 +-- Chunk with length 120 larger than space (56) left in block: copy only remaining space, and we are done +data block (BSN 8, MCS-5): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 8, MCS-5): 07 00 02 58 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=39 block=9 data=07 00 02 58 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==9) +- Sending new block at BSN 9, CS=MCS-5 +-- Chunk with length 64 larger than space (56) left in block: copy only remaining space, and we are done +data block (BSN 9, MCS-5): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 9, MCS-5): 07 40 02 58 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=43 block=10 data=07 40 02 58 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==10) +- Sending new block at BSN 10, CS=MCS-5 +-- Chunk with length 8 is less than remaining space (56): add length header to to delimit LLC frame +Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=512 +-- Empty chunk, added LLC dummy command of size 46, drained_since=0 +-- Chunk with length 46 is less than remaining space (47): add length header to to delimit LLC frame +-- No space left, so we are done. +Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=46 +data block (BSN 10, MCS-5): 10 5d 01 01 01 01 01 01 01 01 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 10, MCS-5): 07 80 02 08 44 57 40 40 40 40 40 40 40 c0 10 70 c0 ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca 0a +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=47 block=11 data=07 80 02 08 44 57 40 40 40 40 40 40 40 c0 10 70 c0 ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca 0a +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink acknowledge +- Final ACK received. +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) changes state from FLOW to WAIT RELEASE +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=WAIT RELEASE EGPRS) starting timer 3193. +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=WAIT RELEASE EGPRS) changes state from WAIT RELEASE to RELEASING +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=RELEASING EGPRS) free +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=RELEASING EGPRS) stopping timer 3193. +PDCH(TS 4, TRX 0): Detaching TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=RELEASING EGPRS), 0 TBFs, USFs = 00, TFIs = 00000000. +Detaching TBF from MS object, TLLI = 0xffeeddcc, TBF = TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=RELEASING EGPRS) +Destroying MS object, TLLI = 0xffeeddcc +********** TBF ends here ********** +Searching for first unallocated TFI: TRX=0 + Found TFI=0. +********** TBF starts here ********** +Allocating DL TBF: MS_CLASS=11/11 +Creating MS object, TLLI = 0x00000000 +Modifying MS object, TLLI = 0x00000000, MS class 0 -> 11 +Modifying MS object, TLLI = 0x00000000, EGPRS MS class 0 -> 11 +Enabled EGPRS for TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), mode EGPRS +Slot Allocation (Algorithm A) for class 0 +- Skipping TS 0, because not enabled +- Skipping TS 1, because not enabled +- Skipping TS 2, because not enabled +- Skipping TS 3, because not enabled +- Skipping TS 5, because not enabled +- Skipping TS 6, because not enabled +- Skipping TS 7, because not enabled +- Assign downlink TS=4 TFI=0 +PDCH(TS 4, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), 1 TBFs, USFs = 00, TFIs = 00000001. +- Setting Control TS 4 +Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) +Allocated TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 10, dl_slots = 10 +TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 64 +TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) changes state from NULL to FLOW +The MS object cannot fully confirm an unexpected TLLI: 0xffeeddcc, partly confirmed +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) append +New and old TBF are the same TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) start Packet Downlink Assignment (PACCH) ++++++++++++++++++++++++++ TX : Packet Downlink Assignment +++++++++++++++++++++++++ +------------------------- TX : Packet Downlink Assignment ------------------------- +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS): Scheduling polling at FN 13 TS 4 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) Scheduled DL Assignment polling on FN=13, TS=4 +Scheduling control message at RTS for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (TRX=0, TS=4) +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=0 block=0 data=4f 08 20 00 44 02 00 02 08 04 00 c0 0b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==0) +- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (len=10) +- Sending new block at BSN 0, CS=MCS-6 +-- Chunk with length 10 is less than remaining space (74): add length header to to delimit LLC frame +Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=10 +-- Empty chunk, added LLC dummy command of size 62, drained_since=0 +-- Chunk with length 62 is less than remaining space (63): add length header to to delimit LLC frame +-- No space left, so we are done. +Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=62 +data block (BSN 0, MCS-6): 14 7d 01 01 01 01 01 01 01 01 01 01 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 0, MCS-6): 07 00 00 00 45 5f 40 40 40 40 40 40 40 40 40 c0 10 70 c0 ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca 0a +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=4 block=1 data=07 00 00 00 45 5f 40 40 40 40 40 40 40 40 40 c0 10 70 c0 ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca 0a +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) append +Received RTS for PDCH: TRX=0 TS=4 FN=8 block_nr=2 scheduling free USF for polling at FN=13 of TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==1) +- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (len=512) +- Sending new block at BSN 1, CS=MCS-6 +-- Chunk with length 512 larger than space (74) left in block: copy only remaining space, and we are done +data block (BSN 1, MCS-6): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 1, MCS-6): 07 40 00 50 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=8 block=2 data=07 40 00 50 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==2) +- Sending new block at BSN 2, CS=MCS-6 +-- Chunk with length 438 larger than space (74) left in block: copy only remaining space, and we are done +data block (BSN 2, MCS-6): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 2, MCS-6): 07 80 00 50 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=13 block=3 data=07 80 00 50 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==3) +- Sending new block at BSN 3, CS=MCS-6 +-- Chunk with length 364 larger than space (74) left in block: copy only remaining space, and we are done +data block (BSN 3, MCS-6): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 3, MCS-6): 07 c0 00 50 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=17 block=4 data=07 c0 00 50 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==4) +- Sending new block at BSN 4, CS=MCS-6 +-- Chunk with length 290 larger than space (74) left in block: copy only remaining space, and we are done +data block (BSN 4, MCS-6): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 4, MCS-6): 07 00 01 50 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=21 block=5 data=07 00 01 50 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==5) +- Sending new block at BSN 5, CS=MCS-6 +-- Chunk with length 216 larger than space (74) left in block: copy only remaining space, and we are done +data block (BSN 5, MCS-6): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 5, MCS-6): 07 40 01 50 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=26 block=6 data=07 40 01 50 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==6) +- Sending new block at BSN 6, CS=MCS-6 +-- Chunk with length 142 larger than space (74) left in block: copy only remaining space, and we are done +data block (BSN 6, MCS-6): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 6, MCS-6): 07 80 01 50 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=30 block=7 data=07 80 01 50 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==7) +- Sending new block at BSN 7, CS=MCS-6 +-- Chunk with length 68 is less than remaining space (74): add length header to to delimit LLC frame +Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=512 +-- Empty chunk, added LLC dummy command of size 6, drained_since=0 +-- Chunk with length 6 larger than space (5) left in block: copy only remaining space, and we are done +data block (BSN 7, MCS-6): 89 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 43 c0 01 2b 2b +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 7, MCS-6): 07 c0 01 40 62 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 c0 10 70 c0 ca 0a +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=34 block=8 data=07 c0 01 40 62 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 c0 10 70 c0 ca 0a +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==8) +- Sending new block at BSN 8, CS=MCS-6 +-- Chunk with length 1 is less than remaining space (74): add length header to to delimit LLC frame +Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=6 +-- Empty chunk, added LLC dummy command of size 71, drained_since=5 +-- Chunk with length 71 is less than remaining space (72): add length header to to delimit LLC frame +-- No space left, so we are done. +Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=71 +data block (BSN 8, MCS-6): 02 8f 2b 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 8, MCS-6): 07 00 02 80 c0 e3 ca 10 70 c0 ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca 0a +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=39 block=9 data=07 00 02 80 c0 e3 ca 10 70 c0 ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca 0a +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink acknowledge +- Final ACK received. +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) changes state from FLOW to WAIT RELEASE +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=WAIT RELEASE EGPRS) starting timer 3193. +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=WAIT RELEASE EGPRS) changes state from WAIT RELEASE to RELEASING +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=RELEASING EGPRS) free +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=RELEASING EGPRS) stopping timer 3193. +PDCH(TS 4, TRX 0): Detaching TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=RELEASING EGPRS), 0 TBFs, USFs = 00, TFIs = 00000000. +Detaching TBF from MS object, TLLI = 0xffeeddcc, TBF = TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=RELEASING EGPRS) +Destroying MS object, TLLI = 0xffeeddcc +********** TBF ends here ********** +Searching for first unallocated TFI: TRX=0 + Found TFI=0. +********** TBF starts here ********** +Allocating DL TBF: MS_CLASS=11/11 +Creating MS object, TLLI = 0x00000000 +Modifying MS object, TLLI = 0x00000000, MS class 0 -> 11 +Modifying MS object, TLLI = 0x00000000, EGPRS MS class 0 -> 11 +Enabled EGPRS for TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), mode EGPRS +Slot Allocation (Algorithm A) for class 0 +- Skipping TS 0, because not enabled +- Skipping TS 1, because not enabled +- Skipping TS 2, because not enabled +- Skipping TS 3, because not enabled +- Skipping TS 5, because not enabled +- Skipping TS 6, because not enabled +- Skipping TS 7, because not enabled +- Assign downlink TS=4 TFI=0 +PDCH(TS 4, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), 1 TBFs, USFs = 00, TFIs = 00000001. +- Setting Control TS 4 +Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) +Allocated TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 10, dl_slots = 10 +TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 64 +TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) changes state from NULL to FLOW +The MS object cannot fully confirm an unexpected TLLI: 0xffeeddcc, partly confirmed +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) append +New and old TBF are the same TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) start Packet Downlink Assignment (PACCH) ++++++++++++++++++++++++++ TX : Packet Downlink Assignment +++++++++++++++++++++++++ +------------------------- TX : Packet Downlink Assignment ------------------------- +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS): Scheduling polling at FN 13 TS 4 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) Scheduled DL Assignment polling on FN=13, TS=4 +Scheduling control message at RTS for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (TRX=0, TS=4) +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=0 block=0 data=4f 08 20 00 44 02 00 02 08 04 00 c0 0b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==0) +- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (len=10) +- Sending new block at BSN 0, CS=MCS-7 +-- Chunk with length 10 is less than remaining space (56): add length header to to delimit LLC frame +Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=10 +-- Empty chunk, added LLC dummy command of size 44, drained_since=0 +-- Chunk with length 44 is less than remaining space (45): add length header to to delimit LLC frame +-- No space left, so we are done. +Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=44 +data block (BSN 0, MCS-7): 14 59 01 01 01 01 01 01 01 01 01 01 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 0, MCS-7): 07 00 00 00 a0 50 64 05 04 04 04 04 04 04 04 04 04 0c 01 07 ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=4 block=1 data=07 00 00 00 a0 50 64 05 04 04 04 04 04 04 04 04 04 0c 01 07 ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) append +Received RTS for PDCH: TRX=0 TS=4 FN=8 block_nr=2 scheduling free USF for polling at FN=13 of TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==1) +- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (len=512) +- Sending new block at BSN 1, CS=MCS-7 +-- Chunk with length 512 larger than space (56) left in block: copy only remaining space, and we are done +data block (BSN 1, MCS-7): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 1, MCS-7): 07 40 00 fe a7 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=8 block=2 data=07 40 00 fe a7 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==2) +- Sending new block at BSN 2, CS=MCS-7 +-- Chunk with length 456 larger than space (56) left in block: copy only remaining space, and we are done +data block (BSN 2, MCS-7): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 2, MCS-7): 07 80 00 fc a7 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=13 block=3 data=07 80 00 fc a7 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==3) +- Sending new block at BSN 3, CS=MCS-7 +-- Chunk with length 400 larger than space (56) left in block: copy only remaining space, and we are done +data block (BSN 3, MCS-7): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 3, MCS-7): 07 c0 00 fa a7 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=17 block=4 data=07 c0 00 fa a7 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==4) +- Sending new block at BSN 4, CS=MCS-7 +-- Chunk with length 344 larger than space (56) left in block: copy only remaining space, and we are done +data block (BSN 4, MCS-7): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 4, MCS-7): 07 00 01 f8 a7 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=21 block=5 data=07 00 01 f8 a7 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==5) +- Sending new block at BSN 5, CS=MCS-7 +-- Chunk with length 288 larger than space (56) left in block: copy only remaining space, and we are done +data block (BSN 5, MCS-7): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 5, MCS-7): 07 40 01 f6 a7 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=26 block=6 data=07 40 01 f6 a7 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==6) +- Sending new block at BSN 6, CS=MCS-7 +-- Chunk with length 232 larger than space (56) left in block: copy only remaining space, and we are done +data block (BSN 6, MCS-7): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 6, MCS-7): 07 80 01 f4 a7 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=30 block=7 data=07 80 01 f4 a7 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==7) +- Sending new block at BSN 7, CS=MCS-7 +-- Chunk with length 176 larger than space (56) left in block: copy only remaining space, and we are done +data block (BSN 7, MCS-7): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 7, MCS-7): 07 c0 01 f2 a7 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=34 block=8 data=07 c0 01 f2 a7 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==8) +- Sending new block at BSN 8, CS=MCS-7 +-- Chunk with length 120 larger than space (56) left in block: copy only remaining space, and we are done +data block (BSN 8, MCS-7): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 8, MCS-7): 07 00 02 f0 a7 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=39 block=9 data=07 00 02 f0 a7 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==9) +- Sending new block at BSN 9, CS=MCS-7 +-- Chunk with length 64 larger than space (56) left in block: copy only remaining space, and we are done +data block (BSN 9, MCS-7): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 9, MCS-7): 07 40 02 ee a7 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=43 block=10 data=07 40 02 ee a7 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==10) +- Sending new block at BSN 10, CS=MCS-7 +-- Chunk with length 8 is less than remaining space (56): add length header to to delimit LLC frame +Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=512 +-- Empty chunk, added LLC dummy command of size 46, drained_since=0 +-- Chunk with length 46 is less than remaining space (47): add length header to to delimit LLC frame +-- No space left, so we are done. +Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=46 +data block (BSN 10, MCS-7): 10 5d 01 01 01 01 01 01 01 01 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 10, MCS-7): 07 80 02 ec a7 40 74 05 04 04 04 04 04 04 04 0c 01 07 ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=47 block=11 data=07 80 02 ec a7 40 74 05 04 04 04 04 04 04 04 0c 01 07 ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink acknowledge +- Final ACK received. +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) changes state from FLOW to WAIT RELEASE +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=WAIT RELEASE EGPRS) starting timer 3193. +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=WAIT RELEASE EGPRS) changes state from WAIT RELEASE to RELEASING +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=RELEASING EGPRS) free +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=RELEASING EGPRS) stopping timer 3193. +PDCH(TS 4, TRX 0): Detaching TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=RELEASING EGPRS), 0 TBFs, USFs = 00, TFIs = 00000000. +Detaching TBF from MS object, TLLI = 0xffeeddcc, TBF = TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=RELEASING EGPRS) +Destroying MS object, TLLI = 0xffeeddcc +********** TBF ends here ********** +Searching for first unallocated TFI: TRX=0 + Found TFI=0. +********** TBF starts here ********** +Allocating DL TBF: MS_CLASS=11/11 +Creating MS object, TLLI = 0x00000000 +Modifying MS object, TLLI = 0x00000000, MS class 0 -> 11 +Modifying MS object, TLLI = 0x00000000, EGPRS MS class 0 -> 11 +Enabled EGPRS for TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), mode EGPRS +Slot Allocation (Algorithm A) for class 0 +- Skipping TS 0, because not enabled +- Skipping TS 1, because not enabled +- Skipping TS 2, because not enabled +- Skipping TS 3, because not enabled +- Skipping TS 5, because not enabled +- Skipping TS 6, because not enabled +- Skipping TS 7, because not enabled +- Assign downlink TS=4 TFI=0 +PDCH(TS 4, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), 1 TBFs, USFs = 00, TFIs = 00000001. +- Setting Control TS 4 +Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) +Allocated TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 10, dl_slots = 10 +TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 64 +TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) changes state from NULL to FLOW +The MS object cannot fully confirm an unexpected TLLI: 0xffeeddcc, partly confirmed +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) append +New and old TBF are the same TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) start Packet Downlink Assignment (PACCH) ++++++++++++++++++++++++++ TX : Packet Downlink Assignment +++++++++++++++++++++++++ +------------------------- TX : Packet Downlink Assignment ------------------------- +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS): Scheduling polling at FN 13 TS 4 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) Scheduled DL Assignment polling on FN=13, TS=4 +Scheduling control message at RTS for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (TRX=0, TS=4) +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=0 block=0 data=4f 08 20 00 44 02 00 02 08 04 00 c0 0b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==0) +- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (len=10) +- Sending new block at BSN 0, CS=MCS-8 +-- Chunk with length 10 is less than remaining space (68): add length header to to delimit LLC frame +Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=10 +-- Empty chunk, added LLC dummy command of size 56, drained_since=0 +-- Chunk with length 56 is less than remaining space (57): add length header to to delimit LLC frame +-- No space left, so we are done. +Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=56 +data block (BSN 0, MCS-8): 14 71 01 01 01 01 01 01 01 01 01 01 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 0, MCS-8): 07 00 00 00 58 50 c4 05 04 04 04 04 04 04 04 04 04 0c 01 07 ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=4 block=1 data=07 00 00 00 58 50 c4 05 04 04 04 04 04 04 04 04 04 0c 01 07 ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) append +Received RTS for PDCH: TRX=0 TS=4 FN=8 block_nr=2 scheduling free USF for polling at FN=13 of TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==1) +- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (len=512) +- Sending new block at BSN 1, CS=MCS-8 +-- Chunk with length 512 larger than space (68) left in block: copy only remaining space, and we are done +data block (BSN 1, MCS-8): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 1, MCS-8): 07 40 00 fe 5f 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=8 block=2 data=07 40 00 fe 5f 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==2) +- Sending new block at BSN 2, CS=MCS-8 +-- Chunk with length 444 larger than space (68) left in block: copy only remaining space, and we are done +data block (BSN 2, MCS-8): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 2, MCS-8): 07 80 00 fc 5f 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=13 block=3 data=07 80 00 fc 5f 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==3) +- Sending new block at BSN 3, CS=MCS-8 +-- Chunk with length 376 larger than space (68) left in block: copy only remaining space, and we are done +data block (BSN 3, MCS-8): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 3, MCS-8): 07 c0 00 fa 5f 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=17 block=4 data=07 c0 00 fa 5f 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==4) +- Sending new block at BSN 4, CS=MCS-8 +-- Chunk with length 308 larger than space (68) left in block: copy only remaining space, and we are done +data block (BSN 4, MCS-8): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 4, MCS-8): 07 00 01 f8 5f 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=21 block=5 data=07 00 01 f8 5f 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==5) +- Sending new block at BSN 5, CS=MCS-8 +-- Chunk with length 240 larger than space (68) left in block: copy only remaining space, and we are done +data block (BSN 5, MCS-8): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 5, MCS-8): 07 40 01 f6 5f 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=26 block=6 data=07 40 01 f6 5f 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==6) +- Sending new block at BSN 6, CS=MCS-8 +-- Chunk with length 172 larger than space (68) left in block: copy only remaining space, and we are done +data block (BSN 6, MCS-8): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 6, MCS-8): 07 80 01 f4 5f 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=30 block=7 data=07 80 01 f4 5f 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==7) +- Sending new block at BSN 7, CS=MCS-8 +-- Chunk with length 104 larger than space (68) left in block: copy only remaining space, and we are done +data block (BSN 7, MCS-8): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 7, MCS-8): 07 c0 01 f2 5f 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=34 block=8 data=07 c0 01 f2 5f 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==8) +- Sending new block at BSN 8, CS=MCS-8 +-- Chunk with length 36 is less than remaining space (68): add length header to to delimit LLC frame +Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=512 +-- Empty chunk, added LLC dummy command of size 30, drained_since=0 +-- Chunk with length 30 is less than remaining space (31): add length header to to delimit LLC frame +-- No space left, so we are done. +Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=30 +data block (BSN 8, MCS-8): 48 3d 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 8, MCS-8): 07 00 02 f0 5f 20 f5 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 0c 01 07 ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=39 block=9 data=07 00 02 f0 5f 20 f5 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 0c 01 07 ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink acknowledge +- Final ACK received. +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) changes state from FLOW to WAIT RELEASE +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=WAIT RELEASE EGPRS) starting timer 3193. +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=WAIT RELEASE EGPRS) changes state from WAIT RELEASE to RELEASING +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=RELEASING EGPRS) free +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=RELEASING EGPRS) stopping timer 3193. +PDCH(TS 4, TRX 0): Detaching TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=RELEASING EGPRS), 0 TBFs, USFs = 00, TFIs = 00000000. +Detaching TBF from MS object, TLLI = 0xffeeddcc, TBF = TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=RELEASING EGPRS) +Destroying MS object, TLLI = 0xffeeddcc +********** TBF ends here ********** +Searching for first unallocated TFI: TRX=0 + Found TFI=0. +********** TBF starts here ********** +Allocating DL TBF: MS_CLASS=11/11 +Creating MS object, TLLI = 0x00000000 +Modifying MS object, TLLI = 0x00000000, MS class 0 -> 11 +Modifying MS object, TLLI = 0x00000000, EGPRS MS class 0 -> 11 +Enabled EGPRS for TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), mode EGPRS +Slot Allocation (Algorithm A) for class 0 +- Skipping TS 0, because not enabled +- Skipping TS 1, because not enabled +- Skipping TS 2, because not enabled +- Skipping TS 3, because not enabled +- Skipping TS 5, because not enabled +- Skipping TS 6, because not enabled +- Skipping TS 7, because not enabled +- Assign downlink TS=4 TFI=0 +PDCH(TS 4, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), 1 TBFs, USFs = 00, TFIs = 00000001. +- Setting Control TS 4 +Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) +Allocated TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 10, dl_slots = 10 +TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 64 +TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) changes state from NULL to FLOW +The MS object cannot fully confirm an unexpected TLLI: 0xffeeddcc, partly confirmed +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) append +New and old TBF are the same TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) start Packet Downlink Assignment (PACCH) ++++++++++++++++++++++++++ TX : Packet Downlink Assignment +++++++++++++++++++++++++ +------------------------- TX : Packet Downlink Assignment ------------------------- +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS): Scheduling polling at FN 13 TS 4 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) Scheduled DL Assignment polling on FN=13, TS=4 +Scheduling control message at RTS for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (TRX=0, TS=4) +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=0 block=0 data=4f 08 20 00 44 02 00 02 08 04 00 c0 0b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==0) +- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (len=10) +- Sending new block at BSN 0, CS=MCS-9 +-- Chunk with length 10 is less than remaining space (74): add length header to to delimit LLC frame +Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=10 +-- Empty chunk, added LLC dummy command of size 62, drained_since=0 +-- Chunk with length 62 is less than remaining space (63): add length header to to delimit LLC frame +-- No space left, so we are done. +Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=62 +data block (BSN 0, MCS-9): 14 7d 01 01 01 01 01 01 01 01 01 01 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 0, MCS-9): 07 00 00 00 00 50 f4 05 04 04 04 04 04 04 04 04 04 0c 01 07 ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=4 block=1 data=07 00 00 00 00 50 f4 05 04 04 04 04 04 04 04 04 04 0c 01 07 ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) append +Received RTS for PDCH: TRX=0 TS=4 FN=8 block_nr=2 scheduling free USF for polling at FN=13 of TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==1) +- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (len=512) +- Sending new block at BSN 1, CS=MCS-9 +-- Chunk with length 512 larger than space (74) left in block: copy only remaining space, and we are done +data block (BSN 1, MCS-9): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 1, MCS-9): 07 40 00 fe 07 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=8 block=2 data=07 40 00 fe 07 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==2) +- Sending new block at BSN 2, CS=MCS-9 +-- Chunk with length 438 larger than space (74) left in block: copy only remaining space, and we are done +data block (BSN 2, MCS-9): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 2, MCS-9): 07 80 00 fc 07 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=13 block=3 data=07 80 00 fc 07 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==3) +- Sending new block at BSN 3, CS=MCS-9 +-- Chunk with length 364 larger than space (74) left in block: copy only remaining space, and we are done +data block (BSN 3, MCS-9): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 3, MCS-9): 07 c0 00 fa 07 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=17 block=4 data=07 c0 00 fa 07 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==4) +- Sending new block at BSN 4, CS=MCS-9 +-- Chunk with length 290 larger than space (74) left in block: copy only remaining space, and we are done +data block (BSN 4, MCS-9): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 4, MCS-9): 07 00 01 f8 07 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=21 block=5 data=07 00 01 f8 07 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==5) +- Sending new block at BSN 5, CS=MCS-9 +-- Chunk with length 216 larger than space (74) left in block: copy only remaining space, and we are done +data block (BSN 5, MCS-9): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 5, MCS-9): 07 40 01 f6 07 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=26 block=6 data=07 40 01 f6 07 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==6) +- Sending new block at BSN 6, CS=MCS-9 +-- Chunk with length 142 larger than space (74) left in block: copy only remaining space, and we are done +data block (BSN 6, MCS-9): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 6, MCS-9): 07 80 01 f4 07 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=30 block=7 data=07 80 01 f4 07 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==7) +- Sending new block at BSN 7, CS=MCS-9 +-- Chunk with length 68 is less than remaining space (74): add length header to to delimit LLC frame +Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=512 +-- Empty chunk, added LLC dummy command of size 6, drained_since=0 +-- Chunk with length 6 larger than space (5) left in block: copy only remaining space, and we are done +data block (BSN 7, MCS-9): 89 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 43 c0 01 2b 2b +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 7, MCS-9): 07 c0 01 f2 07 24 06 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 0c 01 07 ac ac 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=34 block=8 data=07 c0 01 f2 07 24 06 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 0c 01 07 ac ac 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==8) +- Sending new block at BSN 8, CS=MCS-9 +-- Chunk with length 1 is less than remaining space (74): add length header to to delimit LLC frame +Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=6 +-- Empty chunk, added LLC dummy command of size 71, drained_since=5 +-- Chunk with length 71 is less than remaining space (72): add length header to to delimit LLC frame +-- No space left, so we are done. +Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=71 +data block (BSN 8, MCS-9): 02 8f 2b 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) +msg block (BSN 8, MCS-9): 07 00 02 f0 07 08 3c ae 0c 01 07 ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=39 block=9 data=07 00 02 f0 07 08 3c ae 0c 01 07 ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink acknowledge +- Final ACK received. +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) changes state from FLOW to WAIT RELEASE +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=WAIT RELEASE EGPRS) starting timer 3193. +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=WAIT RELEASE EGPRS) changes state from WAIT RELEASE to RELEASING +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=RELEASING EGPRS) free +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=RELEASING EGPRS) stopping timer 3193. +PDCH(TS 4, TRX 0): Detaching TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=RELEASING EGPRS), 0 TBFs, USFs = 00, TFIs = 00000000. +Detaching TBF from MS object, TLLI = 0xffeeddcc, TBF = TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=RELEASING EGPRS) +Destroying MS object, TLLI = 0xffeeddcc +********** TBF ends here ********** diff --git a/tests/tbf/TbfTest.ok b/tests/tbf/TbfTest.ok index c6c4aea2..441b4440 100644 --- a/tests/tbf/TbfTest.ok +++ b/tests/tbf/TbfTest.ok @@ -30,3 +30,16 @@ === end test_tbf_gprs_egprs === === start test_tbf_ws === === end test_tbf_ws === +=== start test_tbf_egprs_two_phase === +=== end test_tbf_egprs_two_phase === +=== start test_tbf_egprs_dl === +Testing MCS-1 +Testing MCS-2 +Testing MCS-3 +Testing MCS-4 +Testing MCS-5 +Testing MCS-6 +Testing MCS-7 +Testing MCS-8 +Testing MCS-9 +=== end test_tbf_egprs_dl === -- cgit v1.2.3 From 14e26cbca3d4fe5b7e7e6729e12708555ddb3a41 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Wed, 3 Feb 2016 15:26:29 +0100 Subject: ms: Fix GprsMs::current_cs_dl() Currently the queue length is overwritten by the remaining chunk length, which should be added instead. This may result in a lower CS/MCS value than expected. Add the chunk length instead if the TBF is present. Sponsored-by: On-Waves ehf --- src/gprs_ms.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gprs_ms.cpp b/src/gprs_ms.cpp index f522586b..78f03f84 100644 --- a/src/gprs_ms.cpp +++ b/src/gprs_ms.cpp @@ -706,7 +706,7 @@ GprsCodingScheme GprsMs::current_cs_dl() const /* If the DL TBF is active, add number of unencoded chunk octets */ if (m_dl_tbf) - unencoded_octets = m_dl_tbf->m_llc.chunk_size(); + unencoded_octets += m_dl_tbf->m_llc.chunk_size(); /* There are many unencoded octets, don't reduce */ if (unencoded_octets >= m_bts->bts_data()->cs_downgrade_threshold) -- cgit v1.2.3 From be314d9a54578d1eb31ab84f5de9bc16f8e892e9 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Tue, 2 Feb 2016 15:32:10 +0100 Subject: edge: Refactor create_dl_acked_block for multi-block support Currently the method is hard-coded to support a single BSN only. MCS-7 to MCS-9 encode 2 data blocks into a single RLC data message. This commit refactors create_dl_acked_block to process any number of blocks internally. Note that this does not extend the parameter list accordingly and just duplicates the BSN if these MCS are being used. Sponsored-by: On-Waves ehf --- src/tbf.h | 2 +- src/tbf_dl.cpp | 109 ++++++++++++++---- tests/tbf/TbfTest.err | 310 ++++++++++++++++++++++++++++++++++++++++---------- 3 files changed, 338 insertions(+), 83 deletions(-) diff --git a/src/tbf.h b/src/tbf.h index 443f85fc..2eefbeea 100644 --- a/src/tbf.h +++ b/src/tbf.h @@ -408,7 +408,7 @@ protected: struct msgb *create_new_bsn(const uint32_t fn, const uint8_t ts); struct msgb *create_dl_acked_block(const uint32_t fn, const uint8_t ts, - const int index); + int index, int index2 = -1); int update_window(const uint8_t ssn, const uint8_t *rbb); int update_window(unsigned first_bsn, const struct bitvec *rbb); int maybe_start_new_window(); diff --git a/src/tbf_dl.cpp b/src/tbf_dl.cpp index 6208b601..21b2ba13 100644 --- a/src/tbf_dl.cpp +++ b/src/tbf_dl.cpp @@ -519,9 +519,9 @@ struct msgb *gprs_rlcmac_dl_tbf::create_new_bsn(const uint32_t fn, const uint8_t struct msgb *gprs_rlcmac_dl_tbf::create_dl_acked_block( const uint32_t fn, const uint8_t ts, - const int index) + int index, int index2) { - uint8_t *block_data, *msg_data; + uint8_t *msg_data; struct msgb *dl_msg; unsigned msg_len; bool need_poll; @@ -530,26 +530,96 @@ struct msgb *gprs_rlcmac_dl_tbf::create_dl_acked_block( unsigned int rrbp; uint32_t new_poll_fn; int rc; - + bool is_final = false; gprs_rlc_data_info rlc; GprsCodingScheme cs; - gprs_rlc_data_block_info *rdbi; + int bsns[ARRAY_SIZE(rlc.block_info)]; + unsigned num_bsns; + int punct[ARRAY_SIZE(rlc.block_info)]; + bool need_padding = false; + + /* + * TODO: This is an experimental work-around to put 2 BSN into + * MSC-7 to MCS-9 encoded messages. It just sends the same BSN + * twice in the block. The cs should be derived from the TBF's + * current CS such that both BSNs (that must be compatible) can + * be put into the data area, even if the resulting CS is higher than + * the current limit. + */ + cs = m_rlc.block(index)->cs; + bsns[0] = index; + num_bsns = 1; - /* get data and header from current block */ - block_data = m_rlc.block(index)->block; + if (index2 >= 0) { + bsns[num_bsns] = index2; + num_bsns += 1; + } - cs = m_rlc.block(index)->cs; + if (num_bsns == 1) + cs.decToSingleBlock(&need_padding); - gprs_rlc_data_info_init_dl(&rlc, cs, false); + gprs_rlc_data_info_init_dl(&rlc, cs, need_padding); rlc.usf = 7; /* will be set at scheduler */ rlc.pr = 0; /* FIXME: power reduction */ rlc.tfi = m_tfi; /* TFI */ - /* TODO: Use real puncturing values */ - rlc.cps = gprs_rlc_mcs_cps(cs, 0, 0, 0); - rlc.block_info[data_block_idx] = m_rlc.block(index)->block_info; - rdbi = &rlc.block_info[data_block_idx]; + /* return data block(s) as message */ + msg_len = cs.sizeDL(); + dl_msg = msgb_alloc(msg_len, "rlcmac_dl_data"); + if (!dl_msg) + return NULL; + + msg_data = msgb_put(dl_msg, msg_len); + + /* Copy block(s) to RLC message */ + for (data_block_idx = 0; data_block_idx < rlc.num_data_blocks; + data_block_idx++) + { + int bsn; + GprsCodingScheme cs_enc; + uint8_t *block_data; + gprs_rlc_data_block_info *rdbi, *block_info; + + /* Check if there are more blocks than BSNs */ + if (data_block_idx < num_bsns) + bsn = bsns[data_block_idx]; + else + bsn = bsns[0]; + + cs_enc = m_rlc.block(bsn)->cs; + + /* get data and header from current block */ + block_data = m_rlc.block(bsn)->block; + + /* TODO: Use real puncturing values */ + punct[data_block_idx] = data_block_idx; + + rdbi = &rlc.block_info[data_block_idx]; + block_info = &m_rlc.block(bsn)->block_info; + + if(rdbi->data_len != m_rlc.block(bsn)->len) { + LOGP(DRLCMACDL, LOGL_ERROR, + "ERROR: Expected len = %d for %s instead of " + "%d in data unit %d (BSN %d, %s)\n", + rdbi->data_len, cs.name(), m_rlc.block(bsn)->len, + data_block_idx, bsn, cs_enc.name()); + OSMO_ASSERT(rdbi->data_len == m_rlc.block(bsn)->len); + } + rdbi->e = block_info->e; + rdbi->cv = block_info->cv; + rdbi->bsn = bsn; + is_final = is_final || rdbi->cv == 0; + + LOGP(DRLCMACDL, LOGL_DEBUG, "- Copying data unit %d (BSN %d)\n", + data_block_idx, bsn); + + Encoding::rlc_copy_from_aligned_buffer(&rlc, data_block_idx, + msg_data, block_data); + } + + OSMO_ASSERT(ARRAY_SIZE(punct) >= 2); + rlc.cps = gprs_rlc_mcs_cps(cs, punct[0], punct[1], need_padding); /* If the TBF has just started, relate frames_since_last_poll to the * current fn */ @@ -583,7 +653,7 @@ struct msgb *gprs_rlcmac_dl_tbf::create_dl_acked_block( "TS %d\n", ts); m_tx_counter = 0; /* start timer whenever we send the final block */ - if (rdbi->cv == 0) + if (is_final) tbf_timer_start(this, 3191, bts_data()->t3191, 0); /* Clear poll timeout flag */ @@ -604,20 +674,11 @@ struct msgb *gprs_rlcmac_dl_tbf::create_dl_acked_block( } } - msg_len = cs.sizeDL(); - - /* return data block as message */ - dl_msg = msgb_alloc(msg_len, "rlcmac_dl_data"); - if (!dl_msg) - return NULL; - - msg_data = msgb_put(dl_msg, msg_len); Encoding::rlc_write_dl_data_header(&rlc, msg_data); - Encoding::rlc_copy_from_aligned_buffer(&rlc, data_block_idx, msg_data, - block_data); - LOGP(DRLCMACDL, LOGL_DEBUG, "msg block (BSN %d, %s): %s\n", + LOGP(DRLCMACDL, LOGL_DEBUG, "msg block (BSN %d, %s%s): %s\n", index, cs.name(), + need_padding ? ", padded" : "", msgb_hexdump(dl_msg)); /* Increment TX-counter */ diff --git a/tests/tbf/TbfTest.err b/tests/tbf/TbfTest.err index 724d9db7..d97589e9 100644 --- a/tests/tbf/TbfTest.err +++ b/tests/tbf/TbfTest.err @@ -72,6 +72,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==0) - Sending new block at BSN 0, CS=CS-1 -- Chunk with length 200 larger than space (20) left in block: copy only remaining space, and we are done data block (BSN 0, CS-1): 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 +- Copying data unit 0 (BSN 0) msg block (BSN 0, CS-1): 07 00 01 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=4 block=1 data=07 00 01 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 Received RTS for PDCH: TRX=0 TS=4 FN=8 block_nr=2 scheduling free USF for polling at FN=13 of TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) @@ -80,6 +81,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==1) - Sending new block at BSN 1, CS=CS-1 -- Chunk with length 180 larger than space (20) left in block: copy only remaining space, and we are done data block (BSN 1, CS-1): 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 +- Copying data unit 0 (BSN 1) msg block (BSN 1, CS-1): 07 00 03 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=8 block=2 data=07 00 03 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink acknowledge @@ -155,6 +157,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==0) - Sending new block at BSN 0, CS=CS-1 -- Chunk with length 200 larger than space (20) left in block: copy only remaining space, and we are done data block (BSN 0, CS-1): 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 +- Copying data unit 0 (BSN 0) msg block (BSN 0, CS-1): 07 00 01 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=4 block=1 data=07 00 01 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 Received RTS for PDCH: TRX=0 TS=4 FN=8 block_nr=2 scheduling free USF for polling at FN=13 of TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) @@ -163,6 +166,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==1) - Sending new block at BSN 1, CS=CS-1 -- Chunk with length 180 larger than space (20) left in block: copy only remaining space, and we are done data block (BSN 1, CS-1): 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 +- Copying data unit 0 (BSN 1) msg block (BSN 1, CS-1): 07 00 03 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=8 block=2 data=07 00 03 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink acknowledge @@ -238,6 +242,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==0) - Sending new block at BSN 0, CS=CS-1 -- Chunk with length 200 larger than space (20) left in block: copy only remaining space, and we are done data block (BSN 0, CS-1): 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 +- Copying data unit 0 (BSN 0) msg block (BSN 0, CS-1): 07 00 01 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=4 block=1 data=07 00 01 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 Received RTS for PDCH: TRX=0 TS=4 FN=8 block_nr=2 scheduling free USF for polling at FN=13 of TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) @@ -246,6 +251,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==1) - Sending new block at BSN 1, CS=CS-1 -- Chunk with length 180 larger than space (20) left in block: copy only remaining space, and we are done data block (BSN 1, CS-1): 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 +- Copying data unit 0 (BSN 1) msg block (BSN 1, CS-1): 07 00 03 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=8 block=2 data=07 00 03 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 @@ -253,6 +259,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==2) - Sending new block at BSN 2, CS=CS-1 -- Chunk with length 160 larger than space (20) left in block: copy only remaining space, and we are done data block (BSN 2, CS-1): 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b +- Copying data unit 0 (BSN 2) msg block (BSN 2, CS-1): 07 00 05 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=13 block=3 data=07 00 05 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 @@ -260,6 +267,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==3) - Sending new block at BSN 3, CS=CS-1 -- Chunk with length 140 larger than space (20) left in block: copy only remaining space, and we are done data block (BSN 3, CS-1): 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f +- Copying data unit 0 (BSN 3) msg block (BSN 3, CS-1): 07 00 07 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=17 block=4 data=07 00 07 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 @@ -267,6 +275,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==4) - Sending new block at BSN 4, CS=CS-1 -- Chunk with length 120 larger than space (20) left in block: copy only remaining space, and we are done data block (BSN 4, CS-1): 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 +- Copying data unit 0 (BSN 4) msg block (BSN 4, CS-1): 07 00 09 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=21 block=5 data=07 00 09 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 @@ -274,6 +283,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==5) - Sending new block at BSN 5, CS=CS-1 -- Chunk with length 100 larger than space (20) left in block: copy only remaining space, and we are done data block (BSN 5, CS-1): 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 +- Copying data unit 0 (BSN 5) msg block (BSN 5, CS-1): 07 00 0b 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=26 block=6 data=07 00 0b 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 @@ -281,6 +291,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==6) - Sending new block at BSN 6, CS=CS-1 -- Chunk with length 80 larger than space (20) left in block: copy only remaining space, and we are done data block (BSN 6, CS-1): 78 79 7a 7b 7c 7d 7e 7f 80 81 82 83 84 85 86 87 88 89 8a 8b +- Copying data unit 0 (BSN 6) msg block (BSN 6, CS-1): 07 00 0d 78 79 7a 7b 7c 7d 7e 7f 80 81 82 83 84 85 86 87 88 89 8a 8b Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=30 block=7 data=07 00 0d 78 79 7a 7b 7c 7d 7e 7f 80 81 82 83 84 85 86 87 88 89 8a 8b Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 @@ -288,6 +299,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==7) - Sending new block at BSN 7, CS=CS-1 -- Chunk with length 60 larger than space (20) left in block: copy only remaining space, and we are done data block (BSN 7, CS-1): 8c 8d 8e 8f 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f +- Copying data unit 0 (BSN 7) msg block (BSN 7, CS-1): 07 00 0f 8c 8d 8e 8f 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=34 block=8 data=07 00 0f 8c 8d 8e 8f 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 @@ -295,6 +307,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==8) - Sending new block at BSN 8, CS=CS-1 -- Chunk with length 40 larger than space (20) left in block: copy only remaining space, and we are done data block (BSN 8, CS-1): a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af b0 b1 b2 b3 +- Copying data unit 0 (BSN 8) msg block (BSN 8, CS-1): 07 00 11 a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af b0 b1 b2 b3 Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=39 block=9 data=07 00 11 a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af b0 b1 b2 b3 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 @@ -302,6 +315,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==9) - Sending new block at BSN 9, CS=CS-1 -- Chunk with length 20 would exactly fit into space (20): add length header with LI=0, to make frame extend to next block, and we are done data block (BSN 9, CS-1): 01 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf c0 c1 c2 c3 c4 c5 c6 +- Copying data unit 0 (BSN 9) msg block (BSN 9, CS-1): 07 00 12 01 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf c0 c1 c2 c3 c4 c5 c6 Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=43 block=10 data=07 00 12 01 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf c0 c1 c2 c3 c4 c5 c6 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 @@ -312,6 +326,7 @@ Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW)len=200 - Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) (len=200) -- Chunk with length 200 larger than space (18) left in block: copy only remaining space, and we are done data block (BSN 10, CS-1): 07 c7 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 +- Copying data unit 0 (BSN 10) msg block (BSN 10, CS-1): 07 00 14 07 c7 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=47 block=11 data=07 00 14 07 c7 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=4 @@ -319,6 +334,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==11) - Sending new block at BSN 11, CS=CS-1 -- Chunk with length 182 larger than space (20) left in block: copy only remaining space, and we are done data block (BSN 11, CS-1): 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 +- Copying data unit 0 (BSN 11) msg block (BSN 11, CS-1): 07 00 17 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=52 block=0 data=07 00 17 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=4 @@ -326,6 +342,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==12) - Sending new block at BSN 12, CS=CS-1 -- Chunk with length 162 larger than space (20) left in block: copy only remaining space, and we are done data block (BSN 12, CS-1): 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 +- Copying data unit 0 (BSN 12) msg block (BSN 12, CS-1): 07 00 19 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=56 block=1 data=07 00 19 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=4 @@ -333,6 +350,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==13) - Sending new block at BSN 13, CS=CS-1 -- Chunk with length 142 larger than space (20) left in block: copy only remaining space, and we are done data block (BSN 13, CS-1): 3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d +- Copying data unit 0 (BSN 13) msg block (BSN 13, CS-1): 07 00 1b 3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=60 block=2 data=07 00 1b 3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=4 @@ -340,6 +358,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==14) - Sending new block at BSN 14, CS=CS-1 -- Chunk with length 122 larger than space (20) left in block: copy only remaining space, and we are done data block (BSN 14, CS-1): 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 +- Copying data unit 0 (BSN 14) msg block (BSN 14, CS-1): 07 00 1d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=65 block=3 data=07 00 1d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=4 @@ -347,6 +366,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==15) - Sending new block at BSN 15, CS=CS-1 -- Chunk with length 102 larger than space (20) left in block: copy only remaining space, and we are done data block (BSN 15, CS-1): 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 +- Copying data unit 0 (BSN 15) msg block (BSN 15, CS-1): 07 00 1f 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=69 block=4 data=07 00 1f 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=4 @@ -354,6 +374,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==16) - Sending new block at BSN 16, CS=CS-1 -- Chunk with length 82 larger than space (20) left in block: copy only remaining space, and we are done data block (BSN 16, CS-1): 76 77 78 79 7a 7b 7c 7d 7e 7f 80 81 82 83 84 85 86 87 88 89 +- Copying data unit 0 (BSN 16) msg block (BSN 16, CS-1): 07 00 21 76 77 78 79 7a 7b 7c 7d 7e 7f 80 81 82 83 84 85 86 87 88 89 Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=73 block=5 data=07 00 21 76 77 78 79 7a 7b 7c 7d 7e 7f 80 81 82 83 84 85 86 87 88 89 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=4 @@ -361,6 +382,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==17) - Sending new block at BSN 17, CS=CS-1 -- Chunk with length 62 larger than space (20) left in block: copy only remaining space, and we are done data block (BSN 17, CS-1): 8a 8b 8c 8d 8e 8f 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d +- Copying data unit 0 (BSN 17) msg block (BSN 17, CS-1): 07 00 23 8a 8b 8c 8d 8e 8f 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=78 block=6 data=07 00 23 8a 8b 8c 8d 8e 8f 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=4 @@ -368,6 +390,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==18) - Sending new block at BSN 18, CS=CS-1 -- Chunk with length 42 larger than space (20) left in block: copy only remaining space, and we are done data block (BSN 18, CS-1): 9e 9f a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af b0 b1 +- Copying data unit 0 (BSN 18) msg block (BSN 18, CS-1): 07 00 25 9e 9f a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af b0 b1 Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=82 block=7 data=07 00 25 9e 9f a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af b0 b1 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=4 @@ -375,6 +398,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==19) - Sending new block at BSN 19, CS=CS-1 -- Chunk with length 22 larger than space (20) left in block: copy only remaining space, and we are done data block (BSN 19, CS-1): b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf c0 c1 c2 c3 c4 c5 +- Copying data unit 0 (BSN 19) msg block (BSN 19, CS-1): 07 00 27 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf c0 c1 c2 c3 c4 c5 Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=86 block=8 data=07 00 27 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf c0 c1 c2 c3 c4 c5 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=4 @@ -387,6 +411,7 @@ Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW)len=200 -- No space left, so we are done. Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW)len=16 data block (BSN 20, CS-1): 0a 41 c6 c7 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +- Copying data unit 0 (BSN 20) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) msg block (BSN 20, CS-1): 07 00 28 0a 41 c6 c7 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b @@ -424,6 +449,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==21 .. V(S)==21) -- No space left, so we are done. Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW)len=19 data block (BSN 21, CS-1): 4d 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +- Copying data unit 0 (BSN 21) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) msg block (BSN 21, CS-1): 07 00 2a 4d 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b @@ -442,6 +468,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==22 .. V(S)==22) Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW)len=19 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) changes state from FLOW to FINISHED data block (BSN 22, CS-1): 4d 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +- Copying data unit 0 (BSN 22) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FINISHED) msg block (BSN 22, CS-1): 07 01 2c 4d 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b @@ -1454,6 +1481,7 @@ TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=WAIT ASSIGN) downlink (V(A)==0 .. V(S)==0 Complete DL frame for TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=WAIT ASSIGN)len=19 - Dequeue next LLC for TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=WAIT ASSIGN) (len=19) data block (BSN 0, CS-1): 4d 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 0) msg block (BSN 0, CS-1): 07 00 00 4d 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 MSG = 07 00 00 4d 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=WAIT ASSIGN) downlink (V(A)==0 .. V(S)==1) @@ -1463,6 +1491,7 @@ TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=WAIT ASSIGN) downlink (V(A)==0 .. V(S)==1 Complete DL frame for TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=WAIT ASSIGN)len=19 - Dequeue next LLC for TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=WAIT ASSIGN) (len=19) data block (BSN 1, CS-1): 4d 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 +- Copying data unit 0 (BSN 1) msg block (BSN 1, CS-1): 07 00 02 4d 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 MSG = 07 00 02 4d 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=WAIT ASSIGN) downlink (V(A)==0 .. V(S)==2) @@ -1472,6 +1501,7 @@ TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=WAIT ASSIGN) downlink (V(A)==0 .. V(S)==2 Complete DL frame for TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=WAIT ASSIGN)len=19 TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=WAIT ASSIGN) changes state from WAIT ASSIGN to FINISHED data block (BSN 2, CS-1): 4d 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 +- Copying data unit 0 (BSN 2) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling cannot be scheduled in this TS 7 (first control TS 4) msg block (BSN 2, CS-1): 07 01 04 4d 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 @@ -1754,6 +1784,7 @@ TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==0) Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=10 TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) changes state from FLOW to FINISHED data block (BSN 0, CS-4): 29 52 41 55 5f 41 43 43 45 50 54 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +- Copying data unit 0 (BSN 0) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FINISHED): Scheduling polling at FN 2654292 TS 7 Polling scheduled in this TS 7 @@ -1766,6 +1797,7 @@ Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=7) prio=1 TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FINISHED) downlink (V(A)==0 .. V(S)==1) - Restarting at BSN 0, because all blocks have been transmitted. - Resending BSN 0 +- Copying data unit 0 (BSN 0) msg block (BSN 0, CS-4): 07 01 00 29 52 41 55 5f 41 43 43 45 50 54 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 00 Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654283 block=11 data=00 01 00 29 52 41 55 5f 41 43 43 45 50 54 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 00 MS requests UL TBF on RACH, so we provide one: @@ -2333,6 +2365,7 @@ Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) -- Chunk with length 13 larger than space (6) left in block: copy only remaining space, and we are done data block (BSN 0, CS-1): 37 4c 4c 43 20 50 41 43 4b 45 54 20 30 30 4c 4c 43 20 50 41 +- Copying data unit 0 (BSN 0) msg block (BSN 0, CS-1): 07 00 00 37 4c 4c 43 20 50 41 43 4b 45 54 20 30 30 4c 4c 43 20 50 41 Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654279 block=10 data=00 00 00 37 4c 4c 43 20 50 41 43 4b 45 54 20 30 30 4c 4c 43 20 50 41 Received RTS on disabled PDCH: TRX=0 TS=0 @@ -2351,6 +2384,7 @@ Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) -- Chunk with length 13 larger than space (12) left in block: copy only remaining space, and we are done data block (BSN 1, CS-1): 1f 43 4b 45 54 20 30 31 4c 4c 43 20 50 41 43 4b 45 54 20 30 +- Copying data unit 0 (BSN 1) msg block (BSN 1, CS-1): 07 00 02 1f 43 4b 45 54 20 30 31 4c 4c 43 20 50 41 43 4b 45 54 20 30 Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654283 block=11 data=00 00 02 1f 43 4b 45 54 20 30 31 4c 4c 43 20 50 41 43 4b 45 54 20 30 Received RTS on disabled PDCH: TRX=0 TS=0 @@ -2372,6 +2406,7 @@ Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) -- Chunk with length 13 larger than space (4) left in block: copy only remaining space, and we are done data block (BSN 2, CS-1): 06 37 32 4c 4c 43 20 50 41 43 4b 45 54 20 30 33 4c 4c 43 20 +- Copying data unit 0 (BSN 2) msg block (BSN 2, CS-1): 07 00 04 06 37 32 4c 4c 43 20 50 41 43 4b 45 54 20 30 33 4c 4c 43 20 Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654288 block=0 data=00 00 04 06 37 32 4c 4c 43 20 50 41 43 4b 45 54 20 30 33 4c 4c 43 20 Received RTS on disabled PDCH: TRX=0 TS=0 @@ -2390,6 +2425,7 @@ Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) -- Chunk with length 13 larger than space (10) left in block: copy only remaining space, and we are done data block (BSN 3, CS-1): 27 50 41 43 4b 45 54 20 30 34 4c 4c 43 20 50 41 43 4b 45 54 +- Copying data unit 0 (BSN 3) msg block (BSN 3, CS-1): 07 00 06 27 50 41 43 4b 45 54 20 30 34 4c 4c 43 20 50 41 43 4b 45 54 Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654292 block=1 data=00 00 06 27 50 41 43 4b 45 54 20 30 34 4c 4c 43 20 50 41 43 4b 45 54 Received RTS on disabled PDCH: TRX=0 TS=0 @@ -2411,6 +2447,7 @@ Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) -- Chunk with length 13 larger than space (2) left in block: copy only remaining space, and we are done data block (BSN 4, CS-1): 0e 37 20 30 35 4c 4c 43 20 50 41 43 4b 45 54 20 30 36 4c 4c +- Copying data unit 0 (BSN 4) msg block (BSN 4, CS-1): 07 00 08 0e 37 20 30 35 4c 4c 43 20 50 41 43 4b 45 54 20 30 36 4c 4c Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654296 block=2 data=00 00 08 0e 37 20 30 35 4c 4c 43 20 50 41 43 4b 45 54 20 30 36 4c 4c Received RTS on disabled PDCH: TRX=0 TS=0 @@ -2429,6 +2466,7 @@ Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) -- Chunk with length 13 larger than space (8) left in block: copy only remaining space, and we are done data block (BSN 5, CS-1): 2f 43 20 50 41 43 4b 45 54 20 30 37 4c 4c 43 20 50 41 43 4b +- Copying data unit 0 (BSN 5) msg block (BSN 5, CS-1): 07 00 0a 2f 43 20 50 41 43 4b 45 54 20 30 37 4c 4c 43 20 50 41 43 4b Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654301 block=3 data=00 00 0a 2f 43 20 50 41 43 4b 45 54 20 30 37 4c 4c 43 20 50 41 43 4b Received RTS on disabled PDCH: TRX=0 TS=0 @@ -2450,6 +2488,7 @@ Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) data block (BSN 6, CS-1): 16 35 45 54 20 30 38 4c 4c 43 20 50 41 43 4b 45 54 20 30 39 +- Copying data unit 0 (BSN 6) msg block (BSN 6, CS-1): 07 00 0c 16 35 45 54 20 30 38 4c 4c 43 20 50 41 43 4b 45 54 20 30 39 Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654305 block=4 data=00 00 0c 16 35 45 54 20 30 38 4c 4c 43 20 50 41 43 4b 45 54 20 30 39 Received RTS on disabled PDCH: TRX=0 TS=0 @@ -2468,6 +2507,7 @@ Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) -- Chunk with length 13 larger than space (6) left in block: copy only remaining space, and we are done data block (BSN 7, CS-1): 37 4c 4c 43 20 50 41 43 4b 45 54 20 31 30 4c 4c 43 20 50 41 +- Copying data unit 0 (BSN 7) msg block (BSN 7, CS-1): 07 00 0e 37 4c 4c 43 20 50 41 43 4b 45 54 20 31 30 4c 4c 43 20 50 41 Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654309 block=5 data=00 00 0e 37 4c 4c 43 20 50 41 43 4b 45 54 20 31 30 4c 4c 43 20 50 41 Received RTS on disabled PDCH: TRX=0 TS=0 @@ -2486,6 +2526,7 @@ Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) -- Chunk with length 13 larger than space (12) left in block: copy only remaining space, and we are done data block (BSN 8, CS-1): 1f 43 4b 45 54 20 31 31 4c 4c 43 20 50 41 43 4b 45 54 20 31 +- Copying data unit 0 (BSN 8) msg block (BSN 8, CS-1): 07 00 10 1f 43 4b 45 54 20 31 31 4c 4c 43 20 50 41 43 4b 45 54 20 31 Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654314 block=6 data=00 00 10 1f 43 4b 45 54 20 31 31 4c 4c 43 20 50 41 43 4b 45 54 20 31 Received RTS on disabled PDCH: TRX=0 TS=0 @@ -2507,6 +2548,7 @@ Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) -- Chunk with length 13 larger than space (4) left in block: copy only remaining space, and we are done data block (BSN 9, CS-1): 06 37 32 4c 4c 43 20 50 41 43 4b 45 54 20 31 33 4c 4c 43 20 +- Copying data unit 0 (BSN 9) msg block (BSN 9, CS-1): 07 00 12 06 37 32 4c 4c 43 20 50 41 43 4b 45 54 20 31 33 4c 4c 43 20 Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654318 block=7 data=00 00 12 06 37 32 4c 4c 43 20 50 41 43 4b 45 54 20 31 33 4c 4c 43 20 Received RTS on disabled PDCH: TRX=0 TS=0 @@ -2525,6 +2567,7 @@ Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) -- Chunk with length 13 larger than space (10) left in block: copy only remaining space, and we are done data block (BSN 10, CS-1): 27 50 41 43 4b 45 54 20 31 34 4c 4c 43 20 50 41 43 4b 45 54 +- Copying data unit 0 (BSN 10) msg block (BSN 10, CS-1): 07 00 14 27 50 41 43 4b 45 54 20 31 34 4c 4c 43 20 50 41 43 4b 45 54 Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654322 block=8 data=00 00 14 27 50 41 43 4b 45 54 20 31 34 4c 4c 43 20 50 41 43 4b 45 54 Received RTS on disabled PDCH: TRX=0 TS=0 @@ -2546,6 +2589,7 @@ Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) -- Chunk with length 13 larger than space (2) left in block: copy only remaining space, and we are done data block (BSN 11, CS-1): 0e 37 20 31 35 4c 4c 43 20 50 41 43 4b 45 54 20 31 36 4c 4c +- Copying data unit 0 (BSN 11) msg block (BSN 11, CS-1): 07 00 16 0e 37 20 31 35 4c 4c 43 20 50 41 43 4b 45 54 20 31 36 4c 4c Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654327 block=9 data=00 00 16 0e 37 20 31 35 4c 4c 43 20 50 41 43 4b 45 54 20 31 36 4c 4c Received RTS on disabled PDCH: TRX=0 TS=0 @@ -2564,6 +2608,7 @@ Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) -- Chunk with length 13 larger than space (8) left in block: copy only remaining space, and we are done data block (BSN 12, CS-1): 2f 43 20 50 41 43 4b 45 54 20 31 37 4c 4c 43 20 50 41 43 4b +- Copying data unit 0 (BSN 12) msg block (BSN 12, CS-1): 07 00 18 2f 43 20 50 41 43 4b 45 54 20 31 37 4c 4c 43 20 50 41 43 4b Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654331 block=10 data=00 00 18 2f 43 20 50 41 43 4b 45 54 20 31 37 4c 4c 43 20 50 41 43 4b Received RTS on disabled PDCH: TRX=0 TS=0 @@ -2585,6 +2630,7 @@ Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) data block (BSN 13, CS-1): 16 35 45 54 20 31 38 4c 4c 43 20 50 41 43 4b 45 54 20 31 39 +- Copying data unit 0 (BSN 13) msg block (BSN 13, CS-1): 07 00 1a 16 35 45 54 20 31 38 4c 4c 43 20 50 41 43 4b 45 54 20 31 39 Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654335 block=11 data=00 00 1a 16 35 45 54 20 31 38 4c 4c 43 20 50 41 43 4b 45 54 20 31 39 Received RTS on disabled PDCH: TRX=0 TS=0 @@ -2603,6 +2649,7 @@ Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) -- Chunk with length 13 larger than space (6) left in block: copy only remaining space, and we are done data block (BSN 14, CS-1): 37 4c 4c 43 20 50 41 43 4b 45 54 20 32 30 4c 4c 43 20 50 41 +- Copying data unit 0 (BSN 14) msg block (BSN 14, CS-1): 07 00 1c 37 4c 4c 43 20 50 41 43 4b 45 54 20 32 30 4c 4c 43 20 50 41 Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654340 block=0 data=00 00 1c 37 4c 4c 43 20 50 41 43 4b 45 54 20 32 30 4c 4c 43 20 50 41 Received RTS on disabled PDCH: TRX=0 TS=0 @@ -2621,6 +2668,7 @@ Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) -- Chunk with length 13 larger than space (12) left in block: copy only remaining space, and we are done data block (BSN 15, CS-1): 1f 43 4b 45 54 20 32 31 4c 4c 43 20 50 41 43 4b 45 54 20 32 +- Copying data unit 0 (BSN 15) msg block (BSN 15, CS-1): 07 00 1e 1f 43 4b 45 54 20 32 31 4c 4c 43 20 50 41 43 4b 45 54 20 32 Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654344 block=1 data=00 00 1e 1f 43 4b 45 54 20 32 31 4c 4c 43 20 50 41 43 4b 45 54 20 32 Received RTS on disabled PDCH: TRX=0 TS=0 @@ -2642,6 +2690,7 @@ Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) -- Chunk with length 13 larger than space (4) left in block: copy only remaining space, and we are done data block (BSN 16, CS-1): 06 37 32 4c 4c 43 20 50 41 43 4b 45 54 20 32 33 4c 4c 43 20 +- Copying data unit 0 (BSN 16) msg block (BSN 16, CS-1): 07 00 20 06 37 32 4c 4c 43 20 50 41 43 4b 45 54 20 32 33 4c 4c 43 20 Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654348 block=2 data=00 00 20 06 37 32 4c 4c 43 20 50 41 43 4b 45 54 20 32 33 4c 4c 43 20 Received RTS on disabled PDCH: TRX=0 TS=0 @@ -2660,6 +2709,7 @@ Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) -- Chunk with length 13 larger than space (10) left in block: copy only remaining space, and we are done data block (BSN 17, CS-1): 27 50 41 43 4b 45 54 20 32 34 4c 4c 43 20 50 41 43 4b 45 54 +- Copying data unit 0 (BSN 17) msg block (BSN 17, CS-1): 07 00 22 27 50 41 43 4b 45 54 20 32 34 4c 4c 43 20 50 41 43 4b 45 54 Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654353 block=3 data=00 00 22 27 50 41 43 4b 45 54 20 32 34 4c 4c 43 20 50 41 43 4b 45 54 Received RTS on disabled PDCH: TRX=0 TS=0 @@ -2681,6 +2731,7 @@ Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) -- Chunk with length 13 larger than space (2) left in block: copy only remaining space, and we are done data block (BSN 18, CS-1): 0e 37 20 32 35 4c 4c 43 20 50 41 43 4b 45 54 20 32 36 4c 4c +- Copying data unit 0 (BSN 18) msg block (BSN 18, CS-1): 07 00 24 0e 37 20 32 35 4c 4c 43 20 50 41 43 4b 45 54 20 32 36 4c 4c Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654357 block=4 data=00 00 24 0e 37 20 32 35 4c 4c 43 20 50 41 43 4b 45 54 20 32 36 4c 4c Received RTS on disabled PDCH: TRX=0 TS=0 @@ -2699,6 +2750,7 @@ Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) -- Chunk with length 13 larger than space (8) left in block: copy only remaining space, and we are done data block (BSN 19, CS-1): 2f 43 20 50 41 43 4b 45 54 20 32 37 4c 4c 43 20 50 41 43 4b +- Copying data unit 0 (BSN 19) msg block (BSN 19, CS-1): 07 00 26 2f 43 20 50 41 43 4b 45 54 20 32 37 4c 4c 43 20 50 41 43 4b Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654361 block=5 data=00 00 26 2f 43 20 50 41 43 4b 45 54 20 32 37 4c 4c 43 20 50 41 43 4b Received RTS on disabled PDCH: TRX=0 TS=0 @@ -2720,6 +2772,7 @@ Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) data block (BSN 20, CS-1): 16 35 45 54 20 32 38 4c 4c 43 20 50 41 43 4b 45 54 20 32 39 +- Copying data unit 0 (BSN 20) - Scheduling Ack/Nack polling, because 20 blocks sent. TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW): Scheduling polling at FN 2654379 TS 7 Polling scheduled in this TS 7 @@ -2742,6 +2795,7 @@ Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) -- Chunk with length 13 larger than space (6) left in block: copy only remaining space, and we are done data block (BSN 21, CS-1): 37 4c 4c 43 20 50 41 43 4b 45 54 20 33 30 4c 4c 43 20 50 41 +- Copying data unit 0 (BSN 21) msg block (BSN 21, CS-1): 07 00 2a 37 4c 4c 43 20 50 41 43 4b 45 54 20 33 30 4c 4c 43 20 50 41 Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654370 block=7 data=00 00 2a 37 4c 4c 43 20 50 41 43 4b 45 54 20 33 30 4c 4c 43 20 50 41 Received RTS on disabled PDCH: TRX=0 TS=0 @@ -2760,6 +2814,7 @@ Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) -- Chunk with length 13 larger than space (12) left in block: copy only remaining space, and we are done data block (BSN 22, CS-1): 1f 43 4b 45 54 20 33 31 4c 4c 43 20 50 41 43 4b 45 54 20 33 +- Copying data unit 0 (BSN 22) msg block (BSN 22, CS-1): 07 00 2c 1f 43 4b 45 54 20 33 31 4c 4c 43 20 50 41 43 4b 45 54 20 33 Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654374 block=8 data=07 00 2c 1f 43 4b 45 54 20 33 31 4c 4c 43 20 50 41 43 4b 45 54 20 33 Received RTS on disabled PDCH: TRX=0 TS=0 @@ -2781,6 +2836,7 @@ Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) -- Chunk with length 13 larger than space (4) left in block: copy only remaining space, and we are done data block (BSN 23, CS-1): 06 37 32 4c 4c 43 20 50 41 43 4b 45 54 20 33 33 4c 4c 43 20 +- Copying data unit 0 (BSN 23) msg block (BSN 23, CS-1): 07 00 2e 06 37 32 4c 4c 43 20 50 41 43 4b 45 54 20 33 33 4c 4c 43 20 Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654379 block=9 data=00 00 2e 06 37 32 4c 4c 43 20 50 41 43 4b 45 54 20 33 33 4c 4c 43 20 Received RTS on disabled PDCH: TRX=0 TS=0 @@ -2799,6 +2855,7 @@ Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) -- Chunk with length 13 larger than space (10) left in block: copy only remaining space, and we are done data block (BSN 24, CS-1): 27 50 41 43 4b 45 54 20 33 34 4c 4c 43 20 50 41 43 4b 45 54 +- Copying data unit 0 (BSN 24) msg block (BSN 24, CS-1): 07 00 30 27 50 41 43 4b 45 54 20 33 34 4c 4c 43 20 50 41 43 4b 45 54 Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654383 block=10 data=00 00 30 27 50 41 43 4b 45 54 20 33 34 4c 4c 43 20 50 41 43 4b 45 54 Received RTS on disabled PDCH: TRX=0 TS=0 @@ -2820,6 +2877,7 @@ Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) -- Chunk with length 13 larger than space (2) left in block: copy only remaining space, and we are done data block (BSN 25, CS-1): 0e 37 20 33 35 4c 4c 43 20 50 41 43 4b 45 54 20 33 36 4c 4c +- Copying data unit 0 (BSN 25) msg block (BSN 25, CS-1): 07 00 32 0e 37 20 33 35 4c 4c 43 20 50 41 43 4b 45 54 20 33 36 4c 4c Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654387 block=11 data=00 00 32 0e 37 20 33 35 4c 4c 43 20 50 41 43 4b 45 54 20 33 36 4c 4c Received RTS on disabled PDCH: TRX=0 TS=0 @@ -2838,6 +2896,7 @@ Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) -- Chunk with length 13 larger than space (8) left in block: copy only remaining space, and we are done data block (BSN 26, CS-1): 2f 43 20 50 41 43 4b 45 54 20 33 37 4c 4c 43 20 50 41 43 4b +- Copying data unit 0 (BSN 26) msg block (BSN 26, CS-1): 07 00 34 2f 43 20 50 41 43 4b 45 54 20 33 37 4c 4c 43 20 50 41 43 4b Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654392 block=0 data=00 00 34 2f 43 20 50 41 43 4b 45 54 20 33 37 4c 4c 43 20 50 41 43 4b Received RTS on disabled PDCH: TRX=0 TS=0 @@ -2859,6 +2918,7 @@ Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) changes state from FLOW to FINISHED data block (BSN 27, CS-1): 16 35 45 54 20 33 38 4c 4c 43 20 50 41 43 4b 45 54 20 33 39 +- Copying data unit 0 (BSN 27) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FINISHED) msg block (BSN 27, CS-1): 07 01 36 16 35 45 54 20 33 38 4c 4c 43 20 50 41 43 4b 45 54 20 33 39 @@ -2968,6 +3028,7 @@ TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==0) - Sending new block at BSN 0, CS=CS-1 -- Chunk with length 21 larger than space (20) left in block: copy only remaining space, and we are done data block (BSN 0, CS-1): 4c 4c 43 20 50 41 43 4b 45 54 20 30 30 20 28 54 42 46 20 32 +- Copying data unit 0 (BSN 0) msg block (BSN 0, CS-1): 07 02 01 4c 4c 43 20 50 41 43 4b 45 54 20 30 30 20 28 54 42 46 20 32 Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654405 block=3 data=00 02 01 4c 4c 43 20 50 41 43 4b 45 54 20 30 30 20 28 54 42 46 20 32 Received RTS on disabled PDCH: TRX=0 TS=0 @@ -2986,6 +3047,7 @@ Complete DL frame for TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=21 - Dequeue next LLC for TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=21) -- Chunk with length 21 larger than space (18) left in block: copy only remaining space, and we are done data block (BSN 1, CS-1): 07 29 4c 4c 43 20 50 41 43 4b 45 54 20 30 31 20 28 54 42 46 +- Copying data unit 0 (BSN 1) msg block (BSN 1, CS-1): 07 02 02 07 29 4c 4c 43 20 50 41 43 4b 45 54 20 30 31 20 28 54 42 46 Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654409 block=4 data=00 02 02 07 29 4c 4c 43 20 50 41 43 4b 45 54 20 30 31 20 28 54 42 46 Received RTS on disabled PDCH: TRX=0 TS=0 @@ -3004,6 +3066,7 @@ Complete DL frame for TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=21 - Dequeue next LLC for TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=21) -- Chunk with length 21 larger than space (16) left in block: copy only remaining space, and we are done data block (BSN 2, CS-1): 0f 20 32 29 4c 4c 43 20 50 41 43 4b 45 54 20 30 32 20 28 54 +- Copying data unit 0 (BSN 2) msg block (BSN 2, CS-1): 07 02 04 0f 20 32 29 4c 4c 43 20 50 41 43 4b 45 54 20 30 32 20 28 54 Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654413 block=5 data=00 02 04 0f 20 32 29 4c 4c 43 20 50 41 43 4b 45 54 20 30 32 20 28 54 Received RTS on disabled PDCH: TRX=0 TS=0 @@ -3022,6 +3085,7 @@ Complete DL frame for TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=21 - Dequeue next LLC for TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=21) -- Chunk with length 21 larger than space (14) left in block: copy only remaining space, and we are done data block (BSN 3, CS-1): 17 42 46 20 32 29 4c 4c 43 20 50 41 43 4b 45 54 20 30 33 20 +- Copying data unit 0 (BSN 3) msg block (BSN 3, CS-1): 07 02 06 17 42 46 20 32 29 4c 4c 43 20 50 41 43 4b 45 54 20 30 33 20 Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654418 block=6 data=00 02 06 17 42 46 20 32 29 4c 4c 43 20 50 41 43 4b 45 54 20 30 33 20 Received RTS on disabled PDCH: TRX=0 TS=0 @@ -3040,6 +3104,7 @@ Complete DL frame for TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=21 - Dequeue next LLC for TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=21) -- Chunk with length 21 larger than space (12) left in block: copy only remaining space, and we are done data block (BSN 4, CS-1): 1f 28 54 42 46 20 32 29 4c 4c 43 20 50 41 43 4b 45 54 20 30 +- Copying data unit 0 (BSN 4) msg block (BSN 4, CS-1): 07 02 08 1f 28 54 42 46 20 32 29 4c 4c 43 20 50 41 43 4b 45 54 20 30 Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654422 block=7 data=00 02 08 1f 28 54 42 46 20 32 29 4c 4c 43 20 50 41 43 4b 45 54 20 30 Received RTS on disabled PDCH: TRX=0 TS=0 @@ -3058,6 +3123,7 @@ Complete DL frame for TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=21 - Dequeue next LLC for TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=21) -- Chunk with length 21 larger than space (10) left in block: copy only remaining space, and we are done data block (BSN 5, CS-1): 27 34 20 28 54 42 46 20 32 29 4c 4c 43 20 50 41 43 4b 45 54 +- Copying data unit 0 (BSN 5) msg block (BSN 5, CS-1): 07 02 0a 27 34 20 28 54 42 46 20 32 29 4c 4c 43 20 50 41 43 4b 45 54 Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654426 block=8 data=00 02 0a 27 34 20 28 54 42 46 20 32 29 4c 4c 43 20 50 41 43 4b 45 54 Received RTS on disabled PDCH: TRX=0 TS=0 @@ -3076,6 +3142,7 @@ Complete DL frame for TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=21 - Dequeue next LLC for TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=21) -- Chunk with length 21 larger than space (8) left in block: copy only remaining space, and we are done data block (BSN 6, CS-1): 2f 20 30 35 20 28 54 42 46 20 32 29 4c 4c 43 20 50 41 43 4b +- Copying data unit 0 (BSN 6) msg block (BSN 6, CS-1): 07 02 0c 2f 20 30 35 20 28 54 42 46 20 32 29 4c 4c 43 20 50 41 43 4b Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654431 block=9 data=00 02 0c 2f 20 30 35 20 28 54 42 46 20 32 29 4c 4c 43 20 50 41 43 4b Received RTS on disabled PDCH: TRX=0 TS=0 @@ -3094,6 +3161,7 @@ Complete DL frame for TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=21 - Dequeue next LLC for TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=21) -- Chunk with length 21 larger than space (6) left in block: copy only remaining space, and we are done data block (BSN 7, CS-1): 37 45 54 20 30 36 20 28 54 42 46 20 32 29 4c 4c 43 20 50 41 +- Copying data unit 0 (BSN 7) msg block (BSN 7, CS-1): 07 02 0e 37 45 54 20 30 36 20 28 54 42 46 20 32 29 4c 4c 43 20 50 41 Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654435 block=10 data=00 02 0e 37 45 54 20 30 36 20 28 54 42 46 20 32 29 4c 4c 43 20 50 41 Received RTS on disabled PDCH: TRX=0 TS=0 @@ -3112,6 +3180,7 @@ Complete DL frame for TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=21 - Dequeue next LLC for TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=21) -- Chunk with length 21 larger than space (4) left in block: copy only remaining space, and we are done data block (BSN 8, CS-1): 3f 43 4b 45 54 20 30 37 20 28 54 42 46 20 32 29 4c 4c 43 20 +- Copying data unit 0 (BSN 8) msg block (BSN 8, CS-1): 07 02 10 3f 43 4b 45 54 20 30 37 20 28 54 42 46 20 32 29 4c 4c 43 20 Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654439 block=11 data=00 02 10 3f 43 4b 45 54 20 30 37 20 28 54 42 46 20 32 29 4c 4c 43 20 Received RTS on disabled PDCH: TRX=0 TS=0 @@ -3130,6 +3199,7 @@ Complete DL frame for TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=21 - Dequeue next LLC for TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=21) -- Chunk with length 21 larger than space (2) left in block: copy only remaining space, and we are done data block (BSN 9, CS-1): 47 50 41 43 4b 45 54 20 30 38 20 28 54 42 46 20 32 29 4c 4c +- Copying data unit 0 (BSN 9) msg block (BSN 9, CS-1): 07 02 12 47 50 41 43 4b 45 54 20 30 38 20 28 54 42 46 20 32 29 4c 4c Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654444 block=0 data=00 02 12 47 50 41 43 4b 45 54 20 30 38 20 28 54 42 46 20 32 29 4c 4c Received RTS on disabled PDCH: TRX=0 TS=0 @@ -3148,6 +3218,7 @@ TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==10) Complete DL frame for TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=21 TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW) changes state from FLOW to FINISHED data block (BSN 10, CS-1): 4d 43 20 50 41 43 4b 45 54 20 30 39 20 28 54 42 46 20 32 29 +- Copying data unit 0 (BSN 10) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FINISHED): Scheduling polling at FN 2654461 TS 7 Polling scheduled in this TS 7 @@ -3371,6 +3442,7 @@ Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=10 -- No space left, so we are done. Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=10 data block (BSN 0, MCS-1): 14 15 01 01 01 01 01 01 01 01 01 01 43 c0 01 2b 2b 2b 2b 2b 2b 2b +- Copying data unit 0 (BSN 0) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 0, MCS-1): 07 00 00 16 28 2a 02 02 02 02 02 02 02 02 02 02 86 80 03 56 56 56 56 56 56 56 00 @@ -3383,6 +3455,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==1) - Sending new block at BSN 1, CS=MCS-1 -- Chunk with length 512 larger than space (22) left in block: copy only remaining space, and we are done data block (BSN 1, MCS-1): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 1) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 1, MCS-1): 07 40 00 96 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 @@ -3392,6 +3465,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==2) - Sending new block at BSN 2, CS=MCS-1 -- Chunk with length 490 larger than space (22) left in block: copy only remaining space, and we are done data block (BSN 2, MCS-1): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 2) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 2, MCS-1): 07 80 00 96 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 @@ -3401,6 +3475,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==3) - Sending new block at BSN 3, CS=MCS-1 -- Chunk with length 468 larger than space (22) left in block: copy only remaining space, and we are done data block (BSN 3, MCS-1): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 3) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 3, MCS-1): 07 c0 00 96 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 @@ -3410,6 +3485,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==4) - Sending new block at BSN 4, CS=MCS-1 -- Chunk with length 446 larger than space (22) left in block: copy only remaining space, and we are done data block (BSN 4, MCS-1): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 4) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 4, MCS-1): 07 00 01 96 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 @@ -3419,6 +3495,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==5) - Sending new block at BSN 5, CS=MCS-1 -- Chunk with length 424 larger than space (22) left in block: copy only remaining space, and we are done data block (BSN 5, MCS-1): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 5) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 5, MCS-1): 07 40 01 96 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 @@ -3428,6 +3505,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==6) - Sending new block at BSN 6, CS=MCS-1 -- Chunk with length 402 larger than space (22) left in block: copy only remaining space, and we are done data block (BSN 6, MCS-1): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 6) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 6, MCS-1): 07 80 01 96 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 @@ -3437,6 +3515,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==7) - Sending new block at BSN 7, CS=MCS-1 -- Chunk with length 380 larger than space (22) left in block: copy only remaining space, and we are done data block (BSN 7, MCS-1): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 7) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 7, MCS-1): 07 c0 01 96 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 @@ -3446,6 +3525,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==8) - Sending new block at BSN 8, CS=MCS-1 -- Chunk with length 358 larger than space (22) left in block: copy only remaining space, and we are done data block (BSN 8, MCS-1): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 8) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 8, MCS-1): 07 00 02 96 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 @@ -3455,6 +3535,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==9) - Sending new block at BSN 9, CS=MCS-1 -- Chunk with length 336 larger than space (22) left in block: copy only remaining space, and we are done data block (BSN 9, MCS-1): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 9) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 9, MCS-1): 07 40 02 96 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 @@ -3464,6 +3545,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==10 - Sending new block at BSN 10, CS=MCS-1 -- Chunk with length 314 larger than space (22) left in block: copy only remaining space, and we are done data block (BSN 10, MCS-1): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 10) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 10, MCS-1): 07 80 02 96 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 @@ -3473,6 +3555,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==11 - Sending new block at BSN 11, CS=MCS-1 -- Chunk with length 292 larger than space (22) left in block: copy only remaining space, and we are done data block (BSN 11, MCS-1): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 11) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 11, MCS-1): 07 c0 02 96 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 @@ -3482,6 +3565,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==12 - Sending new block at BSN 12, CS=MCS-1 -- Chunk with length 270 larger than space (22) left in block: copy only remaining space, and we are done data block (BSN 12, MCS-1): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 12) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 12, MCS-1): 07 00 03 96 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 @@ -3491,6 +3575,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==13 - Sending new block at BSN 13, CS=MCS-1 -- Chunk with length 248 larger than space (22) left in block: copy only remaining space, and we are done data block (BSN 13, MCS-1): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 13) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 13, MCS-1): 07 40 03 96 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 @@ -3500,6 +3585,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==14 - Sending new block at BSN 14, CS=MCS-1 -- Chunk with length 226 larger than space (22) left in block: copy only remaining space, and we are done data block (BSN 14, MCS-1): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 14) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 14, MCS-1): 07 80 03 96 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 @@ -3509,6 +3595,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==15 - Sending new block at BSN 15, CS=MCS-1 -- Chunk with length 204 larger than space (22) left in block: copy only remaining space, and we are done data block (BSN 15, MCS-1): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 15) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 15, MCS-1): 07 c0 03 96 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 @@ -3518,6 +3605,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==16 - Sending new block at BSN 16, CS=MCS-1 -- Chunk with length 182 larger than space (22) left in block: copy only remaining space, and we are done data block (BSN 16, MCS-1): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 16) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 16, MCS-1): 07 00 04 96 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 @@ -3527,6 +3615,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==17 - Sending new block at BSN 17, CS=MCS-1 -- Chunk with length 160 larger than space (22) left in block: copy only remaining space, and we are done data block (BSN 17, MCS-1): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 17) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 17, MCS-1): 07 40 04 96 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 @@ -3536,6 +3625,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==18 - Sending new block at BSN 18, CS=MCS-1 -- Chunk with length 138 larger than space (22) left in block: copy only remaining space, and we are done data block (BSN 18, MCS-1): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 18) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 18, MCS-1): 07 80 04 96 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 @@ -3545,6 +3635,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==19 - Sending new block at BSN 19, CS=MCS-1 -- Chunk with length 116 larger than space (22) left in block: copy only remaining space, and we are done data block (BSN 19, MCS-1): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 19) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 19, MCS-1): 07 c0 04 96 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 @@ -3554,6 +3645,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==20 - Sending new block at BSN 20, CS=MCS-1 -- Chunk with length 94 larger than space (22) left in block: copy only remaining space, and we are done data block (BSN 20, MCS-1): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 20) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 20, MCS-1): 07 00 05 96 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 @@ -3563,6 +3655,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==21 - Sending new block at BSN 21, CS=MCS-1 -- Chunk with length 72 larger than space (22) left in block: copy only remaining space, and we are done data block (BSN 21, MCS-1): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 21) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 21, MCS-1): 07 40 05 96 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 @@ -3572,6 +3665,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==22 - Sending new block at BSN 22, CS=MCS-1 -- Chunk with length 50 larger than space (22) left in block: copy only remaining space, and we are done data block (BSN 22, MCS-1): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 22) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 22, MCS-1): 07 80 05 96 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 @@ -3581,6 +3675,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==23 - Sending new block at BSN 23, CS=MCS-1 -- Chunk with length 28 larger than space (22) left in block: copy only remaining space, and we are done data block (BSN 23, MCS-1): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 23) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 23, MCS-1): 07 c0 05 96 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 @@ -3595,6 +3690,7 @@ Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=512 -- No space left, so we are done. Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=14 data block (BSN 24, MCS-1): 0c 1d 01 01 01 01 01 01 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +- Copying data unit 0 (BSN 24) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 24, MCS-1): 07 00 06 16 18 3a 02 02 02 02 02 02 86 80 03 56 56 56 56 56 56 56 56 56 56 56 00 @@ -3654,6 +3750,7 @@ Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=10 -- No space left, so we are done. Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=16 data block (BSN 0, MCS-2): 14 21 01 01 01 01 01 01 01 01 01 01 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +- Copying data unit 0 (BSN 0) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 0, MCS-2): 07 00 00 12 28 42 02 02 02 02 02 02 02 02 02 02 86 80 03 56 56 56 56 56 56 56 56 56 56 56 56 56 00 @@ -3666,6 +3763,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==1) - Sending new block at BSN 1, CS=MCS-2 -- Chunk with length 512 larger than space (28) left in block: copy only remaining space, and we are done data block (BSN 1, MCS-2): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 1) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 1, MCS-2): 07 40 00 92 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 @@ -3675,6 +3773,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==2) - Sending new block at BSN 2, CS=MCS-2 -- Chunk with length 484 larger than space (28) left in block: copy only remaining space, and we are done data block (BSN 2, MCS-2): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 2) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 2, MCS-2): 07 80 00 92 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 @@ -3684,6 +3783,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==3) - Sending new block at BSN 3, CS=MCS-2 -- Chunk with length 456 larger than space (28) left in block: copy only remaining space, and we are done data block (BSN 3, MCS-2): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 3) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 3, MCS-2): 07 c0 00 92 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 @@ -3693,6 +3793,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==4) - Sending new block at BSN 4, CS=MCS-2 -- Chunk with length 428 larger than space (28) left in block: copy only remaining space, and we are done data block (BSN 4, MCS-2): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 4) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 4, MCS-2): 07 00 01 92 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 @@ -3702,6 +3803,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==5) - Sending new block at BSN 5, CS=MCS-2 -- Chunk with length 400 larger than space (28) left in block: copy only remaining space, and we are done data block (BSN 5, MCS-2): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 5) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 5, MCS-2): 07 40 01 92 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 @@ -3711,6 +3813,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==6) - Sending new block at BSN 6, CS=MCS-2 -- Chunk with length 372 larger than space (28) left in block: copy only remaining space, and we are done data block (BSN 6, MCS-2): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 6) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 6, MCS-2): 07 80 01 92 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 @@ -3720,6 +3823,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==7) - Sending new block at BSN 7, CS=MCS-2 -- Chunk with length 344 larger than space (28) left in block: copy only remaining space, and we are done data block (BSN 7, MCS-2): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 7) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 7, MCS-2): 07 c0 01 92 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 @@ -3729,6 +3833,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==8) - Sending new block at BSN 8, CS=MCS-2 -- Chunk with length 316 larger than space (28) left in block: copy only remaining space, and we are done data block (BSN 8, MCS-2): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 8) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 8, MCS-2): 07 00 02 92 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 @@ -3738,6 +3843,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==9) - Sending new block at BSN 9, CS=MCS-2 -- Chunk with length 288 larger than space (28) left in block: copy only remaining space, and we are done data block (BSN 9, MCS-2): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 9) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 9, MCS-2): 07 40 02 92 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 @@ -3747,6 +3853,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==10 - Sending new block at BSN 10, CS=MCS-2 -- Chunk with length 260 larger than space (28) left in block: copy only remaining space, and we are done data block (BSN 10, MCS-2): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 10) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 10, MCS-2): 07 80 02 92 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 @@ -3756,6 +3863,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==11 - Sending new block at BSN 11, CS=MCS-2 -- Chunk with length 232 larger than space (28) left in block: copy only remaining space, and we are done data block (BSN 11, MCS-2): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 11) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 11, MCS-2): 07 c0 02 92 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 @@ -3765,6 +3873,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==12 - Sending new block at BSN 12, CS=MCS-2 -- Chunk with length 204 larger than space (28) left in block: copy only remaining space, and we are done data block (BSN 12, MCS-2): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 12) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 12, MCS-2): 07 00 03 92 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 @@ -3774,6 +3883,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==13 - Sending new block at BSN 13, CS=MCS-2 -- Chunk with length 176 larger than space (28) left in block: copy only remaining space, and we are done data block (BSN 13, MCS-2): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 13) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 13, MCS-2): 07 40 03 92 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 @@ -3783,6 +3893,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==14 - Sending new block at BSN 14, CS=MCS-2 -- Chunk with length 148 larger than space (28) left in block: copy only remaining space, and we are done data block (BSN 14, MCS-2): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 14) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 14, MCS-2): 07 80 03 92 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 @@ -3792,6 +3903,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==15 - Sending new block at BSN 15, CS=MCS-2 -- Chunk with length 120 larger than space (28) left in block: copy only remaining space, and we are done data block (BSN 15, MCS-2): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 15) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 15, MCS-2): 07 c0 03 92 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 @@ -3801,6 +3913,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==16 - Sending new block at BSN 16, CS=MCS-2 -- Chunk with length 92 larger than space (28) left in block: copy only remaining space, and we are done data block (BSN 16, MCS-2): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 16) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 16, MCS-2): 07 00 04 92 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 @@ -3810,6 +3923,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==17 - Sending new block at BSN 17, CS=MCS-2 -- Chunk with length 64 larger than space (28) left in block: copy only remaining space, and we are done data block (BSN 17, MCS-2): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 17) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 17, MCS-2): 07 40 04 92 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 @@ -3819,6 +3933,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==18 - Sending new block at BSN 18, CS=MCS-2 -- Chunk with length 36 larger than space (28) left in block: copy only remaining space, and we are done data block (BSN 18, MCS-2): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 18) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 18, MCS-2): 07 80 04 92 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 @@ -3833,6 +3948,7 @@ Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=512 -- No space left, so we are done. Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=18 data block (BSN 19, MCS-2): 10 25 01 01 01 01 01 01 01 01 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +- Copying data unit 0 (BSN 19) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 19, MCS-2): 07 c0 04 12 20 4a 02 02 02 02 02 02 02 02 86 80 03 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 00 @@ -3892,6 +4008,7 @@ Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=10 -- No space left, so we are done. Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=25 data block (BSN 0, MCS-3): 14 33 01 01 01 01 01 01 01 01 01 01 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +- Copying data unit 0 (BSN 0) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 0, MCS-3): 07 00 00 06 28 66 02 02 02 02 02 02 02 02 02 02 86 80 03 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 00 @@ -3904,6 +4021,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==1) - Sending new block at BSN 1, CS=MCS-3 -- Chunk with length 512 larger than space (37) left in block: copy only remaining space, and we are done data block (BSN 1, MCS-3): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 1) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 1, MCS-3): 07 40 00 86 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 @@ -3913,6 +4031,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==2) - Sending new block at BSN 2, CS=MCS-3 -- Chunk with length 475 larger than space (37) left in block: copy only remaining space, and we are done data block (BSN 2, MCS-3): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 2) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 2, MCS-3): 07 80 00 86 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 @@ -3922,6 +4041,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==3) - Sending new block at BSN 3, CS=MCS-3 -- Chunk with length 438 larger than space (37) left in block: copy only remaining space, and we are done data block (BSN 3, MCS-3): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 3) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 3, MCS-3): 07 c0 00 86 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 @@ -3931,6 +4051,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==4) - Sending new block at BSN 4, CS=MCS-3 -- Chunk with length 401 larger than space (37) left in block: copy only remaining space, and we are done data block (BSN 4, MCS-3): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 4) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 4, MCS-3): 07 00 01 86 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 @@ -3940,6 +4061,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==5) - Sending new block at BSN 5, CS=MCS-3 -- Chunk with length 364 larger than space (37) left in block: copy only remaining space, and we are done data block (BSN 5, MCS-3): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 5) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 5, MCS-3): 07 40 01 86 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 @@ -3949,6 +4071,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==6) - Sending new block at BSN 6, CS=MCS-3 -- Chunk with length 327 larger than space (37) left in block: copy only remaining space, and we are done data block (BSN 6, MCS-3): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 6) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 6, MCS-3): 07 80 01 86 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 @@ -3958,6 +4081,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==7) - Sending new block at BSN 7, CS=MCS-3 -- Chunk with length 290 larger than space (37) left in block: copy only remaining space, and we are done data block (BSN 7, MCS-3): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 7) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 7, MCS-3): 07 c0 01 86 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 @@ -3967,6 +4091,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==8) - Sending new block at BSN 8, CS=MCS-3 -- Chunk with length 253 larger than space (37) left in block: copy only remaining space, and we are done data block (BSN 8, MCS-3): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 8) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 8, MCS-3): 07 00 02 86 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 @@ -3976,6 +4101,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==9) - Sending new block at BSN 9, CS=MCS-3 -- Chunk with length 216 larger than space (37) left in block: copy only remaining space, and we are done data block (BSN 9, MCS-3): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 9) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 9, MCS-3): 07 40 02 86 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 @@ -3985,6 +4111,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==10 - Sending new block at BSN 10, CS=MCS-3 -- Chunk with length 179 larger than space (37) left in block: copy only remaining space, and we are done data block (BSN 10, MCS-3): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 10) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 10, MCS-3): 07 80 02 86 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 @@ -3994,6 +4121,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==11 - Sending new block at BSN 11, CS=MCS-3 -- Chunk with length 142 larger than space (37) left in block: copy only remaining space, and we are done data block (BSN 11, MCS-3): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 11) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 11, MCS-3): 07 c0 02 86 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 @@ -4003,6 +4131,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==12 - Sending new block at BSN 12, CS=MCS-3 -- Chunk with length 105 larger than space (37) left in block: copy only remaining space, and we are done data block (BSN 12, MCS-3): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 12) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 12, MCS-3): 07 00 03 86 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 @@ -4012,6 +4141,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==13 - Sending new block at BSN 13, CS=MCS-3 -- Chunk with length 68 larger than space (37) left in block: copy only remaining space, and we are done data block (BSN 13, MCS-3): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 13) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 13, MCS-3): 07 40 03 86 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 @@ -4024,6 +4154,7 @@ Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=512 -- Empty chunk, added LLC dummy command of size 6, drained_since=0 -- Chunk with length 6 larger than space (5) left in block: copy only remaining space, and we are done data block (BSN 14, MCS-3): 3f 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 43 c0 01 2b 2b +- Copying data unit 0 (BSN 14) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 14, MCS-3): 07 80 03 06 7e 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 86 80 03 56 56 00 @@ -4038,6 +4169,7 @@ Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=6 -- No space left, so we are done. Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=34 data block (BSN 15, MCS-3): 02 45 2b 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +- Copying data unit 0 (BSN 15) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 15, MCS-3): 07 c0 03 06 04 8a 56 86 80 03 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 00 @@ -4097,6 +4229,7 @@ Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=10 -- No space left, so we are done. Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=32 data block (BSN 0, MCS-4): 14 41 01 01 01 01 01 01 01 01 01 01 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +- Copying data unit 0 (BSN 0) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 0, MCS-4): 07 00 00 00 28 82 02 02 02 02 02 02 02 02 02 02 86 80 03 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 00 @@ -4109,6 +4242,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==1) - Sending new block at BSN 1, CS=MCS-4 -- Chunk with length 512 larger than space (44) left in block: copy only remaining space, and we are done data block (BSN 1, MCS-4): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 1) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 1, MCS-4): 07 40 00 80 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 @@ -4118,6 +4252,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==2) - Sending new block at BSN 2, CS=MCS-4 -- Chunk with length 468 larger than space (44) left in block: copy only remaining space, and we are done data block (BSN 2, MCS-4): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 2) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 2, MCS-4): 07 80 00 80 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 @@ -4127,6 +4262,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==3) - Sending new block at BSN 3, CS=MCS-4 -- Chunk with length 424 larger than space (44) left in block: copy only remaining space, and we are done data block (BSN 3, MCS-4): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 3) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 3, MCS-4): 07 c0 00 80 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 @@ -4136,6 +4272,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==4) - Sending new block at BSN 4, CS=MCS-4 -- Chunk with length 380 larger than space (44) left in block: copy only remaining space, and we are done data block (BSN 4, MCS-4): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 4) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 4, MCS-4): 07 00 01 80 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 @@ -4145,6 +4282,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==5) - Sending new block at BSN 5, CS=MCS-4 -- Chunk with length 336 larger than space (44) left in block: copy only remaining space, and we are done data block (BSN 5, MCS-4): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 5) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 5, MCS-4): 07 40 01 80 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 @@ -4154,6 +4292,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==6) - Sending new block at BSN 6, CS=MCS-4 -- Chunk with length 292 larger than space (44) left in block: copy only remaining space, and we are done data block (BSN 6, MCS-4): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 6) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 6, MCS-4): 07 80 01 80 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 @@ -4163,6 +4302,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==7) - Sending new block at BSN 7, CS=MCS-4 -- Chunk with length 248 larger than space (44) left in block: copy only remaining space, and we are done data block (BSN 7, MCS-4): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 7) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 7, MCS-4): 07 c0 01 80 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 @@ -4172,6 +4312,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==8) - Sending new block at BSN 8, CS=MCS-4 -- Chunk with length 204 larger than space (44) left in block: copy only remaining space, and we are done data block (BSN 8, MCS-4): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 8) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 8, MCS-4): 07 00 02 80 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 @@ -4181,6 +4322,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==9) - Sending new block at BSN 9, CS=MCS-4 -- Chunk with length 160 larger than space (44) left in block: copy only remaining space, and we are done data block (BSN 9, MCS-4): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 9) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 9, MCS-4): 07 40 02 80 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 @@ -4190,6 +4332,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==10 - Sending new block at BSN 10, CS=MCS-4 -- Chunk with length 116 larger than space (44) left in block: copy only remaining space, and we are done data block (BSN 10, MCS-4): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 10) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 10, MCS-4): 07 80 02 80 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 @@ -4199,6 +4342,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==11 - Sending new block at BSN 11, CS=MCS-4 -- Chunk with length 72 larger than space (44) left in block: copy only remaining space, and we are done data block (BSN 11, MCS-4): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 11) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 11, MCS-4): 07 c0 02 80 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 00 @@ -4213,6 +4357,7 @@ Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=512 -- No space left, so we are done. Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=14 data block (BSN 12, MCS-4): 38 1d 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +- Copying data unit 0 (BSN 12) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 12, MCS-4): 07 00 03 00 70 3a 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 86 80 03 56 56 56 56 56 56 56 56 56 56 56 00 @@ -4272,6 +4417,7 @@ Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=10 -- No space left, so we are done. Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=44 data block (BSN 0, MCS-5): 14 59 01 01 01 01 01 01 01 01 01 01 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +- Copying data unit 0 (BSN 0) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 0, MCS-5): 07 00 00 08 45 56 40 40 40 40 40 40 40 40 40 c0 10 70 c0 ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca 0a @@ -4284,6 +4430,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==1) - Sending new block at BSN 1, CS=MCS-5 -- Chunk with length 512 larger than space (56) left in block: copy only remaining space, and we are done data block (BSN 1, MCS-5): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 1) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 1, MCS-5): 07 40 00 58 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 @@ -4293,6 +4440,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==2) - Sending new block at BSN 2, CS=MCS-5 -- Chunk with length 456 larger than space (56) left in block: copy only remaining space, and we are done data block (BSN 2, MCS-5): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 2) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 2, MCS-5): 07 80 00 58 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 @@ -4302,6 +4450,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==3) - Sending new block at BSN 3, CS=MCS-5 -- Chunk with length 400 larger than space (56) left in block: copy only remaining space, and we are done data block (BSN 3, MCS-5): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 3) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 3, MCS-5): 07 c0 00 58 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 @@ -4311,6 +4460,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==4) - Sending new block at BSN 4, CS=MCS-5 -- Chunk with length 344 larger than space (56) left in block: copy only remaining space, and we are done data block (BSN 4, MCS-5): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 4) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 4, MCS-5): 07 00 01 58 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 @@ -4320,6 +4470,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==5) - Sending new block at BSN 5, CS=MCS-5 -- Chunk with length 288 larger than space (56) left in block: copy only remaining space, and we are done data block (BSN 5, MCS-5): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 5) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 5, MCS-5): 07 40 01 58 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 @@ -4329,6 +4480,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==6) - Sending new block at BSN 6, CS=MCS-5 -- Chunk with length 232 larger than space (56) left in block: copy only remaining space, and we are done data block (BSN 6, MCS-5): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 6) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 6, MCS-5): 07 80 01 58 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 @@ -4338,6 +4490,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==7) - Sending new block at BSN 7, CS=MCS-5 -- Chunk with length 176 larger than space (56) left in block: copy only remaining space, and we are done data block (BSN 7, MCS-5): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 7) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 7, MCS-5): 07 c0 01 58 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 @@ -4347,6 +4500,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==8) - Sending new block at BSN 8, CS=MCS-5 -- Chunk with length 120 larger than space (56) left in block: copy only remaining space, and we are done data block (BSN 8, MCS-5): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 8) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 8, MCS-5): 07 00 02 58 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 @@ -4356,6 +4510,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==9) - Sending new block at BSN 9, CS=MCS-5 -- Chunk with length 64 larger than space (56) left in block: copy only remaining space, and we are done data block (BSN 9, MCS-5): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 9) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 9, MCS-5): 07 40 02 58 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 @@ -4370,6 +4525,7 @@ Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=512 -- No space left, so we are done. Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=46 data block (BSN 10, MCS-5): 10 5d 01 01 01 01 01 01 01 01 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +- Copying data unit 0 (BSN 10) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 10, MCS-5): 07 80 02 08 44 57 40 40 40 40 40 40 40 c0 10 70 c0 ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca 0a @@ -4429,6 +4585,7 @@ Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=10 -- No space left, so we are done. Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=62 data block (BSN 0, MCS-6): 14 7d 01 01 01 01 01 01 01 01 01 01 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +- Copying data unit 0 (BSN 0) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 0, MCS-6): 07 00 00 00 45 5f 40 40 40 40 40 40 40 40 40 c0 10 70 c0 ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca 0a @@ -4441,6 +4598,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==1) - Sending new block at BSN 1, CS=MCS-6 -- Chunk with length 512 larger than space (74) left in block: copy only remaining space, and we are done data block (BSN 1, MCS-6): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 1) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 1, MCS-6): 07 40 00 50 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 @@ -4450,6 +4608,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==2) - Sending new block at BSN 2, CS=MCS-6 -- Chunk with length 438 larger than space (74) left in block: copy only remaining space, and we are done data block (BSN 2, MCS-6): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 2) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 2, MCS-6): 07 80 00 50 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 @@ -4459,6 +4618,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==3) - Sending new block at BSN 3, CS=MCS-6 -- Chunk with length 364 larger than space (74) left in block: copy only remaining space, and we are done data block (BSN 3, MCS-6): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 3) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 3, MCS-6): 07 c0 00 50 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 @@ -4468,6 +4628,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==4) - Sending new block at BSN 4, CS=MCS-6 -- Chunk with length 290 larger than space (74) left in block: copy only remaining space, and we are done data block (BSN 4, MCS-6): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 4) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 4, MCS-6): 07 00 01 50 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 @@ -4477,6 +4638,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==5) - Sending new block at BSN 5, CS=MCS-6 -- Chunk with length 216 larger than space (74) left in block: copy only remaining space, and we are done data block (BSN 5, MCS-6): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 5) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 5, MCS-6): 07 40 01 50 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 @@ -4486,6 +4648,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==6) - Sending new block at BSN 6, CS=MCS-6 -- Chunk with length 142 larger than space (74) left in block: copy only remaining space, and we are done data block (BSN 6, MCS-6): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 6) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 6, MCS-6): 07 80 01 50 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 @@ -4498,6 +4661,7 @@ Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=512 -- Empty chunk, added LLC dummy command of size 6, drained_since=0 -- Chunk with length 6 larger than space (5) left in block: copy only remaining space, and we are done data block (BSN 7, MCS-6): 89 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 43 c0 01 2b 2b +- Copying data unit 0 (BSN 7) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 7, MCS-6): 07 c0 01 40 62 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 c0 10 70 c0 ca 0a @@ -4512,6 +4676,7 @@ Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=6 -- No space left, so we are done. Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=71 data block (BSN 8, MCS-6): 02 8f 2b 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +- Copying data unit 0 (BSN 8) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 8, MCS-6): 07 00 02 80 c0 e3 ca 10 70 c0 ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca 0a @@ -4571,10 +4736,11 @@ Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=10 -- No space left, so we are done. Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=44 data block (BSN 0, MCS-7): 14 59 01 01 01 01 01 01 01 01 01 01 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +- Copying data unit 0 (BSN 0) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) -msg block (BSN 0, MCS-7): 07 00 00 00 a0 50 64 05 04 04 04 04 04 04 04 04 04 0c 01 07 ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=4 block=1 data=07 00 00 00 a0 50 64 05 04 04 04 04 04 04 04 04 04 0c 01 07 ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +msg block (BSN 0, MCS-5): 07 00 00 08 45 56 40 40 40 40 40 40 40 40 40 c0 10 70 c0 ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca 0a +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=4 block=1 data=07 00 00 08 45 56 40 40 40 40 40 40 40 40 40 c0 10 70 c0 ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca 0a TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) append Received RTS for PDCH: TRX=0 TS=4 FN=8 block_nr=2 scheduling free USF for polling at FN=13 of TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 @@ -4583,82 +4749,91 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==1) - Sending new block at BSN 1, CS=MCS-7 -- Chunk with length 512 larger than space (56) left in block: copy only remaining space, and we are done data block (BSN 1, MCS-7): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 1) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) -msg block (BSN 1, MCS-7): 07 40 00 fe a7 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=8 block=2 data=07 40 00 fe a7 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +msg block (BSN 1, MCS-5): 07 40 00 58 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=8 block=2 data=07 40 00 58 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==2) - Sending new block at BSN 2, CS=MCS-7 -- Chunk with length 456 larger than space (56) left in block: copy only remaining space, and we are done data block (BSN 2, MCS-7): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 2) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) -msg block (BSN 2, MCS-7): 07 80 00 fc a7 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=13 block=3 data=07 80 00 fc a7 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +msg block (BSN 2, MCS-5): 07 80 00 58 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=13 block=3 data=07 80 00 58 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==3) - Sending new block at BSN 3, CS=MCS-7 -- Chunk with length 400 larger than space (56) left in block: copy only remaining space, and we are done data block (BSN 3, MCS-7): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 3) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) -msg block (BSN 3, MCS-7): 07 c0 00 fa a7 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=17 block=4 data=07 c0 00 fa a7 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +msg block (BSN 3, MCS-5): 07 c0 00 58 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=17 block=4 data=07 c0 00 58 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==4) - Sending new block at BSN 4, CS=MCS-7 -- Chunk with length 344 larger than space (56) left in block: copy only remaining space, and we are done data block (BSN 4, MCS-7): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 4) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) -msg block (BSN 4, MCS-7): 07 00 01 f8 a7 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=21 block=5 data=07 00 01 f8 a7 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +msg block (BSN 4, MCS-5): 07 00 01 58 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=21 block=5 data=07 00 01 58 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==5) - Sending new block at BSN 5, CS=MCS-7 -- Chunk with length 288 larger than space (56) left in block: copy only remaining space, and we are done data block (BSN 5, MCS-7): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 5) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) -msg block (BSN 5, MCS-7): 07 40 01 f6 a7 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=26 block=6 data=07 40 01 f6 a7 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +msg block (BSN 5, MCS-5): 07 40 01 58 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=26 block=6 data=07 40 01 58 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==6) - Sending new block at BSN 6, CS=MCS-7 -- Chunk with length 232 larger than space (56) left in block: copy only remaining space, and we are done data block (BSN 6, MCS-7): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 6) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) -msg block (BSN 6, MCS-7): 07 80 01 f4 a7 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=30 block=7 data=07 80 01 f4 a7 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +msg block (BSN 6, MCS-5): 07 80 01 58 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=30 block=7 data=07 80 01 58 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==7) - Sending new block at BSN 7, CS=MCS-7 -- Chunk with length 176 larger than space (56) left in block: copy only remaining space, and we are done data block (BSN 7, MCS-7): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 7) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) -msg block (BSN 7, MCS-7): 07 c0 01 f2 a7 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=34 block=8 data=07 c0 01 f2 a7 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +msg block (BSN 7, MCS-5): 07 c0 01 58 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=34 block=8 data=07 c0 01 58 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==8) - Sending new block at BSN 8, CS=MCS-7 -- Chunk with length 120 larger than space (56) left in block: copy only remaining space, and we are done data block (BSN 8, MCS-7): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 8) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) -msg block (BSN 8, MCS-7): 07 00 02 f0 a7 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=39 block=9 data=07 00 02 f0 a7 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +msg block (BSN 8, MCS-5): 07 00 02 58 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=39 block=9 data=07 00 02 58 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==9) - Sending new block at BSN 9, CS=MCS-7 -- Chunk with length 64 larger than space (56) left in block: copy only remaining space, and we are done data block (BSN 9, MCS-7): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 9) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) -msg block (BSN 9, MCS-7): 07 40 02 ee a7 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=43 block=10 data=07 40 02 ee a7 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +msg block (BSN 9, MCS-5): 07 40 02 58 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=43 block=10 data=07 40 02 58 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==10) - Sending new block at BSN 10, CS=MCS-7 @@ -4669,10 +4844,11 @@ Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=512 -- No space left, so we are done. Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=46 data block (BSN 10, MCS-7): 10 5d 01 01 01 01 01 01 01 01 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +- Copying data unit 0 (BSN 10) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) -msg block (BSN 10, MCS-7): 07 80 02 ec a7 40 74 05 04 04 04 04 04 04 04 0c 01 07 ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=47 block=11 data=07 80 02 ec a7 40 74 05 04 04 04 04 04 04 04 0c 01 07 ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +msg block (BSN 10, MCS-5): 07 80 02 08 44 57 40 40 40 40 40 40 40 c0 10 70 c0 ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca 0a +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=47 block=11 data=07 80 02 08 44 57 40 40 40 40 40 40 40 c0 10 70 c0 ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca 0a TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink acknowledge - Final ACK received. TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) changes state from FLOW to WAIT RELEASE @@ -4728,10 +4904,11 @@ Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=10 -- No space left, so we are done. Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=56 data block (BSN 0, MCS-8): 14 71 01 01 01 01 01 01 01 01 01 01 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +- Copying data unit 0 (BSN 0) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) -msg block (BSN 0, MCS-8): 07 00 00 00 58 50 c4 05 04 04 04 04 04 04 04 04 04 0c 01 07 ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=4 block=1 data=07 00 00 00 58 50 c4 05 04 04 04 04 04 04 04 04 04 0c 01 07 ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +msg block (BSN 0, MCS-6, padded): 07 00 00 04 00 00 00 00 00 00 45 5c 40 40 40 40 40 40 40 40 40 c0 10 70 c0 ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca 0a +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=4 block=1 data=07 00 00 04 00 00 00 00 00 00 45 5c 40 40 40 40 40 40 40 40 40 c0 10 70 c0 ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca 0a TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) append Received RTS for PDCH: TRX=0 TS=4 FN=8 block_nr=2 scheduling free USF for polling at FN=13 of TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 @@ -4740,64 +4917,71 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==1) - Sending new block at BSN 1, CS=MCS-8 -- Chunk with length 512 larger than space (68) left in block: copy only remaining space, and we are done data block (BSN 1, MCS-8): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 1) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) -msg block (BSN 1, MCS-8): 07 40 00 fe 5f 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=8 block=2 data=07 40 00 fe 5f 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +msg block (BSN 1, MCS-6, padded): 07 40 00 04 00 00 00 00 00 50 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=8 block=2 data=07 40 00 04 00 00 00 00 00 50 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==2) - Sending new block at BSN 2, CS=MCS-8 -- Chunk with length 444 larger than space (68) left in block: copy only remaining space, and we are done data block (BSN 2, MCS-8): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 2) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) -msg block (BSN 2, MCS-8): 07 80 00 fc 5f 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=13 block=3 data=07 80 00 fc 5f 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +msg block (BSN 2, MCS-6, padded): 07 80 00 04 00 00 00 00 00 50 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=13 block=3 data=07 80 00 04 00 00 00 00 00 50 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==3) - Sending new block at BSN 3, CS=MCS-8 -- Chunk with length 376 larger than space (68) left in block: copy only remaining space, and we are done data block (BSN 3, MCS-8): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 3) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) -msg block (BSN 3, MCS-8): 07 c0 00 fa 5f 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=17 block=4 data=07 c0 00 fa 5f 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +msg block (BSN 3, MCS-6, padded): 07 c0 00 04 00 00 00 00 00 50 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=17 block=4 data=07 c0 00 04 00 00 00 00 00 50 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==4) - Sending new block at BSN 4, CS=MCS-8 -- Chunk with length 308 larger than space (68) left in block: copy only remaining space, and we are done data block (BSN 4, MCS-8): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 4) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) -msg block (BSN 4, MCS-8): 07 00 01 f8 5f 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=21 block=5 data=07 00 01 f8 5f 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +msg block (BSN 4, MCS-6, padded): 07 00 01 04 00 00 00 00 00 50 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=21 block=5 data=07 00 01 04 00 00 00 00 00 50 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==5) - Sending new block at BSN 5, CS=MCS-8 -- Chunk with length 240 larger than space (68) left in block: copy only remaining space, and we are done data block (BSN 5, MCS-8): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 5) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) -msg block (BSN 5, MCS-8): 07 40 01 f6 5f 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=26 block=6 data=07 40 01 f6 5f 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +msg block (BSN 5, MCS-6, padded): 07 40 01 04 00 00 00 00 00 50 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=26 block=6 data=07 40 01 04 00 00 00 00 00 50 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==6) - Sending new block at BSN 6, CS=MCS-8 -- Chunk with length 172 larger than space (68) left in block: copy only remaining space, and we are done data block (BSN 6, MCS-8): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 6) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) -msg block (BSN 6, MCS-8): 07 80 01 f4 5f 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=30 block=7 data=07 80 01 f4 5f 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +msg block (BSN 6, MCS-6, padded): 07 80 01 04 00 00 00 00 00 50 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=30 block=7 data=07 80 01 04 00 00 00 00 00 50 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==7) - Sending new block at BSN 7, CS=MCS-8 -- Chunk with length 104 larger than space (68) left in block: copy only remaining space, and we are done data block (BSN 7, MCS-8): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 7) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) -msg block (BSN 7, MCS-8): 07 c0 01 f2 5f 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=34 block=8 data=07 c0 01 f2 5f 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +msg block (BSN 7, MCS-6, padded): 07 c0 01 04 00 00 00 00 00 50 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=34 block=8 data=07 c0 01 04 00 00 00 00 00 50 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==8) - Sending new block at BSN 8, CS=MCS-8 @@ -4808,10 +4992,11 @@ Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=512 -- No space left, so we are done. Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=30 data block (BSN 8, MCS-8): 48 3d 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +- Copying data unit 0 (BSN 8) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) -msg block (BSN 8, MCS-8): 07 00 02 f0 5f 20 f5 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 0c 01 07 ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=39 block=9 data=07 00 02 f0 5f 20 f5 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 0c 01 07 ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +msg block (BSN 8, MCS-6, padded): 07 00 02 04 00 00 00 00 00 00 52 4f 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 c0 10 70 c0 ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca 0a +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=39 block=9 data=07 00 02 04 00 00 00 00 00 00 52 4f 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 c0 10 70 c0 ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca 0a TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink acknowledge - Final ACK received. TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) changes state from FLOW to WAIT RELEASE @@ -4867,10 +5052,11 @@ Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=10 -- No space left, so we are done. Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=62 data block (BSN 0, MCS-9): 14 7d 01 01 01 01 01 01 01 01 01 01 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +- Copying data unit 0 (BSN 0) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) -msg block (BSN 0, MCS-9): 07 00 00 00 00 50 f4 05 04 04 04 04 04 04 04 04 04 0c 01 07 ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=4 block=1 data=07 00 00 00 00 50 f4 05 04 04 04 04 04 04 04 04 04 0c 01 07 ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +msg block (BSN 0, MCS-6): 07 00 00 00 45 5f 40 40 40 40 40 40 40 40 40 c0 10 70 c0 ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca 0a +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=4 block=1 data=07 00 00 00 45 5f 40 40 40 40 40 40 40 40 40 c0 10 70 c0 ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca 0a TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) append Received RTS for PDCH: TRX=0 TS=4 FN=8 block_nr=2 scheduling free USF for polling at FN=13 of TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 @@ -4879,55 +5065,61 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==1) - Sending new block at BSN 1, CS=MCS-9 -- Chunk with length 512 larger than space (74) left in block: copy only remaining space, and we are done data block (BSN 1, MCS-9): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 1) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) -msg block (BSN 1, MCS-9): 07 40 00 fe 07 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=8 block=2 data=07 40 00 fe 07 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +msg block (BSN 1, MCS-6): 07 40 00 50 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=8 block=2 data=07 40 00 50 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==2) - Sending new block at BSN 2, CS=MCS-9 -- Chunk with length 438 larger than space (74) left in block: copy only remaining space, and we are done data block (BSN 2, MCS-9): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 2) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) -msg block (BSN 2, MCS-9): 07 80 00 fc 07 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=13 block=3 data=07 80 00 fc 07 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +msg block (BSN 2, MCS-6): 07 80 00 50 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=13 block=3 data=07 80 00 50 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==3) - Sending new block at BSN 3, CS=MCS-9 -- Chunk with length 364 larger than space (74) left in block: copy only remaining space, and we are done data block (BSN 3, MCS-9): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 3) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) -msg block (BSN 3, MCS-9): 07 c0 00 fa 07 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=17 block=4 data=07 c0 00 fa 07 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +msg block (BSN 3, MCS-6): 07 c0 00 50 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=17 block=4 data=07 c0 00 50 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==4) - Sending new block at BSN 4, CS=MCS-9 -- Chunk with length 290 larger than space (74) left in block: copy only remaining space, and we are done data block (BSN 4, MCS-9): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 4) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) -msg block (BSN 4, MCS-9): 07 00 01 f8 07 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=21 block=5 data=07 00 01 f8 07 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +msg block (BSN 4, MCS-6): 07 00 01 50 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=21 block=5 data=07 00 01 50 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==5) - Sending new block at BSN 5, CS=MCS-9 -- Chunk with length 216 larger than space (74) left in block: copy only remaining space, and we are done data block (BSN 5, MCS-9): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 5) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) -msg block (BSN 5, MCS-9): 07 40 01 f6 07 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=26 block=6 data=07 40 01 f6 07 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +msg block (BSN 5, MCS-6): 07 40 01 50 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=26 block=6 data=07 40 01 50 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==6) - Sending new block at BSN 6, CS=MCS-9 -- Chunk with length 142 larger than space (74) left in block: copy only remaining space, and we are done data block (BSN 6, MCS-9): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +- Copying data unit 0 (BSN 6) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) -msg block (BSN 6, MCS-9): 07 80 01 f4 07 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=30 block=7 data=07 80 01 f4 07 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +msg block (BSN 6, MCS-6): 07 80 01 50 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=30 block=7 data=07 80 01 50 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==7) - Sending new block at BSN 7, CS=MCS-9 @@ -4936,10 +5128,11 @@ Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=512 -- Empty chunk, added LLC dummy command of size 6, drained_since=0 -- Chunk with length 6 larger than space (5) left in block: copy only remaining space, and we are done data block (BSN 7, MCS-9): 89 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 43 c0 01 2b 2b +- Copying data unit 0 (BSN 7) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) -msg block (BSN 7, MCS-9): 07 c0 01 f2 07 24 06 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 0c 01 07 ac ac 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=34 block=8 data=07 c0 01 f2 07 24 06 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 0c 01 07 ac ac 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +msg block (BSN 7, MCS-6): 07 c0 01 40 62 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 c0 10 70 c0 ca 0a +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=34 block=8 data=07 c0 01 40 62 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 c0 10 70 c0 ca 0a Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==8) - Sending new block at BSN 8, CS=MCS-9 @@ -4950,10 +5143,11 @@ Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=6 -- No space left, so we are done. Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=71 data block (BSN 8, MCS-9): 02 8f 2b 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +- Copying data unit 0 (BSN 8) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) -msg block (BSN 8, MCS-9): 07 00 02 f0 07 08 3c ae 0c 01 07 ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=39 block=9 data=07 00 02 f0 07 08 3c ae 0c 01 07 ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +msg block (BSN 8, MCS-6): 07 00 02 80 c0 e3 ca 10 70 c0 ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca 0a +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=39 block=9 data=07 00 02 80 c0 e3 ca 10 70 c0 ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca 0a TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink acknowledge - Final ACK received. TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) changes state from FLOW to WAIT RELEASE -- cgit v1.2.3 From d6752491e1facccf3cb022a6701532379a1f4e0c Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Tue, 2 Feb 2016 18:12:46 +0100 Subject: edge: Send a second BSN block in an RLC message if possible Currently only one BSN block is encoded in each RLC data message, even if MSC7-9 are used, which transport two independant (except for a max BSN delta of 512) BSN blocks. In that case, the same block is just put twice into the same message. The current create_dl_acked_block(fn, ts) method handles block selection (resend, new BSN, dummy block, ...) and restart handling in one method and is too complex to extend it accordingly. Therefore this commit move the block selection/creation handling into a new method (take_next_bsn) which delivers the next BSN along with a hint, whether it may be combined with another block. In that case, the function can be called a second time (this time with a valid previous BSN, that's the one returned by the first call) to get the second BSN. The real block generation method create_dl_acked_block(fn, ts, index, index2) is then called with both BSNs as indices (the second must be -1, if there is only one BSN). Note that every BSN returned by take_next_bsn should be passed to create_dl_acked_block to avoid state inconsistencies. Sponsored-by: On-Waves ehf --- src/rlc.h | 1 + src/tbf.h | 5 +- src/tbf_dl.cpp | 157 ++++++++++++++++++++++------------ tests/tbf/TbfTest.err | 230 ++++++++++++++++++++------------------------------ 4 files changed, 200 insertions(+), 193 deletions(-) diff --git a/src/rlc.h b/src/rlc.h index 28913bd0..54f28dfd 100644 --- a/src/rlc.h +++ b/src/rlc.h @@ -31,6 +31,7 @@ #define RLC_EGPRS_MIN_WS 64 /* min window size */ #define RLC_EGPRS_MAX_WS 1024 /* min window size */ #define RLC_EGPRS_SNS 2048 /* EGPRS, must be power of 2 */ +#define RLC_EGPRS_MAX_BSN_DELTA 512 #define RLC_MAX_SNS RLC_EGPRS_SNS #define RLC_MAX_WS RLC_EGPRS_MAX_WS #define RLC_MAX_LEN 74 /* MCS-9 data unit */ diff --git a/src/tbf.h b/src/tbf.h index 2eefbeea..6c030d23 100644 --- a/src/tbf.h +++ b/src/tbf.h @@ -406,7 +406,10 @@ protected: unsigned lost_bytes; }; - struct msgb *create_new_bsn(const uint32_t fn, const uint8_t ts); + int take_next_bsn(uint32_t fn, int previous_bsn, + GprsCodingScheme *next_cs); + bool restart_bsn_cycle(); + int create_new_bsn(const uint32_t fn, GprsCodingScheme cs); struct msgb *create_dl_acked_block(const uint32_t fn, const uint8_t ts, int index, int index2 = -1); int update_window(const uint8_t ssn, const uint8_t *rbb); diff --git a/src/tbf_dl.cpp b/src/tbf_dl.cpp index 21b2ba13..e2521f84 100644 --- a/src/tbf_dl.cpp +++ b/src/tbf_dl.cpp @@ -326,81 +326,136 @@ drop_frame: return msg; } -/* - * Create DL data block - * The messages are fragmented and forwarded as data blocks. - */ -struct msgb *gprs_rlcmac_dl_tbf::create_dl_acked_block(uint32_t fn, uint8_t ts) +bool gprs_rlcmac_dl_tbf::restart_bsn_cycle() { - LOGP(DRLCMACDL, LOGL_DEBUG, "%s downlink (V(A)==%d .. " - "V(S)==%d)\n", tbf_name(this), - m_window.v_a(), m_window.v_s()); + /* If V(S) == V(A) and finished state, we would have received + * acknowledgement of all transmitted block. In this case we would + * have transmitted the final block, and received ack from MS. But in + * this case we did not receive the final ack indication from MS. This + * should never happen if MS works correctly. + */ + if (m_window.window_empty()) { + LOGP(DRLCMACDL, LOGL_DEBUG, "- MS acked all blocks\n"); + return false; + } -do_resend: - /* check if there is a block with negative acknowledgement */ - int resend_bsn = m_window.resend_needed(); - if (resend_bsn >= 0) { - LOGP(DRLCMACDL, LOGL_DEBUG, "- Resending BSN %d\n", resend_bsn); - /* re-send block with negative aknowlegement */ - m_window.m_v_b.mark_unacked(resend_bsn); - bts->rlc_resent(); - return create_dl_acked_block(fn, ts, resend_bsn); + /* cycle through all unacked blocks */ + int resend = m_window.mark_for_resend(); + + /* At this point there should be at least one unacked block + * to be resent. If not, this is an software error. */ + if (resend == 0) { + LOGP(DRLCMACDL, LOGL_ERROR, "Software error: " + "There are no unacknowledged blocks, but V(A) " + " != V(S). PLEASE FIX!\n"); + return false; } - /* if the window has stalled, or transfer is complete, - * send an unacknowledged block */ - if (state_is(GPRS_RLCMAC_FINISHED)) { + return true; +} + +int gprs_rlcmac_dl_tbf::take_next_bsn(uint32_t fn, + int previous_bsn, GprsCodingScheme *next_cs) +{ + int bsn; + GprsCodingScheme cs2; + GprsCodingScheme force_cs; + + bsn = m_window.resend_needed(); + + if (previous_bsn >= 0) { + force_cs = m_rlc.block(previous_bsn)->cs; + if (!force_cs.isEgprs()) + return -1; + } + + if (bsn >= 0) { + if (previous_bsn == bsn) + return -1; + + if (previous_bsn >= 0 && + m_window.mod_sns(bsn - previous_bsn) > RLC_EGPRS_MAX_BSN_DELTA) + return -1; + + cs2 = m_rlc.block(bsn)->cs; + if (force_cs && !cs2.isCombinable(force_cs)) + return -1; + LOGP(DRLCMACDL, LOGL_DEBUG, "- Resending BSN %d\n", bsn); + /* re-send block with negative aknowlegement */ + m_window.m_v_b.mark_unacked(bsn); + bts->rlc_resent(); + } else if (state_is(GPRS_RLCMAC_FINISHED)) { LOGP(DRLCMACDL, LOGL_DEBUG, "- Restarting at BSN %d, " "because all blocks have been transmitted.\n", m_window.v_a()); bts->rlc_restarted(); + if (restart_bsn_cycle()) + return take_next_bsn(fn, previous_bsn, next_cs); } else if (dl_window_stalled()) { LOGP(DRLCMACDL, LOGL_NOTICE, "- Restarting at BSN %d, " - "because all window is stalled.\n", + "because the window is stalled.\n", m_window.v_a()); bts->rlc_stalled(); + if (restart_bsn_cycle()) + return take_next_bsn(fn, previous_bsn, next_cs); } else if (have_data()) { /* New blocks may be send */ - return create_new_bsn(fn, ts); + cs2 = force_cs ? force_cs : current_cs(); + LOGP(DRLCMACDL, LOGL_DEBUG, + "- Sending new block at BSN %d, CS=%s\n", + m_window.v_s(), cs2.name()); + + bsn = create_new_bsn(fn, cs2); } else if (!m_window.window_empty()) { LOGP(DRLCMACDL, LOGL_DEBUG, "- Restarting at BSN %d, " "because all blocks have been transmitted (FLOW).\n", m_window.v_a()); bts->rlc_restarted(); + if (restart_bsn_cycle()) + return take_next_bsn(fn, previous_bsn, next_cs); } else { /* Nothing left to send, create dummy LLC commands */ - return create_new_bsn(fn, ts); + LOGP(DRLCMACDL, LOGL_DEBUG, + "- Sending new dummy block at BSN %d, CS=%s\n", + m_window.v_s(), current_cs().name()); + bsn = create_new_bsn(fn, current_cs()); + /* Don't send a second block */ } - /* If V(S) == V(A) and finished state, we would have received - * acknowledgement of all transmitted block. In this case we - * would have transmitted the final block, and received ack - * from MS. But in this case we did not receive the final ack - * indication from MS. This should never happen if MS works - * correctly. */ - if (m_window.window_empty()) { - LOGP(DRLCMACDL, LOGL_DEBUG, "- MS acked all blocks, " - "so we re-transmit final block!\n"); + if (bsn < 0) { /* we just send final block again */ - int16_t index = m_window.v_s_mod(-1); + LOGP(DRLCMACDL, LOGL_DEBUG, + "- Nothing else to send, Re-transmit final block!\n"); + bsn = m_window.v_s_mod(-1); bts->rlc_resent(); - return create_dl_acked_block(fn, ts, index); } - /* cycle through all unacked blocks */ - int resend = m_window.mark_for_resend(); + *next_cs = cs2; - /* At this point there should be at least one unacked block - * to be resent. If not, this is an software error. */ - if (resend == 0) { - LOGP(DRLCMACDL, LOGL_ERROR, "Software error: " - "There are no unacknowledged blocks, but V(A) " - " != V(S). PLEASE FIX!\n"); - /* we just send final block again */ - int16_t index = m_window.v_s_mod(-1); - return create_dl_acked_block(fn, ts, index); - } - goto do_resend; + return bsn; +} + +/* + * Create DL data block + * The messages are fragmented and forwarded as data blocks. + */ +struct msgb *gprs_rlcmac_dl_tbf::create_dl_acked_block(uint32_t fn, uint8_t ts) +{ + int bsn, bsn2 = -1; + GprsCodingScheme cs, next_cs; + + LOGP(DRLCMACDL, LOGL_DEBUG, "%s downlink (V(A)==%d .. " + "V(S)==%d)\n", tbf_name(this), + m_window.v_a(), m_window.v_s()); + + bsn = take_next_bsn(fn, -1, &next_cs); + if (bsn < 0) + return NULL; + + if (next_cs.numDataBlocks() > 1) + bsn2 = take_next_bsn(fn, bsn, &next_cs); + + return create_dl_acked_block(fn, ts, bsn, bsn2); } void gprs_rlcmac_dl_tbf::schedule_next_frame() @@ -425,12 +480,11 @@ void gprs_rlcmac_dl_tbf::schedule_next_frame() m_last_dl_drained_fn = -1; } -struct msgb *gprs_rlcmac_dl_tbf::create_new_bsn(const uint32_t fn, const uint8_t ts) +int gprs_rlcmac_dl_tbf::create_new_bsn(const uint32_t fn, GprsCodingScheme cs) { uint8_t *data; gprs_rlc_data *rlc_data; const uint16_t bsn = m_window.v_s(); - GprsCodingScheme cs = current_cs(); gprs_rlc_data_block_info *rdbi; int num_chunks = 0; int write_offset = 0; @@ -439,9 +493,6 @@ struct msgb *gprs_rlcmac_dl_tbf::create_new_bsn(const uint32_t fn, const uint8_t if (m_llc.frame_length() == 0) schedule_next_frame(); - LOGP(DRLCMACDL, LOGL_DEBUG, "- Sending new block at BSN %d, CS=%s\n", - m_window.v_s(), cs.name()); - OSMO_ASSERT(cs.isValid()); /* length of usable data block (single data unit w/o header) */ @@ -514,7 +565,7 @@ struct msgb *gprs_rlcmac_dl_tbf::create_new_bsn(const uint32_t fn, const uint8_t m_window.m_v_b.mark_unacked(bsn); m_window.increment_send(); - return create_dl_acked_block(fn, ts, bsn); + return bsn; } struct msgb *gprs_rlcmac_dl_tbf::create_dl_acked_block( diff --git a/tests/tbf/TbfTest.err b/tests/tbf/TbfTest.err index d97589e9..e0027386 100644 --- a/tests/tbf/TbfTest.err +++ b/tests/tbf/TbfTest.err @@ -68,8 +68,8 @@ Scheduling control message at RTS for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLO Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=0 block=0 data=4f 08 20 00 44 02 00 02 08 04 00 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==0) -- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) (len=200) - Sending new block at BSN 0, CS=CS-1 +- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) (len=200) -- Chunk with length 200 larger than space (20) left in block: copy only remaining space, and we are done data block (BSN 0, CS-1): 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 - Copying data unit 0 (BSN 0) @@ -153,8 +153,8 @@ Scheduling control message at RTS for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLO Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=0 block=0 data=4f 08 20 00 44 02 00 02 08 04 00 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==0) -- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) (len=200) - Sending new block at BSN 0, CS=CS-1 +- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) (len=200) -- Chunk with length 200 larger than space (20) left in block: copy only remaining space, and we are done data block (BSN 0, CS-1): 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 - Copying data unit 0 (BSN 0) @@ -238,8 +238,8 @@ Scheduling control message at RTS for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLO Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=0 block=0 data=4f 08 20 00 44 02 00 02 08 04 00 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==0) -- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) (len=200) - Sending new block at BSN 0, CS=CS-1 +- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) (len=200) -- Chunk with length 200 larger than space (20) left in block: copy only remaining space, and we are done data block (BSN 0, CS-1): 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 - Copying data unit 0 (BSN 0) @@ -443,7 +443,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) DL analysis, range=0:21, lost=0, re - V(B): (V(A)=21)""(V(S)-1=20) A=Acked N=Nacked U=Unacked X=Resend-Unacked I=Invalid Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=4 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==21 .. V(S)==21) -- Sending new block at BSN 21, CS=CS-1 +- Sending new dummy block at BSN 21, CS=CS-1 -- Empty chunk, added LLC dummy command of size 19, drained_since=4 -- Chunk with length 19 is less than remaining space (20): add length header to to delimit LLC frame -- No space left, so we are done. @@ -461,7 +461,7 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) DL analysis, range=21:22, lost=0, r - V(B): (V(A)=22)""(V(S)-1=21) A=Acked N=Nacked U=Unacked X=Resend-Unacked I=Invalid Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=4 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink (V(A)==22 .. V(S)==22) -- Sending new block at BSN 22, CS=CS-1 +- Sending new dummy block at BSN 22, CS=CS-1 -- Empty chunk, added LLC dummy command of size 19, drained_since=112 -- Chunk with length 19 is less than remaining space (20): add length header to to delimit LLC frame -- Final block, so we done. @@ -1474,8 +1474,8 @@ Sending data request: trx=0 ts=0 sapi=3 arfcn=0 fn=0 block=0 data=34 35 36 2d 06 TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=ASSIGN) changes state from ASSIGN to WAIT ASSIGN TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=WAIT ASSIGN) append TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=WAIT ASSIGN) downlink (V(A)==0 .. V(S)==0) -- Dequeue next LLC for TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=WAIT ASSIGN) (len=19) - Sending new block at BSN 0, CS=CS-1 +- Dequeue next LLC for TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=WAIT ASSIGN) (len=19) -- Chunk with length 19 is less than remaining space (20): add length header to to delimit LLC frame -- No space left, so we are done. Complete DL frame for TBF(TFI=0 TLLI=0xc0123456 DIR=DL STATE=WAIT ASSIGN)len=19 @@ -1777,8 +1777,8 @@ Received RTS on disabled PDCH: TRX=0 TS=6 Received RTS for PDCH: TRX=0 TS=7 FN=2654279 block_nr=10 scheduling USF=0 for required uplink resource of UL TFI=0 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=7) prio=3 TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==0) -- Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=10) - Sending new block at BSN 0, CS=CS-4 +- Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=10) -- Chunk with length 10 is less than remaining space (50): add length header to to delimit LLC frame -- Final block, so we done. Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=10 @@ -2358,8 +2358,8 @@ Received RTS on disabled PDCH: TRX=0 TS=6 Received RTS for PDCH: TRX=0 TS=7 FN=2654279 block_nr=10 scheduling USF=0 for required uplink resource of UL TFI=0 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=7) prio=3 TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==0) -- Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) - Sending new block at BSN 0, CS=CS-1 +- Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) -- Chunk with length 13 is less than remaining space (20): add length header to to delimit LLC frame Complete DL frame for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW)len=13 - Dequeue next LLC for TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=13) @@ -3024,8 +3024,8 @@ Received RTS on disabled PDCH: TRX=0 TS=6 Received RTS for PDCH: TRX=0 TS=7 FN=2654405 block_nr=3 scheduling USF=0 for required uplink resource of UL TFI=0 Scheduling data message at RTS for DL TFI=1 (TRX=0, TS=7) prio=3 TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW) downlink (V(A)==0 .. V(S)==0) -- Dequeue next LLC for TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=21) - Sending new block at BSN 0, CS=CS-1 +- Dequeue next LLC for TBF(TFI=1 TLLI=0xf1223344 DIR=DL STATE=FLOW) (len=21) -- Chunk with length 21 larger than space (20) left in block: copy only remaining space, and we are done data block (BSN 0, CS-1): 4c 4c 43 20 50 41 43 4b 45 54 20 30 30 20 28 54 42 46 20 32 - Copying data unit 0 (BSN 0) @@ -3433,8 +3433,8 @@ Scheduling control message at RTS for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLO Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=0 block=0 data=4f 08 20 00 44 02 00 02 08 04 00 c0 0b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==0) -- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (len=10) - Sending new block at BSN 0, CS=MCS-1 +- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (len=10) -- Chunk with length 10 is less than remaining space (22): add length header to to delimit LLC frame Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=10 -- Empty chunk, added LLC dummy command of size 10, drained_since=0 @@ -3451,8 +3451,8 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) append Received RTS for PDCH: TRX=0 TS=4 FN=8 block_nr=2 scheduling free USF for polling at FN=13 of TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==1) -- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (len=512) - Sending new block at BSN 1, CS=MCS-1 +- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (len=512) -- Chunk with length 512 larger than space (22) left in block: copy only remaining space, and we are done data block (BSN 1, MCS-1): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 - Copying data unit 0 (BSN 1) @@ -3741,8 +3741,8 @@ Scheduling control message at RTS for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLO Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=0 block=0 data=4f 08 20 00 44 02 00 02 08 04 00 c0 0b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==0) -- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (len=10) - Sending new block at BSN 0, CS=MCS-2 +- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (len=10) -- Chunk with length 10 is less than remaining space (28): add length header to to delimit LLC frame Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=10 -- Empty chunk, added LLC dummy command of size 16, drained_since=0 @@ -3759,8 +3759,8 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) append Received RTS for PDCH: TRX=0 TS=4 FN=8 block_nr=2 scheduling free USF for polling at FN=13 of TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==1) -- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (len=512) - Sending new block at BSN 1, CS=MCS-2 +- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (len=512) -- Chunk with length 512 larger than space (28) left in block: copy only remaining space, and we are done data block (BSN 1, MCS-2): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 - Copying data unit 0 (BSN 1) @@ -3999,8 +3999,8 @@ Scheduling control message at RTS for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLO Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=0 block=0 data=4f 08 20 00 44 02 00 02 08 04 00 c0 0b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==0) -- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (len=10) - Sending new block at BSN 0, CS=MCS-3 +- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (len=10) -- Chunk with length 10 is less than remaining space (37): add length header to to delimit LLC frame Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=10 -- Empty chunk, added LLC dummy command of size 25, drained_since=0 @@ -4017,8 +4017,8 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) append Received RTS for PDCH: TRX=0 TS=4 FN=8 block_nr=2 scheduling free USF for polling at FN=13 of TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==1) -- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (len=512) - Sending new block at BSN 1, CS=MCS-3 +- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (len=512) -- Chunk with length 512 larger than space (37) left in block: copy only remaining space, and we are done data block (BSN 1, MCS-3): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 - Copying data unit 0 (BSN 1) @@ -4220,8 +4220,8 @@ Scheduling control message at RTS for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLO Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=0 block=0 data=4f 08 20 00 44 02 00 02 08 04 00 c0 0b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==0) -- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (len=10) - Sending new block at BSN 0, CS=MCS-4 +- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (len=10) -- Chunk with length 10 is less than remaining space (44): add length header to to delimit LLC frame Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=10 -- Empty chunk, added LLC dummy command of size 32, drained_since=0 @@ -4238,8 +4238,8 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) append Received RTS for PDCH: TRX=0 TS=4 FN=8 block_nr=2 scheduling free USF for polling at FN=13 of TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==1) -- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (len=512) - Sending new block at BSN 1, CS=MCS-4 +- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (len=512) -- Chunk with length 512 larger than space (44) left in block: copy only remaining space, and we are done data block (BSN 1, MCS-4): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 - Copying data unit 0 (BSN 1) @@ -4408,8 +4408,8 @@ Scheduling control message at RTS for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLO Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=0 block=0 data=4f 08 20 00 44 02 00 02 08 04 00 c0 0b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==0) -- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (len=10) - Sending new block at BSN 0, CS=MCS-5 +- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (len=10) -- Chunk with length 10 is less than remaining space (56): add length header to to delimit LLC frame Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=10 -- Empty chunk, added LLC dummy command of size 44, drained_since=0 @@ -4426,8 +4426,8 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) append Received RTS for PDCH: TRX=0 TS=4 FN=8 block_nr=2 scheduling free USF for polling at FN=13 of TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==1) -- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (len=512) - Sending new block at BSN 1, CS=MCS-5 +- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (len=512) -- Chunk with length 512 larger than space (56) left in block: copy only remaining space, and we are done data block (BSN 1, MCS-5): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 - Copying data unit 0 (BSN 1) @@ -4576,8 +4576,8 @@ Scheduling control message at RTS for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLO Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=0 block=0 data=4f 08 20 00 44 02 00 02 08 04 00 c0 0b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==0) -- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (len=10) - Sending new block at BSN 0, CS=MCS-6 +- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (len=10) -- Chunk with length 10 is less than remaining space (74): add length header to to delimit LLC frame Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=10 -- Empty chunk, added LLC dummy command of size 62, drained_since=0 @@ -4594,8 +4594,8 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) append Received RTS for PDCH: TRX=0 TS=4 FN=8 block_nr=2 scheduling free USF for polling at FN=13 of TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==1) -- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (len=512) - Sending new block at BSN 1, CS=MCS-6 +- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (len=512) -- Chunk with length 512 larger than space (74) left in block: copy only remaining space, and we are done data block (BSN 1, MCS-6): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 - Copying data unit 0 (BSN 1) @@ -4727,8 +4727,8 @@ Scheduling control message at RTS for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLO Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=0 block=0 data=4f 08 20 00 44 02 00 02 08 04 00 c0 0b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==0) -- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (len=10) - Sending new block at BSN 0, CS=MCS-7 +- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (len=10) -- Chunk with length 10 is less than remaining space (56): add length header to to delimit LLC frame Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=10 -- Empty chunk, added LLC dummy command of size 44, drained_since=0 @@ -4736,6 +4736,7 @@ Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=10 -- No space left, so we are done. Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=44 data block (BSN 0, MCS-7): 14 59 01 01 01 01 01 01 01 01 01 01 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +- Restarting at BSN 0, because all blocks have been transmitted (FLOW). - Copying data unit 0 (BSN 0) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) @@ -4745,95 +4746,73 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) append Received RTS for PDCH: TRX=0 TS=4 FN=8 block_nr=2 scheduling free USF for polling at FN=13 of TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==1) -- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (len=512) +- Resending BSN 0 - Sending new block at BSN 1, CS=MCS-7 +- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (len=512) -- Chunk with length 512 larger than space (56) left in block: copy only remaining space, and we are done data block (BSN 1, MCS-7): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 -- Copying data unit 0 (BSN 1) +- Copying data unit 0 (BSN 0) +- Copying data unit 1 (BSN 1) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) -msg block (BSN 1, MCS-5): 07 40 00 58 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 -Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=8 block=2 data=07 40 00 58 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 +msg block (BSN 0, MCS-7): 07 00 00 02 a8 50 64 05 04 04 04 04 04 04 04 04 04 0c 01 07 ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac 14 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=8 block=2 data=07 00 00 02 a8 50 64 05 04 04 04 04 04 04 04 04 04 0c 01 07 ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac 14 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 00 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==2) - Sending new block at BSN 2, CS=MCS-7 -- Chunk with length 456 larger than space (56) left in block: copy only remaining space, and we are done data block (BSN 2, MCS-7): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 -- Copying data unit 0 (BSN 2) -- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). -Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) -msg block (BSN 2, MCS-5): 07 80 00 58 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 -Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=13 block=3 data=07 80 00 58 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 -Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 -TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==3) - Sending new block at BSN 3, CS=MCS-7 -- Chunk with length 400 larger than space (56) left in block: copy only remaining space, and we are done data block (BSN 3, MCS-7): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 -- Copying data unit 0 (BSN 3) +- Copying data unit 0 (BSN 2) +- Copying data unit 1 (BSN 3) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) -msg block (BSN 3, MCS-5): 07 c0 00 58 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 -Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=17 block=4 data=07 c0 00 58 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 +msg block (BSN 2, MCS-7): 07 80 00 02 a8 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 14 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=13 block=3 data=07 80 00 02 a8 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 14 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 00 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==4) - Sending new block at BSN 4, CS=MCS-7 -- Chunk with length 344 larger than space (56) left in block: copy only remaining space, and we are done data block (BSN 4, MCS-7): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 -- Copying data unit 0 (BSN 4) -- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). -Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) -msg block (BSN 4, MCS-5): 07 00 01 58 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 -Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=21 block=5 data=07 00 01 58 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 -Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 -TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==5) - Sending new block at BSN 5, CS=MCS-7 -- Chunk with length 288 larger than space (56) left in block: copy only remaining space, and we are done data block (BSN 5, MCS-7): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 -- Copying data unit 0 (BSN 5) +- Copying data unit 0 (BSN 4) +- Copying data unit 1 (BSN 5) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) -msg block (BSN 5, MCS-5): 07 40 01 58 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 -Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=26 block=6 data=07 40 01 58 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 +msg block (BSN 4, MCS-7): 07 00 01 02 a8 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 14 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=17 block=4 data=07 00 01 02 a8 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 14 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 00 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==6) - Sending new block at BSN 6, CS=MCS-7 -- Chunk with length 232 larger than space (56) left in block: copy only remaining space, and we are done data block (BSN 6, MCS-7): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 -- Copying data unit 0 (BSN 6) -- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). -Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) -msg block (BSN 6, MCS-5): 07 80 01 58 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 -Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=30 block=7 data=07 80 01 58 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 -Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 -TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==7) - Sending new block at BSN 7, CS=MCS-7 -- Chunk with length 176 larger than space (56) left in block: copy only remaining space, and we are done data block (BSN 7, MCS-7): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 -- Copying data unit 0 (BSN 7) +- Copying data unit 0 (BSN 6) +- Copying data unit 1 (BSN 7) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) -msg block (BSN 7, MCS-5): 07 c0 01 58 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 -Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=34 block=8 data=07 c0 01 58 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 +msg block (BSN 6, MCS-7): 07 80 01 02 a8 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 14 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=21 block=5 data=07 80 01 02 a8 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 14 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 00 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==8) - Sending new block at BSN 8, CS=MCS-7 -- Chunk with length 120 larger than space (56) left in block: copy only remaining space, and we are done data block (BSN 8, MCS-7): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 -- Copying data unit 0 (BSN 8) -- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). -Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) -msg block (BSN 8, MCS-5): 07 00 02 58 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 -Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=39 block=9 data=07 00 02 58 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 -Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 -TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==9) - Sending new block at BSN 9, CS=MCS-7 -- Chunk with length 64 larger than space (56) left in block: copy only remaining space, and we are done data block (BSN 9, MCS-7): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 -- Copying data unit 0 (BSN 9) +- Copying data unit 0 (BSN 8) +- Copying data unit 1 (BSN 9) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) -msg block (BSN 9, MCS-5): 07 40 02 58 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 -Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=43 block=10 data=07 40 02 58 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 +msg block (BSN 8, MCS-7): 07 00 02 02 a8 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 14 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=26 block=6 data=07 00 02 02 a8 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 14 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 00 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==10) - Sending new block at BSN 10, CS=MCS-7 @@ -4844,11 +4823,12 @@ Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=512 -- No space left, so we are done. Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=46 data block (BSN 10, MCS-7): 10 5d 01 01 01 01 01 01 01 01 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +- Restarting at BSN 0, because all blocks have been transmitted (FLOW). - Copying data unit 0 (BSN 10) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 10, MCS-5): 07 80 02 08 44 57 40 40 40 40 40 40 40 c0 10 70 c0 ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca 0a -Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=47 block=11 data=07 80 02 08 44 57 40 40 40 40 40 40 40 c0 10 70 c0 ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca 0a +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=30 block=7 data=07 80 02 08 44 57 40 40 40 40 40 40 40 c0 10 70 c0 ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca 0a TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink acknowledge - Final ACK received. TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) changes state from FLOW to WAIT RELEASE @@ -4895,8 +4875,8 @@ Scheduling control message at RTS for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLO Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=0 block=0 data=4f 08 20 00 44 02 00 02 08 04 00 c0 0b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==0) -- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (len=10) - Sending new block at BSN 0, CS=MCS-8 +- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (len=10) -- Chunk with length 10 is less than remaining space (68): add length header to to delimit LLC frame Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=10 -- Empty chunk, added LLC dummy command of size 56, drained_since=0 @@ -4904,6 +4884,7 @@ Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=10 -- No space left, so we are done. Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=56 data block (BSN 0, MCS-8): 14 71 01 01 01 01 01 01 01 01 01 01 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +- Restarting at BSN 0, because all blocks have been transmitted (FLOW). - Copying data unit 0 (BSN 0) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) @@ -4913,75 +4894,59 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) append Received RTS for PDCH: TRX=0 TS=4 FN=8 block_nr=2 scheduling free USF for polling at FN=13 of TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==1) -- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (len=512) +- Resending BSN 0 - Sending new block at BSN 1, CS=MCS-8 +- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (len=512) -- Chunk with length 512 larger than space (68) left in block: copy only remaining space, and we are done data block (BSN 1, MCS-8): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 -- Copying data unit 0 (BSN 1) +- Copying data unit 0 (BSN 0) +- Copying data unit 1 (BSN 1) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) -msg block (BSN 1, MCS-6, padded): 07 40 00 04 00 00 00 00 00 50 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 -Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=8 block=2 data=07 40 00 04 00 00 00 00 00 50 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 +msg block (BSN 0, MCS-8): 07 00 00 02 60 50 c4 05 04 04 04 04 04 04 04 04 04 0c 01 07 ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac 14 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=8 block=2 data=07 00 00 02 60 50 c4 05 04 04 04 04 04 04 04 04 04 0c 01 07 ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac 14 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 00 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==2) - Sending new block at BSN 2, CS=MCS-8 -- Chunk with length 444 larger than space (68) left in block: copy only remaining space, and we are done data block (BSN 2, MCS-8): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 -- Copying data unit 0 (BSN 2) -- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). -Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) -msg block (BSN 2, MCS-6, padded): 07 80 00 04 00 00 00 00 00 50 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 -Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=13 block=3 data=07 80 00 04 00 00 00 00 00 50 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 -Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 -TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==3) - Sending new block at BSN 3, CS=MCS-8 -- Chunk with length 376 larger than space (68) left in block: copy only remaining space, and we are done data block (BSN 3, MCS-8): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 -- Copying data unit 0 (BSN 3) +- Copying data unit 0 (BSN 2) +- Copying data unit 1 (BSN 3) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) -msg block (BSN 3, MCS-6, padded): 07 c0 00 04 00 00 00 00 00 50 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 -Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=17 block=4 data=07 c0 00 04 00 00 00 00 00 50 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 +msg block (BSN 2, MCS-8): 07 80 00 02 60 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 14 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=13 block=3 data=07 80 00 02 60 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 14 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 00 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==4) - Sending new block at BSN 4, CS=MCS-8 -- Chunk with length 308 larger than space (68) left in block: copy only remaining space, and we are done data block (BSN 4, MCS-8): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 -- Copying data unit 0 (BSN 4) -- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). -Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) -msg block (BSN 4, MCS-6, padded): 07 00 01 04 00 00 00 00 00 50 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 -Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=21 block=5 data=07 00 01 04 00 00 00 00 00 50 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 -Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 -TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==5) - Sending new block at BSN 5, CS=MCS-8 -- Chunk with length 240 larger than space (68) left in block: copy only remaining space, and we are done data block (BSN 5, MCS-8): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 -- Copying data unit 0 (BSN 5) +- Copying data unit 0 (BSN 4) +- Copying data unit 1 (BSN 5) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) -msg block (BSN 5, MCS-6, padded): 07 40 01 04 00 00 00 00 00 50 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 -Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=26 block=6 data=07 40 01 04 00 00 00 00 00 50 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 +msg block (BSN 4, MCS-8): 07 00 01 02 60 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 14 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=17 block=4 data=07 00 01 02 60 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 14 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 00 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==6) - Sending new block at BSN 6, CS=MCS-8 -- Chunk with length 172 larger than space (68) left in block: copy only remaining space, and we are done data block (BSN 6, MCS-8): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 -- Copying data unit 0 (BSN 6) -- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). -Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) -msg block (BSN 6, MCS-6, padded): 07 80 01 04 00 00 00 00 00 50 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 -Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=30 block=7 data=07 80 01 04 00 00 00 00 00 50 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 -Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 -TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==7) - Sending new block at BSN 7, CS=MCS-8 -- Chunk with length 104 larger than space (68) left in block: copy only remaining space, and we are done data block (BSN 7, MCS-8): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 -- Copying data unit 0 (BSN 7) +- Copying data unit 0 (BSN 6) +- Copying data unit 1 (BSN 7) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) -msg block (BSN 7, MCS-6, padded): 07 c0 01 04 00 00 00 00 00 50 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 -Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=34 block=8 data=07 c0 01 04 00 00 00 00 00 50 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 +msg block (BSN 6, MCS-8): 07 80 01 02 60 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 14 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=21 block=5 data=07 80 01 02 60 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 14 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 00 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==8) - Sending new block at BSN 8, CS=MCS-8 @@ -4992,11 +4957,12 @@ Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=512 -- No space left, so we are done. Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=30 data block (BSN 8, MCS-8): 48 3d 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +- Restarting at BSN 0, because all blocks have been transmitted (FLOW). - Copying data unit 0 (BSN 8) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 8, MCS-6, padded): 07 00 02 04 00 00 00 00 00 00 52 4f 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 c0 10 70 c0 ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca 0a -Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=39 block=9 data=07 00 02 04 00 00 00 00 00 00 52 4f 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 c0 10 70 c0 ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca 0a +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=26 block=6 data=07 00 02 04 00 00 00 00 00 00 52 4f 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 c0 10 70 c0 ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca 0a TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink acknowledge - Final ACK received. TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) changes state from FLOW to WAIT RELEASE @@ -5043,8 +5009,8 @@ Scheduling control message at RTS for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLO Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=0 block=0 data=4f 08 20 00 44 02 00 02 08 04 00 c0 0b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==0) -- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (len=10) - Sending new block at BSN 0, CS=MCS-9 +- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (len=10) -- Chunk with length 10 is less than remaining space (74): add length header to to delimit LLC frame Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=10 -- Empty chunk, added LLC dummy command of size 62, drained_since=0 @@ -5052,6 +5018,7 @@ Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=10 -- No space left, so we are done. Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=62 data block (BSN 0, MCS-9): 14 7d 01 01 01 01 01 01 01 01 01 01 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +- Restarting at BSN 0, because all blocks have been transmitted (FLOW). - Copying data unit 0 (BSN 0) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) @@ -5061,78 +5028,62 @@ TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) append Received RTS for PDCH: TRX=0 TS=4 FN=8 block_nr=2 scheduling free USF for polling at FN=13 of TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==1) -- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (len=512) +- Resending BSN 0 - Sending new block at BSN 1, CS=MCS-9 +- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (len=512) -- Chunk with length 512 larger than space (74) left in block: copy only remaining space, and we are done data block (BSN 1, MCS-9): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 -- Copying data unit 0 (BSN 1) +- Copying data unit 0 (BSN 0) +- Copying data unit 1 (BSN 1) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) -msg block (BSN 1, MCS-6): 07 40 00 50 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 -Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=8 block=2 data=07 40 00 50 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 +msg block (BSN 0, MCS-9): 07 00 00 02 08 50 f4 05 04 04 04 04 04 04 04 04 04 0c 01 07 ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac 14 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=8 block=2 data=07 00 00 02 08 50 f4 05 04 04 04 04 04 04 04 04 04 0c 01 07 ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac 14 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 00 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==2) - Sending new block at BSN 2, CS=MCS-9 -- Chunk with length 438 larger than space (74) left in block: copy only remaining space, and we are done data block (BSN 2, MCS-9): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 -- Copying data unit 0 (BSN 2) -- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). -Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) -msg block (BSN 2, MCS-6): 07 80 00 50 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 -Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=13 block=3 data=07 80 00 50 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 -Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 -TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==3) - Sending new block at BSN 3, CS=MCS-9 -- Chunk with length 364 larger than space (74) left in block: copy only remaining space, and we are done data block (BSN 3, MCS-9): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 -- Copying data unit 0 (BSN 3) +- Copying data unit 0 (BSN 2) +- Copying data unit 1 (BSN 3) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) -msg block (BSN 3, MCS-6): 07 c0 00 50 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 -Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=17 block=4 data=07 c0 00 50 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 +msg block (BSN 2, MCS-9): 07 80 00 02 08 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 14 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=13 block=3 data=07 80 00 02 08 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 14 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 00 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==4) - Sending new block at BSN 4, CS=MCS-9 -- Chunk with length 290 larger than space (74) left in block: copy only remaining space, and we are done data block (BSN 4, MCS-9): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 -- Copying data unit 0 (BSN 4) -- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). -Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) -msg block (BSN 4, MCS-6): 07 00 01 50 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 -Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=21 block=5 data=07 00 01 50 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 -Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 -TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==5) - Sending new block at BSN 5, CS=MCS-9 -- Chunk with length 216 larger than space (74) left in block: copy only remaining space, and we are done data block (BSN 5, MCS-9): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 -- Copying data unit 0 (BSN 5) +- Copying data unit 0 (BSN 4) +- Copying data unit 1 (BSN 5) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) -msg block (BSN 5, MCS-6): 07 40 01 50 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 -Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=26 block=6 data=07 40 01 50 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 +msg block (BSN 4, MCS-9): 07 00 01 02 08 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 14 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=17 block=4 data=07 00 01 02 08 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 14 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 00 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==6) - Sending new block at BSN 6, CS=MCS-9 -- Chunk with length 142 larger than space (74) left in block: copy only remaining space, and we are done data block (BSN 6, MCS-9): 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 -- Copying data unit 0 (BSN 6) -- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). -Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) -msg block (BSN 6, MCS-6): 07 80 01 50 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 -Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=30 block=7 data=07 80 01 50 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 00 -Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 -TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==7) - Sending new block at BSN 7, CS=MCS-9 -- Chunk with length 68 is less than remaining space (74): add length header to to delimit LLC frame Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=512 -- Empty chunk, added LLC dummy command of size 6, drained_since=0 -- Chunk with length 6 larger than space (5) left in block: copy only remaining space, and we are done data block (BSN 7, MCS-9): 89 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 43 c0 01 2b 2b -- Copying data unit 0 (BSN 7) +- Copying data unit 0 (BSN 6) +- Copying data unit 1 (BSN 7) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) -msg block (BSN 7, MCS-6): 07 c0 01 40 62 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 c0 10 70 c0 ca 0a -Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=34 block=8 data=07 c0 01 40 62 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 c0 10 70 c0 ca 0a +msg block (BSN 6, MCS-9): 07 80 01 02 08 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 90 18 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 30 04 1c b0 b2 02 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=21 block=5 data=07 80 01 02 08 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 90 18 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 30 04 1c b0 b2 02 Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==8) - Sending new block at BSN 8, CS=MCS-9 @@ -5143,11 +5094,12 @@ Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=6 -- No space left, so we are done. Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=71 data block (BSN 8, MCS-9): 02 8f 2b 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +- Restarting at BSN 0, because all blocks have been transmitted (FLOW). - Copying data unit 0 (BSN 8) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) msg block (BSN 8, MCS-6): 07 00 02 80 c0 e3 ca 10 70 c0 ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca 0a -Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=39 block=9 data=07 00 02 80 c0 e3 ca 10 70 c0 ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca 0a +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=26 block=6 data=07 00 02 80 c0 e3 ca 10 70 c0 ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca 0a TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink acknowledge - Final ACK received. TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) changes state from FLOW to WAIT RELEASE -- cgit v1.2.3 From 64e7b83139772c8fff775ef2adfeadb704558920 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Thu, 4 Feb 2016 15:16:47 +0100 Subject: edge: Compare len instead of using cs.isCombinable Comparing the coding scheme properties doesn't seem to be strong enough, since create_dl_acked_block(fn, ts, index, index2) sometimes had to combine data units of different size this way. Check the registered size of the BSN blocks instead, since these must match if two blocks are to be combined in a single RLC data message with MCS7-9. It is not yet clear, what exactly goes wrong with the current implementation, but this commit fixes the problem which trigger the assertion in create_dl_acked_block. Sponsored-by: On-Waves ehf --- src/tbf.h | 2 +- src/tbf_dl.cpp | 25 ++++++++++++++----------- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/tbf.h b/src/tbf.h index 6c030d23..ad8ad4c2 100644 --- a/src/tbf.h +++ b/src/tbf.h @@ -407,7 +407,7 @@ protected: }; int take_next_bsn(uint32_t fn, int previous_bsn, - GprsCodingScheme *next_cs); + bool *may_combine); bool restart_bsn_cycle(); int create_new_bsn(const uint32_t fn, GprsCodingScheme cs); struct msgb *create_dl_acked_block(const uint32_t fn, const uint8_t ts, diff --git a/src/tbf_dl.cpp b/src/tbf_dl.cpp index e2521f84..6d4209f1 100644 --- a/src/tbf_dl.cpp +++ b/src/tbf_dl.cpp @@ -355,9 +355,10 @@ bool gprs_rlcmac_dl_tbf::restart_bsn_cycle() } int gprs_rlcmac_dl_tbf::take_next_bsn(uint32_t fn, - int previous_bsn, GprsCodingScheme *next_cs) + int previous_bsn, bool *may_combine) { int bsn; + int data_len2, force_data_len = -1; GprsCodingScheme cs2; GprsCodingScheme force_cs; @@ -367,6 +368,7 @@ int gprs_rlcmac_dl_tbf::take_next_bsn(uint32_t fn, force_cs = m_rlc.block(previous_bsn)->cs; if (!force_cs.isEgprs()) return -1; + force_data_len = m_rlc.block(previous_bsn)->len; } if (bsn >= 0) { @@ -378,7 +380,8 @@ int gprs_rlcmac_dl_tbf::take_next_bsn(uint32_t fn, return -1; cs2 = m_rlc.block(bsn)->cs; - if (force_cs && !cs2.isCombinable(force_cs)) + data_len2 = m_rlc.block(bsn)->len; + if (force_data_len > 0 && force_data_len != data_len2) return -1; LOGP(DRLCMACDL, LOGL_DEBUG, "- Resending BSN %d\n", bsn); /* re-send block with negative aknowlegement */ @@ -390,14 +393,14 @@ int gprs_rlcmac_dl_tbf::take_next_bsn(uint32_t fn, m_window.v_a()); bts->rlc_restarted(); if (restart_bsn_cycle()) - return take_next_bsn(fn, previous_bsn, next_cs); + return take_next_bsn(fn, previous_bsn, may_combine); } else if (dl_window_stalled()) { LOGP(DRLCMACDL, LOGL_NOTICE, "- Restarting at BSN %d, " "because the window is stalled.\n", m_window.v_a()); bts->rlc_stalled(); if (restart_bsn_cycle()) - return take_next_bsn(fn, previous_bsn, next_cs); + return take_next_bsn(fn, previous_bsn, may_combine); } else if (have_data()) { /* New blocks may be send */ cs2 = force_cs ? force_cs : current_cs(); @@ -412,14 +415,14 @@ int gprs_rlcmac_dl_tbf::take_next_bsn(uint32_t fn, m_window.v_a()); bts->rlc_restarted(); if (restart_bsn_cycle()) - return take_next_bsn(fn, previous_bsn, next_cs); + return take_next_bsn(fn, previous_bsn, may_combine); } else { /* Nothing left to send, create dummy LLC commands */ LOGP(DRLCMACDL, LOGL_DEBUG, "- Sending new dummy block at BSN %d, CS=%s\n", m_window.v_s(), current_cs().name()); bsn = create_new_bsn(fn, current_cs()); - /* Don't send a second block */ + /* Don't send a second block, so don't set cs2 */ } if (bsn < 0) { @@ -430,7 +433,7 @@ int gprs_rlcmac_dl_tbf::take_next_bsn(uint32_t fn, bts->rlc_resent(); } - *next_cs = cs2; + *may_combine = cs2.numDataBlocks() > 1; return bsn; } @@ -442,18 +445,18 @@ int gprs_rlcmac_dl_tbf::take_next_bsn(uint32_t fn, struct msgb *gprs_rlcmac_dl_tbf::create_dl_acked_block(uint32_t fn, uint8_t ts) { int bsn, bsn2 = -1; - GprsCodingScheme cs, next_cs; + bool may_combine; LOGP(DRLCMACDL, LOGL_DEBUG, "%s downlink (V(A)==%d .. " "V(S)==%d)\n", tbf_name(this), m_window.v_a(), m_window.v_s()); - bsn = take_next_bsn(fn, -1, &next_cs); + bsn = take_next_bsn(fn, -1, &may_combine); if (bsn < 0) return NULL; - if (next_cs.numDataBlocks() > 1) - bsn2 = take_next_bsn(fn, bsn, &next_cs); + if (may_combine) + bsn2 = take_next_bsn(fn, bsn, &may_combine); return create_dl_acked_block(fn, ts, bsn, bsn2); } -- cgit v1.2.3 From be881c028fc4da00c4046ecd9296727975c206a3 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Wed, 3 Feb 2016 20:44:46 +0100 Subject: edge: Work-around to not use MCS-6 with padding Currently single BSN blocks of size 68 (a single unit from MCS-8) are put into a MCS-6 block with padding according to TS 44.060 Annex J. Unfortunately, these packets are ignored by the E71. This might be related to the currently incorrect usage of the puncturing schemes and the RSB bit (the puncturing schemes are not updated and the RBS flag is never set). Avoid downgrading from MCS-8 to MCS-6 if there is no second block available. Send the block twice instead. Sponsored-by: On-Waves ehf --- src/tbf_dl.cpp | 8 ++++++-- tests/tbf/TbfTest.err | 10 ++++++---- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/tbf_dl.cpp b/src/tbf_dl.cpp index 6d4209f1..7540d1b3 100644 --- a/src/tbf_dl.cpp +++ b/src/tbf_dl.cpp @@ -609,8 +609,12 @@ struct msgb *gprs_rlcmac_dl_tbf::create_dl_acked_block( num_bsns += 1; } - if (num_bsns == 1) - cs.decToSingleBlock(&need_padding); + if (num_bsns == 1) { + /* TODO: remove the conditional when MCS-6 padding isn't + * failing to be decoded by MEs anymore */ + if (cs != GprsCodingScheme(GprsCodingScheme::MCS8)) + cs.decToSingleBlock(&need_padding); + } gprs_rlc_data_info_init_dl(&rlc, cs, need_padding); diff --git a/tests/tbf/TbfTest.err b/tests/tbf/TbfTest.err index e0027386..77966595 100644 --- a/tests/tbf/TbfTest.err +++ b/tests/tbf/TbfTest.err @@ -4886,10 +4886,11 @@ Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=56 data block (BSN 0, MCS-8): 14 71 01 01 01 01 01 01 01 01 01 01 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b - Restarting at BSN 0, because all blocks have been transmitted (FLOW). - Copying data unit 0 (BSN 0) +- Copying data unit 1 (BSN 0) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) -msg block (BSN 0, MCS-6, padded): 07 00 00 04 00 00 00 00 00 00 45 5c 40 40 40 40 40 40 40 40 40 c0 10 70 c0 ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca 0a -Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=4 block=1 data=07 00 00 04 00 00 00 00 00 00 45 5c 40 40 40 40 40 40 40 40 40 c0 10 70 c0 ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca 0a +msg block (BSN 0, MCS-8): 07 00 00 00 60 50 c4 05 04 04 04 04 04 04 04 04 04 0c 01 07 ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac 40 11 17 10 10 10 10 10 10 10 10 10 30 04 1c b0 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 02 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=4 block=1 data=07 00 00 00 60 50 c4 05 04 04 04 04 04 04 04 04 04 0c 01 07 ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac 40 11 17 10 10 10 10 10 10 10 10 10 30 04 1c b0 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 02 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) append Received RTS for PDCH: TRX=0 TS=4 FN=8 block_nr=2 scheduling free USF for polling at FN=13 of TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=3 @@ -4959,10 +4960,11 @@ Complete DL frame for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS)len=30 data block (BSN 8, MCS-8): 48 3d 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b - Restarting at BSN 0, because all blocks have been transmitted (FLOW). - Copying data unit 0 (BSN 8) +- Copying data unit 1 (BSN 8) - Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). Polling is already scheduled for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) -msg block (BSN 8, MCS-6, padded): 07 00 02 04 00 00 00 00 00 00 52 4f 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 c0 10 70 c0 ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca 0a -Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=26 block=6 data=07 00 02 04 00 00 00 00 00 00 52 4f 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 c0 10 70 c0 ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca ca 0a +msg block (BSN 8, MCS-8): 07 00 02 00 60 20 f5 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 0c 01 07 ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac 80 d4 13 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 30 04 1c b0 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 02 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=26 block=6 data=07 00 02 00 60 20 f5 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 0c 01 07 ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac 80 d4 13 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 30 04 1c b0 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 02 TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink acknowledge - Final ACK received. TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) changes state from FLOW to WAIT RELEASE -- cgit v1.2.3 From 7f28c97fcc87d2ce773a2ae91579a84b40d12539 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Thu, 4 Feb 2016 17:54:42 +0100 Subject: edge: Support all coding schemes for BSSGP flow control Currently the MCS schemes are not supported when the leak rate is being computed. This leads to a lower value for the leak rate, thus limiting the throughput to GPRS-like ranges. Use the payload size reported by GprsCodingScheme instead. Sponsored-by: On-Waves ehf --- src/gprs_bssgp_pcu.cpp | 81 +++++++++++++++++++++++++++++++------------------- 1 file changed, 50 insertions(+), 31 deletions(-) diff --git a/src/gprs_bssgp_pcu.cpp b/src/gprs_bssgp_pcu.cpp index 5eefdefd..da1d26c1 100644 --- a/src/gprs_bssgp_pcu.cpp +++ b/src/gprs_bssgp_pcu.cpp @@ -533,19 +533,12 @@ static unsigned count_pdch(const struct gprs_rlcmac_bts *bts) return num_pdch; } -static uint32_t gprs_bssgp_max_leak_rate(unsigned cs, int num_pdch) +static uint32_t gprs_bssgp_max_leak_rate(GprsCodingScheme cs, int num_pdch) { - static const uint32_t max_lr_per_ts[4] = { - 20 * (1000 / 20), /* CS-1: 20 byte payload per 20ms */ - 30 * (1000 / 20), /* CS-2: 30 byte payload per 20ms */ - 36 * (1000 / 20), /* CS-3: 36 byte payload per 20ms */ - 50 * (1000 / 20), /* CS-4: 50 byte payload per 20ms */ - }; - - if (cs > ARRAY_SIZE(max_lr_per_ts)) - cs = 1; + int bytes_per_rlc_block = cs.maxDataBlockBytes() * cs.numDataBlocks(); - return max_lr_per_ts[cs-1] * num_pdch; + /* n byte payload per 20ms */ + return bytes_per_rlc_block * (1000 / 20) * num_pdch; } static uint32_t compute_bucket_size(struct gprs_rlcmac_bts *bts, @@ -618,6 +611,45 @@ static int get_and_reset_measured_leak_rate(int *usage_by_1000, unsigned num_pdc return rate; } +static GprsCodingScheme max_coding_scheme_dl(struct gprs_rlcmac_bts *bts) +{ + int num; + + if (bts->egprs_enabled) { + if (!bts->cs_adj_enabled) { + if (bts->initial_mcs_dl) + num = bts->initial_mcs_dl; + else + num = 1; + } else if (bts->max_mcs_dl) { + num = bts->max_mcs_dl; + } else { + num = 9; + } + + return GprsCodingScheme::getEgprsByNum(num); + } + + if (!bts->cs_adj_enabled) { + if (bts->initial_cs_dl) + num = bts->initial_cs_dl; + else if (bts->cs4) + num = 4; + else if (bts->cs3) + num = 3; + else if (bts->cs2) + num = 2; + else + num = 1; + } else if (bts->max_cs_dl) { + num = bts->max_cs_dl; + } else { + num = 4; + } + + return GprsCodingScheme::getGprsByNum(num); +} + int gprs_bssgp_tx_fc_bvc(void) { struct gprs_rlcmac_bts *bts; @@ -627,7 +659,7 @@ int gprs_bssgp_tx_fc_bvc(void) uint32_t ms_leak_rate; /* oct/s */ uint32_t avg_delay_ms; int num_pdch = -1; - int max_cs_dl; + GprsCodingScheme max_cs_dl; if (!the_pcu.bctx) { LOGP(DBSSGP, LOGL_ERROR, "No bctx\n"); @@ -635,21 +667,7 @@ int gprs_bssgp_tx_fc_bvc(void) } bts = bts_main_data(); - if (bts->cs_adj_enabled) { - max_cs_dl = bts->max_cs_dl; - if (!max_cs_dl) { - if (bts->cs4) - max_cs_dl = 4; - else if (bts->cs3) - max_cs_dl = 3; - else if (bts->cs2) - max_cs_dl = 2; - else - max_cs_dl = 1; - } - } else { - max_cs_dl = bts->initial_cs_dl; - } + max_cs_dl = max_coding_scheme_dl(bts); bucket_size = bts->fc_bvc_bucket_size; leak_rate = bts->fc_bvc_leak_rate; @@ -683,8 +701,8 @@ int gprs_bssgp_tx_fc_bvc(void) leak_rate = gprs_bssgp_max_leak_rate(max_cs_dl, num_pdch); LOGP(DBSSGP, LOGL_DEBUG, - "Computed BVC leak rate = %d, num_pdch = %d, cs = %d\n", - leak_rate, num_pdch, max_cs_dl); + "Computed BVC leak rate = %d, num_pdch = %d, cs = %s\n", + leak_rate, num_pdch, max_cs_dl.name()); }; if (ms_leak_rate == 0) { @@ -706,8 +724,9 @@ int gprs_bssgp_tx_fc_bvc(void) * should be derived from the max number of PDCH TS per TRX. */ LOGP(DBSSGP, LOGL_DEBUG, - "Computed MS default leak rate = %d, ms_num_pdch = %d, cs = %d\n", - ms_leak_rate, ms_num_pdch, max_cs_dl); + "Computed MS default leak rate = %d, ms_num_pdch = %d, " + "cs = %s\n", + ms_leak_rate, ms_num_pdch, max_cs_dl.name()); }; /* TODO: Force leak_rate to 0 on buffer bloat */ -- cgit v1.2.3