diff --git a/include/osmocom/netif/osmux.h b/include/osmocom/netif/osmux.h index cb6160f..f4c7b45 100644 --- a/include/osmocom/netif/osmux.h +++ b/include/osmocom/netif/osmux.h @@ -65,4 +65,6 @@ void osmux_xfrm_input_deliver(struct osmux_in_handle *h); struct msgb *osmux_xfrm_output(struct osmux_hdr *osmuxh, struct osmux_out_handle *h); struct osmux_hdr *osmux_xfrm_output_pull(struct msgb *msg); +void osmux_tx_sched(struct msgb *msg, struct timeval *when, void (*tx_cb)(struct msgb *msg, void *data), void *data); + #endif diff --git a/src/osmux.c b/src/osmux.c index 11460ba..2fa74ea 100644 --- a/src/osmux.c +++ b/src/osmux.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -218,3 +219,44 @@ void osmux_xfrm_input_init(struct osmux_in_handle *h) batch.timer.cb = osmux_batch_timer_expired; batch.timer.data = h; } + +struct osmux_tx_handle { + struct osmo_timer_list timer; + struct msgb *msg; + void (*tx_cb)(struct msgb *msg, void *data); + void *data; +}; + +static void osmux_tx_cb(void *data) +{ + struct osmux_tx_handle *h = data; + + h->tx_cb(h->msg, h->data); + + talloc_free(h); +} + +void osmux_tx_sched(struct msgb *msg, struct timeval *when, + void (*tx_cb)(struct msgb *msg, void *data), void *data) +{ + struct osmux_tx_handle *h; + + /* send it now */ + if (when->tv_sec == 0 && when->tv_usec == 0) { + tx_cb(msg, data); + return; + } + + /* ... otherwise schedule transmission */ + h = talloc_zero(NULL, struct osmux_tx_handle); + if (h == NULL) + return; + + h->msg = msg; + h->tx_cb = tx_cb; + h->data = data; + h->timer.cb = osmux_tx_cb; + h->timer.data = h; + + osmo_timer_schedule(&h->timer, when->tv_sec, when->tv_usec); +}