pespin has submitted this change. ( 
https://gerrit.osmocom.org/c/libosmo-gprs/+/31328 )

Change subject: rlcmac: Implement Tx of DL ACK/NACK
......................................................................

rlcmac: Implement Tx of DL ACK/NACK

Measurement related functionality is not yet implemented and hence the
related fields cannot be filled in yet.

Related: OS#5500
Change-Id: I6ae2df07929fb6c4733e87b18cebe75a6f24f520
---
M include/osmocom/gprs/rlcmac/rlcmac_enc.h
M include/osmocom/gprs/rlcmac/tbf_dl.h
M src/rlcmac/rlcmac_enc.c
M src/rlcmac/sched.c
M src/rlcmac/tbf_dl.c
M tests/rlcmac/rlcmac_prim_test.err
M tests/rlcmac/rlcmac_prim_test.ok
7 files changed, 114 insertions(+), 4 deletions(-)

Approvals:
  laforge: Looks good to me, but someone else must approve
  Jenkins Builder: Verified
  pespin: Looks good to me, approved




diff --git a/include/osmocom/gprs/rlcmac/rlcmac_enc.h 
b/include/osmocom/gprs/rlcmac/rlcmac_enc.h
index d091d53..1a0f586 100644
--- a/include/osmocom/gprs/rlcmac/rlcmac_enc.h
+++ b/include/osmocom/gprs/rlcmac/rlcmac_enc.h
@@ -46,3 +46,5 @@
 void gprs_rlcmac_enc_prepare_pkt_ul_dummy_block(RlcMacUplink_t *block, 
uint32_t tlli);

 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);
diff --git a/include/osmocom/gprs/rlcmac/tbf_dl.h 
b/include/osmocom/gprs/rlcmac/tbf_dl.h
index facae81..f398c0a 100644
--- a/include/osmocom/gprs/rlcmac/tbf_dl.h
+++ b/include/osmocom/gprs/rlcmac/tbf_dl.h
@@ -40,6 +40,8 @@

 int gprs_rlcmac_dl_tbf_configure_l1ctl(struct gprs_rlcmac_dl_tbf *dl_tbf);

+struct msgb *gprs_rlcmac_dl_tbf_create_pkt_dl_ack_nack(const struct 
gprs_rlcmac_dl_tbf *dl_tbf);
+
 int gprs_rlcmac_dl_tbf_rcv_data_block(struct gprs_rlcmac_dl_tbf *dl_tbf,
                                      const struct gprs_rlcmac_rlc_data_info 
*rlc,
                                      uint8_t *data, uint32_t fn, uint8_t 
ts_nr);
diff --git a/src/rlcmac/rlcmac_enc.c b/src/rlcmac/rlcmac_enc.c
index e1ea990..1f1ebc3 100644
--- a/src/rlcmac/rlcmac_enc.c
+++ b/src/rlcmac/rlcmac_enc.c
@@ -24,6 +24,8 @@
 #include <osmocom/gprs/rlcmac/csn1_defs.h>
 #include <osmocom/gprs/rlcmac/rlcmac_enc.h>
 #include <osmocom/gprs/rlcmac/gre.h>
+#include <osmocom/gprs/rlcmac/tbf_dl.h>
+#include <osmocom/gprs/rlcmac/rlc_window_dl.h>
 #include <osmocom/gprs/rlcmac/tbf_ul.h>

 int gprs_rlcmac_rlc_write_ul_data_header(const struct 
gprs_rlcmac_rlc_data_info *rlc, uint8_t *data)
@@ -352,3 +354,59 @@
        req->Exist_AdditionsR99 = 0;
        /* TODO: no req->AdditionsR99 yet */
 }
