From Bhargava.Abhyankar at radisys.com Fri Apr 1 13:58:25 2016 From: Bhargava.Abhyankar at radisys.com (Bhargava Abhyankar) Date: Fri, 1 Apr 2016 19:28:25 +0530 Subject: [PATCH] Change interface in osmo-bts for 11 bit RACH Message-ID: <1459519105-6525-1-git-send-email-Bhargava.Abhyankar@radisys.com> Interface structure between osmo-bts and osmo-pcu is updated with the parameters to differentiate the type of RACH and further support 11 bit RACH. The function prototype and definitions are changed accordingly. Interface version number is increaded. --- include/osmo-bts/pcu_if.h | 3 ++- include/osmo-bts/pcuif_proto.h | 6 ++++-- src/common/l1sap.c | 3 ++- src/common/pcu_sock.c | 5 ++++- src/osmo-bts-sysmo/l1_if.c | 6 ++++++ 5 files changed, 18 insertions(+), 5 deletions(-) diff --git a/include/osmo-bts/pcu_if.h b/include/osmo-bts/pcu_if.h index 0c4fb69..0c0f0b2 100644 --- a/include/osmo-bts/pcu_if.h +++ b/include/osmo-bts/pcu_if.h @@ -11,7 +11,8 @@ int pcu_tx_rts_req(struct gsm_bts_trx_ts *ts, uint8_t is_ptcch, uint32_t fn, int pcu_tx_data_ind(struct gsm_bts_trx_ts *ts, uint8_t is_ptcch, uint32_t fn, uint16_t arfcn, uint8_t block_nr, uint8_t *data, uint8_t len, int8_t rssi); -int pcu_tx_rach_ind(struct gsm_bts *bts, int16_t qta, uint8_t ra, uint32_t fn); +int pcu_tx_rach_ind(struct gsm_bts *bts, int16_t qta, uint16_t ra, uint32_t fn, + uint8_t is_11bit, enum ph_burst_type burst); int pcu_tx_time_ind(uint32_t fn); int pcu_tx_pag_req(const uint8_t *identity_lv, uint8_t chan_needed); int pcu_tx_pch_data_cnf(uint32_t fn, uint8_t *data, uint8_t len); diff --git a/include/osmo-bts/pcuif_proto.h b/include/osmo-bts/pcuif_proto.h index 9d740ac..b965d7c 100644 --- a/include/osmo-bts/pcuif_proto.h +++ b/include/osmo-bts/pcuif_proto.h @@ -1,7 +1,7 @@ #ifndef _PCUIF_PROTO_H #define _PCUIF_PROTO_H -#define PCU_IF_VERSION 0x05 +#define PCU_IF_VERSION 0x06 /* msg_type */ #define PCU_IF_MSG_DATA_REQ 0x00 /* send data to given channel */ @@ -64,10 +64,12 @@ struct gsm_pcu_if_rts_req { struct gsm_pcu_if_rach_ind { uint8_t sapi; - uint8_t ra; + uint16_t ra; int16_t qta; uint32_t fn; uint16_t arfcn; + uint8_t is_11bit; + enum ph_burst_type burst; } __attribute__ ((packed)); struct gsm_pcu_if_info_trx { diff --git a/src/common/l1sap.c b/src/common/l1sap.c index ac398d3..2b2e8f4 100644 --- a/src/common/l1sap.c +++ b/src/common/l1sap.c @@ -903,7 +903,8 @@ static int l1sap_ph_rach_ind(struct gsm_bts_trx *trx, if (trx == bts->c0 && L1SAP_IS_PACKET_RACH(rach_ind->ra)) { LOGP(DL1P, LOGL_INFO, "RACH for packet access\n"); pcu_tx_rach_ind(bts, rach_ind->acc_delay << 2, - rach_ind->ra, rach_ind->fn); + rach_ind->ra, rach_ind->fn, + rach_ind->is_11bit, rach_ind->burst); return 0; } diff --git a/src/common/pcu_sock.c b/src/common/pcu_sock.c index 7c835fb..d7825f0 100644 --- a/src/common/pcu_sock.c +++ b/src/common/pcu_sock.c @@ -343,7 +343,8 @@ int pcu_tx_data_ind(struct gsm_bts_trx_ts *ts, uint8_t is_ptcch, uint32_t fn, return pcu_sock_send(&bts_gsmnet, msg); } -int pcu_tx_rach_ind(struct gsm_bts *bts, int16_t qta, uint8_t ra, uint32_t fn) +int pcu_tx_rach_ind(struct gsm_bts *bts, int16_t qta, uint16_t ra, uint32_t fn, + uint8_t is_11bit, enum ph_burst_type burst) { struct msgb *msg; struct gsm_pcu_if *pcu_prim; @@ -362,6 +363,8 @@ int pcu_tx_rach_ind(struct gsm_bts *bts, int16_t qta, uint8_t ra, uint32_t fn) rach_ind->ra = ra; rach_ind->qta = qta; rach_ind->fn = fn; + rach_ind->is_11bit = is_11bit; + rach_ind->burst = burst; return pcu_sock_send(&bts_gsmnet, msg); } diff --git a/src/osmo-bts-sysmo/l1_if.c b/src/osmo-bts-sysmo/l1_if.c index debc80a..a8f957c 100644 --- a/src/osmo-bts-sysmo/l1_if.c +++ b/src/osmo-bts-sysmo/l1_if.c @@ -898,6 +898,12 @@ static int handle_ph_ra_ind(struct femtol1_hdl *fl1, GsmL1_PhRaInd_t *ra_ind, l1sap->u.rach_ind.ra = ra; l1sap->u.rach_ind.acc_delay = acc_delay; l1sap->u.rach_ind.fn = fn; + + /* Initialising the parameters needs to be handled when 11 bit RACH + * is supported */ + l1sap->u.rach_ind.is_11bit = 0; + l1sap->u.rach_ind.burst = GSM_L1_BURST_TYPE_ACCESS_0; + if (!lchan || lchan->ts->pchan == GSM_PCHAN_CCCH || lchan->ts->pchan == GSM_PCHAN_CCCH_SDCCH4) l1sap->u.rach_ind.chan_nr = 0x88; -- 2.5.0 From Bhargava.Abhyankar at radisys.com Fri Apr 1 13:59:22 2016 From: Bhargava.Abhyankar at radisys.com (Bhargava Abhyankar) Date: Fri, 1 Apr 2016 19:29:22 +0530 Subject: [PATCH] Change interface in osmo-pcu for 11 bit RACH Message-ID: <1459519162-6579-1-git-send-email-Bhargava.Abhyankar@radisys.com> Interface structure between osmo-bts and osmo-pcu is updated with the parameters to differentiate the type of RACH and further support 11 bit RACH. The function prototype and definitions are changed accordingly. Interface version number is increased. --- src/bts.cpp | 3 ++- src/bts.h | 4 +++- src/pcu_l1_if.cpp | 3 ++- src/pcuif_proto.h | 8 ++++++-- tests/tbf/TbfTest.cpp | 5 +++-- 5 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/bts.cpp b/src/bts.cpp index 715fb51..62b00c4 100644 --- a/src/bts.cpp +++ b/src/bts.cpp @@ -459,7 +459,8 @@ int BTS::rcv_imm_ass_cnf(const uint8_t *data, uint32_t fn) return 0; } -int BTS::rcv_rach(uint8_t ra, uint32_t Fn, int16_t qta) +int BTS::rcv_rach(uint16_t ra, uint32_t Fn, int16_t qta, uint8_t is_11bit, + enum ph_burst_type burst) { struct gprs_rlcmac_ul_tbf *tbf = NULL; uint8_t trx_no, ts_no = 0; diff --git a/src/bts.h b/src/bts.h index c975304..f0fe970 100644 --- a/src/bts.h +++ b/src/bts.h @@ -28,6 +28,7 @@ extern "C" { #include #include #include +#include } #include "poll_controller.h" @@ -275,7 +276,8 @@ public: int tfi_find_free(enum gprs_rlcmac_tbf_direction dir, uint8_t *_trx, int8_t use_trx); int rcv_imm_ass_cnf(const uint8_t *data, uint32_t fn); - int rcv_rach(uint8_t ra, uint32_t Fn, int16_t qta); + int rcv_rach(uint16_t ra, uint32_t Fn, int16_t qta, uint8_t is_11bit, + enum ph_burst_type burst); void trigger_dl_ass(gprs_rlcmac_dl_tbf *tbf, gprs_rlcmac_tbf *old_tbf); void snd_dl_ass(gprs_rlcmac_tbf *tbf, uint8_t poll, const char *imsi); diff --git a/src/pcu_l1_if.cpp b/src/pcu_l1_if.cpp index 19dda5c..dbf713c 100644 --- a/src/pcu_l1_if.cpp +++ b/src/pcu_l1_if.cpp @@ -313,7 +313,8 @@ static int pcu_rx_rach_ind(struct gsm_pcu_if_rach_ind *rach_ind) case PCU_IF_SAPI_RACH: rc = BTS::main_bts()->rcv_rach( rach_ind->ra, rach_ind->fn, - rach_ind->qta); + rach_ind->qta, rach_ind->is_11bit, + rach_ind->burst); break; default: LOGP(DL1IF, LOGL_ERROR, "Received PCU rach request with " diff --git a/src/pcuif_proto.h b/src/pcuif_proto.h index 9d740ac..eb11770 100644 --- a/src/pcuif_proto.h +++ b/src/pcuif_proto.h @@ -1,7 +1,9 @@ #ifndef _PCUIF_PROTO_H #define _PCUIF_PROTO_H -#define PCU_IF_VERSION 0x05 +#include + +#define PCU_IF_VERSION 0x06 /* msg_type */ #define PCU_IF_MSG_DATA_REQ 0x00 /* send data to given channel */ @@ -64,10 +66,12 @@ struct gsm_pcu_if_rts_req { struct gsm_pcu_if_rach_ind { uint8_t sapi; - uint8_t ra; + uint16_t ra; int16_t qta; uint32_t fn; uint16_t arfcn; + uint8_t is_11bit; + enum ph_burst_type burst; } __attribute__ ((packed)); struct gsm_pcu_if_info_trx { diff --git a/tests/tbf/TbfTest.cpp b/tests/tbf/TbfTest.cpp index e1be844..1123ac6 100644 --- a/tests/tbf/TbfTest.cpp +++ b/tests/tbf/TbfTest.cpp @@ -35,6 +35,7 @@ extern "C" { #include #include #include +#include } #include @@ -552,7 +553,7 @@ static gprs_rlcmac_ul_tbf *establish_ul_tbf_single_phase(BTS *the_bts, tfi = the_bts->tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1); - the_bts->rcv_rach(0x03, *fn, qta); + the_bts->rcv_rach(0x03, *fn, qta, 0, GSM_L1_BURST_TYPE_ACCESS_0); ul_tbf = the_bts->ul_tbf_by_tfi(tfi, trx_no, ts_no); OSMO_ASSERT(ul_tbf != NULL); @@ -639,7 +640,7 @@ static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase(BTS *the_bts, request_dl_rlc_block(bts, trx_no, ts_no, 0, fn); /* simulate RACH, this sends an Immediate Assignment Uplink on the AGCH */ - the_bts->rcv_rach(0x73, rach_fn, qta); + the_bts->rcv_rach(0x73, rach_fn, qta, 0, GSM_L1_BURST_TYPE_ACCESS_0); /* get next free TFI */ tfi = the_bts->tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1); -- 2.5.0 From Bhargava.Abhyankar at radisys.com Fri Apr 1 13:57:28 2016 From: Bhargava.Abhyankar at radisys.com (Bhargava Abhyankar) Date: Fri, 1 Apr 2016 19:27:28 +0530 Subject: [PATCH] Update structure in libosmocore for 11 bit RACH Message-ID: <1459519048-6471-1-git-send-email-Bhargava.Abhyankar@radisys.com> Parameters are added to the structure ph_rach_ind_param to differentiate the type of RACH received from Layer 1. This is to further support the 11 bit RACH. --- include/osmocom/gsm/l1sap.h | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/include/osmocom/gsm/l1sap.h b/include/osmocom/gsm/l1sap.h index 1af8ba8..d7bd172 100644 --- a/include/osmocom/gsm/l1sap.h +++ b/include/osmocom/gsm/l1sap.h @@ -44,12 +44,21 @@ struct ph_rach_req_param { uint16_t offset; /*!< \brief Timing Offset */ }; +/*! \brief for PH_RA_IND burstType inforamtion */ +enum ph_burst_type { + GSM_L1_BURST_TYPE_ACCESS_0 = 4, + GSM_L1_BURST_TYPE_ACCESS_1, + GSM_L1_BURST_TYPE_ACCESS_2 +}; + /*! \brief for PH-RANDOM_ACCESS.ind */ struct ph_rach_ind_param { uint8_t chan_nr; /*!< \brief Channel Number (Like RSL) */ - uint8_t ra; /*!< \brief Random Access */ + uint16_t ra; /*!< \brief Random Access */ uint8_t acc_delay; /*!< \brief Delay in bit periods */ uint32_t fn; /*!< \brief GSM Frame Number at time of RA */ + uint8_t is_11bit; /*!< \brief no.of bits in RACH*/ + enum ph_burst_type burst; /*!< \brief type of burst*/ }; /*! \brief for PH-[UNIT]DATA.{req,ind} | PH-RTS.ind */ -- 2.5.0 From Prasad.Kaup at radisys.com Fri Apr 1 15:14:45 2016 From: Prasad.Kaup at radisys.com (Prasad Kaup) Date: Fri, 1 Apr 2016 15:14:45 +0000 Subject: Regarding integration of NURAN L1 1.0 In-Reply-To: <86E210CFD3EEDE46A58DE4793CFA6C3F037CBC9E@NTWAEX01.interne.lyrtech.com> References: <86E210CFD3EEDE46A58DE4793CFA6C3F0373171A@NTWAEX01.interne.lyrtech.com> <20160314001234.GE10039@dub6> <86E210CFD3EEDE46A58DE4793CFA6C3F03732069@NTWAEX01.interne.lyrtech.com> <86E210CFD3EEDE46A58DE4793CFA6C3F0373244D@NTWAEX01.interne.lyrtech.com> <86E210CFD3EEDE46A58DE4793CFA6C3F037CBC9E@NTWAEX01.interne.lyrtech.com> Message-ID: Hi Minh-Quang Nguyen, We are able to connect and make GSM voice calls with mobiles. We are also able to attach and activate PDP context in case of GPRS. We are trying to configure the setup for GPRS connectivity towards internet. We understand that iptables needs to be configured for external connectivity. Can you let us know some more details of configuration to enable external connectivity from GGSN and "tun0" interface ? Regards Prasad From minh-quang.nguyen at nutaq.com Fri Apr 1 15:34:58 2016 From: minh-quang.nguyen at nutaq.com (Minh-Quang Nguyen) Date: Fri, 1 Apr 2016 11:34:58 -0400 Subject: Regarding integration of NURAN L1 1.0 References: <86E210CFD3EEDE46A58DE4793CFA6C3F0373171A@NTWAEX01.interne.lyrtech.com> <20160314001234.GE10039@dub6> <86E210CFD3EEDE46A58DE4793CFA6C3F03732069@NTWAEX01.interne.lyrtech.com> <86E210CFD3EEDE46A58DE4793CFA6C3F0373244D@NTWAEX01.interne.lyrtech.com> <86E210CFD3EEDE46A58DE4793CFA6C3F037CBC9E@NTWAEX01.interne.lyrtech.com> Message-ID: <86E210CFD3EEDE46A58DE4793CFA6C3F037CC081@NTWAEX01.interne.lyrtech.com> Hi Prasad, It's good to know you are able to compile everything and make GSM voice calls with mobiles. Regarding to GTP tunnel, I am guiding you to Osmocom GPRS wiki URL below for more information http://openbsc.osmocom.org/trac/wiki/OpenBSC_GPRS Regards, Minh-Quang Nguyen Concepteur logiciel??|??Software designer GSM/Network T. 418 914-7484 x2296??|??1 855 914-7484??|??F. 418 914-9477 2150, Cyrille-Duquet, Qu?bec (Qu?bec)??G1N 2G3 CANADA minh-quang.nguyen at nutaq.com www.nutaq.com QUEBEC MONTREAL NEW YORK Facebook Twitter LinkedIn YouTube -----Original Message----- From: Prasad Kaup [mailto:Prasad.Kaup at radisys.com] Sent: Friday, April 01, 2016 11:15 AM To: Minh-Quang Nguyen; Neels Hofmeyr; osmocom-net-gprs at lists.osmocom.org Cc: Saurabh Sharan; Yves Godin Subject: RE: Regarding integration of NURAN L1 1.0 Hi Minh-Quang Nguyen, We are able to connect and make GSM voice calls with mobiles. We are also able to attach and activate PDP context in case of GPRS. We are trying to configure the setup for GPRS connectivity towards internet. We understand that iptables needs to be configured for external connectivity. Can you let us know some more details of configuration to enable external connectivity from GGSN and "tun0" interface ? Regards Prasad From arvind.sirsikar at radisys.com Tue Apr 5 07:37:34 2016 From: arvind.sirsikar at radisys.com (Aravind Sirsikar) Date: Tue, 5 Apr 2016 13:07:34 +0530 Subject: [PATCH] Add test cases for EGPRS retransmission in DL Message-ID: <1459841854-18042-1-git-send-email-arvind.sirsikar@radisys.com> Add test cases to validate retransmission of EGPRS RLC data block for all the MCS in downlink direction without support of MCS change during retransmission --- tests/tbf/TbfTest.cpp | 88 ++++++ tests/tbf/TbfTest.err | 833 +++++++++++++++++++++++++++++++++++++++++++++++++ tests/tbf/TbfTest.ok | 11 + 3 files changed, 932 insertions(+) diff --git a/tests/tbf/TbfTest.cpp b/tests/tbf/TbfTest.cpp index e1be844..3fa0625 100644 --- a/tests/tbf/TbfTest.cpp +++ b/tests/tbf/TbfTest.cpp @@ -1213,6 +1213,72 @@ static void test_tbf_egprs_two_phase() printf("=== end %s ===\n", __func__); } +static void establish_and_use_egprs_dl_tbf_for_retx(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 for retx\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(test_data); i++) + test_data[i] = i%512; + + OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW)); + + /* Schedule a LLC frame */ + dl_tbf->append_data(ms_class, 1000, test_data, 100); + + OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW)); + + /* Send only a few RLC/MAC blocks */ + fn = 0; + uint8_t block_nr = 0; + int index1 = 0; + + while (index1 < 4) { + /* Request to send one block */ + request_dl_rlc_block(dl_tbf, &fn, &block_nr); + index1++; + if (dl_tbf->m_window.m_v_b.is_unacked(0)) + dl_tbf->m_window.m_v_b.mark_nacked(0); + if (mcs > 6) + if (dl_tbf->m_window.m_v_b.is_unacked(1)) + dl_tbf->m_window.m_v_b.mark_nacked(1); + + } + + /* 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 establish_and_use_egprs_dl_tbf(BTS *the_bts, int mcs) { unsigned i; @@ -1272,6 +1338,27 @@ static void establish_and_use_egprs_dl_tbf(BTS *the_bts, int mcs) tbf_free(dl_tbf); } +static void test_tbf_egprs_retx_dl(void) +{ + 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_for_retx(&the_bts, i); + + printf("=== end %s ===\n", __func__); +} + static void test_tbf_egprs_dl() { BTS the_bts; @@ -1356,6 +1443,7 @@ int main(int argc, char **argv) test_tbf_ws(); test_tbf_egprs_two_phase(); test_tbf_egprs_dl(); + test_tbf_egprs_retx_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 9bea2fd..c4642f3 100644 --- a/tests/tbf/TbfTest.err +++ b/tests/tbf/TbfTest.err @@ -5113,3 +5113,836 @@ PDCH(TS 4, TRX 0): Detaching TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=RELEASING EG 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 03 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) +- Sending new block at BSN 0, CS=MCS-1 +- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (len=100) +-- Chunk with length 100 larger than space (22) left in block: copy only remaining space, and we are done +data block (BSN 0, MCS-1): 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 +- Copying data unit 0 (BSN 0) +msg block (BSN 0, MCS-1): 07 00 00 96 00 02 04 06 08 0a 0c 0e 10 12 14 16 18 1a 1c 1e 20 22 24 26 28 2a 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=4 block=1 data=07 00 00 96 00 02 04 06 08 0a 0c 0e 10 12 14 16 18 1a 1c 1e 20 22 24 26 28 2a 00 +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) +- Resending BSN 0 +- Copying data unit 0 (BSN 0) +msg block (BSN 0, MCS-1): 07 00 00 98 00 02 04 06 08 0a 0c 0e 10 12 14 16 18 1a 1c 1e 20 22 24 26 28 2a 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=8 block=2 data=07 00 00 98 00 02 04 06 08 0a 0c 0e 10 12 14 16 18 1a 1c 1e 20 22 24 26 28 2a 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)==1) +- Resending BSN 0 +- Copying data unit 0 (BSN 0) +msg block (BSN 0, MCS-1): 07 00 00 96 00 02 04 06 08 0a 0c 0e 10 12 14 16 18 1a 1c 1e 20 22 24 26 28 2a 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=13 block=3 data=07 00 00 96 00 02 04 06 08 0a 0c 0e 10 12 14 16 18 1a 1c 1e 20 22 24 26 28 2a 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)==1) +- Resending BSN 0 +- Copying data unit 0 (BSN 0) +msg block (BSN 0, MCS-1): 07 00 00 98 00 02 04 06 08 0a 0c 0e 10 12 14 16 18 1a 1c 1e 20 22 24 26 28 2a 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=17 block=4 data=07 00 00 98 00 02 04 06 08 0a 0c 0e 10 12 14 16 18 1a 1c 1e 20 22 24 26 28 2a 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)==1) +- Sending new block at BSN 1, CS=MCS-1 +-- Chunk with length 78 larger than space (22) left in block: copy only remaining space, and we are done +data block (BSN 1, MCS-1): 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b +- Copying data unit 0 (BSN 1) +msg block (BSN 1, MCS-1): 07 40 00 96 2c 2e 30 32 34 36 38 3a 3c 3e 40 42 44 46 48 4a 4c 4e 50 52 54 56 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=21 block=5 data=07 40 00 96 2c 2e 30 32 34 36 38 3a 3c 3e 40 42 44 46 48 4a 4c 4e 50 52 54 56 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 56 larger than space (22) left in block: copy only remaining space, and we are done +data block (BSN 2, MCS-1): 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 40 41 +- Copying data unit 0 (BSN 2) +msg block (BSN 2, MCS-1): 07 80 00 96 58 5a 5c 5e 60 62 64 66 68 6a 6c 6e 70 72 74 76 78 7a 7c 7e 80 82 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=26 block=6 data=07 80 00 96 58 5a 5c 5e 60 62 64 66 68 6a 6c 6e 70 72 74 76 78 7a 7c 7e 80 82 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 34 larger than space (22) left in block: copy only remaining space, and we are done +data block (BSN 3, MCS-1): 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 +- Copying data unit 0 (BSN 3) +msg block (BSN 3, MCS-1): 07 c0 00 96 84 86 88 8a 8c 8e 90 92 94 96 98 9a 9c 9e a0 a2 a4 a6 a8 aa ac ae 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=30 block=7 data=07 c0 00 96 84 86 88 8a 8c 8e 90 92 94 96 98 9a 9c 9e a0 a2 a4 a6 a8 aa ac ae 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 12 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=100 +-- Empty chunk, added LLC dummy command of size 8, drained_since=0 +-- Chunk with length 8 is less than remaining space (9): 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=8 +data block (BSN 4, MCS-1): 18 11 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 43 c0 01 2b 2b 2b 2b 2b +- 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 16 30 22 b0 b2 b4 b6 b8 ba bc be c0 c2 c4 c6 86 80 03 56 56 56 56 56 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=34 block=8 data=07 00 01 16 30 22 b0 b2 b4 b6 b8 ba bc be c0 c2 c4 c6 86 80 03 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 03 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) +- Sending new block at BSN 0, CS=MCS-2 +- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (len=100) +-- Chunk with length 100 larger than space (28) left in block: copy only remaining space, and we are done +data block (BSN 0, MCS-2): 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b +- Copying data unit 0 (BSN 0) +msg block (BSN 0, MCS-2): 07 00 00 92 00 02 04 06 08 0a 0c 0e 10 12 14 16 18 1a 1c 1e 20 22 24 26 28 2a 2c 2e 30 32 34 36 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=4 block=1 data=07 00 00 92 00 02 04 06 08 0a 0c 0e 10 12 14 16 18 1a 1c 1e 20 22 24 26 28 2a 2c 2e 30 32 34 36 00 +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) +- Resending BSN 0 +- Copying data unit 0 (BSN 0) +msg block (BSN 0, MCS-2): 07 00 00 94 00 02 04 06 08 0a 0c 0e 10 12 14 16 18 1a 1c 1e 20 22 24 26 28 2a 2c 2e 30 32 34 36 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=8 block=2 data=07 00 00 94 00 02 04 06 08 0a 0c 0e 10 12 14 16 18 1a 1c 1e 20 22 24 26 28 2a 2c 2e 30 32 34 36 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)==1) +- Resending BSN 0 +- Copying data unit 0 (BSN 0) +msg block (BSN 0, MCS-2): 07 00 00 92 00 02 04 06 08 0a 0c 0e 10 12 14 16 18 1a 1c 1e 20 22 24 26 28 2a 2c 2e 30 32 34 36 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=13 block=3 data=07 00 00 92 00 02 04 06 08 0a 0c 0e 10 12 14 16 18 1a 1c 1e 20 22 24 26 28 2a 2c 2e 30 32 34 36 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)==1) +- Resending BSN 0 +- Copying data unit 0 (BSN 0) +msg block (BSN 0, MCS-2): 07 00 00 94 00 02 04 06 08 0a 0c 0e 10 12 14 16 18 1a 1c 1e 20 22 24 26 28 2a 2c 2e 30 32 34 36 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=17 block=4 data=07 00 00 94 00 02 04 06 08 0a 0c 0e 10 12 14 16 18 1a 1c 1e 20 22 24 26 28 2a 2c 2e 30 32 34 36 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)==1) +- Sending new block at BSN 1, CS=MCS-2 +-- Chunk with length 72 larger than space (28) left in block: copy only remaining space, and we are done +data block (BSN 1, MCS-2): 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 +- Copying data unit 0 (BSN 1) +msg block (BSN 1, MCS-2): 07 40 00 92 38 3a 3c 3e 40 42 44 46 48 4a 4c 4e 50 52 54 56 58 5a 5c 5e 60 62 64 66 68 6a 6c 6e 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=21 block=5 data=07 40 00 92 38 3a 3c 3e 40 42 44 46 48 4a 4c 4e 50 52 54 56 58 5a 5c 5e 60 62 64 66 68 6a 6c 6e 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 44 larger than space (28) left in block: copy only remaining space, and we are done +data block (BSN 2, MCS-2): 38 39 3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 +- Copying data unit 0 (BSN 2) +msg block (BSN 2, MCS-2): 07 80 00 92 70 72 74 76 78 7a 7c 7e 80 82 84 86 88 8a 8c 8e 90 92 94 96 98 9a 9c 9e a0 a2 a4 a6 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=26 block=6 data=07 80 00 92 70 72 74 76 78 7a 7c 7e 80 82 84 86 88 8a 8c 8e 90 92 94 96 98 9a 9c 9e a0 a2 a4 a6 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 16 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=100 +-- 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 3, MCS-2): 20 15 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 43 c0 01 2b 2b 2b 2b 2b 2b 2b +- 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 12 40 2a a8 aa ac ae b0 b2 b4 b6 b8 ba bc be c0 c2 c4 c6 86 80 03 56 56 56 56 56 56 56 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=30 block=7 data=07 c0 00 12 40 2a a8 aa ac ae b0 b2 b4 b6 b8 ba bc be c0 c2 c4 c6 86 80 03 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 03 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) +- Sending new block at BSN 0, CS=MCS-3 +- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (len=100) +-- Chunk with length 100 larger than space (37) left in block: copy only remaining space, and we are done +data block (BSN 0, MCS-3): 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 +- Copying data unit 0 (BSN 0) +msg block (BSN 0, MCS-3): 07 00 00 86 00 02 04 06 08 0a 0c 0e 10 12 14 16 18 1a 1c 1e 20 22 24 26 28 2a 2c 2e 30 32 34 36 38 3a 3c 3e 40 42 44 46 48 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=4 block=1 data=07 00 00 86 00 02 04 06 08 0a 0c 0e 10 12 14 16 18 1a 1c 1e 20 22 24 26 28 2a 2c 2e 30 32 34 36 38 3a 3c 3e 40 42 44 46 48 00 +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) +- Resending BSN 0 +- Copying data unit 0 (BSN 0) +msg block (BSN 0, MCS-3): 07 00 00 88 00 02 04 06 08 0a 0c 0e 10 12 14 16 18 1a 1c 1e 20 22 24 26 28 2a 2c 2e 30 32 34 36 38 3a 3c 3e 40 42 44 46 48 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=8 block=2 data=07 00 00 88 00 02 04 06 08 0a 0c 0e 10 12 14 16 18 1a 1c 1e 20 22 24 26 28 2a 2c 2e 30 32 34 36 38 3a 3c 3e 40 42 44 46 48 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)==1) +- Resending BSN 0 +- Copying data unit 0 (BSN 0) +msg block (BSN 0, MCS-3): 07 00 00 8a 00 02 04 06 08 0a 0c 0e 10 12 14 16 18 1a 1c 1e 20 22 24 26 28 2a 2c 2e 30 32 34 36 38 3a 3c 3e 40 42 44 46 48 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=13 block=3 data=07 00 00 8a 00 02 04 06 08 0a 0c 0e 10 12 14 16 18 1a 1c 1e 20 22 24 26 28 2a 2c 2e 30 32 34 36 38 3a 3c 3e 40 42 44 46 48 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)==1) +- Resending BSN 0 +- Copying data unit 0 (BSN 0) +msg block (BSN 0, MCS-3): 07 00 00 86 00 02 04 06 08 0a 0c 0e 10 12 14 16 18 1a 1c 1e 20 22 24 26 28 2a 2c 2e 30 32 34 36 38 3a 3c 3e 40 42 44 46 48 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=17 block=4 data=07 00 00 86 00 02 04 06 08 0a 0c 0e 10 12 14 16 18 1a 1c 1e 20 22 24 26 28 2a 2c 2e 30 32 34 36 38 3a 3c 3e 40 42 44 46 48 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)==1) +- Sending new block at BSN 1, CS=MCS-3 +-- Chunk with length 63 larger than space (37) left in block: copy only remaining space, and we are done +data block (BSN 1, MCS-3): 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 +- Copying data unit 0 (BSN 1) +msg block (BSN 1, MCS-3): 07 40 00 86 4a 4c 4e 50 52 54 56 58 5a 5c 5e 60 62 64 66 68 6a 6c 6e 70 72 74 76 78 7a 7c 7e 80 82 84 86 88 8a 8c 8e 90 92 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=21 block=5 data=07 40 00 86 4a 4c 4e 50 52 54 56 58 5a 5c 5e 60 62 64 66 68 6a 6c 6e 70 72 74 76 78 7a 7c 7e 80 82 84 86 88 8a 8c 8e 90 92 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 26 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=100 +-- Empty chunk, added LLC dummy command of size 9, drained_since=0 +-- Chunk with length 9 is less than remaining space (10): 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=9 +data block (BSN 2, MCS-3): 34 13 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 43 c0 01 2b 2b 2b 2b 2b 2b +- 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 06 68 26 94 96 98 9a 9c 9e a0 a2 a4 a6 a8 aa ac ae b0 b2 b4 b6 b8 ba bc be c0 c2 c4 c6 86 80 03 56 56 56 56 56 56 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=26 block=6 data=07 80 00 06 68 26 94 96 98 9a 9c 9e a0 a2 a4 a6 a8 aa ac ae b0 b2 b4 b6 b8 ba bc be c0 c2 c4 c6 86 80 03 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 03 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) +- Sending new block at BSN 0, CS=MCS-4 +- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (len=100) +-- Chunk with length 100 larger than space (44) left in block: copy only remaining space, and we are done +data block (BSN 0, MCS-4): 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b +- Copying data unit 0 (BSN 0) +msg block (BSN 0, MCS-4): 07 00 00 80 00 02 04 06 08 0a 0c 0e 10 12 14 16 18 1a 1c 1e 20 22 24 26 28 2a 2c 2e 30 32 34 36 38 3a 3c 3e 40 42 44 46 48 4a 4c 4e 50 52 54 56 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=4 block=1 data=07 00 00 80 00 02 04 06 08 0a 0c 0e 10 12 14 16 18 1a 1c 1e 20 22 24 26 28 2a 2c 2e 30 32 34 36 38 3a 3c 3e 40 42 44 46 48 4a 4c 4e 50 52 54 56 00 +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) +- Resending BSN 0 +- Copying data unit 0 (BSN 0) +msg block (BSN 0, MCS-4): 07 00 00 82 00 02 04 06 08 0a 0c 0e 10 12 14 16 18 1a 1c 1e 20 22 24 26 28 2a 2c 2e 30 32 34 36 38 3a 3c 3e 40 42 44 46 48 4a 4c 4e 50 52 54 56 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=8 block=2 data=07 00 00 82 00 02 04 06 08 0a 0c 0e 10 12 14 16 18 1a 1c 1e 20 22 24 26 28 2a 2c 2e 30 32 34 36 38 3a 3c 3e 40 42 44 46 48 4a 4c 4e 50 52 54 56 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)==1) +- Resending BSN 0 +- Copying data unit 0 (BSN 0) +msg block (BSN 0, MCS-4): 07 00 00 84 00 02 04 06 08 0a 0c 0e 10 12 14 16 18 1a 1c 1e 20 22 24 26 28 2a 2c 2e 30 32 34 36 38 3a 3c 3e 40 42 44 46 48 4a 4c 4e 50 52 54 56 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=13 block=3 data=07 00 00 84 00 02 04 06 08 0a 0c 0e 10 12 14 16 18 1a 1c 1e 20 22 24 26 28 2a 2c 2e 30 32 34 36 38 3a 3c 3e 40 42 44 46 48 4a 4c 4e 50 52 54 56 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)==1) +- Resending BSN 0 +- Copying data unit 0 (BSN 0) +msg block (BSN 0, MCS-4): 07 00 00 80 00 02 04 06 08 0a 0c 0e 10 12 14 16 18 1a 1c 1e 20 22 24 26 28 2a 2c 2e 30 32 34 36 38 3a 3c 3e 40 42 44 46 48 4a 4c 4e 50 52 54 56 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=17 block=4 data=07 00 00 80 00 02 04 06 08 0a 0c 0e 10 12 14 16 18 1a 1c 1e 20 22 24 26 28 2a 2c 2e 30 32 34 36 38 3a 3c 3e 40 42 44 46 48 4a 4c 4e 50 52 54 56 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)==1) +- Sending new block at BSN 1, CS=MCS-4 +-- Chunk with length 56 larger than space (44) left in block: copy only remaining space, and we are done +data block (BSN 1, MCS-4): 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 +- Copying data unit 0 (BSN 1) +msg block (BSN 1, MCS-4): 07 40 00 80 58 5a 5c 5e 60 62 64 66 68 6a 6c 6e 70 72 74 76 78 7a 7c 7e 80 82 84 86 88 8a 8c 8e 90 92 94 96 98 9a 9c 9e a0 a2 a4 a6 a8 aa ac ae 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=21 block=5 data=07 40 00 80 58 5a 5c 5e 60 62 64 66 68 6a 6c 6e 70 72 74 76 78 7a 7c 7e 80 82 84 86 88 8a 8c 8e 90 92 94 96 98 9a 9c 9e a0 a2 a4 a6 a8 aa ac ae 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 12 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=100 +-- 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 2, MCS-4): 18 3d 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 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 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 00 30 7a b0 b2 b4 b6 b8 ba bc be c0 c2 c4 c6 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 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=26 block=6 data=07 80 00 00 30 7a b0 b2 b4 b6 b8 ba bc be c0 c2 c4 c6 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 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 03 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) +- Sending new block at BSN 0, CS=MCS-5 +- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (len=100) +-- Chunk with length 100 larger than space (56) left in block: copy only remaining space, and we are done +data block (BSN 0, MCS-5): 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 +- Copying data unit 0 (BSN 0) +msg block (BSN 0, MCS-5): 07 00 00 18 40 80 c0 00 41 81 c1 01 42 82 c2 02 43 83 c3 03 44 84 c4 04 45 85 c5 05 46 86 c6 06 47 87 c7 07 48 88 c8 08 49 89 c9 09 4a 8a ca 0a 4b 8b cb 0b 4c 8c cc 0c 4d 8d cd 0d +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=4 block=1 data=07 00 00 18 40 80 c0 00 41 81 c1 01 42 82 c2 02 43 83 c3 03 44 84 c4 04 45 85 c5 05 46 86 c6 06 47 87 c7 07 48 88 c8 08 49 89 c9 09 4a 8a ca 0a 4b 8b cb 0b 4c 8c cc 0c 4d 8d cd 0d +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) +- Resending BSN 0 +- Copying data unit 0 (BSN 0) +msg block (BSN 0, MCS-5): 07 00 00 1a 40 80 c0 00 41 81 c1 01 42 82 c2 02 43 83 c3 03 44 84 c4 04 45 85 c5 05 46 86 c6 06 47 87 c7 07 48 88 c8 08 49 89 c9 09 4a 8a ca 0a 4b 8b cb 0b 4c 8c cc 0c 4d 8d cd 0d +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=8 block=2 data=07 00 00 1a 40 80 c0 00 41 81 c1 01 42 82 c2 02 43 83 c3 03 44 84 c4 04 45 85 c5 05 46 86 c6 06 47 87 c7 07 48 88 c8 08 49 89 c9 09 4a 8a ca 0a 4b 8b cb 0b 4c 8c cc 0c 4d 8d cd 0d +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) +- Resending BSN 0 +- Copying data unit 0 (BSN 0) +msg block (BSN 0, MCS-5): 07 00 00 18 40 80 c0 00 41 81 c1 01 42 82 c2 02 43 83 c3 03 44 84 c4 04 45 85 c5 05 46 86 c6 06 47 87 c7 07 48 88 c8 08 49 89 c9 09 4a 8a ca 0a 4b 8b cb 0b 4c 8c cc 0c 4d 8d cd 0d +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=13 block=3 data=07 00 00 18 40 80 c0 00 41 81 c1 01 42 82 c2 02 43 83 c3 03 44 84 c4 04 45 85 c5 05 46 86 c6 06 47 87 c7 07 48 88 c8 08 49 89 c9 09 4a 8a ca 0a 4b 8b cb 0b 4c 8c cc 0c 4d 8d cd 0d +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) +- Resending BSN 0 +- Copying data unit 0 (BSN 0) +msg block (BSN 0, MCS-5): 07 00 00 1a 40 80 c0 00 41 81 c1 01 42 82 c2 02 43 83 c3 03 44 84 c4 04 45 85 c5 05 46 86 c6 06 47 87 c7 07 48 88 c8 08 49 89 c9 09 4a 8a ca 0a 4b 8b cb 0b 4c 8c cc 0c 4d 8d cd 0d +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=17 block=4 data=07 00 00 1a 40 80 c0 00 41 81 c1 01 42 82 c2 02 43 83 c3 03 44 84 c4 04 45 85 c5 05 46 86 c6 06 47 87 c7 07 48 88 c8 08 49 89 c9 09 4a 8a ca 0a 4b 8b cb 0b 4c 8c cc 0c 4d 8d cd 0d +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) +- Sending new block at BSN 1, CS=MCS-5 +-- Chunk with length 44 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=100 +-- 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 1, MCS-5): 58 15 38 39 3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 43 c0 01 2b 2b 2b 2b 2b 2b 2b +- 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 08 56 05 4e 8e ce 0e 4f 8f cf 0f 50 90 d0 10 51 91 d1 11 52 92 d2 12 53 93 d3 13 54 94 d4 14 55 95 d5 15 56 96 d6 16 57 97 d7 17 58 98 d8 d8 10 70 c0 ca ca ca ca ca ca 0a +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=21 block=5 data=07 40 00 08 56 05 4e 8e ce 0e 4f 8f cf 0f 50 90 d0 10 51 91 d1 11 52 92 d2 12 53 93 d3 13 54 94 d4 14 55 95 d5 15 56 96 d6 16 57 97 d7 17 58 98 d8 d8 10 70 c0 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 03 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) +- Sending new block at BSN 0, CS=MCS-6 +- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (len=100) +-- Chunk with length 100 larger than space (74) left in block: copy only remaining space, and we are done +data block (BSN 0, MCS-6): 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 +- Copying data unit 0 (BSN 0) +msg block (BSN 0, MCS-6): 07 00 00 10 40 80 c0 00 41 81 c1 01 42 82 c2 02 43 83 c3 03 44 84 c4 04 45 85 c5 05 46 86 c6 06 47 87 c7 07 48 88 c8 08 49 89 c9 09 4a 8a ca 0a 4b 8b cb 0b 4c 8c cc 0c 4d 8d cd 0d 4e 8e ce 0e 4f 8f cf 0f 50 90 d0 10 51 91 d1 11 52 12 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=4 block=1 data=07 00 00 10 40 80 c0 00 41 81 c1 01 42 82 c2 02 43 83 c3 03 44 84 c4 04 45 85 c5 05 46 86 c6 06 47 87 c7 07 48 88 c8 08 49 89 c9 09 4a 8a ca 0a 4b 8b cb 0b 4c 8c cc 0c 4d 8d cd 0d 4e 8e ce 0e 4f 8f cf 0f 50 90 d0 10 51 91 d1 11 52 12 +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) +- Resending BSN 0 +- Copying data unit 0 (BSN 0) +msg block (BSN 0, MCS-6): 07 00 00 12 40 80 c0 00 41 81 c1 01 42 82 c2 02 43 83 c3 03 44 84 c4 04 45 85 c5 05 46 86 c6 06 47 87 c7 07 48 88 c8 08 49 89 c9 09 4a 8a ca 0a 4b 8b cb 0b 4c 8c cc 0c 4d 8d cd 0d 4e 8e ce 0e 4f 8f cf 0f 50 90 d0 10 51 91 d1 11 52 12 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=8 block=2 data=07 00 00 12 40 80 c0 00 41 81 c1 01 42 82 c2 02 43 83 c3 03 44 84 c4 04 45 85 c5 05 46 86 c6 06 47 87 c7 07 48 88 c8 08 49 89 c9 09 4a 8a ca 0a 4b 8b cb 0b 4c 8c cc 0c 4d 8d cd 0d 4e 8e ce 0e 4f 8f cf 0f 50 90 d0 10 51 91 d1 11 52 12 +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) +- Resending BSN 0 +- Copying data unit 0 (BSN 0) +msg block (BSN 0, MCS-6): 07 00 00 10 40 80 c0 00 41 81 c1 01 42 82 c2 02 43 83 c3 03 44 84 c4 04 45 85 c5 05 46 86 c6 06 47 87 c7 07 48 88 c8 08 49 89 c9 09 4a 8a ca 0a 4b 8b cb 0b 4c 8c cc 0c 4d 8d cd 0d 4e 8e ce 0e 4f 8f cf 0f 50 90 d0 10 51 91 d1 11 52 12 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=13 block=3 data=07 00 00 10 40 80 c0 00 41 81 c1 01 42 82 c2 02 43 83 c3 03 44 84 c4 04 45 85 c5 05 46 86 c6 06 47 87 c7 07 48 88 c8 08 49 89 c9 09 4a 8a ca 0a 4b 8b cb 0b 4c 8c cc 0c 4d 8d cd 0d 4e 8e ce 0e 4f 8f cf 0f 50 90 d0 10 51 91 d1 11 52 12 +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) +- Resending BSN 0 +- Copying data unit 0 (BSN 0) +msg block (BSN 0, MCS-6): 07 00 00 12 40 80 c0 00 41 81 c1 01 42 82 c2 02 43 83 c3 03 44 84 c4 04 45 85 c5 05 46 86 c6 06 47 87 c7 07 48 88 c8 08 49 89 c9 09 4a 8a ca 0a 4b 8b cb 0b 4c 8c cc 0c 4d 8d cd 0d 4e 8e ce 0e 4f 8f cf 0f 50 90 d0 10 51 91 d1 11 52 12 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=17 block=4 data=07 00 00 12 40 80 c0 00 41 81 c1 01 42 82 c2 02 43 83 c3 03 44 84 c4 04 45 85 c5 05 46 86 c6 06 47 87 c7 07 48 88 c8 08 49 89 c9 09 4a 8a ca 0a 4b 8b cb 0b 4c 8c cc 0c 4d 8d cd 0d 4e 8e ce 0e 4f 8f cf 0f 50 90 d0 10 51 91 d1 11 52 12 +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) +- Sending new block at BSN 1, CS=MCS-6 +-- Chunk with length 26 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=100 +-- 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 1, MCS-6): 34 5d 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 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 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 00 4d 97 d2 12 53 93 d3 13 54 94 d4 14 55 95 d5 15 56 96 d6 16 57 97 d7 17 58 98 d8 d8 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=21 block=5 data=07 40 00 00 4d 97 d2 12 53 93 d3 13 54 94 d4 14 55 95 d5 15 56 96 d6 16 57 97 d7 17 58 98 d8 d8 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 03 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) +- Sending new block at BSN 0, CS=MCS-7 +- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (len=100) +-- Chunk with length 100 larger than space (56) left in block: copy only remaining space, and we are done +data block (BSN 0, MCS-7): 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 +- Sending new block at BSN 1, CS=MCS-7 +-- Chunk with length 44 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=100 +-- 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 1, MCS-7): 58 15 38 39 3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 43 c0 01 2b 2b 2b 2b 2b 2b 2b +- 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 0, MCS-7): 07 00 00 02 a0 01 04 08 0c 10 14 18 1c 20 24 28 2c 30 34 38 3c 40 44 48 4c 50 54 58 5c 60 64 68 6c 70 74 78 7c 80 84 88 8c 90 94 98 9c a0 a4 a8 ac b0 b4 b8 bc c0 c4 c8 cc d0 d4 d8 dc 80 55 81 93 a3 b3 c3 d3 e3 f3 03 14 24 34 44 54 64 74 84 94 a4 b4 c4 d4 e4 f4 04 15 25 35 45 55 65 75 85 95 a5 b5 c5 d5 e5 f5 05 16 26 36 36 04 1c b0 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 02 a0 01 04 08 0c 10 14 18 1c 20 24 28 2c 30 34 38 3c 40 44 48 4c 50 54 58 5c 60 64 68 6c 70 74 78 7c 80 84 88 8c 90 94 98 9c a0 a4 a8 ac b0 b4 b8 bc c0 c4 c8 cc d0 d4 d8 dc 80 55 81 93 a3 b3 c3 d3 e3 f3 03 14 24 34 44 54 64 74 84 94 a4 b4 c4 d4 e4 f4 04 15 25 35 45 55 65 75 85 95 a5 b5 c5 d5 e5 f5 05 16 26 36 36 04 1c b0 b2 b2 b2 b2 b2 b2 02 +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)==2) +- Resending BSN 0 +- Resending 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 0, MCS-7): 07 00 00 02 c0 01 04 08 0c 10 14 18 1c 20 24 28 2c 30 34 38 3c 40 44 48 4c 50 54 58 5c 60 64 68 6c 70 74 78 7c 80 84 88 8c 90 94 98 9c a0 a4 a8 ac b0 b4 b8 bc c0 c4 c8 cc d0 d4 d8 dc 80 55 81 93 a3 b3 c3 d3 e3 f3 03 14 24 34 44 54 64 74 84 94 a4 b4 c4 d4 e4 f4 04 15 25 35 45 55 65 75 85 95 a5 b5 c5 d5 e5 f5 05 16 26 36 36 04 1c b0 b2 b2 b2 b2 b2 b2 02 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=8 block=2 data=07 00 00 02 c0 01 04 08 0c 10 14 18 1c 20 24 28 2c 30 34 38 3c 40 44 48 4c 50 54 58 5c 60 64 68 6c 70 74 78 7c 80 84 88 8c 90 94 98 9c a0 a4 a8 ac b0 b4 b8 bc c0 c4 c8 cc d0 d4 d8 dc 80 55 81 93 a3 b3 c3 d3 e3 f3 03 14 24 34 44 54 64 74 84 94 a4 b4 c4 d4 e4 f4 04 15 25 35 45 55 65 75 85 95 a5 b5 c5 d5 e5 f5 05 16 26 36 36 04 1c b0 b2 b2 b2 b2 b2 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)==2) +- Resending BSN 0 +- Resending 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 0, MCS-7): 07 00 00 02 e0 01 04 08 0c 10 14 18 1c 20 24 28 2c 30 34 38 3c 40 44 48 4c 50 54 58 5c 60 64 68 6c 70 74 78 7c 80 84 88 8c 90 94 98 9c a0 a4 a8 ac b0 b4 b8 bc c0 c4 c8 cc d0 d4 d8 dc 80 55 81 93 a3 b3 c3 d3 e3 f3 03 14 24 34 44 54 64 74 84 94 a4 b4 c4 d4 e4 f4 04 15 25 35 45 55 65 75 85 95 a5 b5 c5 d5 e5 f5 05 16 26 36 36 04 1c b0 b2 b2 b2 b2 b2 b2 02 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=13 block=3 data=07 00 00 02 e0 01 04 08 0c 10 14 18 1c 20 24 28 2c 30 34 38 3c 40 44 48 4c 50 54 58 5c 60 64 68 6c 70 74 78 7c 80 84 88 8c 90 94 98 9c a0 a4 a8 ac b0 b4 b8 bc c0 c4 c8 cc d0 d4 d8 dc 80 55 81 93 a3 b3 c3 d3 e3 f3 03 14 24 34 44 54 64 74 84 94 a4 b4 c4 d4 e4 f4 04 15 25 35 45 55 65 75 85 95 a5 b5 c5 d5 e5 f5 05 16 26 36 36 04 1c b0 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 +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 03 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) +- Sending new block at BSN 0, CS=MCS-8 +- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (len=100) +-- Chunk with length 100 larger than space (68) left in block: copy only remaining space, and we are done +data block (BSN 0, MCS-8): 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 40 41 42 43 +- Sending new block at BSN 1, CS=MCS-8 +-- Chunk with length 32 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=100 +-- Empty chunk, added LLC dummy command of size 34, drained_since=0 +-- 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 1, MCS-8): 40 45 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 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 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 0, MCS-8): 07 00 00 02 58 01 04 08 0c 10 14 18 1c 20 24 28 2c 30 34 38 3c 40 44 48 4c 50 54 58 5c 60 64 68 6c 70 74 78 7c 80 84 88 8c 90 94 98 9c a0 a4 a8 ac b0 b4 b8 bc c0 c4 c8 cc d0 d4 d8 dc e0 e4 e8 ec f0 f4 f8 fc 00 05 09 0d 01 54 44 54 64 74 84 94 a4 b4 c4 d4 e4 f4 04 15 25 35 45 55 65 75 85 95 a5 b5 c5 d5 e5 f5 05 16 26 36 36 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 02 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=4 block=1 data=07 00 00 02 58 01 04 08 0c 10 14 18 1c 20 24 28 2c 30 34 38 3c 40 44 48 4c 50 54 58 5c 60 64 68 6c 70 74 78 7c 80 84 88 8c 90 94 98 9c a0 a4 a8 ac b0 b4 b8 bc c0 c4 c8 cc d0 d4 d8 dc e0 e4 e8 ec f0 f4 f8 fc 00 05 09 0d 01 54 44 54 64 74 84 94 a4 b4 c4 d4 e4 f4 04 15 25 35 45 55 65 75 85 95 a5 b5 c5 d5 e5 f5 05 16 26 36 36 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 02 +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)==2) +- Resending BSN 0 +- Resending 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 0, MCS-8): 07 00 00 02 78 01 04 08 0c 10 14 18 1c 20 24 28 2c 30 34 38 3c 40 44 48 4c 50 54 58 5c 60 64 68 6c 70 74 78 7c 80 84 88 8c 90 94 98 9c a0 a4 a8 ac b0 b4 b8 bc c0 c4 c8 cc d0 d4 d8 dc e0 e4 e8 ec f0 f4 f8 fc 00 05 09 0d 01 54 44 54 64 74 84 94 a4 b4 c4 d4 e4 f4 04 15 25 35 45 55 65 75 85 95 a5 b5 c5 d5 e5 f5 05 16 26 36 36 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 02 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=8 block=2 data=07 00 00 02 78 01 04 08 0c 10 14 18 1c 20 24 28 2c 30 34 38 3c 40 44 48 4c 50 54 58 5c 60 64 68 6c 70 74 78 7c 80 84 88 8c 90 94 98 9c a0 a4 a8 ac b0 b4 b8 bc c0 c4 c8 cc d0 d4 d8 dc e0 e4 e8 ec f0 f4 f8 fc 00 05 09 0d 01 54 44 54 64 74 84 94 a4 b4 c4 d4 e4 f4 04 15 25 35 45 55 65 75 85 95 a5 b5 c5 d5 e5 f5 05 16 26 36 36 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 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)==2) +- Resending BSN 0 +- Resending 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 0, MCS-8): 07 00 00 02 98 01 04 08 0c 10 14 18 1c 20 24 28 2c 30 34 38 3c 40 44 48 4c 50 54 58 5c 60 64 68 6c 70 74 78 7c 80 84 88 8c 90 94 98 9c a0 a4 a8 ac b0 b4 b8 bc c0 c4 c8 cc d0 d4 d8 dc e0 e4 e8 ec f0 f4 f8 fc 00 05 09 0d 01 54 44 54 64 74 84 94 a4 b4 c4 d4 e4 f4 04 15 25 35 45 55 65 75 85 95 a5 b5 c5 d5 e5 f5 05 16 26 36 36 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 02 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=13 block=3 data=07 00 00 02 98 01 04 08 0c 10 14 18 1c 20 24 28 2c 30 34 38 3c 40 44 48 4c 50 54 58 5c 60 64 68 6c 70 74 78 7c 80 84 88 8c 90 94 98 9c a0 a4 a8 ac b0 b4 b8 bc c0 c4 c8 cc d0 d4 d8 dc e0 e4 e8 ec f0 f4 f8 fc 00 05 09 0d 01 54 44 54 64 74 84 94 a4 b4 c4 d4 e4 f4 04 15 25 35 45 55 65 75 85 95 a5 b5 c5 d5 e5 f5 05 16 26 36 36 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 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 +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 03 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) +- Sending new block at BSN 0, CS=MCS-9 +- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (len=100) +-- Chunk with length 100 larger than space (74) left in block: copy only remaining space, and we are done +data block (BSN 0, MCS-9): 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 +- Sending new block at BSN 1, CS=MCS-9 +-- Chunk with length 26 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=100 +-- 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 1, MCS-9): 34 5d 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 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 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 0, MCS-9): 07 00 00 02 00 01 04 08 0c 10 14 18 1c 20 24 28 2c 30 34 38 3c 40 44 48 4c 50 54 58 5c 60 64 68 6c 70 74 78 7c 80 84 88 8c 90 94 98 9c a0 a4 a8 ac b0 b4 b8 bc c0 c4 c8 cc d0 d4 d8 dc e0 e4 e8 ec f0 f4 f8 fc 00 05 09 0d 11 15 19 1d 21 25 41 d3 a5 b4 c4 d4 e4 f4 04 15 25 35 45 55 65 75 85 95 a5 b5 c5 d5 e5 f5 05 16 26 36 36 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 02 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=4 block=1 data=07 00 00 02 00 01 04 08 0c 10 14 18 1c 20 24 28 2c 30 34 38 3c 40 44 48 4c 50 54 58 5c 60 64 68 6c 70 74 78 7c 80 84 88 8c 90 94 98 9c a0 a4 a8 ac b0 b4 b8 bc c0 c4 c8 cc d0 d4 d8 dc e0 e4 e8 ec f0 f4 f8 fc 00 05 09 0d 11 15 19 1d 21 25 41 d3 a5 b4 c4 d4 e4 f4 04 15 25 35 45 55 65 75 85 95 a5 b5 c5 d5 e5 f5 05 16 26 36 36 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 02 +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)==2) +- Resending BSN 0 +- Resending 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 0, MCS-9): 07 00 00 02 28 01 04 08 0c 10 14 18 1c 20 24 28 2c 30 34 38 3c 40 44 48 4c 50 54 58 5c 60 64 68 6c 70 74 78 7c 80 84 88 8c 90 94 98 9c a0 a4 a8 ac b0 b4 b8 bc c0 c4 c8 cc d0 d4 d8 dc e0 e4 e8 ec f0 f4 f8 fc 00 05 09 0d 11 15 19 1d 21 25 41 d3 a5 b4 c4 d4 e4 f4 04 15 25 35 45 55 65 75 85 95 a5 b5 c5 d5 e5 f5 05 16 26 36 36 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 02 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=8 block=2 data=07 00 00 02 28 01 04 08 0c 10 14 18 1c 20 24 28 2c 30 34 38 3c 40 44 48 4c 50 54 58 5c 60 64 68 6c 70 74 78 7c 80 84 88 8c 90 94 98 9c a0 a4 a8 ac b0 b4 b8 bc c0 c4 c8 cc d0 d4 d8 dc e0 e4 e8 ec f0 f4 f8 fc 00 05 09 0d 11 15 19 1d 21 25 41 d3 a5 b4 c4 d4 e4 f4 04 15 25 35 45 55 65 75 85 95 a5 b5 c5 d5 e5 f5 05 16 26 36 36 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 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)==2) +- Resending BSN 0 +- Resending 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 0, MCS-9): 07 00 00 02 50 01 04 08 0c 10 14 18 1c 20 24 28 2c 30 34 38 3c 40 44 48 4c 50 54 58 5c 60 64 68 6c 70 74 78 7c 80 84 88 8c 90 94 98 9c a0 a4 a8 ac b0 b4 b8 bc c0 c4 c8 cc d0 d4 d8 dc e0 e4 e8 ec f0 f4 f8 fc 00 05 09 0d 11 15 19 1d 21 25 41 d3 a5 b4 c4 d4 e4 f4 04 15 25 35 45 55 65 75 85 95 a5 b5 c5 d5 e5 f5 05 16 26 36 36 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 02 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=13 block=3 data=07 00 00 02 50 01 04 08 0c 10 14 18 1c 20 24 28 2c 30 34 38 3c 40 44 48 4c 50 54 58 5c 60 64 68 6c 70 74 78 7c 80 84 88 8c 90 94 98 9c a0 a4 a8 ac b0 b4 b8 bc c0 c4 c8 cc d0 d4 d8 dc e0 e4 e8 ec f0 f4 f8 fc 00 05 09 0d 11 15 19 1d 21 25 41 d3 a5 b4 c4 d4 e4 f4 04 15 25 35 45 55 65 75 85 95 a5 b5 c5 d5 e5 f5 05 16 26 36 36 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 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 +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 441b444..2a32531 100644 --- a/tests/tbf/TbfTest.ok +++ b/tests/tbf/TbfTest.ok @@ -43,3 +43,14 @@ Testing MCS-7 Testing MCS-8 Testing MCS-9 === end test_tbf_egprs_dl === +=== start test_tbf_egprs_retx_dl === +Testing MCS-1 for retx +Testing MCS-2 for retx +Testing MCS-3 for retx +Testing MCS-4 for retx +Testing MCS-5 for retx +Testing MCS-6 for retx +Testing MCS-7 for retx +Testing MCS-8 for retx +Testing MCS-9 for retx +=== end test_tbf_egprs_retx_dl === -- 1.7.9.5 From Bhargava.Abhyankar at radisys.com Tue Apr 5 11:57:41 2016 From: Bhargava.Abhyankar at radisys.com (Bhargava Abhyankar) Date: Tue, 5 Apr 2016 17:27:41 +0530 Subject: [PATCH] Update parameters in osmo-bts for 11 bit RACH Message-ID: <1459857461-24941-1-git-send-email-Bhargava.Abhyankar@radisys.com> Based on the indication from L1, number of bits in RACH and burst type is determined. Appropriate parameters are filled in osmo-bts. These parameters are sent to osmo-pcu for processing of the RACH. --- src/osmo-bts-sysmo/l1_if.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/src/osmo-bts-sysmo/l1_if.c b/src/osmo-bts-sysmo/l1_if.c index a8f957c..1aec989 100644 --- a/src/osmo-bts-sysmo/l1_if.c +++ b/src/osmo-bts-sysmo/l1_if.c @@ -857,7 +857,7 @@ static int handle_ph_ra_ind(struct femtol1_hdl *fl1, GsmL1_PhRaInd_t *ra_ind, struct gsm_lchan *lchan; struct osmo_phsap_prim *l1sap; uint32_t fn; - uint8_t ra, acc_delay = 0; + uint16_t ra, acc_delay = 0, is_11bit = 0, burst_type = 0; int rc; /* increment number of busy RACH slots, if required */ @@ -879,16 +879,25 @@ static int handle_ph_ra_ind(struct femtol1_hdl *fl1, GsmL1_PhRaInd_t *ra_ind, btsb->load.rach.access++; dump_meas_res(LOGL_DEBUG, &ra_ind->measParam); + burst_type = ra_ind->burstType; - if (ra_ind->msgUnitParam.u8Size != 1) { + if ((ra_ind->msgUnitParam.u8Size != 1) && + (ra_ind->msgUnitParam.u8Size != 2)) { LOGP(DL1C, LOGL_ERROR, "PH-RACH-INDICATION has %d bits\n", ra_ind->sapi); msgb_free(l1p_msg); return 0; } + if (ra_ind->msgUnitParam.u8Size == 2) { + is_11bit = 1; + memcpy(&ra, ra_ind->msgUnitParam.u8Buffer, 2); + } else { + is_11bit = 0; + ra = ra_ind->msgUnitParam.u8Buffer[0]; + } + fn = ra_ind->u32Fn; - ra = ra_ind->msgUnitParam.u8Buffer[0]; rc = msgb_trim(l1p_msg, sizeof(*l1sap)); if (rc < 0) MSGB_ABORT(l1p_msg, "No room for primitive data\n"); @@ -898,11 +907,8 @@ static int handle_ph_ra_ind(struct femtol1_hdl *fl1, GsmL1_PhRaInd_t *ra_ind, l1sap->u.rach_ind.ra = ra; l1sap->u.rach_ind.acc_delay = acc_delay; l1sap->u.rach_ind.fn = fn; - - /* Initialising the parameters needs to be handled when 11 bit RACH - * is supported */ - l1sap->u.rach_ind.is_11bit = 0; - l1sap->u.rach_ind.burst = GSM_L1_BURST_TYPE_ACCESS_0; + l1sap->u.rach_ind.is_11bit = is_11bit; /* no of bits in 11 bit RACH */ + l1sap->u.rach_ind.burst = burst_type; /* type of burst */ if (!lchan || lchan->ts->pchan == GSM_PCHAN_CCCH || lchan->ts->pchan == GSM_PCHAN_CCCH_SDCCH4) @@ -911,6 +917,7 @@ static int handle_ph_ra_ind(struct femtol1_hdl *fl1, GsmL1_PhRaInd_t *ra_ind, l1sap->u.rach_ind.chan_nr = gsm_lchan2chan_nr(lchan); return l1sap_up(trx, l1sap); + } /* handle any random indication from the L1 */ -- 2.5.0 From Bhargava.Abhyankar at radisys.com Tue Apr 5 11:58:18 2016 From: Bhargava.Abhyankar at radisys.com (Bhargava Abhyankar) Date: Tue, 5 Apr 2016 17:28:18 +0530 Subject: [PATCH] Handle GPRS 11 bit RACH in osmo-pcu Message-ID: <1459857498-24990-1-git-send-email-Bhargava.Abhyankar@radisys.com> A function is_single_block is added to get request type of RACH. GPRS 11 bit RACH is handled. --- src/bts.cpp | 56 ++++++++++++++++++++++++++++++++++++++++++++++---------- src/bts.h | 2 ++ 2 files changed, 48 insertions(+), 10 deletions(-) diff --git a/src/bts.cpp b/src/bts.cpp index 62b00c4..2166132 100644 --- a/src/bts.cpp +++ b/src/bts.cpp @@ -473,18 +473,11 @@ int BTS::rcv_rach(uint16_t ra, uint32_t Fn, int16_t qta, uint8_t is_11bit, uint16_t ta; rach_frame(); - LOGP(DRLCMAC, LOGL_DEBUG, "MS requests UL TBF on RACH, so we provide " "one:\n"); - if ((ra & 0xf8) == 0x70) { - LOGP(DRLCMAC, LOGL_DEBUG, "MS requests single block " - "allocation\n"); - sb = 1; - } else if (m_bts.force_two_phase) { - LOGP(DRLCMAC, LOGL_DEBUG, "MS requests single phase access, " - "but we force two phase access\n"); - sb = 1; - } + + sb = is_single_block(ra, burst, is_11bit); + if (qta < 0) qta = 0; if (qta > 252) @@ -556,6 +549,49 @@ int BTS::rcv_rach(uint16_t ra, uint32_t Fn, int16_t qta, uint8_t is_11bit, return 0; } +uint8_t BTS::is_single_block(uint16_t ra, enum ph_burst_type burst, + uint8_t is_11bit) +{ + uint8_t sb = 0; + + if ((is_11bit == 0) && (burst == GSM_L1_BURST_TYPE_ACCESS_0)) { + if ((ra & 0xf8) == 0x70) { + LOGP(DRLCMAC, LOGL_DEBUG, "MS requests single block " + "allocation\n"); + sb = 1; + } else if (m_bts.force_two_phase) { + LOGP(DRLCMAC, LOGL_DEBUG, "MS requests single phase " + "access, but we force two phase access\n"); + sb = 1; + } + } else if ((is_11bit == 1) && (burst == GSM_L1_BURST_TYPE_ACCESS_0)) { + if ((ra & 0x7e0) == 0x0600) { + LOGP(DRLCMAC, LOGL_DEBUG, "GPRS 11 bit RACH received. " + "MS requests single block allocation\n"); + sb = 1; + } else if (m_bts.force_two_phase) { + LOGP(DRLCMAC, LOGL_DEBUG, "GPRS 11 bit RACH received." + "MS requests single phase access but we force " + "two phase access\n"); + sb = 1; + } + } else if ((is_11bit == 1) && ((burst == GSM_L1_BURST_TYPE_ACCESS_1) || + (burst == GSM_L1_BURST_TYPE_ACCESS_2))) { + if ((ra & 0x7e0) == 0x0600) { + LOGP(DRLCMAC, LOGL_DEBUG, "EGPRS 11 bit RACH received. " + "MS requests single block allocation\n"); + sb = 1; + } else if (m_bts.force_two_phase) { + LOGP(DRLCMAC, LOGL_DEBUG, "EGPRS 11 bit RACH received. " + "MS requests single phase access but we force " + "two phase access\n"); + sb = 1; + } + } + + return sb; +} + /* depending on the current TBF, we assign on PACCH or AGCH */ void BTS::trigger_dl_ass( struct gprs_rlcmac_dl_tbf *dl_tbf, diff --git a/src/bts.h b/src/bts.h index f0fe970..1c5b749 100644 --- a/src/bts.h +++ b/src/bts.h @@ -276,6 +276,8 @@ public: int tfi_find_free(enum gprs_rlcmac_tbf_direction dir, uint8_t *_trx, int8_t use_trx); int rcv_imm_ass_cnf(const uint8_t *data, uint32_t fn); + uint8_t is_single_block(uint16_t ra, enum ph_burst_type burst, + uint8_t is_11bit); int rcv_rach(uint16_t ra, uint32_t Fn, int16_t qta, uint8_t is_11bit, enum ph_burst_type burst); -- 2.5.0 From Prasad.Kaup at radisys.com Tue Apr 5 14:50:15 2016 From: Prasad.Kaup at radisys.com (Prasad Kaup) Date: Tue, 5 Apr 2016 14:50:15 +0000 Subject: Regarding integration of NURAN L1 1.0 In-Reply-To: <86E210CFD3EEDE46A58DE4793CFA6C3F037CC081@NTWAEX01.interne.lyrtech.com> References: <86E210CFD3EEDE46A58DE4793CFA6C3F0373171A@NTWAEX01.interne.lyrtech.com> <20160314001234.GE10039@dub6> <86E210CFD3EEDE46A58DE4793CFA6C3F03732069@NTWAEX01.interne.lyrtech.com> <86E210CFD3EEDE46A58DE4793CFA6C3F0373244D@NTWAEX01.interne.lyrtech.com> <86E210CFD3EEDE46A58DE4793CFA6C3F037CBC9E@NTWAEX01.interne.lyrtech.com> <86E210CFD3EEDE46A58DE4793CFA6C3F037CC081@NTWAEX01.interne.lyrtech.com> Message-ID: Hi Minh-Quang Nguyen, Thanks for the information. We are able to connect to internet through GPRS with existing binaries in the board. we are also able to cross compile latest libosmocore, talloc and osmo-pcu. We loaded latest osmo-pcu (from master ) to board and tried to test , but there is no internet connectivity. I see that there is no data received at osmo-pcu /osmo-bts as below, though assignment is given to mobile PCU side: <0002> tbf.cpp:874 TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=WAIT ASSIGN) T3169 timeout during transmission <0002> tbf.cpp:893 - Assignment was on CCCH <0002> tbf.cpp:899 - No uplink data received yet BTS side: <0009> pcu_sock.c:356 Sending RACH indication: qta=-3, ra=123, fn=647328 <0009> pcu_sock.c:466 Data request received: sapi=AGCH arfcn=0 block=0 data=2d 06 3f 10 0e e0 2b 7b 44 86 00 00 c8 00 70 0b 2b 2b 2b 2b 2b 2b 2b <0006> l1_if.c:948 RACH for packet access Let me know your comments Regards Prasad From Prasad.Kaup at radisys.com Wed Apr 6 15:10:57 2016 From: Prasad.Kaup at radisys.com (Prasad Kaup) Date: Wed, 6 Apr 2016 15:10:57 +0000 Subject: Regarding integration of NURAN L1 1.0 In-Reply-To: References: <86E210CFD3EEDE46A58DE4793CFA6C3F0373171A@NTWAEX01.interne.lyrtech.com> <20160314001234.GE10039@dub6> <86E210CFD3EEDE46A58DE4793CFA6C3F03732069@NTWAEX01.interne.lyrtech.com> <86E210CFD3EEDE46A58DE4793CFA6C3F0373244D@NTWAEX01.interne.lyrtech.com> <86E210CFD3EEDE46A58DE4793CFA6C3F037CBC9E@NTWAEX01.interne.lyrtech.com> <86E210CFD3EEDE46A58DE4793CFA6C3F037CC081@NTWAEX01.interne.lyrtech.com> Message-ID: Hello, We are seeing following logs continuously when osmo-pcu cross compiled in our setup (latest master and commit 08e5d604d3fce75b955549244b36fde62f20894b) binaries are used on board And there is no GPRS connectivity. <0002> bts.cpp:202 Late RLC block, FN delta: -30 FN: 112740 curFN: 112770 <0002> bts.cpp:202 Late RLC block, FN delta: -35 FN: 112744 curFN: 112779 <0002> bts.cpp:202 Late RLC block, FN delta: -30 FN: 112749 curFN: 112779 <0002> bts.cpp:202 Late RLC block, FN delta: -30 FN: 112753 curFN: 112783 Any pointers on what could have caused this issue will be helpful. Regards Prasad From holger at freyther.de Thu Apr 7 07:46:41 2016 From: holger at freyther.de (Holger Freyther) Date: Thu, 7 Apr 2016 09:46:41 +0200 Subject: [PATCH] Add test cases for EGPRS retransmission in DL In-Reply-To: <1459841854-18042-1-git-send-email-arvind.sirsikar@radisys.com> References: <1459841854-18042-1-git-send-email-arvind.sirsikar@radisys.com> Message-ID: > On 05 Apr 2016, at 09:37, Aravind Sirsikar wrote: Hi! > Add test cases to validate retransmission of EGPRS RLC data block > for all the MCS in downlink direction without support of MCS change > during retransmission testcases are always good! I would prefer to have stronger assertions or at least some comments in the commit message that says what we should look for in the debug log. Stronger assertions are certainly preferred. > > +static void establish_and_use_egprs_dl_tbf_for_retx(BTS *the_bts, int mcs) > +{ > > + for (i = 0; i < sizeof(test_data); i++) > + test_data[i] = i%512; okay, that is our test data. Can we easily see that all of it has been transferred? > > + /* Send only a few RLC/MAC blocks */ How many? How many are there, why a few? > + fn = 0; > + uint8_t block_nr = 0; > + int index1 = 0; > + > + while (index1 < 4) { > + /* Request to send one block */ > + request_dl_rlc_block(dl_tbf, &fn, &block_nr); > + index1++; > + if (dl_tbf->m_window.m_v_b.is_unacked(0)) > + dl_tbf->m_window.m_v_b.mark_nacked(0); > + if (mcs > 6) > + if (dl_tbf->m_window.m_v_b.is_unacked(1)) > + dl_tbf->m_window.m_v_b.mark_nacked(1); > + > + } E.g. here it might be a good case to really look at the window and verify we have unacked frames? > + > + /* Drain the queue */ > + while (dl_tbf->have_data()) > + /* Request to send one RLC/MAC block */ > + request_dl_rlc_block(dl_tbf, &fn); and specifically check which parts went back to unacked? thank you holger From holger at freyther.de Thu Apr 7 07:48:19 2016 From: holger at freyther.de (Holger Freyther) Date: Thu, 7 Apr 2016 09:48:19 +0200 Subject: [PATCH] Update parameters in osmo-bts for 11 bit RACH In-Reply-To: <1459857461-24941-1-git-send-email-Bhargava.Abhyankar@radisys.com> References: <1459857461-24941-1-git-send-email-Bhargava.Abhyankar@radisys.com> Message-ID: <5003BB6D-3213-4F88-A0FD-89F6F18B2A2D@freyther.de> > On 05 Apr 2016, at 13:57, Bhargava Abhyankar wrote: Dear Bhargava, > Based on the indication from L1, number of bits in RACH and burst > type is determined. Appropriate parameters are filled in osmo-bts. > These parameters are sent to osmo-pcu for processing of the RACH. how did you test this? Do you have a patch for OpenBSC to modify the SIs to allow 11bit RACH bursts? kind regards holger From Bhargava.Abhyankar at radisys.com Thu Apr 7 11:57:54 2016 From: Bhargava.Abhyankar at radisys.com (Bhargava Abhyankar) Date: Thu, 7 Apr 2016 17:27:54 +0530 Subject: [PATCH 1/2] Fix bug in uplink header type 1 parsing Message-ID: <1460030275-543-1-git-send-email-Bhargava.Abhyankar@radisys.com> Fix bug in extraction of E and TI header fields in parsing of uplink header type 1 RLC data block. Test suite for the same is also updated. --- src/decoding.cpp | 15 ++++++++------- tests/edge/EdgeTest.cpp | 16 +++++++--------- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/src/decoding.cpp b/src/decoding.cpp index 6844856..b8e453e 100644 --- a/src/decoding.cpp +++ b/src/decoding.cpp @@ -513,9 +513,9 @@ int Decoding::rlc_parse_ul_data_header_egprs_type_1( offs = rlc->data_offs_bits[0] / 8; OSMO_ASSERT(rlc->data_offs_bits[0] % 8 == 0); - 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); + e_ti_header = (data[offs - 1] & (0xc0)) >> 6; + rlc->block_info[0].e = (e_ti_header & 0x01); + rlc->block_info[0].ti = (e_ti_header & 0x02); cur_bit += 2; rlc->block_info[1].cv = egprs1->cv; @@ -524,20 +524,21 @@ int Decoding::rlc_parse_ul_data_header_egprs_type_1( ((egprs1->bsn2_a << 0) | (egprs1->bsn2_b << 2)); rlc->block_info[1].bsn = rlc->block_info[1].bsn & (RLC_EGPRS_SNS - 1); - cur_bit += rlc->data_offs_bits[1] - 2; + cur_bit = rlc->data_offs_bits[1] - 2; offs = rlc->data_offs_bits[1] / 8; OSMO_ASSERT(rlc->data_offs_bits[1] % 8 == 2); - e_ti_header = (data[offs-1] + (data[offs] << 8)) >> 7; - rlc->block_info[1].e = !!(e_ti_header & 0x01); - rlc->block_info[1].ti = !!(e_ti_header & 0x02); + e_ti_header = (data[offs] & (0x03)); + rlc->block_info[1].e = (e_ti_header & 0x01); + rlc->block_info[1].ti = (e_ti_header & 0x02); cur_bit += 2; /* skip data area */ cur_bit += cs.maxDataBlockBytes() * 8; return cur_bit; } + /** * \brief Copy LSB bitstream RLC data block to byte aligned buffer. * diff --git a/tests/edge/EdgeTest.cpp b/tests/edge/EdgeTest.cpp index ff080f9..9b4a1a5 100644 --- a/tests/edge/EdgeTest.cpp +++ b/tests/edge/EdgeTest.cpp @@ -1376,18 +1376,16 @@ static gprs_rlcmac_ul_tbf *uplink_header_parsing_test(BTS *the_bts, egprs1->r = 1; egprs1->cv = 7; egprs1->tfi_a = tfi & (~((~0) << 2)); - egprs1->tfi_b = tfi & (~((~0) << 3)) << 2; - egprs1->bsn1_a = 10; - egprs1->bsn1_b = 17; - egprs1->bsn2_a = 0; - egprs1->bsn2_b = 25; + egprs1->tfi_b = (tfi & (~((~0) << 3)) << 2) >> 2; + egprs1->bsn1_a = 0; + egprs1->bsn1_b = 0; + egprs1->bsn2_a = 1; + egprs1->bsn2_b = 0; egprs1->cps = 15; egprs1->rsb = 0; egprs1->pi = 0; - data[6] = 1; - data[6 + 68] = 1; - data[75] = 1; - data[75 + 68] = 1; + data[5] = 0x40; + data[5 + 69] = 1; pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no]; pdch->rcv_block(&data[0], 143, *fn, &meas); } -- 2.5.0 From Bhargava.Abhyankar at radisys.com Thu Apr 7 11:57:55 2016 From: Bhargava.Abhyankar at radisys.com (Bhargava Abhyankar) Date: Thu, 7 Apr 2016 17:27:55 +0530 Subject: [PATCH 2/2] Add the test case for parsing uplink header type 2 In-Reply-To: <1460030275-543-1-git-send-email-Bhargava.Abhyankar@radisys.com> References: <1460030275-543-1-git-send-email-Bhargava.Abhyankar@radisys.com> Message-ID: <1460030275-543-2-git-send-email-Bhargava.Abhyankar@radisys.com> A test case is added to validate the uplink header type 2 extraction functionality. Bug identified by unit test in the header type 2 parsing is fixed. --- src/decoding.cpp | 8 ++-- tests/edge/EdgeTest.cpp | 114 ++++++++++++++++++++++++++++++++++++++++++++++++ tests/edge/EdgeTest.ok | 2 + 3 files changed, 120 insertions(+), 4 deletions(-) diff --git a/src/decoding.cpp b/src/decoding.cpp index b8e453e..fb0bd76 100644 --- a/src/decoding.cpp +++ b/src/decoding.cpp @@ -471,11 +471,11 @@ int Decoding::rlc_parse_ul_data_header_egprs_type_2( cur_bit += rlc->data_offs_bits[0] - 2; offs = rlc->data_offs_bits[0] / 8; - OSMO_ASSERT(rlc->data_offs_bits[0] % 8 == 1); + OSMO_ASSERT(rlc->data_offs_bits[0] % 8 == 7); - 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); + e_ti_header = (data[offs] & 0x60) >> 5; + rlc->block_info[0].e = (e_ti_header & 0x01); + rlc->block_info[0].ti = (e_ti_header & 0x02); cur_bit += 2; /* skip data area */ diff --git a/tests/edge/EdgeTest.cpp b/tests/edge/EdgeTest.cpp index 9b4a1a5..c7184e2 100644 --- a/tests/edge/EdgeTest.cpp +++ b/tests/edge/EdgeTest.cpp @@ -1409,6 +1409,119 @@ void uplink_header_type1_test(void) printf("=== end %s ===\n", __func__); } +static gprs_rlcmac_ul_tbf *uplink_header_type_2_parsing_test(BTS *the_bts, + uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta, + uint8_t ms_class) +{ + GprsMs *ms; + struct pcu_l1_meas meas; + uint32_t rach_fn = *fn - 51; + uint32_t sba_fn = *fn + 52; + uint8_t trx_no = 0; + int tfi = 0; + gprs_rlcmac_ul_tbf *ul_tbf; + struct gprs_rlcmac_pdch *pdch; + gprs_rlcmac_bts *bts; + RlcMacUplink_t ulreq = {0}; + uint8_t data[79] = {0}; + struct gprs_rlc_ul_header_egprs_2 *egprs2 = NULL; + + meas.set_rssi(31); + egprs2 = (struct gprs_rlc_ul_header_egprs_2 *) data; + bts = the_bts->bts_data(); + + /* needed to set last_rts_fn in the PDCH object */ + request_dl_rlc_block(bts, trx_no, ts_no, 0, fn); + + /* simulate RACH,this sends a Immediate Assignment Uplink on the AGCH */ + the_bts->rcv_rach(0x73, rach_fn, qta); + + /* get next free TFI */ + tfi = the_bts->tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1); + + /* fake a resource request */ + ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST; + ulreq.u.Packet_Resource_Request.PayloadType = GPRS_RLCMAC_CONTROL_BLOCK; + ulreq.u.Packet_Resource_Request.ID.UnionType = 1; /* != 0 */ + ulreq.u.Packet_Resource_Request.ID.u.TLLI = tlli; + ulreq.u.Packet_Resource_Request.Exist_MS_Radio_Access_capability = 1; + ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability. + Count_MS_RA_capability_value = 1; + ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability. + MS_RA_capability_value[0].u.Content. + Exist_Multislot_capability = 1; + ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability. + MS_RA_capability_value[0].u.Content.Multislot_capability. + Exist_GPRS_multislot_class = 1; + ulreq.u.Packet_Resource_Request.MS_Radio_Access_capability. + MS_RA_capability_value[0].u.Content.Multislot_capability. + GPRS_multislot_class = 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); + + /* check the TBF */ + ul_tbf = the_bts->ul_tbf_by_tfi(tfi, trx_no, ts_no); + OSMO_ASSERT(ul_tbf != NULL); + OSMO_ASSERT(ul_tbf->ta() == qta / 4); + + /* header parsing */ + egprs2->r = 1; + egprs2->si = 1; + egprs2->cv = 7; + egprs2->tfi_a = tfi & (~((~0) << 2)); + egprs2->tfi_b = (tfi & ((~((~0) << 3)) << 2)) >> 2; + egprs2->bsn1_a = 0; + egprs2->bsn1_b = 0; + egprs2->cps_a = 3; + egprs2->cps_b = 0; + egprs2->rsb = 0; + egprs2->pi = 0; + data[10] = 0x20; /* Setting E field */ + pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no]; + pdch->rcv_block(&data[0], 79, *fn, &meas); + + egprs2->r = 1; + egprs2->si = 1; + egprs2->cv = 7; + egprs2->tfi_a = tfi & (~((~0) << 2)); + egprs2->tfi_b = tfi & ((~((~0) << 3)) << 2); + egprs2->bsn1_a = 1; + egprs2->bsn1_b = 0; + egprs2->cps_a = 2; + egprs2->cps_b = 0; + egprs2->rsb = 0; + egprs2->pi = 0; + data[10] = 0x20; /*Setting E field */ + pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no]; + pdch->rcv_block(&data[0], 79, *fn, &meas); +} + +void uplink_header_type2_test(void) +{ + 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; + gprs_rlcmac_ul_tbf *ul_tbf; + GprsMs *ms; + + printf("=== start %s ===\n", __func__); + setup_bts(&the_bts, ts_no, 10); + + ul_tbf = uplink_header_type_2_parsing_test(&the_bts, ts_no, + tlli, &fn, qta, ms_class); + printf("=== end %s ===\n", __func__); +} + int main(int argc, char **argv) { struct vty_app_info pcu_vty_info = {0}; @@ -1431,6 +1544,7 @@ int main(int argc, char **argv) test_rlc_unaligned_copy(); test_rlc_unit_encoder(); uplink_header_type1_test(); + uplink_header_type2_test(); if (getenv("TALLOC_REPORT_FULL")) talloc_report_full(tall_pcu_ctx, stderr); return EXIT_SUCCESS; diff --git a/tests/edge/EdgeTest.ok b/tests/edge/EdgeTest.ok index 353f55d..1277d70 100644 --- a/tests/edge/EdgeTest.ok +++ b/tests/edge/EdgeTest.ok @@ -8,3 +8,5 @@ === end test_rlc_unit_encoder === === start uplink_header_type1_test === === end uplink_header_type1_test === +=== start uplink_header_type2_test === +=== end uplink_header_type2_test === -- 2.5.0 From holger at freyther.de Thu Apr 7 22:19:03 2016 From: holger at freyther.de (Holger Freyther) Date: Fri, 8 Apr 2016 00:19:03 +0200 Subject: [PATCH 1/2] Fix bug in uplink header type 1 parsing In-Reply-To: <1460030275-543-1-git-send-email-Bhargava.Abhyankar@radisys.com> References: <1460030275-543-1-git-send-email-Bhargava.Abhyankar@radisys.com> Message-ID: <69916AC6-393F-4482-9C49-919F8936CD6A@freyther.de> > On 07 Apr 2016, at 13:57, Bhargava Abhyankar wrote: > > Fix bug in extraction of E and TI header fields in parsing of uplink > header type 1 RLC data block. Test suite for the same is also updated. > > - e_ti_header = (data[offs-1] + (data[offs] << 8)) >> 7; > + e_ti_header = (data[offs - 1] & (0xc0)) >> 6; Could you please elaborate about this hunk? What is the issue, how was it found, how are we certain that this is the fix? > - rlc->block_info[0].e = !!(e_ti_header & 0x01); > - rlc->block_info[0].ti = !!(e_ti_header & 0x02); > + rlc->block_info[0].e = (e_ti_header & 0x01); > + rlc->block_info[0].ti = (e_ti_header & 0x02); what is the issue with this? The intention of !! is to normalize the value to 0 and 1. Now .ti can have 0x02 and 0x00 as value. Why is that needed? > cur_bit += 2; > > rlc->block_info[1].cv = egprs1->cv; > @@ -524,20 +524,21 @@ int Decoding::rlc_parse_ul_data_header_egprs_type_1( > ((egprs1->bsn2_a << 0) | (egprs1->bsn2_b << 2)); > rlc->block_info[1].bsn = rlc->block_info[1].bsn & (RLC_EGPRS_SNS - 1); > > - cur_bit += rlc->data_offs_bits[1] - 2; > + cur_bit = rlc->data_offs_bits[1] - 2; Why don't we need to advance this cursor anymore? offs = rlc->data_offs_bits[1] / 8; > OSMO_ASSERT(rlc->data_offs_bits[1] % 8 == 2); > > - e_ti_header = (data[offs-1] + (data[offs] << 8)) >> 7; > + e_ti_header = (data[offs] & (0x03)); What is the misunderstanding here. How did we think we needed to take bits from two different octets? > - rlc->block_info[1].e = !!(e_ti_header & 0x01); > - rlc->block_info[1].ti = !!(e_ti_header & 0x02); > + rlc->block_info[1].e = (e_ti_header & 0x01); > + rlc->block_info[1].ti = (e_ti_header & 0x02); Again, why the change from 0 or 1 to .. 0 or 1 .. and 0 or 2? > > diff --git a/tests/edge/EdgeTest.cpp b/tests/edge/EdgeTest.cpp > index ff080f9..9b4a1a5 100644 > --- a/tests/edge/EdgeTest.cpp > +++ b/tests/edge/EdgeTest.cpp > @@ -1376,18 +1376,16 @@ static gprs_rlcmac_ul_tbf *uplink_header_parsing_test(BTS *the_bts, > egprs1->r = 1; > egprs1->cv = 7; > egprs1->tfi_a = tfi & (~((~0) << 2)); > - egprs1->tfi_b = tfi & (~((~0) << 3)) << 2; > - egprs1->bsn1_a = 10; > - egprs1->bsn1_b = 17; > - egprs1->bsn2_a = 0; > - egprs1->bsn2_b = 25; > + egprs1->tfi_b = (tfi & (~((~0) << 3)) << 2) >> 2; > + egprs1->bsn1_a = 0; > + egprs1->bsn1_b = 0; > + egprs1->bsn2_a = 1; > + egprs1->bsn2_b = 0; > egprs1->cps = 15; > egprs1->rsb = 0; > egprs1->pi = 0; > - data[6] = 1; > - data[6 + 68] = 1; > - data[75] = 1; > - data[75 + 68] = 1; > + data[5] = 0x40; > + data[5 + 69] = 1; Please explain the intention here. What is the issue with tfi_b? Why do you change it. Why do you pick the new bsn1_a and bsn1_b values? holger From holger at freyther.de Thu Apr 7 22:22:21 2016 From: holger at freyther.de (Holger Freyther) Date: Fri, 8 Apr 2016 00:22:21 +0200 Subject: [PATCH 1/2] Fix bug in uplink header type 1 parsing In-Reply-To: <69916AC6-393F-4482-9C49-919F8936CD6A@freyther.de> References: <1460030275-543-1-git-send-email-Bhargava.Abhyankar@radisys.com> <69916AC6-393F-4482-9C49-919F8936CD6A@freyther.de> Message-ID: <5416DAAA-66A1-4ADA-B5F4-C5CB7426849F@freyther.de> > On 08 Apr 2016, at 00:19, Holger Freyther wrote: > > >> On 07 Apr 2016, at 13:57, Bhargava Abhyankar wrote: >> >> Fix bug in extraction of E and TI header fields in parsing of uplink >> header type 1 RLC data block. Test suite for the same is also updated. >> > >> - e_ti_header = (data[offs-1] + (data[offs] << 8)) >> 7; >> + e_ti_header = (data[offs - 1] & (0xc0)) >> 6; > > Could you please elaborate about this hunk? What is the issue, how was it found, how are we certain that this is the fix? And you can confirm that this is an issue in code we have not merged yet? In that case it should be fixed before including a wrong version. thank you holger From holger at freyther.de Thu Apr 7 22:29:16 2016 From: holger at freyther.de (Holger Freyther) Date: Fri, 8 Apr 2016 00:29:16 +0200 Subject: [PATCH 2/2] Add the test case for parsing uplink header type 2 In-Reply-To: <1460030275-543-2-git-send-email-Bhargava.Abhyankar@radisys.com> References: <1460030275-543-1-git-send-email-Bhargava.Abhyankar@radisys.com> <1460030275-543-2-git-send-email-Bhargava.Abhyankar@radisys.com> Message-ID: <8EED6042-39FA-48E5-B784-87BE3A83BAC5@freyther.de> > On 07 Apr 2016, at 13:57, Bhargava Abhyankar wrote: > > A test case is added to validate the uplink header type 2 extraction > functionality. Bug identified by unit test in the header type 2 > parsing is fixed. > offs = rlc->data_offs_bits[0] / 8; > - OSMO_ASSERT(rlc->data_offs_bits[0] % 8 == 1); > + OSMO_ASSERT(rlc->data_offs_bits[0] % 8 == 7); > - 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); > + e_ti_header = (data[offs] & 0x60) >> 5; > + rlc->block_info[0].e = (e_ti_header & 0x01); > + rlc->block_info[0].ti = (e_ti_header & 0x02); > cur_bit += 2; you probably want this to be in another commit. > + pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no]; > + pdch->rcv_block(&data[0], 79, *fn, &meas); like in my other mails, please have more strong post conditions. What do you actually expect in terms of side effects here? Test them specifically. kind regards holger From Arvind.sirsikar at radisys.com Mon Apr 11 10:45:20 2016 From: Arvind.sirsikar at radisys.com (Aravind Sirsikar) Date: Mon, 11 Apr 2016 16:15:20 +0530 Subject: [PATCH 1/4] Add data structure for MCS change in Retx Message-ID: <1460371523-32154-1-git-send-email-Arvind.sirsikar@radisys.com> From: Aravind Sirsikar Modify the existing data structure to support MCS change during retransmission in EGPRS DL --- src/gprs_coding_scheme.cpp | 36 ++++++++++++++++++++++++++++++++++++ src/gprs_coding_scheme.h | 8 ++++++++ src/rlc.h | 11 +++++++++++ 3 files changed, 55 insertions(+) diff --git a/src/gprs_coding_scheme.cpp b/src/gprs_coding_scheme.cpp index 8601d4f..436b2d9 100644 --- a/src/gprs_coding_scheme.cpp +++ b/src/gprs_coding_scheme.cpp @@ -21,6 +21,42 @@ #include "gprs_coding_scheme.h" +/* + * 44.060 Table 8.1.1.1 and Table 8.1.1.2 + * It has 3 level indexing. 0th level is ARQ type + * 1st level is Original MCS (index 0 corresponds to MCS1 and so on) + * 2nd level is MS MCS (index 0 corresponds to MCS1 and so on) + * in 0th level indexing only ARQ type 2 is supported i.e index 1 for + * incremental redundancy + */ + +/* TODO: Need to support ARQ type 1 */ +enum GprsCodingScheme::Scheme GprsCodingScheme::egprs_mcs_retx_tbl[MAX_NUM_ARQ] + [MAX_NUM_MCS][MAX_NUM_MCS] = { + { + {MCS1, MCS1, MCS1, MCS1, MCS1, MCS1, MCS1, MCS1, MCS1}, + {MCS2, MCS2, MCS2, MCS2, MCS2, MCS2, MCS2, MCS2, MCS2}, + {MCS3, MCS3, MCS3, MCS3, MCS3, MCS3, MCS3, MCS3, MCS3}, + {MCS1, MCS1, MCS1, MCS4, MCS4, MCS4, MCS4, MCS4, MCS4}, + {MCS2, MCS2, MCS2, MCS2, MCS5, MCS5, MCS7, MCS7, MCS7}, + {MCS3, MCS3, MCS3, MCS3, MCS3, MCS6, MCS6, MCS6, MCS9}, + {MCS2, MCS2, MCS2, MCS2, MCS5, MCS5, MCS7, MCS7, MCS7}, + {MCS3, MCS3, MCS3, MCS3, MCS3, MCS6, MCS6, MCS8, MCS8}, + {MCS3, MCS3, MCS3, MCS3, MCS3, MCS6, MCS6, MCS6, MCS9} + }, + { + {MCS1, MCS1, MCS1, MCS1, MCS1, MCS1, MCS1, MCS1, MCS1}, + {MCS2, MCS2, MCS2, MCS2, MCS2, MCS2, MCS2, MCS2, MCS2}, + {MCS3, MCS3, MCS3, MCS3, MCS3, MCS3, MCS3, MCS3, MCS3}, + {MCS4, MCS4, MCS4, MCS4, MCS4, MCS4, MCS4, MCS4, MCS4}, + {MCS5, MCS5, MCS5, MCS5, MCS5, MCS5, MCS7, MCS7, MCS7}, + {MCS6, MCS6, MCS6, MCS6, MCS6, MCS6, MCS6, MCS6, MCS9}, + {MCS5, MCS5, MCS5, MCS5, MCS5, MCS5, MCS7, MCS7, MCS7}, + {MCS6, MCS6, MCS6, MCS6, MCS6, MCS6, MCS6, MCS8, MCS8}, + {MCS6, MCS6, MCS6, MCS6, MCS6, MCS6, MCS6, MCS8, MCS9} + } + }; + static struct { struct { unsigned int bytes; diff --git a/src/gprs_coding_scheme.h b/src/gprs_coding_scheme.h index aec3762..06e90fc 100644 --- a/src/gprs_coding_scheme.h +++ b/src/gprs_coding_scheme.h @@ -26,6 +26,12 @@ class GprsCodingScheme { public: + +#define MAX_NUM_ARQ 2 /* max. number of ARQ */ +#define MAX_NUM_MCS 9 /* max. number of MCS */ +#define EGPRS_ARQ1 0x0 +#define EGPRS_ARQ2 0x1 + enum Scheme { UNKNOWN, CS1, CS2, CS3, CS4, @@ -105,6 +111,8 @@ public: static GprsCodingScheme getEgprsByNum(unsigned num); static const char *modeName(Mode mode); + static Scheme egprs_mcs_retx_tbl[MAX_NUM_ARQ] + [MAX_NUM_MCS][MAX_NUM_MCS]; private: GprsCodingScheme(int s); /* fail on use */ GprsCodingScheme& operator =(int s); /* fail on use */ diff --git a/src/rlc.h b/src/rlc.h index 8f75588..f5429c2 100644 --- a/src/rlc.h +++ b/src/rlc.h @@ -120,6 +120,17 @@ struct gprs_rlc_data { uint8_t len; struct gprs_rlc_data_block_info block_info; + + /* + * cs2 is variable to hold the cs value for + * current transmission. cs2 is same as cs during + * transmission case. During retransmission cs2 is + * fetched from egprs_mcs_retx_tbl table based on + * cs and demanded cs. Once the data has been sent successfully, + * cs2 will be copied to cs. Reference is 44.060 Table + * 8.1.1.1 and Table 8.1.1.2 + */ + GprsCodingScheme cs2; GprsCodingScheme cs; /* puncturing scheme value to be used for next transmission*/ -- 1.7.9.5 From Arvind.sirsikar at radisys.com Mon Apr 11 10:45:22 2016 From: Arvind.sirsikar at radisys.com (Aravind Sirsikar) Date: Mon, 11 Apr 2016 16:15:22 +0530 Subject: [PATCH 3/4] Modify DL tbf flow for MCS change in Retx In-Reply-To: <1460371523-32154-1-git-send-email-Arvind.sirsikar@radisys.com> References: <1460371523-32154-1-git-send-email-Arvind.sirsikar@radisys.com> Message-ID: <1460371523-32154-3-git-send-email-Arvind.sirsikar@radisys.com> From: Aravind Sirsikar Modify the DL TBF flow to support MCS change during the EGPRS retransmission --- src/tbf_dl.cpp | 36 +++++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/src/tbf_dl.cpp b/src/tbf_dl.cpp index 9e4d078..28f9083 100644 --- a/src/tbf_dl.cpp +++ b/src/tbf_dl.cpp @@ -365,7 +365,7 @@ int gprs_rlcmac_dl_tbf::take_next_bsn(uint32_t fn, bsn = m_window.resend_needed(); if (previous_bsn >= 0) { - force_cs = m_rlc.block(previous_bsn)->cs; + force_cs = m_rlc.block(previous_bsn)->cs2; if (!force_cs.isEgprs()) return -1; force_data_len = m_rlc.block(previous_bsn)->len; @@ -379,7 +379,19 @@ int gprs_rlcmac_dl_tbf::take_next_bsn(uint32_t fn, m_window.mod_sns(bsn - previous_bsn) > RLC_EGPRS_MAX_BSN_DELTA) return -1; - cs2 = m_rlc.block(bsn)->cs; + if (is_egprs_enabled()) { + m_rlc.block(bsn)->cs2 = GprsCodingScheme::get_retx_mcs + (m_rlc.block(bsn)->cs, ms()->current_cs_dl()); + + /* TODO: Need to remove this check when MCS-8 -> MCS-6 + * transistion is handled + */ + if ((m_rlc.block(bsn)->cs2 == GprsCodingScheme::MCS6) && + (m_rlc.block(bsn)->cs == GprsCodingScheme::MCS8)) + m_rlc.block(bsn)->cs2 = GprsCodingScheme::MCS8; + } else + m_rlc.block(bsn)->cs2 = m_rlc.block(bsn)->cs; + data_len2 = m_rlc.block(bsn)->len; if (force_data_len > 0 && force_data_len != data_len2) return -1; @@ -433,7 +445,7 @@ int gprs_rlcmac_dl_tbf::take_next_bsn(uint32_t fn, bts->rlc_resent(); } - *may_combine = cs2.numDataBlocks() > 1; + *may_combine = m_rlc.block(bsn)->cs2.numDataBlocks() > 1; return bsn; } @@ -505,6 +517,7 @@ int gprs_rlcmac_dl_tbf::create_new_bsn(const uint32_t fn, GprsCodingScheme cs) rlc_data = m_rlc.block(bsn); data = rlc_data->prepare(block_data_len); rlc_data->cs = cs; + rlc_data->cs2 = cs; rlc_data->len = block_data_len; rdbi = &(rlc_data->block_info); @@ -587,7 +600,6 @@ struct msgb *gprs_rlcmac_dl_tbf::create_dl_acked_block( bool is_final = false; gprs_rlc_data_info rlc; GprsCodingScheme cs; - GprsCodingScheme cs_current_trans; int bsns[ARRAY_SIZE(rlc.block_info)]; unsigned num_bsns; enum egprs_puncturing_values punct[ARRAY_SIZE(rlc.block_info)]; @@ -601,7 +613,7 @@ struct msgb *gprs_rlcmac_dl_tbf::create_dl_acked_block( * be put into the data area, even if the resulting CS is higher than * the current limit. */ - cs = m_rlc.block(index)->cs; + cs = m_rlc.block(index)->cs2; bsns[0] = index; num_bsns = 1; @@ -613,6 +625,9 @@ struct msgb *gprs_rlcmac_dl_tbf::create_dl_acked_block( if (num_bsns == 1) { /* TODO: remove the conditional when MCS-6 padding isn't * failing to be decoded by MEs anymore */ + /* TODO: support of MCS-8 -> MCS-6 transition should be + * handled + */ if (cs != GprsCodingScheme(GprsCodingScheme::MCS8)) cs.decToSingleBlock(&need_padding); } @@ -647,18 +662,15 @@ struct msgb *gprs_rlcmac_dl_tbf::create_dl_acked_block( else bsn = bsns[0]; - cs_enc = m_rlc.block(bsn)->cs; + cs_enc = m_rlc.block(bsn)->cs2; /* get data and header from current block */ block_data = m_rlc.block(bsn)->block; - /* TODO: Need to support MCS change during retx */ - cs_current_trans = cs; - /* Get current puncturing scheme from block */ punct_scheme = gprs_get_punct_scheme( m_rlc.block(bsn)->next_ps, - cs, cs_current_trans); + m_rlc.block(bsn)->cs, cs); if (cs.isEgprs()) { OSMO_ASSERT(punct_scheme >= EGPRS_PS_1); @@ -682,7 +694,9 @@ struct msgb *gprs_rlcmac_dl_tbf::create_dl_acked_block( * in header type 1 */ gprs_update_punct_scheme(&m_rlc.block(bsn)->next_ps, - cs_current_trans); + cs); + + m_rlc.block(bsn)->cs = m_rlc.block(bsn)->cs2; rdbi->e = block_info->e; rdbi->cv = block_info->cv; -- 1.7.9.5 From Arvind.sirsikar at radisys.com Mon Apr 11 10:45:23 2016 From: Arvind.sirsikar at radisys.com (Aravind Sirsikar) Date: Mon, 11 Apr 2016 16:15:23 +0530 Subject: [PATCH 4/4] Add test cases to support MCS change during Retx In-Reply-To: <1460371523-32154-1-git-send-email-Arvind.sirsikar@radisys.com> References: <1460371523-32154-1-git-send-email-Arvind.sirsikar@radisys.com> Message-ID: <1460371523-32154-4-git-send-email-Arvind.sirsikar@radisys.com> From: Aravind Sirsikar Add test cases to verify the MCS change functionality. During MCS upgradation such as MCS6->MCS9, 2 blocks which were sent separately as MCS6, will be clubbed into one MCS9 block during retransmission. Same holds good for MCS5->MCS7 transistion. During MCS reduction such as MCS9->MCS6,2 blocks which were sent together will be sent separately during the retransmission case. Same is verified through the generated log file. Currently MCS8->MCS6 transition is not supported. The retransmission MCS is being calculated from Table 8.1.1.2 of TS 44.060. --- tests/tbf/TbfTest.cpp | 117 ++++++ tests/tbf/TbfTest.err | 1007 +++++++++++++++++++++++++++++++++++++++++++++++++ tests/tbf/TbfTest.ok | 11 + 3 files changed, 1135 insertions(+) diff --git a/tests/tbf/TbfTest.cpp b/tests/tbf/TbfTest.cpp index e1be844..48da4c2 100644 --- a/tests/tbf/TbfTest.cpp +++ b/tests/tbf/TbfTest.cpp @@ -1272,6 +1272,122 @@ static void establish_and_use_egprs_dl_tbf(BTS *the_bts, int mcs) tbf_free(dl_tbf); } +static gprs_rlcmac_dl_tbf *tbf_init(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; + + 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(test_data); i++) + test_data[i] = i%256; + + OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW)); + + /* Schedule a LLC frame */ + dl_tbf->append_data(ms_class, 1000, test_data, 300); + + OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW)); + + return dl_tbf; + +} + +static void tbf_cleanup(gprs_rlcmac_dl_tbf *dl_tbf) +{ + uint32_t fn = 0; + uint8_t rbb[64/8]; + /* 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 establish_and_use_egprs_dl_tbf_for_retx_mcs_change(BTS *the_bts, + int mcs, int retx_mcs) +{ + uint32_t fn = 0; + gprs_rlcmac_dl_tbf *dl_tbf; + uint8_t block_nr = 0; + int index1 = 0; + + printf("Testing retx MCS %d -> %d\n", mcs, retx_mcs); + + dl_tbf = tbf_init(the_bts, + mcs); + + while (index1 < 4) { + /* Request to send one block */ + request_dl_rlc_block(dl_tbf, &fn, &block_nr); + index1++; + + /* Wait till 2 blocks are sent. Then change the MCS */ + if (dl_tbf->m_window.m_v_b.is_unacked(0) && + dl_tbf->m_window.m_v_b.is_unacked(1)) { + dl_tbf->m_window.m_v_b.mark_nacked(0); + dl_tbf->m_window.m_v_b.mark_nacked(1); + dl_tbf->ms()->set_current_cs_dl + ((GprsCodingScheme::Scheme) + (GprsCodingScheme::CS4 + retx_mcs)); + } + + } + tbf_cleanup(dl_tbf); +} + +static void test_tbf_egprs_retx_dl_mcs_change(void) +{ + BTS the_bts; + gprs_rlcmac_bts *bts; + uint8_t ts_no = 4; + int i, j; + + printf("=== start %s ===\n", __func__); + + bts = the_bts.bts_data(); + bts->cs_downgrade_threshold = 1; + setup_bts(&the_bts, ts_no); + bts->dl_tbf_idle_msec = 200; + bts->egprs_enabled = 1; + establish_and_use_egprs_dl_tbf_for_retx_mcs_change(&the_bts, 1, 9); + establish_and_use_egprs_dl_tbf_for_retx_mcs_change(&the_bts, 2, 8); + establish_and_use_egprs_dl_tbf_for_retx_mcs_change(&the_bts, 3, 6); + establish_and_use_egprs_dl_tbf_for_retx_mcs_change(&the_bts, 4, 5); + establish_and_use_egprs_dl_tbf_for_retx_mcs_change(&the_bts, 5, 7); + establish_and_use_egprs_dl_tbf_for_retx_mcs_change(&the_bts, 6, 9); + establish_and_use_egprs_dl_tbf_for_retx_mcs_change(&the_bts, 7, 5); + establish_and_use_egprs_dl_tbf_for_retx_mcs_change(&the_bts, 8, 6); + establish_and_use_egprs_dl_tbf_for_retx_mcs_change(&the_bts, 9, 6); + + printf("=== end %s ===\n", __func__); +} + static void test_tbf_egprs_dl() { BTS the_bts; @@ -1356,6 +1472,7 @@ int main(int argc, char **argv) test_tbf_ws(); test_tbf_egprs_two_phase(); test_tbf_egprs_dl(); + test_tbf_egprs_retx_dl_mcs_change(); 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 9bea2fd..5902088 100644 --- a/tests/tbf/TbfTest.err +++ b/tests/tbf/TbfTest.err @@ -5113,3 +5113,1010 @@ PDCH(TS 4, TRX 0): Detaching TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=RELEASING EG 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 03 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) +- Sending new block at BSN 0, CS=MCS-1 +- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (len=300) +-- Chunk with length 300 larger than space (22) left in block: copy only remaining space, and we are done +data block (BSN 0, MCS-1): 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 +- Copying data unit 0 (BSN 0) +msg block (BSN 0, MCS-1): 07 00 00 96 00 02 04 06 08 0a 0c 0e 10 12 14 16 18 1a 1c 1e 20 22 24 26 28 2a 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=4 block=1 data=07 00 00 96 00 02 04 06 08 0a 0c 0e 10 12 14 16 18 1a 1c 1e 20 22 24 26 28 2a 00 +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) +- Sending new block at BSN 1, CS=MCS-1 +-- Chunk with length 278 larger than space (22) left in block: copy only remaining space, and we are done +data block (BSN 1, MCS-1): 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b +- Copying data unit 0 (BSN 1) +msg block (BSN 1, MCS-1): 07 40 00 96 2c 2e 30 32 34 36 38 3a 3c 3e 40 42 44 46 48 4a 4c 4e 50 52 54 56 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=8 block=2 data=07 40 00 96 2c 2e 30 32 34 36 38 3a 3c 3e 40 42 44 46 48 4a 4c 4e 50 52 54 56 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) +- Resending BSN 0 +- Copying data unit 0 (BSN 0) +msg block (BSN 0, MCS-1): 07 00 00 98 00 02 04 06 08 0a 0c 0e 10 12 14 16 18 1a 1c 1e 20 22 24 26 28 2a 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=13 block=3 data=07 00 00 98 00 02 04 06 08 0a 0c 0e 10 12 14 16 18 1a 1c 1e 20 22 24 26 28 2a 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) +- Resending BSN 1 +- Copying data unit 0 (BSN 1) +msg block (BSN 1, MCS-1): 07 40 00 98 2c 2e 30 32 34 36 38 3a 3c 3e 40 42 44 46 48 4a 4c 4e 50 52 54 56 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=0 block=0 data=07 40 00 98 2c 2e 30 32 34 36 38 3a 3c 3e 40 42 44 46 48 4a 4c 4e 50 52 54 56 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 256 larger than space (74) left in block: copy only remaining space, and we are done +data block (BSN 2, MCS-9): 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 +- Sending new block at BSN 3, CS=MCS-9 +-- Chunk with length 182 larger than space (74) left in block: copy only remaining space, and we are done +data block (BSN 3, MCS-9): 76 77 78 79 7a 7b 7c 7d 7e 7f 80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf +- Copying data unit 0 (BSN 2) +- Copying data unit 1 (BSN 3) +msg block (BSN 2, MCS-9): 07 80 00 02 00 b1 b4 b8 bc c0 c4 c8 cc d0 d4 d8 dc e0 e4 e8 ec f0 f4 f8 fc 00 05 09 0d 11 15 19 1d 21 25 29 2d 31 35 39 3d 41 45 49 4d 51 55 59 5d 61 65 69 6d 71 75 79 7d 81 85 89 8d 91 95 99 9d a1 a5 a9 ad b1 b5 b9 bd c1 c5 c9 cd d1 d5 65 77 87 97 a7 b7 c7 d7 e7 f7 07 18 28 38 48 58 68 78 88 98 a8 b8 c8 d8 e8 f8 08 19 29 39 49 59 69 79 89 99 a9 b9 c9 d9 e9 f9 09 1a 2a 3a 4a 5a 6a 7a 8a 9a aa ba ca da ea fa 0a 1b 2b 3b 4b 5b 6b 7b 8b 9b ab bb cb db eb fb 0b +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=4 block=1 data=07 80 00 02 00 b1 b4 b8 bc c0 c4 c8 cc d0 d4 d8 dc e0 e4 e8 ec f0 f4 f8 fc 00 05 09 0d 11 15 19 1d 21 25 29 2d 31 35 39 3d 41 45 49 4d 51 55 59 5d 61 65 69 6d 71 75 79 7d 81 85 89 8d 91 95 99 9d a1 a5 a9 ad b1 b5 b9 bd c1 c5 c9 cd d1 d5 65 77 87 97 a7 b7 c7 d7 e7 f7 07 18 28 38 48 58 68 78 88 98 a8 b8 c8 d8 e8 f8 08 19 29 39 49 59 69 79 89 99 a9 b9 c9 d9 e9 f9 09 1a 2a 3a 4a 5a 6a 7a 8a 9a aa ba ca da ea fa 0a 1b 2b 3b 4b 5b 6b 7b 8b 9b ab bb cb db eb fb 0b +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)==4) +- Sending new block at BSN 4, CS=MCS-9 +-- Chunk with length 108 larger than space (74) left in block: copy only remaining space, and we are done +data block (BSN 4, MCS-9): c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca cb cc cd ce cf d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da db dc dd de df e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff 00 01 02 03 04 05 06 07 08 09 +- Sending new block at BSN 5, CS=MCS-9 +-- Chunk with length 34 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=300 +-- Empty chunk, added LLC dummy command of size 38, drained_since=0 +-- Chunk with length 38 is less than remaining space (39): 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=38 +data block (BSN 5, MCS-9): 44 4d 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 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 +- 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 4, MCS-9): 07 00 01 02 00 01 07 0b 0f 13 17 1b 1f 23 27 2b 2f 33 37 3b 3f 43 47 4b 4f 53 57 5b 5f 63 67 6b 6f 73 77 7b 7f 83 87 8b 8f 93 97 9b 9f a3 a7 ab af b3 b7 bb bf c3 c7 cb cf d3 d7 db df e3 e7 eb ef f3 f7 fb ff 03 04 08 0c 10 14 18 1c 20 24 40 d4 a4 b0 c0 d0 e0 f0 00 11 21 31 41 51 61 71 81 91 a1 b1 c1 d1 e1 f1 01 12 22 32 42 52 62 72 82 92 a2 b2 32 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 02 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=8 block=2 data=07 00 01 02 00 01 07 0b 0f 13 17 1b 1f 23 27 2b 2f 33 37 3b 3f 43 47 4b 4f 53 57 5b 5f 63 67 6b 6f 73 77 7b 7f 83 87 8b 8f 93 97 9b 9f a3 a7 ab af b3 b7 bb bf c3 c7 cb cf d3 d7 db df e3 e7 eb ef f3 f7 fb ff 03 04 08 0c 10 14 18 1c 20 24 40 d4 a4 b0 c0 d0 e0 f0 00 11 21 31 41 51 61 71 81 91 a1 b1 c1 d1 e1 f1 01 12 22 32 42 52 62 72 82 92 a2 b2 32 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 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 +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 03 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) +- Sending new block at BSN 0, CS=MCS-2 +- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (len=300) +-- Chunk with length 300 larger than space (28) left in block: copy only remaining space, and we are done +data block (BSN 0, MCS-2): 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b +- Copying data unit 0 (BSN 0) +msg block (BSN 0, MCS-2): 07 00 00 92 00 02 04 06 08 0a 0c 0e 10 12 14 16 18 1a 1c 1e 20 22 24 26 28 2a 2c 2e 30 32 34 36 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=4 block=1 data=07 00 00 92 00 02 04 06 08 0a 0c 0e 10 12 14 16 18 1a 1c 1e 20 22 24 26 28 2a 2c 2e 30 32 34 36 00 +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) +- Sending new block at BSN 1, CS=MCS-2 +-- Chunk with length 272 larger than space (28) left in block: copy only remaining space, and we are done +data block (BSN 1, MCS-2): 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 +- Copying data unit 0 (BSN 1) +msg block (BSN 1, MCS-2): 07 40 00 92 38 3a 3c 3e 40 42 44 46 48 4a 4c 4e 50 52 54 56 58 5a 5c 5e 60 62 64 66 68 6a 6c 6e 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=8 block=2 data=07 40 00 92 38 3a 3c 3e 40 42 44 46 48 4a 4c 4e 50 52 54 56 58 5a 5c 5e 60 62 64 66 68 6a 6c 6e 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) +- Resending BSN 0 +- Copying data unit 0 (BSN 0) +msg block (BSN 0, MCS-2): 07 00 00 94 00 02 04 06 08 0a 0c 0e 10 12 14 16 18 1a 1c 1e 20 22 24 26 28 2a 2c 2e 30 32 34 36 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=13 block=3 data=07 00 00 94 00 02 04 06 08 0a 0c 0e 10 12 14 16 18 1a 1c 1e 20 22 24 26 28 2a 2c 2e 30 32 34 36 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) +- Resending BSN 1 +- Copying data unit 0 (BSN 1) +msg block (BSN 1, MCS-2): 07 40 00 94 38 3a 3c 3e 40 42 44 46 48 4a 4c 4e 50 52 54 56 58 5a 5c 5e 60 62 64 66 68 6a 6c 6e 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=0 block=0 data=07 40 00 94 38 3a 3c 3e 40 42 44 46 48 4a 4c 4e 50 52 54 56 58 5a 5c 5e 60 62 64 66 68 6a 6c 6e 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 244 larger than space (68) left in block: copy only remaining space, and we are done +data block (BSN 2, MCS-8): 38 39 3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 78 79 7a 7b +- Sending new block at BSN 3, CS=MCS-8 +-- Chunk with length 176 larger than space (68) left in block: copy only remaining space, and we are done +data block (BSN 3, MCS-8): 7c 7d 7e 7f 80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf +- Copying data unit 0 (BSN 2) +- Copying data unit 1 (BSN 3) +msg block (BSN 2, MCS-8): 07 80 00 02 58 e1 e4 e8 ec f0 f4 f8 fc 00 05 09 0d 11 15 19 1d 21 25 29 2d 31 35 39 3d 41 45 49 4d 51 55 59 5d 61 65 69 6d 71 75 79 7d 81 85 89 8d 91 95 99 9d a1 a5 a9 ad b1 b5 b9 bd c1 c5 c9 cd d1 d5 d9 dd e1 e5 e9 ed c5 d7 e7 f7 07 18 28 38 48 58 68 78 88 98 a8 b8 c8 d8 e8 f8 08 19 29 39 49 59 69 79 89 99 a9 b9 c9 d9 e9 f9 09 1a 2a 3a 4a 5a 6a 7a 8a 9a aa ba ca da ea fa 0a 1b 2b 3b 4b 5b 6b 7b 8b 9b ab bb cb db eb fb 0b +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=4 block=1 data=07 80 00 02 58 e1 e4 e8 ec f0 f4 f8 fc 00 05 09 0d 11 15 19 1d 21 25 29 2d 31 35 39 3d 41 45 49 4d 51 55 59 5d 61 65 69 6d 71 75 79 7d 81 85 89 8d 91 95 99 9d a1 a5 a9 ad b1 b5 b9 bd c1 c5 c9 cd d1 d5 d9 dd e1 e5 e9 ed c5 d7 e7 f7 07 18 28 38 48 58 68 78 88 98 a8 b8 c8 d8 e8 f8 08 19 29 39 49 59 69 79 89 99 a9 b9 c9 d9 e9 f9 09 1a 2a 3a 4a 5a 6a 7a 8a 9a aa ba ca da ea fa 0a 1b 2b 3b 4b 5b 6b 7b 8b 9b ab bb cb db eb fb 0b +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)==4) +- Sending new block at BSN 4, CS=MCS-8 +-- Chunk with length 108 larger than space (68) left in block: copy only remaining space, and we are done +data block (BSN 4, MCS-8): c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca cb cc cd ce cf d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da db dc dd de df e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff 00 01 02 03 +- Sending new block at BSN 5, CS=MCS-8 +-- Chunk with length 40 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=300 +-- Empty chunk, added LLC dummy command of size 26, drained_since=0 +-- Chunk with length 26 is less than remaining space (27): 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=26 +data block (BSN 5, MCS-8): 50 35 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 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 +- 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 4, MCS-8): 07 00 01 02 58 01 07 0b 0f 13 17 1b 1f 23 27 2b 2f 33 37 3b 3f 43 47 4b 4f 53 57 5b 5f 63 67 6b 6f 73 77 7b 7f 83 87 8b 8f 93 97 9b 9f a3 a7 ab af b3 b7 bb bf c3 c7 cb cf d3 d7 db df e3 e7 eb ef f3 f7 fb ff 03 04 08 0c 00 55 43 50 60 70 80 90 a0 b0 c0 d0 e0 f0 00 11 21 31 41 51 61 71 81 91 a1 b1 c1 d1 e1 f1 01 12 22 32 42 52 62 72 82 92 a2 b2 32 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 02 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=8 block=2 data=07 00 01 02 58 01 07 0b 0f 13 17 1b 1f 23 27 2b 2f 33 37 3b 3f 43 47 4b 4f 53 57 5b 5f 63 67 6b 6f 73 77 7b 7f 83 87 8b 8f 93 97 9b 9f a3 a7 ab af b3 b7 bb bf c3 c7 cb cf d3 d7 db df e3 e7 eb ef f3 f7 fb ff 03 04 08 0c 00 55 43 50 60 70 80 90 a0 b0 c0 d0 e0 f0 00 11 21 31 41 51 61 71 81 91 a1 b1 c1 d1 e1 f1 01 12 22 32 42 52 62 72 82 92 a2 b2 32 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 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 +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 03 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) +- Sending new block at BSN 0, CS=MCS-3 +- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (len=300) +-- Chunk with length 300 larger than space (37) left in block: copy only remaining space, and we are done +data block (BSN 0, MCS-3): 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 +- Copying data unit 0 (BSN 0) +msg block (BSN 0, MCS-3): 07 00 00 86 00 02 04 06 08 0a 0c 0e 10 12 14 16 18 1a 1c 1e 20 22 24 26 28 2a 2c 2e 30 32 34 36 38 3a 3c 3e 40 42 44 46 48 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=4 block=1 data=07 00 00 86 00 02 04 06 08 0a 0c 0e 10 12 14 16 18 1a 1c 1e 20 22 24 26 28 2a 2c 2e 30 32 34 36 38 3a 3c 3e 40 42 44 46 48 00 +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) +- Sending new block at BSN 1, CS=MCS-3 +-- Chunk with length 263 larger than space (37) left in block: copy only remaining space, and we are done +data block (BSN 1, MCS-3): 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 +- Copying data unit 0 (BSN 1) +msg block (BSN 1, MCS-3): 07 40 00 86 4a 4c 4e 50 52 54 56 58 5a 5c 5e 60 62 64 66 68 6a 6c 6e 70 72 74 76 78 7a 7c 7e 80 82 84 86 88 8a 8c 8e 90 92 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=8 block=2 data=07 40 00 86 4a 4c 4e 50 52 54 56 58 5a 5c 5e 60 62 64 66 68 6a 6c 6e 70 72 74 76 78 7a 7c 7e 80 82 84 86 88 8a 8c 8e 90 92 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) +- Resending BSN 0 +- Copying data unit 0 (BSN 0) +msg block (BSN 0, MCS-3): 07 00 00 88 00 02 04 06 08 0a 0c 0e 10 12 14 16 18 1a 1c 1e 20 22 24 26 28 2a 2c 2e 30 32 34 36 38 3a 3c 3e 40 42 44 46 48 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=13 block=3 data=07 00 00 88 00 02 04 06 08 0a 0c 0e 10 12 14 16 18 1a 1c 1e 20 22 24 26 28 2a 2c 2e 30 32 34 36 38 3a 3c 3e 40 42 44 46 48 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) +- Resending BSN 1 +- Copying data unit 0 (BSN 1) +msg block (BSN 1, MCS-3): 07 40 00 88 4a 4c 4e 50 52 54 56 58 5a 5c 5e 60 62 64 66 68 6a 6c 6e 70 72 74 76 78 7a 7c 7e 80 82 84 86 88 8a 8c 8e 90 92 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=0 block=0 data=07 40 00 88 4a 4c 4e 50 52 54 56 58 5a 5c 5e 60 62 64 66 68 6a 6c 6e 70 72 74 76 78 7a 7c 7e 80 82 84 86 88 8a 8c 8e 90 92 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 226 larger than space (74) left in block: copy only remaining space, and we are done +data block (BSN 2, MCS-6): 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f 80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f 90 91 92 93 +- Copying data unit 0 (BSN 2) +msg block (BSN 2, MCS-6): 07 80 00 90 d2 12 53 93 d3 13 54 94 d4 14 55 95 d5 15 56 96 d6 16 57 97 d7 17 58 98 d8 18 59 99 d9 19 5a 9a da 1a 5b 9b db 1b 5c 9c dc 1c 5d 9d dd 1d 5e 9e de 1e 5f 9f df 1f 60 a0 e0 20 61 a1 e1 21 62 a2 e2 22 63 a3 e3 23 64 a4 e4 24 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=4 block=1 data=07 80 00 90 d2 12 53 93 d3 13 54 94 d4 14 55 95 d5 15 56 96 d6 16 57 97 d7 17 58 98 d8 18 59 99 d9 19 5a 9a da 1a 5b 9b db 1b 5c 9c dc 1c 5d 9d dd 1d 5e 9e de 1e 5f 9f df 1f 60 a0 e0 20 61 a1 e1 21 62 a2 e2 22 63 a3 e3 23 64 a4 e4 24 +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)==3) +- Sending new block at BSN 3, CS=MCS-6 +-- Chunk with length 152 larger than space (74) left in block: copy only remaining space, and we are done +data block (BSN 3, MCS-6): 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca cb cc cd ce cf d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da db dc dd +- Copying data unit 0 (BSN 3) +msg block (BSN 3, MCS-6): 07 c0 00 10 65 a5 e5 25 66 a6 e6 26 67 a7 e7 27 68 a8 e8 28 69 a9 e9 29 6a aa ea 2a 6b ab eb 2b 6c ac ec 2c 6d ad ed 2d 6e ae ee 2e 6f af ef 2f 70 b0 f0 30 71 b1 f1 31 72 b2 f2 32 73 b3 f3 33 74 b4 f4 34 75 b5 f5 35 76 b6 f6 36 77 37 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=8 block=2 data=07 c0 00 10 65 a5 e5 25 66 a6 e6 26 67 a7 e7 27 68 a8 e8 28 69 a9 e9 29 6a aa ea 2a 6b ab eb 2b 6c ac ec 2c 6d ad ed 2d 6e ae ee 2e 6f af ef 2f 70 b0 f0 30 71 b1 f1 31 72 b2 f2 32 73 b3 f3 33 74 b4 f4 34 75 b5 f5 35 76 b6 f6 36 77 37 +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 78 larger than space (74) left in block: copy only remaining space, and we are done +data block (BSN 4, MCS-6): de df e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 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 4) +msg block (BSN 4, MCS-6): 07 00 01 90 f7 37 78 b8 f8 38 79 b9 f9 39 7a ba fa 3a 7b bb fb 3b 7c bc fc 3c 7d bd fd 3d 7e be fe 3e 7f bf ff 3f 40 80 c0 00 41 81 c1 01 42 82 c2 02 43 83 c3 03 44 84 c4 04 45 85 c5 05 46 86 c6 06 47 87 c7 07 48 88 c8 08 49 89 c9 09 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=13 block=3 data=07 00 01 90 f7 37 78 b8 f8 38 79 b9 f9 39 7a ba fa 3a 7b bb fb 3b 7c bc fc 3c 7d bd fd 3d 7e be fe 3e 7f bf ff 3f 40 80 c0 00 41 81 c1 01 42 82 c2 02 43 83 c3 03 44 84 c4 04 45 85 c5 05 46 86 c6 06 47 87 c7 07 48 88 c8 08 49 89 c9 09 +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 4 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=300 +-- Empty chunk, added LLC dummy command of size 68, drained_since=0 +-- Chunk with length 68 is less than remaining space (69): 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=68 +data block (BSN 5, MCS-6): 08 89 28 29 2a 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 +- 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 00 42 22 4a 8a ca 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 0a +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=17 block=4 data=07 40 01 00 42 22 4a 8a ca 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 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 03 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) +- Sending new block at BSN 0, CS=MCS-4 +- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (len=300) +-- Chunk with length 300 larger than space (44) left in block: copy only remaining space, and we are done +data block (BSN 0, MCS-4): 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b +- Copying data unit 0 (BSN 0) +msg block (BSN 0, MCS-4): 07 00 00 80 00 02 04 06 08 0a 0c 0e 10 12 14 16 18 1a 1c 1e 20 22 24 26 28 2a 2c 2e 30 32 34 36 38 3a 3c 3e 40 42 44 46 48 4a 4c 4e 50 52 54 56 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=4 block=1 data=07 00 00 80 00 02 04 06 08 0a 0c 0e 10 12 14 16 18 1a 1c 1e 20 22 24 26 28 2a 2c 2e 30 32 34 36 38 3a 3c 3e 40 42 44 46 48 4a 4c 4e 50 52 54 56 00 +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) +- Sending new block at BSN 1, CS=MCS-4 +-- Chunk with length 256 larger than space (44) left in block: copy only remaining space, and we are done +data block (BSN 1, MCS-4): 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 +- Copying data unit 0 (BSN 1) +msg block (BSN 1, MCS-4): 07 40 00 80 58 5a 5c 5e 60 62 64 66 68 6a 6c 6e 70 72 74 76 78 7a 7c 7e 80 82 84 86 88 8a 8c 8e 90 92 94 96 98 9a 9c 9e a0 a2 a4 a6 a8 aa ac ae 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=8 block=2 data=07 40 00 80 58 5a 5c 5e 60 62 64 66 68 6a 6c 6e 70 72 74 76 78 7a 7c 7e 80 82 84 86 88 8a 8c 8e 90 92 94 96 98 9a 9c 9e a0 a2 a4 a6 a8 aa ac ae 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) +- Resending BSN 0 +- Copying data unit 0 (BSN 0) +msg block (BSN 0, MCS-4): 07 00 00 82 00 02 04 06 08 0a 0c 0e 10 12 14 16 18 1a 1c 1e 20 22 24 26 28 2a 2c 2e 30 32 34 36 38 3a 3c 3e 40 42 44 46 48 4a 4c 4e 50 52 54 56 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=13 block=3 data=07 00 00 82 00 02 04 06 08 0a 0c 0e 10 12 14 16 18 1a 1c 1e 20 22 24 26 28 2a 2c 2e 30 32 34 36 38 3a 3c 3e 40 42 44 46 48 4a 4c 4e 50 52 54 56 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) +- Resending BSN 1 +- Copying data unit 0 (BSN 1) +msg block (BSN 1, MCS-4): 07 40 00 82 58 5a 5c 5e 60 62 64 66 68 6a 6c 6e 70 72 74 76 78 7a 7c 7e 80 82 84 86 88 8a 8c 8e 90 92 94 96 98 9a 9c 9e a0 a2 a4 a6 a8 aa ac ae 00 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=0 block=0 data=07 40 00 82 58 5a 5c 5e 60 62 64 66 68 6a 6c 6e 70 72 74 76 78 7a 7c 7e 80 82 84 86 88 8a 8c 8e 90 92 94 96 98 9a 9c 9e a0 a2 a4 a6 a8 aa ac ae 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 212 larger than space (56) left in block: copy only remaining space, and we are done +data block (BSN 2, MCS-5): 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f 80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f +- Copying data unit 0 (BSN 2) +msg block (BSN 2, MCS-5): 07 80 00 18 56 96 d6 16 57 97 d7 17 58 98 d8 18 59 99 d9 19 5a 9a da 1a 5b 9b db 1b 5c 9c dc 1c 5d 9d dd 1d 5e 9e de 1e 5f 9f df 1f 60 a0 e0 20 61 a1 e1 21 62 a2 e2 22 63 a3 e3 23 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=4 block=1 data=07 80 00 18 56 96 d6 16 57 97 d7 17 58 98 d8 18 59 99 d9 19 5a 9a da 1a 5b 9b db 1b 5c 9c dc 1c 5d 9d dd 1d 5e 9e de 1e 5f 9f df 1f 60 a0 e0 20 61 a1 e1 21 62 a2 e2 22 63 a3 e3 23 +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)==3) +- Sending new block at BSN 3, CS=MCS-5 +-- Chunk with length 156 larger than space (56) left in block: copy only remaining space, and we are done +data block (BSN 3, MCS-5): 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf c0 c1 c2 c3 c4 c5 c6 c7 +- Copying data unit 0 (BSN 3) +msg block (BSN 3, MCS-5): 07 c0 00 18 64 a4 e4 24 65 a5 e5 25 66 a6 e6 26 67 a7 e7 27 68 a8 e8 28 69 a9 e9 29 6a aa ea 2a 6b ab eb 2b 6c ac ec 2c 6d ad ed 2d 6e ae ee 2e 6f af ef 2f 70 b0 f0 30 71 b1 f1 31 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=8 block=2 data=07 c0 00 18 64 a4 e4 24 65 a5 e5 25 66 a6 e6 26 67 a7 e7 27 68 a8 e8 28 69 a9 e9 29 6a aa ea 2a 6b ab eb 2b 6c ac ec 2c 6d ad ed 2d 6e ae ee 2e 6f af ef 2f 70 b0 f0 30 71 b1 f1 31 +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 100 larger than space (56) left in block: copy only remaining space, and we are done +data block (BSN 4, MCS-5): c8 c9 ca cb cc cd ce cf d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da db dc dd de df e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff +- Copying data unit 0 (BSN 4) +msg block (BSN 4, MCS-5): 07 00 01 18 72 b2 f2 32 73 b3 f3 33 74 b4 f4 34 75 b5 f5 35 76 b6 f6 36 77 b7 f7 37 78 b8 f8 38 79 b9 f9 39 7a ba fa 3a 7b bb fb 3b 7c bc fc 3c 7d bd fd 3d 7e be fe 3e 7f bf ff 3f +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=13 block=3 data=07 00 01 18 72 b2 f2 32 73 b3 f3 33 74 b4 f4 34 75 b5 f5 35 76 b6 f6 36 77 b7 f7 37 78 b8 f8 38 79 b9 f9 39 7a ba fa 3a 7b bb fb 3b 7c bc fc 3c 7d bd fd 3d 7e be fe 3e 7f bf ff 3f +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 44 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=300 +-- 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 5, MCS-5): 58 15 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 43 c0 01 2b 2b 2b 2b 2b 2b 2b +- 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 08 56 05 40 80 c0 00 41 81 c1 01 42 82 c2 02 43 83 c3 03 44 84 c4 04 45 85 c5 05 46 86 c6 06 47 87 c7 07 48 88 c8 08 49 89 c9 09 4a 8a ca ca 10 70 c0 ca ca ca ca ca ca 0a +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=17 block=4 data=07 40 01 08 56 05 40 80 c0 00 41 81 c1 01 42 82 c2 02 43 83 c3 03 44 84 c4 04 45 85 c5 05 46 86 c6 06 47 87 c7 07 48 88 c8 08 49 89 c9 09 4a 8a ca ca 10 70 c0 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 03 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) +- Sending new block at BSN 0, CS=MCS-5 +- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (len=300) +-- Chunk with length 300 larger than space (56) left in block: copy only remaining space, and we are done +data block (BSN 0, MCS-5): 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 +- Copying data unit 0 (BSN 0) +msg block (BSN 0, MCS-5): 07 00 00 18 40 80 c0 00 41 81 c1 01 42 82 c2 02 43 83 c3 03 44 84 c4 04 45 85 c5 05 46 86 c6 06 47 87 c7 07 48 88 c8 08 49 89 c9 09 4a 8a ca 0a 4b 8b cb 0b 4c 8c cc 0c 4d 8d cd 0d +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=4 block=1 data=07 00 00 18 40 80 c0 00 41 81 c1 01 42 82 c2 02 43 83 c3 03 44 84 c4 04 45 85 c5 05 46 86 c6 06 47 87 c7 07 48 88 c8 08 49 89 c9 09 4a 8a ca 0a 4b 8b cb 0b 4c 8c cc 0c 4d 8d cd 0d +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) +- Sending new block at BSN 1, CS=MCS-5 +-- Chunk with length 244 larger than space (56) left in block: copy only remaining space, and we are done +data block (BSN 1, MCS-5): 38 39 3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f +- Copying data unit 0 (BSN 1) +msg block (BSN 1, MCS-5): 07 40 00 18 4e 8e ce 0e 4f 8f cf 0f 50 90 d0 10 51 91 d1 11 52 92 d2 12 53 93 d3 13 54 94 d4 14 55 95 d5 15 56 96 d6 16 57 97 d7 17 58 98 d8 18 59 99 d9 19 5a 9a da 1a 5b 9b db 1b +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=8 block=2 data=07 40 00 18 4e 8e ce 0e 4f 8f cf 0f 50 90 d0 10 51 91 d1 11 52 92 d2 12 53 93 d3 13 54 94 d4 14 55 95 d5 15 56 96 d6 16 57 97 d7 17 58 98 d8 18 59 99 d9 19 5a 9a da 1a 5b 9b db 1b +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) +- Resending BSN 0 +- Resending BSN 1 +- Copying data unit 0 (BSN 0) +- Copying data unit 1 (BSN 1) +msg block (BSN 0, MCS-7): 07 00 00 02 c0 01 04 08 0c 10 14 18 1c 20 24 28 2c 30 34 38 3c 40 44 48 4c 50 54 58 5c 60 64 68 6c 70 74 78 7c 80 84 88 8c 90 94 98 9c a0 a4 a8 ac b0 b4 b8 bc c0 c4 c8 cc d0 d4 d8 dc 84 93 a3 b3 c3 d3 e3 f3 03 14 24 34 44 54 64 74 84 94 a4 b4 c4 d4 e4 f4 04 15 25 35 45 55 65 75 85 95 a5 b5 c5 d5 e5 f5 05 16 26 36 46 56 66 76 86 96 a6 b6 c6 d6 e6 f6 06 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=13 block=3 data=07 00 00 02 c0 01 04 08 0c 10 14 18 1c 20 24 28 2c 30 34 38 3c 40 44 48 4c 50 54 58 5c 60 64 68 6c 70 74 78 7c 80 84 88 8c 90 94 98 9c a0 a4 a8 ac b0 b4 b8 bc c0 c4 c8 cc d0 d4 d8 dc 84 93 a3 b3 c3 d3 e3 f3 03 14 24 34 44 54 64 74 84 94 a4 b4 c4 d4 e4 f4 04 15 25 35 45 55 65 75 85 95 a5 b5 c5 d5 e5 f5 05 16 26 36 46 56 66 76 86 96 a6 b6 c6 d6 e6 f6 06 +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) +- Resending BSN 0 +- Resending BSN 1 +- Copying data unit 0 (BSN 0) +- Copying data unit 1 (BSN 1) +msg block (BSN 0, MCS-7): 07 00 00 02 e0 01 04 08 0c 10 14 18 1c 20 24 28 2c 30 34 38 3c 40 44 48 4c 50 54 58 5c 60 64 68 6c 70 74 78 7c 80 84 88 8c 90 94 98 9c a0 a4 a8 ac b0 b4 b8 bc c0 c4 c8 cc d0 d4 d8 dc 84 93 a3 b3 c3 d3 e3 f3 03 14 24 34 44 54 64 74 84 94 a4 b4 c4 d4 e4 f4 04 15 25 35 45 55 65 75 85 95 a5 b5 c5 d5 e5 f5 05 16 26 36 46 56 66 76 86 96 a6 b6 c6 d6 e6 f6 06 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=0 block=0 data=07 00 00 02 e0 01 04 08 0c 10 14 18 1c 20 24 28 2c 30 34 38 3c 40 44 48 4c 50 54 58 5c 60 64 68 6c 70 74 78 7c 80 84 88 8c 90 94 98 9c a0 a4 a8 ac b0 b4 b8 bc c0 c4 c8 cc d0 d4 d8 dc 84 93 a3 b3 c3 d3 e3 f3 03 14 24 34 44 54 64 74 84 94 a4 b4 c4 d4 e4 f4 04 15 25 35 45 55 65 75 85 95 a5 b5 c5 d5 e5 f5 05 16 26 36 46 56 66 76 86 96 a6 b6 c6 d6 e6 f6 06 +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 188 larger than space (56) left in block: copy only remaining space, and we are done +data block (BSN 2, MCS-7): 70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f 80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f a0 a1 a2 a3 a4 a5 a6 a7 +- Sending new block at BSN 3, CS=MCS-7 +-- Chunk with length 132 larger than space (56) left in block: copy only remaining space, and we are done +data block (BSN 3, MCS-7): a8 a9 aa ab ac ad ae af b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca cb cc cd ce cf d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da db dc dd de df +- Copying data unit 0 (BSN 2) +- Copying data unit 1 (BSN 3) +msg block (BSN 2, MCS-7): 07 80 00 02 a0 c1 c5 c9 cd d1 d5 d9 dd e1 e5 e9 ed f1 f5 f9 fd 01 06 0a 0e 12 16 1a 1e 22 26 2a 2e 32 36 3a 3e 42 46 4a 4e 52 56 5a 5e 62 66 6a 6e 72 76 7a 7e 82 86 8a 8e 92 96 9a 9e 86 9a aa ba ca da ea fa 0a 1b 2b 3b 4b 5b 6b 7b 8b 9b ab bb cb db eb fb 0b 1c 2c 3c 4c 5c 6c 7c 8c 9c ac bc cc dc ec fc 0c 1d 2d 3d 4d 5d 6d 7d 8d 9d ad bd cd dd ed fd 0d +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=4 block=1 data=07 80 00 02 a0 c1 c5 c9 cd d1 d5 d9 dd e1 e5 e9 ed f1 f5 f9 fd 01 06 0a 0e 12 16 1a 1e 22 26 2a 2e 32 36 3a 3e 42 46 4a 4e 52 56 5a 5e 62 66 6a 6e 72 76 7a 7e 82 86 8a 8e 92 96 9a 9e 86 9a aa ba ca da ea fa 0a 1b 2b 3b 4b 5b 6b 7b 8b 9b ab bb cb db eb fb 0b 1c 2c 3c 4c 5c 6c 7c 8c 9c ac bc cc dc ec fc 0c 1d 2d 3d 4d 5d 6d 7d 8d 9d ad bd cd dd ed fd 0d +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)==4) +- Sending new block at BSN 4, CS=MCS-7 +-- Chunk with length 76 larger than space (56) left in block: copy only remaining space, and we are done +data block (BSN 4, MCS-7): e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 +- Sending new block at BSN 5, CS=MCS-7 +-- Chunk with length 20 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=300 +-- Empty chunk, added LLC dummy command of size 34, drained_since=0 +-- 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 5, MCS-7): 28 45 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 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 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 4, MCS-7): 07 00 01 02 a0 81 87 8b 8f 93 97 9b 9f a3 a7 ab af b3 b7 bb bf c3 c7 cb cf d3 d7 db df e3 e7 eb ef f3 f7 fb ff 03 04 08 0c 10 14 18 1c 20 24 28 2c 30 34 38 3c 40 44 48 4c 50 54 58 5c 80 52 84 91 a1 b1 c1 d1 e1 f1 01 12 22 32 42 52 62 72 82 92 a2 b2 32 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 02 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=8 block=2 data=07 00 01 02 a0 81 87 8b 8f 93 97 9b 9f a3 a7 ab af b3 b7 bb bf c3 c7 cb cf d3 d7 db df e3 e7 eb ef f3 f7 fb ff 03 04 08 0c 10 14 18 1c 20 24 28 2c 30 34 38 3c 40 44 48 4c 50 54 58 5c 80 52 84 91 a1 b1 c1 d1 e1 f1 01 12 22 32 42 52 62 72 82 92 a2 b2 32 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 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 +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 03 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) +- Sending new block at BSN 0, CS=MCS-6 +- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (len=300) +-- Chunk with length 300 larger than space (74) left in block: copy only remaining space, and we are done +data block (BSN 0, MCS-6): 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 +- Copying data unit 0 (BSN 0) +msg block (BSN 0, MCS-6): 07 00 00 10 40 80 c0 00 41 81 c1 01 42 82 c2 02 43 83 c3 03 44 84 c4 04 45 85 c5 05 46 86 c6 06 47 87 c7 07 48 88 c8 08 49 89 c9 09 4a 8a ca 0a 4b 8b cb 0b 4c 8c cc 0c 4d 8d cd 0d 4e 8e ce 0e 4f 8f cf 0f 50 90 d0 10 51 91 d1 11 52 12 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=4 block=1 data=07 00 00 10 40 80 c0 00 41 81 c1 01 42 82 c2 02 43 83 c3 03 44 84 c4 04 45 85 c5 05 46 86 c6 06 47 87 c7 07 48 88 c8 08 49 89 c9 09 4a 8a ca 0a 4b 8b cb 0b 4c 8c cc 0c 4d 8d cd 0d 4e 8e ce 0e 4f 8f cf 0f 50 90 d0 10 51 91 d1 11 52 12 +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) +- Sending new block at BSN 1, CS=MCS-6 +-- Chunk with length 226 larger than space (74) left in block: copy only remaining space, and we are done +data block (BSN 1, MCS-6): 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f 80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f 90 91 92 93 +- Copying data unit 0 (BSN 1) +msg block (BSN 1, MCS-6): 07 40 00 90 d2 12 53 93 d3 13 54 94 d4 14 55 95 d5 15 56 96 d6 16 57 97 d7 17 58 98 d8 18 59 99 d9 19 5a 9a da 1a 5b 9b db 1b 5c 9c dc 1c 5d 9d dd 1d 5e 9e de 1e 5f 9f df 1f 60 a0 e0 20 61 a1 e1 21 62 a2 e2 22 63 a3 e3 23 64 a4 e4 24 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=8 block=2 data=07 40 00 90 d2 12 53 93 d3 13 54 94 d4 14 55 95 d5 15 56 96 d6 16 57 97 d7 17 58 98 d8 18 59 99 d9 19 5a 9a da 1a 5b 9b db 1b 5c 9c dc 1c 5d 9d dd 1d 5e 9e de 1e 5f 9f df 1f 60 a0 e0 20 61 a1 e1 21 62 a2 e2 22 63 a3 e3 23 64 a4 e4 24 +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) +- Resending BSN 0 +- Resending BSN 1 +- Copying data unit 0 (BSN 0) +- Copying data unit 1 (BSN 1) +msg block (BSN 0, MCS-9): 07 00 00 02 28 01 04 08 0c 10 14 18 1c 20 24 28 2c 30 34 38 3c 40 44 48 4c 50 54 58 5c 60 64 68 6c 70 74 78 7c 80 84 88 8c 90 94 98 9c a0 a4 a8 ac b0 b4 b8 bc c0 c4 c8 cc d0 d4 d8 dc e0 e4 e8 ec f0 f4 f8 fc 00 05 09 0d 11 15 19 1d 21 25 a5 b4 c4 d4 e4 f4 04 15 25 35 45 55 65 75 85 95 a5 b5 c5 d5 e5 f5 05 16 26 36 46 56 66 76 86 96 a6 b6 c6 d6 e6 f6 06 17 27 37 47 57 67 77 87 97 a7 b7 c7 d7 e7 f7 07 18 28 38 48 58 68 78 88 98 a8 b8 c8 d8 e8 f8 08 19 29 39 09 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=13 block=3 data=07 00 00 02 28 01 04 08 0c 10 14 18 1c 20 24 28 2c 30 34 38 3c 40 44 48 4c 50 54 58 5c 60 64 68 6c 70 74 78 7c 80 84 88 8c 90 94 98 9c a0 a4 a8 ac b0 b4 b8 bc c0 c4 c8 cc d0 d4 d8 dc e0 e4 e8 ec f0 f4 f8 fc 00 05 09 0d 11 15 19 1d 21 25 a5 b4 c4 d4 e4 f4 04 15 25 35 45 55 65 75 85 95 a5 b5 c5 d5 e5 f5 05 16 26 36 46 56 66 76 86 96 a6 b6 c6 d6 e6 f6 06 17 27 37 47 57 67 77 87 97 a7 b7 c7 d7 e7 f7 07 18 28 38 48 58 68 78 88 98 a8 b8 c8 d8 e8 f8 08 19 29 39 09 +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) +- Resending BSN 0 +- Resending BSN 1 +- Copying data unit 0 (BSN 0) +- Copying data unit 1 (BSN 1) +msg block (BSN 0, MCS-9): 07 00 00 02 50 01 04 08 0c 10 14 18 1c 20 24 28 2c 30 34 38 3c 40 44 48 4c 50 54 58 5c 60 64 68 6c 70 74 78 7c 80 84 88 8c 90 94 98 9c a0 a4 a8 ac b0 b4 b8 bc c0 c4 c8 cc d0 d4 d8 dc e0 e4 e8 ec f0 f4 f8 fc 00 05 09 0d 11 15 19 1d 21 25 a5 b4 c4 d4 e4 f4 04 15 25 35 45 55 65 75 85 95 a5 b5 c5 d5 e5 f5 05 16 26 36 46 56 66 76 86 96 a6 b6 c6 d6 e6 f6 06 17 27 37 47 57 67 77 87 97 a7 b7 c7 d7 e7 f7 07 18 28 38 48 58 68 78 88 98 a8 b8 c8 d8 e8 f8 08 19 29 39 09 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=0 block=0 data=07 00 00 02 50 01 04 08 0c 10 14 18 1c 20 24 28 2c 30 34 38 3c 40 44 48 4c 50 54 58 5c 60 64 68 6c 70 74 78 7c 80 84 88 8c 90 94 98 9c a0 a4 a8 ac b0 b4 b8 bc c0 c4 c8 cc d0 d4 d8 dc e0 e4 e8 ec f0 f4 f8 fc 00 05 09 0d 11 15 19 1d 21 25 a5 b4 c4 d4 e4 f4 04 15 25 35 45 55 65 75 85 95 a5 b5 c5 d5 e5 f5 05 16 26 36 46 56 66 76 86 96 a6 b6 c6 d6 e6 f6 06 17 27 37 47 57 67 77 87 97 a7 b7 c7 d7 e7 f7 07 18 28 38 48 58 68 78 88 98 a8 b8 c8 d8 e8 f8 08 19 29 39 09 +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 152 larger than space (74) left in block: copy only remaining space, and we are done +data block (BSN 2, MCS-9): 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca cb cc cd ce cf d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da db dc dd +- Sending new block at BSN 3, CS=MCS-9 +-- Chunk with length 78 larger than space (74) left in block: copy only remaining space, and we are done +data block (BSN 3, MCS-9): de df e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 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 2) +- Copying data unit 1 (BSN 3) +msg block (BSN 2, MCS-9): 07 80 00 02 00 51 56 5a 5e 62 66 6a 6e 72 76 7a 7e 82 86 8a 8e 92 96 9a 9e a2 a6 aa ae b2 b6 ba be c2 c6 ca ce d2 d6 da de e2 e6 ea ee f2 f6 fa fe 02 07 0b 0f 13 17 1b 1f 23 27 2b 2f 33 37 3b 3f 43 47 4b 4f 53 57 5b 5f 63 67 6b 6f 73 77 e7 fd 0d 1e 2e 3e 4e 5e 6e 7e 8e 9e ae be ce de ee fe 0e 1f 2f 3f 4f 5f 6f 7f 8f 9f af bf cf df ef ff 0f 10 20 30 40 50 60 70 80 90 a0 b0 c0 d0 e0 f0 00 11 21 31 41 51 61 71 81 91 a1 b1 c1 d1 e1 f1 01 12 22 32 42 52 62 72 02 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=4 block=1 data=07 80 00 02 00 51 56 5a 5e 62 66 6a 6e 72 76 7a 7e 82 86 8a 8e 92 96 9a 9e a2 a6 aa ae b2 b6 ba be c2 c6 ca ce d2 d6 da de e2 e6 ea ee f2 f6 fa fe 02 07 0b 0f 13 17 1b 1f 23 27 2b 2f 33 37 3b 3f 43 47 4b 4f 53 57 5b 5f 63 67 6b 6f 73 77 e7 fd 0d 1e 2e 3e 4e 5e 6e 7e 8e 9e ae be ce de ee fe 0e 1f 2f 3f 4f 5f 6f 7f 8f 9f af bf cf df ef ff 0f 10 20 30 40 50 60 70 80 90 a0 b0 c0 d0 e0 f0 00 11 21 31 41 51 61 71 81 91 a1 b1 c1 d1 e1 f1 01 12 22 32 42 52 62 72 02 +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)==4) +- Sending new block at BSN 4, CS=MCS-9 +-- Chunk with length 4 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=300 +-- Empty chunk, added LLC dummy command of size 68, drained_since=0 +-- Chunk with length 68 is less than remaining space (69): 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=68 +data block (BSN 4, MCS-9): 08 89 28 29 2a 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 +- Restarting at BSN 0, because all blocks have been transmitted (FLOW). +- 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 00 42 22 4a 8a ca 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 0a +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=8 block=2 data=07 00 01 00 42 22 4a 8a ca 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 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 03 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) +- Sending new block at BSN 0, CS=MCS-7 +- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (len=300) +-- Chunk with length 300 larger than space (56) left in block: copy only remaining space, and we are done +data block (BSN 0, MCS-7): 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 +- Sending new block at BSN 1, CS=MCS-7 +-- Chunk with length 244 larger than space (56) left in block: copy only remaining space, and we are done +data block (BSN 1, MCS-7): 38 39 3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f +- Copying data unit 0 (BSN 0) +- Copying data unit 1 (BSN 1) +msg block (BSN 0, MCS-7): 07 00 00 02 a0 01 04 08 0c 10 14 18 1c 20 24 28 2c 30 34 38 3c 40 44 48 4c 50 54 58 5c 60 64 68 6c 70 74 78 7c 80 84 88 8c 90 94 98 9c a0 a4 a8 ac b0 b4 b8 bc c0 c4 c8 cc d0 d4 d8 dc 84 93 a3 b3 c3 d3 e3 f3 03 14 24 34 44 54 64 74 84 94 a4 b4 c4 d4 e4 f4 04 15 25 35 45 55 65 75 85 95 a5 b5 c5 d5 e5 f5 05 16 26 36 46 56 66 76 86 96 a6 b6 c6 d6 e6 f6 06 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=4 block=1 data=07 00 00 02 a0 01 04 08 0c 10 14 18 1c 20 24 28 2c 30 34 38 3c 40 44 48 4c 50 54 58 5c 60 64 68 6c 70 74 78 7c 80 84 88 8c 90 94 98 9c a0 a4 a8 ac b0 b4 b8 bc c0 c4 c8 cc d0 d4 d8 dc 84 93 a3 b3 c3 d3 e3 f3 03 14 24 34 44 54 64 74 84 94 a4 b4 c4 d4 e4 f4 04 15 25 35 45 55 65 75 85 95 a5 b5 c5 d5 e5 f5 05 16 26 36 46 56 66 76 86 96 a6 b6 c6 d6 e6 f6 06 +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)==2) +- Resending BSN 0 +- Copying data unit 0 (BSN 0) +msg block (BSN 0, MCS-5): 07 00 00 18 40 80 c0 00 41 81 c1 01 42 82 c2 02 43 83 c3 03 44 84 c4 04 45 85 c5 05 46 86 c6 06 47 87 c7 07 48 88 c8 08 49 89 c9 09 4a 8a ca 0a 4b 8b cb 0b 4c 8c cc 0c 4d 8d cd 0d +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=8 block=2 data=07 00 00 18 40 80 c0 00 41 81 c1 01 42 82 c2 02 43 83 c3 03 44 84 c4 04 45 85 c5 05 46 86 c6 06 47 87 c7 07 48 88 c8 08 49 89 c9 09 4a 8a ca 0a 4b 8b cb 0b 4c 8c cc 0c 4d 8d cd 0d +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) +- Resending BSN 1 +- Copying data unit 0 (BSN 1) +msg block (BSN 1, MCS-5): 07 40 00 18 4e 8e ce 0e 4f 8f cf 0f 50 90 d0 10 51 91 d1 11 52 92 d2 12 53 93 d3 13 54 94 d4 14 55 95 d5 15 56 96 d6 16 57 97 d7 17 58 98 d8 18 59 99 d9 19 5a 9a da 1a 5b 9b db 1b +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=13 block=3 data=07 40 00 18 4e 8e ce 0e 4f 8f cf 0f 50 90 d0 10 51 91 d1 11 52 92 d2 12 53 93 d3 13 54 94 d4 14 55 95 d5 15 56 96 d6 16 57 97 d7 17 58 98 d8 18 59 99 d9 19 5a 9a da 1a 5b 9b db 1b +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) +- Resending BSN 0 +- Copying data unit 0 (BSN 0) +msg block (BSN 0, MCS-5): 07 00 00 18 40 80 c0 00 41 81 c1 01 42 82 c2 02 43 83 c3 03 44 84 c4 04 45 85 c5 05 46 86 c6 06 47 87 c7 07 48 88 c8 08 49 89 c9 09 4a 8a ca 0a 4b 8b cb 0b 4c 8c cc 0c 4d 8d cd 0d +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=0 block=0 data=07 00 00 18 40 80 c0 00 41 81 c1 01 42 82 c2 02 43 83 c3 03 44 84 c4 04 45 85 c5 05 46 86 c6 06 47 87 c7 07 48 88 c8 08 49 89 c9 09 4a 8a ca 0a 4b 8b cb 0b 4c 8c cc 0c 4d 8d cd 0d +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) +- Resending BSN 1 +- Copying data unit 0 (BSN 1) +msg block (BSN 1, MCS-5): 07 40 00 18 4e 8e ce 0e 4f 8f cf 0f 50 90 d0 10 51 91 d1 11 52 92 d2 12 53 93 d3 13 54 94 d4 14 55 95 d5 15 56 96 d6 16 57 97 d7 17 58 98 d8 18 59 99 d9 19 5a 9a da 1a 5b 9b db 1b +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=4 block=1 data=07 40 00 18 4e 8e ce 0e 4f 8f cf 0f 50 90 d0 10 51 91 d1 11 52 92 d2 12 53 93 d3 13 54 94 d4 14 55 95 d5 15 56 96 d6 16 57 97 d7 17 58 98 d8 18 59 99 d9 19 5a 9a da 1a 5b 9b db 1b +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)==2) +- Sending new block at BSN 2, CS=MCS-5 +-- Chunk with length 188 larger than space (56) left in block: copy only remaining space, and we are done +data block (BSN 2, MCS-5): 70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f 80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f a0 a1 a2 a3 a4 a5 a6 a7 +- Copying data unit 0 (BSN 2) +msg block (BSN 2, MCS-5): 07 80 00 18 5c 9c dc 1c 5d 9d dd 1d 5e 9e de 1e 5f 9f df 1f 60 a0 e0 20 61 a1 e1 21 62 a2 e2 22 63 a3 e3 23 64 a4 e4 24 65 a5 e5 25 66 a6 e6 26 67 a7 e7 27 68 a8 e8 28 69 a9 e9 29 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=8 block=2 data=07 80 00 18 5c 9c dc 1c 5d 9d dd 1d 5e 9e de 1e 5f 9f df 1f 60 a0 e0 20 61 a1 e1 21 62 a2 e2 22 63 a3 e3 23 64 a4 e4 24 65 a5 e5 25 66 a6 e6 26 67 a7 e7 27 68 a8 e8 28 69 a9 e9 29 +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 132 larger than space (56) left in block: copy only remaining space, and we are done +data block (BSN 3, MCS-5): a8 a9 aa ab ac ad ae af b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca cb cc cd ce cf d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da db dc dd de df +- Copying data unit 0 (BSN 3) +msg block (BSN 3, MCS-5): 07 c0 00 18 6a aa ea 2a 6b ab eb 2b 6c ac ec 2c 6d ad ed 2d 6e ae ee 2e 6f af ef 2f 70 b0 f0 30 71 b1 f1 31 72 b2 f2 32 73 b3 f3 33 74 b4 f4 34 75 b5 f5 35 76 b6 f6 36 77 b7 f7 37 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=13 block=3 data=07 c0 00 18 6a aa ea 2a 6b ab eb 2b 6c ac ec 2c 6d ad ed 2d 6e ae ee 2e 6f af ef 2f 70 b0 f0 30 71 b1 f1 31 72 b2 f2 32 73 b3 f3 33 74 b4 f4 34 75 b5 f5 35 76 b6 f6 36 77 b7 f7 37 +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 76 larger than space (56) left in block: copy only remaining space, and we are done +data block (BSN 4, MCS-5): e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 +- Copying data unit 0 (BSN 4) +msg block (BSN 4, MCS-5): 07 00 01 18 78 b8 f8 38 79 b9 f9 39 7a ba fa 3a 7b bb fb 3b 7c bc fc 3c 7d bd fd 3d 7e be fe 3e 7f bf ff 3f 40 80 c0 00 41 81 c1 01 42 82 c2 02 43 83 c3 03 44 84 c4 04 45 85 c5 05 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=17 block=4 data=07 00 01 18 78 b8 f8 38 79 b9 f9 39 7a ba fa 3a 7b bb fb 3b 7c bc fc 3c 7d bd fd 3d 7e be fe 3e 7f bf ff 3f 40 80 c0 00 41 81 c1 01 42 82 c2 02 43 83 c3 03 44 84 c4 04 45 85 c5 05 +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 20 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=300 +-- Empty chunk, added LLC dummy command of size 34, drained_since=0 +-- 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 5, MCS-5): 28 45 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 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 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 08 4a 11 46 86 c6 06 47 87 c7 07 48 88 c8 08 49 89 c9 09 4a 8a ca 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 0a +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=21 block=5 data=07 40 01 08 4a 11 46 86 c6 06 47 87 c7 07 48 88 c8 08 49 89 c9 09 4a 8a ca 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 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 03 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) +- Sending new block at BSN 0, CS=MCS-8 +- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (len=300) +-- Chunk with length 300 larger than space (68) left in block: copy only remaining space, and we are done +data block (BSN 0, MCS-8): 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 40 41 42 43 +- Sending new block at BSN 1, CS=MCS-8 +-- Chunk with length 232 larger than space (68) left in block: copy only remaining space, and we are done +data block (BSN 1, MCS-8): 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f 80 81 82 83 84 85 86 87 +- Copying data unit 0 (BSN 0) +- Copying data unit 1 (BSN 1) +msg block (BSN 0, MCS-8): 07 00 00 02 58 01 04 08 0c 10 14 18 1c 20 24 28 2c 30 34 38 3c 40 44 48 4c 50 54 58 5c 60 64 68 6c 70 74 78 7c 80 84 88 8c 90 94 98 9c a0 a4 a8 ac b0 b4 b8 bc c0 c4 c8 cc d0 d4 d8 dc e0 e4 e8 ec f0 f4 f8 fc 00 05 09 0d 45 54 64 74 84 94 a4 b4 c4 d4 e4 f4 04 15 25 35 45 55 65 75 85 95 a5 b5 c5 d5 e5 f5 05 16 26 36 46 56 66 76 86 96 a6 b6 c6 d6 e6 f6 06 17 27 37 47 57 67 77 87 97 a7 b7 c7 d7 e7 f7 07 18 28 38 48 58 68 78 08 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=4 block=1 data=07 00 00 02 58 01 04 08 0c 10 14 18 1c 20 24 28 2c 30 34 38 3c 40 44 48 4c 50 54 58 5c 60 64 68 6c 70 74 78 7c 80 84 88 8c 90 94 98 9c a0 a4 a8 ac b0 b4 b8 bc c0 c4 c8 cc d0 d4 d8 dc e0 e4 e8 ec f0 f4 f8 fc 00 05 09 0d 45 54 64 74 84 94 a4 b4 c4 d4 e4 f4 04 15 25 35 45 55 65 75 85 95 a5 b5 c5 d5 e5 f5 05 16 26 36 46 56 66 76 86 96 a6 b6 c6 d6 e6 f6 06 17 27 37 47 57 67 77 87 97 a7 b7 c7 d7 e7 f7 07 18 28 38 48 58 68 78 08 +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)==2) +- Resending BSN 0 +- Resending BSN 1 +- Copying data unit 0 (BSN 0) +- Copying data unit 1 (BSN 1) +msg block (BSN 0, MCS-8): 07 00 00 02 78 01 04 08 0c 10 14 18 1c 20 24 28 2c 30 34 38 3c 40 44 48 4c 50 54 58 5c 60 64 68 6c 70 74 78 7c 80 84 88 8c 90 94 98 9c a0 a4 a8 ac b0 b4 b8 bc c0 c4 c8 cc d0 d4 d8 dc e0 e4 e8 ec f0 f4 f8 fc 00 05 09 0d 45 54 64 74 84 94 a4 b4 c4 d4 e4 f4 04 15 25 35 45 55 65 75 85 95 a5 b5 c5 d5 e5 f5 05 16 26 36 46 56 66 76 86 96 a6 b6 c6 d6 e6 f6 06 17 27 37 47 57 67 77 87 97 a7 b7 c7 d7 e7 f7 07 18 28 38 48 58 68 78 08 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=8 block=2 data=07 00 00 02 78 01 04 08 0c 10 14 18 1c 20 24 28 2c 30 34 38 3c 40 44 48 4c 50 54 58 5c 60 64 68 6c 70 74 78 7c 80 84 88 8c 90 94 98 9c a0 a4 a8 ac b0 b4 b8 bc c0 c4 c8 cc d0 d4 d8 dc e0 e4 e8 ec f0 f4 f8 fc 00 05 09 0d 45 54 64 74 84 94 a4 b4 c4 d4 e4 f4 04 15 25 35 45 55 65 75 85 95 a5 b5 c5 d5 e5 f5 05 16 26 36 46 56 66 76 86 96 a6 b6 c6 d6 e6 f6 06 17 27 37 47 57 67 77 87 97 a7 b7 c7 d7 e7 f7 07 18 28 38 48 58 68 78 08 +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) +- Resending BSN 0 +- Resending BSN 1 +- Copying data unit 0 (BSN 0) +- Copying data unit 1 (BSN 1) +msg block (BSN 0, MCS-8): 07 00 00 02 98 01 04 08 0c 10 14 18 1c 20 24 28 2c 30 34 38 3c 40 44 48 4c 50 54 58 5c 60 64 68 6c 70 74 78 7c 80 84 88 8c 90 94 98 9c a0 a4 a8 ac b0 b4 b8 bc c0 c4 c8 cc d0 d4 d8 dc e0 e4 e8 ec f0 f4 f8 fc 00 05 09 0d 45 54 64 74 84 94 a4 b4 c4 d4 e4 f4 04 15 25 35 45 55 65 75 85 95 a5 b5 c5 d5 e5 f5 05 16 26 36 46 56 66 76 86 96 a6 b6 c6 d6 e6 f6 06 17 27 37 47 57 67 77 87 97 a7 b7 c7 d7 e7 f7 07 18 28 38 48 58 68 78 08 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=13 block=3 data=07 00 00 02 98 01 04 08 0c 10 14 18 1c 20 24 28 2c 30 34 38 3c 40 44 48 4c 50 54 58 5c 60 64 68 6c 70 74 78 7c 80 84 88 8c 90 94 98 9c a0 a4 a8 ac b0 b4 b8 bc c0 c4 c8 cc d0 d4 d8 dc e0 e4 e8 ec f0 f4 f8 fc 00 05 09 0d 45 54 64 74 84 94 a4 b4 c4 d4 e4 f4 04 15 25 35 45 55 65 75 85 95 a5 b5 c5 d5 e5 f5 05 16 26 36 46 56 66 76 86 96 a6 b6 c6 d6 e6 f6 06 17 27 37 47 57 67 77 87 97 a7 b7 c7 d7 e7 f7 07 18 28 38 48 58 68 78 08 +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) +- Resending BSN 0 +- Resending BSN 1 +- Copying data unit 0 (BSN 0) +- Copying data unit 1 (BSN 1) +msg block (BSN 0, MCS-8): 07 00 00 02 58 01 04 08 0c 10 14 18 1c 20 24 28 2c 30 34 38 3c 40 44 48 4c 50 54 58 5c 60 64 68 6c 70 74 78 7c 80 84 88 8c 90 94 98 9c a0 a4 a8 ac b0 b4 b8 bc c0 c4 c8 cc d0 d4 d8 dc e0 e4 e8 ec f0 f4 f8 fc 00 05 09 0d 45 54 64 74 84 94 a4 b4 c4 d4 e4 f4 04 15 25 35 45 55 65 75 85 95 a5 b5 c5 d5 e5 f5 05 16 26 36 46 56 66 76 86 96 a6 b6 c6 d6 e6 f6 06 17 27 37 47 57 67 77 87 97 a7 b7 c7 d7 e7 f7 07 18 28 38 48 58 68 78 08 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=0 block=0 data=07 00 00 02 58 01 04 08 0c 10 14 18 1c 20 24 28 2c 30 34 38 3c 40 44 48 4c 50 54 58 5c 60 64 68 6c 70 74 78 7c 80 84 88 8c 90 94 98 9c a0 a4 a8 ac b0 b4 b8 bc c0 c4 c8 cc d0 d4 d8 dc e0 e4 e8 ec f0 f4 f8 fc 00 05 09 0d 45 54 64 74 84 94 a4 b4 c4 d4 e4 f4 04 15 25 35 45 55 65 75 85 95 a5 b5 c5 d5 e5 f5 05 16 26 36 46 56 66 76 86 96 a6 b6 c6 d6 e6 f6 06 17 27 37 47 57 67 77 87 97 a7 b7 c7 d7 e7 f7 07 18 28 38 48 58 68 78 08 +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 164 larger than space (74) left in block: copy only remaining space, and we are done +data block (BSN 2, MCS-6): 88 89 8a 8b 8c 8d 8e 8f 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca cb cc cd ce cf d0 d1 +- Copying data unit 0 (BSN 2) +msg block (BSN 2, MCS-6): 07 80 00 10 62 a2 e2 22 63 a3 e3 23 64 a4 e4 24 65 a5 e5 25 66 a6 e6 26 67 a7 e7 27 68 a8 e8 28 69 a9 e9 29 6a aa ea 2a 6b ab eb 2b 6c ac ec 2c 6d ad ed 2d 6e ae ee 2e 6f af ef 2f 70 b0 f0 30 71 b1 f1 31 72 b2 f2 32 73 b3 f3 33 74 34 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=4 block=1 data=07 80 00 10 62 a2 e2 22 63 a3 e3 23 64 a4 e4 24 65 a5 e5 25 66 a6 e6 26 67 a7 e7 27 68 a8 e8 28 69 a9 e9 29 6a aa ea 2a 6b ab eb 2b 6c ac ec 2c 6d ad ed 2d 6e ae ee 2e 6f af ef 2f 70 b0 f0 30 71 b1 f1 31 72 b2 f2 32 73 b3 f3 33 74 34 +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)==3) +- Sending new block at BSN 3, CS=MCS-6 +-- Chunk with length 90 larger than space (74) left in block: copy only remaining space, and we are done +data block (BSN 3, MCS-6): d2 d3 d4 d5 d6 d7 d8 d9 da db dc dd de df e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b +- Copying data unit 0 (BSN 3) +msg block (BSN 3, MCS-6): 07 c0 00 90 f4 34 75 b5 f5 35 76 b6 f6 36 77 b7 f7 37 78 b8 f8 38 79 b9 f9 39 7a ba fa 3a 7b bb fb 3b 7c bc fc 3c 7d bd fd 3d 7e be fe 3e 7f bf ff 3f 40 80 c0 00 41 81 c1 01 42 82 c2 02 43 83 c3 03 44 84 c4 04 45 85 c5 05 46 86 c6 06 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=8 block=2 data=07 c0 00 90 f4 34 75 b5 f5 35 76 b6 f6 36 77 b7 f7 37 78 b8 f8 38 79 b9 f9 39 7a ba fa 3a 7b bb fb 3b 7c bc fc 3c 7d bd fd 3d 7e be fe 3e 7f bf ff 3f 40 80 c0 00 41 81 c1 01 42 82 c2 02 43 83 c3 03 44 84 c4 04 45 85 c5 05 46 86 c6 06 +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 16 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=300 +-- 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 4, MCS-6): 20 71 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 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 +- 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 00 48 1c 47 87 c7 07 48 88 c8 08 49 89 c9 09 4a 8a ca 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 0a +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=13 block=3 data=07 00 01 00 48 1c 47 87 c7 07 48 88 c8 08 49 89 c9 09 4a 8a ca 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 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 03 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) +- Sending new block at BSN 0, CS=MCS-9 +- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (len=300) +-- Chunk with length 300 larger than space (74) left in block: copy only remaining space, and we are done +data block (BSN 0, MCS-9): 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 +- Sending new block at BSN 1, CS=MCS-9 +-- Chunk with length 226 larger than space (74) left in block: copy only remaining space, and we are done +data block (BSN 1, MCS-9): 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f 80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f 90 91 92 93 +- Copying data unit 0 (BSN 0) +- Copying data unit 1 (BSN 1) +msg block (BSN 0, MCS-9): 07 00 00 02 00 01 04 08 0c 10 14 18 1c 20 24 28 2c 30 34 38 3c 40 44 48 4c 50 54 58 5c 60 64 68 6c 70 74 78 7c 80 84 88 8c 90 94 98 9c a0 a4 a8 ac b0 b4 b8 bc c0 c4 c8 cc d0 d4 d8 dc e0 e4 e8 ec f0 f4 f8 fc 00 05 09 0d 11 15 19 1d 21 25 a5 b4 c4 d4 e4 f4 04 15 25 35 45 55 65 75 85 95 a5 b5 c5 d5 e5 f5 05 16 26 36 46 56 66 76 86 96 a6 b6 c6 d6 e6 f6 06 17 27 37 47 57 67 77 87 97 a7 b7 c7 d7 e7 f7 07 18 28 38 48 58 68 78 88 98 a8 b8 c8 d8 e8 f8 08 19 29 39 09 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=4 block=1 data=07 00 00 02 00 01 04 08 0c 10 14 18 1c 20 24 28 2c 30 34 38 3c 40 44 48 4c 50 54 58 5c 60 64 68 6c 70 74 78 7c 80 84 88 8c 90 94 98 9c a0 a4 a8 ac b0 b4 b8 bc c0 c4 c8 cc d0 d4 d8 dc e0 e4 e8 ec f0 f4 f8 fc 00 05 09 0d 11 15 19 1d 21 25 a5 b4 c4 d4 e4 f4 04 15 25 35 45 55 65 75 85 95 a5 b5 c5 d5 e5 f5 05 16 26 36 46 56 66 76 86 96 a6 b6 c6 d6 e6 f6 06 17 27 37 47 57 67 77 87 97 a7 b7 c7 d7 e7 f7 07 18 28 38 48 58 68 78 88 98 a8 b8 c8 d8 e8 f8 08 19 29 39 09 +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)==2) +- Resending BSN 0 +- Copying data unit 0 (BSN 0) +msg block (BSN 0, MCS-6): 07 00 00 12 40 80 c0 00 41 81 c1 01 42 82 c2 02 43 83 c3 03 44 84 c4 04 45 85 c5 05 46 86 c6 06 47 87 c7 07 48 88 c8 08 49 89 c9 09 4a 8a ca 0a 4b 8b cb 0b 4c 8c cc 0c 4d 8d cd 0d 4e 8e ce 0e 4f 8f cf 0f 50 90 d0 10 51 91 d1 11 52 12 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=8 block=2 data=07 00 00 12 40 80 c0 00 41 81 c1 01 42 82 c2 02 43 83 c3 03 44 84 c4 04 45 85 c5 05 46 86 c6 06 47 87 c7 07 48 88 c8 08 49 89 c9 09 4a 8a ca 0a 4b 8b cb 0b 4c 8c cc 0c 4d 8d cd 0d 4e 8e ce 0e 4f 8f cf 0f 50 90 d0 10 51 91 d1 11 52 12 +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) +- Resending BSN 1 +- Copying data unit 0 (BSN 1) +msg block (BSN 1, MCS-6): 07 40 00 92 d2 12 53 93 d3 13 54 94 d4 14 55 95 d5 15 56 96 d6 16 57 97 d7 17 58 98 d8 18 59 99 d9 19 5a 9a da 1a 5b 9b db 1b 5c 9c dc 1c 5d 9d dd 1d 5e 9e de 1e 5f 9f df 1f 60 a0 e0 20 61 a1 e1 21 62 a2 e2 22 63 a3 e3 23 64 a4 e4 24 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=13 block=3 data=07 40 00 92 d2 12 53 93 d3 13 54 94 d4 14 55 95 d5 15 56 96 d6 16 57 97 d7 17 58 98 d8 18 59 99 d9 19 5a 9a da 1a 5b 9b db 1b 5c 9c dc 1c 5d 9d dd 1d 5e 9e de 1e 5f 9f df 1f 60 a0 e0 20 61 a1 e1 21 62 a2 e2 22 63 a3 e3 23 64 a4 e4 24 +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) +- Resending BSN 0 +- Copying data unit 0 (BSN 0) +msg block (BSN 0, MCS-6): 07 00 00 10 40 80 c0 00 41 81 c1 01 42 82 c2 02 43 83 c3 03 44 84 c4 04 45 85 c5 05 46 86 c6 06 47 87 c7 07 48 88 c8 08 49 89 c9 09 4a 8a ca 0a 4b 8b cb 0b 4c 8c cc 0c 4d 8d cd 0d 4e 8e ce 0e 4f 8f cf 0f 50 90 d0 10 51 91 d1 11 52 12 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=0 block=0 data=07 00 00 10 40 80 c0 00 41 81 c1 01 42 82 c2 02 43 83 c3 03 44 84 c4 04 45 85 c5 05 46 86 c6 06 47 87 c7 07 48 88 c8 08 49 89 c9 09 4a 8a ca 0a 4b 8b cb 0b 4c 8c cc 0c 4d 8d cd 0d 4e 8e ce 0e 4f 8f cf 0f 50 90 d0 10 51 91 d1 11 52 12 +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) +- Resending BSN 1 +- Copying data unit 0 (BSN 1) +msg block (BSN 1, MCS-6): 07 40 00 90 d2 12 53 93 d3 13 54 94 d4 14 55 95 d5 15 56 96 d6 16 57 97 d7 17 58 98 d8 18 59 99 d9 19 5a 9a da 1a 5b 9b db 1b 5c 9c dc 1c 5d 9d dd 1d 5e 9e de 1e 5f 9f df 1f 60 a0 e0 20 61 a1 e1 21 62 a2 e2 22 63 a3 e3 23 64 a4 e4 24 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=4 block=1 data=07 40 00 90 d2 12 53 93 d3 13 54 94 d4 14 55 95 d5 15 56 96 d6 16 57 97 d7 17 58 98 d8 18 59 99 d9 19 5a 9a da 1a 5b 9b db 1b 5c 9c dc 1c 5d 9d dd 1d 5e 9e de 1e 5f 9f df 1f 60 a0 e0 20 61 a1 e1 21 62 a2 e2 22 63 a3 e3 23 64 a4 e4 24 +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)==2) +- Sending new block at BSN 2, CS=MCS-6 +-- Chunk with length 152 larger than space (74) left in block: copy only remaining space, and we are done +data block (BSN 2, MCS-6): 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca cb cc cd ce cf d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da db dc dd +- Copying data unit 0 (BSN 2) +msg block (BSN 2, MCS-6): 07 80 00 10 65 a5 e5 25 66 a6 e6 26 67 a7 e7 27 68 a8 e8 28 69 a9 e9 29 6a aa ea 2a 6b ab eb 2b 6c ac ec 2c 6d ad ed 2d 6e ae ee 2e 6f af ef 2f 70 b0 f0 30 71 b1 f1 31 72 b2 f2 32 73 b3 f3 33 74 b4 f4 34 75 b5 f5 35 76 b6 f6 36 77 37 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=8 block=2 data=07 80 00 10 65 a5 e5 25 66 a6 e6 26 67 a7 e7 27 68 a8 e8 28 69 a9 e9 29 6a aa ea 2a 6b ab eb 2b 6c ac ec 2c 6d ad ed 2d 6e ae ee 2e 6f af ef 2f 70 b0 f0 30 71 b1 f1 31 72 b2 f2 32 73 b3 f3 33 74 b4 f4 34 75 b5 f5 35 76 b6 f6 36 77 37 +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 78 larger than space (74) left in block: copy only remaining space, and we are done +data block (BSN 3, MCS-6): de df e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 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 3) +msg block (BSN 3, MCS-6): 07 c0 00 90 f7 37 78 b8 f8 38 79 b9 f9 39 7a ba fa 3a 7b bb fb 3b 7c bc fc 3c 7d bd fd 3d 7e be fe 3e 7f bf ff 3f 40 80 c0 00 41 81 c1 01 42 82 c2 02 43 83 c3 03 44 84 c4 04 45 85 c5 05 46 86 c6 06 47 87 c7 07 48 88 c8 08 49 89 c9 09 +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=13 block=3 data=07 c0 00 90 f7 37 78 b8 f8 38 79 b9 f9 39 7a ba fa 3a 7b bb fb 3b 7c bc fc 3c 7d bd fd 3d 7e be fe 3e 7f bf ff 3f 40 80 c0 00 41 81 c1 01 42 82 c2 02 43 83 c3 03 44 84 c4 04 45 85 c5 05 46 86 c6 06 47 87 c7 07 48 88 c8 08 49 89 c9 09 +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 4 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=300 +-- Empty chunk, added LLC dummy command of size 68, drained_since=0 +-- Chunk with length 68 is less than remaining space (69): 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=68 +data block (BSN 4, MCS-6): 08 89 28 29 2a 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 +- 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 00 42 22 4a 8a ca 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 0a +Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=17 block=4 data=07 00 01 00 42 22 4a 8a ca 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 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 ********** diff --git a/tests/tbf/TbfTest.ok b/tests/tbf/TbfTest.ok index 441b444..7829ed9 100644 --- a/tests/tbf/TbfTest.ok +++ b/tests/tbf/TbfTest.ok @@ -43,3 +43,14 @@ Testing MCS-7 Testing MCS-8 Testing MCS-9 === end test_tbf_egprs_dl === +=== start test_tbf_egprs_retx_dl_mcs_change === +Testing retx MCS 1 -> 9 +Testing retx MCS 2 -> 8 +Testing retx MCS 3 -> 6 +Testing retx MCS 4 -> 5 +Testing retx MCS 5 -> 7 +Testing retx MCS 6 -> 9 +Testing retx MCS 7 -> 5 +Testing retx MCS 8 -> 6 +Testing retx MCS 9 -> 6 +=== end test_tbf_egprs_retx_dl_mcs_change === -- 1.7.9.5 From Arvind.sirsikar at radisys.com Mon Apr 11 10:45:21 2016 From: Arvind.sirsikar at radisys.com (Aravind Sirsikar) Date: Mon, 11 Apr 2016 16:15:21 +0530 Subject: [PATCH 2/4] Add Accessor functions for MCS change in Retx In-Reply-To: <1460371523-32154-1-git-send-email-Arvind.sirsikar@radisys.com> References: <1460371523-32154-1-git-send-email-Arvind.sirsikar@radisys.com> Message-ID: <1460371523-32154-2-git-send-email-Arvind.sirsikar@radisys.com> From: Aravind Sirsikar Add Accessor functions in existing classes to support MCS change during the retransmission in EGPRS DL --- src/gprs_coding_scheme.h | 19 +++++++++++++++++++ src/gprs_ms.cpp | 5 +++++ src/gprs_ms.h | 1 + 3 files changed, 25 insertions(+) diff --git a/src/gprs_coding_scheme.h b/src/gprs_coding_scheme.h index 06e90fc..e0c5fd8 100644 --- a/src/gprs_coding_scheme.h +++ b/src/gprs_coding_scheme.h @@ -72,6 +72,8 @@ public: GprsCodingScheme& operator =(Scheme s); GprsCodingScheme& operator =(GprsCodingScheme o); + bool operator == (Scheme s); + 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;} @@ -111,6 +113,9 @@ public: static GprsCodingScheme getEgprsByNum(unsigned num); static const char *modeName(Mode mode); + static Scheme get_retx_mcs(const GprsCodingScheme &mcs, + const GprsCodingScheme &demanded_mcs); + static Scheme egprs_mcs_retx_tbl[MAX_NUM_ARQ] [MAX_NUM_MCS][MAX_NUM_MCS]; private: @@ -196,6 +201,13 @@ inline bool operator ==(GprsCodingScheme a, GprsCodingScheme b) return GprsCodingScheme::Scheme(a) == GprsCodingScheme::Scheme(b); } +inline bool GprsCodingScheme::operator == (Scheme scheme) +{ + if (this->m_scheme == scheme) + return true; + return false; +} + inline bool operator !=(GprsCodingScheme a, GprsCodingScheme b) { return !(a == b); @@ -222,3 +234,10 @@ inline bool operator >=(GprsCodingScheme a, GprsCodingScheme b) return a == b || a > b; } +inline GprsCodingScheme::Scheme GprsCodingScheme::get_retx_mcs( + const GprsCodingScheme &mcs, + const GprsCodingScheme &demanded_mcs) +{ + return egprs_mcs_retx_tbl[EGPRS_ARQ2][mcs.to_num() - 1] + [demanded_mcs.to_num() - 1]; +} diff --git a/src/gprs_ms.cpp b/src/gprs_ms.cpp index 4296fd3..b9a04fb 100644 --- a/src/gprs_ms.cpp +++ b/src/gprs_ms.cpp @@ -574,6 +574,11 @@ GprsCodingScheme GprsMs::max_cs_ul() const return GprsCodingScheme(GprsCodingScheme::MCS4); } +void GprsMs::set_current_cs_dl(GprsCodingScheme::Scheme scheme) +{ + m_current_cs_dl = scheme; +} + GprsCodingScheme GprsMs::max_cs_dl() const { struct gprs_rlcmac_bts *bts_data; diff --git a/src/gprs_ms.h b/src/gprs_ms.h index b07f175..bcc4fb3 100644 --- a/src/gprs_ms.h +++ b/src/gprs_ms.h @@ -86,6 +86,7 @@ public: uint8_t egprs_ms_class() const; void set_ms_class(uint8_t ms_class); void set_egprs_ms_class(uint8_t ms_class); + void set_current_cs_dl(GprsCodingScheme::Scheme scheme); GprsCodingScheme current_cs_ul() const; GprsCodingScheme current_cs_dl() const; -- 1.7.9.5 From terjeks at stud.ntnu.no Mon Apr 11 11:25:26 2016 From: terjeks at stud.ntnu.no (Terje Kristoffer Hybbestad Skow) Date: Mon, 11 Apr 2016 13:25:26 +0200 Subject: OpenGGSN In-Reply-To: <082ad804de46465d9ce9d66d1f51100e@AM2PR05MB0675.eurprd05.prod.outlook.com> References: <27920679945c4c37bad3e563b12d0b06@AM2PR05MB0675.eurprd05.prod.outlook.com> <5395e2e5606d4550a1133320e9112771@AM2PR05MB0675.eurprd05.prod.outlook.com> <082ad804de46465d9ce9d66d1f51100e@AM2PR05MB0675.eurprd05.prod.outlook.com> Message-ID: Hi again. I'm still having problem really getting the sgsnemu and ggsn to talk to each other. When I use 127.0.0.1 and 127.0.0.2 as the listen and remote for the sgsnemu and 127.0.0.2 as listen and 127.0.0.0/24 as network in the ggsn conf, the sgsnemu says "Received echo response Received create PDP context response. IP address: 127.0.0.2" and then nothing happens. When using two computers, one running ggsn and one sgsnemu with the ip-addresses as 192.168.1.14 and 192.168.1.11 respectively, the sgsnemu doesn't seem to get connented. It prints out "idletime.tv_sec 3, idleTime.tv_usec 0" over and over, and "Echo Request timed out". The picture attached is from wireshark on the ggsn computer. I lookt at the pcap you send and it looks like what I would like for my setup. You talk mentioned using symoBTS how much does it cost? And how long is a delivery for it? Regards Terje Skow 2016-03-01 12:56 GMT+01:00 Terje Kristoffer Skow : > Thank you very much!! > > I will have some work getting through this, but I recon I'll have some > more questions later. > > Again thank you > > 2016-03-01 12:39 GMT+01:00 Neels Hofmeyr : > >> On Tue, Mar 01, 2016 at 11:12:01AM +0100, Terje Kristoffer Hybbestad Skow >> wrote: >> > The "logfile /tmp/foo" did gave an error message saying "unrecognized >> > option". >> >> It seems the logfile option was added on 2014-03-23 with commit >> 9c0ff4fafe4276396125a52c89d36967566fe08c. It may make sense if you build >> your osmocom stack from the git sources to benefit from the latest fixes. >> >> See http://git.osmocom.org, specifically you'd probably want to clone >> and build >> >> git://git.osmocom.org/libosmocore >> git://git.osmocom.org/openggsn >> >> The build steps being for example >> >> autoreconf -fi >> ./configure >> make >> sudo make install >> >> >> > I'm going to look at DNS packets going through a GGSN to try and find >> ways >> > to detect DNS tunnels, do you have any recommendations how to do this? >> > I do not have the time or resources to use real UE's so I hope to >> simulate >> > it on a computer using VMs or something like that. >> >> > I have looked at this: >> http://openbsc.osmocom.org/trac/wiki/OpenBSC_GPRS as >> >> The BTS is for communicating with a phone over the air interface. Abis and >> osmo-nitb are used for voice calls only. The SGSN is needed for real >> networks, >> you should be fine with the sgsnemu. So all you need is sgsnemu and >> openggsn. >> >> You want to figure out how to use the sgsnemu, starting with a route into >> the >> tunnel device that sgsnemu opens up. So you need to look at the 'ip route' >> commands (if you're on linux). I guess you won't need VMs; granted, it >> might >> make it easier to avoid circular routes (to IP addresses that should only >> be >> seen on the GGSN side), but certainly not a necessary prerequisite. >> >> I tried to ping through the sgsnemu tunnel once but saw, as I mentioned, >> that >> the GGSN thwarts GTP messages without a proper context being created >> first. It >> shouldn't be too hard, but I haven't investigated further. So you'd want >> to >> understand the GTP Ctrl & User messages to setup a PGP context (TEIs and >> stuff), and figure out how sgsnemu might make your life easier in that >> regard. >> You probably want to read ETSI 29.060 to figure out GTP: >> >> http://www.etsi.org/deliver/etsi_ts/129000_129099/129060/03.19.00_60/ts_129060v031900p.pdf >> You may find attached pcap file interesting (open in wireshark and note >> that >> the DNS queries are transmitted over GTP between SGSN and GGSN even though >> wireshark tends to show only the DNS and src/dest enclosed in the GTP). >> And again, you may look at >> http://git.osmocom.org/openbsc/tree/openbsc/tests/gtphub/gtphub_test.c >> about simplistic code examples of composing a PGP context conversation. >> >> If you'd like any more answers to questions you didn't ask ;) >> just give us a shout... >> >> ~Neels >> >> -- >> - Neels Hofmeyr http://www.sysmocom.de/ >> ======================================================================= >> * sysmocom - systems for mobile communications GmbH >> * Alt-Moabit 93 >> * 10559 Berlin, Germany >> * Sitz / Registered office: Berlin, HRB 134158 B >> * Gesch?ftsf?hrer / Managing Directors: Holger Freyther, Harald Welte >> > > -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: wireshark.png Type: image/png Size: 48442 bytes Desc: not available URL: From sangamesh.sajjan at radisys.com Mon Apr 11 12:48:32 2016 From: sangamesh.sajjan at radisys.com (sangamesh sajjan) Date: Mon, 11 Apr 2016 18:18:32 +0530 Subject: [PATCH] Add compression algorithm based on T.4 procedure Message-ID: <1460378912-17145-1-git-send-email-sangamesh.sajjan@radisys.com> This patch includes the changes for compression algorithm and the compression is carried out using T.4 run length coding and the code words used are based on 3GPP 44.060 --- include/osmocom/core/bitcomp.h | 7 +++ src/bitcomp.c | 129 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 136 insertions(+) diff --git a/include/osmocom/core/bitcomp.h b/include/osmocom/core/bitcomp.h index 89eccbc..c5c223c 100644 --- a/include/osmocom/core/bitcomp.h +++ b/include/osmocom/core/bitcomp.h @@ -39,4 +39,11 @@ int osmo_t4_encode(struct bitvec *bv); int osmo_t4_decode(const struct bitvec *in, bool cc, struct bitvec *out); +#define MOD64(X) ((X + 64) & 0x3F) +int osmo_bitmap_compress( + struct bitvec *rbb_vec, + uint16_t *ucmp_bmplen, //Uncompressed bitmap len + uint8_t *cmp_bmplen, //Compressed bitmap len + uint8_t *crbb_bitmap //Compressed bitmap + ); /*! @} */ diff --git a/src/bitcomp.c b/src/bitcomp.c index bf35927..f3326b2 100644 --- a/src/bitcomp.c +++ b/src/bitcomp.c @@ -476,5 +476,134 @@ int osmo_t4_encode(struct bitvec *bv) } return -1; } +void compress_bitmap( + uint16_t *run_len_cnt, /* cnt: run length count */ + uint16_t *codewrd_bitmap, /* code word */ + uint8_t *codewrd_len, /* number of bits in the code word */ + uint8_t *cbmbuf, /* bitmap buffer to put code word in */ + uint16_t *cstrtbits, /* start bits to put codeword. start from + * 0, the first bit in the first octets + * and increment without octets + * consideration. i.e. can be more than 7. + */ + uint8_t *cstrtocts, /* start octets to put codeword. start from 0*/ + uint8_t clr_code) +{ + int i = 0; + uint16_t bitsleft = 0; + uint16_t temp = 0; + *codewrd_bitmap = 0; + *codewrd_len = 0; + + if ((*run_len_cnt) >= 64) { + for (i = 0; i < 15; i++) { + if (t4_make_up_ind[i] == *run_len_cnt) { + *codewrd_bitmap = t4_make_up[clr_code][i]; + *codewrd_len = t4_make_up_length[clr_code][i]; + } + } + } else { + *codewrd_bitmap = t4_term[clr_code][*run_len_cnt]; + *codewrd_len = t4_term_length[clr_code][*run_len_cnt]; + } + bitsleft = *codewrd_len; + /* Move the codeword_bitmap to left in two bytes*/ + (*codewrd_bitmap) = (*codewrd_bitmap)<<(16-(*codewrd_len)); + + while (bitsleft != 0) { + /* Bring left most bits to right and start shifting by cstrtbits, + * we get each bit to update in compressed buffer + */ + temp = (((*codewrd_bitmap) & 0x8000)>>15)<<(7-(*cstrtbits)); + cbmbuf[*cstrtocts] = cbmbuf[*cstrtocts]|temp; + + (*codewrd_bitmap) = (*codewrd_bitmap)<<1; + (*cstrtbits)++; + bitsleft--; + if ((*cstrtbits) >= 8) { + (*cstrtbits) = (*cstrtbits)-8; + (*cstrtocts)++; + /* init buf */ + cbmbuf[*cstrtocts] = 0x00; + } + } +} + +int osmo_bitmap_compress( + struct bitvec *rbb_vec, + uint16_t *ucmp_bmplen, /* Uncompressed bitmap len */ + uint8_t *cmp_bmplen, /* Compressed bitmap len */ + uint8_t *crbb_bitmap /* Compressed bitmap */ + ) +{ + char run_len_bit; + int buflen = *ucmp_bmplen; + uint16_t rlen; + uint16_t temprl = 0; + uint16_t cbmap; /* Compressed code word */ + uint8_t nbits; /* Length of code word */ + uint16_t cstrtbits = 0; + uint8_t cstrtocts = 0; + uint16_t uclen = 0; + uint8_t clen = 0; + uint8_t clr_code = 0; + + run_len_bit = (rbb_vec->data[0] & 0x80)>>7; + while (buflen > 0) { + temprl = 0; + /* Find Run length */ + if (run_len_bit == 1) + rlen = bitvec_rl(rbb_vec, true); + else + rlen = bitvec_rl(rbb_vec, false); + + buflen = buflen - rlen; + /* if rlen> 64 need 2 code words */ + //Compress the bits + if (run_len_bit == 0) { + if (rlen >= 64) { + temprl = (rlen/64)*64; + compress_bitmap(&temprl, &cbmap, &nbits, + crbb_bitmap, &cstrtbits, + &cstrtocts, clr_code); + } + temprl = MOD64(rlen); + compress_bitmap(&temprl, + &cbmap, &nbits, crbb_bitmap, + &cstrtbits, &cstrtocts, clr_code); + + /* next time the run length will be Ones */ + run_len_bit = 1; + } else { + if (rlen >= 64) { + temprl = (rlen/64)*64; + clr_code = 1; + compress_bitmap(&temprl, &cbmap, + &nbits, crbb_bitmap, + &cstrtbits, &cstrtocts, + clr_code); + } + temprl = MOD64(rlen); + compress_bitmap(&temprl, &cbmap, + &nbits, crbb_bitmap, + &cstrtbits, &cstrtocts, clr_code); + + /* next time the run length will be Zeros */ + run_len_bit = 0; + } + uclen = uclen + (rlen); + clen = clen + nbits; + } + *cmp_bmplen = clen; + if (clen >= uclen) { + /* No Gain is observed, So no need to compress, copy original + * bitmap in uncompressed bitmap + */ + return 0; + } else { + /* Add compressed bitmap to final buffer */ + return 1; + } +} -- 1.7.9.5 From sangamesh.sajjan at radisys.com Mon Apr 11 12:48:54 2016 From: sangamesh.sajjan at radisys.com (sangamesh sajjan) Date: Mon, 11 Apr 2016 18:18:54 +0530 Subject: [PATCH] Handle the encoding of PUAN for CRBB bitmap Message-ID: <1460378934-17188-1-git-send-email-sangamesh.sajjan@radisys.com> This patch includes the changes for encoding of PUAN to handle the CRBB bitmap --- src/encoding.cpp | 103 ++++++++++++++++++++++++++++++++++++++++++------------ src/rlc.cpp | 28 +++++++++++++++ src/rlc.h | 1 + 3 files changed, 109 insertions(+), 23 deletions(-) diff --git a/src/encoding.cpp b/src/encoding.cpp index 6c50abe..e0c29af 100644 --- a/src/encoding.cpp +++ b/src/encoding.cpp @@ -25,6 +25,11 @@ #include #include +extern "C" { +#include +#include +} + #include #include @@ -537,8 +542,6 @@ static void write_packet_ack_nack_desc_egprs( 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); @@ -546,9 +549,55 @@ static void write_packet_ack_nack_desc_egprs( int esn_crbb = window->mod_sns(ssn - 1); int rest_bits = dest->data_len * 8 - wp; - if (num_blocks > 0) + uint8_t rbb[128] = {'\0'}; + uint8_t iter = 0; + uint8_t crbb_len = 0; + uint8_t len = 0; + int is_compressed = 0; + uint16_t ucmp_bmplan = window->update_egprs_rbb(rbb); + uint8_t crbb_bitmap[127]; + bool bitmap_len = 0; + + LOGP(DRLCMACUL, LOGL_DEBUG, "Uncompressed bitmap length after" + "rbb update %d\n", ucmp_bmplan); + + rbb[128] = 0; + bitvec out; + + out.data = rbb; + out.cur_bit = 0; + out.data_len = sizeof(rbb); + /* if [V(R) -1] modulo SNS is explicitly included in the bitmap, + set eow =1; + + * If V(Q) equals V(R), then BOW and EOW bit shall be set to the value '1' + * and no need to send bitmap in ack nack, hence no compression + */ + if (window->v_q() == window->v_r()) { + + LOGP(DRLCMACUL, LOGL_DEBUG, "write_packet_ack_nack_desc_egprs:" + "v(Q)=V(R), hence no compression" + " %d %d\n", window->v_q(), window->v_r()); + eow = bow = 1; + bitmap_len = 1; + } + /* Compression part, Try compression only if it is greater than or equal + * to Window size Otherwise encode it in uncompressed + */ + if ((ucmp_bmplan >= (rest_bits - 15)) && (!bitmap_len)) { + + is_compressed = osmo_bitmap_compress(&out, //Uncompressed bitmap + &ucmp_bmplan, //Uncompressed bitmap len + &crbb_len, //Compressed bitmap len + crbb_bitmap + ); + } + + if (num_blocks > 0) { /* V(Q) is NACK and omitted -> SSN = V(Q) + 1 */ num_blocks -= 1; + urbb_len = num_blocks; + } if (num_blocks > window->ws()) num_blocks = window->ws(); @@ -556,17 +605,10 @@ static void write_packet_ack_nack_desc_egprs( 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) @@ -588,20 +630,35 @@ static void write_packet_ack_nack_desc_egprs( 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); + if (is_compressed) { + bitvec_write_field(dest, wp, 1, 1); // CRBB_Exist + bitvec_write_field(dest, wp, crbb_len, 7); // CRBB_LENGTH + uint8_t crbb_start_clr_code = (0x80 & crbb_bitmap[0])>>7; + bitvec_write_field(dest, wp, crbb_start_clr_code, 1); // CRBB_clr_code + + while (crbb_len != 0) { + if (crbb_len > 8) { + bitvec_write_field(dest, wp, crbb_bitmap[iter], 8); + crbb_len = crbb_len - 8; + iter++; + } else{ + bitvec_write_field(dest, wp, crbb_bitmap[iter], crbb_len); + crbb_len = 0; + } + } + } else{ + 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); + } } } diff --git a/src/rlc.cpp b/src/rlc.cpp index 6770043..c201713 100644 --- a/src/rlc.cpp +++ b/src/rlc.cpp @@ -83,6 +83,34 @@ int gprs_rlc_dl_window::mark_for_resend() return resend; } +/* Update the receive block bitmap */ +uint16_t gprs_rlc_ul_window::update_egprs_rbb(uint8_t *rbb) +{ + int i; + uint16_t bsn; + int8_t bitmask = 0x80; + int8_t pos = 0; + int8_t bit_pos = 0; + for (i = 0, bsn = (v_q()+1); ((bsn < (v_r())) && (i < ws())); i++, + bsn = this->mod_sns(bsn + 1)) { + if (m_v_n.is_received(bsn)) { + rbb[pos] = rbb[pos] | bitmask; + } else { + rbb[pos] = rbb[pos] & (~bitmask); + } + bitmask = bitmask >> 1; + bit_pos++; + bit_pos = bit_pos % 8; + if(bit_pos == 0) { + pos++; + bitmask = 0x80; + } + } + LOGP(DRLCMACUL, LOGL_DEBUG, "V(N):in update_egprs_rbb \"%s\"" + "R=Received I=Invalid\n", rbb); + return i; +} + int gprs_rlc_dl_window::count_unacked() { uint16_t unacked = 0; diff --git a/src/rlc.h b/src/rlc.h index 8f75588..83bc5dc 100644 --- a/src/rlc.h +++ b/src/rlc.h @@ -260,6 +260,7 @@ struct gprs_rlc_ul_window: public gprs_rlc_window { bool is_received(uint16_t bsn) const; void update_rbb(char *rbb); + uint16_t update_egprs_rbb(uint8_t *rbb); void raise_v_r_to(int moves); void raise_v_r(const uint16_t bsn); uint16_t raise_v_q(); -- 1.7.9.5 From minh-quang.nguyen at nutaq.com Mon Apr 11 13:47:43 2016 From: minh-quang.nguyen at nutaq.com (Minh-Quang Nguyen) Date: Mon, 11 Apr 2016 09:47:43 -0400 Subject: Regarding integration of NURAN L1 1.0 References: <86E210CFD3EEDE46A58DE4793CFA6C3F0373171A@NTWAEX01.interne.lyrtech.com> <20160314001234.GE10039@dub6> <86E210CFD3EEDE46A58DE4793CFA6C3F03732069@NTWAEX01.interne.lyrtech.com> <86E210CFD3EEDE46A58DE4793CFA6C3F0373244D@NTWAEX01.interne.lyrtech.com> <86E210CFD3EEDE46A58DE4793CFA6C3F037CBC9E@NTWAEX01.interne.lyrtech.com> <86E210CFD3EEDE46A58DE4793CFA6C3F037CC081@NTWAEX01.interne.lyrtech.com> Message-ID: <86E210CFD3EEDE46A58DE4793CFA6C3F03866B60@NTWAEX01.interne.lyrtech.com> Hi Prasad, How is going with the PCU T3169 timeout? Can you try with older commit of the PCU? Can you try commit 42aba81c2f8c8313fcbf85ee422d6b747107d98a? Regards, Minh-Quang Nguyen Concepteur logiciel??|??Software designer GSM/Network T. 418 914-7484 x2296??|??1 855 914-7484??|??F. 418 914-9477 2150, Cyrille-Duquet, Qu?bec (Qu?bec)??G1N 2G3 CANADA minh-quang.nguyen at nutaq.com www.nutaq.com QUEBEC MONTREAL NEW YORK Facebook Twitter LinkedIn YouTube -----Original Message----- From: Prasad Kaup [mailto:Prasad.Kaup at radisys.com] Sent: Tuesday, April 05, 2016 10:50 AM To: Minh-Quang Nguyen; Neels Hofmeyr; osmocom-net-gprs at lists.osmocom.org Cc: Saurabh Sharan; Yves Godin Subject: RE: Regarding integration of NURAN L1 1.0 Hi Minh-Quang Nguyen, Thanks for the information. We are able to connect to internet through GPRS with existing binaries in the board. we are also able to cross compile latest libosmocore, talloc and osmo-pcu. We loaded latest osmo-pcu (from master ) to board and tried to test , but there is no internet connectivity. I see that there is no data received at osmo-pcu /osmo-bts as below, though assignment is given to mobile PCU side: <0002> tbf.cpp:874 TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=WAIT ASSIGN) T3169 timeout during transmission <0002> tbf.cpp:893 - Assignment was on CCCH <0002> tbf.cpp:899 - No uplink data received yet BTS side: <0009> pcu_sock.c:356 Sending RACH indication: qta=-3, ra=123, fn=647328 <0009> pcu_sock.c:466 Data request received: sapi=AGCH arfcn=0 block=0 data=2d 06 3f 10 0e e0 2b 7b 44 86 00 00 c8 00 70 0b 2b 2b 2b 2b 2b 2b 2b <0006> l1_if.c:948 RACH for packet access Let me know your comments Regards Prasad From nhofmeyr at sysmocom.de Mon Apr 11 14:27:27 2016 From: nhofmeyr at sysmocom.de (Neels Hofmeyr) Date: Mon, 11 Apr 2016 16:27:27 +0200 Subject: OpenGGSN In-Reply-To: References: <27920679945c4c37bad3e563b12d0b06@AM2PR05MB0675.eurprd05.prod.outlook.com> <5395e2e5606d4550a1133320e9112771@AM2PR05MB0675.eurprd05.prod.outlook.com> <082ad804de46465d9ce9d66d1f51100e@AM2PR05MB0675.eurprd05.prod.outlook.com> Message-ID: <20160411142727.GA28114@ass40.sysmocom.de> On Mon, Apr 11, 2016 at 01:25:26PM +0200, Terje Kristoffer Hybbestad Skow wrote: > the sgsnemu says "Received echo response > Received create PDP context response." That looks like the sgsnemu has successfully connected to the GGSN. The Echo is sent from sgsnemu to the GGSN, and the GGSN replies with an Echo Response. The sgsnemu apparently also creates a PDP context. > IP address: 127.0.0.2 That seems a bit weirdly configured. The SGSN and GGSN are usually in a "private" part of your core network, and the GGSN passes a "public" IP to the subscriber. Here it seems your GGSN has given you a "public" IP address that is the same as your private GGSN's IP address. So you would assign a "public" IP address range to your GGSN, not entirely unlike DHCP, so that the IP address returned by the GGSN is the one that the outside network would use to contact your subscriber via the GGSN. So the GGSN should have a network more like 10.42.23.0/24 configured. Or maybe 192.168.1.128/25, not sure about your network. outside network ^ | | V 10.42.23.129 <-- public IP of subscriber GGSN ^ 127.0.0.2 | (|)--- GTP "tunnel" | V 127.0.0.1 SGSN ^ | * <--- (some GSM components omitted) | V subscriber: "ok, so I'm 10.42.23.129 to the world outside, thanks!" In your case, 'SGSN' down to 'subscriber' are emulated by sgsnemu, which is incredibly useful. > and then nothing happens. Nothing would happen until you actually send packets via the tun interface created by sgsnemu. You can start by using ping on the tun interface, like `ping -I tun0 192.168.1.1`, depending on your network. Note that both sgsnemu and OpenGGSN each create a tun device. Looking at it again now, I may have misunderstood the reason why sgsnemu didn't work for me. I thought sgsnemu omitted setting up a PDP Context, but from above output that actually seems to have happened. I'd try it again now, just for you ;) but unfortunately I don't have the time resources. I think it would be good if you got into the source code and the GTP specs to really get into the subject... > When using two > computers, one running ggsn and one sgsnemu with the ip-addresses as > 192.168.1.14 and 192.168.1.11 respectively, the sgsnemu doesn't seem to get > connented. It prints out "idletime.tv_sec 3, idleTime.tv_usec 0" over and > over, and "Echo Request timed out". Looks like your sgsnemu IP cannot reach the GGSN IP. You see ARPs to find out who is 192.168.1.14, but no-one is answering. I can't debug your basic network setup from here, so you have to fix that yourself... > You talk mentioned using symoBTS how much does it cost? And how long is a > delivery for it? As much as sysmocom would like you to purchase a sysmoBTS, I don't think you want to go down this road: you'd have to register a part of the public GSM frequency spectrum, provision your own SIM card, ... If you'd still want to, look at [1] and write to sales at sysmocom.de. The BTS aren't in our shop [2] for radio frequency spectrum legislatory reasons -- we're not allowed to sell sysmoBTS everywhere. [1] https://www.sysmocom.de/products/ [2] http://shop.sysmocom.de/ BTW, I did remind you to allow forwarding and masquerading for the GGSN? The GGSN unpacks the traffic from GTP and then sends it into the tun device it created. So what falls out the GGSN's tunnel is to be handled/routed by the linux kernel, and so, for testing, you'd typically use below setup; this should only become necessary after you've resolved the other details above: sudo -s echo 1 > /proc/sys/net/ipv4/ip_forward iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE (replace eth0 if you're using another interface for the GGSN) ~Neels -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: Digital signature URL: From Prasad.Kaup at radisys.com Mon Apr 11 15:17:04 2016 From: Prasad.Kaup at radisys.com (Prasad Kaup) Date: Mon, 11 Apr 2016 15:17:04 +0000 Subject: Regarding integration of NURAN L1 1.0 In-Reply-To: <86E210CFD3EEDE46A58DE4793CFA6C3F03866B60@NTWAEX01.interne.lyrtech.com> References: <86E210CFD3EEDE46A58DE4793CFA6C3F0373171A@NTWAEX01.interne.lyrtech.com> <20160314001234.GE10039@dub6> <86E210CFD3EEDE46A58DE4793CFA6C3F03732069@NTWAEX01.interne.lyrtech.com> <86E210CFD3EEDE46A58DE4793CFA6C3F0373244D@NTWAEX01.interne.lyrtech.com> <86E210CFD3EEDE46A58DE4793CFA6C3F037CBC9E@NTWAEX01.interne.lyrtech.com> <86E210CFD3EEDE46A58DE4793CFA6C3F037CC081@NTWAEX01.interne.lyrtech.com> <86E210CFD3EEDE46A58DE4793CFA6C3F03866B60@NTWAEX01.interne.lyrtech.com> Message-ID: Hi Minh-Quang Nguyen, Thanks for your reply. I tried with commit 42aba81c2f8c8313fcbf85ee422d6b747107d98a. When I run the command, "/usr/bin/osmo-pcu -c /etc/osmocom/osmo-pcu.cfg" , it is getting terminated with message "Aborted" Strace output open("/etc/osmocom/osmo-pcu.cfg", O_RDONLY) = 3 fstat64(3, {st_mode=S_IFREG|0644, st_size=73, ...}) = 0 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb6f7e000 read(3, "pcu\n flow-control-interval 10\n c"..., 4096) = 73 rt_sigprocmask(SIG_UNBLOCK, [ABRT], NULL, 8) = 0 tgkill(1503, 1503, SIGABRT) = 0 --- SIGABRT {si_signo=SIGABRT, si_code=SI_TKILL, si_pid=1503, si_uid=0} --- +++ killed by SIGABRT +++ Aborted It runs without any arguments , but I can still see "late RLC block" messages. Regards Prasad > -----Original Message----- > From: Minh-Quang Nguyen [mailto:minh-quang.nguyen at nutaq.com] > Sent: Monday, April 11, 2016 7:18 PM > To: Prasad Kaup ; Neels Hofmeyr > ; osmocom-net-gprs at lists.osmocom.org > Cc: Saurabh Sharan ; Yves Godin > > Subject: RE: Regarding integration of NURAN L1 1.0 > > Hi Prasad, > > > How is going with the PCU T3169 timeout? > > Can you try with older commit of the PCU? Can you try commit > 42aba81c2f8c8313fcbf85ee422d6b747107d98a? > > Regards, > > Minh-Quang Nguyen > > Concepteur logiciel??|??Software designer GSM/Network > > > T. 418 914-7484 x2296??|??1 855 914-7484??|??F. 418 914-9477 2150, Cyrille- > Duquet, Qu?bec (Qu?bec)??G1N 2G3 CANADA > > > minh-quang.nguyen at nutaq.com > www.nutaq.com > > QUEBEC MONTREAL NEW YORK > > Facebook Twitter LinkedIn YouTube From minh-quang.nguyen at nutaq.com Mon Apr 11 17:32:15 2016 From: minh-quang.nguyen at nutaq.com (Minh-Quang Nguyen) Date: Mon, 11 Apr 2016 13:32:15 -0400 Subject: Regarding integration of NURAN L1 1.0 References: <86E210CFD3EEDE46A58DE4793CFA6C3F0373171A@NTWAEX01.interne.lyrtech.com> <20160314001234.GE10039@dub6> <86E210CFD3EEDE46A58DE4793CFA6C3F03732069@NTWAEX01.interne.lyrtech.com> <86E210CFD3EEDE46A58DE4793CFA6C3F0373244D@NTWAEX01.interne.lyrtech.com> <86E210CFD3EEDE46A58DE4793CFA6C3F037CBC9E@NTWAEX01.interne.lyrtech.com> <86E210CFD3EEDE46A58DE4793CFA6C3F037CC081@NTWAEX01.interne.lyrtech.com> <86E210CFD3EEDE46A58D E4793CFA 6C3F03866B60 @NTWAEX01.interne.lyrtech.com> Message-ID: <86E210CFD3EEDE46A58DE4793CFA6C3F03866C35@NTWAEX01.interne.lyrtech.com> Hi Prasad, I do not have "Abort "terminated message. Can you tell me which commit of libosmocore, libosmo-abis, osmo-bts you are currently using? Thanks, Minh-Quang Nguyen Concepteur logiciel??|??Software designer GSM/Network T. 418 914-7484 x2296??|??1 855 914-7484??|??F. 418 914-9477 2150, Cyrille-Duquet, Qu?bec (Qu?bec)??G1N 2G3 CANADA minh-quang.nguyen at nutaq.com www.nutaq.com QUEBEC MONTREAL NEW YORK Facebook Twitter LinkedIn YouTube -----Original Message----- From: Prasad Kaup [mailto:Prasad.Kaup at radisys.com] Sent: Monday, April 11, 2016 11:17 AM To: Minh-Quang Nguyen; Neels Hofmeyr; osmocom-net-gprs at lists.osmocom.org Cc: Saurabh Sharan; Yves Godin Subject: RE: Regarding integration of NURAN L1 1.0 Hi Minh-Quang Nguyen, Thanks for your reply. I tried with commit 42aba81c2f8c8313fcbf85ee422d6b747107d98a. When I run the command, "/usr/bin/osmo-pcu -c /etc/osmocom/osmo-pcu.cfg" , it is getting terminated with message "Aborted" Strace output open("/etc/osmocom/osmo-pcu.cfg", O_RDONLY) = 3 fstat64(3, {st_mode=S_IFREG|0644, st_size=73, ...}) = 0 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb6f7e000 read(3, "pcu\n flow-control-interval 10\n c"..., 4096) = 73 rt_sigprocmask(SIG_UNBLOCK, [ABRT], NULL, 8) = 0 tgkill(1503, 1503, SIGABRT) = 0 --- SIGABRT {si_signo=SIGABRT, si_code=SI_TKILL, si_pid=1503, si_uid=0} --- +++ killed by SIGABRT +++ Aborted It runs without any arguments , but I can still see "late RLC block" messages. Regards Prasad > -----Original Message----- > From: Minh-Quang Nguyen [mailto:minh-quang.nguyen at nutaq.com] > Sent: Monday, April 11, 2016 7:18 PM > To: Prasad Kaup ; Neels Hofmeyr > ; osmocom-net-gprs at lists.osmocom.org > Cc: Saurabh Sharan ; Yves Godin > > Subject: RE: Regarding integration of NURAN L1 1.0 > > Hi Prasad, > > > How is going with the PCU T3169 timeout? > > Can you try with older commit of the PCU? Can you try commit > 42aba81c2f8c8313fcbf85ee422d6b747107d98a? > > Regards, > > Minh-Quang Nguyen > > Concepteur logiciel??|??Software designer GSM/Network > > > T. 418 914-7484 x2296??|??1 855 914-7484??|??F. 418 914-9477 2150, > Cyrille- Duquet, Qu?bec (Qu?bec)??G1N 2G3 CANADA > > > minh-quang.nguyen at nutaq.com > www.nutaq.com > > QUEBEC MONTREAL NEW YORK > > Facebook Twitter LinkedIn YouTube From Bhargava.Abhyankar at radisys.com Tue Apr 12 07:22:35 2016 From: Bhargava.Abhyankar at radisys.com (Bhargava Abhyankar) Date: Tue, 12 Apr 2016 12:52:35 +0530 Subject: [PATCH] Update the function for EGPRS immediate assignment Message-ID: <1460445755-28819-1-git-send-email-Bhargava.Abhyankar@radisys.com> Encode the EGPRS immediate assignment message in uplink when EGPRS is enabled. --- src/bts.cpp | 2 +- src/encoding.cpp | 53 +++++++++++++++++++++++++++++++++++++++++-------- src/encoding.h | 5 +++-- tests/edge/EdgeTest.cpp | 3 ++- 4 files changed, 51 insertions(+), 12 deletions(-) diff --git a/src/bts.cpp b/src/bts.cpp index 2166132..2c23192 100644 --- a/src/bts.cpp +++ b/src/bts.cpp @@ -536,7 +536,7 @@ int BTS::rcv_rach(uint16_t ra, uint32_t Fn, int16_t qta, uint8_t is_11bit, plen = Encoding::write_immediate_assignment( 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); + m_bts.alpha, m_bts.gamma, -1, burst); if (plen >= 0) { pcu_l1if_tx_agch(immediate_assignment, plen); diff --git a/src/encoding.cpp b/src/encoding.cpp index 6c50abe..3292c2a 100644 --- a/src/encoding.cpp +++ b/src/encoding.cpp @@ -19,9 +19,9 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include #include #include -#include #include #include @@ -140,11 +140,48 @@ 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) + uint8_t alpha, uint8_t gamma, int8_t ta_idx, + enum ph_burst_type burst) { - LOGP(DRLCMACUL, LOGL_ERROR, - "EGPRS Packet Uplink Assignment is not yet implemented\n"); - return -EINVAL; + bitvec_write_field(dest, wp, 1, 2); /* LH */ + bitvec_write_field(dest, wp, 0, 2); /* 0 EGPRS Uplink Assignment */ + bitvec_write_field(dest, wp, 0, 5); /* Extended RA **todo** */ + bitvec_write_field(dest, wp, 0, 1); /* Access technology Request */ + + unsigned int ws_enc = (tbf->m_window.ws() - 64) / 32; + + bitvec_write_field(dest, wp, 1, 1); /* single block alloc */ + bitvec_write_field(dest, wp, tbf->tfi(), 5);/* TFI assignment */ + bitvec_write_field(dest, wp, 0, 1); /* polling bit */ + bitvec_write_field(dest, wp, usf, 3); /* USF bit */ + bitvec_write_field(dest, wp, 0, 1); /* USF granularity */ + bitvec_write_field(dest, wp, 0, 1); /* P0 */ + + if (burst == GSM_L1_BURST_TYPE_ACCESS_1) { /* 8-PSK RACH*/ + bitvec_write_field(dest, wp, tbf->current_cs(). + to_num()-1, 4); /*mcs*/ + } else { + bitvec_write_field(dest, wp, GprsCodingScheme::MCS1, 4); /*mcs*/ + } + + bitvec_write_field(dest, wp, tbf->tlli(), 1); /* tlli channel block */ + bitvec_write_field(dest, wp, 0, 1); /* BEP period present */ + bitvec_write_field(dest, wp, 0, 1); /* resegmentation */ + bitvec_write_field(dest, wp, ws_enc, 5);/* egprs window_size */ + + if (alpha) { + bitvec_write_field(dest, wp, 0x1, 1); /* ALPHA =yes */ + bitvec_write_field(dest, wp, alpha, 4); /* ALPHA */ + bitvec_write_field(dest, wp, gamma, 5); /* GAMMA power contrl */ + } else { + bitvec_write_field(dest, wp, 0x0, 1); /* ALPHA = no */ + } + + bitvec_write_field(dest, wp, 0, 1); /* TIMING_ADVANCE_INDEX */ + bitvec_write_field(dest, wp, 0, 1); /* TBF_STARTING_TIME_FLAG */ + bitvec_write_field(dest, wp, 0, 1); /* NULL */ + + return 0; } /* @@ -153,10 +190,10 @@ static int write_ia_rest_egprs_uplink( */ int Encoding::write_immediate_assignment( struct gprs_rlcmac_tbf *tbf, - bitvec * dest, uint8_t downlink, uint8_t ra, + bitvec * dest, uint8_t downlink, uint16_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) + uint8_t gamma, int8_t ta_idx, enum ph_burst_type burst) { unsigned wp = 0; int plen; @@ -209,7 +246,7 @@ int Encoding::write_immediate_assignment( 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); + alpha, gamma, ta_idx, burst); else rc = write_ia_rest_uplink(as_ul_tbf(tbf), dest, wp, usf, fn, diff --git a/src/encoding.h b/src/encoding.h index 94e9a02..079332d 100644 --- a/src/encoding.h +++ b/src/encoding.h @@ -40,11 +40,12 @@ class Encoding { public: static int write_immediate_assignment( struct gprs_rlcmac_tbf *tbf, - bitvec * dest, uint8_t downlink, uint8_t ra, + bitvec * dest, uint8_t downlink, uint16_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); + int8_t ta_idx, + enum ph_burst_type burst = GSM_L1_BURST_TYPE_ACCESS_0); static void write_packet_uplink_assignment( struct gprs_rlcmac_bts *bts, diff --git a/tests/edge/EdgeTest.cpp b/tests/edge/EdgeTest.cpp index 96ea0c1..9138ae7 100644 --- a/tests/edge/EdgeTest.cpp +++ b/tests/edge/EdgeTest.cpp @@ -23,7 +23,6 @@ #include "gprs_debug.h" #include "gprs_coding_scheme.h" #include "decoding.h" -#include "encoding.h" #include "rlc.h" #include "llc.h" @@ -35,10 +34,12 @@ extern "C" { #include #include #include +#include } #include #include +#include "encoding.h" void *tall_pcu_ctx; int16_t spoof_mnc = 0, spoof_mcc = 0; -- 2.5.0 From laforge at gnumonks.org Tue Apr 12 08:15:18 2016 From: laforge at gnumonks.org (Harald Welte) Date: Tue, 12 Apr 2016 10:15:18 +0200 Subject: [PATCH] Update the function for EGPRS immediate assignment In-Reply-To: <1460445755-28819-1-git-send-email-Bhargava.Abhyankar@radisys.com> References: <1460445755-28819-1-git-send-email-Bhargava.Abhyankar@radisys.com> Message-ID: <20160412081518.GJ15746@nataraja> Dear Bhargava and Radisys team, can you please explain how you validate / verify the various patches you are sending? What is your testing setup? Before I merge some of the patches, I would like to understand that you are already doing some very basic testing to avoid introducing regressions. If that's not the case, I suggest we push those patches with a positive review first to a 'radisys/pending' branch until they have been verified to not cause regressions compared to the behavior in master. Thanks for your understanding. Regards, Harald -- - Harald Welte http://laforge.gnumonks.org/ ============================================================================ "Privacy in residential applications is a desirable marketing option." (ETSI EN 300 175-7 Ch. A6) From msuraev at sysmocom.de Tue Apr 12 12:06:35 2016 From: msuraev at sysmocom.de (Max) Date: Tue, 12 Apr 2016 14:06:35 +0200 Subject: [PATCH] Add compression algorithm based on T.4 procedure In-Reply-To: <1460378912-17145-1-git-send-email-sangamesh.sajjan@radisys.com> References: <1460378912-17145-1-git-send-email-sangamesh.sajjan@radisys.com> Message-ID: <570CE4CB.5030308@sysmocom.de> Hi. Thanks for your contribution. Could you please elaborate on the intent of this function? Can we replace existing osmo_t4_encode() with it? Having couple of test cases would be helpful in understanding what this function do and how it's supposed to be used. On 04/11/2016 02:48 PM, sangamesh sajjan wrote: > This patch includes the changes for compression algorithm and the > compression is carried out using T.4 run length coding and > the code words used are based on 3GPP 44.060 > --- > include/osmocom/core/bitcomp.h | 7 +++ > src/bitcomp.c | 129 ++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 136 insertions(+) > > diff --git a/include/osmocom/core/bitcomp.h b/include/osmocom/core/bitcomp.h > index 89eccbc..c5c223c 100644 > --- a/include/osmocom/core/bitcomp.h > +++ b/include/osmocom/core/bitcomp.h > @@ -39,4 +39,11 @@ > int osmo_t4_encode(struct bitvec *bv); > int osmo_t4_decode(const struct bitvec *in, bool cc, struct bitvec *out); > > +#define MOD64(X) ((X + 64) & 0x3F) > +int osmo_bitmap_compress( > + struct bitvec *rbb_vec, > + uint16_t *ucmp_bmplen, //Uncompressed bitmap len > + uint8_t *cmp_bmplen, //Compressed bitmap len > + uint8_t *crbb_bitmap //Compressed bitmap > + ); > /*! @} */ > diff --git a/src/bitcomp.c b/src/bitcomp.c > index bf35927..f3326b2 100644 > --- a/src/bitcomp.c > +++ b/src/bitcomp.c > @@ -476,5 +476,134 @@ int osmo_t4_encode(struct bitvec *bv) > } > return -1; > } > +void compress_bitmap( > + uint16_t *run_len_cnt, /* cnt: run length count */ > + uint16_t *codewrd_bitmap, /* code word */ > + uint8_t *codewrd_len, /* number of bits in the code word */ > + uint8_t *cbmbuf, /* bitmap buffer to put code word in */ > + uint16_t *cstrtbits, /* start bits to put codeword. start from > + * 0, the first bit in the first octets > + * and increment without octets > + * consideration. i.e. can be more than 7. > + */ > + uint8_t *cstrtocts, /* start octets to put codeword. start from 0*/ > + uint8_t clr_code) > +{ > + int i = 0; > + uint16_t bitsleft = 0; > + uint16_t temp = 0; > + *codewrd_bitmap = 0; > + *codewrd_len = 0; > + > + if ((*run_len_cnt) >= 64) { > + for (i = 0; i < 15; i++) { > + if (t4_make_up_ind[i] == *run_len_cnt) { > + *codewrd_bitmap = t4_make_up[clr_code][i]; > + *codewrd_len = t4_make_up_length[clr_code][i]; > + } > + } > + } else { > + *codewrd_bitmap = t4_term[clr_code][*run_len_cnt]; > + *codewrd_len = t4_term_length[clr_code][*run_len_cnt]; > + } > + bitsleft = *codewrd_len; > + /* Move the codeword_bitmap to left in two bytes*/ > + (*codewrd_bitmap) = (*codewrd_bitmap)<<(16-(*codewrd_len)); > + > + while (bitsleft != 0) { > + /* Bring left most bits to right and start shifting by cstrtbits, > + * we get each bit to update in compressed buffer > + */ > + temp = (((*codewrd_bitmap) & 0x8000)>>15)<<(7-(*cstrtbits)); > + cbmbuf[*cstrtocts] = cbmbuf[*cstrtocts]|temp; > + > + (*codewrd_bitmap) = (*codewrd_bitmap)<<1; > + (*cstrtbits)++; > + bitsleft--; > + if ((*cstrtbits) >= 8) { > + (*cstrtbits) = (*cstrtbits)-8; > + (*cstrtocts)++; > + /* init buf */ > + cbmbuf[*cstrtocts] = 0x00; > + } > + } > +} > + > +int osmo_bitmap_compress( > + struct bitvec *rbb_vec, > + uint16_t *ucmp_bmplen, /* Uncompressed bitmap len */ > + uint8_t *cmp_bmplen, /* Compressed bitmap len */ > + uint8_t *crbb_bitmap /* Compressed bitmap */ > + ) > +{ > > + char run_len_bit; > + int buflen = *ucmp_bmplen; > + uint16_t rlen; > + uint16_t temprl = 0; > + uint16_t cbmap; /* Compressed code word */ > + uint8_t nbits; /* Length of code word */ > + uint16_t cstrtbits = 0; > + uint8_t cstrtocts = 0; > + uint16_t uclen = 0; > + uint8_t clen = 0; > + uint8_t clr_code = 0; > + > + run_len_bit = (rbb_vec->data[0] & 0x80)>>7; > + while (buflen > 0) { > + temprl = 0; > + /* Find Run length */ > + if (run_len_bit == 1) > + rlen = bitvec_rl(rbb_vec, true); > + else > + rlen = bitvec_rl(rbb_vec, false); > + > + buflen = buflen - rlen; > + /* if rlen> 64 need 2 code words */ > + //Compress the bits > + if (run_len_bit == 0) { > + if (rlen >= 64) { > + temprl = (rlen/64)*64; > + compress_bitmap(&temprl, &cbmap, &nbits, > + crbb_bitmap, &cstrtbits, > + &cstrtocts, clr_code); > + } > + temprl = MOD64(rlen); > + compress_bitmap(&temprl, > + &cbmap, &nbits, crbb_bitmap, > + &cstrtbits, &cstrtocts, clr_code); > + > + /* next time the run length will be Ones */ > + run_len_bit = 1; > + } else { > + if (rlen >= 64) { > + temprl = (rlen/64)*64; > + clr_code = 1; > + compress_bitmap(&temprl, &cbmap, > + &nbits, crbb_bitmap, > + &cstrtbits, &cstrtocts, > + clr_code); > + } > + temprl = MOD64(rlen); > + compress_bitmap(&temprl, &cbmap, > + &nbits, crbb_bitmap, > + &cstrtbits, &cstrtocts, clr_code); > + > + /* next time the run length will be Zeros */ > + run_len_bit = 0; > + } > + uclen = uclen + (rlen); > + clen = clen + nbits; > + } > + *cmp_bmplen = clen; > > + if (clen >= uclen) { > + /* No Gain is observed, So no need to compress, copy original > + * bitmap in uncompressed bitmap > + */ > + return 0; > + } else { > + /* Add compressed bitmap to final buffer */ > + return 1; > + } > +} -- Max Suraev http://www.sysmocom.de/ ======================================================================= * sysmocom - systems for mobile communications GmbH * Alt-Moabit 93 * 10559 Berlin, Germany * Sitz / Registered office: Berlin, HRB 134158 B * Geschaeftsfuehrer / Managing Directors: Holger Freyther, Harald Welte From Bhargava.Abhyankar at radisys.com Tue Apr 12 14:06:35 2016 From: Bhargava.Abhyankar at radisys.com (Bhargava Abhyankar) Date: Tue, 12 Apr 2016 14:06:35 +0000 Subject: [PATCH] Update parameters in osmo-bts for 11 bit RACH In-Reply-To: <5003BB6D-3213-4F88-A0FD-89F6F18B2A2D@freyther.de> References: <1459857461-24941-1-git-send-email-Bhargava.Abhyankar@radisys.com> <5003BB6D-3213-4F88-A0FD-89F6F18B2A2D@freyther.de> Message-ID: > On 07 Apr 2016, at 01:18 PM, Holger Freyther wrote: Dear Holger, > Based on the indication from L1, number of bits in RACH and burst type > is determined. Appropriate parameters are filled in osmo-bts. > These parameters are sent to osmo-pcu for processing of the RACH. >> how did you test this? Do you have a patch for OpenBSC to modify the SIs to allow 11 bit RACH bursts? A patch shall be sent to modify the SIs to allow 11 bit RACH bursts in OpenBSC. This patch is implemented based on the inputs from the L1 team. This code is not tested in integration test setup. kind regards Bhargava Abhyankar From Bhargava.Abhyankar at radisys.com Tue Apr 12 14:25:31 2016 From: Bhargava.Abhyankar at radisys.com (Bhargava Abhyankar) Date: Tue, 12 Apr 2016 14:25:31 +0000 Subject: [PATCH] Update the function for EGPRS immediate assignment In-Reply-To: <20160412081518.GJ15746@nataraja> References: <1460445755-28819-1-git-send-email-Bhargava.Abhyankar@radisys.com> <20160412081518.GJ15746@nataraja> Message-ID: Hello Harald, > On 12 Apr 2016, at 01:45 PM, Harald Welte < laforge at gnumonks.org > wrote: > can you please explain how you validate / verify the various patches you are sending? What is your testing setup? Before I > merge some of the patches, I would like to understand that you are already doing some very basic testing to avoid > introducing regressions. Currently we validate the source code patches in unit test environment and the source code behavior is verified by GDB tool. Going forward we have planned to test the same source in the integration test setup. Regards, Bhargava Abhyankar From holger at freyther.de Tue Apr 12 14:28:48 2016 From: holger at freyther.de (Holger Freyther) Date: Tue, 12 Apr 2016 10:28:48 -0400 Subject: [PATCH] Handle the encoding of PUAN for CRBB bitmap In-Reply-To: <1460378934-17188-1-git-send-email-sangamesh.sajjan@radisys.com> References: <1460378934-17188-1-git-send-email-sangamesh.sajjan@radisys.com> Message-ID: > On 11 Apr 2016, at 08:48, sangamesh sajjan wrote: > Hi, > This patch includes the changes for encoding of PUAN to > handle the CRBB bitmap same as with Haralds mail. How was this tested? Can you add a testcase for it? In manual tests how often are the bitmaps compressed in manual tests? Under which conditions? > + for (i = 0, bsn = (v_q()+1); ((bsn < (v_r())) && (i < ws())); i++, > + bsn = this->mod_sns(bsn + 1)) { > + if (m_v_n.is_received(bsn)) { > + rbb[pos] = rbb[pos] | bitmask; > + } else { > + rbb[pos] = rbb[pos] & (~bitmask); > + } coding style issue and hard to read. By itself such a method would be easy to unit test. Could you please add a test? holger From holger at freyther.de Tue Apr 12 14:32:50 2016 From: holger at freyther.de (Holger Freyther) Date: Tue, 12 Apr 2016 10:32:50 -0400 Subject: [PATCH 4/4] Add test cases to support MCS change during Retx In-Reply-To: <1460371523-32154-4-git-send-email-Arvind.sirsikar@radisys.com> References: <1460371523-32154-1-git-send-email-Arvind.sirsikar@radisys.com> <1460371523-32154-4-git-send-email-Arvind.sirsikar@radisys.com> Message-ID: <3FAE6E1C-B075-437E-BE18-DD8577C88E0E@freyther.de> > On 11 Apr 2016, at 06:45, Aravind Sirsikar wrote: > > From: Aravind Sirsikar > > Add test cases to verify the MCS change functionality. > During MCS upgradation such as MCS6->MCS9, 2 blocks > which were sent separately as MCS6, will be clubbed into > one MCS9 block during retransmission. Same holds good for > MCS5->MCS7 transistion. During MCS reduction such as > MCS9->MCS6,2 blocks which were sent together will be > sent separately during the retransmission case. Same is > verified through the generated log file. Currently > MCS8->MCS6 transition is not supported. The retransmission > MCS is being calculated from Table 8.1.1.2 of TS 44.060. We do testing in two ways: 1.) Use OSMO_ASSERT to assert a certain side-effect/result 2.) Capture the output to catch accidental changes In your case only 2nd is done. It is good as it establishes a baseline but it is not sufficient as no actual side-effect/result is being asserted. E.g. as a reviewer it is very hard/time consuming to go through the debug log to actually find the re-transmission. So please add more strong post conditions to the test. kind regards holger From holger at freyther.de Tue Apr 12 14:40:41 2016 From: holger at freyther.de (Holger Freyther) Date: Tue, 12 Apr 2016 10:40:41 -0400 Subject: [PATCH 1/4] Add data structure for MCS change in Retx In-Reply-To: <1460371523-32154-1-git-send-email-Arvind.sirsikar@radisys.com> References: <1460371523-32154-1-git-send-email-Arvind.sirsikar@radisys.com> Message-ID: <86EA7EEE-164A-4A6A-85BD-675FD63DE769@freyther.de> > On 11 Apr 2016, at 06:45, Aravind Sirsikar wrote: > Dear Aravind, > + > + /* > + * cs2 is variable to hold the cs value for > + * current transmission. cs2 is same as cs during > + * transmission case. During retransmission cs2 is > + * fetched from egprs_mcs_retx_tbl table based on > + * cs and demanded cs. Once the data has been sent successfully, > + * cs2 will be copied to cs. Reference is 44.060 Table > + * 8.1.1.1 and Table 8.1.1.2 > + */ > + GprsCodingScheme cs2; > GprsCodingScheme cs; the comment is good and much appreciated. In general putting a suffix like '1' and '2' to variables is something I would like to avoid. E.g. when somebody needs to decide on 1 vs. 2. Can you think of more expressive names? cs_initial cs_retrans cheers holger From laforge at gnumonks.org Tue Apr 12 21:28:22 2016 From: laforge at gnumonks.org (Harald Welte) Date: Tue, 12 Apr 2016 23:28:22 +0200 Subject: [PATCH] Update the function for EGPRS immediate assignment In-Reply-To: References: <1460445755-28819-1-git-send-email-Bhargava.Abhyankar@radisys.com> <20160412081518.GJ15746@nataraja> Message-ID: <20160412212822.GF6186@nataraja> Hi Bhargava, On Tue, Apr 12, 2016 at 02:25:31PM +0000, Bhargava Abhyankar wrote: > Currently we validate the source code patches in unit test environment > and the source code behavior is verified by GDB tool. Going forward we > have planned to test the same source in the integration test setup. So in other words, this code has not yet been used in practise, by real MS interfacing with OsmoBTS and OsmoPCU. I thik this is bad news, and we will have to go for the 'temporary branch' solution that I proposed. Patches that look fine in terms of coding style and that have been reviewed positively could be pushed to something like a 'radisys/reviewed' branch. They would remain there until they have been tested in some way beyond the basic unit test. I hope you can understand that we cannot merge patches where even the original author / submitter has not tried to use them in a real setup. I'm not talking about a comprehensive end-to-end regression test, but just something very basic and simple, like a single type of MS attaching, establishing a PDP context and doing a file transfer over GPRS. Feel free to share what kind of "integration test setup" you have in mind for further testing of the code. -- - Harald Welte http://laforge.gnumonks.org/ ============================================================================ "Privacy in residential applications is a desirable marketing option." (ETSI EN 300 175-7 Ch. A6) From Arvind.Sirsikar at radisys.com Wed Apr 13 09:06:32 2016 From: Arvind.Sirsikar at radisys.com (Aravind Sirsikar) Date: Wed, 13 Apr 2016 09:06:32 +0000 Subject: [PATCH] Add test cases for EGPRS retransmission in DL In-Reply-To: References: <1459841854-18042-1-git-send-email-arvind.sirsikar@radisys.com> Message-ID: > On 07 Apr 2016, at 13:17, Holger Freyther wrote: Hello Holger, > Add test cases to validate retransmission of EGPRS RLC data block for > all the MCS in downlink direction without support of MCS change during > retransmission >> testcases are always good! I would prefer to have stronger assertions or at least some comments in the commit message that says what we should look for in the debug log. Stronger assertions are certainly preferred. The patch will be resent with more assertion as you have suggested and the patch description will also be updated to describe what is expected in the generated log file. > > +static void establish_and_use_egprs_dl_tbf_for_retx(BTS *the_bts, int > +mcs) { > > + for (i = 0; i < sizeof(test_data); i++) > + test_data[i] = i%512; >> okay, that is our test data. Can we easily see that all of it has been transferred? The aim of the test case is to verify retransmission logic in DL. The validation of data itself is done only through generated log. > > + /* Send only a few RLC/MAC blocks */ >> How many? How many are there, why a few? The intention was to have at least 2 RLC DATA blocks. The purpose is to validate retransmission logic functionally with minimum RLC data blocks, hence few. > + fn = 0; > + uint8_t block_nr = 0; > + int index1 = 0; > + > + while (index1 < 4) { > + /* Request to send one block */ > + request_dl_rlc_block(dl_tbf, &fn, &block_nr); > + index1++; > + if (dl_tbf->m_window.m_v_b.is_unacked(0)) > + dl_tbf->m_window.m_v_b.mark_nacked(0); > + if (mcs > 6) > + if (dl_tbf->m_window.m_v_b.is_unacked(1)) > + dl_tbf->m_window.m_v_b.mark_nacked(1); > + > + } >> E.g. here it might be a good case to really look at the window and verify we have unacked frames? Ok. I will add BSN validation for assertion. > + > + /* Drain the queue */ > + while (dl_tbf->have_data()) > + /* Request to send one RLC/MAC block */ > + request_dl_rlc_block(dl_tbf, &fn); >> and specifically check which parts went back to unacked? Ok. I will add the validation of BSN state for assertion. thank you Aravind Sirsikar From Bhargava.Abhyankar at radisys.com Wed Apr 13 09:15:38 2016 From: Bhargava.Abhyankar at radisys.com (Bhargava Abhyankar) Date: Wed, 13 Apr 2016 09:15:38 +0000 Subject: [PATCH 2/2] Add the test case for parsing uplink header type 2 In-Reply-To: <8EED6042-39FA-48E5-B784-87BE3A83BAC5@freyther.de> References: <1460030275-543-1-git-send-email-Bhargava.Abhyankar@radisys.com> <1460030275-543-2-git-send-email-Bhargava.Abhyankar@radisys.com> <8EED6042-39FA-48E5-B784-87BE3A83BAC5@freyther.de> Message-ID: Hello Holger, > On 07 Apr 2016, at 03:59 AM, Holger Freyther < holger at freyther.de> wrote: > + pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no]; > + pdch->rcv_block(&data[0], 79, *fn, &meas); >> like in my other mails, please have more strong post conditions. What do you actually expect in terms of side effects here? >> Test them specifically. Will find the relevant conditions to be tested and update it in the patch. kind regards Bhargava Abhyankar From Bhargava.Abhyankar at radisys.com Wed Apr 13 09:45:22 2016 From: Bhargava.Abhyankar at radisys.com (Bhargava Abhyankar) Date: Wed, 13 Apr 2016 09:45:22 +0000 Subject: [PATCH 1/2] Fix bug in uplink header type 1 parsing In-Reply-To: <69916AC6-393F-4482-9C49-919F8936CD6A@freyther.de> References: <1460030275-543-1-git-send-email-Bhargava.Abhyankar@radisys.com> <69916AC6-393F-4482-9C49-919F8936CD6A@freyther.de> Message-ID: Hello Holger, > On 08 Apr 2016, at 03:49 AM, Holger Freyther wrote: > - e_ti_header = (data[offs-1] + (data[offs] << 8)) >> 7; > + e_ti_header = (data[offs - 1] & (0xc0)) >> 6; >> Could you please elaborate about this hunk? What is the issue, how was it found, how are we certain that this is the fix? According to Figure 10.3a.4.3.1 of TS 44.060, E and TI bits are spread across two bytes for header type 3. In earlier patch sent for header type 1 same was incorrectly used. Later for header type 1, E and TI bits extraction was corrected as given in the spec 10.3a.4.1.1 of TS 44.060 for first RLC data block. According to the fix, The E and TI field are present in last byte of RLC header. > - rlc->block_info[0].e = !!(e_ti_header & 0x01); > - rlc->block_info[0].ti = !!(e_ti_header & 0x02); > + rlc->block_info[0].e = (e_ti_header & 0x01); > + rlc->block_info[0].ti = (e_ti_header & 0x02); >> what is the issue with this? The intention of !! is to normalize the value to 0 and 1. Now .ti can have 0x02 and 0x00 as value. Why is that needed? Due to oversight normalization is skipped, Normalizing is required, and will be adapted in correction patch. > - cur_bit += rlc->data_offs_bits[1] - 2; > + cur_bit = rlc->data_offs_bits[1] - 2; >> Why don't we need to advance this cursor anymore? In case of header type 1, we have two data blocks and one header. rlc->data_offs_bits[1] - 2 will have number of bits of header + first data block, then we calculate length of second data block and add it which makes it to be number of bits of header + 2 data blocks. > - e_ti_header = (data[offs-1] + (data[offs] << 8)) >> 7; > + e_ti_header = (data[offs] & (0x03)); >> What is the misunderstanding here. How did we think we needed to take bits from two different octets? According to Figure 10.3a.4.3.1 of TS 44.060, E and TI bits are spread across two bytes for header type 3. In earlier patch sent for header type 1 same was incorrectly used. Later for header type 1, E and TI bits extraction was corrected as given in the spec 10.3a.4.1.1 of TS 44.060 for second RLC data block. According to the fix, The E and TI field are present first 2 LSBs after first RLC data block. > - rlc->block_info[1].e = !!(e_ti_header & 0x01); > - rlc->block_info[1].ti = !!(e_ti_header & 0x02); > + rlc->block_info[1].e = (e_ti_header & 0x01); > + rlc->block_info[1].ti = (e_ti_header & 0x02); >> Again, why the change from 0 or 1 to .. 0 or 1 .. and 0 or 2? Due to oversight normalization is skipped, Normalizing is required, and will be adapted in correction patch. > egprs1->r = 1; > egprs1->cv = 7; > egprs1->tfi_a = tfi & (~((~0) << 2)); > - egprs1->tfi_b = tfi & (~((~0) << 3)) << 2; > - egprs1->bsn1_a = 10; > - egprs1->bsn1_b = 17; > - egprs1->bsn2_a = 0; > - egprs1->bsn2_b = 25; > + egprs1->tfi_b = (tfi & (~((~0) << 3)) << 2) >> 2; > + egprs1->bsn1_a = 0; > + egprs1->bsn1_b = 0; > + egprs1->bsn2_a = 1; > + egprs1->bsn2_b = 0; > egprs1->cps = 15; > egprs1->rsb = 0; > egprs1->pi = 0; > - data[6] = 1; > - data[6 + 68] = 1; > - data[75] = 1; > - data[75 + 68] = 1; > + data[5] = 0x40; > + data[5 + 69] = 1; >> Please explain the intention here. What is the issue with tfi_b? Why do you change it. Why do you pick the new bsn1_a and bsn1_b values Tfi_b was filled inappropriately. According to 10.3a.4.1 in 44.060. bsn1_a and bsn1_b are changed to starting values of the sequence number which is 0 and 1. Regards Bhargava Abhyankar From Arvind.Sirsikar at radisys.com Wed Apr 13 12:08:46 2016 From: Arvind.Sirsikar at radisys.com (Aravind Sirsikar) Date: Wed, 13 Apr 2016 12:08:46 +0000 Subject: [PATCH 4/4] Add test cases to support MCS change during Retx In-Reply-To: <3FAE6E1C-B075-437E-BE18-DD8577C88E0E@freyther.de> References: <1460371523-32154-1-git-send-email-Arvind.sirsikar@radisys.com> <1460371523-32154-4-git-send-email-Arvind.sirsikar@radisys.com> <3FAE6E1C-B075-437E-BE18-DD8577C88E0E@freyther.de> Message-ID: > On 12 Apr 2016, at 8.03, Holger Freyther wrote: > Add test cases to verify the MCS change functionality. > During MCS upgradation such as MCS6->MCS9, 2 blocks which were sent > separately as MCS6, will be clubbed into one MCS9 block during > retransmission. Same holds good for > MCS5->MCS7 transistion. During MCS reduction such as > MCS9->MCS6,2 blocks which were sent together will be > sent separately during the retransmission case. Same is verified > through the generated log file. Currently > MCS8->MCS6 transition is not supported. The retransmission > MCS is being calculated from Table 8.1.1.2 of TS 44.060. >> We do testing in two ways: >> 1.) Use OSMO_ASSERT to assert a certain side-effect/result >> 2.) Capture the output to catch accidental changes >> In your case only 2nd is done. It is good as it establishes a baseline but it is not sufficient as no actual side-effect/result is being asserted. E.g. as a reviewer it is very hard/time consuming to go through the debug log to >>actually find the re-transmission. So please add more strong post conditions to the test. Ok. I will modify the patch with relevant assert conditions and send it. kind regards Aravind Sirsikar From Arvind.Sirsikar at radisys.com Wed Apr 13 12:22:36 2016 From: Arvind.Sirsikar at radisys.com (Aravind Sirsikar) Date: Wed, 13 Apr 2016 12:22:36 +0000 Subject: [PATCH 1/4] Add data structure for MCS change in Retx In-Reply-To: <86EA7EEE-164A-4A6A-85BD-675FD63DE769@freyther.de> References: <1460371523-32154-1-git-send-email-Arvind.sirsikar@radisys.com> <86EA7EEE-164A-4A6A-85BD-675FD63DE769@freyther.de> Message-ID: On 12 Apr 2016, at 08:11, Holger Freyther wrote: Dear Holger, >the comment is good and much appreciated. In general putting a suffix like '1' >and '2' to variables is something I would like to avoid. E.g. when somebody >needs to decide on 1 vs. 2. Can you think of more expressive names? > > cs_initial cs_retrans Ok. I will modify the patch and resend it. Thanks, Aravind Sirsikar From holger at freyther.de Wed Apr 13 12:33:22 2016 From: holger at freyther.de (Holger Freyther) Date: Wed, 13 Apr 2016 08:33:22 -0400 Subject: [PATCH 1/4] Add data structure for MCS change in Retx In-Reply-To: References: <1460371523-32154-1-git-send-email-Arvind.sirsikar@radisys.com> <86EA7EEE-164A-4A6A-85BD-675FD63DE769@freyther.de> Message-ID: <659CDBD5-2156-487A-934B-2D2898AC1DB8@freyther.de> > On 13 Apr 2016, at 08:22, Aravind Sirsikar wrote: > >> > > Ok. I will modify the patch and resend it. Do you think there is a better name? holger From Arvind.Sirsikar at radisys.com Wed Apr 13 12:54:46 2016 From: Arvind.Sirsikar at radisys.com (Aravind Sirsikar) Date: Wed, 13 Apr 2016 12:54:46 +0000 Subject: [PATCH 1/4] Add data structure for MCS change in Retx In-Reply-To: <659CDBD5-2156-487A-934B-2D2898AC1DB8@freyther.de> References: <1460371523-32154-1-git-send-email-Arvind.sirsikar@radisys.com> <86EA7EEE-164A-4A6A-85BD-675FD63DE769@freyther.de> <659CDBD5-2156-487A-934B-2D2898AC1DB8@freyther.de> Message-ID: On 13 Apr 2016, at 06:03, Holger Freyther wrote: >Do you think there is a better name? Yes. I am planning to modify the new introduced variable cs2 only. This will be renamed as cs_current_trans. Thanks, Aravind Sirsikar From msuraev at sysmocom.de Wed Apr 13 13:46:40 2016 From: msuraev at sysmocom.de (msuraev at sysmocom.de) Date: Wed, 13 Apr 2016 15:46:40 +0200 Subject: [PATCH] Fix make distcheck Message-ID: <1460555200-15790-1-git-send-email-msuraev@sysmocom.de> From: Max Define automake variable for configure flags to be used while running 'make distcheck'. This should prevent additional vty tests from running in readonly distcheck environment. Note: user can still break the build by overriding this with DISTCHECK_CONFIGURE_FLAGS variable. --- src/Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Makefile.am b/src/Makefile.am index 6428bef..487ef1d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -19,6 +19,7 @@ # AM_CPPFLAGS = $(STD_DEFINES_AND_INCLUDES) $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGB_CFLAGS) $(LIBOSMOGSM_CFLAGS) +AM_DISTCHECK_CONFIGURE_FLAGS="--enable-sysmocom-dsp=no" if ENABLE_SYSMODSP AM_CPPFLAGS += -DENABLE_SYSMODSP -- 2.8.1 From msuraev at sysmocom.de Wed Apr 13 13:49:14 2016 From: msuraev at sysmocom.de (Max) Date: Wed, 13 Apr 2016 15:49:14 +0200 Subject: [PATCH] Fix make distcheck In-Reply-To: <1460555200-15790-1-git-send-email-msuraev@sysmocom.de> References: <1460555200-15790-1-git-send-email-msuraev@sysmocom.de> Message-ID: <570E4E5A.9000404@sysmocom.de> Note: I have not tested this with jenkins. Also, make sure to remove any occurrence of DISTCHECK_CONFIGURE_FLAGS from jenkins build description before testing it. -- Max Suraev http://www.sysmocom.de/ ======================================================================= * sysmocom - systems for mobile communications GmbH * Alt-Moabit 93 * 10559 Berlin, Germany * Sitz / Registered office: Berlin, HRB 134158 B * Geschaeftsfuehrer / Managing Directors: Holger Freyther, Harald Welte From Arvind.Sirsikar at radisys.com Fri Apr 15 11:33:53 2016 From: Arvind.Sirsikar at radisys.com (Aravind Sirsikar) Date: Fri, 15 Apr 2016 11:33:53 +0000 Subject: Query for verified EGPRS osmo-pcu version on Nuran1.0 Message-ID: Hi Harald, Can you please let us know the commit version for osmo-pcu which has been verified for EGPRS functionality on Nuran 1.0 hardware. We have been trying the latest commit 1aa75273025b033d17c1068369a7ba145d5c9f06 which does not work( no uplink data received yet). Can you provide details of the hardware in which EGPRS functionality has been successfully verified. Thanks, Aravind Sirsikar -------------- next part -------------- An HTML attachment was scrubbed... URL: From minh-quang.nguyen at nutaq.com Mon Apr 18 15:15:47 2016 From: minh-quang.nguyen at nutaq.com (Minh-Quang Nguyen) Date: Mon, 18 Apr 2016 11:15:47 -0400 Subject: Query for verified EGPRS osmo-pcu version on Nuran1.0 References: Message-ID: <86E210CFD3EEDE46A58DE4793CFA6C3F038674E6@NTWAEX01.interne.lyrtech.com> Hi Aravind, I am performing the first test of EGPRS with this commit by changing the following configurations: - Osmo-pcu: put 'egprs only ' parameter (without quotes) in osmo-pcu.cfg file - Osmo-nitb: change 'gprs mode gprs' to 'gprs mode egprs' in osmo-nitb.cfg file Minh-Quang Nguyen Concepteur logiciel | Software designer GSM/Network T. 418 914-7484 x2296 | 1 855 914-7484 | F. 418 914-9477 2150, Cyrille-Duquet, Qu?bec (Qu?bec) G1N 2G3 CANADA minh-quang.nguyen at nutaq.com www.nutaq.com QUEBEC MONTREAL NEW YORK Facebook Twitter LinkedIn YouTube From: osmocom-net-gprs [mailto:osmocom-net-gprs-bounces at lists.osmocom.org] On Behalf Of Aravind Sirsikar Sent: Friday, April 15, 2016 7:34 AM To: Harald Welte Cc: Prasad Kaup; osmocom-net-gprs at lists.osmocom.org; Saurabh Sharan Subject: Query for verified EGPRS osmo-pcu version on Nuran1.0 Hi Harald, Can you please let us know the commit version for osmo-pcu which has been verified for EGPRS functionality on Nuran 1.0 hardware. We have been trying the latest commit 1aa75273025b033d17c1068369a7ba145d5c9f06 which does not work( no uplink data received yet). Can you provide details of the hardware in which EGPRS functionality has been successfully verified. Thanks, Aravind Sirsikar -------------- next part -------------- An HTML attachment was scrubbed... URL: From msuraev at sysmocom.de Thu Apr 21 12:35:53 2016 From: msuraev at sysmocom.de (msuraev at sysmocom.de) Date: Thu, 21 Apr 2016 14:35:53 +0200 Subject: [PATCH 1/5] Cleanup build leftovers Message-ID: <1461242157-14223-1-git-send-email-msuraev@sysmocom.de> From: Max --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index d2713bf..959b09b 100644 --- a/.gitignore +++ b/.gitignore @@ -18,7 +18,7 @@ compile depcomp install-sh missing -libtool +*libtool ltmain.sh core -- 2.8.1 From msuraev at sysmocom.de Thu Apr 21 12:35:54 2016 From: msuraev at sysmocom.de (msuraev at sysmocom.de) Date: Thu, 21 Apr 2016 14:35:54 +0200 Subject: [PATCH 2/5] Enable subdir-objects In-Reply-To: <1461242157-14223-1-git-send-email-msuraev@sysmocom.de> References: <1461242157-14223-1-git-send-email-msuraev@sysmocom.de> Message-ID: <1461242157-14223-2-git-send-email-msuraev@sysmocom.de> From: Max This helps to increase compatibility with newer automake. --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 5274022..7a97954 100644 --- a/configure.ac +++ b/configure.ac @@ -3,7 +3,7 @@ AC_INIT([osmo-pcu], m4_esyscmd([./git-version-gen .tarball-version]), [osmocom-net-gprs at lists.osmocom.org]) -AM_INIT_AUTOMAKE([dist-bzip2]) +AM_INIT_AUTOMAKE([dist-bzip2 subdir-objects]) AC_CONFIG_TESTDIR(tests) dnl kernel style compile messages -- 2.8.1 From msuraev at sysmocom.de Thu Apr 21 12:35:55 2016 From: msuraev at sysmocom.de (msuraev at sysmocom.de) Date: Thu, 21 Apr 2016 14:35:55 +0200 Subject: [PATCH 3/5] Rename define for direct hw access In-Reply-To: <1461242157-14223-1-git-send-email-msuraev@sysmocom.de> References: <1461242157-14223-1-git-send-email-msuraev@sysmocom.de> Message-ID: <1461242157-14223-3-git-send-email-msuraev@sysmocom.de> From: Max --- src/Makefile.am | 2 +- src/osmobts_sock.cpp | 2 +- src/pcu_l1_if.cpp | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index 6428bef..832c3b0 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -21,7 +21,7 @@ AM_CPPFLAGS = $(STD_DEFINES_AND_INCLUDES) $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGB_CFLAGS) $(LIBOSMOGSM_CFLAGS) if ENABLE_SYSMODSP -AM_CPPFLAGS += -DENABLE_SYSMODSP +AM_CPPFLAGS += -DENABLE_DIRECT_PHY endif AM_CXXFLAGS = -Wall -ldl -pthread diff --git a/src/osmobts_sock.cpp b/src/osmobts_sock.cpp index b42f042..21a404f 100644 --- a/src/osmobts_sock.cpp +++ b/src/osmobts_sock.cpp @@ -100,7 +100,7 @@ static void pcu_sock_close(struct pcu_sock_state *state, int lost) /* disable all slots, kick all TBFs */ for (trx = 0; trx < 8; trx++) { -#ifdef ENABLE_SYSMODSP +#ifdef ENABLE_DIRECT_PHY if (bts->trx[trx].fl1h) { l1if_close_pdch(bts->trx[trx].fl1h); bts->trx[trx].fl1h = NULL; diff --git a/src/pcu_l1_if.cpp b/src/pcu_l1_if.cpp index 19dda5c..67272ab 100644 --- a/src/pcu_l1_if.cpp +++ b/src/pcu_l1_if.cpp @@ -128,7 +128,7 @@ void pcu_l1if_tx_pdtch(msgb *msg, uint8_t trx, uint8_t ts, uint16_t arfcn, { struct gprs_rlcmac_bts *bts = bts_main_data(); -#ifdef ENABLE_SYSMODSP +#ifdef ENABLE_DIRECT_PHY if (bts->trx[trx].fl1h) { l1if_pdch_req(bts->trx[trx].fl1h, ts, 0, fn, arfcn, block_nr, msg->data, msg->len); @@ -147,7 +147,7 @@ void pcu_l1if_tx_ptcch(msgb *msg, uint8_t trx, uint8_t ts, uint16_t arfcn, { struct gprs_rlcmac_bts *bts = bts_main_data(); -#ifdef ENABLE_SYSMODSP +#ifdef ENABLE_DIRECT_PHY if (bts->trx[trx].fl1h) { l1if_pdch_req(bts->trx[trx].fl1h, ts, 1, fn, arfcn, block_nr, msg->data, msg->len); @@ -445,7 +445,7 @@ bssgp_failed: bts->trx[trx].arfcn = info_ind->trx[trx].arfcn; if ((info_ind->flags & PCU_IF_FLAG_SYSMO) && info_ind->trx[trx].hlayer1) { -#ifdef ENABLE_SYSMODSP +#ifdef ENABLE_DIRECT_PHY LOGP(DL1IF, LOGL_DEBUG, " TRX %d hlayer1=%x\n", trx, info_ind->trx[trx].hlayer1); if (!bts->trx[trx].fl1h) @@ -471,7 +471,7 @@ bssgp_failed: if ((info_ind->trx[trx].pdch_mask & (1 << ts))) { /* FIXME: activate dynamically at RLCMAC */ if (!pdch->is_enabled()) { -#ifdef ENABLE_SYSMODSP +#ifdef ENABLE_DIRECT_PHY if ((info_ind->flags & PCU_IF_FLAG_SYSMO)) l1if_connect_pdch( -- 2.8.1 From msuraev at sysmocom.de Thu Apr 21 12:35:56 2016 From: msuraev at sysmocom.de (msuraev at sysmocom.de) Date: Thu, 21 Apr 2016 14:35:56 +0200 Subject: [PATCH 4/5] Restructure sources In-Reply-To: <1461242157-14223-1-git-send-email-msuraev@sysmocom.de> References: <1461242157-14223-1-git-send-email-msuraev@sysmocom.de> Message-ID: <1461242157-14223-4-git-send-email-msuraev@sysmocom.de> From: Max Move hardware-spicefic files into subdirectory similar to the way it's done in OsmoBTS to make adding new hardware support easier. --- src/Makefile.am | 49 +++-- src/femtobts.c | 275 -------------------------- src/femtobts.h | 57 ------ src/osmo-bts-sysmo/femtobts.c | 275 ++++++++++++++++++++++++++ src/osmo-bts-sysmo/femtobts.h | 57 ++++++ src/osmo-bts-sysmo/sysmo_l1_fwd.c | 145 ++++++++++++++ src/osmo-bts-sysmo/sysmo_l1_hw.c | 216 +++++++++++++++++++++ src/osmo-bts-sysmo/sysmo_l1_if.c | 394 ++++++++++++++++++++++++++++++++++++++ src/osmo-bts-sysmo/sysmo_l1_if.h | 91 +++++++++ src/sysmo_l1_fwd.c | 145 -------------- src/sysmo_l1_hw.c | 216 --------------------- src/sysmo_l1_if.c | 394 -------------------------------------- src/sysmo_l1_if.h | 91 --------- 13 files changed, 1207 insertions(+), 1198 deletions(-) delete mode 100644 src/femtobts.c delete mode 100644 src/femtobts.h create mode 100644 src/osmo-bts-sysmo/femtobts.c create mode 100644 src/osmo-bts-sysmo/femtobts.h create mode 100644 src/osmo-bts-sysmo/sysmo_l1_fwd.c create mode 100644 src/osmo-bts-sysmo/sysmo_l1_hw.c create mode 100644 src/osmo-bts-sysmo/sysmo_l1_if.c create mode 100644 src/osmo-bts-sysmo/sysmo_l1_if.h delete mode 100644 src/sysmo_l1_fwd.c delete mode 100644 src/sysmo_l1_hw.c delete mode 100644 src/sysmo_l1_if.c delete mode 100644 src/sysmo_l1_if.h diff --git a/src/Makefile.am b/src/Makefile.am index 832c3b0..3049744 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -64,11 +64,6 @@ bin_PROGRAMS = \ noinst_PROGRAMS = -if ENABLE_SYSMODSP -noinst_PROGRAMS += \ - osmo-pcu-remote -endif - noinst_HEADERS = \ gprs_debug.h \ csn1.h \ @@ -83,8 +78,6 @@ noinst_HEADERS = \ bitvector.h \ pcu_vty.h \ pcu_vty_functions.h \ - sysmo_l1_if.h \ - femtobts.h \ tbf.h \ bts.h \ poll_controller.h \ @@ -101,30 +94,46 @@ noinst_HEADERS = \ osmo_pcu_SOURCES = pcu_main.cpp if ENABLE_SYSMODSP -osmo_pcu_SOURCES += sysmo_l1_if.c \ - sysmo_l1_hw.c \ - femtobts.c - -osmo_pcu_remote_SOURCES = pcu_main.cpp \ - sysmo_l1_if.c \ - sysmo_l1_fwd.c \ - femtobts.c -endif +AM_CPPFLAGS += -I$(srcdir)/osmo-bts-sysmo -osmo_pcu_LDADD = \ +EXTRA_DIST = \ + osmo-bts-sysmo/sysmo_l1_if.c \ + osmo-bts-sysmo/sysmo_l1_if.h \ + osmo-bts-sysmo/sysmo_l1_hw.c \ + osmo-bts-sysmo/femtobts.c \ + osmo-bts-sysmo/femtobts.h + +noinst_HEADERS += \ + osmo-bts-sysmo/sysmo_l1_if.h \ + osmo-bts-sysmo/femtobts.h + +noinst_PROGRAMS += \ + osmo-pcu-remote + +osmo_pcu_SOURCES += \ + osmo-bts-sysmo/sysmo_l1_if.c \ + osmo-bts-sysmo/sysmo_l1_hw.c \ + osmo-bts-sysmo/femtobts.c + +osmo_pcu_remote_SOURCES = \ + pcu_main.cpp \ + osmo-bts-sysmo/sysmo_l1_if.c \ + osmo-bts-sysmo/sysmo_l1_fwd.c \ + osmo-bts-sysmo/femtobts.c + +osmo_pcu_remote_LDADD = \ libgprs.la \ $(LIBOSMOGB_LIBS) \ $(LIBOSMOCORE_LIBS) \ $(LIBOSMOGSM_LIBS) \ $(COMMON_LA) +endif -if ENABLE_SYSMODSP -osmo_pcu_remote_LDADD = \ +osmo_pcu_LDADD = \ libgprs.la \ $(LIBOSMOGB_LIBS) \ $(LIBOSMOCORE_LIBS) \ $(LIBOSMOGSM_LIBS) \ $(COMMON_LA) -endif #MOSTLYCLEANFILES += testSource testDestination diff --git a/src/femtobts.c b/src/femtobts.c deleted file mode 100644 index f6957d2..0000000 --- a/src/femtobts.c +++ /dev/null @@ -1,275 +0,0 @@ -/* sysmocom femtobts L1 API related definitions */ - -/* (C) 2011 by Harald Welte - * - * All Rights Reserved - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - * - */ - -#include -#include -#include - -#include "femtobts.h" - -const enum l1prim_type femtobts_l1prim_type[GsmL1_PrimId_NUM] = { - [GsmL1_PrimId_MphInitReq] = L1P_T_REQ, - [GsmL1_PrimId_MphCloseReq] = L1P_T_REQ, - [GsmL1_PrimId_MphConnectReq] = L1P_T_REQ, - [GsmL1_PrimId_MphDisconnectReq] = L1P_T_REQ, - [GsmL1_PrimId_MphActivateReq] = L1P_T_REQ, - [GsmL1_PrimId_MphDeactivateReq] = L1P_T_REQ, - [GsmL1_PrimId_MphConfigReq] = L1P_T_REQ, - [GsmL1_PrimId_MphMeasureReq] = L1P_T_REQ, - [GsmL1_PrimId_MphInitCnf] = L1P_T_CONF, - [GsmL1_PrimId_MphCloseCnf] = L1P_T_CONF, - [GsmL1_PrimId_MphConnectCnf] = L1P_T_CONF, - [GsmL1_PrimId_MphDisconnectCnf] = L1P_T_CONF, - [GsmL1_PrimId_MphActivateCnf] = L1P_T_CONF, - [GsmL1_PrimId_MphDeactivateCnf] = L1P_T_CONF, - [GsmL1_PrimId_MphConfigCnf] = L1P_T_CONF, - [GsmL1_PrimId_MphMeasureCnf] = L1P_T_CONF, - [GsmL1_PrimId_MphTimeInd] = L1P_T_IND, - [GsmL1_PrimId_MphSyncInd] = L1P_T_IND, - [GsmL1_PrimId_PhEmptyFrameReq] = L1P_T_REQ, - [GsmL1_PrimId_PhDataReq] = L1P_T_REQ, - [GsmL1_PrimId_PhConnectInd] = L1P_T_IND, - [GsmL1_PrimId_PhReadyToSendInd] = L1P_T_IND, - [GsmL1_PrimId_PhDataInd] = L1P_T_IND, - [GsmL1_PrimId_PhRaInd] = L1P_T_IND, -}; - -const struct value_string femtobts_l1prim_names[GsmL1_PrimId_NUM+1] = { - { GsmL1_PrimId_MphInitReq, "MPH-INIT.req" }, - { GsmL1_PrimId_MphCloseReq, "MPH-CLOSE.req" }, - { GsmL1_PrimId_MphConnectReq, "MPH-CONNECT.req" }, - { GsmL1_PrimId_MphDisconnectReq,"MPH-DISCONNECT.req" }, - { GsmL1_PrimId_MphActivateReq, "MPH-ACTIVATE.req" }, - { GsmL1_PrimId_MphDeactivateReq,"MPH-DEACTIVATE.req" }, - { GsmL1_PrimId_MphConfigReq, "MPH-CONFIG.req" }, - { GsmL1_PrimId_MphMeasureReq, "MPH-MEASURE.req" }, - { GsmL1_PrimId_MphInitCnf, "MPH-INIT.conf" }, - { GsmL1_PrimId_MphCloseCnf, "MPH-CLOSE.conf" }, - { GsmL1_PrimId_MphConnectCnf, "MPH-CONNECT.conf" }, - { GsmL1_PrimId_MphDisconnectCnf,"MPH-DISCONNECT.conf" }, - { GsmL1_PrimId_MphActivateCnf, "MPH-ACTIVATE.conf" }, - { GsmL1_PrimId_MphDeactivateCnf,"MPH-DEACTIVATE.conf" }, - { GsmL1_PrimId_MphConfigCnf, "MPH-CONFIG.conf" }, - { GsmL1_PrimId_MphMeasureCnf, "MPH-MEASURE.conf" }, - { GsmL1_PrimId_MphTimeInd, "MPH-TIME.ind" }, - { GsmL1_PrimId_MphSyncInd, "MPH-SYNC.ind" }, - { GsmL1_PrimId_PhEmptyFrameReq, "PH-EMPTY_FRAME.req" }, - { GsmL1_PrimId_PhDataReq, "PH-DATA.req" }, - { GsmL1_PrimId_PhConnectInd, "PH-CONNECT.ind" }, - { GsmL1_PrimId_PhReadyToSendInd,"PH-READY_TO_SEND.ind" }, - { GsmL1_PrimId_PhDataInd, "PH-DATA.ind" }, - { GsmL1_PrimId_PhRaInd, "PH-RA.ind" }, - { 0, NULL } -}; - -const GsmL1_PrimId_t femtobts_l1prim_req2conf[GsmL1_PrimId_NUM] = { - [GsmL1_PrimId_MphInitReq] = GsmL1_PrimId_MphInitCnf, - [GsmL1_PrimId_MphCloseReq] = GsmL1_PrimId_MphCloseCnf, - [GsmL1_PrimId_MphConnectReq] = GsmL1_PrimId_MphConnectCnf, - [GsmL1_PrimId_MphDisconnectReq] = GsmL1_PrimId_MphDisconnectCnf, - [GsmL1_PrimId_MphActivateReq] = GsmL1_PrimId_MphActivateCnf, - [GsmL1_PrimId_MphDeactivateReq] = GsmL1_PrimId_MphDeactivateCnf, - [GsmL1_PrimId_MphConfigReq] = GsmL1_PrimId_MphConfigCnf, - [GsmL1_PrimId_MphMeasureReq] = GsmL1_PrimId_MphMeasureCnf, -}; - -const enum l1prim_type femtobts_sysprim_type[SuperFemto_PrimId_NUM] = { - [SuperFemto_PrimId_SystemInfoReq] = L1P_T_REQ, - [SuperFemto_PrimId_SystemInfoCnf] = L1P_T_CONF, - [SuperFemto_PrimId_SystemFailureInd] = L1P_T_IND, - [SuperFemto_PrimId_ActivateRfReq] = L1P_T_REQ, - [SuperFemto_PrimId_ActivateRfCnf] = L1P_T_CONF, - [SuperFemto_PrimId_DeactivateRfReq] = L1P_T_REQ, - [SuperFemto_PrimId_DeactivateRfCnf] = L1P_T_CONF, - [SuperFemto_PrimId_SetTraceFlagsReq] = L1P_T_REQ, - [SuperFemto_PrimId_RfClockInfoReq] = L1P_T_REQ, - [SuperFemto_PrimId_RfClockInfoCnf] = L1P_T_CONF, - [SuperFemto_PrimId_RfClockSetupReq] = L1P_T_REQ, - [SuperFemto_PrimId_RfClockSetupCnf] = L1P_T_CONF, - [SuperFemto_PrimId_Layer1ResetReq] = L1P_T_REQ, - [SuperFemto_PrimId_Layer1ResetCnf] = L1P_T_CONF, -}; - -const struct value_string femtobts_sysprim_names[SuperFemto_PrimId_NUM+1] = { - { SuperFemto_PrimId_SystemInfoReq, "SYSTEM-INFO.req" }, - { SuperFemto_PrimId_SystemInfoCnf, "SYSTEM-INFO.conf" }, - { SuperFemto_PrimId_SystemFailureInd, "SYSTEM-FAILURE.ind" }, - { SuperFemto_PrimId_ActivateRfReq, "ACTIVATE-RF.req" }, - { SuperFemto_PrimId_ActivateRfCnf, "ACTIVATE-RF.conf" }, - { SuperFemto_PrimId_DeactivateRfReq, "DEACTIVATE-RF.req" }, - { SuperFemto_PrimId_DeactivateRfCnf, "DEACTIVATE-RF.conf" }, - { SuperFemto_PrimId_SetTraceFlagsReq, "SET-TRACE-FLAGS.req" }, - { SuperFemto_PrimId_RfClockInfoReq, "RF-CLOCK-INFO.req" }, - { SuperFemto_PrimId_RfClockInfoCnf, "RF-CLOCK-INFO.conf" }, - { SuperFemto_PrimId_RfClockSetupReq, "RF-CLOCK-SETUP.req" }, - { SuperFemto_PrimId_RfClockSetupCnf, "RF-CLOCK-SETUP.conf" }, - { SuperFemto_PrimId_Layer1ResetReq, "LAYER1-RESET.req" }, - { SuperFemto_PrimId_Layer1ResetCnf, "LAYER1-RESET.conf" }, - { 0, NULL } -}; - -const SuperFemto_PrimId_t femtobts_sysprim_req2conf[SuperFemto_PrimId_NUM] = { - [SuperFemto_PrimId_SystemInfoReq] = SuperFemto_PrimId_SystemInfoCnf, - [SuperFemto_PrimId_ActivateRfReq] = SuperFemto_PrimId_ActivateRfCnf, - [SuperFemto_PrimId_DeactivateRfReq] = SuperFemto_PrimId_DeactivateRfCnf, - [SuperFemto_PrimId_RfClockInfoReq] = SuperFemto_PrimId_RfClockInfoCnf, - [SuperFemto_PrimId_RfClockSetupReq] = SuperFemto_PrimId_RfClockSetupCnf, - [SuperFemto_PrimId_Layer1ResetReq] = SuperFemto_PrimId_Layer1ResetCnf, -}; - -const struct value_string femtobts_l1sapi_names[GsmL1_Sapi_NUM+1] = { - { GsmL1_Sapi_Fcch, "FCCH" }, - { GsmL1_Sapi_Sch, "SCH" }, - { GsmL1_Sapi_Sacch, "SACCH" }, - { GsmL1_Sapi_Sdcch, "SDCCH" }, - { GsmL1_Sapi_Bcch, "BCCH" }, - { GsmL1_Sapi_Pch, "PCH" }, - { GsmL1_Sapi_Agch, "AGCH" }, - { GsmL1_Sapi_Cbch, "CBCH" }, - { GsmL1_Sapi_Rach, "RACH" }, - { GsmL1_Sapi_TchF, "TCH/F" }, - { GsmL1_Sapi_FacchF, "FACCH/F" }, - { GsmL1_Sapi_TchH, "TCH/H" }, - { GsmL1_Sapi_FacchH, "FACCH/H" }, - { GsmL1_Sapi_Nch, "NCH" }, - { GsmL1_Sapi_Pdtch, "PDTCH" }, - { GsmL1_Sapi_Pacch, "PACCH" }, - { GsmL1_Sapi_Pbcch, "PBCCH" }, - { GsmL1_Sapi_Pagch, "PAGCH" }, - { GsmL1_Sapi_Ppch, "PPCH" }, - { GsmL1_Sapi_Pnch, "PNCH" }, - { GsmL1_Sapi_Ptcch, "PTCCH" }, - { GsmL1_Sapi_Prach, "PRACH" }, - { 0, NULL } -}; - -const struct value_string femtobts_l1status_names[GSML1_STATUS_NUM+1] = { - { GsmL1_Status_Success, "Success" }, - { GsmL1_Status_Generic, "Generic error" }, - { GsmL1_Status_NoMemory, "Not enough memory" }, - { GsmL1_Status_Timeout, "Timeout" }, - { GsmL1_Status_InvalidParam, "Invalid parameter" }, - { GsmL1_Status_Busy, "Resource busy" }, - { GsmL1_Status_NoRessource, "No more resources" }, - { GsmL1_Status_Uninitialized, "Trying to use uninitialized resource" }, - { GsmL1_Status_NullInterface, "Trying to call a NULL interface" }, - { GsmL1_Status_NullFctnPtr, "Trying to call a NULL function ptr" }, - { GsmL1_Status_BadCrc, "Bad CRC" }, - { GsmL1_Status_BadUsf, "Bad USF" }, - { GsmL1_Status_InvalidCPS, "Invalid CPS field" }, - { GsmL1_Status_UnexpectedBurst, "Unexpected burst" }, - { GsmL1_Status_UnavailCodec, "AMR codec is unavailable" }, - { GsmL1_Status_CriticalError, "Critical error" }, - { GsmL1_Status_OverheatError, "Overheat error" }, - { GsmL1_Status_DeviceError, "Device error" }, - { GsmL1_Status_FacchError, "FACCH / TCH order error" }, - { GsmL1_Status_AlreadyDeactivated, "Lchan already deactivated" }, - { GsmL1_Status_TxBurstFifoOvrn, "FIFO overrun" }, - { GsmL1_Status_TxBurstFifoUndr, "FIFO underrun" }, - { GsmL1_Status_NotSynchronized, "Not synchronized" }, - { GsmL1_Status_Unsupported, "Unsupported feature" }, - { 0, NULL } -}; - -const struct value_string femtobts_tracef_names[29] = { - { DBG_DEBUG, "DEBUG" }, - { DBG_L1WARNING, "L1_WARNING" }, - { DBG_ERROR, "ERROR" }, - { DBG_L1RXMSG, "L1_RX_MSG" }, - { DBG_L1RXMSGBYTE, "L1_RX_MSG_BYTE" }, - { DBG_L1TXMSG, "L1_TX_MSG" }, - { DBG_L1TXMSGBYTE, "L1_TX_MSG_BYTE" }, - { DBG_MPHCNF, "MPH_CNF" }, - { DBG_MPHIND, "MPH_IND" }, - { DBG_MPHREQ, "MPH_REQ" }, - { DBG_PHIND, "PH_IND" }, - { DBG_PHREQ, "PH_REQ" }, - { DBG_PHYRF, "PHY_RF" }, - { DBG_PHYRFMSGBYTE, "PHY_MSG_BYTE" }, - { DBG_MODE, "MODE" }, - { DBG_TDMAINFO, "TDMA_INFO" }, - { DBG_BADCRC, "BAD_CRC" }, - { DBG_PHINDBYTE, "PH_IND_BYTE" }, - { DBG_PHREQBYTE, "PH_REQ_BYTE" }, - { DBG_DEVICEMSG, "DEVICE_MSG" }, - { DBG_RACHINFO, "RACH_INFO" }, - { DBG_LOGCHINFO, "LOG_CH_INFO" }, - { DBG_MEMORY, "MEMORY" }, - { DBG_PROFILING, "PROFILING" }, - { DBG_TESTCOMMENT, "TEST_COMMENT" }, - { DBG_TEST, "TEST" }, - { DBG_STATUS, "STATUS" }, - { 0, NULL } -}; - -const struct value_string femtobts_tch_pl_names[] = { - { GsmL1_TchPlType_NA, "N/A" }, - { GsmL1_TchPlType_Fr, "FR" }, - { GsmL1_TchPlType_Hr, "HR" }, - { GsmL1_TchPlType_Efr, "EFR" }, - { GsmL1_TchPlType_Amr, "AMR(IF2)" }, - { GsmL1_TchPlType_Amr_SidBad, "AMR(SID BAD)" }, - { GsmL1_TchPlType_Amr_Onset, "AMR(ONSET)" }, - { GsmL1_TchPlType_Amr_Ratscch, "AMR(RATSCCH)" }, - { GsmL1_TchPlType_Amr_SidUpdateInH, "AMR(SID_UPDATE INH)" }, - { GsmL1_TchPlType_Amr_SidFirstP1, "AMR(SID_FIRST P1)" }, - { GsmL1_TchPlType_Amr_SidFirstP2, "AMR(SID_FIRST P2)" }, - { GsmL1_TchPlType_Amr_SidFirstInH, "AMR(SID_FIRST INH)" }, - { GsmL1_TchPlType_Amr_RatscchMarker, "AMR(RATSCCH MARK)" }, - { GsmL1_TchPlType_Amr_RatscchData, "AMR(RATSCCH DATA)" }, - { 0, NULL } -}; - -const struct value_string femtobts_dir_names[] = { - { GsmL1_Dir_TxDownlink, "TxDL" }, - { GsmL1_Dir_TxUplink, "TxUL" }, - { GsmL1_Dir_RxUplink, "RxUL" }, - { GsmL1_Dir_RxDownlink, "RxDL" }, - { GsmL1_Dir_TxDownlink|GsmL1_Dir_RxUplink, "BOTH" }, - { 0, NULL } -}; - -const struct value_string femtobts_chcomb_names[] = { - { GsmL1_LogChComb_0, "dummy" }, - { GsmL1_LogChComb_I, "tch_f" }, - { GsmL1_LogChComb_II, "tch_h" }, - { GsmL1_LogChComb_IV, "ccch" }, - { GsmL1_LogChComb_V, "ccch_sdcch4" }, - { GsmL1_LogChComb_VII, "sdcch8" }, - { GsmL1_LogChComb_XIII, "pdtch" }, - { 0, NULL } -}; - -const uint8_t pdch_msu_size[_NUM_PDCH_CS] = { - [PDCH_CS_1] = 23, - [PDCH_CS_2] = 34, - [PDCH_CS_3] = 40, - [PDCH_CS_4] = 54, - [PDCH_MCS_1] = 27, - [PDCH_MCS_2] = 33, - [PDCH_MCS_3] = 42, - [PDCH_MCS_4] = 49, - [PDCH_MCS_5] = 60, - [PDCH_MCS_6] = 78, - [PDCH_MCS_7] = 118, - [PDCH_MCS_8] = 142, - [PDCH_MCS_9] = 154 -}; diff --git a/src/femtobts.h b/src/femtobts.h deleted file mode 100644 index 7e45578..0000000 --- a/src/femtobts.h +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef FEMTOBTS_H -#define FEMTOBTS_H - -#include -#include - -#include -#include - -#ifdef L1_HAS_RTP_MODE -/* This is temporarily disabled, as AMR has some bugs in RTP mode */ -//#define USE_L1_RTP_MODE /* Tell L1 to use RTP mode */ -#endif - -enum l1prim_type { - L1P_T_REQ, - L1P_T_CONF, - L1P_T_IND, -}; - -const enum l1prim_type femtobts_l1prim_type[GsmL1_PrimId_NUM]; -const struct value_string femtobts_l1prim_names[GsmL1_PrimId_NUM+1]; -const GsmL1_PrimId_t femtobts_l1prim_req2conf[GsmL1_PrimId_NUM]; - -const enum l1prim_type femtobts_sysprim_type[SuperFemto_PrimId_NUM]; -const struct value_string femtobts_sysprim_names[SuperFemto_PrimId_NUM+1]; -const SuperFemto_PrimId_t femtobts_sysprim_req2conf[SuperFemto_PrimId_NUM]; - -const struct value_string femtobts_l1sapi_names[GsmL1_Sapi_NUM+1]; -const struct value_string femtobts_l1status_names[GSML1_STATUS_NUM+1]; - -const struct value_string femtobts_tracef_names[29]; - -const struct value_string femtobts_tch_pl_names[15]; - -const struct value_string femtobts_dir_names[6]; - -enum pdch_cs { - PDCH_CS_1, - PDCH_CS_2, - PDCH_CS_3, - PDCH_CS_4, - PDCH_MCS_1, - PDCH_MCS_2, - PDCH_MCS_3, - PDCH_MCS_4, - PDCH_MCS_5, - PDCH_MCS_6, - PDCH_MCS_7, - PDCH_MCS_8, - PDCH_MCS_9, - _NUM_PDCH_CS -}; - -const uint8_t pdch_msu_size[_NUM_PDCH_CS]; - -#endif /* FEMTOBTS_H */ diff --git a/src/osmo-bts-sysmo/femtobts.c b/src/osmo-bts-sysmo/femtobts.c new file mode 100644 index 0000000..f6957d2 --- /dev/null +++ b/src/osmo-bts-sysmo/femtobts.c @@ -0,0 +1,275 @@ +/* sysmocom femtobts L1 API related definitions */ + +/* (C) 2011 by Harald Welte + * + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +#include +#include +#include + +#include "femtobts.h" + +const enum l1prim_type femtobts_l1prim_type[GsmL1_PrimId_NUM] = { + [GsmL1_PrimId_MphInitReq] = L1P_T_REQ, + [GsmL1_PrimId_MphCloseReq] = L1P_T_REQ, + [GsmL1_PrimId_MphConnectReq] = L1P_T_REQ, + [GsmL1_PrimId_MphDisconnectReq] = L1P_T_REQ, + [GsmL1_PrimId_MphActivateReq] = L1P_T_REQ, + [GsmL1_PrimId_MphDeactivateReq] = L1P_T_REQ, + [GsmL1_PrimId_MphConfigReq] = L1P_T_REQ, + [GsmL1_PrimId_MphMeasureReq] = L1P_T_REQ, + [GsmL1_PrimId_MphInitCnf] = L1P_T_CONF, + [GsmL1_PrimId_MphCloseCnf] = L1P_T_CONF, + [GsmL1_PrimId_MphConnectCnf] = L1P_T_CONF, + [GsmL1_PrimId_MphDisconnectCnf] = L1P_T_CONF, + [GsmL1_PrimId_MphActivateCnf] = L1P_T_CONF, + [GsmL1_PrimId_MphDeactivateCnf] = L1P_T_CONF, + [GsmL1_PrimId_MphConfigCnf] = L1P_T_CONF, + [GsmL1_PrimId_MphMeasureCnf] = L1P_T_CONF, + [GsmL1_PrimId_MphTimeInd] = L1P_T_IND, + [GsmL1_PrimId_MphSyncInd] = L1P_T_IND, + [GsmL1_PrimId_PhEmptyFrameReq] = L1P_T_REQ, + [GsmL1_PrimId_PhDataReq] = L1P_T_REQ, + [GsmL1_PrimId_PhConnectInd] = L1P_T_IND, + [GsmL1_PrimId_PhReadyToSendInd] = L1P_T_IND, + [GsmL1_PrimId_PhDataInd] = L1P_T_IND, + [GsmL1_PrimId_PhRaInd] = L1P_T_IND, +}; + +const struct value_string femtobts_l1prim_names[GsmL1_PrimId_NUM+1] = { + { GsmL1_PrimId_MphInitReq, "MPH-INIT.req" }, + { GsmL1_PrimId_MphCloseReq, "MPH-CLOSE.req" }, + { GsmL1_PrimId_MphConnectReq, "MPH-CONNECT.req" }, + { GsmL1_PrimId_MphDisconnectReq,"MPH-DISCONNECT.req" }, + { GsmL1_PrimId_MphActivateReq, "MPH-ACTIVATE.req" }, + { GsmL1_PrimId_MphDeactivateReq,"MPH-DEACTIVATE.req" }, + { GsmL1_PrimId_MphConfigReq, "MPH-CONFIG.req" }, + { GsmL1_PrimId_MphMeasureReq, "MPH-MEASURE.req" }, + { GsmL1_PrimId_MphInitCnf, "MPH-INIT.conf" }, + { GsmL1_PrimId_MphCloseCnf, "MPH-CLOSE.conf" }, + { GsmL1_PrimId_MphConnectCnf, "MPH-CONNECT.conf" }, + { GsmL1_PrimId_MphDisconnectCnf,"MPH-DISCONNECT.conf" }, + { GsmL1_PrimId_MphActivateCnf, "MPH-ACTIVATE.conf" }, + { GsmL1_PrimId_MphDeactivateCnf,"MPH-DEACTIVATE.conf" }, + { GsmL1_PrimId_MphConfigCnf, "MPH-CONFIG.conf" }, + { GsmL1_PrimId_MphMeasureCnf, "MPH-MEASURE.conf" }, + { GsmL1_PrimId_MphTimeInd, "MPH-TIME.ind" }, + { GsmL1_PrimId_MphSyncInd, "MPH-SYNC.ind" }, + { GsmL1_PrimId_PhEmptyFrameReq, "PH-EMPTY_FRAME.req" }, + { GsmL1_PrimId_PhDataReq, "PH-DATA.req" }, + { GsmL1_PrimId_PhConnectInd, "PH-CONNECT.ind" }, + { GsmL1_PrimId_PhReadyToSendInd,"PH-READY_TO_SEND.ind" }, + { GsmL1_PrimId_PhDataInd, "PH-DATA.ind" }, + { GsmL1_PrimId_PhRaInd, "PH-RA.ind" }, + { 0, NULL } +}; + +const GsmL1_PrimId_t femtobts_l1prim_req2conf[GsmL1_PrimId_NUM] = { + [GsmL1_PrimId_MphInitReq] = GsmL1_PrimId_MphInitCnf, + [GsmL1_PrimId_MphCloseReq] = GsmL1_PrimId_MphCloseCnf, + [GsmL1_PrimId_MphConnectReq] = GsmL1_PrimId_MphConnectCnf, + [GsmL1_PrimId_MphDisconnectReq] = GsmL1_PrimId_MphDisconnectCnf, + [GsmL1_PrimId_MphActivateReq] = GsmL1_PrimId_MphActivateCnf, + [GsmL1_PrimId_MphDeactivateReq] = GsmL1_PrimId_MphDeactivateCnf, + [GsmL1_PrimId_MphConfigReq] = GsmL1_PrimId_MphConfigCnf, + [GsmL1_PrimId_MphMeasureReq] = GsmL1_PrimId_MphMeasureCnf, +}; + +const enum l1prim_type femtobts_sysprim_type[SuperFemto_PrimId_NUM] = { + [SuperFemto_PrimId_SystemInfoReq] = L1P_T_REQ, + [SuperFemto_PrimId_SystemInfoCnf] = L1P_T_CONF, + [SuperFemto_PrimId_SystemFailureInd] = L1P_T_IND, + [SuperFemto_PrimId_ActivateRfReq] = L1P_T_REQ, + [SuperFemto_PrimId_ActivateRfCnf] = L1P_T_CONF, + [SuperFemto_PrimId_DeactivateRfReq] = L1P_T_REQ, + [SuperFemto_PrimId_DeactivateRfCnf] = L1P_T_CONF, + [SuperFemto_PrimId_SetTraceFlagsReq] = L1P_T_REQ, + [SuperFemto_PrimId_RfClockInfoReq] = L1P_T_REQ, + [SuperFemto_PrimId_RfClockInfoCnf] = L1P_T_CONF, + [SuperFemto_PrimId_RfClockSetupReq] = L1P_T_REQ, + [SuperFemto_PrimId_RfClockSetupCnf] = L1P_T_CONF, + [SuperFemto_PrimId_Layer1ResetReq] = L1P_T_REQ, + [SuperFemto_PrimId_Layer1ResetCnf] = L1P_T_CONF, +}; + +const struct value_string femtobts_sysprim_names[SuperFemto_PrimId_NUM+1] = { + { SuperFemto_PrimId_SystemInfoReq, "SYSTEM-INFO.req" }, + { SuperFemto_PrimId_SystemInfoCnf, "SYSTEM-INFO.conf" }, + { SuperFemto_PrimId_SystemFailureInd, "SYSTEM-FAILURE.ind" }, + { SuperFemto_PrimId_ActivateRfReq, "ACTIVATE-RF.req" }, + { SuperFemto_PrimId_ActivateRfCnf, "ACTIVATE-RF.conf" }, + { SuperFemto_PrimId_DeactivateRfReq, "DEACTIVATE-RF.req" }, + { SuperFemto_PrimId_DeactivateRfCnf, "DEACTIVATE-RF.conf" }, + { SuperFemto_PrimId_SetTraceFlagsReq, "SET-TRACE-FLAGS.req" }, + { SuperFemto_PrimId_RfClockInfoReq, "RF-CLOCK-INFO.req" }, + { SuperFemto_PrimId_RfClockInfoCnf, "RF-CLOCK-INFO.conf" }, + { SuperFemto_PrimId_RfClockSetupReq, "RF-CLOCK-SETUP.req" }, + { SuperFemto_PrimId_RfClockSetupCnf, "RF-CLOCK-SETUP.conf" }, + { SuperFemto_PrimId_Layer1ResetReq, "LAYER1-RESET.req" }, + { SuperFemto_PrimId_Layer1ResetCnf, "LAYER1-RESET.conf" }, + { 0, NULL } +}; + +const SuperFemto_PrimId_t femtobts_sysprim_req2conf[SuperFemto_PrimId_NUM] = { + [SuperFemto_PrimId_SystemInfoReq] = SuperFemto_PrimId_SystemInfoCnf, + [SuperFemto_PrimId_ActivateRfReq] = SuperFemto_PrimId_ActivateRfCnf, + [SuperFemto_PrimId_DeactivateRfReq] = SuperFemto_PrimId_DeactivateRfCnf, + [SuperFemto_PrimId_RfClockInfoReq] = SuperFemto_PrimId_RfClockInfoCnf, + [SuperFemto_PrimId_RfClockSetupReq] = SuperFemto_PrimId_RfClockSetupCnf, + [SuperFemto_PrimId_Layer1ResetReq] = SuperFemto_PrimId_Layer1ResetCnf, +}; + +const struct value_string femtobts_l1sapi_names[GsmL1_Sapi_NUM+1] = { + { GsmL1_Sapi_Fcch, "FCCH" }, + { GsmL1_Sapi_Sch, "SCH" }, + { GsmL1_Sapi_Sacch, "SACCH" }, + { GsmL1_Sapi_Sdcch, "SDCCH" }, + { GsmL1_Sapi_Bcch, "BCCH" }, + { GsmL1_Sapi_Pch, "PCH" }, + { GsmL1_Sapi_Agch, "AGCH" }, + { GsmL1_Sapi_Cbch, "CBCH" }, + { GsmL1_Sapi_Rach, "RACH" }, + { GsmL1_Sapi_TchF, "TCH/F" }, + { GsmL1_Sapi_FacchF, "FACCH/F" }, + { GsmL1_Sapi_TchH, "TCH/H" }, + { GsmL1_Sapi_FacchH, "FACCH/H" }, + { GsmL1_Sapi_Nch, "NCH" }, + { GsmL1_Sapi_Pdtch, "PDTCH" }, + { GsmL1_Sapi_Pacch, "PACCH" }, + { GsmL1_Sapi_Pbcch, "PBCCH" }, + { GsmL1_Sapi_Pagch, "PAGCH" }, + { GsmL1_Sapi_Ppch, "PPCH" }, + { GsmL1_Sapi_Pnch, "PNCH" }, + { GsmL1_Sapi_Ptcch, "PTCCH" }, + { GsmL1_Sapi_Prach, "PRACH" }, + { 0, NULL } +}; + +const struct value_string femtobts_l1status_names[GSML1_STATUS_NUM+1] = { + { GsmL1_Status_Success, "Success" }, + { GsmL1_Status_Generic, "Generic error" }, + { GsmL1_Status_NoMemory, "Not enough memory" }, + { GsmL1_Status_Timeout, "Timeout" }, + { GsmL1_Status_InvalidParam, "Invalid parameter" }, + { GsmL1_Status_Busy, "Resource busy" }, + { GsmL1_Status_NoRessource, "No more resources" }, + { GsmL1_Status_Uninitialized, "Trying to use uninitialized resource" }, + { GsmL1_Status_NullInterface, "Trying to call a NULL interface" }, + { GsmL1_Status_NullFctnPtr, "Trying to call a NULL function ptr" }, + { GsmL1_Status_BadCrc, "Bad CRC" }, + { GsmL1_Status_BadUsf, "Bad USF" }, + { GsmL1_Status_InvalidCPS, "Invalid CPS field" }, + { GsmL1_Status_UnexpectedBurst, "Unexpected burst" }, + { GsmL1_Status_UnavailCodec, "AMR codec is unavailable" }, + { GsmL1_Status_CriticalError, "Critical error" }, + { GsmL1_Status_OverheatError, "Overheat error" }, + { GsmL1_Status_DeviceError, "Device error" }, + { GsmL1_Status_FacchError, "FACCH / TCH order error" }, + { GsmL1_Status_AlreadyDeactivated, "Lchan already deactivated" }, + { GsmL1_Status_TxBurstFifoOvrn, "FIFO overrun" }, + { GsmL1_Status_TxBurstFifoUndr, "FIFO underrun" }, + { GsmL1_Status_NotSynchronized, "Not synchronized" }, + { GsmL1_Status_Unsupported, "Unsupported feature" }, + { 0, NULL } +}; + +const struct value_string femtobts_tracef_names[29] = { + { DBG_DEBUG, "DEBUG" }, + { DBG_L1WARNING, "L1_WARNING" }, + { DBG_ERROR, "ERROR" }, + { DBG_L1RXMSG, "L1_RX_MSG" }, + { DBG_L1RXMSGBYTE, "L1_RX_MSG_BYTE" }, + { DBG_L1TXMSG, "L1_TX_MSG" }, + { DBG_L1TXMSGBYTE, "L1_TX_MSG_BYTE" }, + { DBG_MPHCNF, "MPH_CNF" }, + { DBG_MPHIND, "MPH_IND" }, + { DBG_MPHREQ, "MPH_REQ" }, + { DBG_PHIND, "PH_IND" }, + { DBG_PHREQ, "PH_REQ" }, + { DBG_PHYRF, "PHY_RF" }, + { DBG_PHYRFMSGBYTE, "PHY_MSG_BYTE" }, + { DBG_MODE, "MODE" }, + { DBG_TDMAINFO, "TDMA_INFO" }, + { DBG_BADCRC, "BAD_CRC" }, + { DBG_PHINDBYTE, "PH_IND_BYTE" }, + { DBG_PHREQBYTE, "PH_REQ_BYTE" }, + { DBG_DEVICEMSG, "DEVICE_MSG" }, + { DBG_RACHINFO, "RACH_INFO" }, + { DBG_LOGCHINFO, "LOG_CH_INFO" }, + { DBG_MEMORY, "MEMORY" }, + { DBG_PROFILING, "PROFILING" }, + { DBG_TESTCOMMENT, "TEST_COMMENT" }, + { DBG_TEST, "TEST" }, + { DBG_STATUS, "STATUS" }, + { 0, NULL } +}; + +const struct value_string femtobts_tch_pl_names[] = { + { GsmL1_TchPlType_NA, "N/A" }, + { GsmL1_TchPlType_Fr, "FR" }, + { GsmL1_TchPlType_Hr, "HR" }, + { GsmL1_TchPlType_Efr, "EFR" }, + { GsmL1_TchPlType_Amr, "AMR(IF2)" }, + { GsmL1_TchPlType_Amr_SidBad, "AMR(SID BAD)" }, + { GsmL1_TchPlType_Amr_Onset, "AMR(ONSET)" }, + { GsmL1_TchPlType_Amr_Ratscch, "AMR(RATSCCH)" }, + { GsmL1_TchPlType_Amr_SidUpdateInH, "AMR(SID_UPDATE INH)" }, + { GsmL1_TchPlType_Amr_SidFirstP1, "AMR(SID_FIRST P1)" }, + { GsmL1_TchPlType_Amr_SidFirstP2, "AMR(SID_FIRST P2)" }, + { GsmL1_TchPlType_Amr_SidFirstInH, "AMR(SID_FIRST INH)" }, + { GsmL1_TchPlType_Amr_RatscchMarker, "AMR(RATSCCH MARK)" }, + { GsmL1_TchPlType_Amr_RatscchData, "AMR(RATSCCH DATA)" }, + { 0, NULL } +}; + +const struct value_string femtobts_dir_names[] = { + { GsmL1_Dir_TxDownlink, "TxDL" }, + { GsmL1_Dir_TxUplink, "TxUL" }, + { GsmL1_Dir_RxUplink, "RxUL" }, + { GsmL1_Dir_RxDownlink, "RxDL" }, + { GsmL1_Dir_TxDownlink|GsmL1_Dir_RxUplink, "BOTH" }, + { 0, NULL } +}; + +const struct value_string femtobts_chcomb_names[] = { + { GsmL1_LogChComb_0, "dummy" }, + { GsmL1_LogChComb_I, "tch_f" }, + { GsmL1_LogChComb_II, "tch_h" }, + { GsmL1_LogChComb_IV, "ccch" }, + { GsmL1_LogChComb_V, "ccch_sdcch4" }, + { GsmL1_LogChComb_VII, "sdcch8" }, + { GsmL1_LogChComb_XIII, "pdtch" }, + { 0, NULL } +}; + +const uint8_t pdch_msu_size[_NUM_PDCH_CS] = { + [PDCH_CS_1] = 23, + [PDCH_CS_2] = 34, + [PDCH_CS_3] = 40, + [PDCH_CS_4] = 54, + [PDCH_MCS_1] = 27, + [PDCH_MCS_2] = 33, + [PDCH_MCS_3] = 42, + [PDCH_MCS_4] = 49, + [PDCH_MCS_5] = 60, + [PDCH_MCS_6] = 78, + [PDCH_MCS_7] = 118, + [PDCH_MCS_8] = 142, + [PDCH_MCS_9] = 154 +}; diff --git a/src/osmo-bts-sysmo/femtobts.h b/src/osmo-bts-sysmo/femtobts.h new file mode 100644 index 0000000..7e45578 --- /dev/null +++ b/src/osmo-bts-sysmo/femtobts.h @@ -0,0 +1,57 @@ +#ifndef FEMTOBTS_H +#define FEMTOBTS_H + +#include +#include + +#include +#include + +#ifdef L1_HAS_RTP_MODE +/* This is temporarily disabled, as AMR has some bugs in RTP mode */ +//#define USE_L1_RTP_MODE /* Tell L1 to use RTP mode */ +#endif + +enum l1prim_type { + L1P_T_REQ, + L1P_T_CONF, + L1P_T_IND, +}; + +const enum l1prim_type femtobts_l1prim_type[GsmL1_PrimId_NUM]; +const struct value_string femtobts_l1prim_names[GsmL1_PrimId_NUM+1]; +const GsmL1_PrimId_t femtobts_l1prim_req2conf[GsmL1_PrimId_NUM]; + +const enum l1prim_type femtobts_sysprim_type[SuperFemto_PrimId_NUM]; +const struct value_string femtobts_sysprim_names[SuperFemto_PrimId_NUM+1]; +const SuperFemto_PrimId_t femtobts_sysprim_req2conf[SuperFemto_PrimId_NUM]; + +const struct value_string femtobts_l1sapi_names[GsmL1_Sapi_NUM+1]; +const struct value_string femtobts_l1status_names[GSML1_STATUS_NUM+1]; + +const struct value_string femtobts_tracef_names[29]; + +const struct value_string femtobts_tch_pl_names[15]; + +const struct value_string femtobts_dir_names[6]; + +enum pdch_cs { + PDCH_CS_1, + PDCH_CS_2, + PDCH_CS_3, + PDCH_CS_4, + PDCH_MCS_1, + PDCH_MCS_2, + PDCH_MCS_3, + PDCH_MCS_4, + PDCH_MCS_5, + PDCH_MCS_6, + PDCH_MCS_7, + PDCH_MCS_8, + PDCH_MCS_9, + _NUM_PDCH_CS +}; + +const uint8_t pdch_msu_size[_NUM_PDCH_CS]; + +#endif /* FEMTOBTS_H */ diff --git a/src/osmo-bts-sysmo/sysmo_l1_fwd.c b/src/osmo-bts-sysmo/sysmo_l1_fwd.c new file mode 100644 index 0000000..535a7f0 --- /dev/null +++ b/src/osmo-bts-sysmo/sysmo_l1_fwd.c @@ -0,0 +1,145 @@ +/* Interface handler for Sysmocom L1 (forwarding) */ + +/* (C) 2011 by Harald Welte + * + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "gprs_debug.h" +#include "sysmo_l1_if.h" + + +#define L1FWD_L1_PORT 9999 +#define L1FWD_SYS_PORT 9998 +#define L1FWD_TCH_PORT 9997 +#define L1FWD_PDTCH_PORT 9996 + +static const uint16_t fwd_udp_ports[] = { + [MQ_SYS_WRITE] = L1FWD_SYS_PORT, + [MQ_L1_WRITE] = L1FWD_L1_PORT, + [MQ_TCH_WRITE] = L1FWD_TCH_PORT, + [MQ_PDTCH_WRITE]= L1FWD_PDTCH_PORT, +}; + +static int fwd_read_cb(struct osmo_fd *ofd) +{ + struct msgb *msg = msgb_alloc_headroom(sizeof(SuperFemto_Prim_t) + 128, + 128, "udp_rx"); + struct femtol1_hdl *fl1h = ofd->data; + int rc; + + if (!msg) + return -ENOMEM; + + msg->l1h = msg->data; + rc = read(ofd->fd, msg->l1h, msgb_tailroom(msg)); + if (rc < 0) { + LOGP(DL1IF, LOGL_ERROR, "Short read from UDP\n"); + msgb_free(msg); + return rc; + } else if (rc == 0) { + LOGP(DL1IF, LOGL_ERROR, "Len=0 from UDP\n"); + msgb_free(msg); + return rc; + } + msgb_put(msg, rc); + + if (ofd->priv_nr == MQ_SYS_WRITE) + rc = l1if_handle_sysprim(fl1h, msg); + else + rc = l1if_handle_l1prim(ofd->priv_nr, fl1h, msg); + + return rc; +} + +static int prim_write_cb(struct osmo_fd *ofd, struct msgb *msg) +{ + /* write to the fd */ + return write(ofd->fd, msg->head, msg->len); +} + +int l1if_transport_open(int q, struct femtol1_hdl *fl1h) +{ + int rc; + char *bts_host = getenv("L1FWD_BTS_HOST"); + + printf("sizeof(GsmL1_Prim_t) = %zu\n", sizeof(GsmL1_Prim_t)); + printf("sizeof(SuperFemto_Prim_t) = %zu\n", sizeof(SuperFemto_Prim_t)); + + if (!bts_host) { + fprintf(stderr, "You have to set the L1FWD_BTS_HOST environment variable\n"); + exit(2); + } + + struct osmo_wqueue *wq = &fl1h->write_q[q]; + struct osmo_fd *ofd = &wq->bfd; + + osmo_wqueue_init(wq, 10); + wq->write_cb = prim_write_cb; + wq->read_cb = fwd_read_cb; + + ofd->data = fl1h; + ofd->priv_nr = q; + ofd->when |= BSC_FD_READ; + + rc = osmo_sock_init_ofd(ofd, AF_UNSPEC, SOCK_DGRAM, IPPROTO_UDP, + bts_host, fwd_udp_ports[q], + OSMO_SOCK_F_CONNECT); + if (rc < 0) + return rc; + + return 0; +} + +int l1if_transport_close(int q, struct femtol1_hdl *fl1h) +{ + struct osmo_wqueue *wq = &fl1h->write_q[q]; + struct osmo_fd *ofd = &wq->bfd; + + osmo_wqueue_clear(wq); + osmo_fd_unregister(ofd); + close(ofd->fd); + + return 0; +} diff --git a/src/osmo-bts-sysmo/sysmo_l1_hw.c b/src/osmo-bts-sysmo/sysmo_l1_hw.c new file mode 100644 index 0000000..8351d68 --- /dev/null +++ b/src/osmo-bts-sysmo/sysmo_l1_hw.c @@ -0,0 +1,216 @@ +/* Interface handler for Sysmocom L1 (real hardware) */ + +/* (C) 2011 by Harald Welte + * + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "gprs_debug.h" +#include "femtobts.h" +#include "sysmo_l1_if.h" + + +#ifdef HW_SYSMOBTS_V1 +#define DEV_SYS_DSP2ARM_NAME "/dev/msgq/femtobts_dsp2arm" +#define DEV_SYS_ARM2DSP_NAME "/dev/msgq/femtobts_arm2dsp" +#define DEV_L1_DSP2ARM_NAME "/dev/msgq/gsml1_dsp2arm" +#define DEV_L1_ARM2DSP_NAME "/dev/msgq/gsml1_arm2dsp" +#else +#define DEV_SYS_DSP2ARM_NAME "/dev/msgq/superfemto_dsp2arm" +#define DEV_SYS_ARM2DSP_NAME "/dev/msgq/superfemto_arm2dsp" +#define DEV_L1_DSP2ARM_NAME "/dev/msgq/gsml1_sig_dsp2arm" +#define DEV_L1_ARM2DSP_NAME "/dev/msgq/gsml1_sig_arm2dsp" + +#define DEV_TCH_DSP2ARM_NAME "/dev/msgq/gsml1_tch_dsp2arm" +#define DEV_TCH_ARM2DSP_NAME "/dev/msgq/gsml1_tch_arm2dsp" +#define DEV_PDTCH_DSP2ARM_NAME "/dev/msgq/gsml1_pdtch_dsp2arm" +#define DEV_PDTCH_ARM2DSP_NAME "/dev/msgq/gsml1_pdtch_arm2dsp" +#endif + +static const char *rd_devnames[] = { + [MQ_SYS_READ] = DEV_SYS_DSP2ARM_NAME, + [MQ_L1_READ] = DEV_L1_DSP2ARM_NAME, +#ifndef HW_SYSMOBTS_V1 + [MQ_TCH_READ] = DEV_TCH_DSP2ARM_NAME, + [MQ_PDTCH_READ] = DEV_PDTCH_DSP2ARM_NAME, +#endif +}; + +static const char *wr_devnames[] = { + [MQ_SYS_WRITE] = DEV_SYS_ARM2DSP_NAME, + [MQ_L1_WRITE] = DEV_L1_ARM2DSP_NAME, +#ifndef HW_SYSMOBTS_V1 + [MQ_TCH_WRITE] = DEV_TCH_ARM2DSP_NAME, + [MQ_PDTCH_WRITE]= DEV_PDTCH_ARM2DSP_NAME, +#endif +}; + +/* callback when there's something to read from the l1 msg_queue */ +static int l1if_fd_cb(struct osmo_fd *ofd, unsigned int what) +{ + //struct msgb *msg = l1p_msgb_alloc(); + struct msgb *msg = msgb_alloc_headroom(sizeof(SuperFemto_Prim_t) + 128, + 128, "1l_fd"); + struct femtol1_hdl *fl1h = ofd->data; + int rc; + + msg->l1h = msg->data; + rc = read(ofd->fd, msg->l1h, msgb_tailroom(msg)); + if (rc < 0) { + if (rc != -1) + LOGP(DL1IF, LOGL_ERROR, "error reading from L1 msg_queue: %s\n", + strerror(errno)); + msgb_free(msg); + return rc; + } + msgb_put(msg, rc); + + switch (ofd->priv_nr) { + case MQ_SYS_WRITE: + if (rc != sizeof(SuperFemto_Prim_t)) + LOGP(DL1IF, LOGL_NOTICE, "%u != " + "sizeof(SuperFemto_Prim_t)\n", rc); + return l1if_handle_sysprim(fl1h, msg); + case MQ_L1_WRITE: +#ifndef HW_SYSMOBTS_V1 + case MQ_TCH_WRITE: + case MQ_PDTCH_WRITE: +#endif + if (rc != sizeof(GsmL1_Prim_t)) + LOGP(DL1IF, LOGL_NOTICE, "%u != " + "sizeof(GsmL1_Prim_t)\n", rc); + return l1if_handle_l1prim(ofd->priv_nr, fl1h, msg); + default: + /* The compiler can't know that priv_nr is an enum. Assist. */ + LOGP(DL1IF, LOGL_FATAL, "writing on a wrong queue: %d\n", + ofd->priv_nr); + exit(0); + break; + } +}; + +/* callback when we can write to one of the l1 msg_queue devices */ +static int l1fd_write_cb(struct osmo_fd *ofd, struct msgb *msg) +{ + int rc; + + rc = write(ofd->fd, msg->l1h, msgb_l1len(msg)); + if (rc < 0) { + LOGP(DL1IF, LOGL_ERROR, "error writing to L1 msg_queue: %s\n", + strerror(errno)); + return rc; + } else if (rc < msg->len) { + LOGP(DL1IF, LOGL_ERROR, "short write to L1 msg_queue: " + "%u < %u\n", rc, msg->len); + return -EIO; + } + + return 0; +} + +int l1if_transport_open(int q, struct femtol1_hdl *hdl) +{ + int rc; + + /* Step 1: Open all msg_queue file descriptors */ + struct osmo_fd *read_ofd = &hdl->read_ofd[q]; + struct osmo_wqueue *wq = &hdl->write_q[q]; + struct osmo_fd *write_ofd = &hdl->write_q[q].bfd; + + rc = open(rd_devnames[q], O_RDONLY); + if (rc < 0) { + LOGP(DL1IF, LOGL_FATAL, "unable to open msg_queue: %s\n", + strerror(errno)); + return rc; + } + read_ofd->fd = rc; + read_ofd->priv_nr = q; + read_ofd->data = hdl; + read_ofd->cb = l1if_fd_cb; + read_ofd->when = BSC_FD_READ; + rc = osmo_fd_register(read_ofd); + if (rc < 0) { + close(read_ofd->fd); + read_ofd->fd = -1; + return rc; + } + + rc = open(wr_devnames[q], O_WRONLY); + if (rc < 0) { + LOGP(DL1IF, LOGL_FATAL, "unable to open msg_queue: %s\n", + strerror(errno)); + goto out_read; + } + osmo_wqueue_init(wq, 10); + wq->write_cb = l1fd_write_cb; + write_ofd->fd = rc; + write_ofd->priv_nr = q; + write_ofd->data = hdl; + write_ofd->when = BSC_FD_WRITE; + rc = osmo_fd_register(write_ofd); + if (rc < 0) { + close(write_ofd->fd); + write_ofd->fd = -1; + goto out_read; + } + + return 0; + +out_read: + close(hdl->read_ofd[q].fd); + osmo_fd_unregister(&hdl->read_ofd[q]); + + return rc; +} + +int l1if_transport_close(int q, struct femtol1_hdl *hdl) +{ + struct osmo_fd *read_ofd = &hdl->read_ofd[q]; + struct osmo_fd *write_ofd = &hdl->write_q[q].bfd; + + osmo_fd_unregister(read_ofd); + close(read_ofd->fd); + read_ofd->fd = -1; + + osmo_fd_unregister(write_ofd); + close(write_ofd->fd); + write_ofd->fd = -1; + + return 0; +} diff --git a/src/osmo-bts-sysmo/sysmo_l1_if.c b/src/osmo-bts-sysmo/sysmo_l1_if.c new file mode 100644 index 0000000..c7c54dd --- /dev/null +++ b/src/osmo-bts-sysmo/sysmo_l1_if.c @@ -0,0 +1,394 @@ + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +extern void *tall_pcu_ctx; + +uint32_t l1if_ts_to_hLayer2(uint8_t trx, uint8_t ts) +{ + return (ts << 16) | (trx << 24); +} + +/* allocate a msgb containing a GsmL1_Prim_t */ +struct msgb *l1p_msgb_alloc(void) +{ + struct msgb *msg = msgb_alloc(sizeof(GsmL1_Prim_t), "l1_prim"); + + if (msg) + msg->l1h = msgb_put(msg, sizeof(GsmL1_Prim_t)); + + return msg; +} + +static int l1if_req_pdch(struct femtol1_hdl *fl1h, struct msgb *msg) +{ + struct osmo_wqueue *wqueue = &fl1h->write_q[MQ_PDTCH_WRITE]; + + if (osmo_wqueue_enqueue(wqueue, msg) != 0) { + LOGP(DL1IF, LOGL_ERROR, "PDTCH queue full. dropping message.\n"); + msgb_free(msg); + } + + return 0; +} + +static void *prim_init(GsmL1_Prim_t *prim, GsmL1_PrimId_t id, struct femtol1_hdl *gl1) +{ + prim->id = id; + + /* for some reason the hLayer1 field is not always at the same position + * in the GsmL1_Prim_t, so we have to have this ugly case statement here... */ + switch (id) { + case GsmL1_PrimId_MphInitReq: + //prim->u.mphInitReq.hLayer1 = gl1->hLayer1; + break; + case GsmL1_PrimId_MphCloseReq: + prim->u.mphCloseReq.hLayer1 = gl1->hLayer1; + break; + case GsmL1_PrimId_MphConnectReq: + prim->u.mphConnectReq.hLayer1 = gl1->hLayer1; + break; + case GsmL1_PrimId_MphDisconnectReq: + prim->u.mphDisconnectReq.hLayer1 = gl1->hLayer1; + break; + case GsmL1_PrimId_MphActivateReq: + prim->u.mphActivateReq.hLayer1 = gl1->hLayer1; + break; + case GsmL1_PrimId_MphDeactivateReq: + prim->u.mphDeactivateReq.hLayer1 = gl1->hLayer1; + break; + case GsmL1_PrimId_MphConfigReq: + prim->u.mphConfigReq.hLayer1 = gl1->hLayer1; + break; + case GsmL1_PrimId_MphMeasureReq: + prim->u.mphMeasureReq.hLayer1 = gl1->hLayer1; + break; + case GsmL1_PrimId_MphInitCnf: + case GsmL1_PrimId_MphCloseCnf: + case GsmL1_PrimId_MphConnectCnf: + case GsmL1_PrimId_MphDisconnectCnf: + case GsmL1_PrimId_MphActivateCnf: + case GsmL1_PrimId_MphDeactivateCnf: + case GsmL1_PrimId_MphConfigCnf: + case GsmL1_PrimId_MphMeasureCnf: + break; + case GsmL1_PrimId_MphTimeInd: + break; + case GsmL1_PrimId_MphSyncInd: + break; + case GsmL1_PrimId_PhEmptyFrameReq: + prim->u.phEmptyFrameReq.hLayer1 = gl1->hLayer1; + break; + case GsmL1_PrimId_PhDataReq: + prim->u.phDataReq.hLayer1 = gl1->hLayer1; + break; + case GsmL1_PrimId_PhConnectInd: + break; + case GsmL1_PrimId_PhReadyToSendInd: + break; + case GsmL1_PrimId_PhDataInd: + break; + case GsmL1_PrimId_PhRaInd: + break; + default: + LOGP(DL1IF, LOGL_ERROR, "unknown L1 primitive %u\n", id); + break; + } + return &prim->u; +} + +struct sapi_dir { + GsmL1_Sapi_t sapi; + GsmL1_Dir_t dir; +}; + +static const struct sapi_dir pdtch_sapis[] = { + { GsmL1_Sapi_Pdtch, GsmL1_Dir_TxDownlink }, + { GsmL1_Sapi_Pdtch, GsmL1_Dir_RxUplink }, + { GsmL1_Sapi_Ptcch, GsmL1_Dir_TxDownlink }, + { GsmL1_Sapi_Prach, GsmL1_Dir_RxUplink }, +#if 0 + { GsmL1_Sapi_Ptcch, GsmL1_Dir_RxUplink }, + { GsmL1_Sapi_Pacch, GsmL1_Dir_TxDownlink }, +#endif +}; + + +/* connect PDTCH */ +int l1if_connect_pdch(void *obj, uint8_t ts) +{ + struct femtol1_hdl *fl1h = obj; + struct msgb *msg = l1p_msgb_alloc(); + GsmL1_MphConnectReq_t *cr; + + cr = prim_init(msgb_l1prim(msg), GsmL1_PrimId_MphConnectReq, fl1h); + cr->u8Tn = ts; + cr->logChComb = GsmL1_LogChComb_XIII; + + return l1if_req_pdch(fl1h, msg); +} + +static int handle_ph_readytosend_ind(struct femtol1_hdl *fl1h, + GsmL1_PhReadyToSendInd_t *rts_ind) +{ + struct gsm_time g_time; + int rc = 0; + + gsm_fn2gsmtime(&g_time, rts_ind->u32Fn); + + DEBUGP(DL1IF, "Rx PH-RTS.ind %02u/%02u/%02u SAPI=%s\n", + g_time.t1, g_time.t2, g_time.t3, + get_value_string(femtobts_l1sapi_names, rts_ind->sapi)); + + switch (rts_ind->sapi) { + case GsmL1_Sapi_Pdtch: + case GsmL1_Sapi_Pacch: + rc = pcu_rx_rts_req_pdtch((long)fl1h->priv, rts_ind->u8Tn, + rts_ind->u16Arfcn, rts_ind->u32Fn, rts_ind->u8BlockNbr); + case GsmL1_Sapi_Ptcch: + // FIXME + default: + break; + } + + return rc; +} + +static void get_meas(struct pcu_l1_meas *meas, const GsmL1_MeasParam_t *l1_meas) +{ + meas->rssi = (int8_t) (l1_meas->fRssi); + meas->have_rssi = 1; + meas->ber = (uint8_t) (l1_meas->fBer * 100); + meas->have_ber = 1; + meas->bto = (int16_t) (l1_meas->i16BurstTiming); + meas->have_bto = 1; + meas->link_qual = (int16_t) (l1_meas->fLinkQuality); + meas->have_link_qual = 1; +} + +static int handle_ph_data_ind(struct femtol1_hdl *fl1h, + GsmL1_PhDataInd_t *data_ind, struct msgb *l1p_msg) +{ + int rc = 0; + struct pcu_l1_meas meas = {0}; + + DEBUGP(DL1IF, "Rx PH-DATA.ind %s (hL2 %08x): %s\n", + get_value_string(femtobts_l1sapi_names, data_ind->sapi), + data_ind->hLayer2, + osmo_hexdump(data_ind->msgUnitParam.u8Buffer, + data_ind->msgUnitParam.u8Size)); + + pcu_rx_block_time(data_ind->u16Arfcn, data_ind->u32Fn, data_ind->u8Tn); + + /* + * TODO: Add proper bad frame handling here. This could be used + * to switch the used CS. Avoid a crash with the PCU right now + * feed "0 - 1" amount of data. + */ + if (data_ind->msgUnitParam.u8Size == 0) + return -1; + + gsmtap_send(fl1h->gsmtap, data_ind->u16Arfcn | GSMTAP_ARFCN_F_UPLINK, + data_ind->u8Tn, GSMTAP_CHANNEL_PACCH, 0, + data_ind->u32Fn, 0, 0, data_ind->msgUnitParam.u8Buffer+1, + data_ind->msgUnitParam.u8Size-1); + + get_meas(&meas, &data_ind->measParam); + + switch (data_ind->sapi) { + case GsmL1_Sapi_Pdtch: + case GsmL1_Sapi_Pacch: + /* drop incomplete UL block */ + if (data_ind->msgUnitParam.u8Buffer[0] + != GsmL1_PdtchPlType_Full) + break; + /* PDTCH / PACCH frame handling */ + pcu_rx_data_ind_pdtch((long)fl1h->priv, data_ind->u8Tn, + data_ind->msgUnitParam.u8Buffer + 1, + data_ind->msgUnitParam.u8Size - 1, + data_ind->u32Fn, + &meas); + break; + case GsmL1_Sapi_Ptcch: + // FIXME + break; + default: + LOGP(DL1IF, LOGL_NOTICE, "Rx PH-DATA.ind for unknown L1 SAPI %s\n", + get_value_string(femtobts_l1sapi_names, data_ind->sapi)); + break; + } + + return rc; +} + +#define MIN_QUAL_RACH 5.0f + +static int handle_ph_ra_ind(struct femtol1_hdl *fl1h, GsmL1_PhRaInd_t *ra_ind) +{ + uint8_t acc_delay; + + pcu_rx_ra_time(ra_ind->u16Arfcn, ra_ind->u32Fn, ra_ind->u8Tn); + + if (ra_ind->measParam.fLinkQuality < MIN_QUAL_RACH) + return 0; + + DEBUGP(DL1IF, "Rx PH-RA.ind"); + + /* check for under/overflow / sign */ + if (ra_ind->measParam.i16BurstTiming < 0) + acc_delay = 0; + else + acc_delay = ra_ind->measParam.i16BurstTiming >> 2; + + LOGP(DL1IF, LOGL_NOTICE, "got (P)RACH request, TA = %u (ignored)\n", + acc_delay); + +#warning "The (P)RACH request is just dropped here" + +#if 0 + if (acc_delay > bts->max_ta) { + LOGP(DL1C, LOGL_INFO, "ignoring RACH request %u > max_ta(%u)\n", + acc_delay, btsb->max_ta); + return 0; + } +#endif + + return 0; +} + + +/* handle any random indication from the L1 */ +int l1if_handle_l1prim(int wq, struct femtol1_hdl *fl1h, struct msgb *msg) +{ + GsmL1_Prim_t *l1p = msgb_l1prim(msg); + int rc = 0; + + LOGP(DL1IF, LOGL_DEBUG, "Rx L1 prim %s on queue %d\n", + get_value_string(femtobts_l1prim_names, l1p->id), wq); + + switch (l1p->id) { +#if 0 + case GsmL1_PrimId_MphTimeInd: + rc = handle_mph_time_ind(fl1h, &l1p->u.mphTimeInd); + break; + case GsmL1_PrimId_MphSyncInd: + break; + case GsmL1_PrimId_PhConnectInd: + break; +#endif + case GsmL1_PrimId_PhReadyToSendInd: + rc = handle_ph_readytosend_ind(fl1h, &l1p->u.phReadyToSendInd); + break; + case GsmL1_PrimId_PhDataInd: + rc = handle_ph_data_ind(fl1h, &l1p->u.phDataInd, msg); + break; + case GsmL1_PrimId_PhRaInd: + rc = handle_ph_ra_ind(fl1h, &l1p->u.phRaInd); + break; + default: + break; + } + + msgb_free(msg); + + return rc; +} + +int l1if_handle_sysprim(struct femtol1_hdl *fl1h, struct msgb *msg) +{ + return -ENOTSUP; +} + +/* send packet data request to L1 */ +int l1if_pdch_req(void *obj, uint8_t ts, int is_ptcch, uint32_t fn, + uint16_t arfcn, uint8_t block_nr, uint8_t *data, uint8_t len) +{ + struct femtol1_hdl *fl1h = obj; + struct msgb *msg; + GsmL1_Prim_t *l1p; + GsmL1_PhDataReq_t *data_req; + GsmL1_MsgUnitParam_t *msu_param; + struct gsm_time g_time; + + gsm_fn2gsmtime(&g_time, fn); + + DEBUGP(DL1IF, "TX packet data %02u/%02u/%02u is_ptcch=%d ts=%d " + "block_nr=%d, arfcn=%d, len=%d\n", g_time.t1, g_time.t2, + g_time.t3, is_ptcch, ts, block_nr, arfcn, len); + + msg = l1p_msgb_alloc(); + l1p = msgb_l1prim(msg); + l1p->id = GsmL1_PrimId_PhDataReq; + data_req = &l1p->u.phDataReq; + data_req->hLayer1 = fl1h->hLayer1; + data_req->sapi = (is_ptcch) ? GsmL1_Sapi_Ptcch : GsmL1_Sapi_Pdtch; + data_req->subCh = GsmL1_SubCh_NA; + data_req->u8BlockNbr = block_nr; + data_req->u8Tn = ts; + data_req->u32Fn = fn; + msu_param = &data_req->msgUnitParam; + msu_param->u8Size = len; + memcpy(msu_param->u8Buffer, data, len); + + gsmtap_send(fl1h->gsmtap, arfcn, data_req->u8Tn, GSMTAP_CHANNEL_PACCH, + 0, data_req->u32Fn, 0, 0, + data_req->msgUnitParam.u8Buffer, + data_req->msgUnitParam.u8Size); + + + /* transmit */ + if (osmo_wqueue_enqueue(&fl1h->write_q[MQ_PDTCH_WRITE], msg) != 0) { + LOGP(DL1IF, LOGL_ERROR, "PDTCH queue full. dropping message.\n"); + msgb_free(msg); + } + + return 0; +} + +void *l1if_open_pdch(void *priv, uint32_t hlayer1, struct gsmtap_inst *gsmtap) +{ + struct femtol1_hdl *fl1h; + int rc; + + fl1h = talloc_zero(tall_pcu_ctx, struct femtol1_hdl); + if (!fl1h) + return NULL; + + fl1h->hLayer1 = hlayer1; + fl1h->priv = priv; + fl1h->clk_cal = 0; + /* default clock source: OCXO */ + fl1h->clk_src = SuperFemto_ClkSrcId_Ocxo; + + rc = l1if_transport_open(MQ_PDTCH_WRITE, fl1h); + if (rc < 0) { + talloc_free(fl1h); + return NULL; + } + + fl1h->gsmtap = gsmtap; + + return fl1h; +} + +int l1if_close_pdch(void *obj) +{ + struct femtol1_hdl *fl1h = obj; + if (fl1h) + l1if_transport_close(MQ_PDTCH_WRITE, fl1h); + talloc_free(fl1h); + return 0; +} + diff --git a/src/osmo-bts-sysmo/sysmo_l1_if.h b/src/osmo-bts-sysmo/sysmo_l1_if.h new file mode 100644 index 0000000..6b50d4e --- /dev/null +++ b/src/osmo-bts-sysmo/sysmo_l1_if.h @@ -0,0 +1,91 @@ +#ifndef _SYSMO_L1_IF_H +#define _SYSMO_L1_IF_H + +#include +#include +#include +#include +#include "femtobts.h" + +enum { + MQ_SYS_READ, + MQ_L1_READ, +#ifndef HW_SYSMOBTS_V1 + MQ_TCH_READ, + MQ_PDTCH_READ, +#endif + _NUM_MQ_READ +}; + +enum { + MQ_SYS_WRITE, + MQ_L1_WRITE, +#ifndef HW_SYSMOBTS_V1 + MQ_TCH_WRITE, + MQ_PDTCH_WRITE, +#endif + _NUM_MQ_WRITE +}; + +struct femtol1_hdl { + struct gsm_time gsm_time; + uint32_t hLayer1; /* handle to the L1 instance in the DSP */ + uint32_t dsp_trace_f; + int clk_cal; + uint8_t clk_src; + struct llist_head wlc_list; + + struct gsmtap_inst *gsmtap; + uint32_t gsmtap_sapi_mask; + + void *priv; /* user reference */ + + struct osmo_timer_list alive_timer; + unsigned int alive_prim_cnt; + + struct osmo_fd read_ofd[_NUM_MQ_READ]; /* osmo file descriptors */ + struct osmo_wqueue write_q[_NUM_MQ_WRITE]; + + struct { + uint8_t dsp_version[3]; + uint8_t fpga_version[3]; + uint32_t band_support; /* bitmask of GSM_BAND_* */ + } hw_info; +}; + +#define msgb_l1prim(msg) ((GsmL1_Prim_t *)(msg)->l1h) +#define msgb_sysprim(msg) ((SuperFemto_Prim_t *)(msg)->l1h) + +typedef int l1if_compl_cb(struct msgb *l1_msg, void *data); + +/* send a request primitive to the L1 and schedule completion call-back */ +int l1if_req_compl(struct femtol1_hdl *fl1h, struct msgb *msg, + int is_system_prim, l1if_compl_cb *cb, void *data); + +int l1if_reset(struct femtol1_hdl *hdl); +int l1if_activate_rf(struct femtol1_hdl *hdl, int on); +int l1if_set_trace_flags(struct femtol1_hdl *hdl, uint32_t flags); +int l1if_set_txpower(struct femtol1_hdl *fl1h, float tx_power); + +struct msgb *l1p_msgb_alloc(void); +struct msgb *sysp_msgb_alloc(void); + +uint32_t l1if_lchan_to_hLayer2(struct gsm_lchan *lchan); +struct gsm_lchan *l1if_hLayer2_to_lchan(struct gsm_bts_trx *trx, uint32_t hLayer2); + +int l1if_handle_sysprim(struct femtol1_hdl *fl1h, struct msgb *msg); +int l1if_handle_l1prim(int wq, struct femtol1_hdl *fl1h, struct msgb *msg); + +/* tch.c */ +int l1if_tch_rx(struct gsm_lchan *lchan, struct msgb *l1p_msg); +int l1if_tch_fill(struct gsm_lchan *lchan, uint8_t *l1_buffer); +struct msgb *gen_empty_tch_msg(struct gsm_lchan *lchan); + +/* + * The implementation of these functions is selected by either compiling and + * linking sysmo_l1_hw.c or sysmo_l1_fwd.c + */ +int l1if_transport_open(int q, struct femtol1_hdl *hdl); +int l1if_transport_close(int q, struct femtol1_hdl *hdl); + +#endif /* _SYSMO_L1_IF_H */ diff --git a/src/sysmo_l1_fwd.c b/src/sysmo_l1_fwd.c deleted file mode 100644 index 535a7f0..0000000 --- a/src/sysmo_l1_fwd.c +++ /dev/null @@ -1,145 +0,0 @@ -/* Interface handler for Sysmocom L1 (forwarding) */ - -/* (C) 2011 by Harald Welte - * - * All Rights Reserved - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - * - */ - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "gprs_debug.h" -#include "sysmo_l1_if.h" - - -#define L1FWD_L1_PORT 9999 -#define L1FWD_SYS_PORT 9998 -#define L1FWD_TCH_PORT 9997 -#define L1FWD_PDTCH_PORT 9996 - -static const uint16_t fwd_udp_ports[] = { - [MQ_SYS_WRITE] = L1FWD_SYS_PORT, - [MQ_L1_WRITE] = L1FWD_L1_PORT, - [MQ_TCH_WRITE] = L1FWD_TCH_PORT, - [MQ_PDTCH_WRITE]= L1FWD_PDTCH_PORT, -}; - -static int fwd_read_cb(struct osmo_fd *ofd) -{ - struct msgb *msg = msgb_alloc_headroom(sizeof(SuperFemto_Prim_t) + 128, - 128, "udp_rx"); - struct femtol1_hdl *fl1h = ofd->data; - int rc; - - if (!msg) - return -ENOMEM; - - msg->l1h = msg->data; - rc = read(ofd->fd, msg->l1h, msgb_tailroom(msg)); - if (rc < 0) { - LOGP(DL1IF, LOGL_ERROR, "Short read from UDP\n"); - msgb_free(msg); - return rc; - } else if (rc == 0) { - LOGP(DL1IF, LOGL_ERROR, "Len=0 from UDP\n"); - msgb_free(msg); - return rc; - } - msgb_put(msg, rc); - - if (ofd->priv_nr == MQ_SYS_WRITE) - rc = l1if_handle_sysprim(fl1h, msg); - else - rc = l1if_handle_l1prim(ofd->priv_nr, fl1h, msg); - - return rc; -} - -static int prim_write_cb(struct osmo_fd *ofd, struct msgb *msg) -{ - /* write to the fd */ - return write(ofd->fd, msg->head, msg->len); -} - -int l1if_transport_open(int q, struct femtol1_hdl *fl1h) -{ - int rc; - char *bts_host = getenv("L1FWD_BTS_HOST"); - - printf("sizeof(GsmL1_Prim_t) = %zu\n", sizeof(GsmL1_Prim_t)); - printf("sizeof(SuperFemto_Prim_t) = %zu\n", sizeof(SuperFemto_Prim_t)); - - if (!bts_host) { - fprintf(stderr, "You have to set the L1FWD_BTS_HOST environment variable\n"); - exit(2); - } - - struct osmo_wqueue *wq = &fl1h->write_q[q]; - struct osmo_fd *ofd = &wq->bfd; - - osmo_wqueue_init(wq, 10); - wq->write_cb = prim_write_cb; - wq->read_cb = fwd_read_cb; - - ofd->data = fl1h; - ofd->priv_nr = q; - ofd->when |= BSC_FD_READ; - - rc = osmo_sock_init_ofd(ofd, AF_UNSPEC, SOCK_DGRAM, IPPROTO_UDP, - bts_host, fwd_udp_ports[q], - OSMO_SOCK_F_CONNECT); - if (rc < 0) - return rc; - - return 0; -} - -int l1if_transport_close(int q, struct femtol1_hdl *fl1h) -{ - struct osmo_wqueue *wq = &fl1h->write_q[q]; - struct osmo_fd *ofd = &wq->bfd; - - osmo_wqueue_clear(wq); - osmo_fd_unregister(ofd); - close(ofd->fd); - - return 0; -} diff --git a/src/sysmo_l1_hw.c b/src/sysmo_l1_hw.c deleted file mode 100644 index 8351d68..0000000 --- a/src/sysmo_l1_hw.c +++ /dev/null @@ -1,216 +0,0 @@ -/* Interface handler for Sysmocom L1 (real hardware) */ - -/* (C) 2011 by Harald Welte - * - * All Rights Reserved - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - * - */ - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "gprs_debug.h" -#include "femtobts.h" -#include "sysmo_l1_if.h" - - -#ifdef HW_SYSMOBTS_V1 -#define DEV_SYS_DSP2ARM_NAME "/dev/msgq/femtobts_dsp2arm" -#define DEV_SYS_ARM2DSP_NAME "/dev/msgq/femtobts_arm2dsp" -#define DEV_L1_DSP2ARM_NAME "/dev/msgq/gsml1_dsp2arm" -#define DEV_L1_ARM2DSP_NAME "/dev/msgq/gsml1_arm2dsp" -#else -#define DEV_SYS_DSP2ARM_NAME "/dev/msgq/superfemto_dsp2arm" -#define DEV_SYS_ARM2DSP_NAME "/dev/msgq/superfemto_arm2dsp" -#define DEV_L1_DSP2ARM_NAME "/dev/msgq/gsml1_sig_dsp2arm" -#define DEV_L1_ARM2DSP_NAME "/dev/msgq/gsml1_sig_arm2dsp" - -#define DEV_TCH_DSP2ARM_NAME "/dev/msgq/gsml1_tch_dsp2arm" -#define DEV_TCH_ARM2DSP_NAME "/dev/msgq/gsml1_tch_arm2dsp" -#define DEV_PDTCH_DSP2ARM_NAME "/dev/msgq/gsml1_pdtch_dsp2arm" -#define DEV_PDTCH_ARM2DSP_NAME "/dev/msgq/gsml1_pdtch_arm2dsp" -#endif - -static const char *rd_devnames[] = { - [MQ_SYS_READ] = DEV_SYS_DSP2ARM_NAME, - [MQ_L1_READ] = DEV_L1_DSP2ARM_NAME, -#ifndef HW_SYSMOBTS_V1 - [MQ_TCH_READ] = DEV_TCH_DSP2ARM_NAME, - [MQ_PDTCH_READ] = DEV_PDTCH_DSP2ARM_NAME, -#endif -}; - -static const char *wr_devnames[] = { - [MQ_SYS_WRITE] = DEV_SYS_ARM2DSP_NAME, - [MQ_L1_WRITE] = DEV_L1_ARM2DSP_NAME, -#ifndef HW_SYSMOBTS_V1 - [MQ_TCH_WRITE] = DEV_TCH_ARM2DSP_NAME, - [MQ_PDTCH_WRITE]= DEV_PDTCH_ARM2DSP_NAME, -#endif -}; - -/* callback when there's something to read from the l1 msg_queue */ -static int l1if_fd_cb(struct osmo_fd *ofd, unsigned int what) -{ - //struct msgb *msg = l1p_msgb_alloc(); - struct msgb *msg = msgb_alloc_headroom(sizeof(SuperFemto_Prim_t) + 128, - 128, "1l_fd"); - struct femtol1_hdl *fl1h = ofd->data; - int rc; - - msg->l1h = msg->data; - rc = read(ofd->fd, msg->l1h, msgb_tailroom(msg)); - if (rc < 0) { - if (rc != -1) - LOGP(DL1IF, LOGL_ERROR, "error reading from L1 msg_queue: %s\n", - strerror(errno)); - msgb_free(msg); - return rc; - } - msgb_put(msg, rc); - - switch (ofd->priv_nr) { - case MQ_SYS_WRITE: - if (rc != sizeof(SuperFemto_Prim_t)) - LOGP(DL1IF, LOGL_NOTICE, "%u != " - "sizeof(SuperFemto_Prim_t)\n", rc); - return l1if_handle_sysprim(fl1h, msg); - case MQ_L1_WRITE: -#ifndef HW_SYSMOBTS_V1 - case MQ_TCH_WRITE: - case MQ_PDTCH_WRITE: -#endif - if (rc != sizeof(GsmL1_Prim_t)) - LOGP(DL1IF, LOGL_NOTICE, "%u != " - "sizeof(GsmL1_Prim_t)\n", rc); - return l1if_handle_l1prim(ofd->priv_nr, fl1h, msg); - default: - /* The compiler can't know that priv_nr is an enum. Assist. */ - LOGP(DL1IF, LOGL_FATAL, "writing on a wrong queue: %d\n", - ofd->priv_nr); - exit(0); - break; - } -}; - -/* callback when we can write to one of the l1 msg_queue devices */ -static int l1fd_write_cb(struct osmo_fd *ofd, struct msgb *msg) -{ - int rc; - - rc = write(ofd->fd, msg->l1h, msgb_l1len(msg)); - if (rc < 0) { - LOGP(DL1IF, LOGL_ERROR, "error writing to L1 msg_queue: %s\n", - strerror(errno)); - return rc; - } else if (rc < msg->len) { - LOGP(DL1IF, LOGL_ERROR, "short write to L1 msg_queue: " - "%u < %u\n", rc, msg->len); - return -EIO; - } - - return 0; -} - -int l1if_transport_open(int q, struct femtol1_hdl *hdl) -{ - int rc; - - /* Step 1: Open all msg_queue file descriptors */ - struct osmo_fd *read_ofd = &hdl->read_ofd[q]; - struct osmo_wqueue *wq = &hdl->write_q[q]; - struct osmo_fd *write_ofd = &hdl->write_q[q].bfd; - - rc = open(rd_devnames[q], O_RDONLY); - if (rc < 0) { - LOGP(DL1IF, LOGL_FATAL, "unable to open msg_queue: %s\n", - strerror(errno)); - return rc; - } - read_ofd->fd = rc; - read_ofd->priv_nr = q; - read_ofd->data = hdl; - read_ofd->cb = l1if_fd_cb; - read_ofd->when = BSC_FD_READ; - rc = osmo_fd_register(read_ofd); - if (rc < 0) { - close(read_ofd->fd); - read_ofd->fd = -1; - return rc; - } - - rc = open(wr_devnames[q], O_WRONLY); - if (rc < 0) { - LOGP(DL1IF, LOGL_FATAL, "unable to open msg_queue: %s\n", - strerror(errno)); - goto out_read; - } - osmo_wqueue_init(wq, 10); - wq->write_cb = l1fd_write_cb; - write_ofd->fd = rc; - write_ofd->priv_nr = q; - write_ofd->data = hdl; - write_ofd->when = BSC_FD_WRITE; - rc = osmo_fd_register(write_ofd); - if (rc < 0) { - close(write_ofd->fd); - write_ofd->fd = -1; - goto out_read; - } - - return 0; - -out_read: - close(hdl->read_ofd[q].fd); - osmo_fd_unregister(&hdl->read_ofd[q]); - - return rc; -} - -int l1if_transport_close(int q, struct femtol1_hdl *hdl) -{ - struct osmo_fd *read_ofd = &hdl->read_ofd[q]; - struct osmo_fd *write_ofd = &hdl->write_q[q].bfd; - - osmo_fd_unregister(read_ofd); - close(read_ofd->fd); - read_ofd->fd = -1; - - osmo_fd_unregister(write_ofd); - close(write_ofd->fd); - write_ofd->fd = -1; - - return 0; -} diff --git a/src/sysmo_l1_if.c b/src/sysmo_l1_if.c deleted file mode 100644 index c7c54dd..0000000 --- a/src/sysmo_l1_if.c +++ /dev/null @@ -1,394 +0,0 @@ - -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -extern void *tall_pcu_ctx; - -uint32_t l1if_ts_to_hLayer2(uint8_t trx, uint8_t ts) -{ - return (ts << 16) | (trx << 24); -} - -/* allocate a msgb containing a GsmL1_Prim_t */ -struct msgb *l1p_msgb_alloc(void) -{ - struct msgb *msg = msgb_alloc(sizeof(GsmL1_Prim_t), "l1_prim"); - - if (msg) - msg->l1h = msgb_put(msg, sizeof(GsmL1_Prim_t)); - - return msg; -} - -static int l1if_req_pdch(struct femtol1_hdl *fl1h, struct msgb *msg) -{ - struct osmo_wqueue *wqueue = &fl1h->write_q[MQ_PDTCH_WRITE]; - - if (osmo_wqueue_enqueue(wqueue, msg) != 0) { - LOGP(DL1IF, LOGL_ERROR, "PDTCH queue full. dropping message.\n"); - msgb_free(msg); - } - - return 0; -} - -static void *prim_init(GsmL1_Prim_t *prim, GsmL1_PrimId_t id, struct femtol1_hdl *gl1) -{ - prim->id = id; - - /* for some reason the hLayer1 field is not always at the same position - * in the GsmL1_Prim_t, so we have to have this ugly case statement here... */ - switch (id) { - case GsmL1_PrimId_MphInitReq: - //prim->u.mphInitReq.hLayer1 = gl1->hLayer1; - break; - case GsmL1_PrimId_MphCloseReq: - prim->u.mphCloseReq.hLayer1 = gl1->hLayer1; - break; - case GsmL1_PrimId_MphConnectReq: - prim->u.mphConnectReq.hLayer1 = gl1->hLayer1; - break; - case GsmL1_PrimId_MphDisconnectReq: - prim->u.mphDisconnectReq.hLayer1 = gl1->hLayer1; - break; - case GsmL1_PrimId_MphActivateReq: - prim->u.mphActivateReq.hLayer1 = gl1->hLayer1; - break; - case GsmL1_PrimId_MphDeactivateReq: - prim->u.mphDeactivateReq.hLayer1 = gl1->hLayer1; - break; - case GsmL1_PrimId_MphConfigReq: - prim->u.mphConfigReq.hLayer1 = gl1->hLayer1; - break; - case GsmL1_PrimId_MphMeasureReq: - prim->u.mphMeasureReq.hLayer1 = gl1->hLayer1; - break; - case GsmL1_PrimId_MphInitCnf: - case GsmL1_PrimId_MphCloseCnf: - case GsmL1_PrimId_MphConnectCnf: - case GsmL1_PrimId_MphDisconnectCnf: - case GsmL1_PrimId_MphActivateCnf: - case GsmL1_PrimId_MphDeactivateCnf: - case GsmL1_PrimId_MphConfigCnf: - case GsmL1_PrimId_MphMeasureCnf: - break; - case GsmL1_PrimId_MphTimeInd: - break; - case GsmL1_PrimId_MphSyncInd: - break; - case GsmL1_PrimId_PhEmptyFrameReq: - prim->u.phEmptyFrameReq.hLayer1 = gl1->hLayer1; - break; - case GsmL1_PrimId_PhDataReq: - prim->u.phDataReq.hLayer1 = gl1->hLayer1; - break; - case GsmL1_PrimId_PhConnectInd: - break; - case GsmL1_PrimId_PhReadyToSendInd: - break; - case GsmL1_PrimId_PhDataInd: - break; - case GsmL1_PrimId_PhRaInd: - break; - default: - LOGP(DL1IF, LOGL_ERROR, "unknown L1 primitive %u\n", id); - break; - } - return &prim->u; -} - -struct sapi_dir { - GsmL1_Sapi_t sapi; - GsmL1_Dir_t dir; -}; - -static const struct sapi_dir pdtch_sapis[] = { - { GsmL1_Sapi_Pdtch, GsmL1_Dir_TxDownlink }, - { GsmL1_Sapi_Pdtch, GsmL1_Dir_RxUplink }, - { GsmL1_Sapi_Ptcch, GsmL1_Dir_TxDownlink }, - { GsmL1_Sapi_Prach, GsmL1_Dir_RxUplink }, -#if 0 - { GsmL1_Sapi_Ptcch, GsmL1_Dir_RxUplink }, - { GsmL1_Sapi_Pacch, GsmL1_Dir_TxDownlink }, -#endif -}; - - -/* connect PDTCH */ -int l1if_connect_pdch(void *obj, uint8_t ts) -{ - struct femtol1_hdl *fl1h = obj; - struct msgb *msg = l1p_msgb_alloc(); - GsmL1_MphConnectReq_t *cr; - - cr = prim_init(msgb_l1prim(msg), GsmL1_PrimId_MphConnectReq, fl1h); - cr->u8Tn = ts; - cr->logChComb = GsmL1_LogChComb_XIII; - - return l1if_req_pdch(fl1h, msg); -} - -static int handle_ph_readytosend_ind(struct femtol1_hdl *fl1h, - GsmL1_PhReadyToSendInd_t *rts_ind) -{ - struct gsm_time g_time; - int rc = 0; - - gsm_fn2gsmtime(&g_time, rts_ind->u32Fn); - - DEBUGP(DL1IF, "Rx PH-RTS.ind %02u/%02u/%02u SAPI=%s\n", - g_time.t1, g_time.t2, g_time.t3, - get_value_string(femtobts_l1sapi_names, rts_ind->sapi)); - - switch (rts_ind->sapi) { - case GsmL1_Sapi_Pdtch: - case GsmL1_Sapi_Pacch: - rc = pcu_rx_rts_req_pdtch((long)fl1h->priv, rts_ind->u8Tn, - rts_ind->u16Arfcn, rts_ind->u32Fn, rts_ind->u8BlockNbr); - case GsmL1_Sapi_Ptcch: - // FIXME - default: - break; - } - - return rc; -} - -static void get_meas(struct pcu_l1_meas *meas, const GsmL1_MeasParam_t *l1_meas) -{ - meas->rssi = (int8_t) (l1_meas->fRssi); - meas->have_rssi = 1; - meas->ber = (uint8_t) (l1_meas->fBer * 100); - meas->have_ber = 1; - meas->bto = (int16_t) (l1_meas->i16BurstTiming); - meas->have_bto = 1; - meas->link_qual = (int16_t) (l1_meas->fLinkQuality); - meas->have_link_qual = 1; -} - -static int handle_ph_data_ind(struct femtol1_hdl *fl1h, - GsmL1_PhDataInd_t *data_ind, struct msgb *l1p_msg) -{ - int rc = 0; - struct pcu_l1_meas meas = {0}; - - DEBUGP(DL1IF, "Rx PH-DATA.ind %s (hL2 %08x): %s\n", - get_value_string(femtobts_l1sapi_names, data_ind->sapi), - data_ind->hLayer2, - osmo_hexdump(data_ind->msgUnitParam.u8Buffer, - data_ind->msgUnitParam.u8Size)); - - pcu_rx_block_time(data_ind->u16Arfcn, data_ind->u32Fn, data_ind->u8Tn); - - /* - * TODO: Add proper bad frame handling here. This could be used - * to switch the used CS. Avoid a crash with the PCU right now - * feed "0 - 1" amount of data. - */ - if (data_ind->msgUnitParam.u8Size == 0) - return -1; - - gsmtap_send(fl1h->gsmtap, data_ind->u16Arfcn | GSMTAP_ARFCN_F_UPLINK, - data_ind->u8Tn, GSMTAP_CHANNEL_PACCH, 0, - data_ind->u32Fn, 0, 0, data_ind->msgUnitParam.u8Buffer+1, - data_ind->msgUnitParam.u8Size-1); - - get_meas(&meas, &data_ind->measParam); - - switch (data_ind->sapi) { - case GsmL1_Sapi_Pdtch: - case GsmL1_Sapi_Pacch: - /* drop incomplete UL block */ - if (data_ind->msgUnitParam.u8Buffer[0] - != GsmL1_PdtchPlType_Full) - break; - /* PDTCH / PACCH frame handling */ - pcu_rx_data_ind_pdtch((long)fl1h->priv, data_ind->u8Tn, - data_ind->msgUnitParam.u8Buffer + 1, - data_ind->msgUnitParam.u8Size - 1, - data_ind->u32Fn, - &meas); - break; - case GsmL1_Sapi_Ptcch: - // FIXME - break; - default: - LOGP(DL1IF, LOGL_NOTICE, "Rx PH-DATA.ind for unknown L1 SAPI %s\n", - get_value_string(femtobts_l1sapi_names, data_ind->sapi)); - break; - } - - return rc; -} - -#define MIN_QUAL_RACH 5.0f - -static int handle_ph_ra_ind(struct femtol1_hdl *fl1h, GsmL1_PhRaInd_t *ra_ind) -{ - uint8_t acc_delay; - - pcu_rx_ra_time(ra_ind->u16Arfcn, ra_ind->u32Fn, ra_ind->u8Tn); - - if (ra_ind->measParam.fLinkQuality < MIN_QUAL_RACH) - return 0; - - DEBUGP(DL1IF, "Rx PH-RA.ind"); - - /* check for under/overflow / sign */ - if (ra_ind->measParam.i16BurstTiming < 0) - acc_delay = 0; - else - acc_delay = ra_ind->measParam.i16BurstTiming >> 2; - - LOGP(DL1IF, LOGL_NOTICE, "got (P)RACH request, TA = %u (ignored)\n", - acc_delay); - -#warning "The (P)RACH request is just dropped here" - -#if 0 - if (acc_delay > bts->max_ta) { - LOGP(DL1C, LOGL_INFO, "ignoring RACH request %u > max_ta(%u)\n", - acc_delay, btsb->max_ta); - return 0; - } -#endif - - return 0; -} - - -/* handle any random indication from the L1 */ -int l1if_handle_l1prim(int wq, struct femtol1_hdl *fl1h, struct msgb *msg) -{ - GsmL1_Prim_t *l1p = msgb_l1prim(msg); - int rc = 0; - - LOGP(DL1IF, LOGL_DEBUG, "Rx L1 prim %s on queue %d\n", - get_value_string(femtobts_l1prim_names, l1p->id), wq); - - switch (l1p->id) { -#if 0 - case GsmL1_PrimId_MphTimeInd: - rc = handle_mph_time_ind(fl1h, &l1p->u.mphTimeInd); - break; - case GsmL1_PrimId_MphSyncInd: - break; - case GsmL1_PrimId_PhConnectInd: - break; -#endif - case GsmL1_PrimId_PhReadyToSendInd: - rc = handle_ph_readytosend_ind(fl1h, &l1p->u.phReadyToSendInd); - break; - case GsmL1_PrimId_PhDataInd: - rc = handle_ph_data_ind(fl1h, &l1p->u.phDataInd, msg); - break; - case GsmL1_PrimId_PhRaInd: - rc = handle_ph_ra_ind(fl1h, &l1p->u.phRaInd); - break; - default: - break; - } - - msgb_free(msg); - - return rc; -} - -int l1if_handle_sysprim(struct femtol1_hdl *fl1h, struct msgb *msg) -{ - return -ENOTSUP; -} - -/* send packet data request to L1 */ -int l1if_pdch_req(void *obj, uint8_t ts, int is_ptcch, uint32_t fn, - uint16_t arfcn, uint8_t block_nr, uint8_t *data, uint8_t len) -{ - struct femtol1_hdl *fl1h = obj; - struct msgb *msg; - GsmL1_Prim_t *l1p; - GsmL1_PhDataReq_t *data_req; - GsmL1_MsgUnitParam_t *msu_param; - struct gsm_time g_time; - - gsm_fn2gsmtime(&g_time, fn); - - DEBUGP(DL1IF, "TX packet data %02u/%02u/%02u is_ptcch=%d ts=%d " - "block_nr=%d, arfcn=%d, len=%d\n", g_time.t1, g_time.t2, - g_time.t3, is_ptcch, ts, block_nr, arfcn, len); - - msg = l1p_msgb_alloc(); - l1p = msgb_l1prim(msg); - l1p->id = GsmL1_PrimId_PhDataReq; - data_req = &l1p->u.phDataReq; - data_req->hLayer1 = fl1h->hLayer1; - data_req->sapi = (is_ptcch) ? GsmL1_Sapi_Ptcch : GsmL1_Sapi_Pdtch; - data_req->subCh = GsmL1_SubCh_NA; - data_req->u8BlockNbr = block_nr; - data_req->u8Tn = ts; - data_req->u32Fn = fn; - msu_param = &data_req->msgUnitParam; - msu_param->u8Size = len; - memcpy(msu_param->u8Buffer, data, len); - - gsmtap_send(fl1h->gsmtap, arfcn, data_req->u8Tn, GSMTAP_CHANNEL_PACCH, - 0, data_req->u32Fn, 0, 0, - data_req->msgUnitParam.u8Buffer, - data_req->msgUnitParam.u8Size); - - - /* transmit */ - if (osmo_wqueue_enqueue(&fl1h->write_q[MQ_PDTCH_WRITE], msg) != 0) { - LOGP(DL1IF, LOGL_ERROR, "PDTCH queue full. dropping message.\n"); - msgb_free(msg); - } - - return 0; -} - -void *l1if_open_pdch(void *priv, uint32_t hlayer1, struct gsmtap_inst *gsmtap) -{ - struct femtol1_hdl *fl1h; - int rc; - - fl1h = talloc_zero(tall_pcu_ctx, struct femtol1_hdl); - if (!fl1h) - return NULL; - - fl1h->hLayer1 = hlayer1; - fl1h->priv = priv; - fl1h->clk_cal = 0; - /* default clock source: OCXO */ - fl1h->clk_src = SuperFemto_ClkSrcId_Ocxo; - - rc = l1if_transport_open(MQ_PDTCH_WRITE, fl1h); - if (rc < 0) { - talloc_free(fl1h); - return NULL; - } - - fl1h->gsmtap = gsmtap; - - return fl1h; -} - -int l1if_close_pdch(void *obj) -{ - struct femtol1_hdl *fl1h = obj; - if (fl1h) - l1if_transport_close(MQ_PDTCH_WRITE, fl1h); - talloc_free(fl1h); - return 0; -} - diff --git a/src/sysmo_l1_if.h b/src/sysmo_l1_if.h deleted file mode 100644 index 6b50d4e..0000000 --- a/src/sysmo_l1_if.h +++ /dev/null @@ -1,91 +0,0 @@ -#ifndef _SYSMO_L1_IF_H -#define _SYSMO_L1_IF_H - -#include -#include -#include -#include -#include "femtobts.h" - -enum { - MQ_SYS_READ, - MQ_L1_READ, -#ifndef HW_SYSMOBTS_V1 - MQ_TCH_READ, - MQ_PDTCH_READ, -#endif - _NUM_MQ_READ -}; - -enum { - MQ_SYS_WRITE, - MQ_L1_WRITE, -#ifndef HW_SYSMOBTS_V1 - MQ_TCH_WRITE, - MQ_PDTCH_WRITE, -#endif - _NUM_MQ_WRITE -}; - -struct femtol1_hdl { - struct gsm_time gsm_time; - uint32_t hLayer1; /* handle to the L1 instance in the DSP */ - uint32_t dsp_trace_f; - int clk_cal; - uint8_t clk_src; - struct llist_head wlc_list; - - struct gsmtap_inst *gsmtap; - uint32_t gsmtap_sapi_mask; - - void *priv; /* user reference */ - - struct osmo_timer_list alive_timer; - unsigned int alive_prim_cnt; - - struct osmo_fd read_ofd[_NUM_MQ_READ]; /* osmo file descriptors */ - struct osmo_wqueue write_q[_NUM_MQ_WRITE]; - - struct { - uint8_t dsp_version[3]; - uint8_t fpga_version[3]; - uint32_t band_support; /* bitmask of GSM_BAND_* */ - } hw_info; -}; - -#define msgb_l1prim(msg) ((GsmL1_Prim_t *)(msg)->l1h) -#define msgb_sysprim(msg) ((SuperFemto_Prim_t *)(msg)->l1h) - -typedef int l1if_compl_cb(struct msgb *l1_msg, void *data); - -/* send a request primitive to the L1 and schedule completion call-back */ -int l1if_req_compl(struct femtol1_hdl *fl1h, struct msgb *msg, - int is_system_prim, l1if_compl_cb *cb, void *data); - -int l1if_reset(struct femtol1_hdl *hdl); -int l1if_activate_rf(struct femtol1_hdl *hdl, int on); -int l1if_set_trace_flags(struct femtol1_hdl *hdl, uint32_t flags); -int l1if_set_txpower(struct femtol1_hdl *fl1h, float tx_power); - -struct msgb *l1p_msgb_alloc(void); -struct msgb *sysp_msgb_alloc(void); - -uint32_t l1if_lchan_to_hLayer2(struct gsm_lchan *lchan); -struct gsm_lchan *l1if_hLayer2_to_lchan(struct gsm_bts_trx *trx, uint32_t hLayer2); - -int l1if_handle_sysprim(struct femtol1_hdl *fl1h, struct msgb *msg); -int l1if_handle_l1prim(int wq, struct femtol1_hdl *fl1h, struct msgb *msg); - -/* tch.c */ -int l1if_tch_rx(struct gsm_lchan *lchan, struct msgb *l1p_msg); -int l1if_tch_fill(struct gsm_lchan *lchan, uint8_t *l1_buffer); -struct msgb *gen_empty_tch_msg(struct gsm_lchan *lchan); - -/* - * The implementation of these functions is selected by either compiling and - * linking sysmo_l1_hw.c or sysmo_l1_fwd.c - */ -int l1if_transport_open(int q, struct femtol1_hdl *hdl); -int l1if_transport_close(int q, struct femtol1_hdl *hdl); - -#endif /* _SYSMO_L1_IF_H */ -- 2.8.1 From msuraev at sysmocom.de Thu Apr 21 12:35:57 2016 From: msuraev at sysmocom.de (msuraev at sysmocom.de) Date: Thu, 21 Apr 2016 14:35:57 +0200 Subject: [PATCH 5/5] Change internal API for consistency In-Reply-To: <1461242157-14223-1-git-send-email-msuraev@sysmocom.de> References: <1461242157-14223-1-git-send-email-msuraev@sysmocom.de> Message-ID: <1461242157-14223-5-git-send-email-msuraev@sysmocom.de> From: Max Use uint8_t for TRX numbering everywhere (we don't expect hardware with more than 256 transceivers in the near future). This change helps to avoid unnecessary casts and make API much clearer. --- src/osmo-bts-sysmo/sysmo_l1_if.c | 8 ++++---- src/osmo-bts-sysmo/sysmo_l1_if.h | 2 +- src/pcu_l1_if.cpp | 9 ++++----- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/osmo-bts-sysmo/sysmo_l1_if.c b/src/osmo-bts-sysmo/sysmo_l1_if.c index c7c54dd..4bfcecd 100644 --- a/src/osmo-bts-sysmo/sysmo_l1_if.c +++ b/src/osmo-bts-sysmo/sysmo_l1_if.c @@ -155,7 +155,7 @@ static int handle_ph_readytosend_ind(struct femtol1_hdl *fl1h, switch (rts_ind->sapi) { case GsmL1_Sapi_Pdtch: case GsmL1_Sapi_Pacch: - rc = pcu_rx_rts_req_pdtch((long)fl1h->priv, rts_ind->u8Tn, + rc = pcu_rx_rts_req_pdtch(fl1h->trx, rts_ind->u8Tn, rts_ind->u16Arfcn, rts_ind->u32Fn, rts_ind->u8BlockNbr); case GsmL1_Sapi_Ptcch: // FIXME @@ -215,7 +215,7 @@ static int handle_ph_data_ind(struct femtol1_hdl *fl1h, != GsmL1_PdtchPlType_Full) break; /* PDTCH / PACCH frame handling */ - pcu_rx_data_ind_pdtch((long)fl1h->priv, data_ind->u8Tn, + pcu_rx_data_ind_pdtch(fl1h->trx, data_ind->u8Tn, data_ind->msgUnitParam.u8Buffer + 1, data_ind->msgUnitParam.u8Size - 1, data_ind->u32Fn, @@ -357,7 +357,7 @@ int l1if_pdch_req(void *obj, uint8_t ts, int is_ptcch, uint32_t fn, return 0; } -void *l1if_open_pdch(void *priv, uint32_t hlayer1, struct gsmtap_inst *gsmtap) +void *l1if_open_pdch(uint8_t trx, uint32_t hlayer1, struct gsmtap_inst *gsmtap) { struct femtol1_hdl *fl1h; int rc; @@ -367,7 +367,7 @@ void *l1if_open_pdch(void *priv, uint32_t hlayer1, struct gsmtap_inst *gsmtap) return NULL; fl1h->hLayer1 = hlayer1; - fl1h->priv = priv; + fl1h->trx = trx; fl1h->clk_cal = 0; /* default clock source: OCXO */ fl1h->clk_src = SuperFemto_ClkSrcId_Ocxo; diff --git a/src/osmo-bts-sysmo/sysmo_l1_if.h b/src/osmo-bts-sysmo/sysmo_l1_if.h index 6b50d4e..83ca481 100644 --- a/src/osmo-bts-sysmo/sysmo_l1_if.h +++ b/src/osmo-bts-sysmo/sysmo_l1_if.h @@ -38,7 +38,7 @@ struct femtol1_hdl { struct gsmtap_inst *gsmtap; uint32_t gsmtap_sapi_mask; - void *priv; /* user reference */ + uint8_t trx; struct osmo_timer_list alive_timer; unsigned int alive_prim_cnt; diff --git a/src/pcu_l1_if.cpp b/src/pcu_l1_if.cpp index 67272ab..2acf8ce 100644 --- a/src/pcu_l1_if.cpp +++ b/src/pcu_l1_if.cpp @@ -44,7 +44,7 @@ extern "C" { // FIXME: move this, when changed from c++ to c. extern "C" { -void *l1if_open_pdch(void *priv, uint32_t hlayer1, struct gsmtap_inst *gsmtap); +void *l1if_open_pdch(uint8_t trx, uint32_t hlayer1, struct gsmtap_inst *gsmtap); int l1if_connect_pdch(void *obj, uint8_t ts); int l1if_pdch_req(void *obj, uint8_t ts, int is_ptcch, uint32_t fn, uint16_t arfcn, uint8_t block_nr, uint8_t *data, uint8_t len); @@ -330,9 +330,8 @@ static int pcu_rx_info_ind(struct gsm_pcu_if_info_ind *info_ind) struct gprs_bssgp_pcu *pcu; struct gprs_rlcmac_pdch *pdch; struct in_addr ia; - int rc = 0; - int trx, ts; - int i; + int rc = 0, ts, i; + uint8_t trx; if (info_ind->version != PCU_IF_VERSION) { fprintf(stderr, "PCU interface version number of BTS (%d) is " @@ -450,7 +449,7 @@ bssgp_failed: info_ind->trx[trx].hlayer1); if (!bts->trx[trx].fl1h) bts->trx[trx].fl1h = l1if_open_pdch( - (void *)trx, + trx, info_ind->trx[trx].hlayer1, bts->gsmtap); if (!bts->trx[trx].fl1h) { -- 2.8.1 From laforge at gnumonks.org Fri Apr 22 12:38:21 2016 From: laforge at gnumonks.org (Harald Welte) Date: Fri, 22 Apr 2016 14:38:21 +0200 Subject: [PATCH 2/5] Enable subdir-objects In-Reply-To: <1461242157-14223-2-git-send-email-msuraev@sysmocom.de> References: <1461242157-14223-1-git-send-email-msuraev@sysmocom.de> <1461242157-14223-2-git-send-email-msuraev@sysmocom.de> Message-ID: <20160422123821.GD25360@nataraja> Hi Max, On Thu, Apr 21, 2016 at 02:35:54PM +0200, msuraev at sysmocom.de wrote: > This helps to increase compatibility with newer automake. I tried several times to add subdir-objects, but we always had to revert these kind of changes, as they broke something. Don't recall what exactly, but I think it was related to either out-of-source builds and/or autotest? Holger? -- - Harald Welte http://laforge.gnumonks.org/ ============================================================================ "Privacy in residential applications is a desirable marketing option." (ETSI EN 300 175-7 Ch. A6) From msuraev at sysmocom.de Sat Apr 23 17:44:44 2016 From: msuraev at sysmocom.de (Max) Date: Sat, 23 Apr 2016 19:44:44 +0200 Subject: [PATCH 2/5] Enable subdir-objects In-Reply-To: <20160422123821.GD25360@nataraja> References: <1461242157-14223-1-git-send-email-msuraev@sysmocom.de> <1461242157-14223-2-git-send-email-msuraev@sysmocom.de> <20160422123821.GD25360@nataraja> Message-ID: <571BB48C.4030907@sysmocom.de> It's currently enabled for libosmocore master. On 04/22/2016 02:38 PM, Harald Welte wrote: > Hi Max, > > On Thu, Apr 21, 2016 at 02:35:54PM +0200, msuraev at sysmocom.de wrote: >> This helps to increase compatibility with newer automake. > I tried several times to add subdir-objects, but we always had to revert > these kind of changes, as they broke something. Don't recall what > exactly, but I think it was related to either out-of-source builds > and/or autotest? Holger? > -- Max Suraev http://www.sysmocom.de/ ======================================================================= * sysmocom - systems for mobile communications GmbH * Alt-Moabit 93 * 10559 Berlin, Germany * Sitz / Registered office: Berlin, HRB 134158 B * Geschaeftsfuehrer / Managing Directors: Holger Freyther, Harald Welte From nhofmeyr at sysmocom.de Mon Apr 25 10:18:03 2016 From: nhofmeyr at sysmocom.de (Neels Hofmeyr) Date: Mon, 25 Apr 2016 12:18:03 +0200 Subject: [PATCH 2/5] Enable subdir-objects In-Reply-To: <20160422123821.GD25360@nataraja> References: <1461242157-14223-1-git-send-email-msuraev@sysmocom.de> <1461242157-14223-2-git-send-email-msuraev@sysmocom.de> <20160422123821.GD25360@nataraja> Message-ID: <20160425101803.GB1334@dub6> See my mail from 17th Feb Cc'd to openbsc@, where I ask autoconf about the weird dirs showing up when subdir-objects is used, answered by Eric Blake of RedHat: [[[ > On Thu, Jan 14, 2016 at 02:40:38PM +0100, Neels Hofmeyr wrote: >> Dear autoconf, >> >> I am observing a bug with `autoreconf -i`. >> To my/our knowledge, this is not due to an error in >> our configuration but a genuine bug from 'subdir-objects'. >> >> The symptom: after running ./configure, I find a directory >> src/tests/\$(top_srcdir) This is a known automake bug, not caused by autoconf; that may explain why you haven't seen much response on the autoconf list, but I don't know if there are any active maintainers on the automake list that have suggestions on how to work around it, or on when a fixed automake will be available (or if it is already available). A quick search found this, though: https://lists.gnu.org/archive/html/automake/2015-12/msg00001.html ]]] Here is the openbsc@ thread: http://lists.osmocom.org/pipermail/openbsc/2016-February/007971.html So besides creating those weird directories, subdir-objects works AFAIK. We are currently using subdir-objects in osmo-iuh, libosmo-abis, libosmo-netif and last but not least libosmocore. (at least on 3G branches) ~Neels On Fri, Apr 22, 2016 at 02:38:21PM +0200, Harald Welte wrote: > Hi Max, > > On Thu, Apr 21, 2016 at 02:35:54PM +0200, msuraev at sysmocom.de wrote: > > This helps to increase compatibility with newer automake. > > I tried several times to add subdir-objects, but we always had to revert > these kind of changes, as they broke something. Don't recall what > exactly, but I think it was related to either out-of-source builds > and/or autotest? Holger? > > -- > - Harald Welte http://laforge.gnumonks.org/ > ============================================================================ > "Privacy in residential applications is a desirable marketing option." > (ETSI EN 300 175-7 Ch. A6) -- - Neels Hofmeyr http://www.sysmocom.de/ ======================================================================= * sysmocom - systems for mobile communications GmbH * Alt-Moabit 93 * 10559 Berlin, Germany * Sitz / Registered office: Berlin, HRB 134158 B * Gesch?ftsf?hrer / Managing Directors: Holger Freyther, Harald Welte -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: Digital signature URL: From arvind.sirsikar at radisys.com Mon Apr 25 10:30:57 2016 From: arvind.sirsikar at radisys.com (Aravind Sirsikar) Date: Mon, 25 Apr 2016 16:00:57 +0530 Subject: [PATCH 1/4] Add data structure for MCS change in Retx In-Reply-To: <1461580260-9199-1-git-send-email-arvind.sirsikar@radisys.com> References: <1461580260-9199-1-git-send-email-arvind.sirsikar@radisys.com> Message-ID: <1461580260-9199-2-git-send-email-arvind.sirsikar@radisys.com> From: Aravind Sirsikar Modify the existing data structure to support MCS change during Retx case in EGPRS DL. --- src/gprs_coding_scheme.cpp | 36 ++++++++++++++++++++++++++++++++++++ src/gprs_coding_scheme.h | 8 ++++++++ src/rlc.h | 10 ++++++++++ 3 files changed, 54 insertions(+) diff --git a/src/gprs_coding_scheme.cpp b/src/gprs_coding_scheme.cpp index 8601d4f..4b47c0b 100644 --- a/src/gprs_coding_scheme.cpp +++ b/src/gprs_coding_scheme.cpp @@ -21,6 +21,42 @@ #include "gprs_coding_scheme.h" +/* + * 44.060 Table 8.1.1.1 and Table 8.1.1.2 + * In has 3 level indexing. 0th level is ARQ type + * 1st level is Original MCS( index 0 corresponds to MCS1 and so on) + * 2nd level is MS MCS (index 0 corresponds to MCS1 and so on) + * in 0th level indexing only ARQ type 2 is supported i.e index 1 for + * incremental redundancy + */ + +/* TODO: Need to support ARQ type 1 */ +enum GprsCodingScheme::Scheme GprsCodingScheme::egprs_mcs_retx_tbl[MAX_NUM_ARQ] + [MAX_NUM_MCS][MAX_NUM_MCS] = { + { + {MCS1, MCS1, MCS1, MCS1, MCS1, MCS1, MCS1, MCS1, MCS1}, + {MCS2, MCS2, MCS2, MCS2, MCS2, MCS2, MCS2, MCS2, MCS2}, + {MCS3, MCS3, MCS3, MCS3, MCS3, MCS3, MCS3, MCS3, MCS3}, + {MCS1, MCS1, MCS1, MCS4, MCS4, MCS4, MCS4, MCS4, MCS4}, + {MCS2, MCS2, MCS2, MCS2, MCS5, MCS5, MCS7, MCS7, MCS7}, + {MCS3, MCS3, MCS3, MCS3, MCS3, MCS6, MCS6, MCS6, MCS9}, + {MCS2, MCS2, MCS2, MCS2, MCS5, MCS5, MCS7, MCS7, MCS7}, + {MCS3, MCS3, MCS3, MCS3, MCS3, MCS6, MCS6, MCS8, MCS8}, + {MCS3, MCS3, MCS3, MCS3, MCS3, MCS6, MCS6, MCS6, MCS9} + }, + { + {MCS1, MCS1, MCS1, MCS1, MCS1, MCS1, MCS1, MCS1, MCS1}, + {MCS2, MCS2, MCS2, MCS2, MCS2, MCS2, MCS2, MCS2, MCS2}, + {MCS3, MCS3, MCS3, MCS3, MCS3, MCS3, MCS3, MCS3, MCS3}, + {MCS4, MCS4, MCS4, MCS4, MCS4, MCS4, MCS4, MCS4, MCS4}, + {MCS5, MCS5, MCS5, MCS5, MCS5, MCS5, MCS7, MCS7, MCS7}, + {MCS6, MCS6, MCS6, MCS6, MCS6, MCS6, MCS6, MCS6, MCS9}, + {MCS5, MCS5, MCS5, MCS5, MCS5, MCS5, MCS7, MCS7, MCS7}, + {MCS6, MCS6, MCS6, MCS6, MCS6, MCS6, MCS6, MCS8, MCS8}, + {MCS6, MCS6, MCS6, MCS6, MCS6, MCS6, MCS6, MCS6, MCS9} + } + }; + static struct { struct { unsigned int bytes; diff --git a/src/gprs_coding_scheme.h b/src/gprs_coding_scheme.h index aec3762..bb0bad4 100644 --- a/src/gprs_coding_scheme.h +++ b/src/gprs_coding_scheme.h @@ -26,6 +26,12 @@ class GprsCodingScheme { public: + +#define MAX_NUM_ARQ 2 /* max. number of ARQ */ +#define MAX_NUM_MCS 9 /* max. number of MCS */ +#define EGPRS_ARQ1 0x0 +#define EGPRS_ARQ2 0x1 + enum Scheme { UNKNOWN, CS1, CS2, CS3, CS4, @@ -105,6 +111,8 @@ public: static GprsCodingScheme getEgprsByNum(unsigned num); static const char *modeName(Mode mode); + static enum Scheme egprs_mcs_retx_tbl[MAX_NUM_ARQ] + [MAX_NUM_MCS][MAX_NUM_MCS]; private: GprsCodingScheme(int s); /* fail on use */ GprsCodingScheme& operator =(int s); /* fail on use */ diff --git a/src/rlc.h b/src/rlc.h index 8f75588..3b0b04c 100644 --- a/src/rlc.h +++ b/src/rlc.h @@ -120,6 +120,16 @@ struct gprs_rlc_data { uint8_t len; struct gprs_rlc_data_block_info block_info; +/* + * cs_current_trans is variable to hold the cs value for + * current transmission. cs_current_trans is same as cs during + * transmission case. during retransmission cs_current_trans is + * fetched from egprs_mcs_retx_tbl table based on + * cs and demanded cs.reference is 44.060 Table + * 8.1.1.1 and Table 8.1.1.2 + */ + GprsCodingScheme cs_current_trans; + GprsCodingScheme cs; /* puncturing scheme value to be used for next transmission*/ -- 1.7.9.5 From arvind.sirsikar at radisys.com Mon Apr 25 10:30:56 2016 From: arvind.sirsikar at radisys.com (Aravind Sirsikar) Date: Mon, 25 Apr 2016 16:00:56 +0530 Subject: [PATCH 0/4] Support for Incremental redundency in EGPRS DL Message-ID: <1461580260-9199-1-git-send-email-arvind.sirsikar@radisys.com> This series of patches supports Incremental redundency for EGPRS DL case. These patches have been integration tested on Nuran 1.0 for EGPRS MCS 9 support in DL. And in UL only MCS4 has been tested. The EGPRS testing has been done with Browsing and Ping in DL with larger packet sizes(1500). Aravind Sirsikar (4): Add data structure for MCS change in Retx Add Accessor functions for MCS change in Retx Modify DL tbf flow for MCS change in Retx Add test cases to support MCS change during Retx src/gprs_coding_scheme.cpp | 36 ++++ src/gprs_coding_scheme.h | 27 ++- src/gprs_ms.cpp | 5 + src/gprs_ms.h | 1 + src/rlc.h | 10 ++ src/tbf_dl.cpp | 41 +++-- tests/tbf/TbfTest.cpp | 224 +++++++++++++++++++++++++ tests/tbf/TbfTest.err | 397 ++++++++++++++++++++++++++++++++++++++++++++ tests/tbf/TbfTest.ok | 9 + 9 files changed, 737 insertions(+), 13 deletions(-) -- 1.7.9.5 From arvind.sirsikar at radisys.com Mon Apr 25 10:30:59 2016 From: arvind.sirsikar at radisys.com (Aravind Sirsikar) Date: Mon, 25 Apr 2016 16:00:59 +0530 Subject: [PATCH 3/4] Modify DL tbf flow for MCS change in Retx In-Reply-To: <1461580260-9199-1-git-send-email-arvind.sirsikar@radisys.com> References: <1461580260-9199-1-git-send-email-arvind.sirsikar@radisys.com> Message-ID: <1461580260-9199-4-git-send-email-arvind.sirsikar@radisys.com> Modify the DL TBF flow to support MCS change during the EGPRS retransmission --- src/tbf_dl.cpp | 41 +++++++++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/src/tbf_dl.cpp b/src/tbf_dl.cpp index 9e4d078..17e3603 100644 --- a/src/tbf_dl.cpp +++ b/src/tbf_dl.cpp @@ -365,7 +365,7 @@ int gprs_rlcmac_dl_tbf::take_next_bsn(uint32_t fn, bsn = m_window.resend_needed(); if (previous_bsn >= 0) { - force_cs = m_rlc.block(previous_bsn)->cs; + force_cs = m_rlc.block(previous_bsn)->cs_current_trans; if (!force_cs.isEgprs()) return -1; force_data_len = m_rlc.block(previous_bsn)->len; @@ -379,7 +379,21 @@ int gprs_rlcmac_dl_tbf::take_next_bsn(uint32_t fn, m_window.mod_sns(bsn - previous_bsn) > RLC_EGPRS_MAX_BSN_DELTA) return -1; - cs2 = m_rlc.block(bsn)->cs; + if (is_egprs_enabled()) { + m_rlc.block(bsn)->cs_current_trans = + GprsCodingScheme::get_retx_mcs(m_rlc.block(bsn)->cs, + ms()->current_cs_dl()); + + /* TODO: Need to remove this check when MCS-8 -> MCS-6 + * transistion is handled + */ + if (m_rlc.block(bsn)->cs == GprsCodingScheme::MCS8) + m_rlc.block(bsn)->cs_current_trans = + GprsCodingScheme::MCS8; + } else + m_rlc.block(bsn)->cs_current_trans = + m_rlc.block(bsn)->cs; + data_len2 = m_rlc.block(bsn)->len; if (force_data_len > 0 && force_data_len != data_len2) return -1; @@ -422,7 +436,7 @@ int gprs_rlcmac_dl_tbf::take_next_bsn(uint32_t fn, "- 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, so don't set cs2 */ + /* Don't send a second block, so don't set cs_current_trans*/ } if (bsn < 0) { @@ -433,7 +447,7 @@ int gprs_rlcmac_dl_tbf::take_next_bsn(uint32_t fn, bts->rlc_resent(); } - *may_combine = cs2.numDataBlocks() > 1; + *may_combine = m_rlc.block(bsn)->cs_current_trans.numDataBlocks() > 1; return bsn; } @@ -505,6 +519,7 @@ int gprs_rlcmac_dl_tbf::create_new_bsn(const uint32_t fn, GprsCodingScheme cs) rlc_data = m_rlc.block(bsn); data = rlc_data->prepare(block_data_len); rlc_data->cs = cs; + rlc_data->cs_current_trans = cs; rlc_data->len = block_data_len; rdbi = &(rlc_data->block_info); @@ -587,7 +602,6 @@ struct msgb *gprs_rlcmac_dl_tbf::create_dl_acked_block( bool is_final = false; gprs_rlc_data_info rlc; GprsCodingScheme cs; - GprsCodingScheme cs_current_trans; int bsns[ARRAY_SIZE(rlc.block_info)]; unsigned num_bsns; enum egprs_puncturing_values punct[ARRAY_SIZE(rlc.block_info)]; @@ -601,7 +615,7 @@ struct msgb *gprs_rlcmac_dl_tbf::create_dl_acked_block( * be put into the data area, even if the resulting CS is higher than * the current limit. */ - cs = m_rlc.block(index)->cs; + cs = m_rlc.block(index)->cs_current_trans; bsns[0] = index; num_bsns = 1; @@ -613,6 +627,9 @@ struct msgb *gprs_rlcmac_dl_tbf::create_dl_acked_block( if (num_bsns == 1) { /* TODO: remove the conditional when MCS-6 padding isn't * failing to be decoded by MEs anymore */ + /* TODO: support of MCS-8 -> MCS-6 transition should be + * handled + */ if (cs != GprsCodingScheme(GprsCodingScheme::MCS8)) cs.decToSingleBlock(&need_padding); } @@ -647,18 +664,16 @@ struct msgb *gprs_rlcmac_dl_tbf::create_dl_acked_block( else bsn = bsns[0]; - cs_enc = m_rlc.block(bsn)->cs; + cs_enc = m_rlc.block(bsn)->cs_current_trans; + /* get data and header from current block */ block_data = m_rlc.block(bsn)->block; - /* TODO: Need to support MCS change during retx */ - cs_current_trans = cs; - /* Get current puncturing scheme from block */ punct_scheme = gprs_get_punct_scheme( m_rlc.block(bsn)->next_ps, - cs, cs_current_trans); + m_rlc.block(bsn)->cs, cs); if (cs.isEgprs()) { OSMO_ASSERT(punct_scheme >= EGPRS_PS_1); @@ -682,7 +697,9 @@ struct msgb *gprs_rlcmac_dl_tbf::create_dl_acked_block( * in header type 1 */ gprs_update_punct_scheme(&m_rlc.block(bsn)->next_ps, - cs_current_trans); + cs); + + m_rlc.block(bsn)->cs = m_rlc.block(bsn)->cs_current_trans; rdbi->e = block_info->e; rdbi->cv = block_info->cv; -- 1.7.9.5 From arvind.sirsikar at radisys.com Mon Apr 25 10:31:00 2016 From: arvind.sirsikar at radisys.com (Aravind Sirsikar) Date: Mon, 25 Apr 2016 16:01:00 +0530 Subject: [PATCH 4/4] Add test cases to support MCS change during Retx In-Reply-To: <1461580260-9199-1-git-send-email-arvind.sirsikar@radisys.com> References: <1461580260-9199-1-git-send-email-arvind.sirsikar@radisys.com> Message-ID: <1461580260-9199-5-git-send-email-arvind.sirsikar@radisys.com> During MCS upgradation such as MCS6->MCS9, 2 blocks which were sent separately as MCS6, will be clubbed into one MCS9 block during retransmission. Same holds good for MCS5->MCS7 transistion. During MCS reduction such as MCS9->MCS6,2 blocks which were sent together will be sent separately during the retransmission case. Same is verified through the generated log file. Currently MCS8->MCS6 transition is not supported. The retransmission MCS is being calculated from Table 8.1.1.2 of TS 44.060. --- tests/tbf/TbfTest.cpp | 224 ++++++++++++++++++++++++++++ tests/tbf/TbfTest.err | 397 +++++++++++++++++++++++++++++++++++++++++++++++++ tests/tbf/TbfTest.ok | 9 ++ 3 files changed, 630 insertions(+) diff --git a/tests/tbf/TbfTest.cpp b/tests/tbf/TbfTest.cpp index e1be844..23c8dd5 100644 --- a/tests/tbf/TbfTest.cpp +++ b/tests/tbf/TbfTest.cpp @@ -1272,6 +1272,229 @@ static void establish_and_use_egprs_dl_tbf(BTS *the_bts, int mcs) tbf_free(dl_tbf); } +static gprs_rlcmac_dl_tbf *tbf_init(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; + + 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(test_data); i++) + test_data[i] = i%256; + + OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW)); + + /* Schedule a LLC frame + * passing only 100 bytes, since it is enough to construct + * 2 RLC data blocks. Which are enough to test Header Type 1 + * cases + */ + dl_tbf->append_data(ms_class, 1000, test_data, 100); + + OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW)); + + return dl_tbf; + +} + +static void tbf_cleanup(gprs_rlcmac_dl_tbf *dl_tbf) +{ + uint32_t fn = 0; + uint8_t rbb[64/8]; + + /* 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 establish_and_use_egprs_dl_tbf_for_retx(BTS *the_bts, + int mcs, int demanded_mcs) +{ + uint32_t fn = 0; + gprs_rlcmac_dl_tbf *dl_tbf; + uint8_t block_nr = 0; + int index1 = 0; + uint8_t bn; + struct msgb *msg; + + printf("Testing retx for MCS %d - %d\n", mcs, demanded_mcs); + + dl_tbf = tbf_init(the_bts, mcs); + + /* For MCS reduction cases like MCS9->MCS6, MCS7->MCS5 + * The MCS transition are referred from table Table 8.1.1.2 + * of TS 44.060 + */ + /* TODO: Need to support of MCS8 -> MCS6 transistion */ + if (((mcs == 9) && (demanded_mcs < 9)) || + ((mcs == 7) && (demanded_mcs < 7))) { + fn = fn_add_blocks(fn, 1); + /* Send 2 RLC data block */ + msg = dl_tbf->create_dl_acked_block(fn, dl_tbf->control_ts); + + OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(0)); + OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(1)); + OSMO_ASSERT(dl_tbf->m_rlc.block(0)->cs_current_trans.to_num() + == mcs); + OSMO_ASSERT(dl_tbf->m_rlc.block(1)->cs_current_trans.to_num() + == mcs); + + dl_tbf->m_window.m_v_b.mark_nacked(0); + dl_tbf->m_window.m_v_b.mark_nacked(1); + OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_nacked(0)); + OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_nacked(1)); + + /* Set the demanded MCS to demanded_mcs */ + dl_tbf->ms()->set_current_cs_dl + ((GprsCodingScheme::Scheme)(GprsCodingScheme::CS4 + + demanded_mcs)); + + fn = fn_add_blocks(fn, 1); + /* Retransmit the first RLC data block with demanded_mcs */ + msg = dl_tbf->create_dl_acked_block(fn, dl_tbf->control_ts); + OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(0)); + OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_nacked(1)); + OSMO_ASSERT(dl_tbf->m_rlc.block(0)->cs_current_trans.to_num() + == demanded_mcs); + + fn = fn_add_blocks(fn, 1); + /* Retransmit the second RLC data block with demanded_mcs */ + msg = dl_tbf->create_dl_acked_block(fn, dl_tbf->control_ts); + OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(0)); + OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(1)); + OSMO_ASSERT(dl_tbf->m_rlc.block(1)->cs_current_trans.to_num() + == demanded_mcs); + } else if (((mcs == 5) && (demanded_mcs > 6)) || + ((mcs == 6) && (demanded_mcs > 8))) { + fn = fn_add_blocks(fn, 1); + /* Send first RLC data block BSN 0 */ + msg = dl_tbf->create_dl_acked_block(fn, dl_tbf->control_ts); + OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(0)); + OSMO_ASSERT(dl_tbf->m_rlc.block(0)->cs_current_trans.to_num() + == mcs); + + fn = fn_add_blocks(fn, 1); + /* Send second RLC data block BSN 1 */ + msg = dl_tbf->create_dl_acked_block(fn, dl_tbf->control_ts); + OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(1)); + OSMO_ASSERT(dl_tbf->m_rlc.block(1)->cs_current_trans.to_num() + == mcs); + + dl_tbf->m_window.m_v_b.mark_nacked(0); + dl_tbf->m_window.m_v_b.mark_nacked(1); + OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_nacked(0)); + OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_nacked(1)); + + dl_tbf->ms()->set_current_cs_dl + ((GprsCodingScheme::Scheme)(GprsCodingScheme::CS4 + + demanded_mcs)); + + fn = fn_add_blocks(fn, 1); + /* Send first, second RLC data blocks with demanded_mcs */ + msg = dl_tbf->create_dl_acked_block(fn, dl_tbf->control_ts); + OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(0)); + OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(1)); + OSMO_ASSERT(dl_tbf->m_rlc.block(0)->cs_current_trans.to_num() + == demanded_mcs); + OSMO_ASSERT(dl_tbf->m_rlc.block(1)->cs_current_trans.to_num() + == demanded_mcs); + } else if (mcs > 6) { + /* No Mcs change cases are handled here for mcs > MCS6*/ + fn = fn_add_blocks(fn, 1); + /* Send first,second RLC data blocks */ + msg = dl_tbf->create_dl_acked_block(fn, dl_tbf->control_ts); + OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(0)); + OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(1)); + OSMO_ASSERT(dl_tbf->m_rlc.block(0)->cs_current_trans.to_num() + == mcs); + OSMO_ASSERT(dl_tbf->m_rlc.block(1)->cs_current_trans.to_num() + == mcs); + + dl_tbf->m_window.m_v_b.mark_nacked(0); + dl_tbf->m_window.m_v_b.mark_nacked(1); + OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_nacked(0)); + OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_nacked(1)); + + fn = fn_add_blocks(fn, 1); + /* Send first,second RLC data blocks with demanded_mcs*/ + msg = dl_tbf->create_dl_acked_block(fn, dl_tbf->control_ts); + OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(0)); + OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(1)); + OSMO_ASSERT(dl_tbf->m_rlc.block(0)->cs_current_trans.to_num() + == mcs); + OSMO_ASSERT(dl_tbf->m_rlc.block(1)->cs_current_trans.to_num() + == mcs); + } else { + + /* No MCS change cases are handled here for mcs <= MCS6*/ + fn = fn_add_blocks(fn, 1); + /* Send first RLC data block */ + msg = dl_tbf->create_dl_acked_block(fn, dl_tbf->control_ts); + OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(0)); + OSMO_ASSERT(dl_tbf->m_rlc.block(0)->cs_current_trans.to_num() + == mcs); + + dl_tbf->m_window.m_v_b.mark_nacked(0); + OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_nacked(0)); + + fn = fn_add_blocks(fn, 1); + /* Send first RLC data block with demanded_mcs */ + msg = dl_tbf->create_dl_acked_block(fn, dl_tbf->control_ts); + OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(0)); + OSMO_ASSERT(dl_tbf->m_rlc.block(0)->cs_current_trans.to_num() + == mcs); + } + + tbf_cleanup(dl_tbf); +} + +static void test_tbf_egprs_retx_dl(void) +{ + BTS the_bts; + gprs_rlcmac_bts *bts; + uint8_t ts_no = 4; + int i, j; + + printf("=== start %s ===\n", __func__); + + bts = the_bts.bts_data(); + bts->cs_downgrade_threshold = 0; + setup_bts(&the_bts, ts_no); + bts->dl_tbf_idle_msec = 200; + bts->egprs_enabled = 1; + + /* First parameter is current MCS, second one is demanded_mcs */ + establish_and_use_egprs_dl_tbf_for_retx(&the_bts, 6, 6); + establish_and_use_egprs_dl_tbf_for_retx(&the_bts, 1, 9); + establish_and_use_egprs_dl_tbf_for_retx(&the_bts, 2, 8); + establish_and_use_egprs_dl_tbf_for_retx(&the_bts, 5, 7); + establish_and_use_egprs_dl_tbf_for_retx(&the_bts, 6, 9); + establish_and_use_egprs_dl_tbf_for_retx(&the_bts, 7, 5); + establish_and_use_egprs_dl_tbf_for_retx(&the_bts, 9, 6); + + printf("=== end %s ===\n", __func__); +} + static void test_tbf_egprs_dl() { BTS the_bts; @@ -1356,6 +1579,7 @@ int main(int argc, char **argv) test_tbf_ws(); test_tbf_egprs_two_phase(); test_tbf_egprs_dl(); + test_tbf_egprs_retx_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 9bea2fd..4b694a7 100644 --- a/tests/tbf/TbfTest.err +++ b/tests/tbf/TbfTest.err @@ -5113,3 +5113,400 @@ PDCH(TS 4, TRX 0): Detaching TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=RELEASING EG 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 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==0) +- Sending new block at BSN 0, CS=MCS-6 +- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (len=100) +-- Chunk with length 100 larger than space (74) left in block: copy only remaining space, and we are done +data block (BSN 0, MCS-6): 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 +- Copying data unit 0 (BSN 0) +msg block (BSN 0, MCS-6): 07 00 00 10 40 80 c0 00 41 81 c1 01 42 82 c2 02 43 83 c3 03 44 84 c4 04 45 85 c5 05 46 86 c6 06 47 87 c7 07 48 88 c8 08 49 89 c9 09 4a 8a ca 0a 4b 8b cb 0b 4c 8c cc 0c 4d 8d cd 0d 4e 8e ce 0e 4f 8f cf 0f 50 90 d0 10 51 91 d1 11 52 12 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==1) +- Resending BSN 0 +- Copying data unit 0 (BSN 0) +msg block (BSN 0, MCS-6): 07 00 00 12 40 80 c0 00 41 81 c1 01 42 82 c2 02 43 83 c3 03 44 84 c4 04 45 85 c5 05 46 86 c6 06 47 87 c7 07 48 88 c8 08 49 89 c9 09 4a 8a ca 0a 4b 8b cb 0b 4c 8c cc 0c 4d 8d cd 0d 4e 8e ce 0e 4f 8f cf 0f 50 90 d0 10 51 91 d1 11 52 12 +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 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==0) +- Sending new block at BSN 0, CS=MCS-1 +- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (len=100) +-- Chunk with length 100 larger than space (22) left in block: copy only remaining space, and we are done +data block (BSN 0, MCS-1): 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 +- Copying data unit 0 (BSN 0) +msg block (BSN 0, MCS-1): 07 00 00 96 00 02 04 06 08 0a 0c 0e 10 12 14 16 18 1a 1c 1e 20 22 24 26 28 2a 00 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==1) +- Resending BSN 0 +- Copying data unit 0 (BSN 0) +msg block (BSN 0, MCS-1): 07 00 00 98 00 02 04 06 08 0a 0c 0e 10 12 14 16 18 1a 1c 1e 20 22 24 26 28 2a 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 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==0) +- Sending new block at BSN 0, CS=MCS-2 +- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (len=100) +-- Chunk with length 100 larger than space (28) left in block: copy only remaining space, and we are done +data block (BSN 0, MCS-2): 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b +- Copying data unit 0 (BSN 0) +msg block (BSN 0, MCS-2): 07 00 00 92 00 02 04 06 08 0a 0c 0e 10 12 14 16 18 1a 1c 1e 20 22 24 26 28 2a 2c 2e 30 32 34 36 00 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==1) +- Resending BSN 0 +- Copying data unit 0 (BSN 0) +msg block (BSN 0, MCS-2): 07 00 00 94 00 02 04 06 08 0a 0c 0e 10 12 14 16 18 1a 1c 1e 20 22 24 26 28 2a 2c 2e 30 32 34 36 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 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==0) +- Sending new block at BSN 0, CS=MCS-5 +- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (len=100) +-- Chunk with length 100 larger than space (56) left in block: copy only remaining space, and we are done +data block (BSN 0, MCS-5): 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 +- Copying data unit 0 (BSN 0) +msg block (BSN 0, MCS-5): 07 00 00 18 40 80 c0 00 41 81 c1 01 42 82 c2 02 43 83 c3 03 44 84 c4 04 45 85 c5 05 46 86 c6 06 47 87 c7 07 48 88 c8 08 49 89 c9 09 4a 8a ca 0a 4b 8b cb 0b 4c 8c cc 0c 4d 8d cd 0d +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 44 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=100 +-- 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 1, MCS-5): 58 15 38 39 3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 43 c0 01 2b 2b 2b 2b 2b 2b 2b +- Copying data unit 0 (BSN 1) +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS): Scheduling polling at FN 21 TS 4 +Polling scheduled in this TS 4 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) Scheduled Ack/Nack polling on FN=21, TS=4 +msg block (BSN 1, MCS-5): 0f 40 00 08 56 05 4e 8e ce 0e 4f 8f cf 0f 50 90 d0 10 51 91 d1 11 52 92 d2 12 53 93 d3 13 54 94 d4 14 55 95 d5 15 56 96 d6 16 57 97 d7 17 58 98 d8 d8 10 70 c0 ca ca ca ca ca ca 0a +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==2) +- Resending BSN 0 +- Resending BSN 1 +- Copying data unit 0 (BSN 0) +- Copying data unit 1 (BSN 1) +msg block (BSN 0, MCS-7): 07 00 00 02 c0 01 04 08 0c 10 14 18 1c 20 24 28 2c 30 34 38 3c 40 44 48 4c 50 54 58 5c 60 64 68 6c 70 74 78 7c 80 84 88 8c 90 94 98 9c a0 a4 a8 ac b0 b4 b8 bc c0 c4 c8 cc d0 d4 d8 dc 80 55 81 93 a3 b3 c3 d3 e3 f3 03 14 24 34 44 54 64 74 84 94 a4 b4 c4 d4 e4 f4 04 15 25 35 45 55 65 75 85 95 a5 b5 c5 d5 e5 f5 05 16 26 36 36 04 1c b0 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 +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 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==0) +- Sending new block at BSN 0, CS=MCS-6 +- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (len=100) +-- Chunk with length 100 larger than space (74) left in block: copy only remaining space, and we are done +data block (BSN 0, MCS-6): 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 +- Copying data unit 0 (BSN 0) +msg block (BSN 0, MCS-6): 07 00 00 10 40 80 c0 00 41 81 c1 01 42 82 c2 02 43 83 c3 03 44 84 c4 04 45 85 c5 05 46 86 c6 06 47 87 c7 07 48 88 c8 08 49 89 c9 09 4a 8a ca 0a 4b 8b cb 0b 4c 8c cc 0c 4d 8d cd 0d 4e 8e ce 0e 4f 8f cf 0f 50 90 d0 10 51 91 d1 11 52 12 +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 26 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=100 +-- 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 1, MCS-6): 34 5d 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 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 1) +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS): Scheduling polling at FN 21 TS 4 +Polling scheduled in this TS 4 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) Scheduled Ack/Nack polling on FN=21, TS=4 +msg block (BSN 1, MCS-6): 0f 40 00 00 4d 97 d2 12 53 93 d3 13 54 94 d4 14 55 95 d5 15 56 96 d6 16 57 97 d7 17 58 98 d8 d8 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 (V(A)==0 .. V(S)==2) +- Resending BSN 0 +- Resending BSN 1 +- Copying data unit 0 (BSN 0) +- Copying data unit 1 (BSN 1) +msg block (BSN 0, MCS-9): 07 00 00 02 28 01 04 08 0c 10 14 18 1c 20 24 28 2c 30 34 38 3c 40 44 48 4c 50 54 58 5c 60 64 68 6c 70 74 78 7c 80 84 88 8c 90 94 98 9c a0 a4 a8 ac b0 b4 b8 bc c0 c4 c8 cc d0 d4 d8 dc e0 e4 e8 ec f0 f4 f8 fc 00 05 09 0d 11 15 19 1d 21 25 41 d3 a5 b4 c4 d4 e4 f4 04 15 25 35 45 55 65 75 85 95 a5 b5 c5 d5 e5 f5 05 16 26 36 36 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 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 +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 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==0) +- Sending new block at BSN 0, CS=MCS-7 +- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (len=100) +-- Chunk with length 100 larger than space (56) left in block: copy only remaining space, and we are done +data block (BSN 0, MCS-7): 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 +- Sending new block at BSN 1, CS=MCS-7 +-- Chunk with length 44 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=100 +-- 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 1, MCS-7): 58 15 38 39 3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 43 c0 01 2b 2b 2b 2b 2b 2b 2b +- 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). +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS): Scheduling polling at FN 17 TS 4 +Polling scheduled in this TS 4 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) Scheduled Ack/Nack polling on FN=17, TS=4 +msg block (BSN 0, MCS-7): 0f 00 00 02 a0 01 04 08 0c 10 14 18 1c 20 24 28 2c 30 34 38 3c 40 44 48 4c 50 54 58 5c 60 64 68 6c 70 74 78 7c 80 84 88 8c 90 94 98 9c a0 a4 a8 ac b0 b4 b8 bc c0 c4 c8 cc d0 d4 d8 dc 80 55 81 93 a3 b3 c3 d3 e3 f3 03 14 24 34 44 54 64 74 84 94 a4 b4 c4 d4 e4 f4 04 15 25 35 45 55 65 75 85 95 a5 b5 c5 d5 e5 f5 05 16 26 36 36 04 1c b0 b2 b2 b2 b2 b2 b2 02 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==2) +- Resending BSN 0 +- Copying data unit 0 (BSN 0) +msg block (BSN 0, MCS-5): 07 00 00 18 40 80 c0 00 41 81 c1 01 42 82 c2 02 43 83 c3 03 44 84 c4 04 45 85 c5 05 46 86 c6 06 47 87 c7 07 48 88 c8 08 49 89 c9 09 4a 8a ca 0a 4b 8b cb 0b 4c 8c cc 0c 4d 8d cd 0d +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==2) +- Resending BSN 1 +- Copying data unit 0 (BSN 1) +msg block (BSN 1, MCS-5): 07 40 00 08 56 05 4e 8e ce 0e 4f 8f cf 0f 50 90 d0 10 51 91 d1 11 52 92 d2 12 53 93 d3 13 54 94 d4 14 55 95 d5 15 56 96 d6 16 57 97 d7 17 58 98 d8 d8 10 70 c0 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 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==0) +- Sending new block at BSN 0, CS=MCS-9 +- Dequeue next LLC for TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) (len=100) +-- Chunk with length 100 larger than space (74) left in block: copy only remaining space, and we are done +data block (BSN 0, MCS-9): 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 +- Sending new block at BSN 1, CS=MCS-9 +-- Chunk with length 26 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=100 +-- 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 1, MCS-9): 34 5d 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 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 0) +- Copying data unit 1 (BSN 1) +- Scheduling Ack/Nack polling, because is was requested explicitly (e.g. first final block sent). +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS): Scheduling polling at FN 17 TS 4 +Polling scheduled in this TS 4 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) Scheduled Ack/Nack polling on FN=17, TS=4 +msg block (BSN 0, MCS-9): 0f 00 00 02 00 01 04 08 0c 10 14 18 1c 20 24 28 2c 30 34 38 3c 40 44 48 4c 50 54 58 5c 60 64 68 6c 70 74 78 7c 80 84 88 8c 90 94 98 9c a0 a4 a8 ac b0 b4 b8 bc c0 c4 c8 cc d0 d4 d8 dc e0 e4 e8 ec f0 f4 f8 fc 00 05 09 0d 11 15 19 1d 21 25 41 d3 a5 b4 c4 d4 e4 f4 04 15 25 35 45 55 65 75 85 95 a5 b5 c5 d5 e5 f5 05 16 26 36 36 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 02 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==2) +- Resending BSN 0 +- Copying data unit 0 (BSN 0) +msg block (BSN 0, MCS-6): 07 00 00 12 40 80 c0 00 41 81 c1 01 42 82 c2 02 43 83 c3 03 44 84 c4 04 45 85 c5 05 46 86 c6 06 47 87 c7 07 48 88 c8 08 49 89 c9 09 4a 8a ca 0a 4b 8b cb 0b 4c 8c cc 0c 4d 8d cd 0d 4e 8e ce 0e 4f 8f cf 0f 50 90 d0 10 51 91 d1 11 52 12 +TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink (V(A)==0 .. V(S)==2) +- Resending BSN 1 +- Copying data unit 0 (BSN 1) +msg block (BSN 1, MCS-6): 07 40 00 02 4d 97 d2 12 53 93 d3 13 54 94 d4 14 55 95 d5 15 56 96 d6 16 57 97 d7 17 58 98 d8 d8 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 ********** diff --git a/tests/tbf/TbfTest.ok b/tests/tbf/TbfTest.ok index 441b444..8a7862f 100644 --- a/tests/tbf/TbfTest.ok +++ b/tests/tbf/TbfTest.ok @@ -43,3 +43,12 @@ Testing MCS-7 Testing MCS-8 Testing MCS-9 === end test_tbf_egprs_dl === +=== start test_tbf_egprs_retx_dl === +Testing retx for MCS 6 - 6 +Testing retx for MCS 1 - 9 +Testing retx for MCS 2 - 8 +Testing retx for MCS 5 - 7 +Testing retx for MCS 6 - 9 +Testing retx for MCS 7 - 5 +Testing retx for MCS 9 - 6 +=== end test_tbf_egprs_retx_dl === -- 1.7.9.5 From arvind.sirsikar at radisys.com Mon Apr 25 10:30:58 2016 From: arvind.sirsikar at radisys.com (Aravind Sirsikar) Date: Mon, 25 Apr 2016 16:00:58 +0530 Subject: [PATCH 2/4] Add Accessor functions for MCS change in Retx In-Reply-To: <1461580260-9199-1-git-send-email-arvind.sirsikar@radisys.com> References: <1461580260-9199-1-git-send-email-arvind.sirsikar@radisys.com> Message-ID: <1461580260-9199-3-git-send-email-arvind.sirsikar@radisys.com> Add accessor function in existing classes to support MCS change during the retransmission in EGPRS DL --- src/gprs_coding_scheme.h | 19 ++++++++++++++++++- src/gprs_ms.cpp | 5 +++++ src/gprs_ms.h | 1 + 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/gprs_coding_scheme.h b/src/gprs_coding_scheme.h index bb0bad4..fb3a191 100644 --- a/src/gprs_coding_scheme.h +++ b/src/gprs_coding_scheme.h @@ -70,6 +70,7 @@ public: unsigned int to_num() const; GprsCodingScheme& operator =(Scheme s); + bool operator == (Scheme s); GprsCodingScheme& operator =(GprsCodingScheme o); bool isValid() const {return UNKNOWN <= m_scheme && m_scheme <= MCS9;} @@ -111,6 +112,9 @@ public: static GprsCodingScheme getEgprsByNum(unsigned num); static const char *modeName(Mode mode); + static Scheme get_retx_mcs(const GprsCodingScheme &mcs, + const GprsCodingScheme &retx_mcs); + static enum Scheme egprs_mcs_retx_tbl[MAX_NUM_ARQ] [MAX_NUM_MCS][MAX_NUM_MCS]; private: @@ -196,6 +200,13 @@ inline bool operator ==(GprsCodingScheme a, GprsCodingScheme b) return GprsCodingScheme::Scheme(a) == GprsCodingScheme::Scheme(b); } +inline bool GprsCodingScheme::operator == (Scheme scheme) +{ + if (this->m_scheme == scheme) + return true; + return false; +} + inline bool operator !=(GprsCodingScheme a, GprsCodingScheme b) { return !(a == b); @@ -221,4 +232,10 @@ inline bool operator >=(GprsCodingScheme a, GprsCodingScheme b) { return a == b || a > b; } - +inline GprsCodingScheme::Scheme GprsCodingScheme::get_retx_mcs( + const GprsCodingScheme &mcs, + const GprsCodingScheme &demanded_mcs) +{ + return egprs_mcs_retx_tbl[EGPRS_ARQ2][mcs.to_num() - 1] + [demanded_mcs.to_num() - 1]; +} diff --git a/src/gprs_ms.cpp b/src/gprs_ms.cpp index 4296fd3..b9a04fb 100644 --- a/src/gprs_ms.cpp +++ b/src/gprs_ms.cpp @@ -574,6 +574,11 @@ GprsCodingScheme GprsMs::max_cs_ul() const return GprsCodingScheme(GprsCodingScheme::MCS4); } +void GprsMs::set_current_cs_dl(GprsCodingScheme::Scheme scheme) +{ + m_current_cs_dl = scheme; +} + GprsCodingScheme GprsMs::max_cs_dl() const { struct gprs_rlcmac_bts *bts_data; diff --git a/src/gprs_ms.h b/src/gprs_ms.h index b07f175..bcc4fb3 100644 --- a/src/gprs_ms.h +++ b/src/gprs_ms.h @@ -86,6 +86,7 @@ public: uint8_t egprs_ms_class() const; void set_ms_class(uint8_t ms_class); void set_egprs_ms_class(uint8_t ms_class); + void set_current_cs_dl(GprsCodingScheme::Scheme scheme); GprsCodingScheme current_cs_ul() const; GprsCodingScheme current_cs_dl() const; -- 1.7.9.5 From nhofmeyr at sysmocom.de Tue Apr 26 11:06:59 2016 From: nhofmeyr at sysmocom.de (Neels Hofmeyr) Date: Tue, 26 Apr 2016 13:06:59 +0200 Subject: [PATCH 5/5] Change internal API for consistency In-Reply-To: <1461242157-14223-5-git-send-email-msuraev@sysmocom.de> References: <1461242157-14223-1-git-send-email-msuraev@sysmocom.de> <1461242157-14223-5-git-send-email-msuraev@sysmocom.de> Message-ID: <20160426110659.GB14118@ass40.sysmocom.de> On Thu, Apr 21, 2016 at 02:35:57PM +0200, msuraev at sysmocom.de wrote: > - void *priv; /* user reference */ > + uint8_t trx; So I presume you are certain that priv was so far only used for the trx number, that there are no other callers using priv, and that it makes sense to not have a priv pointer anymore? Looking at the patch it does look like priv was never really a priv in the arbitrary-backpointer case, but IMHO it would be good to clarify that in the log message. > - int rc = 0; > - int trx, ts; > - int i; > + int rc = 0, ts, i; Unrelated cosmetic change, keep that out of this patch, i.e. only remove the trx int, the point being that I noticed only on the second glance. Also I believe we prefer to have each variable on its own line. ~Neels -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: Digital signature URL: From msuraev at sysmocom.de Tue Apr 26 11:14:54 2016 From: msuraev at sysmocom.de (Max) Date: Tue, 26 Apr 2016 13:14:54 +0200 Subject: [PATCH 5/5] Change internal API for consistency In-Reply-To: <20160426110659.GB14118@ass40.sysmocom.de> References: <1461242157-14223-1-git-send-email-msuraev@sysmocom.de> <1461242157-14223-5-git-send-email-msuraev@sysmocom.de> <20160426110659.GB14118@ass40.sysmocom.de> Message-ID: <571F4DAE.5020008@sysmocom.de> Thanks. Comments are inline. On 04/26/2016 01:06 PM, Neels Hofmeyr wrote: > On Thu, Apr 21, 2016 at 02:35:57PM +0200, msuraev at sysmocom.de wrote: >> - void *priv; /* user reference */ >> + uint8_t trx; > So I presume you are certain that priv was so far only used for the trx > number, that there are no other callers using priv, and that it makes > sense to not have a priv pointer anymore? Yes. > Looking at the patch it does look like priv was never really a priv in the > arbitrary-backpointer case, but IMHO it would be good to clarify that in > the log message. > >> - int rc = 0; >> - int trx, ts; >> - int i; >> + int rc = 0, ts, i; > Unrelated cosmetic change, keep that out of this patch, i.e. only remove > the trx int, the point being that I noticed only on the second glance. Noted. > Also I believe we prefer to have each variable on its own line. > It doesn't look that way from looking at the other code. It also decreases readability by cluttering the code with useless repetitions. -- Max Suraev http://www.sysmocom.de/ ======================================================================= * sysmocom - systems for mobile communications GmbH * Alt-Moabit 93 * 10559 Berlin, Germany * Sitz / Registered office: Berlin, HRB 134158 B * Geschaeftsfuehrer / Managing Directors: Holger Freyther, Harald Welte From nhofmeyr at sysmocom.de Thu Apr 28 11:31:09 2016 From: nhofmeyr at sysmocom.de (Neels Hofmeyr) Date: Thu, 28 Apr 2016 13:31:09 +0200 Subject: [PATCH 5/5] Change internal API for consistency In-Reply-To: <571F4DAE.5020008@sysmocom.de> References: <1461242157-14223-1-git-send-email-msuraev@sysmocom.de> <1461242157-14223-5-git-send-email-msuraev@sysmocom.de> <20160426110659.GB14118@ass40.sysmocom.de> <571F4DAE.5020008@sysmocom.de> Message-ID: <20160428113109.GG2164@ass40.sysmocom.de> On Tue, Apr 26, 2016 at 01:14:54PM +0200, Max wrote: > > Also I believe we prefer to have each variable on its own line. > > > It doesn't look that way from looking at the other code. It also > decreases readability by cluttering the code with useless repetitions. but removing/adding variables where there are more than one per line makes the patches less readable, and potentially introduces more merge conflicts than necessary... I used to be against one-per-line but have changed my opinion quite some time ago :) ~Neels -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: Digital signature URL: