Skip to content
项目
群组
代码片段
帮助
正在加载...
登录
切换导航
F
freeswitch
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
张华
freeswitch
Commits
46e9704b
提交
46e9704b
authored
7月 31, 2010
作者:
Moises Silva
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
freetdm: make pri tapping actually work - missing audio mix
上级
b485f25f
显示空白字符变更
内嵌
并排
正在显示
1 个修改的文件
包含
294 行增加
和
48 行删除
+294
-48
ftmod_pritap.c
libs/freetdm/src/ftmod/ftmod_pritap/ftmod_pritap.c
+294
-48
没有找到文件。
libs/freetdm/src/ftmod/ftmod_pritap/ftmod_pritap.c
浏览文件 @
46e9704b
...
@@ -35,10 +35,24 @@
...
@@ -35,10 +35,24 @@
#include <poll.h>
#include <poll.h>
#include "private/ftdm_core.h"
#include "private/ftdm_core.h"
#define PRI_SPAN(p) (((p) >> 8) & 0xff)
#define PRI_CHANNEL(p) ((p) & 0xff)
typedef
enum
{
typedef
enum
{
PRITAP_RUNNING
=
(
1
<<
0
),
PRITAP_RUNNING
=
(
1
<<
0
),
}
pritap_flags_t
;
}
pritap_flags_t
;
typedef
struct
{
void
*
callref
;
ftdm_number_t
callingnum
;
ftdm_number_t
callingani
;
ftdm_number_t
callednum
;
ftdm_channel_t
*
fchan
;
char
callingname
[
80
];
int
proceeding
:
1
;
int
inuse
:
1
;
}
passive_call_t
;
typedef
struct
pritap
{
typedef
struct
pritap
{
int32_t
flags
;
int32_t
flags
;
struct
pri
*
pri
;
struct
pri
*
pri
;
...
@@ -46,7 +60,8 @@ typedef struct pritap {
...
@@ -46,7 +60,8 @@ typedef struct pritap {
ftdm_channel_t
*
dchan
;
ftdm_channel_t
*
dchan
;
ftdm_span_t
*
span
;
ftdm_span_t
*
span
;
ftdm_span_t
*
peerspan
;
ftdm_span_t
*
peerspan
;
struct
pritap
*
pritap
;
ftdm_mutex_t
*
pcalls_lock
;
passive_call_t
pcalls
[
FTDM_MAX_CHANNELS_PHYSICAL_SPAN
];
}
pritap_t
;
}
pritap_t
;
static
FIO_IO_UNLOAD_FUNCTION
(
ftdm_pritap_unload
)
static
FIO_IO_UNLOAD_FUNCTION
(
ftdm_pritap_unload
)
...
@@ -219,21 +234,26 @@ static ftdm_state_map_t pritap_state_map = {
...
@@ -219,21 +234,26 @@ static ftdm_state_map_t pritap_state_map = {
{
{
ZSD_INBOUND
,
ZSD_INBOUND
,
ZSM_UNACCEPTABLE
,
ZSM_UNACCEPTABLE
,
{
FTDM_CHANNEL_STATE_HANGUP
,
FTDM_
CHANNEL_STATE_TERMINATING
,
FTDM_
END
},
{
FTDM_CHANNEL_STATE_HANGUP
,
FTDM_END
},
{
FTDM_CHANNEL_STATE_
HANGUP_COMPLETE
,
FTDM_CHANNEL_STATE_DOWN
,
FTDM_END
},
{
FTDM_CHANNEL_STATE_
TERMINATING
,
FTDM_END
},
},
},
{
{
ZSD_INBOUND
,
ZSD_INBOUND
,
ZSM_UNACCEPTABLE
,
ZSM_UNACCEPTABLE
,
{
FTDM_CHANNEL_STATE_
HANGUP_COMPLETE
,
FTDM_END
},
{
FTDM_CHANNEL_STATE_
TERMINATING
,
FTDM_END
},
{
FTDM_CHANNEL_STATE_DOWN
,
FTDM_END
},
{
FTDM_CHANNEL_STATE_DOWN
,
FTDM_END
},
},
},
{
{
ZSD_INBOUND
,
ZSD_INBOUND
,
ZSM_UNACCEPTABLE
,
ZSM_UNACCEPTABLE
,
{
FTDM_CHANNEL_STATE_PROGRESS
,
FTDM_CHANNEL_STATE_PROGRESS_MEDIA
,
FTDM_END
},
{
FTDM_CHANNEL_STATE_PROGRESS
,
FTDM_END
},
{
FTDM_CHANNEL_STATE_HANGUP
,
FTDM_CHANNEL_STATE_TERMINATING
,
FTDM_CHANNEL_STATE_PROGRESS_MEDIA
,
{
FTDM_CHANNEL_STATE_HANGUP
,
FTDM_CHANNEL_STATE_TERMINATING
,
FTDM_CHANNEL_STATE_PROGRESS_MEDIA
,
FTDM_CHANNEL_STATE_UP
,
FTDM_END
},
FTDM_CHANNEL_STATE_CANCEL
,
FTDM_CHANNEL_STATE_UP
,
FTDM_END
},
},
{
ZSD_INBOUND
,
ZSM_UNACCEPTABLE
,
{
FTDM_CHANNEL_STATE_PROGRESS_MEDIA
,
FTDM_END
},
{
FTDM_CHANNEL_STATE_HANGUP
,
FTDM_CHANNEL_STATE_TERMINATING
,
FTDM_CHANNEL_STATE_UP
,
FTDM_END
},
},
},
{
{
ZSD_INBOUND
,
ZSD_INBOUND
,
...
@@ -242,19 +262,16 @@ static ftdm_state_map_t pritap_state_map = {
...
@@ -242,19 +262,16 @@ static ftdm_state_map_t pritap_state_map = {
{
FTDM_CHANNEL_STATE_HANGUP
,
FTDM_CHANNEL_STATE_TERMINATING
,
FTDM_END
},
{
FTDM_CHANNEL_STATE_HANGUP
,
FTDM_CHANNEL_STATE_TERMINATING
,
FTDM_END
},
},
},
}
}
};
};
static
__inline__
void
state_advance
(
ftdm_channel_t
*
ftdmchan
)
static
__inline__
void
state_advance
(
ftdm_channel_t
*
ftdmchan
)
{
{
pritap_t
*
pritap
=
ftdmchan
->
span
->
signal_data
;
ftdm_status_t
status
;
ftdm_status_t
status
;
ftdm_sigmsg_t
sig
;
ftdm_sigmsg_t
sig
;
q931_call
*
call
=
(
q931_call
*
)
ftdmchan
->
call_data
;
ftdm_channel_t
*
peerchan
=
ftdmchan
->
call_data
;
ftdm_log_chan
(
ftdmchan
,
FTDM_LOG_DEBUG
,
"processing state %s
\n
"
,
ftdm
chan
->
span_id
,
ftdmchan
->
chan_id
,
ftdm
_channel_state2str
(
ftdmchan
->
state
));
ftdm_log_chan
(
ftdmchan
,
FTDM_LOG_DEBUG
,
"processing state %s
\n
"
,
ftdm_channel_state2str
(
ftdmchan
->
state
));
memset
(
&
sig
,
0
,
sizeof
(
sig
));
memset
(
&
sig
,
0
,
sizeof
(
sig
));
sig
.
chan_id
=
ftdmchan
->
chan_id
;
sig
.
chan_id
=
ftdmchan
->
chan_id
;
...
@@ -264,26 +281,22 @@ static __inline__ void state_advance(ftdm_channel_t *ftdmchan)
...
@@ -264,26 +281,22 @@ static __inline__ void state_advance(ftdm_channel_t *ftdmchan)
switch
(
ftdmchan
->
state
)
{
switch
(
ftdmchan
->
state
)
{
case
FTDM_CHANNEL_STATE_DOWN
:
case
FTDM_CHANNEL_STATE_DOWN
:
{
{
ftdmchan
->
call_data
=
NULL
;
ftdm_channel_done
(
ftdmchan
);
ftdm_channel_done
(
ftdmchan
);
}
ftdmchan
->
call_data
=
NULL
;
break
;
case
FTDM_CHANNEL_STATE_PROGRESS
:
ftdm_channel_done
(
peerchan
);
{
peerchan
->
call_data
=
NULL
;
pri_progress
(
pritap
->
pri
,
call
,
ftdmchan
->
chan_id
,
1
);
}
}
break
;
break
;
case
FTDM_CHANNEL_STATE_PROGRESS
:
case
FTDM_CHANNEL_STATE_PROGRESS_MEDIA
:
case
FTDM_CHANNEL_STATE_PROGRESS_MEDIA
:
{
case
FTDM_CHANNEL_STATE_UP
:
pri_proceeding
(
pritap
->
pri
,
call
,
ftdmchan
->
chan_id
,
1
);
case
FTDM_CHANNEL_STATE_HANGUP
:
}
break
;
break
;
case
FTDM_CHANNEL_STATE_RING
:
case
FTDM_CHANNEL_STATE_RING
:
{
{
pri_acknowledge
(
pritap
->
pri
,
call
,
ftdmchan
->
chan_id
,
0
);
sig
.
event_id
=
FTDM_SIGEVENT_START
;
sig
.
event_id
=
FTDM_SIGEVENT_START
;
if
((
status
=
ftdm_span_send_signal
(
ftdmchan
->
span
,
&
sig
)
!=
FTDM_SUCCESS
))
{
if
((
status
=
ftdm_span_send_signal
(
ftdmchan
->
span
,
&
sig
)
!=
FTDM_SUCCESS
))
{
ftdm_set_state_locked
(
ftdmchan
,
FTDM_CHANNEL_STATE_HANGUP
);
ftdm_set_state_locked
(
ftdmchan
,
FTDM_CHANNEL_STATE_HANGUP
);
...
@@ -291,34 +304,15 @@ static __inline__ void state_advance(ftdm_channel_t *ftdmchan)
...
@@ -291,34 +304,15 @@ static __inline__ void state_advance(ftdm_channel_t *ftdmchan)
}
}
break
;
break
;
case
FTDM_CHANNEL_STATE_UP
:
{
pri_answer
(
pritap
->
pri
,
call
,
0
,
1
);
}
break
;
case
FTDM_CHANNEL_STATE_HANGUP
:
{
if
(
call
)
{
pri_hangup
(
pritap
->
pri
,
call
,
ftdmchan
->
caller_data
.
hangup_cause
);
pri_destroycall
(
pritap
->
pri
,
call
);
ftdm_set_state_locked
(
ftdmchan
,
FTDM_CHANNEL_STATE_DOWN
);
}
else
{
ftdm_set_state_locked
(
ftdmchan
,
FTDM_CHANNEL_STATE_RESTART
);
}
}
break
;
case
FTDM_CHANNEL_STATE_HANGUP_COMPLETE
:
break
;
case
FTDM_CHANNEL_STATE_TERMINATING
:
case
FTDM_CHANNEL_STATE_TERMINATING
:
{
{
if
(
ftdmchan
->
last_state
!=
FTDM_CHANNEL_STATE_HANGUP
)
{
sig
.
event_id
=
FTDM_SIGEVENT_STOP
;
sig
.
event_id
=
FTDM_SIGEVENT_STOP
;
status
=
ftdm_span_send_signal
(
ftdmchan
->
span
,
&
sig
);
status
=
ftdm_span_send_signal
(
ftdmchan
->
span
,
&
sig
);
}
ftdm_set_state_locked
(
ftdmchan
,
FTDM_CHANNEL_STATE_DOWN
);
ftdm_set_state_locked
(
ftdmchan
,
FTDM_CHANNEL_STATE_DOWN
);
}
}
break
;
default:
default:
{
{
...
@@ -385,28 +379,277 @@ static int pri_io_write(struct pri *pri, void *buf, int buflen)
...
@@ -385,28 +379,277 @@ static int pri_io_write(struct pri *pri, void *buf, int buflen)
return
(
int
)
buflen
;
return
(
int
)
buflen
;
}
}
static
int
tap_pri_get_crv
(
struct
pri
*
ctrl
,
q931_call
*
call
)
{
int
callmode
=
0
;
int
crv
=
pri_get_crv
(
ctrl
,
call
,
&
callmode
);
crv
<<=
3
;
crv
|=
(
callmode
&
0x7
);
return
crv
;
}
static
passive_call_t
*
tap_pri_get_pcall_bycrv
(
pritap_t
*
pritap
,
int
crv
)
{
int
i
;
int
tstcrv
;
ftdm_mutex_lock
(
pritap
->
pcalls_lock
);
for
(
i
=
0
;
i
<
ftdm_array_len
(
pritap
->
pcalls
);
i
++
)
{
tstcrv
=
pritap
->
pcalls
[
i
].
callref
?
tap_pri_get_crv
(
pritap
->
pri
,
pritap
->
pcalls
[
i
].
callref
)
:
0
;
if
(
pritap
->
pcalls
[
i
].
callref
&&
tstcrv
==
crv
)
{
if
(
!
pritap
->
pcalls
[
i
].
inuse
)
{
ftdm_log
(
FTDM_LOG_ERROR
,
"Found crv %d in slot %d of span %s with call %p but is no longer in use!
\n
"
,
crv
,
i
,
pritap
->
span
->
name
,
pritap
->
pcalls
[
i
].
callref
);
continue
;
}
ftdm_mutex_unlock
(
pritap
->
pcalls_lock
);
return
&
pritap
->
pcalls
[
i
];
}
}
ftdm_mutex_unlock
(
pritap
->
pcalls_lock
);
return
NULL
;
}
static
passive_call_t
*
tap_pri_get_pcall
(
pritap_t
*
pritap
,
void
*
callref
)
{
int
i
;
int
crv
;
ftdm_mutex_lock
(
pritap
->
pcalls_lock
);
for
(
i
=
0
;
i
<
ftdm_array_len
(
pritap
->
pcalls
);
i
++
)
{
if
(
pritap
->
pcalls
[
i
].
callref
&&
!
pritap
->
pcalls
[
i
].
inuse
)
{
crv
=
tap_pri_get_crv
(
pritap
->
pri
,
pritap
->
pcalls
[
i
].
callref
);
/* garbage collection */
ftdm_log
(
FTDM_LOG_DEBUG
,
"Garbage collecting callref %d/%p from span %s in slot %d
\n
"
,
crv
,
pritap
->
pcalls
[
i
].
callref
,
pritap
->
span
->
name
,
i
);
pri_passive_destroycall
(
pritap
->
pri
,
pritap
->
pcalls
[
i
].
callref
);
memset
(
&
pritap
->
pcalls
[
i
],
0
,
sizeof
(
pritap
->
pcalls
[
0
]));
}
if
(
callref
==
pritap
->
pcalls
[
i
].
callref
)
{
pritap
->
pcalls
[
i
].
inuse
=
1
;
ftdm_mutex_unlock
(
pritap
->
pcalls_lock
);
return
&
pritap
->
pcalls
[
i
];
}
}
ftdm_mutex_unlock
(
pritap
->
pcalls_lock
);
return
NULL
;
}
static
void
tap_pri_put_pcall
(
pritap_t
*
pritap
,
void
*
callref
)
{
int
i
;
int
crv
;
int
tstcrv
;
if
(
!
callref
)
{
ftdm_log
(
FTDM_LOG_ERROR
,
"Cannot put pcall for null callref in span %s
\n
"
,
pritap
->
span
->
name
);
return
;
}
ftdm_mutex_lock
(
pritap
->
pcalls_lock
);
crv
=
tap_pri_get_crv
(
pritap
->
pri
,
callref
);
for
(
i
=
0
;
i
<
ftdm_array_len
(
pritap
->
pcalls
);
i
++
)
{
if
(
!
pritap
->
pcalls
[
i
].
callref
)
{
continue
;
}
tstcrv
=
tap_pri_get_crv
(
pritap
->
pri
,
pritap
->
pcalls
[
i
].
callref
);
if
(
tstcrv
==
crv
)
{
ftdm_log
(
FTDM_LOG_DEBUG
,
"releasing slot %d in span %s used by callref %d/%p
\n
"
,
i
,
pritap
->
span
->
name
,
crv
,
pritap
->
pcalls
[
i
].
callref
);
if
(
!
pritap
->
pcalls
[
i
].
inuse
)
{
ftdm_log
(
FTDM_LOG_ERROR
,
"slot %d in span %s used by callref %d/%p was released already?
\n
"
,
i
,
pritap
->
span
->
name
,
crv
,
pritap
->
pcalls
[
i
].
callref
);
}
pritap
->
pcalls
[
i
].
inuse
=
0
;
}
}
ftdm_mutex_unlock
(
pritap
->
pcalls_lock
);
}
static
__inline__
ftdm_channel_t
*
tap_pri_get_fchan
(
pritap_t
*
pritap
,
passive_call_t
*
pcall
,
int
channel
)
{
ftdm_channel_t
*
fchan
=
NULL
;
int
chanpos
=
PRI_CHANNEL
(
channel
);
if
(
!
chanpos
||
chanpos
>
pritap
->
span
->
chan_count
)
{
ftdm_log
(
FTDM_LOG_CRIT
,
"Invalid pri tap channel %d requested in span %s
\n
"
,
channel
,
pritap
->
span
->
name
);
return
NULL
;
}
fchan
=
pritap
->
span
->
channels
[
PRI_CHANNEL
(
channel
)];
if
(
ftdm_test_flag
(
fchan
,
FTDM_CHANNEL_INUSE
))
{
ftdm_log
(
FTDM_LOG_ERROR
,
"Channel %d requested in span %s is already in use!
\n
"
,
channel
,
pritap
->
span
->
name
);
return
NULL
;
}
if
(
ftdm_channel_open_chan
(
fchan
)
!=
FTDM_SUCCESS
)
{
ftdm_log
(
FTDM_LOG_ERROR
,
"Could not open tap channel %d requested in span %s
\n
"
,
channel
,
pritap
->
span
->
name
);
return
NULL
;
}
memset
(
&
fchan
->
caller_data
,
0
,
sizeof
(
fchan
->
caller_data
));
ftdm_set_string
(
fchan
->
caller_data
.
cid_num
.
digits
,
pcall
->
callingnum
.
digits
);
if
(
!
ftdm_strlen_zero
(
pcall
->
callingname
))
{
ftdm_set_string
(
fchan
->
caller_data
.
cid_name
,
pcall
->
callingname
);
}
else
{
ftdm_set_string
(
fchan
->
caller_data
.
cid_name
,
pcall
->
callingnum
.
digits
);
}
ftdm_set_string
(
fchan
->
caller_data
.
ani
.
digits
,
pcall
->
callingani
.
digits
);
ftdm_set_string
(
fchan
->
caller_data
.
dnis
.
digits
,
pcall
->
callednum
.
digits
);
return
fchan
;
}
static
void
handle_pri_passive_event
(
pritap_t
*
pritap
,
pri_event
*
e
)
static
void
handle_pri_passive_event
(
pritap_t
*
pritap
,
pri_event
*
e
)
{
{
ftdm_log
(
FTDM_LOG_NOTICE
,
"passive event %s on span %s
\n
"
,
pri_event2str
(
e
->
gen
.
e
),
pritap
->
span
->
name
);
passive_call_t
*
pcall
=
NULL
;
passive_call_t
*
peerpcall
=
NULL
;
ftdm_channel_t
*
fchan
=
NULL
;
ftdm_channel_t
*
peerfchan
=
NULL
;
int
layer1
,
transcap
=
0
;
int
crv
=
0
;
pritap_t
*
peertap
=
pritap
->
peerspan
->
signal_data
;
switch
(
e
->
e
)
{
switch
(
e
->
e
)
{
case
PRI_EVENT_RING
:
case
PRI_EVENT_RING
:
/* we cannot use ftdm_channel_t because we still dont know which channel will be used
* (ie, flexible channel was requested), thus, we need our own list of call references */
crv
=
tap_pri_get_crv
(
pritap
->
pri
,
e
->
ring
.
call
);
ftdm_log
(
FTDM_LOG_DEBUG
,
"Ring on channel %s:%d:%d with callref %d
\n
"
,
pritap
->
span
->
name
,
PRI_SPAN
(
e
->
ring
.
channel
),
PRI_CHANNEL
(
e
->
ring
.
channel
),
crv
);
pcall
=
tap_pri_get_pcall_bycrv
(
pritap
,
crv
);
if
(
pcall
)
{
ftdm_log
(
FTDM_LOG_WARNING
,
"There is a call with callref %d already, ignoring duplicated ring event
\n
"
,
crv
);
break
;
}
pcall
=
tap_pri_get_pcall
(
pritap
,
NULL
);
if
(
!
pcall
)
{
ftdm_log
(
FTDM_LOG_ERROR
,
"Failed to get a free passive PRI call slot for callref %d, this is a bug!
\n
"
,
crv
);
break
;
}
pcall
->
callref
=
e
->
ring
.
call
;
ftdm_set_string
(
pcall
->
callingnum
.
digits
,
e
->
ring
.
callingnum
);
ftdm_set_string
(
pcall
->
callingani
.
digits
,
e
->
ring
.
callingani
);
ftdm_set_string
(
pcall
->
callednum
.
digits
,
e
->
ring
.
callednum
);
ftdm_set_string
(
pcall
->
callingname
,
e
->
ring
.
callingname
);
break
;
break
;
case
PRI_EVENT_PROGRESS
:
case
PRI_EVENT_PROGRESS
:
crv
=
tap_pri_get_crv
(
pritap
->
pri
,
e
->
ring
.
call
);
ftdm_log
(
FTDM_LOG_DEBUG
,
"Progress on channel %s:%d:%d with callref %d
\n
"
,
pritap
->
span
->
name
,
PRI_SPAN
(
e
->
proceeding
.
channel
),
PRI_CHANNEL
(
e
->
proceeding
.
channel
),
crv
);
break
;
break
;
case
PRI_EVENT_PROCEEDING
:
case
PRI_EVENT_PROCEEDING
:
crv
=
tap_pri_get_crv
(
pritap
->
pri
,
e
->
proceeding
.
call
);
/* at this point we should know the real b chan that will be used and can therefore proceed to notify about the call, but
* only if a couple of call tests are passed first */
ftdm_log
(
FTDM_LOG_DEBUG
,
"Proceeding on channel %s:%d:%d with callref %d
\n
"
,
pritap
->
span
->
name
,
PRI_SPAN
(
e
->
proceeding
.
channel
),
PRI_CHANNEL
(
e
->
proceeding
.
channel
),
crv
);
/* check that we already know about this call in the peer PRI (which was the one receiving the PRI_EVENT_RING event) */
if
(
!
(
pcall
=
tap_pri_get_pcall_bycrv
(
peertap
,
crv
)))
{
ftdm_log
(
FTDM_LOG_DEBUG
,
"ignoring proceeding in channel %s:%d:%d for callref %d since we don't know about it"
,
pritap
->
span
->
name
,
PRI_SPAN
(
e
->
proceeding
.
channel
),
PRI_CHANNEL
(
e
->
proceeding
.
channel
),
crv
);
break
;
}
if
(
pcall
->
proceeding
)
{
ftdm_log
(
FTDM_LOG_DEBUG
,
"Ignoring duplicated proceeding with callref %d
\n
"
,
crv
);
break
;
}
peerpcall
=
tap_pri_get_pcall
(
pritap
,
NULL
);
if
(
!
peerpcall
)
{
ftdm_log
(
FTDM_LOG_ERROR
,
"Failed to get a free peer PRI passive call slot for callref %d in span %s, this is a bug!
\n
"
,
crv
,
pritap
->
span
->
name
);
break
;
}
peerpcall
->
callref
=
e
->
proceeding
.
call
;
/* check that the layer 1 and trans capability are supported */
layer1
=
pri_get_layer1
(
peertap
->
pri
,
pcall
->
callref
);
transcap
=
pri_get_transcap
(
peertap
->
pri
,
pcall
->
callref
);
if
(
PRI_LAYER_1_ULAW
!=
layer1
&&
PRI_LAYER_1_ALAW
!=
layer1
)
{
ftdm_log
(
FTDM_LOG_NOTICE
,
"Not monitoring callref %d with unsupported layer 1 format %d
\n
"
,
crv
,
layer1
);
break
;
}
if
(
transcap
!=
PRI_TRANS_CAP_SPEECH
&&
transcap
!=
PRI_TRANS_CAP_3_1K_AUDIO
&&
transcap
!=
PRI_TRANS_CAP_7K_AUDIO
)
{
ftdm_log
(
FTDM_LOG_NOTICE
,
"Not monitoring callref %d with unsupported capability %d
\n
"
,
crv
,
transcap
);
break
;
}
fchan
=
tap_pri_get_fchan
(
pritap
,
pcall
,
e
->
proceeding
.
channel
);
if
(
!
fchan
)
{
ftdm_log
(
FTDM_LOG_ERROR
,
"Proceeding requested on odd/unavailable channel %s:%d:%d for callref %d
\n
"
,
pritap
->
span
->
name
,
PRI_SPAN
(
e
->
proceeding
.
channel
),
PRI_CHANNEL
(
e
->
proceeding
.
channel
),
crv
);
break
;
}
pcall
->
fchan
=
fchan
;
peerfchan
=
tap_pri_get_fchan
(
peertap
,
pcall
,
e
->
proceeding
.
channel
);
if
(
!
peerfchan
)
{
ftdm_log
(
FTDM_LOG_ERROR
,
"Proceeding requested on odd/unavailable channel %s:%d:%d for callref %d
\n
"
,
peertap
->
span
->
name
,
PRI_SPAN
(
e
->
proceeding
.
channel
),
PRI_CHANNEL
(
e
->
proceeding
.
channel
),
crv
);
break
;
}
peerpcall
->
fchan
=
fchan
;
fchan
->
call_data
=
peerfchan
;
peerfchan
->
call_data
=
fchan
;
ftdm_set_state_locked
(
fchan
,
FTDM_CHANNEL_STATE_RING
);
break
;
break
;
case
PRI_EVENT_ANSWER
:
case
PRI_EVENT_ANSWER
:
crv
=
tap_pri_get_crv
(
pritap
->
pri
,
e
->
answer
.
call
);
ftdm_log
(
FTDM_LOG_DEBUG
,
"Answer on channel %s:%d:%d with callref %d
\n
"
,
pritap
->
span
->
name
,
PRI_SPAN
(
e
->
answer
.
channel
),
PRI_CHANNEL
(
e
->
answer
.
channel
),
crv
);
if
(
!
(
pcall
=
tap_pri_get_pcall_bycrv
(
pritap
,
crv
)))
{
ftdm_log
(
FTDM_LOG_DEBUG
,
"ignoring answer in channel %s:%d:%d for callref %d since we don't know about it"
,
pritap
->
span
->
name
,
PRI_SPAN
(
e
->
proceeding
.
channel
),
PRI_CHANNEL
(
e
->
proceeding
.
channel
),
crv
);
break
;
}
ftdm_log_chan
(
pcall
->
fchan
,
FTDM_LOG_NOTICE
,
"Tapped call was answered in state %s
\n
"
,
ftdm_channel_state2str
(
pcall
->
fchan
->
state
));
break
;
case
PRI_EVENT_HANGUP_REQ
:
crv
=
tap_pri_get_crv
(
pritap
->
pri
,
e
->
hangup
.
call
);
ftdm_log
(
FTDM_LOG_DEBUG
,
"Hangup on channel %s:%d:%d with callref %d
\n
"
,
pritap
->
span
->
name
,
PRI_SPAN
(
e
->
answer
.
channel
),
PRI_CHANNEL
(
e
->
answer
.
channel
),
crv
);
if
(
!
(
pcall
=
tap_pri_get_pcall_bycrv
(
pritap
,
crv
)))
{
ftdm_log
(
FTDM_LOG_DEBUG
,
"ignoring hangup in channel %s:%d:%d for callref %d since we don't know about it"
,
pritap
->
span
->
name
,
PRI_SPAN
(
e
->
proceeding
.
channel
),
PRI_CHANNEL
(
e
->
proceeding
.
channel
),
crv
);
break
;
break
;
}
case
PRI_EVENT_HANGUP
:
fchan
=
pcall
->
fchan
;
ftdm_set_state_locked
(
fchan
,
FTDM_CHANNEL_STATE_TERMINATING
);
break
;
break
;
case
PRI_EVENT_HANGUP_ACK
:
case
PRI_EVENT_HANGUP_ACK
:
crv
=
tap_pri_get_crv
(
pritap
->
pri
,
e
->
hangup
.
call
);
ftdm_log
(
FTDM_LOG_DEBUG
,
"Hangup ack on channel %s:%d:%d with callref %d
\n
"
,
pritap
->
span
->
name
,
PRI_SPAN
(
e
->
answer
.
channel
),
PRI_CHANNEL
(
e
->
answer
.
channel
),
crv
);
tap_pri_put_pcall
(
pritap
,
e
->
hangup
.
call
);
tap_pri_put_pcall
(
peertap
,
e
->
hangup
.
call
);
break
;
break
;
default:
default:
...
@@ -502,6 +745,7 @@ static ftdm_status_t ftdm_pritap_stop(ftdm_span_t *span)
...
@@ -502,6 +745,7 @@ static ftdm_status_t ftdm_pritap_stop(ftdm_span_t *span)
ftdm_sleep
(
100
);
ftdm_sleep
(
100
);
}
}
ftdm_mutex_destroy
(
&
pritap
->
pcalls_lock
);
return
FTDM_SUCCESS
;
return
FTDM_SUCCESS
;
}
}
...
@@ -514,6 +758,8 @@ static ftdm_status_t ftdm_pritap_start(ftdm_span_t *span)
...
@@ -514,6 +758,8 @@ static ftdm_status_t ftdm_pritap_start(ftdm_span_t *span)
return
FTDM_FAIL
;
return
FTDM_FAIL
;
}
}
ftdm_mutex_create
(
&
pritap
->
pcalls_lock
);
ftdm_clear_flag
(
span
,
FTDM_SPAN_STOP_THREAD
);
ftdm_clear_flag
(
span
,
FTDM_SPAN_STOP_THREAD
);
ftdm_clear_flag
(
span
,
FTDM_SPAN_IN_THREAD
);
ftdm_clear_flag
(
span
,
FTDM_SPAN_IN_THREAD
);
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论