bugfix and improvements.

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@15227 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Georgiewskiy Yuriy 2009-10-26 16:40:11 +00:00
parent 052816bc32
commit f07564b0e7
5 changed files with 253 additions and 63 deletions

View File

@ -1,5 +1,7 @@
BASE=../../../.. BASE=../../../..
LOCAL_CFLAGS+=-g -I/usr/include/ptlib -I/usr/local/src/h323plus/include -I. -DPTRACING=1 -D_REENTRANT -fno-exceptions LOCAL_CFLAGS+=-g -ggdb -I/usr/include/ptlib -I/usr/include/openh323 -I. -DPTRACING=1 -D_REENTRANT -fno-exceptions
LOCAL_LDFLAGS= -L/usr/local/src/h323plus/lib -lh323_linux_x86_ -lpt -lrt LOCAL_LDFLAGS= -lopenh323 -lpt -lrt
include $(BASE)/build/modmake.rules include $(BASE)/build/modmake.rules

View File

@ -1,4 +1,10 @@
implement jitter-size value option.
implement gk register retry timer.
implement h245insetup enable/disable option.
implement h245tunneling enable/disable option.
implement faststart enable/disable option.
fix release handling from h323 leg.
fix misstype in codec conversion. fix misstype in codec conversion.
fix rtp issue causes choppy sound. fix rtp issue causes choppy sound.
fix progress ind handling on outbound calls. fix progress ind handling on outbound calls.

View File

@ -7,6 +7,11 @@
<param name="gk-address" value=""/> <!-- empty to disable, "*" to search LAN --> <param name="gk-address" value=""/> <!-- empty to disable, "*" to search LAN -->
<param name="gk-identifer" value=""/> <!-- optional name of gk --> <param name="gk-identifer" value=""/> <!-- optional name of gk -->
<param name="gk-interface" value=""/> <!-- optional listener interface name --> <param name="gk-interface" value=""/> <!-- optional listener interface name -->
<param name="gk-retry" value="30"/> <!-- optional GK register retry timer -->
<param name="faststart" value="true"/> <!-- optional -->
<param name="h245tunneling" value="true"/> <!-- optional -->
<param name="h245insetup" value="true"/> <!-- optional -->
<param name="jitter-size" value="60"/> <!-- optional -->
</settings> </settings>
<listeners> <listeners>
<listener name="default"> <listener name="default">

View File

