pespin has uploaded this change for review. ( 
https://gerrit.osmocom.org/c/libosmo-gprs/+/31576 )


Change subject: rlcmac: dl_tbf: Improve logic requesting a new UL TBF
......................................................................

rlcmac: dl_tbf: Improve logic requesting a new UL TBF

Change-Id: I702872ba32a410bb5f09943af3cdadca482562db
---
M include/osmocom/gprs/rlcmac/gre.h
M src/rlcmac/gre.c
M src/rlcmac/rlcmac_enc.c
M src/rlcmac/tbf_ul.c
M tests/rlcmac/rlcmac_prim_test.c
M tests/rlcmac/rlcmac_prim_test.err
M tests/rlcmac/rlcmac_prim_test.ok
7 files changed, 147 insertions(+), 4 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/libosmo-gprs refs/changes/76/31576/1

diff --git a/include/osmocom/gprs/rlcmac/gre.h 
b/include/osmocom/gprs/rlcmac/gre.h
index ca5f773..f6397a6 100644
--- a/include/osmocom/gprs/rlcmac/gre.h
+++ b/include/osmocom/gprs/rlcmac/gre.h
@@ -20,6 +20,10 @@
 struct gprs_rlcmac_entity *gprs_rlcmac_entity_alloc(uint32_t tlli);
 void gprs_rlcmac_entity_free(struct gprs_rlcmac_entity *gre);

+bool gprs_rlcmac_entity_in_packet_idle_mode(const struct gprs_rlcmac_entity 
*gre);
+bool gprs_rlcmac_entity_in_packet_transfer_mode(const struct 
gprs_rlcmac_entity *gre);
+bool gprs_rlcmac_entity_have_tx_data_queued(const struct gprs_rlcmac_entity 
*gre);
+
 int gprs_rlcmac_entity_llc_enqueue(struct gprs_rlcmac_entity *gre, uint8_t 
*ll_pdu, unsigned int ll_pdu_len,
                                   enum osmo_gprs_rlcmac_llc_sapi sapi, uint8_t 
radio_prio);

diff --git a/src/rlcmac/gre.c b/src/rlcmac/gre.c
index 40cd585..53d53c7 100644
--- a/src/rlcmac/gre.c
+++ b/src/rlcmac/gre.c
@@ -66,6 +66,40 @@
        talloc_free(gre);
 }

