pespin submitted this change.
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(-)
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 change 31328. To unsubscribe, or for help writing mail filters, visit settings.