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


Change subject: rlcmac: ul_tbf: Answer Pkt Ul Ack/Nack poll with Pkt Ctrl Ack
......................................................................

rlcmac: ul_tbf: Answer Pkt Ul Ack/Nack poll with Pkt Ctrl Ack

Related: OS#5500
Change-Id: I833d0f189c06d093ce9bd4c36c37024cf5cb6446
---
M include/osmocom/gprs/rlcmac/rlcmac_enc.h
M include/osmocom/gprs/rlcmac/tbf_ul.h
M src/rlcmac/rlcmac.c
M src/rlcmac/rlcmac_enc.c
M src/rlcmac/sched.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
9 files changed, 119 insertions(+), 28 deletions(-)



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

diff --git a/include/osmocom/gprs/rlcmac/rlcmac_enc.h 
b/include/osmocom/gprs/rlcmac/rlcmac_enc.h
index 1a0f586..b729522 100644
--- a/include/osmocom/gprs/rlcmac/rlcmac_enc.h
+++ b/include/osmocom/gprs/rlcmac/rlcmac_enc.h
@@ -48,3 +48,5 @@
 void gprs_rlcmac_enc_prepare_pkt_resource_req(RlcMacUplink_t *block, struct 
gprs_rlcmac_ul_tbf *ul_tbf, enum gprs_rlcmac_access_type acc_type);

 void gprs_rlcmac_enc_prepare_pkt_downlink_ack_nack(RlcMacUplink_t *block, 
const struct gprs_rlcmac_dl_tbf *dl_tbf);
+
+void gprs_rlcmac_enc_prepare_pkt_ctrl_ack(RlcMacUplink_t *block, uint32_t 
tlli);
\ No newline at end of file
diff --git a/include/osmocom/gprs/rlcmac/tbf_ul.h 
b/include/osmocom/gprs/rlcmac/tbf_ul.h
index c187938..32d7036 100644
--- a/include/osmocom/gprs/rlcmac/tbf_ul.h
+++ b/include/osmocom/gprs/rlcmac/tbf_ul.h
@@ -52,9 +52,10 @@

 struct msgb *gprs_rlcmac_ul_tbf_data_create(struct gprs_rlcmac_ul_tbf *ul_tbf, 
const struct gprs_rlcmac_rts_block_ind *bi);
 struct msgb *gprs_rlcmac_ul_tbf_dummy_create(const struct gprs_rlcmac_ul_tbf 
*ul_tbf);
+struct msgb *gprs_rlcmac_ul_tbf_create_pkt_ctrl_ack(const struct 
gprs_rlcmac_ul_tbf *ul_tbf);

-int gprs_rlcmac_ul_tbf_handle_pkt_ul_ack_nack(struct gprs_rlcmac_ul_tbf 
*ul_tbf, bool final_ack,
-                                             unsigned first_bsn, struct bitvec 
*rbb);
+int gprs_rlcmac_ul_tbf_handle_pkt_ul_ack_nack(struct gprs_rlcmac_ul_tbf 
*ul_tbf,
+                                             const RlcMacDownlink_t *dl_block);

 static inline struct gprs_rlcmac_tbf *ul_tbf_as_tbf(struct gprs_rlcmac_ul_tbf 
*ul_tbf)
 {
diff --git a/src/rlcmac/rlcmac.c b/src/rlcmac/rlcmac.c
index 39e5c9e..b273b68 100644
--- a/src/rlcmac/rlcmac.c
+++ b/src/rlcmac/rlcmac.c
@@ -320,19 +320,7 @@

 static int gprs_rlcmac_handle_pkt_ul_ack_nack(const struct 
osmo_gprs_rlcmac_prim *rlcmac_prim, const RlcMacDownlink_t *dl_block)
 {
-       const Packet_Uplink_Ack_Nack_t *ack = 
&dl_block->u.Packet_Uplink_Ack_Nack;
-       const PU_AckNack_GPRS_t *gprs = &ack->u.PU_AckNack_GPRS_Struct;
-       const Ack_Nack_Description_t *ack_desc = &gprs->Ack_Nack_Description;
        struct gprs_rlcmac_ul_tbf *ul_tbf;
-       int bsn_begin, bsn_end;
-       int num_blocks;
-       uint8_t bits_data[GPRS_RLCMAC_GPRS_WS/8];
-       char show_bits[GPRS_RLCMAC_GPRS_WS + 1];
-       struct bitvec bits = {
-               .data = bits_data,
-               .data_len = sizeof(bits_data),
-               .cur_bit = 0,
-       };
        int rc;

        ul_tbf = gprs_rlcmac_find_ul_tbf_by_tfi(dl_block->TFI);
@@ -344,16 +332,15 @@
                return -ENOENT;
        }

-       num_blocks = gprs_rlcmac_decode_gprs_acknack_bits(
-               ack_desc, &bits, &bsn_begin, &bsn_end, ul_tbf->ulw);
+       rc = gprs_rlcmac_ul_tbf_handle_pkt_ul_ack_nack(ul_tbf, dl_block);

-       LOGPTBFUL(ul_tbf, LOGL_DEBUG,
-               "Got GPRS UL ACK bitmap: SSN: %d, BSN %d to %d - 1 (%d blocks), 
\"%s\"\n",
-               ack_desc->STARTING_SEQUENCE_NUMBER,
-               bsn_begin, bsn_end, num_blocks,
-               (gprs_rlcmac_extract_rbb(&bits, show_bits), show_bits));
-
-       rc = gprs_rlcmac_ul_tbf_handle_pkt_ul_ack_nack(ul_tbf, 
ack_desc->FINAL_ACK_INDICATION, bsn_begin, &bits);
+       /* If RRBP contains valid data, schedule a response (PKT CONTROL ACK or 
PKT RESOURCE REQ). */
+       if (dl_block->SP) {
+               uint32_t poll_fn = rrbp2fn(rlcmac_prim->l1ctl.pdch_data_ind.fn, 
dl_block->RRBP);
+               
gprs_rlcmac_pdch_ulc_reserve(g_ctx->sched.ulc[rlcmac_prim->l1ctl.pdch_data_ind.ts_nr],
 poll_fn,
+                                            GPRS_RLCMAC_PDCH_ULC_POLL_UL_ACK,
+                                            ul_tbf_as_tbf(ul_tbf));
+       }
        return rc;
 }

