summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2009-05-23 06:20:41 +0000
committerHarald Welte <laforge@gnumonks.org>2009-05-23 06:20:41 +0000
commitf55b49fef3f2c8c091c4fa732788ce82d1f33af1 (patch)
tree0587ae9aa8438f3382ad93cc281282614fc2e378 /src
parent703af9887d252a65cdc8d97e98ca23f7b521d21c (diff)
To slow down transmission of many ABIS frames at a time, a delay timer
is used for the E1's time slot. This timer replaces the "usleep()" function, so the process will not block the execution of libbsc. The timer is started after a frame is transmitted. If another frame is in the transmit queue, the frame will only be queued until the timer times out. If the timer is not running or times out, the frame is transmitted and the timer is restarted. The problem with partly provisioned TRX (locks show on LMT) is solved. The adjustment for the inter frame delay of 50 miliseconds is for further study. (Andreas Eversberg)
Diffstat (limited to 'src')
-rw-r--r--src/e1_input.c22
-rw-r--r--src/input/misdn.c44
2 files changed, 42 insertions, 24 deletions
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,