提交 4340c4d7 authored 作者: David Yat Sin's avatar David Yat Sin

Merged latest FreeTDM code from Sangoma's repo

Merge remote branch 'smgfs/master'

Conflicts:
	build/modules.conf.in
	configure.in
	libs/esl/fs_cli.c
	libs/freetdm/mod_freetdm/mod_freetdm.c
	libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h
	libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c
	libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_logger.c
	libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c
	src/include/switch_types.h
	src/mod/applications/mod_commands/mod_commands.c
	src/mod/applications/mod_spandsp/mod_spandsp.c
	src/mod/endpoints/mod_opal/mod_opal.cpp
	src/mod/endpoints/mod_opal/mod_opal.h
	src/mod/endpoints/mod_sofia/mod_sofia.h
	src/mod/endpoints/mod_sofia/rtp.c
	src/switch.c
	src/switch_core.c
	src/switch_rtp.c
......@@ -214,6 +214,8 @@ ftmod_sangoma_ss7_la_SOURCES = \
$(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_sta.c \
$(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_sts.c \
$(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_logger.c \
$(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_m2ua_xml.c \
$(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_m2ua.c \
$(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_relay.c
ftmod_sangoma_ss7_la_CFLAGS = $(FTDM_CFLAGS) $(AM_CFLAGS) -D_GNU_SOURCE
......
......@@ -13,7 +13,7 @@ cpu_monitoring_interval => 1000
cpu_set_alarm_threshold => 80
; At what CPU percentage stop the CPU alarm
cpu_reset_alarm_threshold => 70
cpu_clear_alarm_threshold => 70
; Which action to take when the CPU alarm is raised
; it can be warn and/or reject calls
......
SS7 Native Bridge
Native bridge is enabled on 2 conditions:
* The SIP header FreeTDM-TransUUID is set in the originating leg and matches a freetdm channel
* The variable freetdm_native_sigbridge is true and the originating leg is also a freetdm channel
Some coding rules apply to this feature:
- Each channel is responsible for clearning its own peer_data and event queue
at the end of the call (when moving to DOWN state)
- Each channel dequeues messages only from its own queue and enqueues messages
in the peer's queue, with the only exception being messages received before
the bridge is stablished (IAM for sure and possible SAM messages) because
if the bridge is not yet stablished the messages must be queued by the channel
in its own queue temporarily until the bridge is ready
- When the bridge is ready it is the responsibility of the incoming channel to
move the messages that stored temporarily in its own queue to the bridged peer queue
- During hangup, each channel is responsible for moving itself to DOWN. The procedure
however differs slightly depending on the hangup conditions
If the user requests hangup (ie, FreeSWITCH) the request will be noted by setting the
FTDM_CHANNEL_USER_HANGUP flag but will not be processed yet because call control is
driven only by the link messages (so no hangup from ESL or command line allowed)
When REL message comes, the channel receiving it must move to TERMINATING state and:
- If the user has not hangup yet (FTDM_CHANNEL_USER_HANGUP flag not set) then
notify the user via SIGEVENT_STOP and wait for the user to move to HANGUP
state by calling ftdm_channel_call_hangup() before sending RLC
- If the user did hangup already (FTDM_CHANNEL_USER_HANGUP flag is set) then
skip user notification and move to HANGUP state directly where the RLC message
will be sent
- On HANGUP state the RLC is sent and the channel is moved to DOWN, final state
The peer channel will forward the REL message and wait for RLC from the network, when
RLC is received the channel can move straight to DOWN itself because the peer channel
is completing its own shutdown procedure when it received the REL message
......@@ -4,6 +4,7 @@ BASE=../../..
FT_DIR=..
VERBOSE=1
FTLA=$(FT_DIR)/libfreetdm.la
LOCAL_OBJS=tdm.o
LOCAL_CFLAGS=-I$(FT_DIR)/src/include -I$(FT_DIR)/src/isdn/include $(FT_CFLAGS)
LOCAL_LDFLAGS=-L$(FT_DIR) -lfreetdm
include $(BASE)/build/modmake.rules
......
差异被折叠。
差异被折叠。
......@@ -48,9 +48,26 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_complete_state(const char *file, const c
ftdm_time_t diff = 0;
ftdm_channel_state_t state = fchan->state;
#if 0
/* I could not perform this sanity check without more disruptive changes. Ideally we should check here if the signaling module completing the state
executed a state processor (called ftdm_channel_advance_states() which call fchan->span->state_processor(fchan)) for the state. That is just a
sanity check, as in the past we had at least one bug where the signaling module set the state and then accidentally changed the state to a new one
without calling ftdm_channel_advance_states(), meaning the state processor for the first state was not executed and that lead to unexpected behavior.
If we want to be able to perform this kind of sanity check it would be nice to add a new state status (FTDM_STATE_STATUS_PROCESSING), the function
ftdm_channel_advance_states() would set the state_status to PROCESSING and then the check below for STATUS_NEW would be valid. Currently is not
valid because the signaling module may be completing the state at the end of the state_processor callback and therefore the state will still be
in STATUS_NEW, and is perfectly valid ... */
if (fchan->state_status == FTDM_STATE_STATUS_NEW) {
ftdm_log_chan_ex(fchan, file, func, line, FTDM_LOG_LEVEL_CRIT,
"Asking to complete state change from %s to %s in %llums, but the state is still unprocessed (this might be a bug!)\n",
ftdm_channel_state2str(fchan->last_state), ftdm_channel_state2str(state), diff);
}
#endif
if (fchan->state_status == FTDM_STATE_STATUS_COMPLETED) {
ftdm_assert_return(!ftdm_test_flag(fchan, FTDM_CHANNEL_STATE_CHANGE), FTDM_FAIL,
"State change flag set but state is not completed\n");
ftdm_assert_return(!ftdm_test_flag(fchan, FTDM_CHANNEL_STATE_CHANGE), FTDM_FAIL, "State change flag set but state is already completed\n");
return FTDM_SUCCESS;
}
......@@ -87,6 +104,7 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_complete_state(const char *file, const c
ftdm_assert(!fchan->history[hindex].end_time, "End time should be zero!\n");
fchan->history[hindex].end_time = ftdm_current_time_in_ms();
fchan->last_state_change_time = ftdm_current_time_in_ms();
fchan->state_status = FTDM_STATE_STATUS_COMPLETED;
......@@ -262,6 +280,9 @@ static ftdm_status_t ftdm_core_set_state(const char *file, const char *func, int
}
}
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_NATIVE_SIGBRIDGE)) {
goto perform_state_change;
}
if (ftdmchan->span->state_map) {
ok = ftdm_parse_state_map(ftdmchan, state, ftdmchan->span->state_map);
......@@ -353,6 +374,8 @@ end:
goto done;
}
perform_state_change:
ftdm_log_chan_ex(ftdmchan, file, func, line, FTDM_LOG_LEVEL_DEBUG, "Changed state from %s to %s\n", ftdm_channel_state2str(ftdmchan->state), ftdm_channel_state2str(state));
ftdmchan->last_state = ftdmchan->state;
ftdmchan->state = state;
......
......@@ -288,6 +288,7 @@ typedef struct sngisdn_span_data {
uint8_t force_sending_complete;
uint8_t cid_name_method;
uint8_t send_cid_name;
uint8_t send_connect_ack;
int32_t timer_t301;
int32_t timer_t302;
......@@ -305,7 +306,6 @@ typedef struct sngisdn_span_data {
int32_t timer_t318;
int32_t timer_t319;
int32_t timer_t322;
char* local_numbers[SNGISDN_NUM_LOCAL_NUMBERS];
ftdm_timer_id_t timers[SNGISDN_NUM_SPAN_TIMERS];
ftdm_sched_t *sched;
......
......@@ -433,6 +433,7 @@ ftdm_status_t ftmod_isdn_parse_cfg(ftdm_conf_parameter_t *ftdm_parameters, ftdm_
signal_data->cid_name_method = SNGISDN_CID_NAME_AUTO;
signal_data->send_cid_name = SNGISDN_OPT_DEFAULT;
signal_data->send_connect_ack = SNGISDN_OPT_DEFAULT;
span->default_caller_data.dnis.plan = FTDM_NPI_INVALID;
span->default_caller_data.dnis.type = FTDM_TON_INVALID;
......@@ -615,6 +616,8 @@ ftdm_status_t ftmod_isdn_parse_cfg(ftdm_conf_parameter_t *ftdm_parameters, ftdm_
parse_timer(val, &signal_data->timer_t322);
} else if (!strcasecmp(var, "trunkgroup")) {
/* Do nothing, we already parsed this parameter */
} else if (!strcasecmp(var, "send-connect-ack")) {
parse_yesno(var, val, &signal_data->send_connect_ack);
} else {
ftdm_log(FTDM_LOG_WARNING, "Ignoring unknown parameter %s\n", ftdm_parameters[paramindex].var);
}
......
......@@ -738,6 +738,14 @@ ftdm_status_t sngisdn_stack_cfg_q931_dlsap(ftdm_span_t *span)
}
}
if (signal_data->send_connect_ack != SNGISDN_OPT_DEFAULT) {
if (signal_data->send_connect_ack == SNGISDN_OPT_TRUE) {
cfg.t.cfg.s.inDLSAP.ackOpt = TRUE;
} else {
cfg.t.cfg.s.inDLSAP.ackOpt = FALSE;
}
}
/* Override the restart options if user selected that option */
if (signal_data->restart_opt != SNGISDN_OPT_DEFAULT) {
if (signal_data->restart_opt == SNGISDN_OPT_TRUE) {
......
......@@ -48,35 +48,7 @@ static int ftmod_ss7_enable_isap(int suId);
static int ftmod_ss7_enable_nsap(int suId);
static int ftmod_ss7_enable_mtpLinkSet(int lnkSetId);
int ftmod_ss7_inhibit_mtp3link(uint32_t id);
int ftmod_ss7_uninhibit_mtp3link(uint32_t id);
int ftmod_ss7_bind_mtp3link(uint32_t id);
int ftmod_ss7_unbind_mtp3link(uint32_t id);
int ftmod_ss7_activate_mtp3link(uint32_t id);
int ftmod_ss7_deactivate_mtp3link(uint32_t id);
int ftmod_ss7_deactivate2_mtp3link(uint32_t id);
int ftmod_ss7_activate_mtplinkSet(uint32_t id);
int ftmod_ss7_deactivate_mtplinkSet(uint32_t id);
int ftmod_ss7_deactivate2_mtplinkSet(uint32_t id);
int ftmod_ss7_lpo_mtp3link(uint32_t id);
int ftmod_ss7_lpr_mtp3link(uint32_t id);
int ftmod_ss7_shutdown_isup(void);
int ftmod_ss7_shutdown_mtp3(void);
int ftmod_ss7_shutdown_mtp2(void);
int ftmod_ss7_shutdown_relay(void);
int ftmod_ss7_disable_relay_channel(uint32_t chanId);
int ftmod_ss7_disable_grp_mtp3Link(uint32_t procId);
int ftmod_ss7_enable_grp_mtp3Link(uint32_t procId);
int ftmod_ss7_disable_grp_mtp2Link(uint32_t procId);
int ftmod_ss7_block_isup_ckt(uint32_t cktId);
int ftmod_ss7_unblock_isup_ckt(uint32_t cktId);
/******************************************************************************/
/* FUNCTIONS ******************************************************************/
......@@ -88,7 +60,7 @@ int ft_to_sngss7_activate_all(void)
while (x < (MAX_ISAPS)) {
/* check if this link has already been actived */
if ((g_ftdm_sngss7_data.cfg.isap[x].id != 0) &&
(!(g_ftdm_sngss7_data.cfg.isap[x].flags & SNGSS7_ACTIVE))) {
(!(g_ftdm_sngss7_data.cfg.isap[x].flags & SNGSS7_ACTIVE))) {
if (ftmod_ss7_enable_isap(x)) {
SS7_CRITICAL("ISAP %d Enable: NOT OK\n", x);
......@@ -100,15 +72,16 @@ int ft_to_sngss7_activate_all(void)
/* set the SNGSS7_ACTIVE flag */
g_ftdm_sngss7_data.cfg.isap[x].flags |= SNGSS7_ACTIVE;
} /* if !SNGSS7_ACTIVE */
x++;
} /* while (x < (MAX_ISAPS)) */
if(SNG_SS7_OPR_MODE_M2UA_SG != g_ftdm_operating_mode){
x = 1;
while (x < (MAX_NSAPS)) {
/* check if this link has already been actived */
if ((g_ftdm_sngss7_data.cfg.nsap[x].id != 0) &&
(!(g_ftdm_sngss7_data.cfg.nsap[x].flags & SNGSS7_ACTIVE))) {
(!(g_ftdm_sngss7_data.cfg.nsap[x].flags & SNGSS7_ACTIVE))) {
if (ftmod_ss7_enable_nsap(x)) {
SS7_CRITICAL("NSAP %d Enable: NOT OK\n", x);
......@@ -120,30 +93,35 @@ int ft_to_sngss7_activate_all(void)
/* set the SNGSS7_ACTIVE flag */
g_ftdm_sngss7_data.cfg.nsap[x].flags |= SNGSS7_ACTIVE;
} /* if !SNGSS7_ACTIVE */
x++;
} /* while (x < (MAX_NSAPS)) */
if (g_ftdm_sngss7_data.cfg.mtpRoute[1].id != 0) {
x = 1;
while (x < (MAX_MTP_LINKSETS+1)) {
/* check if this link has already been actived */
if ((g_ftdm_sngss7_data.cfg.mtpLinkSet[x].id != 0) &&
(!(g_ftdm_sngss7_data.cfg.mtpLinkSet[x].flags & SNGSS7_ACTIVE))) {
if (ftmod_ss7_enable_mtpLinkSet(x)) {
SS7_CRITICAL("LinkSet \"%s\" Enable: NOT OK\n", g_ftdm_sngss7_data.cfg.mtpLinkSet[x].name);
return 1;
} else {
SS7_INFO("LinkSet \"%s\" Enable: OK\n", g_ftdm_sngss7_data.cfg.mtpLinkSet[x].name);
}
/* set the SNGSS7_ACTIVE flag */
g_ftdm_sngss7_data.cfg.mtpLinkSet[x].flags |= SNGSS7_ACTIVE;
} /* if !SNGSS7_ACTIVE */
x++;
} /* while (x < (MAX_MTP_LINKSETS+1)) */
if (g_ftdm_sngss7_data.cfg.mtpRoute[1].id != 0) {
x = 1;
while (x < (MAX_MTP_LINKSETS+1)) {
/* check if this link has already been actived */
if ((g_ftdm_sngss7_data.cfg.mtpLinkSet[x].id != 0) &&
(!(g_ftdm_sngss7_data.cfg.mtpLinkSet[x].flags & SNGSS7_ACTIVE))) {
if (ftmod_ss7_enable_mtpLinkSet(x)) {
SS7_CRITICAL("LinkSet \"%s\" Enable: NOT OK\n", g_ftdm_sngss7_data.cfg.mtpLinkSet[x].name);
return 1;
} else {
SS7_INFO("LinkSet \"%s\" Enable: OK\n", g_ftdm_sngss7_data.cfg.mtpLinkSet[x].name);
}
/* set the SNGSS7_ACTIVE flag */
g_ftdm_sngss7_data.cfg.mtpLinkSet[x].flags |= SNGSS7_ACTIVE;
} /* if !SNGSS7_ACTIVE */
x++;
} /* while (x < (MAX_MTP_LINKSETS+1)) */
}
}
if(SNG_SS7_OPR_MODE_M2UA_SG == g_ftdm_operating_mode){
return ftmod_ss7_m2ua_start();
}
return 0;
......@@ -779,7 +757,14 @@ int ftmod_ss7_disable_grp_mtp3Link(uint32_t procId)
cntrl.t.cntrl.action = AUBND_DIS; /* disable and unbind */
cntrl.t.cntrl.subAction = SAGR_DSTPROCID; /* specificed element */
return (sng_cntrl_mtp3(&pst, &cntrl));
if (g_ftdm_sngss7_data.cfg.procId == procId) {
SS7_DEBUG("Executing MTP3 cntrl command local pid =%i\n",procId);
return (sng_cntrl_mtp3(&pst, &cntrl));
} else {
SS7_WARN("Executing MTP3 cntrl command different local=%i target=%i\n",
g_ftdm_sngss7_data.cfg.procId,procId);
return (sng_cntrl_mtp3_nowait(&pst, &cntrl));
}
}
......@@ -811,7 +796,14 @@ int ftmod_ss7_enable_grp_mtp3Link(uint32_t procId)
cntrl.t.cntrl.action = ABND_ENA; /* bind and enable */
cntrl.t.cntrl.subAction = SAGR_DSTPROCID; /* specificed element */
return (sng_cntrl_mtp3(&pst, &cntrl));
if (g_ftdm_sngss7_data.cfg.procId == procId) {
SS7_DEBUG("Executing MTP3 cntrl command local pid =%i\n",procId);
return (sng_cntrl_mtp3(&pst, &cntrl));
} else {
SS7_WARN("Executing MTP3 cntrl command different local=%i target=%i\n",
g_ftdm_sngss7_data.cfg.procId,procId);
return (sng_cntrl_mtp3_nowait(&pst, &cntrl));
}
}
......@@ -848,7 +840,7 @@ int ftmod_ss7_disable_grp_mtp2Link(uint32_t procId)
}
/******************************************************************************/
int ftmod_ss7_block_isup_ckt(uint32_t cktId)
int __ftmod_ss7_block_isup_ckt(uint32_t cktId, ftdm_bool_t wait)
{
SiMngmt cntrl;
Pst pst;
......@@ -876,7 +868,11 @@ int ftmod_ss7_block_isup_ckt(uint32_t cktId)
cntrl.t.cntrl.action = ADISIMM; /* block via BLO */
cntrl.t.cntrl.subAction = SAELMNT; /* specificed element */
return (sng_cntrl_isup(&pst, &cntrl));
if (wait == FTDM_TRUE) {
return (sng_cntrl_isup(&pst, &cntrl));
} else {
return (sng_cntrl_isup_nowait(&pst, &cntrl));
}
}
/******************************************************************************/
......
......@@ -81,6 +81,7 @@ void sngss7_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiCo
/* initalize the sngss7_event */
sngss7_event = ftdm_malloc(sizeof(*sngss7_event));
if (sngss7_event == NULL) {
SS7_ERROR("Failed to allocate memory for sngss7_event!\n");
SS7_FUNC_TRACE_EXIT(__FUNCTION__);
......
/*
* Copyright (c) 2012, Kapil Gupta <kgupta@sangoma.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the original author; nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
* Contributors:
*
*/
/******************************************************************************/
#ifndef __FTMOD_SNG_SS7_M2UA_H__
#define __FTMOD_SNG_SS7_M2UA_H__
/******************************************************************************/
#include "private/ftdm_core.h"
#define MAX_NAME_LEN 25
typedef struct sng_nif_cfg{
char name[MAX_NAME_LEN];
uint32_t flags;
uint32_t id;
uint32_t m2uaLnkNmb;
uint32_t mtp2LnkNmb;
}sng_nif_cfg_t;
typedef enum{
SNG_M2UA_NODE_TYPE_SGP = 1, /* type SG */
SNG_M2UA_NODE_TYPE_ASP = 2, /* type ASP */
}sng_m2ua_node_types_e;
typedef struct sng_m2ua_cfg{
char name[MAX_NAME_LEN];
uint32_t flags;
uint32_t id; /* ID */
uint32_t iid; /* ID */
uint8_t nodeType; /*Node Type SG/ASP */
uint8_t end_point_opened; /* flag to check is end-point already opened */
uint16_t clusterId; /* idx to m2ua_cluster profile */
}sng_m2ua_cfg_t;
typedef struct sng_m2ua_peer_cfg{
char name[MAX_NAME_LEN];
uint32_t flags;
uint32_t id; /* ID */
uint8_t aspIdFlag; /* Flag used to indicate whether include the ASP ID in the ASP UP message */
uint16_t selfAspId; /* Self ASP ID. ASP identifier for this ASP node if the aspIdFlag is TRUE. */
uint32_t numDestAddr; /* Number of destination address defined */
uint16_t sctpId; /* idx to sctp profile */
uint16_t port;
uint32_t destAddrList[SCT_MAX_NET_ADDRS+1]; /* Destination adddress list */
uint16_t locOutStrms; /*Number of outgoing streams supported by this association*/
int init_sctp_assoc; /* flag to tell if we need to initiate SCTP association */
}sng_m2ua_peer_cfg_t;
typedef enum{
SNG_M2UA_LOAD_SHARE_ALGO_RR = 0x1, /* Round Robin Mode*/
SNG_M2UA_LOAD_SHARE_ALGO_LS = 0x2, /* Link Specified */
SNG_M2UA_LOAD_SHARE_ALGO_CS = 0x3, /* Customer Specified */
}sng_m2ua_load_share_algo_types_e;
/* Possible values of Traffic mode */
typedef enum{
SNG_M2UA_TRF_MODE_OVERRIDE = 0x1, /* Override Mode */
SNG_M2UA_TRF_MODE_LOADSHARE = 0x2, /* Loadshare Mode */
SNG_M2UA_TRF_MODE_BROADCAST = 0x3, /* Broadcast Mode */
SNG_M2UA_TRF_MODE_ANY = 0x0, /* ANY Mode */
}sng_m2ua_traffic_mode_types_e;
typedef struct sng_m2ua_cluster_cfg{
char name[MAX_NAME_LEN];
uint32_t flags;
uint32_t id; /* ID */
uint32_t sct_sap_id; /* Internal - sct_sap_id */
uint8_t trfMode; /* Traffic mode. This parameter defines the mode in which this m2ua cluster is supposed to work */
uint8_t loadShareAlgo; /* This parameter defines the M2UA load share algorithm which is used to distribute the traffic */
uint16_t numOfPeers; /* idx to m2ua_peer profile */
uint16_t peerIdLst[MW_MAX_NUM_OF_PEER]; /* idx to m2ua_peer profile */
}sng_m2ua_cluster_cfg_t;
typedef struct sng_m2ua_gbl_cfg{
sng_nif_cfg_t nif[MW_MAX_NUM_OF_INTF+1];
sng_m2ua_cfg_t m2ua[MW_MAX_NUM_OF_INTF+1];
sng_m2ua_peer_cfg_t m2ua_peer[MW_MAX_NUM_OF_PEER+1];
sng_m2ua_cluster_cfg_t m2ua_clus[MW_MAX_NUM_OF_CLUSTER+1];
}sng_m2ua_gbl_cfg_t;
/* m2ua xml parsing APIs */
int ftmod_ss7_parse_nif_interfaces(ftdm_conf_node_t *nif_interfaces);
int ftmod_ss7_parse_m2ua_interfaces(ftdm_conf_node_t *m2ua_interfaces);
int ftmod_ss7_parse_m2ua_peer_interfaces(ftdm_conf_node_t *m2ua_peer_interfaces);
int ftmod_ss7_parse_m2ua_clust_interfaces(ftdm_conf_node_t *m2ua_clust_interfaces);
int ftmod_ss7_parse_sctp_links(ftdm_conf_node_t *node);
uint32_t iptoul(const char *ip);
int ftmod_ss7_m2ua_start(void);
void ftmod_ss7_m2ua_free(void);
ftdm_status_t ftmod_ss7_m2ua_cfg(void);
ftdm_status_t ftmod_ss7_m2ua_init(void);
int ftmod_sctp_ssta_req(int elemt, int id, SbMgmt* cfm);
int ftmod_m2ua_ssta_req(int elemt, int id, MwMgmt* cfm);
int ftmod_nif_ssta_req(int elemt, int id, NwMgmt* cfm);
void ftmod_ss7_enable_m2ua_sg_logging(void);
void ftmod_ss7_disable_m2ua_sg_logging(void);
#endif /*__FTMOD_SNG_SS7_M2UA_H__*/
......@@ -42,8 +42,6 @@
/******************************************************************************/
/* PROTOTYPES *****************************************************************/
ftdm_status_t handle_relay_connect(RyMngmt *sta);
ftdm_status_t handle_relay_disconnect(RyMngmt *sta);
/*static ftdm_status_t enable_all_ckts_for_relay(void);*/
static ftdm_status_t reconfig_all_ckts_for_relay(void);
......@@ -66,11 +64,9 @@ ftdm_status_t handle_relay_connect(RyMngmt *sta)
SS7_INFO("Relay Channel %d connection UP\n", sng_relay->id);
if (sng_relay->type == LRY_CT_TCP_CLIENT) {
if (!sngss7_test_flag(sng_relay, SNGSS7_RELAY_INIT)) {
if (reconfig_all_ckts_for_relay()) {
SS7_ERROR("Failed to reconfigure ISUP Ckts!\n");
/* we're done....this is very bad! */
}
if (reconfig_all_ckts_for_relay()) {
SS7_ERROR("Failed to reconfigure ISUP Ckts!\n");
/* we're done....this is very bad! */
}
return FTDM_SUCCESS;
} else if (sng_relay->type == LRY_CT_TCP_SERVER) {
......@@ -84,23 +80,24 @@ ftdm_status_t handle_relay_connect(RyMngmt *sta)
/******************************************************************************/
ftdm_status_t handle_relay_disconnect_on_error(RyMngmt *sta)
{
SS7_DEBUG("SS7 relay disconnect on error\n");
/* check which procId is in error, if it is 1, disable the ckts */
if (sta->t.usta.s.ryErrUsta.errPid == 1 ) {
/* we've lost the server, bring down the mtp2 links */
disble_all_mtp2_sigs_for_relay();
/* we've lost the server, bring the sig status down on all ckts */
disable_all_ckts_for_relay();
/* we've lost the server, bring down the mtp2 links */
disble_all_mtp2_sigs_for_relay();
}
/* check if the channel is a server, means we just lost a MGW */
if (g_ftdm_sngss7_data.cfg.relay[sta->t.usta.s.ryErrUsta.errPid].type == LRY_CT_TCP_SERVER) {
/* we've lost the client, bring down all mtp3 links for this procId */
disable_all_sigs_for_relay(sta->t.usta.s.ryErrUsta.errPid);
/* we've lost the client, bring down all the ckts for this procId */
block_all_ckts_for_relay(sta->t.usta.s.ryErrUsta.errPid);
/* we've lost the client, bring down all mtp3 links for this procId */
disable_all_sigs_for_relay(sta->t.usta.s.ryErrUsta.errPid);
}
return FTDM_SUCCESS;
......@@ -110,6 +107,8 @@ ftdm_status_t handle_relay_disconnect_on_error(RyMngmt *sta)
ftdm_status_t handle_relay_disconnect_on_down(RyMngmt *sta)
{
SS7_DEBUG("SS7 relay disconnect on down\n");
/* check if the channel is a server, means we just lost a MGW */
if (g_ftdm_sngss7_data.cfg.relay[sta->t.usta.s.ryUpUsta.id].type == LRY_CT_TCP_SERVER) {
block_all_ckts_for_relay(sta->t.usta.s.ryUpUsta.id);
......@@ -248,7 +247,7 @@ ftdm_status_t block_all_ckts_for_relay(uint32_t procId)
if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == SNG_CKT_VOICE) {
/* send a block request via stack manager */
ret = ftmod_ss7_block_isup_ckt(g_ftdm_sngss7_data.cfg.isupCkt[x].id);
ret = ftmod_ss7_block_isup_ckt_nowait(g_ftdm_sngss7_data.cfg.isupCkt[x].id);
if (ret) {
SS7_INFO("Successfully BLOcked CIC:%d(ckt:%d) due to Relay failure\n",
g_ftdm_sngss7_data.cfg.isupCkt[x].cic,
......@@ -331,6 +330,7 @@ static ftdm_status_t unblock_all_ckts_for_relay(uint32_t procId)
}
#endif
/******************************************************************************/
/* For Emacs:
* Local Variables:
......
......@@ -49,7 +49,7 @@
/******************************************************************************/
/* PROTOTYPES *****************************************************************/
void handle_isup_t35(void *userdata);
/******************************************************************************/
/* FUNCTIONS ******************************************************************/
......@@ -76,10 +76,13 @@ void handle_isup_t35(void *userdata)
/* end the call */
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_CANCEL);
/* kill t10 if active */
/* kill t10 t39 if active */
if (sngss7_info->t10.hb_timer_id) {
ftdm_sched_cancel_timer (sngss7_info->t10.sched, sngss7_info->t10.hb_timer_id);
}
if (sngss7_info->t39.hb_timer_id) {
ftdm_sched_cancel_timer (sngss7_info->t39.sched, sngss7_info->t39.hb_timer_id);
}
/*unlock*/
ftdm_channel_unlock(ftdmchan);
......@@ -108,7 +111,43 @@ void handle_isup_t10(void *userdata)
SS7_FUNC_TRACE_EXIT(__FUNCTION__);
}
void handle_isup_t39(void *userdata)
{
SS7_FUNC_TRACE_ENTER(__FUNCTION__);
sngss7_timer_data_t *timer = userdata;
sngss7_chan_data_t *sngss7_info = timer->sngss7_info;
ftdm_channel_t *ftdmchan = sngss7_info->ftdmchan;
/* now that we have the right channel...put a lock on it so no-one else can use it */
ftdm_channel_lock(ftdmchan);
/* Q.764 2.2.5 Address incomplete (T35 expiry action is hangup with cause 28 according to Table A.1/Q.764) */
SS7_ERROR("[Call-Control] Timer 39 expired on CIC = %d\n", sngss7_info->circuit->cic);
/* set the flag to indicate this hangup is started from the local side */
sngss7_set_ckt_flag(sngss7_info, FLAG_LOCAL_REL);
/* hang up on timer expiry */
ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_INVALID_NUMBER_FORMAT;
/* end the call */
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_CANCEL);
/* kill t10 t35 if active */
if (sngss7_info->t10.hb_timer_id) {
ftdm_sched_cancel_timer (sngss7_info->t10.sched, sngss7_info->t10.hb_timer_id);
}
if (sngss7_info->t35.hb_timer_id) {
ftdm_sched_cancel_timer (sngss7_info->t35.sched, sngss7_info->t35.hb_timer_id);
}
/*unlock*/
ftdm_channel_unlock(ftdmchan);
SS7_FUNC_TRACE_EXIT(__FUNCTION__);
}
/******************************************************************************/
/* For Emacs:
* Local Variables:
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论