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 ===