From c96c57b8d587e466fe63026fc210bf7ca6a5e7cf Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Sun, 22 Jan 2012 10:16:29 +0000 Subject: 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. --- include/mgcp/mgcp.h | 2 ++ include/mgcp_ss7.h | 1 + src/mgcp_hw.c | 10 ++++++++++ src/mgcp_ss7.c | 43 ++++++++++++++++++++++++++++++++++++++----- src/mgcp_ss7_vty.c | 15 +++++++++++++++ 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 - * (C) 2010-2011 by On-Waves + * (C) 2010-2012 by Holger Hans Peter Freyther + * (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, ×lot); + 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, ×lot); + 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, ×lot); - 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); } -- cgit v1.2.3