aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/mgcp/mgcp.h2
-rw-r--r--include/mgcp_ss7.h1
-rw-r--r--src/mgcp_hw.c10
-rw-r--r--src/mgcp_ss7.c43
-rw-r--r--src/mgcp_ss7_vty.c15
5 files changed, 66 insertions, 5 deletions
diff --git a/include/mgcp/mgcp.h b/include/mgcp/mgcp.h
index 9f21a37..e02da08 100644
--- a/include/mgcp/mgcp.h
+++ b/include/mgcp/mgcp.h
@@ -136,6 +136,8 @@ struct mgcp_trunk_config {
int dwnstr_adp_rate;
int dwnstr_max_gain;
int dwnstr_target_lvl;
+
+ int loop_on_idle;
};
struct mgcp_config {
diff --git a/include/mgcp_ss7.h b/include/mgcp_ss7.h
index 40051e1..4847989 100644
--- a/include/mgcp_ss7.h
+++ b/include/mgcp_ss7.h
@@ -58,6 +58,7 @@ struct mgcp_ss7_cmd {
void mgcp_mgw_vty_init();
int mgcp_hw_init();
+int mgcp_hw_loop(int trunk, int timeslot);
int mgcp_hw_connect(int port, int trunk, int timeslot);
#endif
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);
}