aboutsummaryrefslogtreecommitdiffstats
path: root/src/common/scheduler.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/scheduler.c')
-rw-r--r--src/common/scheduler.c34
1 files changed, 34 insertions, 0 deletions
diff --git a/src/common/scheduler.c b/src/common/scheduler.c
index 5bf1c5bc..b61330d2 100644
--- a/src/common/scheduler.c
+++ b/src/common/scheduler.c
@@ -968,6 +968,37 @@ int trx_sched_set_pchan(struct l1sched_trx *l1t, uint8_t tn,
return 0;
}
+/* Remove all matching (by chan_nr & link_id) primitives from the given queue */
+static void trx_sched_queue_filter(struct llist_head *q, uint8_t chan_nr, uint8_t link_id)
+{
+ struct msgb *msg, *_msg;
+
+ llist_for_each_entry_safe(msg, _msg, q, list) {
+ struct osmo_phsap_prim *l1sap = msgb_l1sap_prim(msg);
+ switch (l1sap->oph.primitive) {
+ case PRIM_PH_DATA:
+ if (l1sap->u.data.chan_nr != chan_nr)
+ continue;
+ if (l1sap->u.data.link_id != link_id)
+ continue;
+ break;
+ case PRIM_TCH:
+ if (l1sap->u.tch.chan_nr != chan_nr)
+ continue;
+ if (link_id != 0x00)
+ continue;
+ break;
+ default:
+ /* Shall not happen */
+ OSMO_ASSERT(0);
+ }
+
+ /* Unlink and free() */
+ llist_del(&msg->list);
+ talloc_free(msg);
+ }
+}
+
/* setting all logical channels given attributes to active/inactive */
int trx_sched_set_lchan(struct l1sched_trx *l1t, uint8_t chan_nr, uint8_t link_id, bool active)
{
@@ -1011,6 +1042,9 @@ int trx_sched_set_lchan(struct l1sched_trx *l1t, uint8_t chan_nr, uint8_t link_i
OSMO_ASSERT(chan_state->lchan != NULL);
} else {
chan_state->ho_rach_detect = 0;
+
+ /* Remove pending Tx prims belonging to this lchan */
+ trx_sched_queue_filter(&l1ts->dl_prims, chan_nr, link_id);
}
chan_state->active = active;