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

Related: OS#5500
Change-Id: I833d0f189c06d093ce9bd4c36c37024cf5cb6446
This commit is contained in:
Pau Espin 2023-02-20 17:46:29 +01:00
parent bf1f5f3613
commit 5daf94b203
9 changed files with 112 additions and 28 deletions

View File

@ -48,3 +48,5 @@ void gprs_rlcmac_enc_prepare_pkt_ul_dummy_block(RlcMacUplink_t *block, uint32_t
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);

View File

@ -52,9 +52,10 @@ bool gprs_rlcmac_ul_tbf_dummy_rts(const struct gprs_rlcmac_ul_tbf *ul_tbf, const
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)
{

View File

@ -320,19 +320,7 @@ int gprs_rlcmac_handle_bcch_si13(const struct gsm48_system_information_type_13 *
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 @@ static int gprs_rlcmac_handle_pkt_ul_ack_nack(const struct osmo_gprs_rlcmac_prim
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;
}

View File

@ -410,3 +410,16 @@ void gprs_rlcmac_enc_prepare_pkt_downlink_ack_nack(RlcMacUplink_t *block, const
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 */
}

View File

@ -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 @@ static void get_ctrl_msg_tbf_candidates(const struct gprs_rlcmac_rts_block_ind *
/* 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 @@ static struct msgb *sched_select_ctrl_msg(const struct gprs_rlcmac_rts_block_ind
}
/* 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)

View File

@ -199,16 +199,38 @@ int gprs_rlcmac_ul_tbf_handle_final_ack(struct gprs_rlcmac_ul_tbf *ul_tbf)
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 @@ int gprs_rlcmac_ul_tbf_handle_pkt_ul_ack_nack(struct gprs_rlcmac_ul_tbf *ul_tbf,
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 @@ free_ret:
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) ||

View File

@ -503,10 +503,19 @@ static void test_ul_tbf_attach(void)
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();
}

View File

@ -53,6 +53,10 @@ DLGLOBAL INFO UL_TBF{FINISHED}: Received Event CONTENTION_RESOLUTION_SUCCESS
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

View File

@ -4,6 +4,7 @@ test_rlcmac_prim_down_cb(): Rx L1CTL-RACH.request ra=0x7e
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