rlcmac: dl_tbf: Improve logic requesting a new UL TBF

Change-Id: I702872ba32a410bb5f09943af3cdadca482562db
This commit is contained in:
Pau Espin 2023-02-27 17:16:16 +01:00 committed by pespin
parent eb622ef09c
commit 9a212cc2b6
12 changed files with 491 additions and 26 deletions

View File

@ -20,6 +20,10 @@ struct gprs_rlcmac_entity {
struct gprs_rlcmac_entity *gprs_rlcmac_entity_alloc(uint32_t tlli);
void gprs_rlcmac_entity_free(struct gprs_rlcmac_entity *gre);
bool gprs_rlcmac_entity_in_packet_idle_mode(const struct gprs_rlcmac_entity *gre);
bool gprs_rlcmac_entity_in_packet_transfer_mode(const struct gprs_rlcmac_entity *gre);
bool gprs_rlcmac_entity_have_tx_data_queued(const struct gprs_rlcmac_entity *gre);
int gprs_rlcmac_entity_llc_enqueue(struct gprs_rlcmac_entity *gre, uint8_t *ll_pdu, unsigned int ll_pdu_len,
enum osmo_gprs_rlcmac_llc_sapi sapi, uint8_t radio_prio);

View File

@ -58,6 +58,9 @@ struct msgb *gprs_rlcmac_ul_tbf_create_pkt_ctrl_ack(const struct gprs_rlcmac_ul_
int gprs_rlcmac_ul_tbf_handle_pkt_ul_ack_nack(struct gprs_rlcmac_ul_tbf *ul_tbf,
const RlcMacDownlink_t *dl_block);
int gprs_rlcmac_ul_tbf_handle_pkt_ul_ass(struct gprs_rlcmac_ul_tbf *ul_tbf,
const struct osmo_gprs_rlcmac_prim *rlcmac_prim,
const RlcMacDownlink_t *dl_block);
static inline struct gprs_rlcmac_tbf *ul_tbf_as_tbf(struct gprs_rlcmac_ul_tbf *ul_tbf)
{

View File

@ -32,14 +32,11 @@ struct gprs_rlcmac_tbf_ul_ass_fsm_ctx {
struct gprs_rlcmac_tbf *tbf;
struct gprs_rlcmac_ul_tbf *ul_tbf;
};
const struct gprs_rlcmac_dl_tbf *dl_tbf; /* Not null if assignment was started by a DL TBF ACK/NACK */
enum gprs_rlcmac_tbf_ul_ass_type ass_type;
uint8_t rach_req_ra;
struct gprs_rlcmac_ul_tbf_allocation phase1_alloc;
struct gprs_rlcmac_ul_tbf_allocation phase2_alloc;
struct { /* Filled when we receive the poll; exact time here the response PKT CTL ACK is to be transmitted: */
uint8_t ts;
uint32_t fn;
} sched_pkt_ctrl_ack;
/* Number of packet resource request transmitted (T3168) */
unsigned int pkt_res_req_proc_attempts;
};
@ -47,9 +44,10 @@ 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_START_FROM_DL_TBF, /* Uplink assignment requested by DL TBF ACK/NACK, wait to receive Pkt Ul Ass on its PACCH */
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) */
GPRS_RLCMAC_TBF_UL_ASS_EV_RX_PKT_UL_ASS, /* (data: struct tbf_ul_ass_ev_create_rlcmac_msg_ctx) */
GPRS_RLCMAC_TBF_UL_ASS_EV_FOOBAR,
};
@ -59,6 +57,12 @@ struct tbf_ul_ass_ev_rx_ccch_imm_ass_ctx {
const IA_RestOctets_t *iaro;
};
struct tbf_ul_ass_ev_rx_pkt_ul_ass_ctx {
uint8_t ts_nr;
uint32_t fn;
const RlcMacDownlink_t *dl_block; /* decoded PktUlAss */
};
struct tbf_ul_ass_ev_create_rlcmac_msg_ctx {
uint8_t ts; /* TS where the created UL ctrl block is to be sent */
uint32_t fn; /* FN where the created UL ctrl block is to be sent */
@ -73,6 +77,8 @@ 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);
int gprs_rlcmac_tbf_ul_ass_start_from_dl_tbf_ack_nack(struct gprs_rlcmac_ul_tbf *ul_tbf, const struct gprs_rlcmac_dl_tbf *dl_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

@ -66,6 +66,40 @@ void gprs_rlcmac_entity_free(struct gprs_rlcmac_entity *gre)
talloc_free(gre);
}
/* TS 44.060 5.3 In packet idle mode:
* - no temporary block flow (TBF) exists..
* - the mobile station monitors the relevant paging subchannels on CCCH. In packet
* idle mode, upper layers may require the transfer of a upper layer PDU, which
* implicitly triggers the establishment of a TBF and the transition to packet
* transfer mode. In packet idle mode, upper layers may require the establishment
* of an RR connection. When the mobile station enters dedicated mode (see 3GPP TS
* 44.018), it may leave the packet idle mode, if the mobile station limitations
* make it unable to handle the RR connection and the procedures in packet idle
* mode simultaneously.*/
bool gprs_rlcmac_entity_in_packet_idle_mode(const struct gprs_rlcmac_entity *gre)
{
return !gre->ul_tbf && !gre->dl_tbf;
}
/* TS 44.060 5.4 "In packet transfer mode, the mobile station is allocated radio
* resources providing one or more TBFs. [...]
* When a transfer of upper layer PDUs
* terminates, in either downlink or uplink direction, the corresponding TBF is
* released. In packet transfer mode, when all TBFs have been released, in downlink
* and uplink direction, the mobile station returns to packet idle mode."
*/
bool gprs_rlcmac_entity_in_packet_transfer_mode(const struct gprs_rlcmac_entity *gre)
{
return gre->ul_tbf || gre->dl_tbf;
}
/* Whether MS has data queued from upper layers waiting to be transmitted in the
* Tx queue (an active UL TBF may still have some extra data) */
bool gprs_rlcmac_entity_have_tx_data_queued(const struct gprs_rlcmac_entity *gre)
{
return gprs_rlcmac_llc_queue_size(gre->llc_queue) > 0;
}
int gprs_rlcmac_entity_llc_enqueue(struct gprs_rlcmac_entity *gre, uint8_t *ll_pdu, unsigned int ll_pdu_len,
enum osmo_gprs_rlcmac_llc_sapi sapi, uint8_t radio_prio)
{
@ -75,7 +109,11 @@ int gprs_rlcmac_entity_llc_enqueue(struct gprs_rlcmac_entity *gre, uint8_t *ll_p
if (rc < 0)
return rc;
if (!gre->ul_tbf) {
/* TS 44.060 5.3 "In packet idle mode, upper layers may require the
* transfer of a upper layer PDU, which implicitly triggers the
* establishment of a TBF and the transition to packet transfer mode." */
if (gprs_rlcmac_entity_in_packet_idle_mode(gre)) {
OSMO_ASSERT(!gre->ul_tbf);
/* We have new data in the queue but we have no ul_tbf. Allocate one and start UL Assignment. */
gre->ul_tbf = gprs_rlcmac_ul_tbf_alloc(gre);
if (!gre->ul_tbf)

View File

@ -358,6 +358,58 @@ static int gprs_rlcmac_handle_pkt_ul_ack_nack(const struct osmo_gprs_rlcmac_prim
return rc;
}
static int gprs_rlcmac_handle_pkt_ul_ass(const struct osmo_gprs_rlcmac_prim *rlcmac_prim, const RlcMacDownlink_t *dl_block)
{
struct gprs_rlcmac_entity *gre = NULL;
struct gprs_rlcmac_ul_tbf *ul_tbf = NULL;
struct gprs_rlcmac_dl_tbf *dl_tbf;
const Packet_Uplink_Assignment_t *ulass = &dl_block->u.Packet_Uplink_Assignment;
int rc;
/* Attempt to find relevant UL TBF in assignment state from ID (set "gre" ptr): */
switch (ulass->ID.UnionType) {
case 0: /* GLOBAL_TFI: */
switch (ulass->ID.u.Global_TFI.UnionType) {
case 0: /* UL TFI */
ul_tbf = gprs_rlcmac_find_ul_tbf_by_tfi(ulass->ID.u.Global_TFI.u.UPLINK_TFI);
gre = ul_tbf->tbf.gre;
break;
case 1: /* DL TFI */
dl_tbf = gprs_rlcmac_find_dl_tbf_by_tfi(ulass->ID.u.Global_TFI.u.DOWNLINK_TFI);
if (dl_tbf)
gre = dl_tbf->tbf.gre;
break;
default:
OSMO_ASSERT(0);
}
break;
case 1: /* TLLI */
gre = gprs_rlcmac_find_entity_by_tlli(ulass->ID.u.TLLI);
if (gre)
ul_tbf = gre->ul_tbf;
break;
case 2: /* TQI */
case 3: /* Packet_Request_Reference */
LOGRLCMAC(LOGL_NOTICE, "TS=%u FN=%u Rx Pkt UL ASS: HANDLING OF ID=%u NOT IMPLEMENTED!\n",
ulass->ID.UnionType,
rlcmac_prim->l1ctl.pdch_data_ind.ts_nr,
rlcmac_prim->l1ctl.pdch_data_ind.fn);
break;
}
if (!gre->ul_tbf) {
LOGRLCMAC(LOGL_INFO, "TS=%u FN=%u Rx Pkt UL ACK/NACK: UL_TBF TFI=%u not found\n",
rlcmac_prim->l1ctl.pdch_data_ind.ts_nr,
rlcmac_prim->l1ctl.pdch_data_ind.fn,
dl_block->TFI);
return -ENOENT;
}
rc = gprs_rlcmac_ul_tbf_handle_pkt_ul_ass(gre->ul_tbf, rlcmac_prim, dl_block);
return rc;
}
static int gprs_rlcmac_handle_gprs_dl_ctrl_block(const struct osmo_gprs_rlcmac_prim *rlcmac_prim)
{
struct bitvec *bv;
@ -388,6 +440,9 @@ static int gprs_rlcmac_handle_gprs_dl_ctrl_block(const struct osmo_gprs_rlcmac_p
case OSMO_GPRS_RLCMAC_DL_MSGT_PACKET_UPLINK_ACK_NACK:
rc = gprs_rlcmac_handle_pkt_ul_ack_nack(rlcmac_prim, dl_ctrl_block);
break;
case OSMO_GPRS_RLCMAC_DL_MSGT_PACKET_UPLINK_ASSIGNMENT:
rc = gprs_rlcmac_handle_pkt_ul_ass(rlcmac_prim, dl_ctrl_block);
break;
default:
LOGRLCMAC(LOGL_ERROR, "TS=%u FN=%u Rx %s NOT SUPPORTED! ignoring\n",
rlcmac_prim->l1ctl.pdch_data_ind.ts_nr,

View File

@ -386,6 +386,7 @@ void gprs_rlcmac_enc_prepare_pkt_downlink_ack_nack(RlcMacUplink_t *block, const
{
Packet_Downlink_Ack_Nack_t *ack = &block->u.Packet_Downlink_Ack_Nack;
struct gprs_rlcmac_entity *gre = dl_tbf->tbf.gre;
int rc;
memset(block, 0, sizeof(*block));
ack->MESSAGE_TYPE = OSMO_GPRS_RLCMAC_UL_MSGT_PACKET_RESOURCE_REQUEST;
@ -395,8 +396,9 @@ void gprs_rlcmac_enc_prepare_pkt_downlink_ack_nack(RlcMacUplink_t *block, const
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. Request a UL-TBF if we have UL data
* queued to send and no active UL BF (TS 44.060 8.1.2.5) */
if (!gre->ul_tbf && gprs_rlcmac_entity_have_tx_data_queued(gre)) {
Channel_Request_Description_t *chan_req = &ack->Channel_Request_Description;
ack->Exist_Channel_Request_Description = 1;
chan_req->PEAK_THROUGHPUT_CLASS = 0; /* TODO */
@ -404,6 +406,11 @@ void gprs_rlcmac_enc_prepare_pkt_downlink_ack_nack(RlcMacUplink_t *block, const
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 */
gre->ul_tbf = gprs_rlcmac_ul_tbf_alloc(gre);
rc = gprs_rlcmac_tbf_ul_ass_start_from_dl_tbf_ack_nack(gre->ul_tbf, dl_tbf);
if (rc < 0)
LOGPTBFDL(dl_tbf, LOGL_ERROR, "Failed starting assignment of requested UL TBF (%d)\n", rc);
} else {
ack->Exist_Channel_Request_Description = 0;
}

View File

@ -37,7 +37,8 @@ struct tbf_sched_ctrl_candidates {
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;
struct gprs_rlcmac_ul_tbf *poll_ul_ass; /* (answer Pkt UL ASS with PKT CTRL ACK) */
struct gprs_rlcmac_ul_tbf *ul_ass; /* PCU grants USF/SBA: transmit Pkt Res Req (2phase access)*/
};
static inline bool fn_valid(uint32_t fn)
@ -80,7 +81,8 @@ static void get_ctrl_msg_tbf_candidates(const struct gprs_rlcmac_rts_block_ind *
if (node) {
switch (node->reason) {
case GPRS_RLCMAC_PDCH_ULC_POLL_UL_ASS:
/* TODO */
/* Answer with ctrl ack generated by ul_tbf->ul_ass_fsm. */
tbfs->poll_ul_ass = tbf_as_ul_tbf(node->tbf);
break;
case GPRS_RLCMAC_PDCH_ULC_POLL_DL_ASS:
/* TODO */
@ -207,6 +209,11 @@ static struct msgb *sched_select_ctrl_msg(const struct gprs_rlcmac_rts_block_ind
gprs_rlcmac_ul_tbf_free(tbfs->poll_ul_ack);
return msg;
}
if (tbfs->poll_ul_ass) {
msg = gprs_rlcmac_tbf_ul_ass_create_rlcmac_msg(tbfs->poll_ul_ass, bi);
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

@ -261,6 +261,21 @@ int gprs_rlcmac_ul_tbf_handle_pkt_ul_ack_nack(struct gprs_rlcmac_ul_tbf *ul_tbf,
return rc;
}
int gprs_rlcmac_ul_tbf_handle_pkt_ul_ass(struct gprs_rlcmac_ul_tbf *ul_tbf,
const struct osmo_gprs_rlcmac_prim *rlcmac_prim,
const RlcMacDownlink_t *dl_block)
{
int rc;
struct tbf_ul_ass_ev_rx_pkt_ul_ass_ctx d = {
.ts_nr = rlcmac_prim->l1ctl.pdch_data_ind.ts_nr,
.fn = rlcmac_prim->l1ctl.pdch_data_ind.fn,
.dl_block = dl_block,
};
rc = osmo_fsm_inst_dispatch(ul_tbf->ul_ass_fsm.fi, GPRS_RLCMAC_TBF_UL_ASS_EV_RX_PKT_UL_ASS, &d);
return rc;
}
struct msgb *gprs_rlcmac_ul_tbf_dummy_create(const struct gprs_rlcmac_ul_tbf *ul_tbf)
{
struct msgb *msg;
@ -333,7 +348,7 @@ free_ret:
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) ||
(gprs_rlcmac_llc_queue_size(ul_tbf->tbf.gre->llc_queue) > 0);
gprs_rlcmac_entity_have_tx_data_queued(ul_tbf->tbf.gre);
}
bool gprs_rlcmac_ul_tbf_shall_keep_open(const struct gprs_rlcmac_ul_tbf *ul_tbf, const struct gprs_rlcmac_rts_block_ind *bi)

View File

@ -32,12 +32,14 @@
#include <osmocom/gprs/rlcmac/sched.h>
#include <osmocom/gprs/rlcmac/csn1_defs.h>
#include <osmocom/gprs/rlcmac/rlcmac_enc.h>
#include <osmocom/gprs/rlcmac/pdch_ul_controller.h>
#define X(s) (1 << (s))
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_START_FROM_DL_TBF, "START_FROM_DL_TBF" },
{ 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" },
@ -165,14 +167,73 @@ static int handle_imm_ass(struct gprs_rlcmac_tbf_ul_ass_fsm_ctx *ctx, const stru
return -EFAULT;
}
static int handle_pkt_ul_ass(struct gprs_rlcmac_tbf_ul_ass_fsm_ctx *ctx, const struct tbf_ul_ass_ev_rx_pkt_ul_ass_ctx *d)
{
const Packet_Uplink_Assignment_t *ulass = &d->dl_block->u.Packet_Uplink_Assignment;
uint8_t tn;
const Timeslot_Allocation_t *ts_alloc;
const Timeslot_Allocation_Power_Ctrl_Param_t *ts_alloc_pwr_ctl;
switch (ulass->UnionType) {
case 0: /* ulass->u.PUA_GPRS_Struct.* (PUA_GPRS_t) */
ctx->ul_tbf->tx_cs = ulass->u.PUA_GPRS_Struct.CHANNEL_CODING_COMMAND + 1;
switch (ulass->u.PUA_GPRS_Struct.UnionType) {
case 1: /* Dynamic Allocation (Dynamic_Allocation_t) */
if (ulass->u.PUA_GPRS_Struct.u.Dynamic_Allocation.Exist_UPLINK_TFI_ASSIGNMENT)
ctx->phase2_alloc.ul_tfi = ulass->u.PUA_GPRS_Struct.u.Dynamic_Allocation.UPLINK_TFI_ASSIGNMENT;
/* TODO: P0, PR_MODE, USF_GRANULARITY, RLC_DATA_BLOCKS_GRANTED, TBF_Starting_Time */
switch (ulass->u.PUA_GPRS_Struct.u.Dynamic_Allocation.UnionType) {
case 0: /* Timeslot_Allocation_t */
ts_alloc = &ulass->u.PUA_GPRS_Struct.u.Dynamic_Allocation.u.Timeslot_Allocation[0];
ctx->phase2_alloc.num_ts = 0;
for (tn = 0; tn < 8; tn++) {
ctx->phase2_alloc.ts[tn].allocated = ts_alloc[tn].Exist;
if (ts_alloc[tn].Exist) {
ctx->phase2_alloc.num_ts++;
ctx->phase2_alloc.ts[tn].usf = ts_alloc[tn].USF_TN;
}
}
break;
case 1: /* Timeslot_Allocation_Power_Ctrl_Param_t */
/* TODO: ALPHA, GAMMA */
ts_alloc_pwr_ctl = &ulass->u.PUA_GPRS_Struct.u.Dynamic_Allocation.u.Timeslot_Allocation_Power_Ctrl_Param;
ctx->phase2_alloc.num_ts = 0;
for (tn = 0; tn < 8; tn++) {
ctx->phase2_alloc.ts[tn].allocated = ts_alloc_pwr_ctl->Slot[tn].Exist;
if (ts_alloc_pwr_ctl->Slot[tn].Exist) {
ctx->phase2_alloc.num_ts++;
ctx->phase2_alloc.ts[tn].usf = ts_alloc_pwr_ctl->Slot[tn].USF_TN;
}
}
break;
}
break;
case 2: /* Single Block Allocation */
LOGPFSML(ctx->fi, LOGL_NOTICE, "Rx Pkt Ul Ass GPRS Single Block Allocation not supported!\n");
return -ENOTSUP;
case 0: /* Fixed Allocation */
LOGPFSML(ctx->fi, LOGL_NOTICE, "Rx Pkt Ul Ass GPRS Fixed Allocation not supported!\n");
return -ENOTSUP;
}
return 0;
case 1: /* ulass->u.PUA_EGPRS_Struct.* (PUA_EGPRS_t) */
LOGPFSML(ctx->fi, LOGL_NOTICE, "Rx Pkt Ul Ass EGPRS not supported!\n");
return -ENOTSUP;
}
OSMO_ASSERT(0);
return -EFAULT;
}
static void st_idle_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state)
{
struct gprs_rlcmac_tbf_ul_ass_fsm_ctx *ctx = (struct gprs_rlcmac_tbf_ul_ass_fsm_ctx *)fi->priv;
/* Reset state: */
ctx->dl_tbf = NULL;
memset(&ctx->phase1_alloc, 0, sizeof(ctx->phase1_alloc));
memset(&ctx->phase2_alloc, 0, sizeof(ctx->phase2_alloc));
memset(&ctx->sched_pkt_ctrl_ack, 0, sizeof(ctx->sched_pkt_ctrl_ack));
}
static void st_idle(struct osmo_fsm_inst *fi, uint32_t event, void *data)
@ -191,6 +252,11 @@ static void st_idle(struct osmo_fsm_inst *fi, uint32_t event, void *data)
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;
case GPRS_RLCMAC_TBF_UL_ASS_EV_START_FROM_DL_TBF:
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_WAIT_PKT_UL_ASS);
break;
default:
OSMO_ASSERT(0);
}
@ -235,12 +301,27 @@ static void st_sched_pkt_res_req(struct osmo_fsm_inst *fi, uint32_t event, void
static void st_wait_pkt_ul_ass(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
//struct gprs_rlcmac_tbf_ul_ass_fsm_ctx *ctx = (struct gprs_rlcmac_tbf_ul_ass_fsm_ctx *)fi->priv;
struct gprs_rlcmac_tbf_ul_ass_fsm_ctx *ctx = (struct gprs_rlcmac_tbf_ul_ass_fsm_ctx *)fi->priv;
struct tbf_ul_ass_ev_rx_pkt_ul_ass_ctx *d;
int rc;
switch (event) {
case GPRS_RLCMAC_TBF_UL_ASS_EV_RX_PKT_UL_ASS:
// TODO: fill ctx->phase2_alloc with contents from pkt_ul_ass
d = data;
rc = handle_pkt_ul_ass(ctx, d);
if (rc < 0)
LOGPFSML(fi, LOGL_ERROR, "Rx Pkt Ul Ass: failed to parse!\n");
// TODO: what to do if Pkt_ul_ass is "reject"? need to check spec, depending on cause.
tbf_ul_ass_fsm_state_chg(fi, GPRS_RLCMAC_TBF_UL_ASS_ST_SCHED_PKT_CTRL_ACK);
/* If RRBP contains valid data, schedule a response (PKT CONTROL ACK or PKT RESOURCE REQ). */
if (d->dl_block->SP) {
uint32_t poll_fn = rrbp2fn(d->fn, d->dl_block->RRBP);
gprs_rlcmac_pdch_ulc_reserve(g_ctx->sched.ulc[d->ts_nr], poll_fn,
GPRS_RLCMAC_PDCH_ULC_POLL_UL_ASS,
ul_tbf_as_tbf(ctx->ul_tbf));
tbf_ul_ass_fsm_state_chg(fi, GPRS_RLCMAC_TBF_UL_ASS_ST_SCHED_PKT_CTRL_ACK);
} else {
tbf_ul_ass_fsm_state_chg(fi, GPRS_RLCMAC_TBF_UL_ASS_ST_COMPL);
}
break;
default:
OSMO_ASSERT(0);
@ -249,15 +330,13 @@ static void st_wait_pkt_ul_ass(struct osmo_fsm_inst *fi, uint32_t event, void *d
static void st_sched_pkt_ctrl_ack(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
//struct gprs_rlcmac_tbf_ul_ass_fsm_ctx *ctx = (struct gprs_rlcmac_tbf_ul_ass_fsm_ctx *)fi->priv;
struct gprs_rlcmac_tbf_ul_ass_fsm_ctx *ctx = (struct gprs_rlcmac_tbf_ul_ass_fsm_ctx *)fi->priv;
struct tbf_ul_ass_ev_create_rlcmac_msg_ctx *data_ctx;
switch (event) {
case GPRS_RLCMAC_TBF_UL_ASS_EV_CREATE_RLCMAC_MSG:
data_ctx = (struct tbf_ul_ass_ev_create_rlcmac_msg_ctx *)data;
LOGPFSML(fi, LOGL_ERROR, "TODO: create PKT CTRL ACK...\n");
//data_ctx->msg = create_packet_ctrl_ack(ctx, data_ctx);
data_ctx->msg = NULL;
data_ctx->msg = gprs_rlcmac_ul_tbf_create_pkt_ctrl_ack(ctx->ul_tbf);
if (!data_ctx->msg)
return;
tbf_ul_ass_fsm_state_chg(fi, GPRS_RLCMAC_TBF_UL_ASS_ST_COMPL);
@ -275,7 +354,7 @@ static void st_compl_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state)
if (ctx->ass_type == GPRS_RLCMAC_TBF_UL_ASS_TYPE_1PHASE)
memcpy(&ctx->ul_tbf->cur_alloc, &ctx->phase1_alloc, sizeof(ctx->phase1_alloc));
else
memcpy(&ctx->ul_tbf->cur_alloc, &ctx->phase2_alloc, sizeof(ctx->phase1_alloc));
memcpy(&ctx->ul_tbf->cur_alloc, &ctx->phase2_alloc, sizeof(ctx->phase2_alloc));
/* Inform the main TBF state about the assignment completed: */
osmo_fsm_inst_dispatch(ctx->ul_tbf->state_fsm.fi, GPRS_RLCMAC_TBF_UL_EV_UL_ASS_COMPL, NULL);
/* Go back to IDLE state. */
@ -286,10 +365,12 @@ 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_DIRECT_2PHASE),
X(GPRS_RLCMAC_TBF_UL_ASS_EV_START_DIRECT_2PHASE) |
X(GPRS_RLCMAC_TBF_UL_ASS_EV_START_FROM_DL_TBF),
.out_state_mask =
X(GPRS_RLCMAC_TBF_UL_ASS_ST_WAIT_CCCH_IMM_ASS) |
X(GPRS_RLCMAC_TBF_UL_ASS_ST_SCHED_PKT_RES_REQ),
X(GPRS_RLCMAC_TBF_UL_ASS_ST_SCHED_PKT_RES_REQ) |
X(GPRS_RLCMAC_TBF_UL_ASS_ST_WAIT_PKT_UL_ASS),
.name = "IDLE",
.onenter = st_idle_on_enter,
.action = st_idle,
@ -316,7 +397,8 @@ static struct osmo_fsm_state tbf_ul_ass_fsm_states[] = {
X(GPRS_RLCMAC_TBF_UL_ASS_EV_RX_PKT_UL_ASS),
.out_state_mask =
X(GPRS_RLCMAC_TBF_UL_ASS_ST_SCHED_PKT_RES_REQ) |
X(GPRS_RLCMAC_TBF_UL_ASS_ST_SCHED_PKT_CTRL_ACK),
X(GPRS_RLCMAC_TBF_UL_ASS_ST_SCHED_PKT_CTRL_ACK) |
X(GPRS_RLCMAC_TBF_UL_ASS_ST_COMPL),
.name = "WAIT_PKT_UL_ASS",
.action = st_wait_pkt_ul_ass,
},
@ -343,6 +425,17 @@ static int tbf_ul_ass_fsm_timer_cb(struct osmo_fsm_inst *fi)
struct gprs_rlcmac_tbf_ul_ass_fsm_ctx *ctx = (struct gprs_rlcmac_tbf_ul_ass_fsm_ctx *)fi->priv;
switch (fi->T) {
case 3168:
/* If the UL TBF assignment was started from DL TBF it is not
really possible reattempting because we haven't yet any phase1
allocation. Hence simply destroy the TBF and let next DL TBF DL
ACK/NACK re-request an UL TBF assignment: */
if (ctx->dl_tbf) {
LOGPFSML(ctx->fi, LOGL_NOTICE,
"UL TBF establishment failure (T3168 timeout attempts=%u, ass from DL TBF)\n",
ctx->pkt_res_req_proc_attempts);
gprs_rlcmac_ul_tbf_free(ctx->ul_tbf);
return 0;
}
/* TS 44.060 7.1.3.3: "the mobile station shall then reinitiate the packet access
* procedure unless the packet access procedure has already been attempted four
* times. In that case, TBF failure has occurred and an RLC/MAC error should be
@ -424,6 +517,18 @@ int gprs_rlcmac_tbf_ul_ass_start_from_releasing_ul_tbf(struct gprs_rlcmac_ul_tbf
return rc;
}
/* A DL-TBF requested a UL TBF over DL ACK/NACK, wait to receive Pkt Ul Ass for
* it, aka switch the FSM to trigger the 2hpase directly (tx Pkt Res Req) */
int gprs_rlcmac_tbf_ul_ass_start_from_dl_tbf_ack_nack(struct gprs_rlcmac_ul_tbf *ul_tbf, const struct gprs_rlcmac_dl_tbf *dl_tbf)
{
int rc;
ul_tbf->ul_ass_fsm.dl_tbf = dl_tbf;
rc = osmo_fsm_inst_dispatch(ul_tbf->ul_ass_fsm.fi,
GPRS_RLCMAC_TBF_UL_ASS_EV_START_FROM_DL_TBF,
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;
@ -449,9 +554,6 @@ bool gprs_rlcmac_tbf_ul_ass_rts(const struct gprs_rlcmac_ul_tbf *ul_tbf, const s
case GPRS_RLCMAC_TBF_UL_ASS_ST_SCHED_PKT_RES_REQ:
return (ctx->phase1_alloc.ts[bi->ts].allocated &&
ctx->phase1_alloc.ts[bi->ts].usf == bi->usf);
case GPRS_RLCMAC_TBF_UL_ASS_ST_SCHED_PKT_CTRL_ACK:
return (ctx->sched_pkt_ctrl_ack.ts == bi->ts &&
ctx->sched_pkt_ctrl_ack.fn == bi->fn);
default:
return false;
};

View File

@ -295,6 +295,75 @@ static void ul_ack_nack_mark(Ack_Nack_Description_t *ack_desc, unsigned int idx,
ack_desc->RECEIVED_BLOCK_BITMAP[sizeof(ack_desc->RECEIVED_BLOCK_BITMAP) - idx/8 - 1] &= ~(1 << (idx & 0x03));
}
static void pkt_ul_ass_from_dl_tbf_init(RlcMacDownlink_t *block, uint8_t dl_tfi, uint8_t new_ul_tfi, uint16_t arfcn, uint8_t *usf_li)
{
Packet_Uplink_Assignment_t *pua = &block->u.Packet_Uplink_Assignment;
PUA_GPRS_t *gprs = &pua->u.PUA_GPRS_Struct;
Packet_Timing_Advance_t *pta = &gprs->Packet_Timing_Advance;
Frequency_Parameters_t *fp = &gprs->Frequency_Parameters;
Dynamic_Allocation_t *da = &gprs->u.Dynamic_Allocation;
unsigned int tn;
memset(block, 0, sizeof(*block));
block->PAYLOAD_TYPE = GPRS_RLCMAC_PT_CONTROL_BLOCK;
block->RRBP = 0;
block->SP = 0;
block->USF = 0x00;
block->u.MESSAGE_TYPE = OSMO_GPRS_RLCMAC_DL_MSGT_PACKET_UPLINK_ASSIGNMENT;
/* See 3GPP TS 44.060, section 11.2.29 */
pua = &block->u.Packet_Uplink_Assignment;
pua->MESSAGE_TYPE = OSMO_GPRS_RLCMAC_DL_MSGT_PACKET_UPLINK_ASSIGNMENT;
pua->PAGE_MODE = 0x00;
/* TLLI or Global DL TFI */
pua->ID.UnionType = 0x00;
pua->ID.u.Global_TFI.UnionType = 0x01;
pua->ID.u.Global_TFI.u.UPLINK_TFI = dl_tfi;
/* GPRS specific parameters */
pua->UnionType = 0x00;
/* Use the commanded CS/MCS value during the content resolution */
gprs->CHANNEL_CODING_COMMAND = gprs_rlcmac_mcs_chan_code(GPRS_RLCMAC_MCS_2);
gprs->TLLI_BLOCK_CHANNEL_CODING = 0x01; // ^^^
/* Dynamic allocation */
gprs->UnionType = 0x01;
/* Frequency Parameters IE is present */
gprs->Exist_Frequency_Parameters = 0x01;
/* Packet Timing Advance (if known) */
pta->Exist_TIMING_ADVANCE_VALUE = 0x01; // Present
pta->TIMING_ADVANCE_VALUE = 1;
/* Continuous Timing Advance Control */
pta->Exist_IndexAndtimeSlot = 0x01; // Present
pta->TIMING_ADVANCE_TIMESLOT_NUMBER = 0; // FIXME!
pta->TIMING_ADVANCE_INDEX = 2;
/* Frequency Parameters IE */
fp->TSC = 2;
fp->UnionType = 0x00;
fp->u.ARFCN = arfcn;
/* Dynamic allocation parameters */
da->USF_GRANULARITY = 0x00;
/* Assign an Uplink TFI */
da->Exist_UPLINK_TFI_ASSIGNMENT = 0x01;
da->UPLINK_TFI_ASSIGNMENT = new_ul_tfi;
/* Timeslot Allocation with or without Power Control */
da->UnionType = 0x00;
for (tn = 0; tn < 8; tn++) {
Timeslot_Allocation_t *slot = &da->u.Timeslot_Allocation[tn];
if (usf_li[tn] == 0xff)
continue;
slot->Exist = 0x01; // Enable this timeslot
slot->USF_TN = usf_li[tn]; // USF_TN(i)
}
}
static uint8_t *create_si13(uint8_t bs_cv_max /* 0..15 */)
{
static uint8_t si13_buf[GSM_MACBLOCK_LEN];
@ -869,6 +938,88 @@ static void test_dl_tbf_ccch_assign(void)
cleanup_test();
}
/* PCU allocates a DL TBF through PCH ImmAss for MS (when in packet-idle). Then
* upper layers want to transmit more data so during DL ACK/NACK a new UL TBF is
* requested. */
static void test_dl_tbf_ccch_assign_requests_ul_tbf_pacch(void)
{
struct osmo_gprs_rlcmac_prim *rlcmac_prim;
int rc;
struct msgb *dl_data_msg;
printf("=== %s start ===\n", __func__);
prepare_test();
RlcMacDownlink_t dl_block;
uint32_t tlli = 0x0000001;
uint8_t ts_nr = 7;
uint8_t usf = 0;
uint32_t rts_fn = 4;
uint8_t dl_tfi = 0;
uint8_t ul_tfi = 3;
uint8_t rrbp = GPRS_RLCMAC_RRBP_N_plus_17_18;
uint16_t arfcn = 871;
uint8_t usf_li[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 1, 2 };
/* Notify RLCMAC about our TLLI */
rlcmac_prim = osmo_gprs_rlcmac_prim_alloc_gmmrr_assign_req(tlli);
rc = osmo_gprs_rlcmac_prim_upper_down(rlcmac_prim);
OSMO_ASSERT(sizeof(ccch_imm_ass_pkt_dl_tbf) == GSM_MACBLOCK_LEN);
rlcmac_prim = osmo_gprs_rlcmac_prim_alloc_l1ctl_ccch_data_ind(0, ccch_imm_ass_pkt_dl_tbf);
rc = osmo_gprs_rlcmac_prim_lower_up(rlcmac_prim);
OSMO_ASSERT(rc == 0);
/* Transmit some DL LLC data MS<-PCU */
dl_data_msg = create_dl_data_block(dl_tfi, usf, GPRS_RLCMAC_CS_1, 0, true, true, rrbp);
rlcmac_prim = osmo_gprs_rlcmac_prim_alloc_l1ctl_pdch_data_ind(ts_nr, rts_fn, 0, 0, 0,
msgb_data(dl_data_msg),
msgb_length(dl_data_msg));
rc = osmo_gprs_rlcmac_prim_lower_up(rlcmac_prim);
OSMO_ASSERT(rc == 0);
msgb_free(dl_data_msg);
/* Upper layers wants to transmit some payload, but no UL TBF exists yet: */
/* Submit 14 bytes to fit in 1 RLCMAC block to shorten test and end up in FINISHED state quickly: */
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(rc == 0);
/* Trigger transmission of DL ACK/NACK, which should request a UL TBF in "Channel Request Description" */
rts_fn = rrbp2fn(rts_fn, 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);
/* Network sends a Pkt Ul Ass to DL TBF's PACCH: */
rts_fn = fn_next_block(rts_fn);
pkt_ul_ass_from_dl_tbf_init(&dl_block, dl_tfi, ul_tfi, arfcn, &usf_li[0]);
/* has Poll set: */
dl_block.SP = 1;
dl_block.RRBP = rrbp;
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, rrbp);
rlcmac_prim = osmo_gprs_rlcmac_prim_alloc_l1ctl_pdch_rts_ind(ts_nr, rts_fn, usf_li[ts_nr]);
rc = osmo_gprs_rlcmac_prim_lower_up(rlcmac_prim);
OSMO_ASSERT(rc == 0);
/* from now on use one of the assigned TS in UL TBF.*/
rts_fn = fn_next_block(rts_fn);
ts_nr = 6;
/* Trigger transmission of LLC data (GMM Attach) (first part) */
rlcmac_prim = osmo_gprs_rlcmac_prim_alloc_l1ctl_pdch_rts_ind(ts_nr, rts_fn, usf_li[ts_nr]);
rc = osmo_gprs_rlcmac_prim_lower_up(rlcmac_prim);
OSMO_ASSERT(rc == 0);
printf("=== %s end ===\n", __func__);
cleanup_test();
}
static const struct log_info_cat test_log_categories[] = { };
static const struct log_info test_log_info = {
.cat = test_log_categories,
@ -899,6 +1050,7 @@ int main(int argc, char *argv[])
test_ul_tbf_last_data_cv0_retrans_max();
test_ul_tbf_request_another_ul_tbf();
test_dl_tbf_ccch_assign();
test_dl_tbf_ccch_assign_requests_ul_tbf_pacch();
talloc_free(tall_ctx);
}

View File

@ -620,3 +620,70 @@ 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 TBF(DL:NR-0:TLLI-00000001) - V(N): "IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIR" R=Received I=Invalid
DLGLOBAL INFO DL_TBF{FINISHED}: 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
DLGLOBAL INFO GRE(00000001) Got PCH IMM_ASS (DL_TBF): DL_TFI=0 TS=7
DLGLOBAL INFO DL_TBF{NEW}: Allocated
DLGLOBAL INFO DL_TBF{NEW}: Received Event DL_ASS_COMPL
DLGLOBAL INFO TBF(DL:NR-0:TLLI-00000001) Send L1CTL-CF_DL_TBF.req dl_slotmask=0x80 dl_tfi=0
DLGLOBAL INFO DL_TBF{NEW}: state_chg to FLOW
DLGLOBAL INFO Rx from lower layers: L1CTL-PDCH_DATA.indication
DLGLOBAL DEBUG TBF(DL:NR-0:TLLI-00000001) Rx new DL data
DLGLOBAL DEBUG TBF(DL:NR-0:TLLI-00000001) DL DATA TFI=0 received (V(Q)=0 .. V(R)=0)
DLGLOBAL DEBUG TBF(DL:NR-0:TLLI-00000001) Got CS-1 RLC data block: FBI=1, BSN=0, SPB=0, S/P=1 RRBP=1, E=0, bitoffs=24
DLGLOBAL DEBUG TBF(DL:NR-0:TLLI-00000001) BSN 0 storing in window (0..63)
DLGLOBAL DEBUG TBF(DL:NR-0:TLLI-00000001) data_length=20, data=19 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b
DLGLOBAL DEBUG - Raising V(R) to 1
DLGLOBAL DEBUG - Taking block 0 out, raising V(Q) to 1
DLGLOBAL DEBUG TBF(DL:NR-0:TLLI-00000001) Assembling frames: (len=20)
DLGLOBAL DEBUG DL DATA LI contains extension octet: LI=6, M=0, E=1, count=0
DLGLOBAL DEBUG TBF(DL:NR-0:TLLI-00000001) Frame 1 starts at offset 1, length=6, is_complete=1
DLGLOBAL DEBUG TBF(DL:NR-0:TLLI-00000001) complete UL frame len=6
DLGLOBAL DEBUG TBF(DL:NR-0:TLLI-00000001) No gaps in received block, last block: BSN=0 FBI=1
DLGLOBAL DEBUG TBF(DL:NR-0:TLLI-00000001) Finished with DL TBF
DLGLOBAL INFO DL_TBF{FLOW}: Received Event LAST_DL_DATA_RECVD
DLGLOBAL INFO DL_TBF{FLOW}: state_chg to FINISHED
DLGLOBAL DEBUG Register POLL (TS=7 FN=21, reason=DL_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=21,usf=0) Tx DL ACK/NACK FinalAck=1
DLGLOBAL DEBUG TBF(DL:NR-0:TLLI-00000001) - V(N): "IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIR" R=Received I=Invalid
DLGLOBAL INFO UL_TBF{NEW}: Allocated
DLGLOBAL INFO UL_TBF_ASS{IDLE}: Allocated
DLGLOBAL INFO UL_TBF_ASS{IDLE}: Received Event START_FROM_DL_TBF
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 WAIT_PKT_UL_ASS
DLGLOBAL INFO Rx from lower layers: L1CTL-PDCH_DATA.indication
DLGLOBAL INFO TS=7 FN=26 Rx Pkt UL ASS
DLGLOBAL INFO UL_TBF_ASS{WAIT_PKT_UL_ASS}: Received Event RX_PKT_UL_ASS
DLGLOBAL DEBUG Register POLL (TS=7 FN=43, reason=UL_ASS)
DLGLOBAL INFO UL_TBF_ASS{WAIT_PKT_UL_ASS}: state_chg to SCHED_PKT_CTRL_ACK
DLGLOBAL INFO Rx from lower layers: L1CTL-PDCH_RTS.indication
DLGLOBAL INFO UL_TBF_ASS{SCHED_PKT_CTRL_ACK}: Received Event CREATE_RLCMAC_MSG
DLGLOBAL DEBUG TBF(UL:NR-0:TLLI-00000001) Tx Packet Control Ack
DLGLOBAL INFO UL_TBF_ASS{SCHED_PKT_CTRL_ACK}: 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=0xc0
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-00000001) Sending new block at BSN 0, CS=CS-2
DLGLOBAL DEBUG TBF(UL:NR-0:TLLI-00000001) Dequeue next LLC (len=14)
DLGLOBAL DEBUG -- Chunk with length 14 is less than remaining space (30): add length header to delimit LLC frame
DLGLOBAL DEBUG -- Final block, so we done.
DLGLOBAL DEBUG TBF(UL:NR-0:TLLI-00000001) Complete UL frame, len=0
DLGLOBAL DEBUG TBF(UL:NR-0:TLLI-00000001) data block (BSN 0, CS-2): 39 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 2b 2b 2b 2b
DLGLOBAL DEBUG TBF(UL:NR-0:TLLI-00000001) need_padding 0 spb_status 0 spb 0 (BSN1 0 BSN2 -1)
DLGLOBAL DEBUG TBF(UL:NR-0:TLLI-00000001) Copying 1 RLC blocks, 1 BSNs
DLGLOBAL DEBUG TBF(UL:NR-0:TLLI-00000001) Copying data unit 0 (BSN 0)
DLGLOBAL DEBUG TBF(UL:NR-0:TLLI-00000001) msg block (BSN 0, CS-2): 00 06 00 39 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 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}: Received Event LAST_UL_DATA_SENT
DLGLOBAL INFO UL_TBF{FLOW}: Last UL block sent (CV=0), start T3182
DLGLOBAL INFO UL_TBF{FLOW}: state_chg to FINISHED
DLGLOBAL INFO DL_TBF{FINISHED}: Deallocated
DLGLOBAL INFO UL_TBF_ASS{IDLE}: Deallocated
DLGLOBAL INFO UL_TBF{FINISHED}: Deallocated

View File

@ -117,3 +117,12 @@ test_rlcmac_prim_down_cb(): Rx L1CTL-CFG_DL_TBF.request dl_tbf_nr=0 dl_slotmask=
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 ===
=== test_dl_tbf_ccch_assign_requests_ul_tbf_pacch 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
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_rlcmac_prim_down_cb(): Rx L1CTL-CFG_UL_TBF.request ul_tbf_nr=0 ul_slotmask=0xc0
test_rlcmac_prim_down_cb(): Rx L1CTL-PDCH_DATA.request fn=43 ts=7 data_len=23 data=[40 04 00 00 00 04 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b ]
test_rlcmac_prim_down_cb(): Rx L1CTL-PDCH_DATA.request fn=47 ts=6 data_len=34 data=[00 06 00 39 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 2b 2b 2b 2b 00 ]
=== test_dl_tbf_ccch_assign_requests_ul_tbf_pacch end ===