+/* TS 44.060 5.3 In packet idle mode:
+* - no temporary block flow (TBF) exists..
+* - the mobile station monitors the relevant paging subchannels on CCCH. In 
packet
+* idle mode, upper layers may require the transfer of a upper layer PDU, which
+* implicitly triggers the establishment of a TBF and the transition to packet
+* transfer mode. In packet idle mode, upper layers may require the 
establishment
+* of an RR connection. When the mobile station enters dedicated mode (see 3GPP 
TS
+* 44.018), it may leave the packet idle mode, if the mobile station limitations
+* make it unable to handle the RR connection and the procedures in packet idle
+* mode simultaneously.*/
+bool gprs_rlcmac_entity_in_packet_idle_mode(const struct gprs_rlcmac_entity 
*gre)
+{
+       return !gre->ul_tbf && !gre->dl_tbf;
+}
+
+/* TS 44.060 5.4 "In packet transfer mode, the mobile station is allocated 
radio
+* resources providing one or more TBFs. [...]
+* When a transfer of upper layer PDUs
+* terminates, in either downlink or uplink direction, the corresponding TBF is
+* released. In packet transfer mode, when all TBFs have been released, in 
downlink
+* and uplink direction, the mobile station returns to packet idle mode."
+*/
+bool gprs_rlcmac_entity_in_packet_transfer_mode(const struct 
gprs_rlcmac_entity *gre)
+{
+       return gre->ul_tbf || gre->dl_tbf;
+}
+
+/* Whether MS has data queued from upper layers waiting to be transmitted in 
the
+ * Tx queue (an active UL TBF may still have some extra data) */
+bool gprs_rlcmac_entity_have_tx_data_queued(const struct gprs_rlcmac_entity 
*gre)
+{
+       return gprs_rlcmac_llc_queue_size(gre->llc_queue) > 0;
+}
+
 int gprs_rlcmac_entity_llc_enqueue(struct gprs_rlcmac_entity *gre, uint8_t 
*ll_pdu, unsigned int ll_pdu_len,
                                   enum osmo_gprs_rlcmac_llc_sapi sapi, uint8_t 
radio_prio)
 {
@@ -75,7 +109,11 @@
        if (rc < 0)
                return rc;

-       if (!gre->ul_tbf) {
+       /* TS 44.060 5.3 "In packet idle mode, upper layers may require the
+       * transfer of a upper layer PDU, which implicitly triggers the
+       * establishment of a TBF and the transition to packet transfer mode." */
+       if (gprs_rlcmac_entity_in_packet_idle_mode(gre)) {
+               OSMO_ASSERT(!gre->ul_tbf);
                /* We have new data in the queue but we have no ul_tbf. 
Allocate one and start UL Assignment. */
                gre->ul_tbf = gprs_rlcmac_ul_tbf_alloc(gre);
                if (!gre->ul_tbf)
diff --git a/src/rlcmac/rlcmac_enc.c b/src/rlcmac/rlcmac_enc.c
index 6bceb8d..94f85f2 100644
--- a/src/rlcmac/rlcmac_enc.c
+++ b/src/rlcmac/rlcmac_enc.c
@@ -395,8 +395,9 @@
        ack->DOWNLINK_TFI = dl_tbf->cur_alloc.dl_tfi;
        
gprs_rlcmac_enc_prepare_pkt_ack_nack_desc_gprs(&ack->Ack_Nack_Description, 
dl_tbf);

-       /* Channel Request Description */
-       if (gre->ul_tbf && gprs_rlcmac_tbf_ul_ass_pending(gre->ul_tbf)) {
+       /* Channel Request Description. Request a UL-TBF if we have UL data
+        * queued to send and no active UL BF (TS 44.060 8.1.2.5) */
+       if (!gre->ul_tbf && gprs_rlcmac_entity_have_tx_data_queued(gre)) {
                Channel_Request_Description_t *chan_req = 
&ack->Channel_Request_Description;
                ack->Exist_Channel_Request_Description = 1;
                chan_req->PEAK_THROUGHPUT_CLASS = 0; /* TODO */
diff --git a/src/rlcmac/tbf_ul.c b/src/rlcmac/tbf_ul.c
index fbef343..e73b7f7 100644
--- a/src/rlcmac/tbf_ul.c
+++ b/src/rlcmac/tbf_ul.c
@@ -329,7 +329,7 @@
 bool gprs_rlcmac_ul_tbf_have_data(const struct gprs_rlcmac_ul_tbf *ul_tbf)
 {
        return (ul_tbf->llc_tx_msg && msgb_length(ul_tbf->llc_tx_msg) > 0) ||
-              (gprs_rlcmac_llc_queue_size(ul_tbf->tbf.gre->llc_queue) > 0);
+              gprs_rlcmac_entity_have_tx_data_queued(ul_tbf->tbf.gre);
 }

 bool gprs_rlcmac_ul_tbf_shall_keep_open(const struct gprs_rlcmac_ul_tbf 
*ul_tbf, const struct gprs_rlcmac_rts_block_ind *bi)
diff --git a/tests/rlcmac/rlcmac_prim_test.c b/tests/rlcmac/rlcmac_prim_test.c
index 02ee04c..bbd7dcd 100644
--- a/tests/rlcmac/rlcmac_prim_test.c
+++ b/tests/rlcmac/rlcmac_prim_test.c
@@ -825,6 +825,7 @@
        cleanup_test();
 }

+
 /* PCU allocates a DL TBF through PCH ImmAss for MS (when in packet-idle) */
 static void test_dl_tbf_ccch_assign(void)
 {
@@ -869,6 +870,59 @@
        cleanup_test();
 }

+/* PCU allocates a DL TBF through PCH ImmAss for MS (when in packet-idle). Then
+ * upper layers want to transmit more data so during DL ACK/NACK a new UL TBF 
is
+ * requested. */
+static void test_dl_tbf_ccch_assign_requests_ul_tbf_pacch(void)
+{
+       struct osmo_gprs_rlcmac_prim *rlcmac_prim;
+       int rc;
+       struct msgb *dl_data_msg;
+
+       printf("=== %s start ===\n", __func__);
+       prepare_test();
+       uint32_t tlli = 0x0000001;
+       uint8_t ts_nr = 7;
+       uint8_t usf = 0;
+       uint32_t rts_fn = 4;
+       uint8_t dl_tfi = 0;
+       uint8_t rrbp = GPRS_RLCMAC_RRBP_N_plus_17_18;
+
+       /* Notify RLCMAC about our TLLI */
+       rlcmac_prim = osmo_gprs_rlcmac_prim_alloc_gmmrr_assign_req(tlli);
+       rc = osmo_gprs_rlcmac_prim_upper_down(rlcmac_prim);
+
+       OSMO_ASSERT(sizeof(ccch_imm_ass_pkt_dl_tbf) == GSM_MACBLOCK_LEN);
+       rlcmac_prim = osmo_gprs_rlcmac_prim_alloc_l1ctl_ccch_data_ind(0, 
ccch_imm_ass_pkt_dl_tbf);
+       rc = osmo_gprs_rlcmac_prim_lower_up(rlcmac_prim);
+       OSMO_ASSERT(rc == 0);
+
+       /* Transmit some DL LLC data MS<-PCU */
+       dl_data_msg = create_dl_data_block(dl_tfi, usf, GPRS_RLCMAC_CS_1, 0, 
true, true, rrbp);
+       rlcmac_prim = osmo_gprs_rlcmac_prim_alloc_l1ctl_pdch_data_ind(ts_nr, 
rts_fn, 0, 0, 0,
+                                                                     
msgb_data(dl_data_msg),
+                                                                     
msgb_length(dl_data_msg));
+       rc = osmo_gprs_rlcmac_prim_lower_up(rlcmac_prim);
+       OSMO_ASSERT(rc == 0);
+       msgb_free(dl_data_msg);
+
+       /* Upper layers wants to transmit some payload, but no UL TBF exists 
yet: */
+       /* Submit 14 bytes to fit in 1 RLCMAC block to shorten test and end up 
in FINISHED state quickly: */
+       rlcmac_prim = osmo_gprs_rlcmac_prim_alloc_grr_unitdata_req(tlli, 
pdu_llc_gmm_att_req, 14);
+       rlcmac_prim->grr.unitdata_req.sapi = OSMO_GPRS_RLCMAC_LLC_SAPI_GMM;
+       rc = osmo_gprs_rlcmac_prim_upper_down(rlcmac_prim);
+       OSMO_ASSERT(rc == 0);
+
+       /* Trigger transmission of DL ACK/NACK, which should request a UL TBF 
in "Channel Request Description" */
+       rts_fn = rrbp2fn(rts_fn, rrbp);
+       rlcmac_prim = osmo_gprs_rlcmac_prim_alloc_l1ctl_pdch_rts_ind(ts_nr, 
rts_fn, usf);
+       rc = osmo_gprs_rlcmac_prim_lower_up(rlcmac_prim);
+       OSMO_ASSERT(rc == 0);
+
+       printf("=== %s end ===\n", __func__);
+       cleanup_test();
+}
+
 static const struct log_info_cat test_log_categories[] = { };
 static const struct log_info test_log_info = {
        .cat = test_log_categories,
@@ -899,6 +953,7 @@
        test_ul_tbf_last_data_cv0_retrans_max();
        test_ul_tbf_request_another_ul_tbf();
        test_dl_tbf_ccch_assign();
+       test_dl_tbf_ccch_assign_requests_ul_tbf_pacch();

        talloc_free(tall_ctx);
 }
diff --git a/tests/rlcmac/rlcmac_prim_test.err 
b/tests/rlcmac/rlcmac_prim_test.err
index 0d8dd3a..d42a822 100644
--- a/tests/rlcmac/rlcmac_prim_test.err
+++ b/tests/rlcmac/rlcmac_prim_test.err
@@ -620,3 +620,33 @@
 DLGLOBAL DEBUG (ts=7,fn=21,usf=0) Tx DL ACK/NACK FinalAck=1
 DLGLOBAL DEBUG TBF(DL:NR-0:TLLI-00000001) - V(N): 
"IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIR" R=Received 
I=Invalid
 DLGLOBAL INFO DL_TBF{FINISHED}: Deallocated
+DLGLOBAL INFO Rx from upper layers: GMMRR-ASSIGN.request
+DLGLOBAL INFO GMMRR-ASSIGN.req: creating new entity TLLI=0x00000001
+DLGLOBAL INFO Rx from lower layers: L1CTL-CCCH_DATA.indication
+DLGLOBAL INFO GRE(00000001) Got PCH IMM_ASS (DL_TBF): DL_TFI=0 TS=7
+DLGLOBAL INFO DL_TBF{NEW}: Allocated
+DLGLOBAL INFO DL_TBF{NEW}: Received Event DL_ASS_COMPL
+DLGLOBAL INFO TBF(DL:NR-0:TLLI-00000001) Send L1CTL-CF_DL_TBF.req 
dl_slotmask=0x80 dl_tfi=0
+DLGLOBAL INFO DL_TBF{NEW}: state_chg to FLOW
+DLGLOBAL INFO Rx from lower layers: L1CTL-PDCH_DATA.indication
+DLGLOBAL DEBUG TBF(DL:NR-0:TLLI-00000001) Rx new DL data
+DLGLOBAL DEBUG TBF(DL:NR-0:TLLI-00000001) DL DATA TFI=0 received (V(Q)=0 .. 
V(R)=0)
+DLGLOBAL DEBUG TBF(DL:NR-0:TLLI-00000001) Got CS-1 RLC data block: FBI=1, 
BSN=0, SPB=0, S/P=1 RRBP=1, E=0, bitoffs=24
+DLGLOBAL DEBUG TBF(DL:NR-0:TLLI-00000001) BSN 0 storing in window (0..63)
+DLGLOBAL DEBUG TBF(DL:NR-0:TLLI-00000001) data_length=20, data=19 43 c0 01 2b 
2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b
+DLGLOBAL DEBUG - Raising V(R) to 1
+DLGLOBAL DEBUG - Taking block 0 out, raising V(Q) to 1
+DLGLOBAL DEBUG TBF(DL:NR-0:TLLI-00000001) Assembling frames: (len=20)
+DLGLOBAL DEBUG DL DATA LI contains extension octet: LI=6, M=0, E=1, count=0
+DLGLOBAL DEBUG TBF(DL:NR-0:TLLI-00000001) Frame 1 starts at offset 1, 
length=6, is_complete=1
+DLGLOBAL DEBUG TBF(DL:NR-0:TLLI-00000001) complete UL frame len=6
+DLGLOBAL DEBUG TBF(DL:NR-0:TLLI-00000001) No gaps in received block, last 
block: BSN=0 FBI=1
+DLGLOBAL DEBUG TBF(DL:NR-0:TLLI-00000001) Finished with DL TBF
+DLGLOBAL INFO DL_TBF{FLOW}: Received Event LAST_DL_DATA_RECVD
+DLGLOBAL INFO DL_TBF{FLOW}: state_chg to FINISHED
+DLGLOBAL DEBUG Register POLL (TS=7 FN=21, reason=DL_ACK)
+DLGLOBAL INFO Rx from upper layers: GRR-UNITDATA.request
+DLGLOBAL INFO Rx from lower layers: L1CTL-PDCH_RTS.indication
+DLGLOBAL DEBUG (ts=7,fn=21,usf=0) Tx DL ACK/NACK FinalAck=1
+DLGLOBAL DEBUG TBF(DL:NR-0:TLLI-00000001) - V(N): 
"IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIR" R=Received 
I=Invalid
+DLGLOBAL INFO DL_TBF{FINISHED}: Deallocated
diff --git a/tests/rlcmac/rlcmac_prim_test.ok b/tests/rlcmac/rlcmac_prim_test.ok
index 9e913ed..3effeb3 100644
--- a/tests/rlcmac/rlcmac_prim_test.ok
+++ b/tests/rlcmac/rlcmac_prim_test.ok
@@ -117,3 +117,9 @@
 test_rlcmac_prim_up_cb(): Rx GRR-UNITDATA.indication TLLI=0x00000001 ll=[43 c0 
01 2b 2b 2b ]
 test_rlcmac_prim_down_cb(): Rx L1CTL-PDCH_DATA.request fn=21 ts=7 data_len=23 
data=[40 14 00 00 00 00 00 00 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b ]
 === test_dl_tbf_ccch_assign end ===
+=== test_dl_tbf_ccch_assign_requests_ul_tbf_pacch start ===
+sys={0.000000}, mono={0.000000}: clock_override_set
+test_rlcmac_prim_down_cb(): Rx L1CTL-CFG_DL_TBF.request dl_tbf_nr=0 
dl_slotmask=0x80 dl_tfi=0
+test_rlcmac_prim_up_cb(): Rx GRR-UNITDATA.indication TLLI=0x00000001 ll=[43 c0 
01 2b 2b 2b ]
+test_rlcmac_prim_down_cb(): Rx L1CTL-PDCH_DATA.request fn=21 ts=7 data_len=23 
data=[40 14 00 00 00 00 00 00 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b ]
+=== test_dl_tbf_ccch_assign_requests_ul_tbf_pacch end ===

--
To view, visit https://gerrit.osmocom.org/c/libosmo-gprs/+/31576
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.osmocom.org/settings

Gerrit-Project: libosmo-gprs
Gerrit-Branch: master
Gerrit-Change-Id: I702872ba32a410bb5f09943af3cdadca482562db
Gerrit-Change-Number: 31576
Gerrit-PatchSet: 1
Gerrit-Owner: pespin <pes...@sysmocom.de>
Gerrit-MessageType: newchange

Reply via email to