diff --git a/src/rlcmac/rlcmac_enc.c b/src/rlcmac/rlcmac_enc.c
index dbebc4f..4b8c469 100644
--- a/src/rlcmac/rlcmac_enc.c
+++ b/src/rlcmac/rlcmac_enc.c
@@ -410,3 +410,16 @@

        
gprs_rlcmac_enc_prepare_channel_quality_report(&ack->Channel_Quality_Report, 
dl_tbf);
 }
+
+void gprs_rlcmac_enc_prepare_pkt_ctrl_ack(RlcMacUplink_t *block, uint32_t tlli)
+{
+       Packet_Control_Acknowledgement_t *ctrl_ack = 
&block->u.Packet_Control_Acknowledgement;
+
+       memset(block, 0, sizeof(*block));
+       ctrl_ack->MESSAGE_TYPE = OSMO_GPRS_RLCMAC_UL_MSGT_PACKET_CONTROL_ACK;
+       ctrl_ack->PayloadType = GPRS_RLCMAC_PT_CONTROL_BLOCK;
+       ctrl_ack->R = 0; /* MS sent channel request message once */
+
+       ctrl_ack->TLLI = tlli;
+       ctrl_ack->CTRL_ACK = 0; /* not clear what this should be set to. TS 
44.060 Table 11.2.2.2 */
+}
diff --git a/src/rlcmac/sched.c b/src/rlcmac/sched.c
index 6a31f83..adf83a2 100644
--- a/src/rlcmac/sched.c
+++ b/src/rlcmac/sched.c
@@ -34,6 +34,7 @@
 struct tbf_sched_ctrl_candidates {
        struct gprs_rlcmac_dl_tbf *poll_dl_ack_final_ack; /* 8.1.2.2 1) */
        struct gprs_rlcmac_dl_tbf *poll_dl_ack; /* 8.1.2.2 7) */
+       struct gprs_rlcmac_ul_tbf *poll_ul_ack; /* 11.2.2 (answer with PKT CTRL 
ACK) */
        struct gprs_rlcmac_ul_tbf *ul_ass;
 };

@@ -88,7 +89,8 @@
                        /* TODO */
                        break;
                case GPRS_RLCMAC_PDCH_ULC_POLL_UL_ACK:
-                       /* TODO */
+                       ul_tbf = tbf_as_ul_tbf(node->tbf);
+                       tbfs->poll_ul_ack = ul_tbf;
                        break;
                case GPRS_RLCMAC_PDCH_ULC_POLL_DL_ACK:
                        dl_tbf = tbf_as_dl_tbf(node->tbf);
