Skip to content
项目
群组
代码片段
帮助
正在加载...
登录
切换导航
F
freeswitch
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
张华
freeswitch
Commits
23a32838
提交
23a32838
authored
1月 27, 2012
作者:
Moises Silva
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
freetdm: Initial attempt to bridge natively SS7 signaling between 2 channels
上级
b4e8d5b6
显示空白字符变更
内嵌
并排
正在显示
6 个修改的文件
包含
490 行增加
和
52 行删除
+490
-52
ftdm_io.c
libs/freetdm/src/ftdm_io.c
+69
-2
ftmod_sangoma_ss7_main.c
...etdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c
+378
-17
ftmod_sangoma_ss7_main.h
...etdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h
+6
-1
ftmod_sangoma_ss7_out.c
...eetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c
+29
-32
ftdm_core.h
libs/freetdm/src/include/private/ftdm_core.h
+6
-0
ftdm_types.h
libs/freetdm/src/include/private/ftdm_types.h
+2
-0
没有找到文件。
libs/freetdm/src/ftdm_io.c
浏览文件 @
23a32838
...
...
@@ -53,8 +53,6 @@ struct tm *localtime_r(const time_t *clock, struct tm *result);
#endif
#define FORCE_HANGUP_TIMER 30000
#define SPAN_PENDING_CHANS_QUEUE_SIZE 1000
#define SPAN_PENDING_SIGNALS_QUEUE_SIZE 1000
#define FTDM_READ_TRACE_INDEX 0
#define FTDM_WRITE_TRACE_INDEX 1
#define MAX_CALLIDS 6000
...
...
@@ -2201,6 +2199,12 @@ static ftdm_status_t _ftdm_channel_call_hangup_nl(const char *file, const char *
{
ftdm_status_t
status
=
FTDM_SUCCESS
;
if
(
ftdm_test_flag
(
chan
,
FTDM_CHANNEL_NATIVE_SIGBRIDGE
))
{
ftdm_log_chan_ex
(
chan
,
file
,
func
,
line
,
FTDM_LOG_LEVEL_DEBUG
,
"Ignoring hangup in channel in state %s (native bridge enabled)
\n
"
,
ftdm_channel_state2str
(
chan
->
state
));
goto
done
;
}
if
(
chan
->
state
!=
FTDM_CHANNEL_STATE_DOWN
)
{
if
(
chan
->
state
==
FTDM_CHANNEL_STATE_HANGUP
)
{
/* make user's life easier, and just ignore double hangup requests */
...
...
@@ -2227,6 +2231,8 @@ static ftdm_status_t _ftdm_channel_call_hangup_nl(const char *file, const char *
ftdm_channel_close
(
&
chan
);
}
}
done
:
return
status
;
}
...
...
@@ -2322,6 +2328,15 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_indicate(const char *file, const ch
ftdm_channel_lock
(
ftdmchan
);
if
(
ftdm_test_flag
(
ftdmchan
,
FTDM_CHANNEL_NATIVE_SIGBRIDGE
))
{
ftdm_log_chan_ex
(
ftdmchan
,
file
,
func
,
line
,
FTDM_LOG_LEVEL_DEBUG
,
"Ignoring indication %s in channel in state %s (native bridge enabled)
\n
"
,
ftdm_channel_indication2str
(
indication
),
ftdm_channel_state2str
(
ftdmchan
->
state
));
status
=
FTDM_SUCCESS
;
goto
done
;
}
if
(
ftdm_test_flag
(
ftdmchan
,
FTDM_CHANNEL_IND_ACK_PENDING
))
{
ftdm_log_chan_ex
(
ftdmchan
,
file
,
func
,
line
,
FTDM_LOG_LEVEL_WARNING
,
"Cannot indicate %s in channel with indication %s still pending in state %s
\n
"
,
ftdm_channel_indication2str
(
indication
),
...
...
@@ -2422,10 +2437,50 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_reset(const char *file, const char *func
return
FTDM_SUCCESS
;
}
FT_DECLARE
(
ftdm_status_t
)
ftdm_get_channel_from_string
(
const
char
*
string_id
,
ftdm_span_t
**
out_span
,
ftdm_channel_t
**
out_channel
)
{
ftdm_status_t
status
=
FTDM_SUCCESS
;
int
rc
=
0
;
ftdm_span_t
*
span
=
NULL
;
ftdm_channel_t
*
ftdmchan
=
NULL
;
unsigned
span_id
=
0
;
unsigned
chan_id
=
0
;
*
out_span
=
NULL
;
*
out_channel
=
NULL
;
rc
=
sscanf
(
string_id
,
"%u:%u"
,
&
span_id
,
&
chan_id
);
if
(
rc
!=
2
)
{
ftdm_log
(
FTDM_LOG_ERROR
,
"Failed to parse channel id string '%s'
\n
"
,
string_id
);
status
=
FTDM_EINVAL
;
goto
done
;
}
status
=
ftdm_span_find
(
span_id
,
&
span
);
if
(
status
!=
FTDM_SUCCESS
||
!
span
)
{
ftdm_log
(
FTDM_LOG_ERROR
,
"Failed to find span for channel id string '%s'
\n
"
,
string_id
);
status
=
FTDM_EINVAL
;
goto
done
;
}
if
(
chan_id
>
(
FTDM_MAX_CHANNELS_SPAN
+
1
)
||
!
(
ftdmchan
=
span
->
channels
[
chan_id
]))
{
ftdm_log
(
FTDM_LOG_ERROR
,
"Invalid channel id string '%s'
\n
"
,
string_id
);
status
=
FTDM_EINVAL
;
goto
done
;
}
status
=
FTDM_SUCCESS
;
*
out_span
=
span
;
*
out_channel
=
ftdmchan
;
done
:
return
status
;
}
/* this function MUST be called with the channel lock held with lock recursivity of 1 exactly,
* and the caller must be aware we might unlock the channel for a brief period of time and then lock it again */
static
ftdm_status_t
_ftdm_channel_call_place_nl
(
const
char
*
file
,
const
char
*
func
,
int
line
,
ftdm_channel_t
*
ftdmchan
,
ftdm_usrmsg_t
*
usrmsg
)
{
const
char
*
var
=
NULL
;
ftdm_status_t
status
=
FTDM_FAIL
;
ftdm_assert_return
(
ftdmchan
!=
NULL
,
FTDM_FAIL
,
"null channel"
);
...
...
@@ -2461,6 +2516,17 @@ static ftdm_status_t _ftdm_channel_call_place_nl(const char *file, const char *f
ftdm_set_flag
(
ftdmchan
,
FTDM_CHANNEL_CALL_STARTED
);
ftdm_call_set_call_id
(
ftdmchan
,
&
ftdmchan
->
caller_data
);
var
=
ftdm_usrmsg_get_var
(
usrmsg
,
"sigbridge_peer"
);
if
(
var
)
{
ftdm_span_t
*
peer_span
=
NULL
;
ftdm_channel_t
*
peer_chan
=
NULL
;
ftdm_log_chan_msg
(
ftdmchan
,
FTDM_LOG_CRIT
,
"enabling native signaling bridge!
\n
"
);
ftdm_set_flag
(
ftdmchan
,
FTDM_CHANNEL_NATIVE_SIGBRIDGE
);
ftdm_get_channel_from_string
(
var
,
&
peer_span
,
&
peer_chan
);
if
(
peer_chan
)
{
ftdm_set_flag
(
peer_chan
,
FTDM_CHANNEL_NATIVE_SIGBRIDGE
);
}
}
/* if the signaling stack left the channel in state down on success, is expecting us to move to DIALING */
if
(
ftdmchan
->
state
==
FTDM_CHANNEL_STATE_DOWN
)
{
...
...
@@ -2662,6 +2728,7 @@ static ftdm_status_t ftdm_channel_done(ftdm_channel_t *ftdmchan)
ftdm_clear_flag
(
ftdmchan
,
FTDM_CHANNEL_ANSWERED
);
ftdm_clear_flag
(
ftdmchan
,
FTDM_CHANNEL_USER_HANGUP
);
ftdm_clear_flag
(
ftdmchan
,
FTDM_CHANNEL_DIGITAL_MEDIA
);
ftdm_clear_flag
(
ftdmchan
,
FTDM_CHANNEL_NATIVE_SIGBRIDGE
);
ftdm_mutex_lock
(
ftdmchan
->
pre_buffer_mutex
);
ftdm_buffer_destroy
(
&
ftdmchan
->
pre_buffer
);
ftdmchan
->
pre_buffer_size
=
0
;
...
...
libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c
浏览文件 @
23a32838
...
...
@@ -55,6 +55,7 @@ ftdm_sngss7_data_t g_ftdm_sngss7_data;
/* PROTOTYPES *****************************************************************/
static
void
*
ftdm_sangoma_ss7_run
(
ftdm_thread_t
*
me
,
void
*
obj
);
static
void
ftdm_sangoma_ss7_process_stack_event
(
sngss7_event_data_t
*
sngss7_event
);
static
void
ftdm_sangoma_ss7_process_peer_stack_event
(
ftdm_channel_t
*
ftdmchan
,
sngss7_event_data_t
*
sngss7_event
);
static
ftdm_status_t
ftdm_sangoma_ss7_stop
(
ftdm_span_t
*
span
);
static
ftdm_status_t
ftdm_sangoma_ss7_start
(
ftdm_span_t
*
span
);
...
...
@@ -338,9 +339,10 @@ static void handle_hw_alarm(ftdm_event_t *e)
/* MONITIOR THREADS ***********************************************************/
static
void
*
ftdm_sangoma_ss7_run
(
ftdm_thread_t
*
me
,
void
*
obj
)
{
ftdm_interrupt_t
*
ftdm_sangoma_ss7_int
[
2
];
ftdm_interrupt_t
*
ftdm_sangoma_ss7_int
[
3
];
ftdm_span_t
*
ftdmspan
=
(
ftdm_span_t
*
)
obj
;
ftdm_channel_t
*
ftdmchan
=
NULL
;
ftdm_channel_t
*
peerchan
=
NULL
;
ftdm_event_t
*
event
=
NULL
;
sngss7_event_data_t
*
sngss7_event
=
NULL
;
sngss7_span_data_t
*
sngss7_span
=
(
sngss7_span_data_t
*
)
ftdmspan
->
signal_data
;
...
...
@@ -365,6 +367,12 @@ static void *ftdm_sangoma_ss7_run(ftdm_thread_t * me, void *obj)
goto
ftdm_sangoma_ss7_run_exit
;
}
/* get an interrupt queue for this span for peer channel events */
if
(
ftdm_queue_get_interrupt
(
sngss7_span
->
peer_chans
,
&
ftdm_sangoma_ss7_int
[
2
])
!=
FTDM_SUCCESS
)
{
SS7_CRITICAL
(
"Failed to get a ftdm_interrupt for span = %d for peer channel events queue!
\n
"
,
ftdmspan
->
span_id
);
goto
ftdm_sangoma_ss7_run_exit
;
}
while
(
ftdm_running
()
&&
!
(
ftdm_test_flag
(
ftdmspan
,
FTDM_SPAN_STOP_THREAD
)))
{
int
x
=
0
;
if
(
b_alarm_test
)
{
...
...
@@ -395,7 +403,7 @@ static void *ftdm_sangoma_ss7_run(ftdm_thread_t * me, void *obj)
}
/* check the channel state queue for an event*/
switch
((
ftdm_interrupt_multiple_wait
(
ftdm_sangoma_ss7_int
,
2
,
100
)))
{
switch
((
ftdm_interrupt_multiple_wait
(
ftdm_sangoma_ss7_int
,
ftdm_array_len
(
ftdm_sangoma_ss7_int
)
,
100
)))
{
/**********************************************************************/
case
FTDM_SUCCESS
:
/* process all pending state changes */
...
...
@@ -412,6 +420,31 @@ static void *ftdm_sangoma_ss7_run(ftdm_thread_t * me, void *obj)
ftdm_mutex_unlock
(
ftdmchan
->
mutex
);
}
/* clean out all peer pending channel events */
while
((
peerchan
=
ftdm_queue_dequeue
(
sngss7_span
->
peer_chans
)))
{
/* note that the channels being dequeued here may not belong to this span
they may belong to just about any other span that one of our channels
happens to be bridged to */
sngss7_chan_data_t
*
peer_info
=
peerchan
->
call_data
;
sngss7_chan_data_t
*
chan_info
=
peer_info
->
peer_data
;
ftdmchan
=
chan_info
->
ftdmchan
;
/*
if there is any state changes at all, those will be done in the opposite channel
to peerchan (where the original event was received), therefore we must lock ftdmchan,
but do not need to lock peerchan as we only read its event queue, which is already
locked when dequeueing */
ftdm_channel_lock
(
ftdmchan
);
/* clean out all pending stack events in the peer channel */
while
((
sngss7_event
=
ftdm_queue_dequeue
(
peer_info
->
event_queue
)))
{
ftdm_sangoma_ss7_process_peer_stack_event
(
ftdmchan
,
sngss7_event
);
ftdm_safe_free
(
sngss7_event
);
}
ftdm_channel_lock
(
ftdmchan
);
}
/* clean out all pending stack events */
while
((
sngss7_event
=
ftdm_queue_dequeue
(
sngss7_span
->
event_queue
)))
{
ftdm_sangoma_ss7_process_stack_event
(
sngss7_event
);
...
...
@@ -522,7 +555,9 @@ static void ftdm_sangoma_ss7_process_stack_event (sngss7_event_data_t *sngss7_ev
/* now that we have the right channel ... put a lock on it so no-one else can use it */
ftdm_channel_lock
(
ftdmchan
);
if
(
sngss7_info
->
event_queue
)
{
/* while there's a state change present on this channel process it */
ftdm_channel_advance_states
(
ftdmchan
);
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
)))
{
...
...
@@ -530,16 +565,50 @@ static void ftdm_sangoma_ss7_process_stack_event (sngss7_event_data_t *sngss7_ev
ftdm_safe_free
(
event_clone
);
}
}
/* clone the event and save it for later usage */
event_clone
=
ftdm_calloc
(
1
,
sizeof
(
*
sngss7_event
));
if
(
event_clone
)
{
memcpy
(
event_clone
,
sngss7_event
,
sizeof
(
*
sngss7_event
));
ftdm_queue_enqueue
(
sngss7_info
->
event_queue
,
event_clone
);
if
(
sngss7_info
->
peer_data
)
{
sngss7_span_data_t
*
sngss7_peer_span
=
(
sngss7_span_data_t
*
)
sngss7_info
->
peer_data
->
ftdmchan
->
span
->
signal_data
;
/* we already have a peer attached, wake him up */
ftdm_queue_enqueue
(
sngss7_peer_span
->
peer_chans
,
sngss7_info
->
ftdmchan
);
}
}
/* while there's a state change present on this channel process it */
/* we could test for sngss7_info->peer_data too, bit this flag is set earlier, the earlier we know the better */
if
(
ftdm_test_flag
(
ftdmchan
,
FTDM_CHANNEL_NATIVE_SIGBRIDGE
))
{
/* most messages are simply relayed in sig bridge mode, except for hangup which requires state changing */
switch
(
sngss7_event
->
event_id
)
{
case
SNGSS7_REL_IND_EVENT
:
ftdm_set_state
(
ftdmchan
,
FTDM_CHANNEL_STATE_TERMINATING
);
break
;
case
SNGSS7_REL_CFM_EVENT
:
{
ftdm_channel_t
*
peer_chan
=
sngss7_info
->
peer_data
->
ftdmchan
;
ftdm_set_state
(
ftdmchan
,
FTDM_CHANNEL_STATE_DOWN
);
if
(
peer_chan
)
{
/* we need to unlock our chan or we risk deadlock */
ftdm_channel_advance_states
(
ftdmchan
);
ftdm_channel_unlock
(
ftdmchan
);
ftdm_channel_lock
(
peer_chan
);
if
(
peer_chan
->
state
!=
FTDM_CHANNEL_STATE_DOWN
)
{
ftdm_set_state
(
ftdmchan
,
FTDM_CHANNEL_STATE_DOWN
);
}
ftdm_channel_unlock
(
peer_chan
);
ftdm_channel_lock
(
ftdmchan
);
}
}
break
;
default:
break
;
}
goto
done
;
}
/* figure out the type of event and send it to the right handler */
switch
(
sngss7_event
->
event_id
)
{
...
...
@@ -602,6 +671,7 @@ static void ftdm_sangoma_ss7_process_stack_event (sngss7_event_data_t *sngss7_ev
/**************************************************************************/
}
done:
/* while there's a state change present on this channel process it */
ftdm_channel_advance_states
(
ftdmchan
);
...
...
@@ -610,8 +680,290 @@ static void ftdm_sangoma_ss7_process_stack_event (sngss7_event_data_t *sngss7_ev
}
FTDM_ENUM_NAMES
(
SNG_EVENT_TYPE_NAMES
,
SNG_EVENT_TYPE_STRINGS
)
FTDM_STR2ENUM
(
ftdm_str2sngss7_event
,
ftdm_sngss7_event2str
,
sng_event_type_t
,
SNG_EVENT_TYPE_NAMES
,
SNGSS7_INVALID_EVENT
)
static
void
ftdm_sangoma_ss7_process_peer_stack_event
(
ftdm_channel_t
*
ftdmchan
,
sngss7_event_data_t
*
sngss7_event
)
{
sngss7_chan_data_t
*
sngss7_info
=
ftdmchan
->
call_data
;
if
(
ftdmchan
->
state
<
FTDM_CHANNEL_STATE_UP
)
{
ftdm_set_state
(
ftdmchan
,
FTDM_CHANNEL_STATE_UP
);
ftdm_channel_advance_states
(
ftdmchan
);
}
SS7_ERROR_CHAN
(
ftdmchan
,
"[CIC:%d]Relaying message %s from bridged peer
\n
"
,
sngss7_info
->
circuit
->
cic
,
ftdm_sngss7_event2str
(
sngss7_event
->
event_id
));
switch
(
sngss7_event
->
event_id
)
{
case
(
SNGSS7_CON_IND_EVENT
):
SS7_ERROR_CHAN
(
ftdmchan
,
"[CIC:%d]Rx IAM (bridged)??
\n
"
,
sngss7_info
->
circuit
->
cic
);
break
;
case
(
SNGSS7_CON_CFM_EVENT
):
/* send the ANM request to LibSngSS7 */
sng_cc_con_response
(
1
,
sngss7_info
->
suInstId
,
sngss7_info
->
spInstId
,
sngss7_info
->
circuit
->
id
,
&
sngss7_event
->
event
.
siConEvnt
,
5
);
SS7_INFO_CHAN
(
ftdmchan
,
"[CIC:%d]Tx peer ANM
\n
"
,
sngss7_info
->
circuit
->
cic
);
break
;
case
(
SNGSS7_CON_STA_EVENT
):
switch
(
sngss7_event
->
evntType
)
{
/**************************************************************************/
case
(
ADDRCMPLT
):
SS7_INFO_CHAN
(
ftdmchan
,
"[CIC:%d]Tx peer ACM
\n
"
,
sngss7_info
->
circuit
->
cic
);
break
;
/**************************************************************************/
case
(
MODIFY
):
SS7_INFO_CHAN
(
ftdmchan
,
"[CIC:%d]Tx peer MODIFY
\n
"
,
sngss7_info
->
circuit
->
cic
);
break
;
/**************************************************************************/
case
(
MODCMPLT
):
SS7_INFO_CHAN
(
ftdmchan
,
"[CIC:%d]Tx peer MODIFY-COMPLETE
\n
"
,
sngss7_info
->
circuit
->
cic
);
break
;
/**************************************************************************/
case
(
MODREJ
):
SS7_INFO_CHAN
(
ftdmchan
,
"[CIC:%d]Tx peer MODIFY-REJECT
\n
"
,
sngss7_info
->
circuit
->
cic
);
break
;
/**************************************************************************/
case
(
PROGRESS
):
SS7_INFO_CHAN
(
ftdmchan
,
"[CIC:%d]Tx peer CPG
\n
"
,
sngss7_info
->
circuit
->
cic
);
break
;
/**************************************************************************/
case
(
FRWDTRSFR
):
SS7_INFO_CHAN
(
ftdmchan
,
"[CIC:%d]Tx peer FOT
\n
"
,
sngss7_info
->
circuit
->
cic
);
break
;
/**************************************************************************/
case
(
INFORMATION
):
SS7_INFO_CHAN
(
ftdmchan
,
"[CIC:%d]Tx peer INF
\n
"
,
sngss7_info
->
circuit
->
cic
);
break
;
/**************************************************************************/
case
(
INFORMATREQ
):
SS7_INFO_CHAN
(
ftdmchan
,
"[CIC:%d]Tx peer INR
\n
"
,
sngss7_info
->
circuit
->
cic
);
break
;
/**************************************************************************/
case
(
SUBSADDR
):
SS7_INFO_CHAN
(
ftdmchan
,
"[CIC:%d]Tx peer SAM
\n
"
,
sngss7_info
->
circuit
->
cic
);
break
;
/**************************************************************************/
case
(
EXIT
):
SS7_INFO_CHAN
(
ftdmchan
,
"[CIC:%d]Tx peer EXIT
\n
"
,
sngss7_info
->
circuit
->
cic
);
break
;
/**************************************************************************/
case
(
NETRESMGT
):
SS7_INFO_CHAN
(
ftdmchan
,
"[CIC:%d]Tx peer NRM
\n
"
,
sngss7_info
->
circuit
->
cic
);
break
;
/**************************************************************************/
case
(
IDENTREQ
):
SS7_INFO_CHAN
(
ftdmchan
,
"[CIC:%d]Tx peer IDR
\n
"
,
sngss7_info
->
circuit
->
cic
);
break
;
/**************************************************************************/
case
(
IDENTRSP
):
SS7_INFO_CHAN
(
ftdmchan
,
"[CIC:%d]Tx peer IRS
\n
"
,
sngss7_info
->
circuit
->
cic
);
break
;
/**************************************************************************/
case
(
MALCLLPRNT
):
SS7_INFO_CHAN
(
ftdmchan
,
"[CIC:%d]Tx peer MALICIOUS CALL
\n
"
,
sngss7_info
->
circuit
->
cic
);
break
;
/**************************************************************************/
case
(
CHARGE
):
SS7_INFO_CHAN
(
ftdmchan
,
"[CIC:%d]Tx peer CRG
\n
"
,
sngss7_info
->
circuit
->
cic
);
break
;
/**************************************************************************/
case
(
TRFFCHGE
):
SS7_INFO_CHAN
(
ftdmchan
,
"[CIC:%d]Tx peer CRG-TARIFF
\n
"
,
sngss7_info
->
circuit
->
cic
);
break
;
/**************************************************************************/
case
(
CHARGEACK
):
SS7_INFO_CHAN
(
ftdmchan
,
"[CIC:%d]Tx peer CRG-ACK
\n
"
,
sngss7_info
->
circuit
->
cic
);
break
;
/**************************************************************************/
case
(
CALLOFFMSG
):
SS7_INFO_CHAN
(
ftdmchan
,
"[CIC:%d]Tx peer CALL-OFFER
\n
"
,
sngss7_info
->
circuit
->
cic
);
break
;
/**************************************************************************/
case
(
LOOPPRVNT
):
SS7_INFO_CHAN
(
ftdmchan
,
"[CIC:%d]Tx peer LOP
\n
"
,
sngss7_info
->
circuit
->
cic
);
break
;
/**************************************************************************/
case
(
TECT_TIMEOUT
):
SS7_INFO_CHAN
(
ftdmchan
,
"[CIC:%d]Tx peer ECT-Timeout
\n
"
,
sngss7_info
->
circuit
->
cic
);
break
;
/**************************************************************************/
case
(
RINGSEND
):
SS7_INFO_CHAN
(
ftdmchan
,
"[CIC:%d]Tx peer RINGING-SEND
\n
"
,
sngss7_info
->
circuit
->
cic
);
break
;
/**************************************************************************/
case
(
CALLCLEAR
):
SS7_INFO_CHAN
(
ftdmchan
,
"[CIC:%d]Tx peer CALL-LINE Clear
\n
"
,
sngss7_info
->
circuit
->
cic
);
break
;
/**************************************************************************/
case
(
PRERELEASE
):
SS7_INFO_CHAN
(
ftdmchan
,
"[CIC:%d]Tx peer PRI
\n
"
,
sngss7_info
->
circuit
->
cic
);
break
;
/**************************************************************************/
case
(
APPTRANSPORT
):
SS7_INFO_CHAN
(
ftdmchan
,
"[CIC:%d]Tx peer APM
\n
"
,
sngss7_info
->
circuit
->
cic
);
break
;
/**************************************************************************/
case
(
OPERATOR
):
SS7_INFO_CHAN
(
ftdmchan
,
"[CIC:%d]Tx peer OPERATOR
\n
"
,
sngss7_info
->
circuit
->
cic
);
break
;
/**************************************************************************/
case
(
METPULSE
):
SS7_INFO_CHAN
(
ftdmchan
,
"[CIC:%d]Tx peer METERING-PULSE
\n
"
,
sngss7_info
->
circuit
->
cic
);
break
;
/**************************************************************************/
case
(
CLGPTCLR
):
SS7_INFO_CHAN
(
ftdmchan
,
"[CIC:%d]Tx peer CALLING_PARTY_CLEAR
\n
"
,
sngss7_info
->
circuit
->
cic
);
break
;
/**************************************************************************/
case
(
SUBDIRNUM
):
SS7_INFO_CHAN
(
ftdmchan
,
"[CIC:%d]Tx peer SUB-DIR
\n
"
,
sngss7_info
->
circuit
->
cic
);
break
;
#ifdef SANGOMA_SPIROU
case
(
CHARGE_ACK
):
SS7_INFO_CHAN
(
ftdmchan
,
"[CIC:%d]Tx peer TXA
\n
"
,
sngss7_info
->
circuit
->
cic
);
break
;
case
(
CHARGE_UNIT
):
SS7_INFO_CHAN
(
ftdmchan
,
"[CIC:%d]Tx peer ITX
\n
"
,
sngss7_info
->
circuit
->
cic
);
break
;
#endif
/**************************************************************************/
default
:
SS7_INFO_CHAN
(
ftdmchan
,
"[CIC:%d]Tx peer Unknown Msg %d
\n
"
,
sngss7_info
->
circuit
->
cic
,
sngss7_event
->
evntType
);
break
;
/**************************************************************************/
}
sng_cc_con_status
(
1
,
sngss7_info
->
suInstId
,
sngss7_info
->
spInstId
,
sngss7_info
->
circuit
->
id
,
&
sngss7_event
->
event
.
siCnStEvnt
,
sngss7_event
->
evntType
);
break
;
/**************************************************************************/
case
(
SNGSS7_REL_IND_EVENT
):
SS7_INFO_CHAN
(
ftdmchan
,
"[CIC:%d]Tx peer REL cause=%d
\n
"
,
sngss7_info
->
circuit
->
cic
,
sngss7_event
->
event
.
siRelEvnt
.
causeDgn
.
causeVal
.
val
);
//handle_rel_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, &sngss7_event->event.siRelEvnt);
sng_cc_rel_request
(
1
,
sngss7_info
->
suInstId
,
sngss7_info
->
spInstId
,
sngss7_info
->
circuit
->
id
,
&
sngss7_event
->
event
.
siRelEvnt
);
break
;
/**************************************************************************/
case
(
SNGSS7_REL_CFM_EVENT
):
SS7_INFO_CHAN
(
ftdmchan
,
"[CIC:%d]Tx peer RLC
\n
"
,
sngss7_info
->
circuit
->
cic
);
sng_cc_rel_response
(
1
,
sngss7_info
->
suInstId
,
sngss7_info
->
spInstId
,
sngss7_info
->
circuit
->
id
,
&
sngss7_event
->
event
.
siRelEvnt
);
//handle_rel_cfm(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, &sngss7_event->event.siRelEvnt);
break
;
/**************************************************************************/
case
(
SNGSS7_DAT_IND_EVENT
):
//handle_dat_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, &sngss7_event->event.siInfoEvnt);
break
;
/**************************************************************************/
case
(
SNGSS7_FAC_IND_EVENT
):
//handle_fac_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, sngss7_event->evntType, &sngss7_event->event.siFacEvnt);
break
;
/**************************************************************************/
case
(
SNGSS7_FAC_CFM_EVENT
):
//handle_fac_cfm(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, sngss7_event->evntType, &sngss7_event->event.siFacEvnt);
break
;
/**************************************************************************/
case
(
SNGSS7_UMSG_IND_EVENT
):
//handle_umsg_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit);
break
;
/**************************************************************************/
case
(
SNGSS7_STA_IND_EVENT
):
//handle_sta_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, sngss7_event->globalFlg, sngss7_event->evntType, &sngss7_event->event.siStaEvnt);
break
;
/**************************************************************************/
case
(
SNGSS7_SUSP_IND_EVENT
):
//handle_susp_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, &sngss7_event->event.siSuspEvnt);
break
;
/**************************************************************************/
case
(
SNGSS7_RESM_IND_EVENT
):
//handle_resm_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, &sngss7_event->event.siResmEvnt);
break
;
/**************************************************************************/
case
(
SNGSS7_SSP_STA_CFM_EVENT
):
SS7_ERROR
(
"dazed and confused ... hu?!
\n
"
);
break
;
/**************************************************************************/
default
:
SS7_ERROR
(
"Unknown Event Id!
\n
"
);
break
;
/**************************************************************************/
}
}
static
ftdm_status_t
ftdm_sangoma_ss7_native_bridge_state_change
(
ftdm_channel_t
*
ftdmchan
);
static
ftdm_status_t
ftdm_sangoma_ss7_native_bridge_state_change
(
ftdm_channel_t
*
ftdmchan
)
{
sngss7_chan_data_t
*
sngss7_info
=
ftdmchan
->
call_data
;
ftdm_channel_complete_state
(
ftdmchan
);
switch
(
ftdmchan
->
state
)
{
case
FTDM_CHANNEL_STATE_DOWN
:
{
/* both peers come here after the channel processing the RLC moves the pair to DOWN */
ftdm_channel_t
*
close_chan
=
ftdmchan
;
/* detach native bridging if needed (only the outbound leg is responsible for that to avoid races or messy locks) */
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 */
ftdm_channel_close
(
&
close_chan
);
}
break
;
case
FTDM_CHANNEL_STATE_UP
:
{
if
(
ftdm_test_flag
(
ftdmchan
,
FTDM_CHANNEL_OUTBOUND
))
{
sngss7_send_signal
(
sngss7_info
,
FTDM_SIGEVENT_UP
);
}
}
break
;
case
FTDM_CHANNEL_STATE_TERMINATING
:
{
/* when receiving REL we move to TERMINATING and notify the user that the bridge is ending */
sngss7_send_signal
(
sngss7_info
,
FTDM_SIGEVENT_STOP
);
}
break
;
default:
break
;
}
return
FTDM_SUCCESS
;
}
/******************************************************************************/
ftdm_status_t
ftdm_sangoma_ss7_process_state_change
(
ftdm_channel_t
*
ftdmchan
)
ftdm_status_t
ftdm_sangoma_ss7_process_state_change
(
ftdm_channel_t
*
ftdmchan
)
{
sngss7_chan_data_t
*
sngss7_info
=
ftdmchan
->
call_data
;
sng_isup_inf_t
*
isup_intf
=
NULL
;
...
...
@@ -623,6 +975,9 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
sngss7_info
->
ckt_flags
,
sngss7_info
->
blk_flags
);
if
(
sngss7_info
->
peer_data
)
{
return
ftdm_sangoma_ss7_native_bridge_state_change
(
ftdmchan
);
}
/*check what state we are supposed to be in */
switch
(
ftdmchan
->
state
)
{
...
...
@@ -1940,6 +2295,12 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_ss7_span_config)
return
FTDM_FAIL
;
}
/* create an peer channel queue for this span */
if
((
ftdm_queue_create
(
&
(
ss7_span_info
)
->
peer_chans
,
SPAN_PENDING_CHANS_QUEUE_SIZE
))
!=
FTDM_SUCCESS
)
{
SS7_CRITICAL
(
"Unable to create peer chans queue!
\n
"
);
return
FTDM_FAIL
;
}
/*setup the span structure with the info so far */
g_ftdm_sngss7_data
.
sig_cb
=
sig_cb
;
span
->
start
=
ftdm_sangoma_ss7_start
;
...
...
libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h
浏览文件 @
23a32838
...
...
@@ -81,8 +81,12 @@ typedef enum {
SNGSS7_STA_IND_EVENT
,
SNGSS7_SUSP_IND_EVENT
,
SNGSS7_RESM_IND_EVENT
,
SNGSS7_SSP_STA_CFM_EVENT
SNGSS7_SSP_STA_CFM_EVENT
,
SNGSS7_INVALID_EVENT
,
}
sng_event_type_t
;
#define SNG_EVENT_TYPE_STRINGS "CON_IND", "CON_CFM", "CON_STA", "REL_IND", "REL_CFM", "DAT_IND", "FAC_IND", \
"FAC_CFM", "UMSG_IND", "STA_IND", "SUSP_IND", "RESM_IND", "SSP_STA_CFM", "INVALID"
FTDM_STR2ENUM_P
(
ftdm_str2sngss7_event
,
ftdm_sngss7_event2str
,
sng_event_type_t
)
typedef
enum
{
SNG_BIT_A
=
(
1
<<
0
),
...
...
@@ -500,6 +504,7 @@ typedef struct sngss7_span_data {
sngss7_group_data_t
rx_cgu
;
sngss7_group_data_t
tx_cgu
;
ftdm_queue_t
*
event_queue
;
ftdm_queue_t
*
peer_chans
;
}
sngss7_span_data_t
;
typedef
struct
sngss7_event_data
...
...
libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c
浏览文件 @
23a32838
...
...
@@ -58,26 +58,17 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan)
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
);
ftdm_get_channel_from_string
(
var
,
&
peer_span
,
&
peer_chan
);
if
(
!
peer_chan
)
{
SS7_ERROR_CHAN
(
ftdmchan
,
"Failed to find sigbridge peer from string '%s'
\n
"
,
var
);
}
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
);
if
(
peer_span
->
signal_type
!=
FTDM_SIGTYPE_SS7
)
{
SS7_ERROR_CHAN
(
ftdmchan
,
"Peer channel '%s' has different signaling type %d'
\n
"
,
var
,
peer_span
->
signal_type
);
}
else
{
sngss7_event_data_t
*
event_clone
=
NULL
;
peer_info
=
peer_chan
->
call_data
;
...
...
@@ -91,12 +82,15 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan)
SS7_WARN
(
"[CIC:%d]Discarding clone event from past call!
\n
"
,
sngss7_info
->
circuit
->
cic
);
ftdm_safe_free
(
event_clone
);
}
}
/* go up until release comes, note that state processing is done different and much simpler when there is a peer */
ftdm_set_state
(
ftdmchan
,
FTDM_CHANNEL_STATE_UP
);
ftdm_channel_advance_states
(
ftdmchan
);
}
}
}
if
(
sngss7_info
->
peer_data
)
{
sngss7_span_data_t
*
span_data
=
ftdmchan
->
span
->
signal_data
;
sngss7_event_data_t
*
event_clone
=
ftdm_queue_dequeue
(
sngss7_info
->
peer_data
->
event_queue
);
/* Retrieve IAM from our peer */
if
(
!
event_clone
)
{
...
...
@@ -108,6 +102,9 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan)
SS7_INFO_CHAN
(
ftdmchan
,
"[CIC:%d]Tx IAM (Bridged)
\n
"
,
sngss7_info
->
circuit
->
cic
);
memcpy
(
&
iam
,
&
event_clone
->
event
.
siConEvnt
,
sizeof
(
iam
));
}
/* since this is the first time we dequeue an event from the peer, make sure our main thread process any other events,
this will trigger the interrupt in our span peer_chans queue which will wake up our main thread if it is sleeping */
ftdm_queue_enqueue
(
span_data
->
peer_chans
,
sngss7_info
->
peer_data
->
ftdmchan
);
}
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
);
...
...
libs/freetdm/src/include/private/ftdm_core.h
浏览文件 @
23a32838
...
...
@@ -130,6 +130,9 @@
extern
"C"
{
#endif
#define SPAN_PENDING_CHANS_QUEUE_SIZE 1000
#define SPAN_PENDING_SIGNALS_QUEUE_SIZE 1000
#define GOTO_STATUS(label,st) status = st; goto label ;
#define ftdm_copy_string(x,y,z) strncpy(x, y, z - 1)
...
...
@@ -686,6 +689,9 @@ FT_DECLARE(ftdm_status_t) ftdm_sigmsg_remove_var(ftdm_sigmsg_t *sigmsg, const ch
*/
FT_DECLARE
(
ftdm_status_t
)
ftdm_sigmsg_set_raw_data
(
ftdm_sigmsg_t
*
sigmsg
,
void
*
data
,
ftdm_size_t
datalen
);
/*! \brief Retrieve a span and channel data structure from a string in the format 'span_id:chan_id'*/
FT_DECLARE
(
ftdm_status_t
)
ftdm_get_channel_from_string
(
const
char
*
string_id
,
ftdm_span_t
**
out_span
,
ftdm_channel_t
**
out_channel
);
/*!
\brief Assert condition
*/
...
...
libs/freetdm/src/include/private/ftdm_types.h
浏览文件 @
23a32838
...
...
@@ -265,6 +265,8 @@ typedef enum {
#define FTDM_CHANNEL_BLOCKING (1ULL << 35)
/*!< Media is digital */
#define FTDM_CHANNEL_DIGITAL_MEDIA (1ULL << 36)
/*!< Native signaling bridge is enabled */
#define FTDM_CHANNEL_NATIVE_SIGBRIDGE (1ULL << 37)
#include "ftdm_state.h"
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论