rlcmac: Use finished UL TBF to request a new one after Final UL ACK/NACK

Change-Id: I4eb873250f5ee7eafb5b6126382ce088091d0447
This commit is contained in:
Pau Espin 2023-02-21 12:28:30 +01:00
parent 13c2601974
commit 4486aa276c
10 changed files with 280 additions and 15 deletions

View File

@ -47,6 +47,8 @@ void gprs_rlcmac_ul_tbf_free(struct gprs_rlcmac_ul_tbf *ul_tbf);
bool gprs_rlcmac_ul_tbf_in_contention_resolution(const struct gprs_rlcmac_ul_tbf *ul_tbf);
unsigned int gprs_rlcmac_ul_tbf_n3104_max(const struct gprs_rlcmac_ul_tbf *ul_tbf);
bool gprs_rlcmac_ul_tbf_have_data(const struct gprs_rlcmac_ul_tbf *ul_tbf);
bool gprs_rlcmac_ul_tbf_can_request_new_ul_tbf(const struct gprs_rlcmac_ul_tbf *ul_tbf);
bool gprs_rlcmac_ul_tbf_data_rts(const struct gprs_rlcmac_ul_tbf *ul_tbf, const struct gprs_rlcmac_rts_block_ind *bi);
bool gprs_rlcmac_ul_tbf_dummy_rts(const struct gprs_rlcmac_ul_tbf *ul_tbf, const struct gprs_rlcmac_rts_block_ind *bi);

View File