@ -1,4 +1,6 @@
/*
Version 0.0.8
*/
#include "mod_h323.h" #include "mod_h323.h"
@ -239,36 +241,41 @@ class FSTrace : public ostream {
#endif #endif
PString GetH245CodecName(const H245_AudioCapability &cap){ PString GetH245CodecName(const H323Capability* cap){
switch (cap.GetTag()) {
case H245_AudioCapability::e_g711Alaw64k: switch (cap->GetSubType()) {
case H245_AudioCapability::e_g711Alaw56k: case H245_AudioCapability::e_g711Alaw64k:
return "PCMA"; case H245_AudioCapability::e_g711Alaw56k:
case H245_AudioCapability::e_g711Ulaw64k: return "PCMA";
case H245_AudioCapability::e_g711Ulaw56k: case H245_AudioCapability::e_g711Ulaw64k:
return "PCMU"; case H245_AudioCapability::e_g711Ulaw56k:
case H245_AudioCapability::e_g722_64k: return "PCMU";
case H245_AudioCapability::e_g722_56k: case H245_AudioCapability::e_g722_64k:
case H245_AudioCapability::e_g722_48k: case H245_AudioCapability::e_g722_56k:
return "G722"; case H245_AudioCapability::e_g722_48k:
case H245_AudioCapability::e_g728: return "G722";
return "G728"; case H245_AudioCapability::e_g728:
case H245_AudioCapability::e_g729: return "G728";
case H245_AudioCapability::e_g729AnnexA: case H245_AudioCapability::e_g729:
case H245_AudioCapability::e_g729wAnnexB: case H245_AudioCapability::e_g729AnnexA:
case H245_AudioCapability::e_g729AnnexAwAnnexB: case H245_AudioCapability::e_g729wAnnexB:
return "G729"; case H245_AudioCapability::e_g729AnnexAwAnnexB:
case H245_AudioCapability::e_g7231: return "G729";
case H245_AudioCapability::e_g7231AnnexCCapability: case H245_AudioCapability::e_g7231:
return "G723"; case H245_AudioCapability::e_g7231AnnexCCapability:
case H245_AudioCapability::e_gsmFullRate: return "G723";
case H245_AudioCapability::e_gsmHalfRate: case H245_AudioCapability::e_gsmFullRate:
case H245_AudioCapability::e_gsmEnhancedFullRate: case H245_AudioCapability::e_gsmHalfRate:
return "GSM"; case H245_AudioCapability::e_gsmEnhancedFullRate:
return "GSM";
case H245_AudioCapability::e_nonStandard:{
if (cap->GetFormatName().Find("726-40")) return "G726-40";
}
} }
return "Unknown"; return "Unknown";
} }
FSProcess::FSProcess() FSProcess::FSProcess()
: PLibraryProcess("Test", "mod_h323", 1, 0, AlphaCode, 1) : PLibraryProcess("Test", "mod_h323", 1, 0, AlphaCode, 1)
, m_h323endpoint(NULL){ , m_h323endpoint(NULL){
@ -302,6 +309,8 @@ bool FSH323EndPoint::Initialise(switch_loadable_module_interface_t *iface){
PString codec = ((const char *)mod_h323_globals.codec_string); PString codec = ((const char *)mod_h323_globals.codec_string);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Config capabilliti %s \n",(const char *)codec); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Config capabilliti %s \n",(const char *)codec);
if (!codec.IsEmpty()) { if (!codec.IsEmpty()) {
const char** f = h323_formats; const char** f = h323_formats;
for (; *f; f += 2) { for (; *f; f += 2) {
@ -329,10 +338,16 @@ bool FSH323EndPoint::Initialise(switch_loadable_module_interface_t *iface){
} }
} }
// AddAllCapabilities(0, 0, "*");
AddAllUserInputCapabilities(0,1); AddAllUserInputCapabilities(0,1);
PTRACE(1, "OpenPhone\tCapability Table:\n" << setprecision(4) << capabilities); PTRACE(1, "OpenPhone\tCapability Table:\n" << setprecision(4) << capabilities);
DisableFastStart(!m_faststart);
DisableH245Tunneling(!m_h245tunneling);
DisableH245inSetup(!m_h245insetup);
if (m_listeners.empty()) { if (m_listeners.empty()) {
StartListener(""); StartListener("");
} else { } else {
@ -353,7 +368,11 @@ bool FSH323EndPoint::Initialise(switch_loadable_module_interface_t *iface){
} }
*/ */
if (!m_gkAddress.IsEmpty()) { if (!m_gkAddress.IsEmpty() && !m_gkIdentifer.IsEmpty() && !m_gkInterface.IsEmpty()) {
m_thread = new FSGkRegThread(this,&m_gkAddress,&m_gkIdentifer,&m_gkInterface,m_gkretry);
m_thread->SetAutoDelete();
m_thread->Resume();
/*
if (UseGatekeeper(m_gkAddress, m_gkIdentifer, m_gkInterface)) if (UseGatekeeper(m_gkAddress, m_gkIdentifer, m_gkInterface))
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Started gatekeeper: %s\n", switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Started gatekeeper: %s\n",
(const char *)GetGatekeeper()->GetName()); (const char *)GetGatekeeper()->GetName());
@ -363,8 +382,9 @@ bool FSH323EndPoint::Initialise(switch_loadable_module_interface_t *iface){
(const char *)m_gkAddress, (const char *)m_gkAddress,
(const char *)m_gkIdentifer, (const char *)m_gkIdentifer,
(const char *)m_gkInterface); (const char *)m_gkInterface);
*/
} }
return TRUE; return TRUE;
} }
@ -422,6 +442,12 @@ switch_status_t FSH323EndPoint::ReadConfig(int reload){
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Set zero Jitter buffer\n"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Set zero Jitter buffer\n");
SetAudioJitterDelay(0, 0); SetAudioJitterDelay(0, 0);
} }
} else if (!strcasecmp(var, "faststart")) {
m_faststart = switch_true(val);
} else if (!strcasecmp(var, "h245tunneling")) {
m_h245tunneling = switch_true(val);
} else if (!strcasecmp(var, "h245insetup")) {
m_h245insetup = switch_true(val);
} else if (!strcasecmp(var, "gk-address")) { } else if (!strcasecmp(var, "gk-address")) {
m_gkAddress = val; m_gkAddress = val;
} else if (!strcasecmp(var, "gk-identifer")) { } else if (!strcasecmp(var, "gk-identifer")) {
@ -430,7 +456,10 @@ switch_status_t FSH323EndPoint::ReadConfig(int reload){
m_gkInterface = val; m_gkInterface = val;
} else if (!strcasecmp(var, "gk-prefix")) { } else if (!strcasecmp(var, "gk-prefix")) {
m_gkPrefixes.AppendString(val); m_gkPrefixes.AppendString(val);
} } else if (!strcasecmp(var, "gk-retry")) {
m_gkretry = atoi(val);
}
} }
} }
@ -471,11 +500,20 @@ switch_status_t FSH323EndPoint::ReadConfig(int reload){
return status; return status;
} }
FSH323EndPoint::FSH323EndPoint(){ FSH323EndPoint::FSH323EndPoint()
PTRACE(4, "mod_h323\t======>FSH323EndPoint::FSH323EndPoint " << *this); :m_faststart(true)
,m_h245tunneling(true)
,m_h245insetup(true)
{
PTRACE(4, "mod_h323\t======>FSH323EndPoint::FSH323EndPoint [" << *this<<"]");
terminalType = e_GatewayOnly; terminalType = e_GatewayOnly;
} }
FSH323EndPoint::~FSH323EndPoint(){
PTRACE(4, "mod_h323\t======>FSH323EndPoint::~FSH323EndPoint [" << *this<<"]");
StopGkClient();
}
H323Connection *FSH323EndPoint::CreateConnection( H323Connection *FSH323EndPoint::CreateConnection(
unsigned callReference, unsigned callReference,
void* userData, void* userData,
@ -516,14 +554,43 @@ bool FSH323EndPoint::OnSetGatewayPrefixes(PStringList & prefixes) const{
return false; return false;
} }
void FSH323EndPoint::StartGkClient(int retry, PString* gkAddress,PString* gkIdentifer,PString* gkInterface){
PTRACE(4, "mod_h323\t======>FSH323EndPoint::StartGkClient [" << *this<<"]");
while(!UseGatekeeper(m_gkAddress, m_gkIdentifer, m_gkInterface) && retry > 0 ){
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
"Could not start gatekeeper: addr=\"%s\", id=\"%s\", if=\"%s\"\n",
(const char *)m_gkAddress,
(const char *)m_gkIdentifer,
(const char *)m_gkInterface);
switch_yield(retry*1000);
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Started gatekeeper: %s\n",
(const char *)GetGatekeeper()->GetName());
m_thread = 0;
}
void FSH323EndPoint::StopGkClient(){
PTRACE(4, "mod_h323\t======> FSH323EndPoint::StopGkClient [" << *this<<"]");
if (m_thread) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Started gatekeeper thread\n");
RemoveGatekeeper();
m_thread->Terminate();
m_thread = 0;
}
}
FSH323Connection::FSH323Connection(FSH323EndPoint& endpoint, H323Transport* transport, unsigned callReference, switch_caller_profile_t *outbound_profile, switch_core_session_t *fsSession, switch_channel_t *fsChannel) FSH323Connection::FSH323Connection(FSH323EndPoint& endpoint, H323Transport* transport, unsigned callReference, switch_caller_profile_t *outbound_profile, switch_core_session_t *fsSession, switch_channel_t *fsChannel)
: H323Connection(endpoint,callReference) : H323Connection(endpoint,callReference)
, m_endpoint(&endpoint) , m_endpoint(&endpoint)
, m_fsSession(fsSession) , m_fsSession(fsSession)
, m_fsChannel(fsChannel) , m_fsChannel(fsChannel)
, m_callOnPreAnswer(false) , m_callOnPreAnswer(false)
, m_startRTP(false){ , m_startRTP(false)
PTRACE(4, "mod_h323\t======>FSH323Connection::FSH323Connection " << *this); , m_rxChennel(false)
, m_txChennel(false)
, m_ChennelAnswer(false)
, m_ChennelProgress(false){
PTRACE(4, "mod_h323\t======>FSH323Connection::FSH323Connection [" << *this<<"]");
h323_private_t *tech_pvt = (h323_private_t *) switch_core_session_alloc(m_fsSession, sizeof(*tech_pvt)); h323_private_t *tech_pvt = (h323_private_t *) switch_core_session_alloc(m_fsSession, sizeof(*tech_pvt));
tech_pvt->me = this; tech_pvt->me = this;
@ -720,7 +787,7 @@ H323Connection::AnswerCallResponse FSH323Connection::OnAnswerCall(const PString
} }
H323Channel* FSH323Connection::CreateRealTimeLogicalChannel(const H323Capability& capability,H323Channel::Directions dir,unsigned sessionID,const H245_H2250LogicalChannelParameters* param, RTP_QOS * rtpqos){ H323Channel* FSH323Connection::CreateRealTimeLogicalChannel(const H323Capability& capability,H323Channel::Directions dir,unsigned sessionID,const H245_H2250LogicalChannelParameters* param, RTP_QOS * rtpqos){
PTRACE(4, "mod_h323\t======>FSH323Connection::CreateRealTimeLogicalChannel " << *this); PTRACE(4, "mod_h323\t======>FSH323Connection::CreateRealTimeLogicalChannel [" << *this<<"]");
H323TransportAddress m_h323transportadd = GetSignallingChannel()->GetLocalAddress(); H323TransportAddress m_h323transportadd = GetSignallingChannel()->GetLocalAddress();
m_h323transportadd.GetIpAddress(m_RTPlocalIP); m_h323transportadd.GetIpAddress(m_RTPlocalIP);
@ -729,14 +796,14 @@ H323Channel* FSH323Connection::CreateRealTimeLogicalChannel(const H323Capability
} }
PBoolean FSH323Connection::OnStartLogicalChannel(H323Channel & channel){ PBoolean FSH323Connection::OnStartLogicalChannel(H323Channel & channel){
PTRACE(4, "mod_h323\t======>FSH323Connection::OnStartLogicalChannel chennel = "<<&channel<<", "<<*this); PTRACE(4, "mod_h323\t======>FSH323Connection::OnStartLogicalChannel chennel = "<<&channel<<" ["<<*this<<"]");
// return H323Connection::OnStartLogicalChannel(channel); // return H323Connection::OnStartLogicalChannel(channel);
return true; return true;
} }
PBoolean FSH323Connection::OnCreateLogicalChannel(const H323Capability& capability, H323Channel::Directions dir, unsigned& errorCode){ PBoolean FSH323Connection::OnCreateLogicalChannel(const H323Capability& capability, H323Channel::Directions dir, unsigned& errorCode){
PTRACE(4, "mod_h323\t======>FSH323Connection::OnCreateLogicalChannel ('"<< (const char *)capability.GetFormatName()<<"',"<<dir<<") "<<*this); PTRACE(4, "mod_h323\t======>FSH323Connection::OnCreateLogicalChannel ('"<< (const char *)capability.GetFormatName()<<"',"<<dir<<") ["<<*this<<"]");
return H323Connection::OnCreateLogicalChannel(capability,dir,errorCode); return H323Connection::OnCreateLogicalChannel(capability,dir,errorCode);
} }
@ -753,9 +820,12 @@ void FSH323Connection::OnReceivedReleaseComplete(const H323SignalPDU & pdu){
bool FSH323Connection::OnReceivedProgress(const H323SignalPDU &pdu) bool FSH323Connection::OnReceivedProgress(const H323SignalPDU &pdu)
{ {
PTRACE(4, "mod_h323\t======>FSH323Connection::OnReceivedProgress"); PTRACE(4, "mod_h323\t======>FSH323Connection::OnReceivedProgress ["<<*this<<"]");
m_txAudioOpened.Wait(); if ((m_rxChennel && m_txChennel) || (m_ChennelProgress && m_rxChennel))
switch_channel_mark_pre_answered(m_fsChannel); switch_channel_mark_pre_answered(m_fsChannel);
else{
m_ChennelProgress = true;
}
return true; return true;
} }
@ -810,8 +880,9 @@ bool FSH323Connection::OnAlerting(const H323SignalPDU &alertingPDU, const PStrin
void FSH323Connection::OnEstablished(){ void FSH323Connection::OnEstablished(){
PTRACE(4, "mod_h323\t======>PFSH323Connection::OnEstablished ["<<*this<<"]"); PTRACE(4, "mod_h323\t======>PFSH323Connection::OnEstablished ["<<*this<<"]");
if(m_startRTP)
switch_channel_mark_answered(m_fsChannel); switch_channel_mark_answered(m_fsChannel);
else m_ChennelAnswer = true;
} }
@ -819,26 +890,26 @@ void FSH323Connection::OnEstablished(){
void FSH323Connection::setRemoteAddress(const char* remoteIP, WORD remotePort){ void FSH323Connection::setRemoteAddress(const char* remoteIP, WORD remotePort){
PTRACE(4, "mod_h323\t======>PFSH323Connection::setRemoteAddress remoteIP ="<<remoteIP<<", remotePort = "<<remotePort<<" "<<*this); PTRACE(4, "mod_h323\t======>PFSH323Connection::setRemoteAddress remoteIP ="<<remoteIP<<", remotePort = "<<remotePort<<" "<<*this);
if (!m_remotePort) { if (!m_remotePort) {
PTRACE(4, "mod_h323\tGot remote RTP address "<<remoteIP<<":"<<remotePort<<" "<<*this); PTRACE(4, "mod_h323\tGot remote RTP address "<<remoteIP<<":"<<remotePort<<" ["<<*this<<"]");
m_remotePort = remotePort; m_remotePort = remotePort;
m_remoteAddr = remoteIP; m_remoteAddr = remoteIP;
} }
} }
switch_status_t FSH323Connection::on_execute(){ switch_status_t FSH323Connection::on_execute(){
PTRACE(4, "mod_h323\t======>FSH323Connection::on_execute " << *this); PTRACE(4, "mod_h323\t======>FSH323Connection::on_execute [" << *this<<"]");
return SWITCH_STATUS_SUCCESS; return SWITCH_STATUS_SUCCESS;
} }
switch_status_t FSH323Connection::on_routing(){ switch_status_t FSH323Connection::on_routing(){
PTRACE(4, "mod_h323\t======>FSH323Connection::on_routing " << *this); PTRACE(4, "mod_h323\t======>FSH323Connection::on_routing ["<< *this<<"]");
return SWITCH_STATUS_SUCCESS; return SWITCH_STATUS_SUCCESS;
} }
switch_status_t FSH323Connection::kill_channel(int sig){ switch_status_t FSH323Connection::kill_channel(int sig){
PTRACE(4, "mod_h323\t======>FSH323Connection::kill_channel " << *this); PTRACE(4, "mod_h323\t======>FSH323Connection::kill_channel ["<< *this<<"]");
PTRACE(3, "mod_h323\tKill " << sig << " on connection " << *this); PTRACE(3, "mod_h323\tKill " << sig << " on connection " << *this);
h323_private_t *tech_pvt = (h323_private_t *) switch_core_session_get_private(m_fsSession); h323_private_t *tech_pvt = (h323_private_t *) switch_core_session_get_private(m_fsSession);
@ -1004,13 +1075,12 @@ switch_status_t FSH323Connection::read_audio_frame(switch_frame_t **frame, switc
} else { } else {
switch_core_timer_next(&tech_pvt->read_timer); switch_core_timer_next(&tech_pvt->read_timer);
} }
*/ */
switch_set_flag_locked(tech_pvt, TFLAG_READING); switch_set_flag_locked(tech_pvt, TFLAG_READING);
if (!switch_channel_ready(m_fsChannel)) { if (!switch_channel_ready(m_fsChannel)) {
PTRACE(4, "mod_h323\t---------> RETURN"); PTRACE(4, "mod_h323\t---------> RETURN");
switch_clear_flag_locked(tech_pvt, TFLAG_READING); switch_clear_flag_locked(tech_pvt, TFLAG_READING);
return SWITCH_STATUS_FALSE; return SWITCH_STATUS_FALSE;
} }
if (!switch_core_codec_ready(&tech_pvt->read_codec )) { if (!switch_core_codec_ready(&tech_pvt->read_codec )) {
@ -1019,7 +1089,6 @@ switch_status_t FSH323Connection::read_audio_frame(switch_frame_t **frame, switc
return SWITCH_STATUS_FALSE; return SWITCH_STATUS_FALSE;
} }
//switch_core_timer_step(&m_switchTimer);
switch_status_t status = switch_rtp_zerocopy_read_frame(tech_pvt->rtp_session, &tech_pvt->read_frame, flags); switch_status_t status = switch_rtp_zerocopy_read_frame(tech_pvt->rtp_session, &tech_pvt->read_frame, flags);
@ -1043,11 +1112,10 @@ switch_status_t FSH323Connection::read_audio_frame(switch_frame_t **frame, switc
tech_pvt->read_frame.codec = &tech_pvt->read_codec ; tech_pvt->read_frame.codec = &tech_pvt->read_codec ;
} }
switch_clear_flag_locked(tech_pvt, TFLAG_READING); switch_clear_flag_locked(tech_pvt, TFLAG_READING);
*frame = &tech_pvt->read_frame; *frame = &tech_pvt->read_frame;
return SWITCH_STATUS_SUCCESS; return SWITCH_STATUS_SUCCESS;
} }
switch_status_t FSH323Connection::write_audio_frame(switch_frame_t *frame, switch_io_flag_t flags, int stream_id){ switch_status_t FSH323Connection::write_audio_frame(switch_frame_t *frame, switch_io_flag_t flags, int stream_id){
@ -1184,7 +1252,7 @@ PBoolean FSH323_ExternalRTPChannel::Start(){
PTRACE(4, "mod_h323\t------------------->m_capability->GetTxFramesInPacket() return = "<<m_capability->GetTxFramesInPacket()); PTRACE(4, "mod_h323\t------------------->m_capability->GetTxFramesInPacket() return = "<<m_capability->GetTxFramesInPacket());
PTRACE(4, "mod_h323\t------------------->m_capability->GetFormatName() return = "<<m_capability->GetFormatName()); PTRACE(4, "mod_h323\t------------------->m_capability->GetFormatName() return = "<<m_capability->GetFormatName());
PTRACE(4, "mod_h323\t------------------->GetH245CodecName() return = "<<GetH245CodecName(m_capability->GetSubType())); PTRACE(4, "mod_h323\t------------------->GetH245CodecName() return = "<<GetH245CodecName(m_capability));
@ -1193,8 +1261,10 @@ PBoolean FSH323_ExternalRTPChannel::Start(){
if (GetDirection() == IsReceiver){ if (GetDirection() == IsReceiver){
m_switchCodec = isAudio ? &tech_pvt->read_codec : &tech_pvt->vid_read_codec; m_switchCodec = isAudio ? &tech_pvt->read_codec : &tech_pvt->vid_read_codec;
m_switchTimer = isAudio ? &tech_pvt->read_timer : &tech_pvt->vid_read_timer; m_switchTimer = isAudio ? &tech_pvt->read_timer : &tech_pvt->vid_read_timer;
m_conn->m_rxChennel = true;
}else{ }else{
m_switchCodec = isAudio ? &tech_pvt->write_codec : &tech_pvt->vid_write_codec; m_switchCodec = isAudio ? &tech_pvt->write_codec : &tech_pvt->vid_write_codec;
m_conn->m_txChennel = true;
} }
if (m_conn->m_callOnPreAnswer && !(GetDirection() == IsReceiver)){ if (m_conn->m_callOnPreAnswer && !(GetDirection() == IsReceiver)){
@ -1202,14 +1272,12 @@ PBoolean FSH323_ExternalRTPChannel::Start(){
m_switchTimer = isAudio ? &tech_pvt->read_timer : &tech_pvt->vid_read_timer; m_switchTimer = isAudio ? &tech_pvt->read_timer : &tech_pvt->vid_read_timer;
} }
if (switch_core_codec_init(m_switchCodec, GetH245CodecName(m_capability), NULL, // FMTP
if (switch_core_codec_init(m_switchCodec, GetH245CodecName(m_capability->GetSubType()), NULL, // FMTP
8000, m_capability->GetTxFramesInPacket(), 1, // Channels 8000, m_capability->GetTxFramesInPacket(), 1, // Channels
SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, // Settings SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, // Settings
switch_core_session_get_pool(m_fsSession)) != SWITCH_STATUS_SUCCESS) { switch_core_session_get_pool(m_fsSession)) != SWITCH_STATUS_SUCCESS) {
if (switch_core_codec_init(m_switchCodec, GetH245CodecName(m_capability->GetSubType()), NULL, // FMTP if (switch_core_codec_init(m_switchCodec, GetH245CodecName(m_capability), NULL, // FMTP
8000, 0, 1, // Channels 8000, 0, 1, // Channels
SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, // Settings SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, // Settings
switch_core_session_get_pool(m_fsSession)) != SWITCH_STATUS_SUCCESS) { switch_core_session_get_pool(m_fsSession)) != SWITCH_STATUS_SUCCESS) {
@ -1271,6 +1339,12 @@ PBoolean FSH323_ExternalRTPChannel::Start(){
} }
} }
if (m_conn->m_ChennelProgress && (GetDirection() == IsReceiver)){
if (isAudio) {
switch_core_session_set_write_codec(m_fsSession, m_switchCodec);
}
}
PTRACE(3, "mod_h323\tSet " << ((GetDirection() == IsReceiver)? " read" : " write") << ' ' PTRACE(3, "mod_h323\tSet " << ((GetDirection() == IsReceiver)? " read" : " write") << ' '
<< m_capability->GetMainType() << " codec to << " << m_capability << " for connection " << *this); << m_capability->GetMainType() << " codec to << " << m_capability << " for connection " << *this);
@ -1314,7 +1388,12 @@ PBoolean FSH323_ExternalRTPChannel::Start(){
else m_conn->m_txAudioOpened.Signal(); else m_conn->m_txAudioOpened.Signal();
PTRACE(4, "mod_h323\t------------->External RTP address "<<m_RTPremoteIP<<":"<<m_RTPremotePort); PTRACE(4, "mod_h323\t------------->External RTP address "<<m_RTPremoteIP<<":"<<m_RTPremotePort);
switch_mutex_unlock(tech_pvt->h323_mutex); switch_mutex_unlock(tech_pvt->h323_mutex);
if ( m_conn->m_ChennelAnswer && m_conn->m_rxChennel && m_conn->m_txChennel)
switch_channel_mark_answered(m_fsChannel);
if (m_conn->m_ChennelProgress && m_conn->m_rxChennel)
switch_channel_mark_pre_answered(m_fsChannel);
return true; return true;
} }

View File

@ -125,12 +125,13 @@ struct FSListener {
PString localUserName; PString localUserName;
PString gatekeeper; PString gatekeeper;
}; };
class FSGkRegThread;
class FSH323EndPoint:public H323EndPoint { class FSH323EndPoint:public H323EndPoint {
PCLASSINFO(FSH323EndPoint, H323EndPoint); PCLASSINFO(FSH323EndPoint, H323EndPoint);
public: public:
FSH323EndPoint(); FSH323EndPoint();
~FSH323EndPoint();
/**Create a connection that uses the specified call. /**Create a connection that uses the specified call.
@ -147,6 +148,9 @@ class FSH323EndPoint:public H323EndPoint {
switch_status_t ReadConfig(int reload); switch_status_t ReadConfig(int reload);
void StartGkClient(int retry, PString* gkAddress,PString* gkIdentifer,PString* gkInterface);
void StopGkClient();
switch_endpoint_interface_t *GetSwitchInterface() const { switch_endpoint_interface_t *GetSwitchInterface() const {
return m_freeswitch; return m_freeswitch;
} }
@ -159,9 +163,33 @@ class FSH323EndPoint:public H323EndPoint {
PString m_gkAddress; PString m_gkAddress;
PString m_gkIdentifer; PString m_gkIdentifer;
PString m_gkInterface; PString m_gkInterface;
bool m_faststart;
bool m_h245tunneling;
bool m_h245insetup;
int m_gkretry;
FSGkRegThread* m_thread;
}; };
class FSGkRegThread : public PThread
{
PCLASSINFO(FSGkRegThread, PThread);
public:
FSGkRegThread(FSH323EndPoint* endpoint, PString* gkAddress, PString* gkIdentifer, PString* gkInterface, int retry = 0)
: PThread(10000), m_ep(endpoint), m_retry(retry), m_gkAddress(gkAddress),m_gkIdentifer(gkIdentifer),m_gkInterface(gkInterface)
{ }
void Main()
{ m_ep->StartGkClient(m_retry,m_gkAddress,m_gkIdentifer,m_gkInterface); }
protected:
FSH323EndPoint* m_ep;
int m_retry;
PString* m_gkAddress;
PString* m_gkIdentifer;
PString* m_gkInterface;
};
class FSH323Connection:public H323Connection { class FSH323Connection:public H323Connection {
PCLASSINFO(FSH323Connection, H323Connection) PCLASSINFO(FSH323Connection, H323Connection)
@ -225,6 +253,10 @@ class FSH323Connection:public H323Connection {
bool m_callOnPreAnswer; bool m_callOnPreAnswer;
bool m_startRTP; bool m_startRTP;
bool m_rxChennel;
bool m_txChennel;
bool m_ChennelAnswer;
bool m_ChennelProgress;
PSyncPoint m_rxAudioOpened; PSyncPoint m_rxAudioOpened;
PSyncPoint m_txAudioOpened; PSyncPoint m_txAudioOpened;
protected: protected:
@ -238,6 +270,7 @@ class FSH323Connection:public H323Connection {
unsigned char m_buf[SWITCH_RECOMMENDED_BUFFER_SIZE]; unsigned char m_buf[SWITCH_RECOMMENDED_BUFFER_SIZE];
}; };
class FSH323_ExternalRTPChannel : public H323_ExternalRTPChannel{ class FSH323_ExternalRTPChannel : public H323_ExternalRTPChannel{
PCLASSINFO(FSH323_ExternalRTPChannel, H323_ExternalRTPChannel); PCLASSINFO(FSH323_ExternalRTPChannel, H323_ExternalRTPChannel);
public: public:
@ -409,6 +442,70 @@ protected:
unsigned m_type; unsigned m_type;
}; };
class BaseG726Cap : public H323AudioCapability
{
PCLASSINFO(BaseG726Cap, H323AudioCapability);
public:
BaseG726Cap(const char* fname, unsigned type = H245_AudioCapability::e_nonStandard)
: H323AudioCapability(24,2), m_name(fname), m_type(type),m_comfortNoise(0),m_scrambled(0)
{ }
virtual PObject * Clone() const{
return new BaseG726Cap(*this);
}
virtual H323Codec* CreateCodec(H323Codec::Direction direction) const{
return 0;
}
virtual unsigned GetSubType() const{
PTRACE(2, "mod_h323\t==============>BaseG726Cap::GetSubType");
return H245_AudioCapability::e_nonStandard;
}
virtual PString GetFormatName() const{
PTRACE(2, "mod_h323\t==============>BaseG726Cap::GetFormatName");
return m_name;
}
virtual bool OnSendingPDU(H245_AudioCapability & pdu, unsigned packetSize) const{
PTRACE(2, "mod_h323\t==============>BaseG726Cap::OnSendingPDU");
pdu.SetTag(H245_AudioCapability::e_nonStandard);
return true;
}
virtual bool OnReceivedPDU(const H245_AudioCapability & pdu, unsigned & packetSize){
PTRACE(2, "mod_h323\t==============>BaseG726Cap::OnReceivedPDU");
return true;
}
protected:
const char* m_name;
int m_comfortNoise;
int m_scrambled;
unsigned m_type;
};
#define OPAL_G726_40 "G.726-40k"
char OpalG726_40[] = OPAL_G726_40;
OPAL_MEDIA_FORMAT_DECLARE(OpalG726Format,
OpalG726_40,
OpalMediaFormat::DefaultAudioSessionID,
RTP_DataFrame::G726,
TRUE, // Needs jitter
8000, // bits/sec
5, // bytes
80, // 10 milliseconds
OpalMediaFormat::AudioTimeUnits,
0)
#define DEFINE_H323_CAPAB(cls,base,param,name) \ #define DEFINE_H323_CAPAB(cls,base,param,name) \
class cls : public base { \ class cls : public base { \
@ -427,5 +524,6 @@ DEFINE_H323_CAPAB(FS_G729A,BaseG729Capab,H245_AudioCapability::e_g729AnnexA,OPAL
DEFINE_H323_CAPAB(FS_G729B,BaseG729Capab,H245_AudioCapability::e_g729wAnnexB,OPAL_G729B"{sw}") DEFINE_H323_CAPAB(FS_G729B,BaseG729Capab,H245_AudioCapability::e_g729wAnnexB,OPAL_G729B"{sw}")
DEFINE_H323_CAPAB(FS_G729AB,BaseG729Capab,H245_AudioCapability::e_g729AnnexAwAnnexB,OPAL_G729AB"{sw}") DEFINE_H323_CAPAB(FS_G729AB,BaseG729Capab,H245_AudioCapability::e_g729AnnexAwAnnexB,OPAL_G729AB"{sw}")
DEFINE_H323_CAPAB(FS_GSM,BaseGSM0610Cap,H245_AudioCapability::e_gsmFullRate,OPAL_GSM0610"{sw}") DEFINE_H323_CAPAB(FS_GSM,BaseGSM0610Cap,H245_AudioCapability::e_gsmFullRate,OPAL_GSM0610"{sw}")
DEFINE_H323_CAPAB(FS_G726_40,BaseG726Cap,H245_AudioCapability::e_nonStandard,OPAL_G726_40"{sw}")
static FSProcess *h323_process = NULL; static FSProcess *h323_process = NULL;