aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/octoi/e1oip.c28
-rw-r--r--src/octoi/e1oip.h6
-rw-r--r--src/octoi/frame_rifo.c6
-rw-r--r--src/octoi/frame_rifo.h2
-rw-r--r--src/octoi/octoi_clnt_fsm.c2
-rw-r--r--src/octoi/octoi_clnt_vty.c1
-rw-r--r--src/octoi/octoi_srv_fsm.c2
-rw-r--r--src/octoi/octoi_srv_vty.c14
-rw-r--r--src/octoi/octoi_vty.h1
9 files changed, 51 insertions, 11 deletions
diff --git a/src/octoi/e1oip.c b/src/octoi/e1oip.c
index 85dd165..e2aad34 100644
--- a/src/octoi/e1oip.c
+++ b/src/octoi/e1oip.c
@@ -250,7 +250,7 @@ int e1oip_rcvmsg_tdm_data(struct e1oip_line *iline, struct msgb *msg)
"RxIP: %u extraneous bytes (len=%u, num_ts=%u, n_frames=%u)\n",
msgb_length(msg) % num_ts, msgb_length(msg), num_ts, n_frames);
}
- LOGPEER(peer, LOGL_INFO, "RxIP: frame=%05u ts_mask=0x%08x num_ts=%02u, n_frames=%u\n",
+ LOGPEER(peer, LOGL_DEBUG, "RxIP: frame=%05u ts_mask=0x%08x num_ts=%02u, n_frames=%u\n",
frame_nr, ts_mask, num_ts, n_frames);
} else {
if (msgb_l3len(msg) < 1) {
@@ -271,7 +271,26 @@ int e1oip_rcvmsg_tdm_data(struct e1oip_line *iline, struct msgb *msg)
rc = frame_rifo_in(&iline->e1t.rifo, frame_buf, fn32+i);
if (rc < 0)
iline_ctr_add(iline, LINE_CTR_E1oIP_E1T_OVERFLOW, 1);
+ /* Continue the for loop, if buffer reset is not configured. */
+ if (!iline->cfg.buffer_reset_percent)
+ continue;
+ /* Calculate average RIFO delay. */
+ int32_t d = fn32 + i - iline->e1t.rifo.next_out_fn;
+ iline->e1t.delay += d;
+ if (++iline->e1t.delay_cnt == FRAMES_BUFFER_RESET_AVG) {
+ int offset;
+ d = iline->e1t.delay / iline->e1t.delay_cnt;
+ iline->e1t.delay = iline->e1t.delay_cnt = 0;
+ offset = abs((int32_t)iline->cfg.prefill_frame_count - d) * 100 / iline->cfg.prefill_frame_count;
+ LOGPEER(peer, LOGL_INFO, "RxIP: Buffer fill %u frames, %u%% off target.\n", d, offset);
+ if (offset > iline->cfg.buffer_reset_percent) {
+ LOGPEER(peer, LOGL_ERROR, "RxIP: frame number out of range. Reset buffer.\n");
+ frame_rifo_init(&iline->e1t.rifo, fn32 + i);
+ iline->e1t.primed_rx_tdm = false;
+ }
+ }
}
+
/* update local state */
memcpy(iline->e1t.last_frame, frame_buf, BYTES_PER_FRAME);
if (update_next)
@@ -318,10 +337,11 @@ struct e1oip_line *e1oip_line_alloc(struct octoi_peer *peer)
}
void e1oip_line_configure(struct e1oip_line *iline, uint8_t batching_factor,
- uint32_t prefill_frame_count, bool force_send_all_ts)
+ uint32_t prefill_frame_count, uint8_t buffer_reset_percent, bool force_send_all_ts)
{
iline->cfg.batching_factor = batching_factor;
iline->cfg.prefill_frame_count = prefill_frame_count;
+ iline->cfg.buffer_reset_percent = buffer_reset_percent;
iline->cfg.force_send_all_ts = force_send_all_ts;
}
@@ -331,10 +351,12 @@ void e1oip_line_reset(struct e1oip_line *iline)
memset(&iline->e1o.last_frame, 0xff, sizeof(iline->e1o.last_frame));
iline->e1o.next_seq = 0;
- frame_rifo_init(&iline->e1t.rifo);
+ frame_rifo_init(&iline->e1t.rifo, 0);
memset(&iline->e1t.last_frame, 0xff, sizeof(iline->e1t.last_frame));
iline->e1t.next_fn32 = 0;
iline->e1t.primed_rx_tdm = false;
+ iline->e1t.delay = 0;
+ iline->e1t.delay_cnt = 0;
}
void e1oip_line_destroy(struct e1oip_line *iline)
diff --git a/src/octoi/e1oip.h b/src/octoi/e1oip.h
index a17c257..8aaa420 100644
--- a/src/octoi/e1oip.h
+++ b/src/octoi/e1oip.h
@@ -15,6 +15,8 @@
#define FRAMES_PER_SEC_THRESHOLD 7500
+#define FRAMES_BUFFER_RESET_AVG 40000
+
#define DEFAULT_BATCHING_FACTOR 32
#define DEFAULT_PREFILL_FRAME_COUNT 200 /* 25ms */
@@ -54,6 +56,7 @@ struct e1oip_line {
struct {
uint8_t batching_factor;
uint32_t prefill_frame_count;
+ uint8_t buffer_reset_percent;
bool force_send_all_ts;
} cfg;
@@ -70,6 +73,7 @@ struct e1oip_line {
uint8_t last_frame[BYTES_PER_FRAME]; /* last frame on the E1 side */
uint32_t next_fn32; /* next expected frame number */
bool primed_rx_tdm; /* Was RX RIFO primed */
+ int32_t delay, delay_cnt; /* Delay counter to calculate average delay */
} e1t;
};
@@ -84,7 +88,7 @@ struct e1oip_line *e1oip_line_alloc(struct octoi_peer *peer);
void e1oip_line_set_name(struct e1oip_line *line, const char *name);
void e1oip_line_reset(struct e1oip_line *iline);
void e1oip_line_configure(struct e1oip_line *iline, uint8_t batching_factor,
- uint32_t prefill_frame_count, bool force_send_all_ts);
+ uint32_t prefill_frame_count, uint8_t buffer_reset_percent, bool force_send_all_ts);
void e1oip_line_destroy(struct e1oip_line *iline);
int e1oip_rcvmsg_tdm_data(struct e1oip_line *iline, struct msgb *msg);
diff --git a/src/octoi/frame_rifo.c b/src/octoi/frame_rifo.c
index e3c22d9..00fb6a5 100644
--- a/src/octoi/frame_rifo.c
+++ b/src/octoi/frame_rifo.c
@@ -86,12 +86,12 @@ static bool bucket_bit_get(struct frame_rifo *rifo, uint32_t bucket_nr)
/*! Initialize a frame RIFO.
* \param rifo Caller-allocated memory for RIFO data structure */
-void frame_rifo_init(struct frame_rifo *rifo)
+void frame_rifo_init(struct frame_rifo *rifo, uint32_t fn)
{
memset(rifo->buf, 0xff, sizeof(rifo->buf));
rifo->next_out = rifo->buf;
- rifo->next_out_fn = 0;
- rifo->last_in_fn = -1;
+ rifo->next_out_fn = fn;
+ rifo->last_in_fn = fn - 1;
memset(rifo->bitvec, 0, sizeof(rifo->bitvec));
}
diff --git a/src/octoi/frame_rifo.h b/src/octoi/frame_rifo.h
index ac97506..19a9acb 100644
--- a/src/octoi/frame_rifo.h
+++ b/src/octoi/frame_rifo.h
@@ -27,7 +27,7 @@ static inline unsigned int frame_rifo_depth(struct frame_rifo *rifo)
return rifo->last_in_fn - rifo->next_out_fn + 1;
}
-void frame_rifo_init(struct frame_rifo *rifo);
+void frame_rifo_init(struct frame_rifo *rifo, uint32_t fn);
/* number of frames currently available in FIFO */
static inline unsigned int frame_rifo_frames(struct frame_rifo *rifo)
diff --git a/src/octoi/octoi_clnt_fsm.c b/src/octoi/octoi_clnt_fsm.c
index 2bfc8f9..d4cf90d 100644
--- a/src/octoi/octoi_clnt_fsm.c
+++ b/src/octoi/octoi_clnt_fsm.c
@@ -123,7 +123,7 @@ static void clnt_st_accepted_onenter(struct osmo_fsm_inst *fi, uint32_t prev_sta
struct clnt_state *st = fi->priv;
e1oip_line_configure(st->peer->iline, st->acc->batching_factor,
- st->acc->prefill_frame_count, st->acc->force_send_all_ts);
+ st->acc->prefill_frame_count, st->acc->buffer_reset_percent, st->acc->force_send_all_ts);
/* reset RIFO/FIFO etc. */
e1oip_line_reset(st->peer->iline);
iline_ctr_add(st->peer->iline, LINE_CTR_E1oIP_CONNECT_ACCEPT, 1);
diff --git a/src/octoi/octoi_clnt_vty.c b/src/octoi/octoi_clnt_vty.c
index 54ed60f..afca60c 100644
--- a/src/octoi/octoi_clnt_vty.c
+++ b/src/octoi/octoi_clnt_vty.c
@@ -283,6 +283,7 @@ void octoi_client_vty_init(void)
install_element(OCTOI_CLNT_ACCOUNT_NODE, &cfg_account_force_all_ts_cmd);
install_element(OCTOI_CLNT_ACCOUNT_NODE, &cfg_account_no_force_all_ts_cmd);
install_element(OCTOI_CLNT_ACCOUNT_NODE, &cfg_account_prefill_frame_count_cmd);
+ install_element(OCTOI_CLNT_ACCOUNT_NODE, &cfg_account_buffer_reset_cmd);
#ifdef HAVE_DAHDI_TRUNKDEV
install_element(OCTOI_CLNT_ACCOUNT_NODE, &cfg_account_trunkdev_name_cmd);
install_element(OCTOI_CLNT_ACCOUNT_NODE, &cfg_account_trunkdev_line_cmd);
diff --git a/src/octoi/octoi_srv_fsm.c b/src/octoi/octoi_srv_fsm.c
index b6914b7..81b27da 100644
--- a/src/octoi/octoi_srv_fsm.c
+++ b/src/octoi/octoi_srv_fsm.c
@@ -176,7 +176,7 @@ static void srv_st_accepted_onenter(struct osmo_fsm_inst *fi, uint32_t prev_stat
struct srv_state *st = fi->priv;
e1oip_line_configure(st->peer->iline, st->acc->batching_factor,
- st->acc->prefill_frame_count, st->acc->force_send_all_ts);
+ st->acc->prefill_frame_count, st->acc->buffer_reset_percent, st->acc->force_send_all_ts);
/* reset RIFO/FIFO etc. */
e1oip_line_reset(st->peer->iline);
iline_ctr_add(st->peer->iline, LINE_CTR_E1oIP_CONNECT_ACCEPT, 1);
diff --git a/src/octoi/octoi_srv_vty.c b/src/octoi/octoi_srv_vty.c
index 4fc4e47..05a99a4 100644
--- a/src/octoi/octoi_srv_vty.c
+++ b/src/octoi/octoi_srv_vty.c
@@ -412,7 +412,7 @@ gDEFUN(cfg_account_no_force_all_ts, cfg_account_no_force_all_ts_cmd,
}
gDEFUN(cfg_account_prefill_frame_count, cfg_account_prefill_frame_count_cmd,
- "prefill-frame-count <0-8000>",
+ "prefill-frame-count <0-900>",
"Number of E1 frames to pre-fill/pre-seed in Rx RIFO\n"
"Number of E1 frames to pre-fill/pre-seed in Rx RIFO\n")
{
@@ -422,6 +422,17 @@ gDEFUN(cfg_account_prefill_frame_count, cfg_account_prefill_frame_count_cmd,
return CMD_SUCCESS;
}
+gDEFUN(cfg_account_buffer_reset, cfg_account_buffer_reset_cmd,
+ "buffer-reset <0-100>",
+ "Reset Rx RIFO when fill in Rx RIFO drifts too much off normal\n"
+ "Give fill in percentage, use 0 to disable this feature\n")
+{
+ struct octoi_account *acc = vty->index;
+
+ acc->buffer_reset_percent = atoi(argv[0]);
+ return CMD_SUCCESS;
+}
+
void octoi_vty_show_one_account(struct vty *vty, const char *pfx, struct octoi_account *acc)
{
vty_out(vty, "%sAccount '%s': Mode=%s, Batching=%u, Prefill=%u%s", pfx,
@@ -563,6 +574,7 @@ void octoi_server_vty_init(void)
install_element(OCTOI_ACCOUNT_NODE, &cfg_account_force_all_ts_cmd);
install_element(OCTOI_ACCOUNT_NODE, &cfg_account_no_force_all_ts_cmd);
install_element(OCTOI_ACCOUNT_NODE, &cfg_account_prefill_frame_count_cmd);
+ install_element(OCTOI_ACCOUNT_NODE, &cfg_account_buffer_reset_cmd);
#ifdef HAVE_DAHDI_TRUNKDEV
install_element(OCTOI_ACCOUNT_NODE, &cfg_account_trunkdev_name_cmd);
install_element(OCTOI_ACCOUNT_NODE, &cfg_account_trunkdev_line_cmd);
diff --git a/src/octoi/octoi_vty.h b/src/octoi/octoi_vty.h
index 55fa7fe..a452e9d 100644
--- a/src/octoi/octoi_vty.h
+++ b/src/octoi/octoi_vty.h
@@ -11,6 +11,7 @@ extern struct cmd_element cfg_account_batching_factor_cmd;
extern struct cmd_element cfg_account_force_all_ts_cmd;
extern struct cmd_element cfg_account_no_force_all_ts_cmd;
extern struct cmd_element cfg_account_prefill_frame_count_cmd;
+extern struct cmd_element cfg_account_buffer_reset_cmd;
extern struct cmd_element cfg_account_trunkdev_name_cmd;
extern struct cmd_element cfg_account_trunkdev_line_cmd;