@@ -156,6 +158,11 @@
        }

        /* 8.1.2.2 5) Any other RLC/MAC control message, other than a (EGPRS) 
PACKET DOWNLINK ACK/NACK */
+       if (tbfs->poll_ul_ack) {
+               msg = gprs_rlcmac_ul_tbf_create_pkt_ctrl_ack(tbfs->poll_ul_ack);
+               if (msg)
+                       return msg;
+       }
        if (tbfs->ul_ass) {
                msg = gprs_rlcmac_tbf_ul_ass_create_rlcmac_msg(tbfs->ul_ass, 
bi);
                if (msg)
diff --git a/src/rlcmac/tbf_ul.c b/src/rlcmac/tbf_ul.c
index 964f1ad..60bb0a2 100644
--- a/src/rlcmac/tbf_ul.c
+++ b/src/rlcmac/tbf_ul.c
@@ -199,16 +199,38 @@
        return rc;
 }

-int gprs_rlcmac_ul_tbf_handle_pkt_ul_ack_nack(struct gprs_rlcmac_ul_tbf 
*ul_tbf, bool final_ack,
-                                             unsigned first_bsn, struct bitvec 
*rbb)
+int gprs_rlcmac_ul_tbf_handle_pkt_ul_ack_nack(struct gprs_rlcmac_ul_tbf 
*ul_tbf,
+                                             const RlcMacDownlink_t *dl_block)
 {
+       const Packet_Uplink_Ack_Nack_t *ack = 
&dl_block->u.Packet_Uplink_Ack_Nack;
+       const PU_AckNack_GPRS_t *gprs = &ack->u.PU_AckNack_GPRS_Struct;
+       const Ack_Nack_Description_t *ack_desc = &gprs->Ack_Nack_Description;
+       int bsn_begin, bsn_end;
+       int num_blocks;
+       uint8_t bits_data[GPRS_RLCMAC_GPRS_WS/8];
+       char show_bits[GPRS_RLCMAC_GPRS_WS + 1];
+       struct bitvec bits = {
+               .data = bits_data,
+               .data_len = sizeof(bits_data),
+               .cur_bit = 0,
+       };
        int rc;
-       rc = gprs_rlcmac_ul_tbf_update_window(ul_tbf, first_bsn, rbb);
+
+       num_blocks = gprs_rlcmac_decode_gprs_acknack_bits(
+               ack_desc, &bits, &bsn_begin, &bsn_end, ul_tbf->ulw);
+
+       LOGPTBFUL(ul_tbf, LOGL_DEBUG,
+               "Got GPRS UL ACK bitmap: SSN: %d, BSN %d to %d - 1 (%d blocks), 
\"%s\"\n",
+               ack_desc->STARTING_SEQUENCE_NUMBER,
+               bsn_begin, bsn_end, num_blocks,
+               (gprs_rlcmac_extract_rbb(&bits, show_bits), show_bits));
+
+       rc = gprs_rlcmac_ul_tbf_update_window(ul_tbf, bsn_begin, &bits);

        if (gprs_rlcmac_ul_tbf_in_contention_resolution(ul_tbf))
                osmo_fsm_inst_dispatch(ul_tbf->state_fsm.fi, 
GPRS_RLCMAC_TBF_UL_EV_CONTENTION_RESOLUTION_SUCCESS, NULL);

-       if (final_ack) {
+       if (ack_desc->FINAL_ACK_INDICATION) {
                LOGPTBFUL(ul_tbf, LOGL_DEBUG, "Final ACK received.\n");
                rc = gprs_rlcmac_ul_tbf_handle_final_ack(ul_tbf);
        } else if (gprs_rlcmac_tbf_ul_state(ul_tbf) &&
@@ -216,6 +238,7 @@
                LOGPTBFUL(ul_tbf, LOGL_NOTICE,
                          "Received acknowledge of all blocks, but without 
final ack indication (don't worry)\n");
        }
+
        return rc;
 }

@@ -253,6 +276,41 @@
        return NULL;
 }

+struct msgb *gprs_rlcmac_ul_tbf_create_pkt_ctrl_ack(const struct 
gprs_rlcmac_ul_tbf *ul_tbf)
+{
+       struct msgb *msg;
+       struct bitvec bv;
+       RlcMacUplink_t ul_block;
+       int rc;
+
+       OSMO_ASSERT(ul_tbf);
+
+       msg = msgb_alloc(GSM_MACBLOCK_LEN, "pkt_ctrl_ack");
+       if (!msg)
+               return NULL;
+
+       /* Initialize a bit vector that uses allocated msgb as the data buffer. 
*/
+       bv = (struct bitvec){
+               .data = msgb_put(msg, GSM_MACBLOCK_LEN),
+               .data_len = GSM_MACBLOCK_LEN,
+       };
+       bitvec_unhex(&bv, GPRS_RLCMAC_DUMMY_VEC);
+
+       gprs_rlcmac_enc_prepare_pkt_ctrl_ack(&ul_block, ul_tbf->tbf.gre->tlli);
+       rc = osmo_gprs_rlcmac_encode_uplink(&bv, &ul_block);
+       if (rc < 0) {
+               LOGPTBFUL(ul_tbf, LOGL_ERROR, "Encoding of Packet Control ACK 
failed (%d)\n", rc);
+               goto free_ret;
+       }
+       LOGPTBFUL(ul_tbf, LOGL_DEBUG, "Tx Packet Control Ack\n");
+
+       return msg;
+
+free_ret:
+       msgb_free(msg);
+       return NULL;
+}
+
 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) ||
diff --git a/tests/rlcmac/rlcmac_prim_test.c b/tests/rlcmac/rlcmac_prim_test.c
index 6a7254b..4819a5e 100644
--- a/tests/rlcmac/rlcmac_prim_test.c
+++ b/tests/rlcmac/rlcmac_prim_test.c
@@ -503,10 +503,19 @@
        ack_desc->FINAL_ACK_INDICATION = 1;
        ul_ack_nack_mark(ack_desc, 0, true);
        ul_ack_nack_mark(ack_desc, 1, true);
+       /* Final ACK has Poll set: */
+       dl_block.SP = 1;
+       dl_block.RRBP = GPRS_RLCMAC_RRBP_N_plus_13;
        rlcmac_prim = create_dl_ctrl_block(&dl_block, ts_nr, rts_fn);
        rc = osmo_gprs_rlcmac_prim_lower_up(rlcmac_prim);
        OSMO_ASSERT(rc == 0);

+       /* Trigger transmission of PKT CTRL ACK */
+       rts_fn = rrbp2fn(rts_fn, dl_block.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();
 }
diff --git a/tests/rlcmac/rlcmac_prim_test.err 
b/tests/rlcmac/rlcmac_prim_test.err
index 6fbf91e..d74d6a0 100644
--- a/tests/rlcmac/rlcmac_prim_test.err
+++ b/tests/rlcmac/rlcmac_prim_test.err
@@ -53,6 +53,9 @@
 DLGLOBAL INFO UL_TBF{FINISHED}: Contention resolution succeeded, stop T3166
 DLGLOBAL DEBUG TBF(UL:NR-0:TLLI-00002342) Final ACK received.
 DLGLOBAL INFO UL_TBF{FINISHED}: Received Event FINAL_ACK_RECVD
+DLGLOBAL DEBUG Register POLL (TS=7 FN=21, reason=UL_ACK)
+DLGLOBAL INFO Rx from lower layers: L1CTL-PDCH_RTS.indication
+DLGLOBAL DEBUG TBF(UL:NR-0:TLLI-00002342) Tx Packet Control Ack
 DLGLOBAL INFO UL_TBF_ASS{IDLE}: Deallocated
 DLGLOBAL INFO UL_TBF{FINISHED}: Deallocated
 DLGLOBAL INFO Rx from upper layers: GRR-UNITDATA.request
diff --git a/tests/rlcmac/rlcmac_prim_test.ok b/tests/rlcmac/rlcmac_prim_test.ok
index bc6a9d1..d355ebb 100644
--- a/tests/rlcmac/rlcmac_prim_test.ok
+++ b/tests/rlcmac/rlcmac_prim_test.ok
@@ -4,6 +4,7 @@
 test_rlcmac_prim_down_cb(): Rx L1CTL-CFG_UL_TBF.request ul_tbf_nr=0 
ul_slotmask=0x80
 test_rlcmac_prim_down_cb(): Rx L1CTL-PDCH_DATA.request fn=4 ts=7 data_len=34 
data=[3c 00 01 00 00 23 42 01 c0 00 08 01 01 d5 71 00 00 08 29 26 24 00 00 00 
00 71 62 f2 24 6c 84 44 04 00 ]
 test_rlcmac_prim_down_cb(): Rx L1CTL-PDCH_DATA.request fn=8 ts=7 data_len=34 
data=[00 00 02 1d 00 00 23 42 11 e5 10 00 e2 18 f2 2b 2b 2b 2b 2b 2b 2b 2b 2b 
2b 2b 2b 2b 2b 2b 2b 2b 2b 00 ]
+test_rlcmac_prim_down_cb(): Rx L1CTL-PDCH_DATA.request fn=21 ts=7 data_len=23 
data=[40 04 00 00 8d 08 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b ]
 === test_ul_tbf_attach end ===
 === test_ul_tbf_t3164_timeout start ===
 sys={0.000000}, mono={0.000000}: clock_override_set

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

Gerrit-Project: libosmo-gprs
Gerrit-Branch: master
Gerrit-Change-Id: I833d0f189c06d093ce9bd4c36c37024cf5cb6446
Gerrit-Change-Number: 31420
Gerrit-PatchSet: 1
Gerrit-Owner: pespin <[email protected]>
Gerrit-MessageType: newchange

Reply via email to