trxcon/l1sched: trigger sending UL BLOCK.cnf for PDTCH
In tx_pdtch_fn(), delay sending DATA.cnf until bid=3. Otherwise we send it too early (at bid=0) and trick the upper layers (RLC/MAC) to believe that the whole block (all bursts) has been transmitted. Change-Id: If32fafeef0ea347ed3800e6b67349bf12e66047f
This commit is contained in:
parent
8da604cfb3
commit
c5f93fc2c2
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue