diff options
-rw-r--r-- | include/openbsc/e1_input.h | 3 | ||||
-rw-r--r-- | src/e1_input.c | 22 | ||||
-rw-r--r-- | src/input/misdn.c | 44 |
3 files changed, 45 insertions, 24 deletions
diff --git a/include/openbsc/e1_input.h b/include/openbsc/e1_input.h index 2752db645..132672364 100644 --- a/include/openbsc/e1_input.h +++ b/include/openbsc/e1_input.h @@ -64,7 +64,10 @@ struct e1inp_ts { union { struct { + /* list of all signalling links on this TS */ struct llist_head sign_links; + /* timer when to dequeue next frame */ + struct timer_list tx_timer; } sign; struct { /* subchannel demuxer for frames from E1 */ diff --git a/src/e1_input.c b/src/e1_input.c index 14352d03e..7fbf1797a 100644 --- a/src/e1_input.c +++ b/src/e1_input.c @@ -223,6 +223,7 @@ int abis_rsl_sendmsg(struct msgb *msg) { struct e1inp_sign_link *sign_link; struct e1inp_driver *e1inp_driver; + struct e1inp_ts *e1i_ts; msg->l2h = msg->data; @@ -232,15 +233,17 @@ int abis_rsl_sendmsg(struct msgb *msg) } sign_link = msg->trx->rsl_link; + e1i_ts = sign_link->ts; + if (!bsc_timer_pending(&e1i_ts->sign.tx_timer)) { + /* notify the driver we have something to write */ + e1inp_driver = sign_link->ts->line->driver; + e1inp_driver->want_write(e1i_ts); + } msgb_enqueue(&sign_link->tx_list, msg); /* dump it */ write_pcap_packet(PCAP_OUTPUT, sign_link->sapi, sign_link->tei, msg); - /* notify the driver we have something to write */ - e1inp_driver = sign_link->ts->line->driver; - e1inp_driver->want_write(sign_link->ts); - return 0; } @@ -248,6 +251,7 @@ int _abis_nm_sendmsg(struct msgb *msg) { struct e1inp_sign_link *sign_link; struct e1inp_driver *e1inp_driver; + struct e1inp_ts *e1i_ts; msg->l2h = msg->data; @@ -257,15 +261,17 @@ int _abis_nm_sendmsg(struct msgb *msg) } sign_link = msg->trx->bts->oml_link; + e1i_ts = sign_link->ts; + if (!bsc_timer_pending(&e1i_ts->sign.tx_timer)) { + /* notify the driver we have something to write */ + e1inp_driver = sign_link->ts->line->driver; + e1inp_driver->want_write(e1i_ts); + } msgb_enqueue(&sign_link->tx_list, msg); /* dump it */ write_pcap_packet(PCAP_OUTPUT, sign_link->sapi, sign_link->tei, msg); - /* notify the driver we have something to write */ - e1inp_driver = sign_link->ts->line->driver; - e1inp_driver->want_write(sign_link->ts); - return 0; } diff --git a/src/input/misdn.c b/src/input/misdn.c index d6ba63c64..77da77c8e 100644 --- a/src/input/misdn.c +++ b/src/input/misdn.c @@ -171,6 +171,27 @@ static int handle_ts1_read(struct bsc_fd *bfd) return ret; } +static int ts_want_write(struct e1inp_ts *e1i_ts) +{ + /* We never include the mISDN B-Channel FD into the + * writeset, since it doesn't support poll() based + * write flow control */ + if (e1i_ts->type == E1INP_TS_TYPE_TRAU) + return 0; + + e1i_ts->driver.misdn.fd.when |= BSC_FD_WRITE; + + return 0; +} + +static void timeout_ts1_write(void *data) +{ + struct e1inp_ts *e1i_ts = (struct e1inp_ts *)data; + + /* trigger write of ts1, due to tx delay timer */ + ts_want_write(e1i_ts); +} + static int handle_ts1_write(struct bsc_fd *bfd) { struct e1inp_line *line = bfd->data; @@ -183,10 +204,12 @@ static int handle_ts1_write(struct bsc_fd *bfd) u_int8_t *l2_data; int ret; + bfd->when &= ~BSC_FD_WRITE; + /* get the next msg for this timeslot */ msg = e1inp_tx_ts(e1i_ts, &sign_link); if (!msg) { - bfd->when &= ~BSC_FD_WRITE; + /* no message after tx delay timer */ return 0; } @@ -211,8 +234,10 @@ static int handle_ts1_write(struct bsc_fd *bfd) fprintf(stderr, "%s sendto failed %d\n", __func__, ret); msgb_free(msg); - /* FIXME: this has to go */ - usleep(100000); + /* set tx delay timer for next event */ + e1i_ts->sign.tx_timer.cb = timeout_ts1_write; + e1i_ts->sign.tx_timer.data = e1i_ts; + bsc_schedule_timer(&e1i_ts->sign.tx_timer, 0, 50000); return ret; } @@ -349,19 +374,6 @@ static int activate_bchan(struct e1inp_line *line, int ts, int act) return ret; } -static int ts_want_write(struct e1inp_ts *e1i_ts) -{ - /* We never include the mISDN B-Channel FD into the - * writeset, since it doesn't support poll() based - * write flow control */ - if (e1i_ts->type == E1INP_TS_TYPE_TRAU) - return 0; - - e1i_ts->driver.misdn.fd.when |= BSC_FD_WRITE; - - return 0; -} - struct e1inp_driver misdn_driver = { .name = "mISDNuser", .want_write = ts_want_write, |