@ -46,6 +46,7 @@ struct gprs_rlcmac_tbf_ul_ass_fsm_ctx {
enum tbf_ul_ass_fsm_event {
GPRS_RLCMAC_TBF_UL_ASS_EV_START, /* Start Uplink assignment (data: enum gprs_rlcmac_tbf_ul_ass_type) */
GPRS_RLCMAC_TBF_UL_ASS_EV_START_DIRECT_2PHASE, /* Start Uplink assignment directly into 2phase from an older UL TBF */
GPRS_RLCMAC_TBF_UL_ASS_EV_RX_CCCH_IMM_ASS, /* (data: struct tbf_ul_ass_ev_rx_ccch_imm_ass_ctx *) */
GPRS_RLCMAC_TBF_UL_ASS_EV_CREATE_RLCMAC_MSG, /* Generate RLC/MAC block (data: struct tbf_ul_ass_ev_create_rlcmac_msg_ctx) */
GPRS_RLCMAC_TBF_UL_ASS_EV_RX_PKT_UL_ASS, /* (data: decoded PktUlAss) */
@ -71,6 +72,7 @@ int gprs_rlcmac_tbf_ul_ass_fsm_constructor(struct gprs_rlcmac_ul_tbf *ul_tbf);
void gprs_rlcmac_tbf_ul_ass_fsm_destructor(struct gprs_rlcmac_ul_tbf *ul_tbf);
int gprs_rlcmac_tbf_ul_ass_start(struct gprs_rlcmac_ul_tbf *ul_tbf, enum gprs_rlcmac_tbf_ul_ass_type type);
int gprs_rlcmac_tbf_ul_ass_start_from_releasing_ul_tbf(struct gprs_rlcmac_ul_tbf *ul_tbf, struct gprs_rlcmac_ul_tbf *old_ul_tbf);
bool gprs_rlcmac_tbf_ul_ass_pending(struct gprs_rlcmac_ul_tbf *ul_tbf);
bool gprs_rlcmac_tbf_ul_ass_match_rach_req(struct gprs_rlcmac_ul_tbf *ul_tbf, uint8_t ra);
bool gprs_rlcmac_tbf_ul_ass_rts(const struct gprs_rlcmac_ul_tbf *ul_tbf, const struct gprs_rlcmac_rts_block_ind *bi);

View File

@ -11,7 +11,8 @@ enum gprs_rlcmac_tbf_ul_fsm_states {
GPRS_RLCMAC_TBF_UL_ST_NEW = 0, /* new created TBF */
GPRS_RLCMAC_TBF_UL_ST_WAIT_ASSIGN, /* wait for Immediate Assignment */
GPRS_RLCMAC_TBF_UL_ST_FLOW, /* RLC/MAC flow, resource needed */
GPRS_RLCMAC_TBF_UL_ST_FINISHED, /* flow finished, wait for release */
GPRS_RLCMAC_TBF_UL_ST_FINISHED, /* All data transmitted (CV=0), only retransmits and waiting for ACKs */
GPRS_RLCMAC_TBF_UL_ST_RELEASING, /* Network sent UL ACK w/ FinalAck=1 and polled for response */
};
struct gprs_rlcmac_tbf_ul_fsm_ctx {
@ -24,6 +25,10 @@ struct gprs_rlcmac_tbf_ul_fsm_ctx {
unsigned int pkt_acc_proc_attempts;
/* 9.3.3.3.2: The block with CV=0 shall not be retransmitted more than four times. */
unsigned int last_data_block_retrans_attempts;
/* Whether the Received Packet UL ACK/NACK w/ FinalAck=1 had 'TBF Est' field to '1'.
* Used during ST_RELEASING to find out if a new UL TBF can be recreated
* when ansering the final UL ACK. */
bool rx_final_pkt_ul_ack_nack_has_tbf_est;
};
enum tbf_ul_fsm_event {
@ -33,7 +38,7 @@ enum tbf_ul_fsm_event {
GPRS_RLCMAC_TBF_UL_EV_N3104_MAX,
GPRS_RLCMAC_TBF_UL_EV_CONTENTION_RESOLUTION_SUCCESS,
GPRS_RLCMAC_TBF_UL_EV_LAST_UL_DATA_SENT,
GPRS_RLCMAC_TBF_UL_EV_FINAL_ACK_RECVD,
GPRS_RLCMAC_TBF_UL_EV_FINAL_ACK_RECVD, /* data: bool TBF_EST */
};
int gprs_rlcmac_tbf_ul_fsm_init(void);

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_new_ul_tbf; /* 9.3.2.4.2 (answer with PKT RES REQ) */
struct gprs_rlcmac_ul_tbf *poll_ul_ack; /* 11.2.2 (answer with PKT CTRL ACK) */
struct gprs_rlcmac_ul_tbf *ul_ass;
};
@ -89,8 +90,26 @@ static void get_ctrl_msg_tbf_candidates(const struct gprs_rlcmac_rts_block_ind *
/* TODO */
break;
case GPRS_RLCMAC_PDCH_ULC_POLL_UL_ACK:
/* TS 44.060: 9.3.2.4.2 If the PACKET UPLINK ACK/NACK message
* has the Final Ack Indicator bit set to '1' and the following
* conditions are fulfilled: TBF Est field is set to '1'; the
* mobile station has new data to transmit; the mobile station
* has no other ongoing downlink TBFs, the mobile station shall
* release the uplink TBF and may request the establishment of a
* new TBF using one of the following procedures.
* If Control Ack Type parameter in System Information indicates
* acknowledgement is RLC/MAC control block, the mobile station
* shall transmit the PACKET RESOURCE REQUEST message and start
* timer T3168 for the TBF request. The mobile station shall use
* the same procedures as are used for TBF establishment using two
* phase access described in sub-clause 7.1.3 starting from the
* point where the mobile station transmits the PACKET RESOURCE
* REQUEST message. */
ul_tbf = tbf_as_ul_tbf(node->tbf);
tbfs->poll_ul_ack = ul_tbf;
if (gprs_rlcmac_ul_tbf_can_request_new_ul_tbf(ul_tbf))
tbfs->poll_ul_ack_new_ul_tbf = ul_tbf;
else
tbfs->poll_ul_ack = ul_tbf;
break;
case GPRS_RLCMAC_PDCH_ULC_POLL_DL_ACK:
dl_tbf = tbf_as_dl_tbf(node->tbf);
@ -148,6 +167,9 @@ static struct msgb *sched_select_ctrl_msg(const struct gprs_rlcmac_rts_block_ind
struct tbf_sched_ctrl_candidates *tbfs)
{
struct msgb *msg = NULL;
struct gprs_rlcmac_entity *gre;
int rc;
/* 8.1.2.2 1) (EGPRS) PACKET DOWNLINK ACK/NACK w/ FinalAckInd=1 */
if (tbfs->poll_dl_ack_final_ack) {
LOGRLCMAC(LOGL_DEBUG, "(ts=%u,fn=%u,usf=%u) Tx DL ACK/NACK FinalAck=1\n",
@ -158,12 +180,36 @@ 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_new_ul_tbf) {
LOGRLCMAC(LOGL_DEBUG, "(ts=%u,fn=%u,usf=%u) Tx Pkt Resource Request (UL ACK/NACK poll)\n",
bi->ts, bi->fn, bi->usf);
gre = tbfs->poll_ul_ack_new_ul_tbf->tbf.gre;
OSMO_ASSERT(gre->ul_tbf == tbfs->poll_ul_ack_new_ul_tbf);
gre->ul_tbf = gprs_rlcmac_ul_tbf_alloc(gre);
if (!gre->ul_tbf) {
gprs_rlcmac_ul_tbf_free(tbfs->poll_ul_ack_new_ul_tbf);
return NULL;
}
/* Prepare new UL TBF from old UL TBF: */
rc = gprs_rlcmac_tbf_ul_ass_start_from_releasing_ul_tbf(gre->ul_tbf, tbfs->poll_ul_ack_new_ul_tbf);
gprs_rlcmac_ul_tbf_free(tbfs->poll_ul_ack_new_ul_tbf); /* always free */
if (rc < 0) {
gprs_rlcmac_ul_tbf_free(gre->ul_tbf);
return NULL;
}
/* New UL TBF is ready to send the Pkt Res Req: */
OSMO_ASSERT(gprs_rlcmac_tbf_ul_ass_rts(gre->ul_tbf, bi));
msg = gprs_rlcmac_tbf_ul_ass_create_rlcmac_msg(gre->ul_tbf, bi);
if (msg)
return msg;
}
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;
/* Last UL message, freeing */
gprs_rlcmac_ul_tbf_free(tbfs->poll_ul_ack);
return msg;
}
if (tbfs->ul_ass) {
msg = gprs_rlcmac_tbf_ul_ass_create_rlcmac_msg(tbfs->ul_ass, bi);

View File

@ -123,6 +123,36 @@ unsigned int gprs_rlcmac_ul_tbf_n3104_max(const struct gprs_rlcmac_ul_tbf *ul_tb
return 3 * (bs_cv_max + 3) * ul_tbf->cur_alloc.num_ts;
}
/* Whether the existing UL TBF can directly request a new UL TBF instead of goig to packet idle mode. */
bool gprs_rlcmac_ul_tbf_can_request_new_ul_tbf(const struct gprs_rlcmac_ul_tbf *ul_tbf)
{
/* 9.3.2.4.2: "If the PACKET UPLINK ACK/NACK message has the Final Ack Indicator
* bit set to '1' and the following conditions are fulfilled: TBF Est field is set
* to '1'; the mobile station has new data to transmit; the mobile station has no
* other ongoing downlink TBFs, the mobile station shall release the uplink TBF and
* may request the establishment of a new TBF"
*/
/* "PACKET UPLINK ACK/NACK message has the Final Ack Indicator" means GPRS_RLCMAC_TBF_UL_ST_RELEASING: */
if (gprs_rlcmac_tbf_ul_state(ul_tbf) != GPRS_RLCMAC_TBF_UL_ST_RELEASING)
return false;
/* "TBF Est field is set to '1'"" */
if (!ul_tbf->state_fsm.rx_final_pkt_ul_ack_nack_has_tbf_est)
return false;
/* the mobile station has new data to transmit */
if (!gprs_rlcmac_ul_tbf_have_data(ul_tbf))
return false;
/* "the mobile station has no other ongoing downlink TBFs */
if (ul_tbf->tbf.gre->dl_tbf)
return false;
return true;
}
/* Used by the scheduler to find out whether an Uplink Dummy Control Block can be transmitted. If
* true, it will potentially call gprs_rlcmac_ul_tbf_dummy_create() to generate a new dummy message to transmit. */
bool gprs_rlcmac_ul_tbf_dummy_rts(const struct gprs_rlcmac_ul_tbf *ul_tbf, const struct gprs_rlcmac_rts_block_ind *bi)
@ -182,20 +212,22 @@ static int gprs_rlcmac_ul_tbf_update_window(struct gprs_rlcmac_ul_tbf *ul_tbf,
return 0;
}
int gprs_rlcmac_ul_tbf_handle_final_ack(struct gprs_rlcmac_ul_tbf *ul_tbf)
int gprs_rlcmac_ul_tbf_handle_final_ack(struct gprs_rlcmac_ul_tbf *ul_tbf, const RlcMacDownlink_t *dl_block)
{
int rc = 0;
bool tbf_est = false;
const PU_AckNack_GPRS_t *ack_gprs = &dl_block->u.Packet_Uplink_Ack_Nack.u.PU_AckNack_GPRS_Struct;
osmo_fsm_inst_dispatch(ul_tbf->state_fsm.fi, GPRS_RLCMAC_TBF_UL_EV_FINAL_ACK_RECVD, NULL);
if (ack_gprs->Exist_AdditionsR99)
tbf_est = ack_gprs->AdditionsR99.TBF_EST;
osmo_fsm_inst_dispatch(ul_tbf->state_fsm.fi, GPRS_RLCMAC_TBF_UL_EV_FINAL_ACK_RECVD, &tbf_est);
/* range V(A)..V(S)-1 */
//received = gprs_rlcmac_rlc_ul_window_count_unacked(ul_tbf->ulw);
/* report all outstanding packets as received */
//gprs_rlcmac_received_lost(this, received, 0);
gprs_rlcmac_rlc_ul_window_reset(ul_tbf->ulw);
/* TODO: check for RRBP and attempt to create a new UL TBF if
* gprs_rlcmac_ul_tbf_have_data(ul_tbf) */
return rc;
}
@ -232,7 +264,7 @@ int gprs_rlcmac_ul_tbf_handle_pkt_ul_ack_nack(struct gprs_rlcmac_ul_tbf *ul_tbf,
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);
rc = gprs_rlcmac_ul_tbf_handle_final_ack(ul_tbf, dl_block);
} else if (gprs_rlcmac_tbf_ul_state(ul_tbf) &&
gprs_rlcmac_rlc_ul_window_window_empty(ul_tbf->ulw)) {
LOGPTBFUL(ul_tbf, LOGL_NOTICE,

View File

@ -37,6 +37,7 @@
static const struct value_string tbf_ul_ass_fsm_event_names[] = {
{ GPRS_RLCMAC_TBF_UL_ASS_EV_START, "START" },
{ GPRS_RLCMAC_TBF_UL_ASS_EV_START_DIRECT_2PHASE, "START_DIRECT_2PHASE" },
{ GPRS_RLCMAC_TBF_UL_ASS_EV_RX_CCCH_IMM_ASS, "RX_CCCH_IMM_ASS" },
{ GPRS_RLCMAC_TBF_UL_ASS_EV_CREATE_RLCMAC_MSG, "CREATE_RLCMAC_MSG" },
{ GPRS_RLCMAC_TBF_UL_ASS_EV_RX_PKT_UL_ASS, "RX_PKT_UL_ASS" },
@ -185,6 +186,11 @@ static void st_idle(struct osmo_fsm_inst *fi, uint32_t event, void *data)
submit_rach_req(ctx);
tbf_ul_ass_fsm_state_chg(fi, GPRS_RLCMAC_TBF_UL_ASS_ST_WAIT_CCCH_IMM_ASS);
break;
case GPRS_RLCMAC_TBF_UL_ASS_EV_START_DIRECT_2PHASE:
osmo_fsm_inst_dispatch(ctx->ul_tbf->state_fsm.fi, GPRS_RLCMAC_TBF_UL_EV_UL_ASS_START, NULL);
ctx->ass_type = GPRS_RLCMAC_TBF_UL_ASS_TYPE_2PHASE;
tbf_ul_ass_fsm_state_chg(fi, GPRS_RLCMAC_TBF_UL_ASS_ST_SCHED_PKT_RES_REQ);
break;
default:
OSMO_ASSERT(0);
}
@ -279,9 +285,11 @@ static void st_compl_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state)
static struct osmo_fsm_state tbf_ul_ass_fsm_states[] = {
[GPRS_RLCMAC_TBF_UL_ASS_ST_IDLE] = {
.in_event_mask =
X(GPRS_RLCMAC_TBF_UL_ASS_EV_START),
X(GPRS_RLCMAC_TBF_UL_ASS_EV_START) |
X(GPRS_RLCMAC_TBF_UL_ASS_EV_START_DIRECT_2PHASE),
.out_state_mask =
X(GPRS_RLCMAC_TBF_UL_ASS_ST_WAIT_CCCH_IMM_ASS),
X(GPRS_RLCMAC_TBF_UL_ASS_ST_WAIT_CCCH_IMM_ASS) |
X(GPRS_RLCMAC_TBF_UL_ASS_ST_SCHED_PKT_RES_REQ),
.name = "IDLE",
.onenter = st_idle_on_enter,
.action = st_idle,
@ -403,6 +411,19 @@ int gprs_rlcmac_tbf_ul_ass_start(struct gprs_rlcmac_ul_tbf *ul_tbf, enum gprs_rl
return rc;
}
/* A releasing TBF being polled is used to fill in 1phase access internally and
* switch the FSM to trigger the 2hpase directly (tx Pkt Res Req) */
int gprs_rlcmac_tbf_ul_ass_start_from_releasing_ul_tbf(struct gprs_rlcmac_ul_tbf *ul_tbf, struct gprs_rlcmac_ul_tbf *old_ul_tbf)
{
int rc;
memcpy(&ul_tbf->ul_ass_fsm.phase1_alloc, &old_ul_tbf->cur_alloc,
sizeof(ul_tbf->ul_ass_fsm.phase1_alloc));
rc = osmo_fsm_inst_dispatch(ul_tbf->ul_ass_fsm.fi,
GPRS_RLCMAC_TBF_UL_ASS_EV_START_DIRECT_2PHASE,
NULL);
return rc;
}
bool gprs_rlcmac_tbf_ul_ass_pending(struct gprs_rlcmac_ul_tbf *ul_tbf)
{
return ul_tbf->ul_ass_fsm.fi->state != GPRS_RLCMAC_TBF_UL_ASS_ST_IDLE;

View File

@ -196,12 +196,23 @@ static void st_finished(struct osmo_fsm_inst *fi, uint32_t event, void *data)
}
break;
case GPRS_RLCMAC_TBF_UL_EV_FINAL_ACK_RECVD:
ctx->rx_final_pkt_ul_ack_nack_has_tbf_est = *((bool *)data);
tbf_ul_fsm_state_chg(fi, GPRS_RLCMAC_TBF_UL_ST_RELEASING);
break;
default:
OSMO_ASSERT(0);
}
}
static void st_releasing(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
//struct gprs_rlcmac_tbf_ul_fsm_ctx *ctx = (struct gprs_rlcmac_tbf_ul_fsm_ctx *)fi->priv;
switch (event) {
default:
OSMO_ASSERT(0);
}
}
static struct osmo_fsm_state tbf_ul_fsm_states[] = {
[GPRS_RLCMAC_TBF_UL_ST_NEW] = {
.in_event_mask =
@ -240,10 +251,17 @@ static struct osmo_fsm_state tbf_ul_fsm_states[] = {
X(GPRS_RLCMAC_TBF_UL_EV_LAST_UL_DATA_SENT) |
X(GPRS_RLCMAC_TBF_UL_EV_FINAL_ACK_RECVD),
.out_state_mask =
X(GPRS_RLCMAC_TBF_UL_ST_NEW),
X(GPRS_RLCMAC_TBF_UL_ST_NEW) |
X(GPRS_RLCMAC_TBF_UL_ST_RELEASING),
.name = "FINISHED",
.action = st_finished,
},
[GPRS_RLCMAC_TBF_UL_ST_RELEASING] = {
.in_event_mask = 0,
.out_state_mask = 0,
.name = "RELEASING",
.action = st_releasing,
},
};
static int tbf_ul_fsm_timer_cb(struct osmo_fsm_inst *fi)

View File

@ -520,6 +520,74 @@ static void test_ul_tbf_attach(void)
cleanup_test();
}
/* Test UL TBF requesting assignment of a new UL TBF through PACCH when
* answering UL ACK/NACK w/ FinalACK=1 */
static void test_ul_tbf_request_another_ul_tbf(void)
{
struct osmo_gprs_rlcmac_prim *rlcmac_prim;
int rc;
printf("=== %s start ===\n", __func__);
prepare_test();
RlcMacDownlink_t dl_block;
PU_AckNack_GPRS_t *ack_gprs = &dl_block.u.Packet_Uplink_Ack_Nack.u.PU_AckNack_GPRS_Struct;
Ack_Nack_Description_t *ack_desc = &ack_gprs->Ack_Nack_Description;
uint32_t tlli = 0x2342;
uint8_t ul_tfi = 0;
uint8_t ts_nr = 7;
uint8_t usf = 0;
uint32_t rts_fn = 4;
/* Send only 14 data to feed it in 1 UL block and speed up test length: */
rlcmac_prim = osmo_gprs_rlcmac_prim_alloc_grr_unitdata_req(tlli, pdu_llc_gmm_att_req,
14);
rlcmac_prim->grr.unitdata_req.sapi = OSMO_GPRS_RLCMAC_LLC_SAPI_GMM;
rc = osmo_gprs_rlcmac_prim_upper_down(rlcmac_prim);
OSMO_ASSERT(sizeof(ccch_imm_ass_pkt_ul_tbf_normal) == GSM_MACBLOCK_LEN);
ccch_imm_ass_pkt_ul_tbf_normal[7] = last_rach_req_ra; /* Update RA to match */
rlcmac_prim = osmo_gprs_rlcmac_prim_alloc_l1ctl_ccch_data_ind(0, ccch_imm_ass_pkt_ul_tbf_normal);
rc = osmo_gprs_rlcmac_prim_lower_up(rlcmac_prim);
/* Trigger transmission of LLC data (GMM Attach) */
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);
/* PCU acks it: */
ul_ack_nack_init(&dl_block, ul_tfi, GPRS_RLCMAC_CS_2);
ack_desc->STARTING_SEQUENCE_NUMBER = 1;
ack_desc->FINAL_ACK_INDICATION = 1;
ul_ack_nack_mark(ack_desc, 0, true);
ul_ack_nack_mark(ack_desc, 1, true);
/* TBF Est is set: */
ack_gprs->Exist_AdditionsR99 = 1;
ack_gprs->AdditionsR99.TBF_EST = 1;
/* 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);
/* New data from upper layers arrive which needs to be transmitted. This
* will make UL_TBF request a new UL_TBF when triggered to answer the final
* UL ACK/NACK, because there's no active DL TBF: */
rlcmac_prim = osmo_gprs_rlcmac_prim_alloc_grr_unitdata_req(tlli, pdu_llc_gmm_att_req,
14);
rlcmac_prim->grr.unitdata_req.sapi = OSMO_GPRS_RLCMAC_LLC_SAPI_GMM;
rc = osmo_gprs_rlcmac_prim_upper_down(rlcmac_prim);
/* Trigger transmission of PKT RES REQ: */
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();
}
static void test_ul_tbf_t3164_timeout(void)
{
struct osmo_gprs_rlcmac_prim *rlcmac_prim;
@ -773,6 +841,7 @@ int main(int argc, char *argv[])
test_ul_tbf_t3166_timeout();
test_ul_tbf_n3104_timeout();
test_ul_tbf_last_data_cv0_retrans_max();
test_ul_tbf_request_another_ul_tbf();
test_dl_tbf_ccch_assign();
talloc_free(tall_ctx);

View File

@ -53,12 +53,13 @@ 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 INFO UL_TBF{FINISHED}: state_chg to RELEASING
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 UL_TBF{RELEASING}: Deallocated
DLGLOBAL INFO Rx from upper layers: GRR-UNITDATA.request
DLGLOBAL INFO TLLI=0x00002342 not found, creating entity on the fly
DLGLOBAL INFO UL_TBF{NEW}: Allocated
@ -471,6 +472,68 @@ DLGLOBAL INFO UL_TBF{FINISHED}: Data block with CV=0 retransmit attempts=4
DLGLOBAL NOTICE UL_TBF{FINISHED}: TBF establishment failure (Data block with CV=0 retransmit attempts=4)
DLGLOBAL INFO UL_TBF_ASS{IDLE}: Deallocated
DLGLOBAL INFO UL_TBF{FINISHED}: Deallocated
DLGLOBAL INFO Rx from upper layers: GRR-UNITDATA.request
DLGLOBAL INFO TLLI=0x00002342 not found, creating entity on the fly
DLGLOBAL INFO UL_TBF{NEW}: Allocated
DLGLOBAL INFO UL_TBF_ASS{IDLE}: Allocated
DLGLOBAL INFO UL_TBF_ASS{IDLE}: Received Event START
DLGLOBAL INFO UL_TBF{NEW}: Received Event UL_ASS_START
DLGLOBAL INFO UL_TBF{NEW}: state_chg to ASSIGN
DLGLOBAL INFO UL_TBF_ASS{IDLE}: Send RACH.req ra=0x7b
DLGLOBAL INFO UL_TBF_ASS{IDLE}: state_chg to WAIT_CCCH_IMM_ASS
DLGLOBAL INFO Rx from lower layers: L1CTL-CCCH_DATA.indication
DLGLOBAL INFO UL_TBF_ASS{WAIT_CCCH_IMM_ASS}: Received Event RX_CCCH_IMM_ASS
DLGLOBAL INFO UL_TBF_ASS{WAIT_CCCH_IMM_ASS}: ImmAss initial CS=CS-2
DLGLOBAL INFO UL_TBF_ASS{WAIT_CCCH_IMM_ASS}: ImmAss DynamicAlloc (1phase access) ts_nr=7 usf=0
DLGLOBAL INFO UL_TBF_ASS{WAIT_CCCH_IMM_ASS}: state_chg to COMPLETED
DLGLOBAL INFO UL_TBF{ASSIGN}: Received Event UL_ASS_COMPL
DLGLOBAL INFO UL_TBF{ASSIGN}: Send L1CTL-CF_UL_TBF.req ul_slotmask=0x80
DLGLOBAL INFO UL_TBF{ASSIGN}: state_chg to FLOW
DLGLOBAL INFO UL_TBF_ASS{COMPLETED}: state_chg to IDLE
DLGLOBAL INFO Rx from lower layers: L1CTL-PDCH_RTS.indication
DLGLOBAL DEBUG TBF(UL:NR-0:TLLI-00002342) Sending new block at BSN 0, CS=CS-2
DLGLOBAL DEBUG TBF(UL:NR-0:TLLI-00002342) Dequeue next LLC (len=14)
DLGLOBAL DEBUG -- Chunk with length 14 is less than remaining space (26): add length header to delimit LLC frame
DLGLOBAL DEBUG -- Final block, so we done.
DLGLOBAL DEBUG TBF(UL:NR-0:TLLI-00002342) Complete UL frame, len=0
DLGLOBAL DEBUG TBF(UL:NR-0:TLLI-00002342) data block (BSN 0, CS-2): 39 00 00 23 42 01 c0 00 08 01 01 d5 71 00 00 08 29 26 24 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b
DLGLOBAL DEBUG TBF(UL:NR-0:TLLI-00002342) need_padding 0 spb_status 0 spb 0 (BSN1 0 BSN2 -1)
DLGLOBAL DEBUG TBF(UL:NR-0:TLLI-00002342) Copying 1 RLC blocks, 1 BSNs
DLGLOBAL DEBUG TBF(UL:NR-0:TLLI-00002342) Copying data unit 0 (BSN 0)
DLGLOBAL DEBUG TBF(UL:NR-0:TLLI-00002342) msg block (BSN 0, CS-2): 00 00 00 39 00 00 23 42 01 c0 00 08 01 01 d5 71 00 00 08 29 26 24 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 00
DLGLOBAL INFO UL_TBF{FLOW}: Received Event FIRST_UL_DATA_SENT
DLGLOBAL INFO UL_TBF{FLOW}: First UL block sent, stop T3164
DLGLOBAL INFO UL_TBF{FLOW}: First UL block sent (1 phase access), start T3166
DLGLOBAL INFO UL_TBF{FLOW}: Received Event LAST_UL_DATA_SENT
DLGLOBAL INFO UL_TBF{FLOW}: state_chg to FINISHED
DLGLOBAL DEBUG TBF(UL:NR-0:TLLI-00002342) N3104 inc (1)
DLGLOBAL INFO Rx from lower layers: L1CTL-PDCH_DATA.indication
DLGLOBAL INFO TS=7 FN=4 Rx Pkt UL ACK/NACK
DLGLOBAL DEBUG TBF(UL:NR-0:TLLI-00002342) Got GPRS UL ACK bitmap: SSN: 1, BSN 0 to 1 - 1 (1 blocks), "R"
DLGLOBAL DEBUG TBF(UL:NR-0:TLLI-00002342) ack: (BSN=0)"R"(BSN=0) R=ACK I=NACK
DLGLOBAL DEBUG - got ack for BSN=0
DLGLOBAL DEBUG TBF(UL:NR-0:TLLI-00002342) V(B): (V(A)=1)""(V(S)-1=0) A=Acked N=Nacked U=Unacked X=Resend-Unacked I=Invalid
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 INFO UL_TBF{FINISHED}: state_chg to RELEASING
DLGLOBAL DEBUG Register POLL (TS=7 FN=17, reason=UL_ACK)
DLGLOBAL INFO Rx from upper layers: GRR-UNITDATA.request
DLGLOBAL INFO Rx from lower layers: L1CTL-PDCH_RTS.indication
DLGLOBAL DEBUG (ts=7,fn=17,usf=0) Tx Pkt Resource Request (UL ACK/NACK poll)
DLGLOBAL INFO UL_TBF{NEW}: Allocated
DLGLOBAL INFO UL_TBF_ASS{IDLE}: Allocated
DLGLOBAL INFO UL_TBF_ASS{IDLE}: Received Event START_DIRECT_2PHASE
DLGLOBAL INFO UL_TBF{NEW}: Received Event UL_ASS_START
DLGLOBAL INFO UL_TBF{NEW}: state_chg to ASSIGN
DLGLOBAL INFO UL_TBF_ASS{IDLE}: state_chg to SCHED_PKT_RES_REQ
DLGLOBAL INFO UL_TBF_ASS{IDLE}: Deallocated
DLGLOBAL INFO UL_TBF{RELEASING}: Deallocated
DLGLOBAL INFO UL_TBF_ASS{SCHED_PKT_RES_REQ}: Received Event CREATE_RLCMAC_MSG
DLGLOBAL INFO UL_TBF_ASS{SCHED_PKT_RES_REQ}: state_chg to WAIT_PKT_UL_ASS
DLGLOBAL INFO UL_TBF_ASS{WAIT_PKT_UL_ASS}: Deallocated
DLGLOBAL INFO UL_TBF{ASSIGN}: Deallocated
DLGLOBAL INFO Rx from upper layers: GMMRR-ASSIGN.request
DLGLOBAL INFO GMMRR-ASSIGN.req: creating new entity TLLI=0x00000001
DLGLOBAL INFO Rx from lower layers: L1CTL-CCCH_DATA.indication

View File

@ -95,6 +95,13 @@ test_rlcmac_prim_down_cb(): Rx L1CTL-PDCH_DATA.request fn=21 ts=7 data_len=34 da
RTS 3: FN=26
test_rlcmac_prim_down_cb(): Rx L1CTL-PDCH_DATA.request fn=26 ts=7 data_len=34 data=[00 00 02 1d 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 2b 2b 2b 2b 00 ]
=== test_ul_tbf_last_data_cv0_retrans_max end ===
=== test_ul_tbf_request_another_ul_tbf start ===
sys={0.000000}, mono={0.000000}: clock_override_set
test_rlcmac_prim_down_cb(): Rx L1CTL-RACH.request ra=0x7b
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=[00 00 00 39 00 00 23 42 01 c0 00 08 01 01 d5 71 00 00 08 29 26 24 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 00 ]
test_rlcmac_prim_down_cb(): Rx L1CTL-PDCH_DATA.request fn=17 ts=7 data_len=23 data=[40 16 40 00 08 d0 a0 bc 00 00 00 00 00 00 70 00 38 00 00 2b 2b 2b 2b ]
=== test_ul_tbf_request_another_ul_tbf end ===
=== test_dl_tbf_ccch_assign start ===
sys={0.000000}, mono={0.000000}: clock_override_set
test_rlcmac_prim_down_cb(): Rx L1CTL-CFG_DL_TBF.request dl_tbf_nr=0 dl_slotmask=0x80 dl_tfi=0