+
+static void 
gprs_rlcmac_enc_prepare_pkt_ack_nack_desc_gprs(Ack_Nack_Description_t 
*ack_desc, const struct gprs_rlcmac_dl_tbf *dl_tbf)
+{
+       struct bitvec bv = {
+               .data = &ack_desc->RECEIVED_BLOCK_BITMAP[0],
+               .data_len = sizeof(ack_desc->RECEIVED_BLOCK_BITMAP),
+       };
+       char rbb[65];
+
+       gprs_rlcmac_rlc_dl_window_update_rbb(dl_tbf->dlw, rbb);
+       rbb[64] = 0;
+       LOGPTBFDL(dl_tbf, LOGL_DEBUG, "- V(N): \"%s\" R=Received I=Invalid\n", 
rbb);
+
+       ack_desc->FINAL_ACK_INDICATION = (gprs_rlcmac_tbf_dl_state(dl_tbf) == 
GPRS_RLCMAC_TBF_DL_ST_FINISHED);
+       ack_desc->STARTING_SEQUENCE_NUMBER = 
gprs_rlcmac_rlc_dl_window_ssn(dl_tbf->dlw);
+       for (int i = 0; i < 64; i++) {
+               /* Set bit at the appropriate position (see 3GPP TS 44.060 
9.1.8.1) */
+               bool is_ack = (rbb[i] == 'R');
+               bitvec_set_bit(&bv, is_ack == 1 ? ONE : ZERO);
+       }
+}
+
+/* Channel Quality Report struct, TS 44.060 Table 11.2.6. */
+static void 
gprs_rlcmac_enc_prepare_channel_quality_report(Channel_Quality_Report_t *cqr, 
const struct gprs_rlcmac_dl_tbf *dl_tbf)
+{
+       /* TODO: fill cqr from info stored probably in the gre object. */
+}
+
+void gprs_rlcmac_enc_prepare_pkt_downlink_ack_nack(RlcMacUplink_t *block, 
const struct gprs_rlcmac_dl_tbf *dl_tbf)
+{
+       Packet_Downlink_Ack_Nack_t *ack = &block->u.Packet_Downlink_Ack_Nack;
+       struct gprs_rlcmac_entity *gre = dl_tbf->tbf.gre;
+
+       memset(block, 0, sizeof(*block));
+       ack->MESSAGE_TYPE = OSMO_GPRS_RLCMAC_UL_MSGT_PACKET_RESOURCE_REQUEST;
+       ack->PayloadType = GPRS_RLCMAC_PT_CONTROL_BLOCK;
+       ack->R = 0; /* MS sent channel request message once */
+
+       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_t *chan_req = 
&ack->Channel_Request_Description;
+               ack->Exist_Channel_Request_Description = 1;
+               chan_req->PEAK_THROUGHPUT_CLASS = 0; /* TODO */
+               chan_req->RADIO_PRIORITY = 0; /* TODO */
+               chan_req->RLC_MODE = GPRS_RLCMAC_RLC_MODE_ACKNOWLEDGED;
+               chan_req->LLC_PDU_TYPE = GPRS_RLCMAC_LLC_PDU_TYPE_ACKNOWLEDGED;
+               chan_req->RLC_OCTET_COUNT = 0; /* TODO */
+       } else {
+               ack->Exist_Channel_Request_Description = 0;
+       }
+
+       
gprs_rlcmac_enc_prepare_channel_quality_report(&ack->Channel_Quality_Report, 
dl_tbf);
+}
diff --git a/src/rlcmac/sched.c b/src/rlcmac/sched.c
index f229b7a..6a31f83 100644
--- a/src/rlcmac/sched.c
+++ b/src/rlcmac/sched.c
@@ -150,7 +150,7 @@
        if (tbfs->poll_dl_ack_final_ack) {
                LOGRLCMAC(LOGL_DEBUG, "(ts=%u,fn=%u,usf=%u) Tx DL ACK/NACK 
FinalAck=1\n",
                          bi->ts, bi->fn, bi->usf);
-               msg = NULL; /* TODO: generate DL ACK/NACK ctrl block */
+               msg = 
gprs_rlcmac_dl_tbf_create_pkt_dl_ack_nack(tbfs->poll_dl_ack_final_ack);
                if (msg)
                        return msg;
        }
