rlcmac: ul_tbf: Answer Pkt Ul Ack/Nack poll with Pkt Ctrl Ack
Related: OS#5500 Change-Id: I833d0f189c06d093ce9bd4c36c37024cf5cb6446
This commit is contained in:
parent
bf1f5f3613
commit
5daf94b203
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 */
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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) ||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue