aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <zecke@selfish.org>2012-01-22 10:16:29 +0000
committerHolger Hans Peter Freyther <zecke@selfish.org>2012-01-22 11:44:33 +0100
commitc96c57b8d587e466fe63026fc210bf7ca6a5e7cf (patch)
treec663db650ab909fb7406df426dd850ae99fd09fe /src
parent765c48aba794bc86f83e617ab68ab64f9f2d5ecf (diff)
mgcp: Implement to loop timeslots when not used for audio
Deal with broken ISUP switches and allow to loop endpoints when they are not connected. Introduce an option to do it.
Diffstat (limited to 'src')
-rw-r--r--src/mgcp_hw.c10
-rw-r--r--src/mgcp_ss7.c43
-rw-r--r--src/mgcp_ss7_vty.c15
3 files changed, 63 insertions, 5 deletions
diff --git a/src/mgcp_hw.c b/src/mgcp_hw.c
index ea33bdc..bcda02e 100644
--- a/src/mgcp_hw.c
+++ b/src/mgcp_hw.c
@@ -52,6 +52,16 @@ int mgcp_hw_init()
return 0;
}
+int mgcp_hw_loop(int trunk, int timeslot)
+{
+#ifdef NO_UNIPORTE
+ return 0;
+#else
+ return PTI_ConnectHSCM(PTI_HSCM_TRUNK + trunk, timeslot - 1,
+ PTI_HSCM_TRUNK + trunk, timeslot - 1, 1, 1);
+#endif
+}
+
int mgcp_hw_connect(int port, int trunk, int timeslot)
{
#ifdef NO_UNIPORTE
diff --git a/src/mgcp_ss7.c b/src/mgcp_ss7.c
index ae43e5e..345ea68 100644
--- a/src/mgcp_ss7.c
+++ b/src/mgcp_ss7.c
@@ -1,7 +1,7 @@
/* Use the UniPorte library to allocate endpoints */
/*
- * (C) 2010-2011 by Holger Hans Peter Freyther <zecke@selfish.org>
- * (C) 2010-2011 by On-Waves
+ * (C) 2010-2012 by Holger Hans Peter Freyther <zecke@selfish.org>
+ * (C) 2010-2012 by On-Waves
* All Rights Reserved
*
* This program is free software: you can redistribute it and/or modify
@@ -421,6 +421,34 @@ static void allocate_endp(struct mgcp_ss7 *ss7, struct mgcp_endpoint *endp)
endp->block_processing = 1;
}
+static int hw_maybe_loop_endp(struct mgcp_endpoint *mgw_endp)
+{
+ int multiplex, timeslot, start;
+ struct mgcp_trunk_config *tcfg;
+ if (!mgw_endp->tcfg->loop_on_idle)
+ return 0;
+
+ tcfg = mgw_endp->tcfg;
+ start = tcfg->trunk_type == MGCP_TRUNK_VIRTUAL ?
+ tcfg->target_trunk_start : tcfg->trunk_nr;
+ mgcp_endpoint_to_timeslot(ENDPOINT_NUMBER(mgw_endp), &multiplex, &timeslot);
+ return mgcp_hw_loop(start + multiplex, timeslot);
+}
+
+static int hw_maybe_connect(struct mgcp_endpoint *mgw_endp)
+{
+ int multiplex, timeslot, start;
+ struct mgcp_trunk_config *tcfg;
+ if (!mgw_endp->tcfg->loop_on_idle)
+ return 0;
+
+ tcfg = mgw_endp->tcfg;
+ start = tcfg->trunk_type == MGCP_TRUNK_VIRTUAL ?
+ tcfg->target_trunk_start : tcfg->trunk_nr;
+ mgcp_endpoint_to_timeslot(ENDPOINT_NUMBER(mgw_endp), &multiplex, &timeslot);
+ return mgcp_hw_connect(mgw_endp->hw_dsp_port, start + multiplex, timeslot);
+}
+
static void mgcp_ss7_do_exec(struct mgcp_ss7 *mgcp, uint8_t type,
struct mgcp_endpoint *mgw_endp, uint32_t param)
{
@@ -442,9 +470,11 @@ static void mgcp_ss7_do_exec(struct mgcp_ss7 *mgcp, uint8_t type,
mgw_endp->audio_port = UINT_MAX;
mgw_endp->block_processing = 1;
+ hw_maybe_loop_endp(mgw_endp);
}
break;
case MGCP_SS7_ALLOCATE:
+ hw_maybe_connect(mgw_endp);
allocate_endp(mgcp, mgw_endp);
break;
}
@@ -681,9 +711,12 @@ static int configure_trunk(struct mgcp_trunk_config *tcfg, int *dsp_resource)
int multiplex, timeslot, res;
mgcp_endpoint_to_timeslot(i, &multiplex, &timeslot);
- res = mgcp_hw_connect(*dsp_resource,
- start + multiplex,
- timeslot);
+ if (tcfg->loop_on_idle)
+ res = mgcp_hw_loop(start + multiplex, timeslot);
+ else
+ res = mgcp_hw_connect(*dsp_resource,
+ start + multiplex,
+ timeslot);
if (res != 0) {
LOGP(DMGCP, LOGL_ERROR,
diff --git a/src/mgcp_ss7_vty.c b/src/mgcp_ss7_vty.c
index 30651ba..07e44a5 100644
--- a/src/mgcp_ss7_vty.c
+++ b/src/mgcp_ss7_vty.c
@@ -235,6 +235,17 @@ DEFUN(cfg_trunk_timeslot_block, cfg_trunk_timeslot_block_cmd,
return CMD_SUCCESS;
}
+DEFUN(cfg_trunk_loop_idle, cfg_trunk_loop_idle_cmd,
+ "loop-on-idle <0-1>",
+ "Loop timeslot on idle mode\n"
+ "Do not loop\n" "Loop\n"
+)
+{
+ struct mgcp_trunk_config *trunk = vty->index;
+ trunk->loop_on_idle = atoi(argv[0]);
+ return CMD_SUCCESS;
+}
+
void mgcp_write_extra(struct vty *vty, struct mgcp_config *cfg)
{
vty_out(vty, " configure-trunks %d%s",
@@ -280,6 +291,8 @@ void write_trunk_extra(struct vty *vty, struct mgcp_trunk_config *trunk)
trunk->dwnstr_max_gain, VTY_NEWLINE);
vty_out(vty, " downstream-target-level %d%s",
trunk->dwnstr_target_lvl, VTY_NEWLINE);
+ vty_out(vty, " loop-on-idle %d%s",
+ trunk->loop_on_idle, VTY_NEWLINE);
write_blocked_endpoints(vty, trunk);
}
@@ -321,6 +334,7 @@ void mgcp_mgw_vty_init(void)
install_element(VTRUNK_NODE, &cfg_trunk_dwnstr_target_cmd);
install_element(VTRUNK_NODE, &cfg_trunk_endp_offset_cmd);
install_element(VTRUNK_NODE, &cfg_trunk_timeslot_block_cmd);
+ install_element(VTRUNK_NODE, &cfg_trunk_loop_idle_cmd);
install_element(TRUNK_NODE, &cfg_trunk_vad_cmd);
install_element(TRUNK_NODE, &cfg_trunk_realloc_cmd);
@@ -336,6 +350,7 @@ void mgcp_mgw_vty_init(void)
install_element(TRUNK_NODE, &cfg_trunk_dwnstr_target_cmd);
install_element(TRUNK_NODE, &cfg_trunk_endp_offset_cmd);
install_element(TRUNK_NODE, &cfg_trunk_timeslot_block_cmd);
+ install_element(TRUNK_NODE, &cfg_trunk_loop_idle_cmd);
}