@@ -167,7 +167,7 @@
        if (tbfs->poll_dl_ack) {
                LOGRLCMAC(LOGL_DEBUG, "(ts=%u,fn=%u,usf=%u) Tx DL ACK/NACK\n",
                          bi->ts, bi->fn, bi->usf);
-               msg = NULL; /* TODO: generate DL ACK/NACK ctrl block */
+               msg = 
gprs_rlcmac_dl_tbf_create_pkt_dl_ack_nack(tbfs->poll_dl_ack);
                if (msg)
                        return msg;
        }
diff --git a/src/rlcmac/tbf_dl.c b/src/rlcmac/tbf_dl.c
index da9b871..49f8187 100644
--- a/src/rlcmac/tbf_dl.c
+++ b/src/rlcmac/tbf_dl.c
@@ -24,6 +24,7 @@
 #include <osmocom/gprs/rlcmac/gre.h>
 #include <osmocom/gprs/rlcmac/rlc_window_dl.h>
 #include <osmocom/gprs/rlcmac/rlcmac_dec.h>
+#include <osmocom/gprs/rlcmac/rlcmac_enc.h>
 #include <osmocom/gprs/rlcmac/pdch_ul_controller.h>

 struct gprs_rlcmac_dl_tbf *gprs_rlcmac_dl_tbf_alloc(struct gprs_rlcmac_entity 
*gre)
@@ -105,6 +106,40 @@
        return gprs_rlcmac_prim_call_down_cb(rlcmac_prim);
 }

+struct msgb *gprs_rlcmac_dl_tbf_create_pkt_dl_ack_nack(const struct 
gprs_rlcmac_dl_tbf *dl_tbf)
+{
+       struct msgb *msg;
+       struct bitvec bv;
+       RlcMacUplink_t ul_block;
+       int rc;
+
+       OSMO_ASSERT(dl_tbf);
+
+       msg = msgb_alloc(GSM_MACBLOCK_LEN, "pkt_dl_ack_nack");
+       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_downlink_ack_nack(&ul_block, dl_tbf);
+       rc = osmo_gprs_rlcmac_encode_uplink(&bv, &ul_block);
+       if (rc < 0) {
+               LOGPTBFDL(dl_tbf, LOGL_ERROR, "Encoding of Packet Downlink 
ACK/NACK failed (%d)\n", rc);
+               goto free_ret;
+       }
+
+       return msg;
+
+free_ret:
+       msgb_free(msg);
+       return NULL;
+}
+
 /*
  * Store received block data in LLC message(s) and forward to SGSN
  * if complete.
diff --git a/tests/rlcmac/rlcmac_prim_test.err 
b/tests/rlcmac/rlcmac_prim_test.err
index 2d1b804..d4c8250 100644
--- a/tests/rlcmac/rlcmac_prim_test.err
+++ b/tests/rlcmac/rlcmac_prim_test.err
@@ -54,5 +54,4 @@
 DLGLOBAL DEBUG Register POLL (TS=7 FN=21, reason=DL_ACK)
 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 (ts=7,fn=21,usf=0) No Uplink TBF available to transmit RLC/MAC 
Ul Data Block
-DLGLOBAL DEBUG (ts=7,fn=21,usf=0) No Uplink TBF available to transmit RLC/MAC 
Ul Dummy Ctrl Block
+DLGLOBAL DEBUG TBF(DL:NR-0:TLLI-00000001) - V(N): 
"IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIR" R=Received 
I=Invalid
diff --git a/tests/rlcmac/rlcmac_prim_test.ok b/tests/rlcmac/rlcmac_prim_test.ok
index 49b02b9..7823636 100644
--- a/tests/rlcmac/rlcmac_prim_test.ok
+++ b/tests/rlcmac/rlcmac_prim_test.ok
@@ -6,4 +6,5 @@
 === test_dl_tbf_ccch_assign start ===
 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 end ===

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

Gerrit-Project: libosmo-gprs
Gerrit-Branch: master
Gerrit-Change-Id: I6ae2df07929fb6c4733e87b18cebe75a6f24f520
Gerrit-Change-Number: 31328
Gerrit-PatchSet: 3
Gerrit-Owner: pespin <[email protected]>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: laforge <[email protected]>
Gerrit-Reviewer: pespin <[email protected]>
Gerrit-MessageType: merged

Reply via email to