forked from Mirrors/freeswitch
freetdm: Implement SS7 transparent IAM functionality using the event clones queue
This commit is contained in:
parent
1b964054de
commit
a1a1af579b
@ -1603,6 +1603,23 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
|
||||
hunt_data.tech_pvt = tech_pvt;
|
||||
caller_data.priv = &hunt_data;
|
||||
|
||||
if (session
|
||||
&& (var = channel_get_variable(session, var_event, FREETDM_VAR_PREFIX "native_sigbridge"))
|
||||
&& switch_true(var)
|
||||
&& switch_core_session_compare(*new_session, session)) {
|
||||
char sigbridge_peer[255];
|
||||
private_t *peer_pvt = switch_core_session_get_private(session);
|
||||
switch_channel_t *peer_chan = switch_core_session_get_channel(session);
|
||||
switch_channel_t *our_chan = switch_core_session_get_channel(*new_session);
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT,
|
||||
"Bridging native signaling of channel %s to channel %s\n",
|
||||
switch_channel_get_name(peer_chan), switch_channel_get_name(our_chan));
|
||||
snprintf(sigbridge_peer, sizeof(sigbridge_peer), "%u:%u",
|
||||
ftdm_channel_get_span_id(peer_pvt->ftdmchan), ftdm_channel_get_id(peer_pvt->ftdmchan));
|
||||
ftdm_usrmsg_add_var(&usrmsg, "sigbridge_peer", sigbridge_peer);
|
||||
}
|
||||
|
||||
|
||||
if ((status = ftdm_call_place_ex(&caller_data, &hunting, &usrmsg)) != FTDM_SUCCESS) {
|
||||
if (tech_pvt->read_codec.implementation) {
|
||||
switch_core_codec_destroy(&tech_pvt->read_codec);
|
||||
|
@ -526,7 +526,7 @@ static void ftdm_sangoma_ss7_process_stack_event (sngss7_event_data_t *sngss7_ev
|
||||
if (sngss7_event->event_id == SNGSS7_CON_IND_EVENT) {
|
||||
/* this is the first event in a call, flush the event queue */
|
||||
while ((event_clone = ftdm_queue_dequeue(sngss7_info->event_queue))) {
|
||||
SS7_WARN("Discarding clone event from past call for circuit = %d!\n", sngss7_event->circuit);
|
||||
SS7_WARN("[CIC:%d]Discarding clone event from past call!\n", sngss7_info->circuit->cic);
|
||||
ftdm_safe_free(event_clone);
|
||||
}
|
||||
}
|
||||
@ -1076,6 +1076,19 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
|
||||
|
||||
if (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_OPEN)) {
|
||||
ftdm_channel_t *close_chan = ftdmchan;
|
||||
|
||||
/* detach native bridging if needed (only the outbound leg is responsible for that)
|
||||
Inbound leg was responsible of flushing its queue of events, but peer attach/detach
|
||||
is left as an outbound leg responsibility
|
||||
*/
|
||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
|
||||
sngss7_chan_data_t *peer_info = sngss7_info->peer_data;
|
||||
sngss7_info->peer_data = NULL;
|
||||
if (peer_info) {
|
||||
peer_info->peer_data = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* close the channel */
|
||||
SS7_DEBUG_CHAN(ftdmchan,"FTDM Channel Close %s\n", "");
|
||||
ftdm_channel_close (&close_chan);
|
||||
|
@ -486,6 +486,7 @@ typedef struct sngss7_chan_data {
|
||||
sngss7_group_data_t tx_grs;
|
||||
sngss7_group_data_t ucic;
|
||||
ftdm_queue_t *event_queue;
|
||||
struct sngss7_chan_data *peer_data;
|
||||
} sngss7_chan_data_t;
|
||||
|
||||
#define SNGSS7_RX_GRS_PENDING (1 << 0)
|
||||
|
@ -44,6 +44,7 @@
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan)
|
||||
{
|
||||
const char *var = NULL;
|
||||
SiConEvnt iam;
|
||||
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;;
|
||||
|
||||
@ -55,7 +56,59 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan)
|
||||
|
||||
memset (&iam, 0x0, sizeof (iam));
|
||||
|
||||
if (sngss7_info->circuit->transparent_iam &&
|
||||
var = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "sigbridge_peer");
|
||||
if (!ftdm_strlen_zero(var)) {
|
||||
ftdm_status_t status = FTDM_SUCCESS;
|
||||
int rc = 0;
|
||||
ftdm_span_t *peer_span = NULL;
|
||||
ftdm_channel_t *peer_chan = NULL;
|
||||
sngss7_chan_data_t *peer_info = NULL;
|
||||
unsigned peer_span_id = 0;
|
||||
unsigned peer_chan_id = 0;
|
||||
rc = sscanf(var, "%u:%u", &peer_span_id, &peer_chan_id);
|
||||
if (rc != 2) {
|
||||
SS7_ERROR_CHAN(ftdmchan, "Failed to parse sigbridge_peer string '%s'\n", var);
|
||||
} else {
|
||||
status = ftdm_span_find(peer_span_id, &peer_span);
|
||||
if (status != FTDM_SUCCESS || !peer_span) {
|
||||
SS7_ERROR_CHAN(ftdmchan, "Failed to find peer span for channel id '%u:%u'\n", peer_span_id, peer_chan_id);
|
||||
} else if (peer_span->signal_type != FTDM_SIGTYPE_SS7) {
|
||||
SS7_ERROR_CHAN(ftdmchan, "Peer channel %d:%d has different signaling type %d'\n",
|
||||
peer_span_id, peer_chan_id, peer_span->signal_type);
|
||||
} else {
|
||||
if (peer_chan_id > (FTDM_MAX_CHANNELS_SPAN+1) || !(peer_chan = peer_span->channels[peer_chan_id])) {
|
||||
SS7_ERROR_CHAN(ftdmchan, "Invalid peer channel id '%u:%u'\n", peer_span_id, peer_chan_id);
|
||||
} else {
|
||||
sngss7_event_data_t *event_clone = NULL;
|
||||
peer_info = peer_chan->call_data;
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Starting native bridge with peer CIC %d\n",
|
||||
sngss7_info->circuit->cic, peer_info->circuit->cic);
|
||||
/* make each one of us aware of the native bridge */
|
||||
peer_info->peer_data = sngss7_info;
|
||||
sngss7_info->peer_data = peer_info;
|
||||
/* flush our own queue */
|
||||
while ((event_clone = ftdm_queue_dequeue(sngss7_info->event_queue))) {
|
||||
SS7_WARN("[CIC:%d]Discarding clone event from past call!\n", sngss7_info->circuit->cic);
|
||||
ftdm_safe_free(event_clone);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (sngss7_info->peer_data) {
|
||||
sngss7_event_data_t *event_clone = ftdm_queue_dequeue(sngss7_info->peer_data->event_queue);
|
||||
/* Retrieve IAM from our peer */
|
||||
if (!event_clone) {
|
||||
SS7_ERROR_CHAN(ftdmchan, "No event clone in peer queue!%s\n", "");
|
||||
} else if (event_clone->event_id != SNGSS7_CON_IND_EVENT) {
|
||||
/* first message in the queue should ALWAYS be an IAM */
|
||||
SS7_ERROR_CHAN(ftdmchan, "Invalid initial peer message type '%d'\n", event_clone->event_id);
|
||||
} else {
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx IAM (Bridged)\n", sngss7_info->circuit->cic);
|
||||
memcpy(&iam, &event_clone->event.siConEvnt, sizeof(iam));
|
||||
}
|
||||
} else if (sngss7_info->circuit->transparent_iam &&
|
||||
sngss7_retrieve_iam(ftdmchan, &iam) == FTDM_SUCCESS) {
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx IAM (Transparent)\n", sngss7_info->circuit->cic);
|
||||
} else {
|
||||
|
Loading…
Reference in New Issue
Block a user