diff --git a/src/host/trxcon/include/osmocom/bb/l1sched/l1sched.h b/src/host/trxcon/include/osmocom/bb/l1sched/l1sched.h index 3f5e8b045..6c5a31e8e 100644 --- a/src/host/trxcon/include/osmocom/bb/l1sched/l1sched.h +++ b/src/host/trxcon/include/osmocom/bb/l1sched/l1sched.h @@ -223,6 +223,8 @@ struct l1sched_lchan_state { /*! Queue of Tx primitives */ struct llist_head tx_prims; + /*! Tx primitive being sent */ + struct msgb *prim; /*! Mode for TCH channels (see GSM48_CMODE_*) */ uint8_t tch_mode; diff --git a/src/host/trxcon/include/osmocom/bb/trxcon/trxcon_fsm.h b/src/host/trxcon/include/osmocom/bb/trxcon/trxcon_fsm.h index bbb4eb57d..9eba4fde1 100644 --- a/src/host/trxcon/include/osmocom/bb/trxcon/trxcon_fsm.h +++ b/src/host/trxcon/include/osmocom/bb/trxcon/trxcon_fsm.h @@ -105,6 +105,8 @@ struct trxcon_param_tx_data_cnf { uint8_t link_id; uint16_t band_arfcn; uint32_t frame_nr; + size_t data_len; + const uint8_t *data; }; /* param of TRXCON_EV_RX_DATA_IND */ diff --git a/src/host/trxcon/src/sched_lchan_pdtch.c b/src/host/trxcon/src/sched_lchan_pdtch.c index 4c49504a1..5b884ddc5 100644 --- a/src/host/trxcon/src/sched_lchan_pdtch.c +++ b/src/host/trxcon/src/sched_lchan_pdtch.c @@ -160,8 +160,9 @@ int tx_pdtch_fn(struct l1sched_lchan_state *lchan, return -EINVAL; } - /* Confirm data / traffic sending (pass ownership of the msgb/prim) */ - l1sched_lchan_emit_data_cnf(lchan, msg, br->fn); + /* Cache the prim, so that we can confirm it later (see below) */ + OSMO_ASSERT(lchan->prim == NULL); + lchan->prim = msg; send_burst: /* Determine which burst should be sent */ @@ -183,5 +184,12 @@ send_burst: LOGP_LCHAND(lchan, LOGL_DEBUG, "Scheduled at fn=%u burst=%u\n", br->fn, br->bid); + if (br->bid == 3) { + /* Confirm data / traffic sending (pass ownership of the msgb/prim) */ + l1sched_lchan_emit_data_cnf(lchan, lchan->prim, + GSM_TDMA_FN_SUB(br->fn, 3)); + lchan->prim = NULL; + } + return 0; } diff --git a/src/host/trxcon/src/trxcon_fsm.c b/src/host/trxcon/src/trxcon_fsm.c index f6c9a058f..95458838d 100644 --- a/src/host/trxcon/src/trxcon_fsm.c +++ b/src/host/trxcon/src/trxcon_fsm.c @@ -610,6 +610,18 @@ static void trxcon_st_packet_data_action(struct osmo_fsm_inst *fi, l1sched_prim_from_user(trxcon->sched, msg); break; } + case TRXCON_EV_TX_DATA_CNF: + { + const struct trxcon_param_tx_data_cnf *cnf = data; + struct msgb *msg; + + msg = l1gprs_handle_ul_block_cnf(trxcon->gprs, + cnf->frame_nr, cnf->chan_nr & 0x07, + cnf->data, cnf->data_len); + if (msg != NULL) + trxcon_l1ctl_send(trxcon, msg); + break; + } case TRXCON_EV_RX_DATA_IND: { const struct trxcon_param_rx_data_ind *ind = data; @@ -655,8 +667,6 @@ static void trxcon_st_packet_data_action(struct osmo_fsm_inst *fi, l1sched_reset(trxcon->sched, false); /* TODO: switch to (not implemented) TRXCON_ST_DCH_TUNING? */ break; - case TRXCON_EV_TX_DATA_CNF: - break; default: OSMO_ASSERT(0); } diff --git a/src/host/trxcon/src/trxcon_shim.c b/src/host/trxcon/src/trxcon_shim.c index 54d976a1d..ed2d402e8 100644 --- a/src/host/trxcon/src/trxcon_shim.c +++ b/src/host/trxcon/src/trxcon_shim.c @@ -102,6 +102,8 @@ static int handle_prim_data_cnf(struct trxcon_inst *trxcon, struct msgb *msg) .link_id = prim->data_cnf.link_id, .band_arfcn = trxcon->l1p.band_arfcn, .frame_nr = prim->data_cnf.frame_nr, + .data_len = msgb_l2len(msg), + .data = msgb_l2(msg), }; if (trxcon->gsmtap != NULL) {