pespin submitted this change.

View Change


Approvals: pespin: Looks good to me, approved Jenkins Builder: Verified
rlcmac: dl_tbf: Improve logic requesting a new UL TBF

Change-Id: I702872ba32a410bb5f09943af3cdadca482562db
---
M include/osmocom/gprs/rlcmac/gre.h
M include/osmocom/gprs/rlcmac/tbf_ul.h
M include/osmocom/gprs/rlcmac/tbf_ul_ass_fsm.h
M src/rlcmac/gre.c
M src/rlcmac/rlcmac.c
M src/rlcmac/rlcmac_enc.c
M src/rlcmac/sched.c
M src/rlcmac/tbf_ul.c
M src/rlcmac/tbf_ul_ass_fsm.c
M tests/rlcmac/rlcmac_prim_test.c
M tests/rlcmac/rlcmac_prim_test.err
M tests/rlcmac/rlcmac_prim_test.ok
12 files changed, 500 insertions(+), 26 deletions(-)

diff --git a/include/osmocom/gprs/rlcmac/gre.h b/include/osmocom/gprs/rlcmac/gre.h
index ca5f773..f6397a6 100644
--- a/include/osmocom/gprs/rlcmac/gre.h
+++ b/include/osmocom/gprs/rlcmac/gre.h
@@ -20,6 +20,10 @@
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);

diff --git a/include/osmocom/gprs/rlcmac/tbf_ul.h b/include/osmocom/gprs/rlcmac/tbf_ul.h
index 3382778..ab85f50 100644
--- a/include/osmocom/gprs/rlcmac/tbf_ul.h
+++ b/include/osmocom/gprs/rlcmac/tbf_ul.h
@@ -58,6 +58,9 @@

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)
{
diff --git a/include/osmocom/gprs/rlcmac/tbf_ul_ass_fsm.h b/include/osmocom/gprs/rlcmac/tbf_ul_ass_fsm.h
index 4a1658d..377c86c 100644
--- a/include/osmocom/gprs/rlcmac/tbf_ul_ass_fsm.h
+++ b/include/osmocom/gprs/rlcmac/tbf_ul_ass_fsm.h
@@ -32,14 +32,11 @@
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 @@
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 @@
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 @@

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);
diff --git a/src/rlcmac/gre.c b/src/rlcmac/gre.c
index 40cd585..53d53c7 100644
--- a/src/rlcmac/gre.c
+++ b/src/rlcmac/gre.c
@@ -66,6 +66,40 @@
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 @@
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)
diff --git a/src/rlcmac/rlcmac.c b/src/rlcmac/rlcmac.c
index 4023586..82394e6 100644
--- a/src/rlcmac/rlcmac.c
+++ b/src/rlcmac/rlcmac.c
@@ -358,6 +358,58 @@
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 @@
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,
diff --git a/src/rlcmac/rlcmac_enc.c b/src/rlcmac/rlcmac_enc.c
index 6bceb8d..ef1d4cd 100644
--- a/src/rlcmac/rlcmac_enc.c
+++ b/src/rlcmac/rlcmac_enc.c
@@ -386,6 +386,7 @@
{
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 @@
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 @@
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;
}
diff --git a/src/rlcmac/sched.c b/src/rlcmac/sched.c
index c2b981f..6ec76c7 100644
--- a/src/rlcmac/sched.c
+++ b/src/rlcmac/sched.c
@@ -37,7 +37,8 @@
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 @@
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 @@
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)
diff --git a/src/rlcmac/tbf_ul.c b/src/rlcmac/tbf_ul.c
index 7642832..fcd7f56 100644
--- a/src/rlcmac/tbf_ul.c
+++ b/src/rlcmac/tbf_ul.c
@@ -261,6 +261,21 @@
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 @@
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)
diff --git a/src/rlcmac/tbf_ul_ass_fsm.c b/src/rlcmac/tbf_ul_ass_fsm.c
index 6169080..d88acd3 100644
--- a/src/rlcmac/tbf_ul_ass_fsm.c
+++ b/src/rlcmac/tbf_ul_ass_fsm.c
@@ -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 @@
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 @@
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_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_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 @@
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 @@
[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 @@
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 @@
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 @@
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 @@
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;
};
diff --git a/tests/rlcmac/rlcmac_prim_test.c b/tests/rlcmac/rlcmac_prim_test.c
index 02ee04c..604546d 100644
--- a/tests/rlcmac/rlcmac_prim_test.c
+++ b/tests/rlcmac/rlcmac_prim_test.c
@@ -295,6 +295,75 @@
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 @@
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 @@
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);
}
diff --git a/tests/rlcmac/rlcmac_prim_test.err b/tests/rlcmac/rlcmac_prim_test.err
index c022e4a..6ffd87d 100644
--- a/tests/rlcmac/rlcmac_prim_test.err
+++ b/tests/rlcmac/rlcmac_prim_test.err
@@ -620,3 +620,70 @@
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
diff --git a/tests/rlcmac/rlcmac_prim_test.ok b/tests/rlcmac/rlcmac_prim_test.ok
index d2bce62..7bafb85 100644
--- a/tests/rlcmac/rlcmac_prim_test.ok
+++ b/tests/rlcmac/rlcmac_prim_test.ok
@@ -117,3 +117,12 @@
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 ===

To view, visit change 31576. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: libosmo-gprs
Gerrit-Branch: master
Gerrit-Change-Id: I702872ba32a410bb5f09943af3cdadca482562db
Gerrit-Change-Number: 31576
Gerrit-PatchSet: 3
Gerrit-Owner: pespin <pespin@sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: laforge <laforge@osmocom.org>
Gerrit-Reviewer: pespin <pespin@sysmocom.de>
Gerrit-MessageType: merged