pespin submitted this change.

View Change


Approvals: Jenkins Builder: Verified pespin: Looks good to me, approved
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, 122 insertions(+), 28 deletions(-)

diff --git a/include/osmocom/gprs/rlcmac/rlcmac_enc.h b/include/osmocom/gprs/rlcmac/rlcmac_enc.h
index 1a0f586..406109a 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);
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..5a3fae8 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,13 @@
}

/* 8.1.2.2 5) Any other RLC/MAC control message, other than a (EGPRS) PACKET DOWNLINK ACK/NACK */
+ if (tbfs->poll_ul_ack) {
+ LOGRLCMAC(LOGL_DEBUG, "(ts=%u,fn=%u,usf=%u) Tx Pkt Control Ack (UL ACK/NACK poll)\n",
+ bi->ts, bi->fn, bi->usf);
+ 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 cc33c4c..45b0b21 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 794bfbc..a690bb0 100644
--- a/tests/rlcmac/rlcmac_prim_test.err
+++ b/tests/rlcmac/rlcmac_prim_test.err
@@ -53,6 +53,10 @@
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 (ts=7,fn=21,usf=0) Tx Pkt Control Ack (UL ACK/NACK poll)
+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 669738a..76cd901 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 change 31420. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: libosmo-gprs
Gerrit-Branch: master
Gerrit-Change-Id: I833d0f189c06d093ce9bd4c36c37024cf5cb6446
Gerrit-Change-Number: 31420
Gerrit-PatchSet: 3
Gerrit-Owner: pespin <pespin@sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: pespin <pespin@sysmocom.de>
Gerrit-MessageType: merged