forked from Mirrors/freeswitch
new codebase, does not work for now, but does the things in opal way
and media flows in rtp. git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@6225 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
parent
20a47df18b
commit
b2a026b9d1
567
src/mod/endpoints/mod_opal/fscon.cxx
Normal file
567
src/mod/endpoints/mod_opal/fscon.cxx
Normal file
@ -0,0 +1,567 @@
|
||||
|
||||
#include "fsep.h"
|
||||
#include "fscon.h"
|
||||
#include "fsmediastream.h"
|
||||
|
||||
extern switch_endpoint_interface_t *opalfs_endpoint_interface;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
FSConnection::FSConnection(OpalCall & call, FSEndPoint & endpoint, const PString & token, unsigned int options)
|
||||
:OpalConnection(call, endpoint, token, options), FSEndpointInterface(NULL), FSRTPSession(NULL), OpalRTPSession(NULL)
|
||||
|
||||
{
|
||||
|
||||
rtpmanager = new RTP_SessionManager();
|
||||
RTPLocalPort = endpoint.GetMediaPort(); // source is opal
|
||||
RTPRemotePort = endpoint.GetMediaPort() + 150; // destination is Freeswitch
|
||||
RTPLocalAddress = endpoint.GetRTPAddress();
|
||||
RTPRemoteAddress = endpoint.GetRTPAddress();
|
||||
|
||||
mediaformats+=endpoint.GetMediaFormats(); // Set mediaformats from owner endpoint
|
||||
|
||||
|
||||
}
|
||||
|
||||
FSConnection::~FSConnection()
|
||||
{
|
||||
delete rtpmanager;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void FSConnection::InitiateCall(const PString & party)
|
||||
{
|
||||
phase = SetUpPhase;
|
||||
PTRACE(1, "FSConnection: \t Initiating Call to " << party);
|
||||
if (!OnIncomingConnection(0, NULL)){
|
||||
PTRACE(1, "FSConnection: \t Releasing the call with CallerAbort");
|
||||
Release(EndedByCallerAbort);
|
||||
}else{
|
||||
PTRACE(1, "FSConnection: \t Setting up the ownerCall");
|
||||
ownerCall.OnSetUp(*this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
switch_call_cause_t FSConnection::SwitchInitiateCall(switch_core_session_t *session, switch_caller_profile_t *outbound_profile,
|
||||
switch_core_session_t **new_session, switch_memory_pool_t **pool)
|
||||
{
|
||||
|
||||
return SWITCH_CAUSE_SUCCESS;
|
||||
}
|
||||
|
||||
// function name sucks, but lets keep it for now
|
||||
// this function gets called when calls come from external opal endpoints
|
||||
// and goes to fs
|
||||
BOOL FSConnection::CreateIncomingFSConnection()
|
||||
{
|
||||
|
||||
OpalCall & call = GetCall();
|
||||
PSafePtr<OpalConnection> OtherConnection = call.GetOtherPartyConnection(*this);
|
||||
|
||||
//ownerCall.GetOtherPartyConnection(*this)->PreviewPeerMediaFormats(mediaformats);
|
||||
|
||||
PString dest(OtherConnection->GetCalledDestinationNumber());
|
||||
//dest = dest.Right(dest.GetLength() - 3); // get destination without 'fs:'
|
||||
|
||||
switch_mutex_t *mut;
|
||||
switch_core_session_t *session = NULL;
|
||||
switch_caller_profile_t *caller_profile = NULL;
|
||||
fs_obj_t *fs_pvt = NULL; // private object
|
||||
|
||||
if (!OtherConnection)
|
||||
return FALSE;
|
||||
|
||||
session = switch_core_session_request(opalfs_endpoint_interface, NULL);
|
||||
|
||||
if(!session){
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Could not allocate session object\n");
|
||||
call.Clear(EndedByNoEndPoint);
|
||||
}
|
||||
|
||||
fssession = session; // store the fs session there
|
||||
fs_pvt = (fs_obj_t*) switch_core_session_alloc(session, sizeof(fs_obj_t));
|
||||
|
||||
if (!fs_pvt){
|
||||
PTRACE(3, "!fs_pvt");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (switch_mutex_init(&(fs_pvt->flag_mutex), SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session))){
|
||||
PTRACE(3, "CAnnot init mutex");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
fs_pvt->ownercall = &call;
|
||||
fs_pvt->Connection = this;
|
||||
|
||||
switch_core_session_set_private(session, fs_pvt);
|
||||
|
||||
frame.data = databuf;
|
||||
switch_set_flag(fs_pvt, TFLAG_INBOUND);
|
||||
|
||||
caller_profile = switch_caller_profile_new(switch_core_session_get_pool(session),
|
||||
(const char*)GetRemotePartyName(), /** username */
|
||||
"XML", /** TODO -> this should be configurable by core */
|
||||
(const char*)GetRemotePartyName(), /** caller_id_name */
|
||||
(const char*)GetRemotePartyNumber(), /** caller_id_number */
|
||||
(const char*)GetRemotePartyAddress(),/** network addr */
|
||||
NULL, /** ANI */
|
||||
NULL, /** ANI II */
|
||||
NULL, /** RDNIS */
|
||||
"FSOpal", /** source */
|
||||
"10.0.0.1", /** TODO -> set context */
|
||||
(const char*) dest /** destination_number */
|
||||
);
|
||||
|
||||
PWaitAndSignal m(ChannelMutex);
|
||||
|
||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||
switch_channel_set_name(channel,(const char*) GetToken());
|
||||
switch_channel_set_caller_profile(channel, caller_profile);
|
||||
switch_core_session_thread_launch(session);
|
||||
switch_channel_set_state(channel, CS_INIT);
|
||||
switch_channel_set_flag(channel, CF_ORIGINATOR);
|
||||
SetConnected();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL FSConnection::SetUpConnection()
|
||||
{
|
||||
|
||||
OpalCall & call = GetCall();
|
||||
PSafePtr<OpalConnection> OtherConnection = call.GetOtherPartyConnection(*this);
|
||||
|
||||
if (!OtherConnection && !IsOriginating()){
|
||||
PTRACE(3, "FSConn:\t No other connection in the call");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (IsOriginating()){
|
||||
PTRACE(3, "FSConn:\tOutgoing Connection"); // outgoing channel on fs
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
PTRACE(3, "FSConn:\tIncoming Connection for " << OtherConnection->GetCalledDestinationNumber());
|
||||
|
||||
SetPhase(SetUpPhase);
|
||||
|
||||
return CreateIncomingFSConnection();
|
||||
}
|
||||
|
||||
BOOL FSConnection::OnSetUpConnection()
|
||||
{
|
||||
switch_channel_t *channel = switch_core_session_get_channel(fssession);
|
||||
assert(channel);
|
||||
|
||||
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
BOOL FSConnection::SetAlerting(const PString& caleeName, BOOL withMedia)
|
||||
{
|
||||
switch_channel_t *channel = NULL;
|
||||
|
||||
channel = switch_core_session_get_channel(fssession);
|
||||
fs_obj_t *fs_pvt = (fs_obj_t*) switch_core_session_get_private(fssession);
|
||||
assert(channel);
|
||||
|
||||
if (IsOriginating()) {
|
||||
PTRACE(2, "FSConn\tSetAlerting ignored on call we originated.");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (phase != SetUpPhase)
|
||||
return FALSE;
|
||||
|
||||
SetPhase(AlertingPhase);
|
||||
OnAlerting(*this);
|
||||
|
||||
switch_channel_set_state(channel, CS_RING);
|
||||
switch_set_flag(fs_pvt, TFLAG_IO);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void FSConnection::OnAlerting(OpalConnection & connection)
|
||||
{
|
||||
switch_channel_t *channel = NULL;
|
||||
|
||||
channel = switch_core_session_get_channel(fssession);
|
||||
fs_obj_t *fs_pvt = (fs_obj_t*) switch_core_session_get_private(fssession);
|
||||
SetPhase(EstablishedPhase);
|
||||
switch_channel_set_variable(channel, SWITCH_ORIGINATOR_CODEC_VARIABLE, "PCMU@30i,PCMA@30i");
|
||||
|
||||
switch_channel_set_flag(channel, CF_ANSWERED);
|
||||
//
|
||||
//if (!IsOriginating())
|
||||
|
||||
//switch_channel_set_state(channel, CS_RING);
|
||||
|
||||
}
|
||||
|
||||
BOOL FSConnection::SetConnected()
|
||||
{
|
||||
PTRACE(3, "FSConn:\tSetConnected");
|
||||
PINDEX Session = 1;
|
||||
if (!IsOriginating()){
|
||||
if (mediaStreams.IsEmpty()){
|
||||
|
||||
//RTP_Session *rtpsession = rtpmanager->GetSession(sessionID);
|
||||
//Get an rtp session to see if we have some in the manager
|
||||
/*
|
||||
for (; Session <=3 ; Session++){ // We are adding rtpsession to the manager.
|
||||
// we have only rtp over udp for now.
|
||||
PTRACE(3, "Adding a new rtp session to rtpmanager with id " << Session);
|
||||
RTP_UDP *newsession = new RTP_UDP(NULL, Session, FALSE);
|
||||
newsession->Open(RTPLocalAddress, RTPLocalPort, 0, Session, NULL, NULL);
|
||||
newsession->SetLocalAddress(RTPLocalAddress);
|
||||
newsession->SetRemoteSocketInfo(RTPRemoteAddress, RTPRemotePort, FALSE);
|
||||
rtpmanager->AddSession(newsession);
|
||||
}
|
||||
*/
|
||||
PTRACE(3, "Mediaformats " << mediaformats);
|
||||
//increments usecount on the rtp session object so, we have to release it after
|
||||
//we are done.
|
||||
//rtpsession = rtpmanager->UseSession(sessionID);
|
||||
//OpalRTPSession = rtpsession;
|
||||
OnConnected();
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void FSConnection::OnConnected()
|
||||
{
|
||||
switch_channel_t *channel = NULL;
|
||||
|
||||
channel = switch_core_session_get_channel(fssession);
|
||||
fs_obj_t *fs_pvt = (fs_obj_t*) switch_core_session_get_private(fssession);
|
||||
|
||||
if (!IsOriginating()){
|
||||
switch_channel_set_state(channel, CS_INIT);
|
||||
SetPhase(SetUpPhase);
|
||||
SetAlerting("", FALSE);
|
||||
//switch_set_flag(fs_pvt, TFLAG_IO);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void FSConnection::OnReleased()
|
||||
{
|
||||
switch_channel_t *channel = NULL;
|
||||
|
||||
SetPhase(ReleasingPhase);
|
||||
|
||||
CloseMediaStreams();
|
||||
|
||||
channel = switch_core_session_get_channel(fssession);
|
||||
assert(channel);
|
||||
switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
|
||||
OpalConnection::OnReleased();
|
||||
|
||||
}
|
||||
|
||||
OpalMediaFormatList FSConnection::GetMediaFormats() const
|
||||
{
|
||||
|
||||
return mediaformats;
|
||||
}
|
||||
|
||||
BOOL FSConnection::IsMediaBypassPossible(unsigned sessionID)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
OpalMediaStream* FSConnection::CreateMediaStream(const OpalMediaFormat & mediaFormat,
|
||||
unsigned sessionID,
|
||||
BOOL isSource)
|
||||
{
|
||||
if (sessionID != OpalMediaFormat::DefaultAudioSessionID) // only audio for now
|
||||
return OpalConnection::CreateMediaStream(mediaFormat, sessionID, isSource);
|
||||
|
||||
PTRACE(3, "CODEC NAME from source is " << mediaFormat.GetEncodingName());
|
||||
|
||||
RTP_Session *rtpsession = rtpmanager->GetSession(sessionID); // Get an rtp session
|
||||
|
||||
if (!rtpsession){ // We have to add an rtpsession to the manager.
|
||||
// we have only rtp over udp for now.
|
||||
PTRACE(3, "Adding a new rtp session to rtpmanager");
|
||||
RTP_UDP *newsession = new RTP_UDP(NULL, sessionID, FALSE);
|
||||
newsession->Open(RTPLocalAddress, 44000, 0, sessionID, NULL, NULL);
|
||||
newsession->SetLocalAddress(RTPLocalAddress);
|
||||
newsession->SetRemoteSocketInfo(RTPRemoteAddress, 44501, FALSE);
|
||||
newsession->SetRemoteSocketInfo(RTPRemoteAddress, 44500, TRUE);
|
||||
rtpmanager->AddSession(newsession);
|
||||
}
|
||||
|
||||
rtpsession = rtpmanager->UseSession(sessionID); /*increments usecount on the rtp session object*/
|
||||
|
||||
return CreateMediaStream(*this, mediaFormat, isSource, *rtpsession /*RTPSession*/, 0 /*minjitter delay*/, 0/*maxjitter delay*/);
|
||||
}
|
||||
|
||||
|
||||
|
||||
OpalMediaStream * FSConnection::CreateMediaStream(OpalConnection & conn,
|
||||
const OpalMediaFormat & mediaFormat,
|
||||
BOOL isSource,
|
||||
RTP_Session &rtpSession,
|
||||
unsigned minAudioJitterDelay,
|
||||
unsigned maxAudioJitterDelay)
|
||||
{
|
||||
switch_channel_t *channel;
|
||||
switch_rtp_flag_t flags ;
|
||||
const char *err;
|
||||
|
||||
fs_obj_t *fs_pvt = (fs_obj_t*) switch_core_session_get_private(fssession);
|
||||
channel = switch_core_session_get_channel(fssession);
|
||||
|
||||
PTRACE(3, "Codec name: " << mediaFormat.GetEncodingName() << " " << mediaFormat.GetClockRate() << " " << mediaFormat.GetFrameTime());
|
||||
|
||||
if (isSource) {
|
||||
if (switch_core_codec_init
|
||||
(&write_codec, "L16", NULL, mediaFormat.GetClockRate(), 30, 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL,
|
||||
switch_core_session_get_pool(fssession)) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s Cannot set write codec\n", switch_channel_get_name(channel));
|
||||
switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
|
||||
return NULL;
|
||||
}
|
||||
switch_core_session_set_write_codec(fssession, &write_codec);
|
||||
|
||||
}else{
|
||||
if (switch_core_codec_init
|
||||
(&read_codec, "L16", NULL, mediaFormat.GetClockRate(), 30, 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL,
|
||||
switch_core_session_get_pool(fssession)) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s Cannot set read codec\n", switch_channel_get_name(channel));
|
||||
switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
switch_core_session_set_read_codec(fssession, &read_codec);
|
||||
|
||||
frame.rate = mediaFormat.GetClockRate();
|
||||
frame.codec = &read_codec;
|
||||
|
||||
|
||||
}
|
||||
|
||||
FSRTPSession = switch_rtp_new("10.0.0.1",
|
||||
44500, // Source and destination is switched from opal
|
||||
"10.0.0.1",
|
||||
44000, //this goes to Opal rtp data port
|
||||
write_codec.implementation->ianacode,
|
||||
write_codec.implementation->samples_per_frame,
|
||||
write_codec.implementation->microseconds_per_frame,
|
||||
flags, NULL, "soft", &err, switch_core_session_get_pool(fssession));
|
||||
|
||||
switch_rtp_set_flag(FSRTPSession, SWITCH_RTP_FLAG_DATAWAIT);
|
||||
//switch_rtp_set_flag(FSRTPSession, SWITCH_RTP_FLAG_USE_TIMER);
|
||||
//switch_rtp_set_flag(FSRTPSession, SWITCH_RTP_FLAG_AUTOADJ);
|
||||
|
||||
|
||||
|
||||
PTRACE(1, "FSConnection: new media stream !!!" << mediaFormat.GetEncodingName());
|
||||
//switch_channel_set_state(channel, CS_UNHOLD);
|
||||
return new FSMediaStream(*this, mediaFormat, isSource, rtpSession /*RTPSession*/, minAudioJitterDelay /*minjitter delay*/, maxAudioJitterDelay/*maxjitter delay*/);
|
||||
}
|
||||
|
||||
|
||||
switch_status_t FSConnection::callback_on_init(switch_core_session_t *session)
|
||||
{
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
PWaitAndSignal m(ChannelMutex);
|
||||
|
||||
OpalCall & call = GetCall();
|
||||
PSafePtr<OpalConnection> OtherConnection = call.GetOtherPartyConnection(*this);
|
||||
|
||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||
assert(channel);
|
||||
|
||||
if (!IsOriginating()) { // incoming call initialize
|
||||
// TODO Set all the Mediaformats from fs endpoint to the
|
||||
// fs codec strings for the channels. be carefull about early media etc.
|
||||
//PTRACE(2, "FSConn:\t Answering Incoming Call");
|
||||
SetConnected();
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
switch_status_t FSConnection::callback_on_ring(switch_core_session_t *io_session)
|
||||
{
|
||||
switch_channel_t *channel = NULL;
|
||||
|
||||
channel = switch_core_session_get_channel(io_session);
|
||||
//switch_channel_set_state(channel, CS_HOLD);
|
||||
OpalConnection::StartMediaStreams();
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
switch_status_t FSConnection::callback_on_execute(switch_core_session_t *io_session)
|
||||
{
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
switch_status_t FSConnection::callback_on_hangup(switch_core_session_t *io_session)
|
||||
{
|
||||
phase = ReleasingPhase;
|
||||
//OpalConnection::CloseMediaStreams();
|
||||
OpalConnection::ownerCall.Clear();
|
||||
OnReleased();
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
switch_status_t FSConnection::callback_on_loopback(switch_core_session_t *session)
|
||||
{
|
||||
OpalCall & call = GetCall();
|
||||
PSafePtr<OpalConnection> OtherConnection = call.GetOtherPartyConnection(*this);
|
||||
|
||||
OtherConnection->AnsweringCall(AnswerCallNow);
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
switch_status_t FSConnection::io_read_frame(switch_core_session_t *session, switch_frame_t **o_frame, int i_timeout, switch_io_flag_t i_flag, int i_streamId)
|
||||
{
|
||||
switch_channel_t *channel = NULL;
|
||||
switch_frame_t *pframe;
|
||||
switch_status_t result;
|
||||
|
||||
fs_obj_t *fs_pvt = (fs_obj_t*) switch_core_session_get_private(session);
|
||||
|
||||
channel = switch_core_session_get_channel(session);
|
||||
assert(channel != NULL);
|
||||
|
||||
|
||||
if (!switch_test_flag(fs_pvt, TFLAG_IO)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "read");
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
pframe = &frame;
|
||||
*o_frame = pframe;
|
||||
|
||||
switch_set_flag_locked(fs_pvt, TFLAG_READING);
|
||||
result = switch_rtp_zerocopy_read_frame(FSRTPSession, pframe);
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "result from read %i\n", result);
|
||||
switch_clear_flag_locked(fs_pvt, TFLAG_READING);
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
switch_status_t FSConnection::io_write_frame(switch_core_session_t *session, switch_frame_t *frame, int i_timeout, switch_io_flag_t i_flag, int i_streamId)
|
||||
{
|
||||
|
||||
switch_channel_t *channel = NULL;
|
||||
|
||||
channel = switch_core_session_get_channel(session);
|
||||
fs_obj_t *fs_pvt = (fs_obj_t*) switch_core_session_get_private(session);
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "write \n");
|
||||
|
||||
while(!switch_rtp_ready(FSRTPSession)){
|
||||
if (switch_channel_ready(channel)) {
|
||||
switch_yield(10000);
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Yielding\n");
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Yielding\n");
|
||||
return SWITCH_STATUS_GENERR;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!switch_test_flag(fs_pvt, TFLAG_IO)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "write");
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
switch_set_flag_locked(fs_pvt, TFLAG_WRITING);
|
||||
switch_rtp_write_frame(FSRTPSession, frame, 0);
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "write \n");
|
||||
switch_clear_flag_locked(fs_pvt, TFLAG_WRITING);
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
switch_status_t FSConnection::io_receive_message(switch_core_session_t *i_session, switch_core_session_message_t *i_message)
|
||||
{
|
||||
|
||||
switch_channel_t *channel = NULL;
|
||||
|
||||
channel = switch_core_session_get_channel(i_session);
|
||||
OpalCall & call = GetCall();
|
||||
PSafePtr<OpalConnection> OtherConnection = call.GetOtherPartyConnection(*this);
|
||||
|
||||
|
||||
|
||||
switch(i_message->message_id)
|
||||
{
|
||||
case SWITCH_MESSAGE_REDIRECT_AUDIO:
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG ,"SWITCH_MESSAGE_REDIRECT_AUDIO\n");
|
||||
break;
|
||||
case SWITCH_MESSAGE_TRANSMIT_TEXT:
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,"SWITCH_MESSAGE_TRANSMIT_TEXT\n");
|
||||
break;
|
||||
case SWITCH_MESSAGE_INDICATE_ANSWER:
|
||||
OtherConnection->AnsweringCall(AnswerCallNow);
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,"SWITCH_MESSAGE_INDICATE_ANSWER\n");
|
||||
break;
|
||||
case SWITCH_MESSAGE_INDICATE_PROGRESS:
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,"SWITCH_MESSAGE_INDICATE_PROGRESS\n");
|
||||
break;
|
||||
case SWITCH_MESSAGE_INDICATE_BRIDGE:
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,"SWITCH_MESSAGE_INDICATE_BRIDGE\n");
|
||||
break;
|
||||
case SWITCH_MESSAGE_INDICATE_UNBRIDGE:
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,"SWITCH_MESSAGE_INDICATE_UNBRIDGE\n");
|
||||
break;
|
||||
case SWITCH_MESSAGE_INDICATE_TRANSFER:
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,"SWITCH_MESSAGE_INDICATE_TRANSFER\n");
|
||||
break;
|
||||
case SWITCH_MESSAGE_INDICATE_RINGING:
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,"SWITCH_MESSAGE_INDICATE_RINGING\n");
|
||||
break;
|
||||
case SWITCH_MESSAGE_INDICATE_MEDIA:
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,"SWITCH_MESSAGE_INDICATE_MEDIA\n");
|
||||
break;
|
||||
case SWITCH_MESSAGE_INDICATE_NOMEDIA:
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,"SWITCH_MESSAGE_INDICATE_NOMEDIA\n");
|
||||
break;
|
||||
case SWITCH_MESSAGE_INDICATE_HOLD:
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,"SWITCH_MESSAGE_INDICATE_HOLD\n");
|
||||
break;
|
||||
case SWITCH_MESSAGE_INDICATE_UNHOLD:
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,"SWITCH_MESSAGE_INDICATE_UNHOLD\n");
|
||||
break;
|
||||
case SWITCH_MESSAGE_INDICATE_REDIRECT:
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,"SWITCH_MESSAGE_INDICATE_REDIRECT\n");
|
||||
break;
|
||||
case SWITCH_MESSAGE_INDICATE_REJECT:
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,"SWITCH_MESSAGE_INDICATE_REJECT\n");
|
||||
break;
|
||||
case SWITCH_MESSAGE_INDICATE_BROADCAST:
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,"SWITCH_MESSAGE_INDICATE_BROADCAST\n");
|
||||
break;
|
||||
case SWITCH_MESSAGE_INDICATE_MEDIA_REDIRECT:
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,"SWITCH_MESSAGE_INDICATE_MEDIA_REDIRECT\n");
|
||||
break;
|
||||
default:
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,"SWITCH_MESSAGE_???\n");
|
||||
}
|
||||
|
||||
//switch_mutex_unlock(tech_prv->m_mutex);
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
126
src/mod/endpoints/mod_opal/fscon.h
Normal file
126
src/mod/endpoints/mod_opal/fscon.h
Normal file
@ -0,0 +1,126 @@
|
||||
|
||||
#ifndef __FREESWITCH_OPAL_CONNECTION__
|
||||
#define __FREESWITCH_OPAL_CONNECTION__
|
||||
|
||||
#include <switch.h>
|
||||
#include <ptlib.h>
|
||||
#include <ptlib/psync.h>
|
||||
#include <opal/buildopts.h>
|
||||
#include <opal/endpoint.h>
|
||||
#include <opal/connection.h>
|
||||
#include <opal/transports.h>
|
||||
|
||||
#include "fsep.h"
|
||||
#include "fsmediastream.h"
|
||||
|
||||
typedef enum {
|
||||
TFLAG_IO = (1 << 0),
|
||||
TFLAG_INBOUND = (1 << 1),
|
||||
TFLAG_OUTBOUND = (1 << 2),
|
||||
TFLAG_READING = (1 << 3),
|
||||
TFLAG_WRITING = (1 << 4)
|
||||
} TFLAGS;
|
||||
|
||||
|
||||
class FSConnection;
|
||||
class FSMediaStream;
|
||||
|
||||
typedef struct fs_obj
|
||||
{
|
||||
unsigned int flags;
|
||||
switch_mutex_t *flag_mutex;
|
||||
OpalCall *ownercall;
|
||||
FSConnection *Connection;
|
||||
|
||||
} fs_obj_t;
|
||||
|
||||
|
||||
|
||||
class FSConnection : public OpalConnection
|
||||
{
|
||||
PCLASSINFO(FSConnection, OpalConnection);
|
||||
public:
|
||||
FSConnection(OpalCall & call, FSEndPoint & endpoint, const PString & token, unsigned int options);
|
||||
~FSConnection();
|
||||
virtual OpalMediaFormatList GetMediaFormats() const;
|
||||
virtual OpalMediaStream * CreateMediaStream(OpalConnection & conn,
|
||||
const OpalMediaFormat & mediaFormat,
|
||||
BOOL isSource,
|
||||
RTP_Session &rtpSession,
|
||||
unsigned minAudioJitterDelay,
|
||||
unsigned maxAudioJitterDelay);
|
||||
virtual OpalMediaStream* CreateMediaStream (const OpalMediaFormat & mediaFormat,
|
||||
unsigned sessionID,
|
||||
BOOL isSource);
|
||||
|
||||
void InitiateCall(const PString & party);
|
||||
|
||||
|
||||
|
||||
virtual BOOL SetUpConnection();
|
||||
virtual BOOL OnSetUpConnection();
|
||||
virtual BOOL SetAlerting(const PString& caleeName, BOOL withMedia);
|
||||
virtual BOOL SetConnected();
|
||||
virtual void OnAlerting(OpalConnection & connection);
|
||||
virtual void OnConnected();
|
||||
virtual void OnReleased();
|
||||
virtual BOOL IsMediaBypassPossible(unsigned sessionID);
|
||||
|
||||
switch_status_t callback_on_init(switch_core_session_t *io_session);
|
||||
switch_status_t callback_on_ring(switch_core_session_t *io_session);
|
||||
switch_status_t callback_on_execute(switch_core_session_t *io_session);
|
||||
switch_status_t callback_on_hangup(switch_core_session_t *io_session);
|
||||
switch_status_t callback_on_loopback(switch_core_session_t *session);
|
||||
switch_status_t callback_on_transmit(switch_core_session_t *io_session);
|
||||
|
||||
switch_call_cause_t SwitchInitiateCall(switch_core_session_t *session, switch_caller_profile_t *outbound_profile,
|
||||
switch_core_session_t **new_session, switch_memory_pool_t **pool);
|
||||
|
||||
switch_status_t io_read_frame(switch_core_session_t *, switch_frame_t **, int, switch_io_flag_t, int);
|
||||
switch_status_t io_write_frame(switch_core_session_t *, switch_frame_t *, int, switch_io_flag_t, int);
|
||||
switch_status_t io_kill_channel(switch_core_session_t *, int);
|
||||
switch_status_t io_waitfor_read(switch_core_session_t *, int, int);
|
||||
switch_status_t io_waitfor_write(switch_core_session_t *, int, int);
|
||||
switch_status_t io_send_dtmf(switch_core_session_t *, char *);
|
||||
switch_status_t io_receive_message(switch_core_session_t *, switch_core_session_message_t *);
|
||||
switch_status_t io_receive_event(switch_core_session_t *, switch_event_t *);
|
||||
switch_status_t io_state_change(switch_core_session_t *);
|
||||
switch_status_t io_read_video_frame(switch_core_session_t *, switch_frame_t **, int, switch_io_flag_t, int);
|
||||
switch_status_t io_write_video_frame(switch_core_session_t *, switch_frame_t *, int, switch_io_flag_t, int);
|
||||
|
||||
private:
|
||||
OpalMediaFormatList mediaformats;
|
||||
|
||||
|
||||
switch_frame_t frame;
|
||||
char databuf[SWITCH_RECOMMENDED_BUFFER_SIZE];
|
||||
switch_codec_t read_codec; /* Read codec*/
|
||||
switch_codec_t write_codec; /* Write codec*/
|
||||
switch_timer_t timer;
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
BOOL CreateIncomingFSConnection();
|
||||
|
||||
switch_endpoint_interface_t *FSEndpointInterface;
|
||||
WORD RTPLocalPort;
|
||||
WORD RTPRemotePort;
|
||||
PIPSocket::Address RTPLocalAddress;
|
||||
PIPSocket::Address RTPRemoteAddress;
|
||||
|
||||
PMutex ChannelMutex;
|
||||
|
||||
RTP_SessionManager *rtpmanager;
|
||||
|
||||
RTP_Session *OpalRTPSession;
|
||||
|
||||
switch_core_session_t *fssession;
|
||||
|
||||
|
||||
switch_rtp_t *FSRTPSession;
|
||||
};
|
||||
|
||||
|
||||
#endif //__FREESWITCH_OPAL_CONNECTION__
|
||||
|
107
src/mod/endpoints/mod_opal/fsep.cxx
Normal file
107
src/mod/endpoints/mod_opal/fsep.cxx
Normal file
@ -0,0 +1,107 @@
|
||||
|
||||
|
||||
#include "fsep.h"
|
||||
#include "fscon.h"
|
||||
|
||||
|
||||
static PString MakeToken()
|
||||
{
|
||||
return PGloballyUniqueID().AsString();
|
||||
}
|
||||
|
||||
FSEndPoint::FSEndPoint(OpalManager & manager)
|
||||
:OpalEndPoint(manager, "fs", CanTerminateCall), initialized(TRUE),
|
||||
currentmediaport(MIN_MEDIA_PORT), RTPLocalAddress(PIPSocket::Address::Address())
|
||||
{
|
||||
|
||||
|
||||
mediaformats+=OpalPCM16;
|
||||
mediaformats+=OpalG711uLaw;
|
||||
mediaformats+=OpalG711ALaw;
|
||||
mediaformats+=OpalG711_ULAW_64K;
|
||||
mediaformats+=OpalG711_ALAW_64K;
|
||||
mediaformats+=OpalGSM0610;
|
||||
mediaformats+=OpalPCM16_16KHZ;
|
||||
mediaformats+=OPAL_G729;
|
||||
mediaformats+=OPAL_G729A;
|
||||
mediaformats+=OPAL_G729B;
|
||||
mediaformats+=OPAL_G729AB;
|
||||
PTRACE(3, "FSEndPoint: \t FSEndPoint Created!");
|
||||
}
|
||||
|
||||
FSEndPoint::~FSEndPoint()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
BOOL FSEndPoint::SetRTPAddress(PIPSocket::Address addr)
|
||||
{
|
||||
RTPLocalAddress = addr;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
PIPSocket::Address FSEndPoint::GetRTPAddress()
|
||||
{
|
||||
return RTPLocalAddress;
|
||||
}
|
||||
|
||||
|
||||
BOOL FSEndPoint::OnOpenMediaStream(OpalConnection & connection, OpalMediaStream & stream)
|
||||
{
|
||||
manager.OnOpenMediaStream(connection, stream);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL FSEndPoint::OnIncomingConnection(OpalConnection&, unsigned int, OpalConnection::StringOptions*)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL FSEndPoint::OnSetUpConnection(OpalConnection & connection)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void FSEndPoint::OnEstablished(OpalConnection &connection)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
BOOL FSEndPoint::MakeConnection (OpalCall & call, const PString & party,
|
||||
void *userData, unsigned int options,
|
||||
OpalConnection::StringOptions* stringOptions)
|
||||
{
|
||||
FSConnection *connection;
|
||||
PString token = MakeToken();
|
||||
connection = new FSConnection(call, *this, token, 0);
|
||||
PString dest = PString((const char*) userData);
|
||||
|
||||
if (connection != NULL){
|
||||
|
||||
if (!AddConnection(connection))
|
||||
return FALSE;
|
||||
|
||||
if (call.GetConnection(0) == (OpalConnection*)connection){
|
||||
connection->SetUpConnection();
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
OpalMediaFormatList FSEndPoint::GetMediaFormats() const
|
||||
{
|
||||
return mediaformats;
|
||||
}
|
||||
|
||||
|
||||
|
||||
WORD FSEndPoint::GetMediaPort()
|
||||
{
|
||||
if (currentmediaport++ >= MAX_MEDIA_PORT) {
|
||||
currentmediaport = MIN_MEDIA_PORT;
|
||||
}
|
||||
|
||||
return currentmediaport;
|
||||
}
|
45
src/mod/endpoints/mod_opal/fsep.h
Normal file
45
src/mod/endpoints/mod_opal/fsep.h
Normal file
@ -0,0 +1,45 @@
|
||||
|
||||
|
||||
#ifndef __FREESWITCH_OPAL_ENDPOINT__
|
||||
#define __FREESWITCH_OPAL_ENDPOINT__
|
||||
|
||||
#include <switch.h>
|
||||
#include <ptlib.h>
|
||||
#include <opal/buildopts.h>
|
||||
#include <opal/endpoint.h>
|
||||
|
||||
#define MAX_MEDIA_PORT 44526
|
||||
#define MIN_MEDIA_PORT 44000
|
||||
|
||||
class FSEndPoint : public OpalEndPoint
|
||||
{
|
||||
PCLASSINFO(FSEndPoint, OpalEndPoint);
|
||||
public:
|
||||
FSEndPoint(OpalManager& manager);
|
||||
~FSEndPoint();
|
||||
|
||||
virtual BOOL OnIncomingConnection(OpalConnection&, unsigned int, OpalConnection::StringOptions*);
|
||||
|
||||
virtual BOOL MakeConnection(OpalCall & call, const PString & party,
|
||||
void * userData, unsigned int options = 0,
|
||||
OpalConnection::StringOptions* stringOptions = NULL);
|
||||
|
||||
virtual BOOL OnOpenMediaStream(OpalConnection & connection, OpalMediaStream & stream);
|
||||
virtual BOOL OnSetUpConnection(OpalConnection & connection);
|
||||
virtual void OnEstablished(OpalConnection &connection);
|
||||
virtual OpalMediaFormatList GetMediaFormats() const;
|
||||
|
||||
WORD GetMediaPort();
|
||||
BOOL SetRTPAddress(PIPSocket::Address ipaddr);
|
||||
PIPSocket::Address GetRTPAddress();
|
||||
|
||||
private:
|
||||
BOOL initialized;
|
||||
PINDEX maxcalls;
|
||||
OpalMediaFormatList mediaformats;
|
||||
WORD currentmediaport;
|
||||
PIPSocket::Address RTPLocalAddress;
|
||||
|
||||
};
|
||||
|
||||
#endif //__FREESWITCH_OPAL_ENDPOINT__
|
63
src/mod/endpoints/mod_opal/fsmanager.cxx
Normal file
63
src/mod/endpoints/mod_opal/fsmanager.cxx
Normal file
@ -0,0 +1,63 @@
|
||||
|
||||
#include "fsmanager.h"
|
||||
|
||||
FSManager::FSManager()
|
||||
:SessionsHashTable(NULL), SessionsHashTableMutex(NULL),
|
||||
h323ep(NULL), fsep(NULL)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
FSManager::~FSManager()
|
||||
{
|
||||
switch_mutex_destroy(SessionsHashTableMutex);
|
||||
switch_core_hash_destroy(&SessionsHashTable);
|
||||
}
|
||||
|
||||
BOOL FSManager::Initialize(switch_memory_pool_t* MemoryPool)
|
||||
{
|
||||
silenceDetectParams.m_mode = OpalSilenceDetector::NoSilenceDetection;
|
||||
SetAudioJitterDelay(800, 3000);
|
||||
|
||||
if(switch_core_hash_init(&SessionsHashTable,MemoryPool)!=SWITCH_STATUS_SUCCESS)
|
||||
{
|
||||
assert(0);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if(switch_mutex_init(&SessionsHashTableMutex,SWITCH_MUTEX_UNNESTED,MemoryPool)!=SWITCH_STATUS_SUCCESS)
|
||||
{
|
||||
assert(0);
|
||||
switch_core_hash_destroy(&SessionsHashTable);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
sipep = new FSSIPEndPoint( *(static_cast<OpalManager*>(this)));
|
||||
h323ep = new FSH323EndPoint( *(static_cast<OpalManager*>(this)));
|
||||
fsep = new FSEndPoint( *(static_cast<OpalManager*>(this)));
|
||||
|
||||
PIPSocket::Address addr("10.0.0.1");
|
||||
|
||||
OpalTransportAddress sipTransportAddress(addr,5060, "udp");
|
||||
OpalTransportAddress h323TransportAddress(addr,1726);
|
||||
|
||||
|
||||
fsep->SetRTPAddress(addr);
|
||||
|
||||
if(!sipep->StartListeners(sipTransportAddress)){
|
||||
delete sipep;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if(!h323ep->StartListeners(h323TransportAddress)){
|
||||
delete h323ep;
|
||||
delete sipep;
|
||||
return FALSE;
|
||||
}
|
||||
SetSTUNServer("stun.voxgratia.org");
|
||||
PStringArray routes;
|
||||
routes += "h323:.* = sip:<da>@fwd.pulver.com";
|
||||
SetRouteTable(routes);
|
||||
|
||||
return TRUE;
|
||||
}
|
34
src/mod/endpoints/mod_opal/fsmanager.h
Normal file
34
src/mod/endpoints/mod_opal/fsmanager.h
Normal file
@ -0,0 +1,34 @@
|
||||
|
||||
#ifndef __FREESWITCH_OPAL_MANAGER__
|
||||
#define __FREESWITCH_OPAL_MANAGER__
|
||||
|
||||
#include <ptlib.h>
|
||||
#include <opal/manager.h>
|
||||
#include <h323/h323ep.h>
|
||||
#include "fsep.h"
|
||||
#include "opal_h323.h"
|
||||
#include "opal_sip.h"
|
||||
|
||||
class FSH323EndPoint;
|
||||
|
||||
class FSManager : public OpalManager
|
||||
{
|
||||
PCLASSINFO(FSManager, PObject);
|
||||
public:
|
||||
FSManager();
|
||||
~FSManager();
|
||||
|
||||
BOOL Initialize(switch_memory_pool_t* MemoryPool);
|
||||
|
||||
private:
|
||||
switch_hash_t *SessionsHashTable;
|
||||
switch_mutex_t *SessionsHashTableMutex;
|
||||
switch_memory_pool_t *MemoryPool;
|
||||
|
||||
protected:
|
||||
FSH323EndPoint *h323ep;
|
||||
FSSIPEndPoint *sipep;
|
||||
FSEndPoint *fsep;
|
||||
};
|
||||
|
||||
#endif //__FREESWITCH_OPAL_MANAGER__
|
55
src/mod/endpoints/mod_opal/fsmediastream.cxx
Normal file
55
src/mod/endpoints/mod_opal/fsmediastream.cxx
Normal file
@ -0,0 +1,55 @@
|
||||
|
||||
#include "fsmediastream.h"
|
||||
|
||||
FSMediaStream::FSMediaStream(FSConnection & connection, const OpalMediaFormat &mediaFormat,
|
||||
BOOL isSource,
|
||||
RTP_Session & rtpSession,
|
||||
unsigned minAudioJitterDelay,
|
||||
unsigned maxAudioJitterDelay)
|
||||
|
||||
:OpalRTPMediaStream(connection, mediaFormat, isSource, rtpSession, minAudioJitterDelay, maxAudioJitterDelay),
|
||||
fsconnection((FSConnection&) connection)
|
||||
{
|
||||
|
||||
if (isSource){
|
||||
PTRACE(3, "FSMediaStream: Created SOURCE Media Stream");
|
||||
//channel = fsconnection.writechannel;
|
||||
}else{
|
||||
//channel = fsconnection.readchannel;
|
||||
PTRACE(3, "FSMediaStream: Created SINK Media Stream");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
BOOL FSMediaStream::IsSynchronous() const
|
||||
{
|
||||
return FALSE; //rtp mediastream
|
||||
}
|
||||
|
||||
|
||||
FSMediaStream::~FSMediaStream()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
FSUDPMediaStream::FSUDPMediaStream(OpalConnection & connection, const OpalMediaFormat &mediaFormat,
|
||||
unsigned sessionID,
|
||||
BOOL isSource,
|
||||
OpalTransportUDP &transport)
|
||||
|
||||
:OpalUDPMediaStream(connection, mediaFormat, sessionID, isSource, transport)
|
||||
{
|
||||
if (isSource){
|
||||
PTRACE(3, "FSMediaStream: Created SOURCE Media Stream");
|
||||
}else{
|
||||
PTRACE(3, "FSMediaStream: Created SINK Media Stream");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
FSUDPMediaStream::~FSUDPMediaStream()
|
||||
{
|
||||
|
||||
}
|
51
src/mod/endpoints/mod_opal/fsmediastream.h
Normal file
51
src/mod/endpoints/mod_opal/fsmediastream.h
Normal file
@ -0,0 +1,51 @@
|
||||
|
||||
#ifndef __FREESWITCH_OPAL_MEDIASTREAM__
|
||||
#define __FREESWITCH_OPAL_MEDIASTREAM__
|
||||
|
||||
|
||||
#include <ptlib.h>
|
||||
#include <opal/buildopts.h>
|
||||
#include <opal/connection.h>
|
||||
#include <opal/mediastrm.h>
|
||||
#include <switch.h>
|
||||
#include "fscon.h"
|
||||
|
||||
class FSConnection;
|
||||
|
||||
class FSMediaStream : public OpalRTPMediaStream
|
||||
{
|
||||
PCLASSINFO(FSMediaStream, OpalRTPMediaStream);
|
||||
public:
|
||||
FSMediaStream(FSConnection & connection, const OpalMediaFormat &mediaFormat,
|
||||
BOOL isSource,
|
||||
RTP_Session & rtpSession,
|
||||
unsigned minAudioJitterDelay,
|
||||
unsigned maxAudioJitterDelay);
|
||||
|
||||
|
||||
~FSMediaStream();
|
||||
//virtual BOOL ReadData(BYTE* data,PINDEX size,PINDEX& length);
|
||||
//virtual BOOL WriteData(const BYTE* data,PINDEX length, PINDEX& written);
|
||||
virtual BOOL IsSynchronous() const;
|
||||
|
||||
FSConnection &fsconnection;
|
||||
protected:
|
||||
PAdaptiveDelay channelDelay;
|
||||
BOOL isSource;
|
||||
PQueueChannel *channel;
|
||||
};
|
||||
|
||||
class FSUDPMediaStream : public OpalUDPMediaStream
|
||||
{
|
||||
PCLASSINFO(FSUDPMediaStream, OpalUDPMediaStream);
|
||||
public:
|
||||
FSUDPMediaStream(OpalConnection & connection, const OpalMediaFormat &mediaFormat,
|
||||
unsigned sessionID,
|
||||
BOOL isSource,
|
||||
OpalTransportUDP &transport);
|
||||
|
||||
~FSUDPMediaStream();
|
||||
|
||||
};
|
||||
|
||||
#endif// __FREESWITCH_OPAL_CONNECTION__
|
239
src/mod/endpoints/mod_opal/mod_opal.cpp
Normal file
239
src/mod/endpoints/mod_opal/mod_opal.cpp
Normal file
@ -0,0 +1,239 @@
|
||||
|
||||
#include <switch.h>
|
||||
#include <ptlib.h>
|
||||
#include <ptlib/svcproc.h>
|
||||
#include "mod_opal.h"
|
||||
#include "fsmanager.h"
|
||||
#include "fscon.h"
|
||||
|
||||
|
||||
static switch_call_cause_t opalfs_outgoing_channel(switch_core_session_t *, switch_caller_profile_t *, switch_core_session_t **, switch_memory_pool_t **);
|
||||
static switch_status_t opalfs_read_frame(switch_core_session_t *, switch_frame_t **, int, switch_io_flag_t, int);
|
||||
static switch_status_t opalfs_write_frame(switch_core_session_t *, switch_frame_t *, int, switch_io_flag_t, int);
|
||||
static switch_status_t opalfs_kill_channel(switch_core_session_t *, int);
|
||||
static switch_status_t opalfs_waitfor_read(switch_core_session_t *, int, int);
|
||||
static switch_status_t opalfs_waitfor_write(switch_core_session_t *, int, int);
|
||||
static switch_status_t opalfs_send_dtmf(switch_core_session_t *, char *);
|
||||
static switch_status_t opalfs_receive_message(switch_core_session_t *, switch_core_session_message_t *);
|
||||
static switch_status_t opalfs_receive_event(switch_core_session_t *, switch_event_t *);
|
||||
static switch_status_t opalfs_state_change(switch_core_session_t *);
|
||||
static switch_status_t opalfs_read_video_frame(switch_core_session_t *, switch_frame_t **, int, switch_io_flag_t, int);
|
||||
static switch_status_t opalfs_write_video_frame(switch_core_session_t *, switch_frame_t *, int, switch_io_flag_t, int);
|
||||
|
||||
|
||||
|
||||
static switch_status_t opalfs_on_init(switch_core_session_t *session);
|
||||
static switch_status_t opalfs_on_ring(switch_core_session_t *session);
|
||||
static switch_status_t opalfs_on_execute(switch_core_session_t *session);
|
||||
static switch_status_t opalfs_on_hangup(switch_core_session_t *session);
|
||||
static switch_status_t opalfs_on_loopback(switch_core_session_t *session);
|
||||
static switch_status_t opalfs_on_transmit(switch_core_session_t *session);
|
||||
|
||||
|
||||
static switch_memory_pool_t *opal_pool = NULL;
|
||||
switch_endpoint_interface_t *opalfs_endpoint_interface = NULL;
|
||||
static FSManager *opal_manager = NULL;
|
||||
|
||||
|
||||
class _FSOpalProcess : public PProcess
|
||||
{
|
||||
PCLASSINFO(_FSOpalProcess, PProcess)
|
||||
public:
|
||||
_FSOpalProcess(){PTrace::SetLevel(PSystemLog::Info);}; //just for fun and eyecandy ;)
|
||||
void Main() {};
|
||||
} FSOpalProcess;
|
||||
|
||||
|
||||
|
||||
static switch_io_routines_t opalfs_io_routines = {
|
||||
/*.outgoing_channel */ opalfs_outgoing_channel,
|
||||
/*.read_frame */ opalfs_read_frame,
|
||||
/*.write_frame */ opalfs_write_frame,
|
||||
/*.kill_channel */ opalfs_kill_channel,
|
||||
/*.waitfor_read */ opalfs_waitfor_read,
|
||||
/*.waitfor_read */ opalfs_waitfor_write,
|
||||
/*.send_dtmf */ opalfs_send_dtmf,
|
||||
/*.receive_message */ opalfs_receive_message,
|
||||
/*.receive_event */ opalfs_receive_event,
|
||||
/*.state_change*/ opalfs_state_change,
|
||||
/*.read_video_frame*/ opalfs_read_video_frame,
|
||||
/*.write_video_frame*/ opalfs_write_video_frame
|
||||
};
|
||||
|
||||
static switch_state_handler_table_t opalfs_event_handlers = {
|
||||
/*.on_init */ opalfs_on_init,
|
||||
/*.on_ring */ opalfs_on_ring,
|
||||
/*.on_execute */ opalfs_on_execute,
|
||||
/*.on_hangup */ opalfs_on_hangup,
|
||||
/*.on_loopback */ opalfs_on_loopback,
|
||||
/*.on_transmit */ opalfs_on_transmit
|
||||
};
|
||||
|
||||
|
||||
SWITCH_MODULE_LOAD_FUNCTION(mod_opal_load);
|
||||
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_opal_shutdown);
|
||||
SWITCH_MODULE_DEFINITION(mod_opal, mod_opal_load, mod_opal_shutdown, NULL);
|
||||
|
||||
SWITCH_MODULE_LOAD_FUNCTION(mod_opal_load)
|
||||
{
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE,"Starting loading mod_opal\n");
|
||||
opal_pool = pool;
|
||||
|
||||
*module_interface =NULL;
|
||||
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
|
||||
|
||||
if(!module_interface){
|
||||
return SWITCH_STATUS_MEMERR;
|
||||
}
|
||||
|
||||
opalfs_endpoint_interface = (switch_endpoint_interface_t*)switch_loadable_module_create_interface(*module_interface, SWITCH_ENDPOINT_INTERFACE);
|
||||
opalfs_endpoint_interface->interface_name = "opalFS";
|
||||
opalfs_endpoint_interface->io_routines = &opalfs_io_routines;
|
||||
opalfs_endpoint_interface->state_handler = &opalfs_event_handlers;
|
||||
|
||||
opal_manager = new FSManager();
|
||||
|
||||
if(!opal_manager) {
|
||||
return SWITCH_STATUS_MEMERR;
|
||||
}
|
||||
|
||||
if(!opal_manager->Initialize(pool)){
|
||||
delete opal_manager;
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Opal manager initilaized and running\n");
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_opal_shutdown)
|
||||
{
|
||||
delete opal_manager;
|
||||
opal_manager = NULL;
|
||||
opal_pool = NULL;
|
||||
opalfs_endpoint_interface = NULL;
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static switch_call_cause_t opalfs_outgoing_channel(switch_core_session_t *session,
|
||||
switch_caller_profile_t *outbound_profile,
|
||||
switch_core_session_t **new_session,
|
||||
switch_memory_pool_t **pool)
|
||||
{
|
||||
fs_obj_t* tech_prv = (fs_obj_t*)switch_core_session_get_private(session);
|
||||
|
||||
return SWITCH_CAUSE_SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
static switch_status_t opalfs_read_frame(switch_core_session_t *session, switch_frame_t **frame, int timeout, switch_io_flag_t flags, int stream_id)
|
||||
{
|
||||
fs_obj_t* tech_prv = (fs_obj_t*)switch_core_session_get_private(session);
|
||||
|
||||
return tech_prv->Connection->io_read_frame(session, frame, timeout, flags, stream_id);
|
||||
}
|
||||
|
||||
static switch_status_t opalfs_write_frame(switch_core_session_t *session, switch_frame_t *frame, int timeout, switch_io_flag_t flags, int stream_id)
|
||||
{
|
||||
fs_obj_t* tech_prv = (fs_obj_t*)switch_core_session_get_private(session);
|
||||
|
||||
return tech_prv->Connection->io_write_frame(session, frame, timeout, flags, stream_id);
|
||||
}
|
||||
|
||||
static switch_status_t opalfs_kill_channel(switch_core_session_t *session, int sig)
|
||||
{
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static switch_status_t opalfs_waitfor_read(switch_core_session_t *session, int ms, int stream_id)
|
||||
{
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Waitfor read!!!\n");
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static switch_status_t opalfs_waitfor_write(switch_core_session_t *session, int ms, int stream_id)
|
||||
{
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Waitfor write!!!\n");
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static switch_status_t opalfs_send_dtmf(switch_core_session_t *session, char *dtmf)
|
||||
{
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static switch_status_t opalfs_receive_message(switch_core_session_t *session, switch_core_session_message_t *msg)
|
||||
{
|
||||
fs_obj_t* tech_prv = (fs_obj_t*) switch_core_session_get_private(session);
|
||||
|
||||
return tech_prv->Connection->io_receive_message(session, msg);
|
||||
}
|
||||
|
||||
static switch_status_t opalfs_receive_event(switch_core_session_t *session, switch_event_t *event)
|
||||
{
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static switch_status_t opalfs_state_change(switch_core_session_t *session)
|
||||
{
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static switch_status_t opalfs_read_video_frame(switch_core_session_t *session, switch_frame_t **frame, int timeout, switch_io_flag_t flag, int stream_id)
|
||||
{
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static switch_status_t opalfs_write_video_frame(switch_core_session_t *session, switch_frame_t *frame, int timeout, switch_io_flag_t flag, int stream_id)
|
||||
{
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static switch_status_t opalfs_on_init(switch_core_session_t *session)
|
||||
{
|
||||
fs_obj_t* fs_pvt = (fs_obj_t*)switch_core_session_get_private(session);
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
return fs_pvt->Connection->callback_on_init(session);
|
||||
}
|
||||
|
||||
static switch_status_t opalfs_on_ring(switch_core_session_t *session)
|
||||
{
|
||||
fs_obj_t* tech_prv = (fs_obj_t*)switch_core_session_get_private(session);
|
||||
|
||||
return tech_prv->Connection->callback_on_ring(session);
|
||||
}
|
||||
|
||||
static switch_status_t opalfs_on_execute(switch_core_session_t *session)
|
||||
{
|
||||
fs_obj_t* tech_prv = (fs_obj_t*)switch_core_session_get_private(session);
|
||||
|
||||
return tech_prv->Connection->callback_on_execute(session);
|
||||
}
|
||||
|
||||
static switch_status_t opalfs_on_hangup(switch_core_session_t *session)
|
||||
{
|
||||
fs_obj_t* tech_prv = (fs_obj_t*)switch_core_session_get_private(session);
|
||||
|
||||
return tech_prv->Connection->callback_on_hangup(session);
|
||||
}
|
||||
|
||||
static switch_status_t opalfs_on_loopback(switch_core_session_t *session)
|
||||
{
|
||||
fs_obj_t* tech_prv = (fs_obj_t*)switch_core_session_get_private(session);
|
||||
|
||||
return tech_prv->Connection->callback_on_loopback(session);;
|
||||
}
|
||||
|
||||
static switch_status_t opalfs_on_transmit(switch_core_session_t *session)
|
||||
{
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
12
src/mod/endpoints/mod_opal/mod_opal.h
Normal file
12
src/mod/endpoints/mod_opal/mod_opal.h
Normal file
@ -0,0 +1,12 @@
|
||||
|
||||
#ifndef __FREESWITCH_MOD_OPAL__
|
||||
#define __FREESWITCH_MOD_OPAL__
|
||||
|
||||
#define HAVE_APR
|
||||
#include <switch.h>
|
||||
#include <switch_version.h>
|
||||
#define MODNAME "mod_opal"
|
||||
|
||||
|
||||
|
||||
#endif /* __FREESWITCH_MOD_OPAL__ */
|
59
src/mod/endpoints/mod_opal/opal_h323.cxx
Normal file
59
src/mod/endpoints/mod_opal/opal_h323.cxx
Normal file
@ -0,0 +1,59 @@
|
||||
|
||||
#include "opal_h323.h"
|
||||
#include "opal_h323con.h"
|
||||
|
||||
FSH323EndPoint::FSH323EndPoint(OpalManager & manager)
|
||||
:H323EndPoint(manager), UseH323ExternalRTP(TRUE)
|
||||
{
|
||||
//if we have config option for using external rtp for h323,
|
||||
//please set UseH323ExternalRTP to TRUE
|
||||
|
||||
mediaformats+=OpalPCM16;
|
||||
mediaformats+=OpalG711uLaw;
|
||||
mediaformats+=OpalG711ALaw;
|
||||
mediaformats+=OpalG711_ULAW_64K;
|
||||
mediaformats+=OpalG711_ALAW_64K;
|
||||
mediaformats+=OpalGSM0610;
|
||||
mediaformats+=OpalPCM16_16KHZ;
|
||||
mediaformats+=OPAL_G729;
|
||||
mediaformats+=OPAL_G729A;
|
||||
mediaformats+=OPAL_G729B;
|
||||
mediaformats+=OPAL_G729AB;
|
||||
}
|
||||
|
||||
FSH323EndPoint::~FSH323EndPoint()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
OpalMediaFormatList FSH323EndPoint::GetMediaFormats() const
|
||||
{
|
||||
PTRACE(3, "GIMME MEDIA FORMAT");
|
||||
return mediaformats;
|
||||
}
|
||||
|
||||
|
||||
OpalConnection::AnswerCallResponse FSH323EndPoint::OnAnswerCall(OpalConnection & connection,
|
||||
const PString & caller)
|
||||
{
|
||||
return OpalConnection::AnswerCallPending;
|
||||
}
|
||||
|
||||
|
||||
H323Connection * FSH323EndPoint::CreateConnection(OpalCall & call,
|
||||
const PString & token,
|
||||
void * userData,
|
||||
OpalTransport & transport,
|
||||
const PString & alias,
|
||||
const H323TransportAddress & address,
|
||||
H323SignalPDU * setupPDU,
|
||||
unsigned options,
|
||||
OpalConnection::StringOptions * stringOptions)
|
||||
|
||||
{
|
||||
if (UseH323ExternalRTP)
|
||||
return new FSH323Connection(call, *this, token, alias, address, options);
|
||||
|
||||
return new H323Connection(call, *this, token, alias, address, options);
|
||||
}
|
43
src/mod/endpoints/mod_opal/opal_h323.h
Normal file
43
src/mod/endpoints/mod_opal/opal_h323.h
Normal file
@ -0,0 +1,43 @@
|
||||
#ifndef __OPAL_H323_ENDPOINT__
|
||||
#define __OPAL_H323_ENDPOINT__
|
||||
|
||||
#include <ptlib.h>
|
||||
#include <opal/buildopts.h>
|
||||
#include <opal/endpoint.h>
|
||||
#include <h323/h323ep.h>
|
||||
#include <h323/h323con.h>
|
||||
#include "opal_h323con.h"
|
||||
|
||||
|
||||
|
||||
class FSH323EndPoint : public H323EndPoint
|
||||
{
|
||||
PCLASSINFO(FSH323EndPoint, H323EndPoint);
|
||||
public:
|
||||
FSH323EndPoint(OpalManager & manager);
|
||||
~FSH323EndPoint();
|
||||
|
||||
virtual OpalConnection::AnswerCallResponse OnAnswerCall(OpalConnection & connection,
|
||||
const PString & caller);
|
||||
|
||||
virtual OpalMediaFormatList GetMediaFormats() const;
|
||||
|
||||
H323Connection * CreateConnection(OpalCall & call,
|
||||
const PString & token,
|
||||
void * userData,
|
||||
OpalTransport & transport,
|
||||
const PString & alias,
|
||||
const H323TransportAddress & address,
|
||||
H323SignalPDU * setupPDU,
|
||||
unsigned options,
|
||||
OpalConnection::StringOptions * stringOptions);
|
||||
|
||||
BOOL isExternalRTPEnabled(){return UseH323ExternalRTP;};
|
||||
|
||||
protected:
|
||||
BOOL UseH323ExternalRTP;
|
||||
OpalMediaFormatList mediaformats;
|
||||
};
|
||||
|
||||
|
||||
#endif //__OPAL_H323_ENDPOINT__
|
88
src/mod/endpoints/mod_opal/opal_h323con.cxx
Normal file
88
src/mod/endpoints/mod_opal/opal_h323con.cxx
Normal file
@ -0,0 +1,88 @@
|
||||
|
||||
#include "opal_h323.h"
|
||||
#include "opal_h323con.h"
|
||||
|
||||
|
||||
FSExternalRTPChannel::FSExternalRTPChannel(H323Connection & connection, ///< Connection to endpoint for channel
|
||||
const H323Capability & capability, ///< Capability channel is using
|
||||
Directions direction, ///< Direction of channel
|
||||
unsigned sessionID) ///< Session ID for channel)
|
||||
|
||||
: H323_ExternalRTPChannel(connection, capability, direction, sessionID)
|
||||
{
|
||||
PTRACE(3,"Creating External RTP Channel");
|
||||
|
||||
PIPSocket::Address addr("10.0.0.1");
|
||||
WORD port = 41004;
|
||||
SetExternalAddress(H323TransportAddress(addr, port), H323TransportAddress(addr, port+1));
|
||||
|
||||
// get the payload code
|
||||
PTRACE(3, "Channel Capability " << capability.GetFormatName());
|
||||
OpalMediaFormat format(capability.GetFormatName());
|
||||
payloadCode = format.GetPayloadType();
|
||||
|
||||
Start();
|
||||
}
|
||||
|
||||
BOOL FSExternalRTPChannel::Start()
|
||||
{
|
||||
if (!H323_ExternalRTPChannel::Start())
|
||||
return FALSE;
|
||||
|
||||
PIPSocket::Address addr;
|
||||
WORD port;
|
||||
GetRemoteAddress(addr, port);
|
||||
PTRACE(3, "External RTP Channel Started ::Start");
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
FSH323Connection::FSH323Connection(OpalCall &call,FSH323EndPoint &endpoint,
|
||||
const PString & token,const PString &alias,
|
||||
const H323TransportAddress & address,unsigned options)
|
||||
|
||||
:H323Connection(call,endpoint,token,alias,address,options)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
FSH323Connection::~FSH323Connection()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
OpalMediaFormatList FSH323Connection::GetMediaFormats()
|
||||
{
|
||||
OpalMediaFormatList mediaformats;
|
||||
|
||||
mediaformats+=OpalPCM16;
|
||||
mediaformats+=OpalG711uLaw;
|
||||
mediaformats+=OpalG711ALaw;
|
||||
mediaformats+=OpalG711_ULAW_64K;
|
||||
mediaformats+=OpalG711_ALAW_64K;
|
||||
mediaformats+=OpalGSM0610;
|
||||
mediaformats+=OpalPCM16_16KHZ;
|
||||
mediaformats+=OPAL_G729;
|
||||
mediaformats+=OPAL_G729A;
|
||||
mediaformats+=OPAL_G729B;
|
||||
mediaformats+=OPAL_G729AB;
|
||||
PTRACE(3, "RTP Channel Callback !");
|
||||
|
||||
return mediaformats;
|
||||
}
|
||||
|
||||
/*
|
||||
H323Channel* FSH323Connection::CreateRealTimeLogicalChannel(const H323Capability & capability,
|
||||
H323Channel::Directions dir,
|
||||
unsigned sessionID,
|
||||
const H245_H2250LogicalChannelParameters * param,
|
||||
RTP_QOS * rtpqos)
|
||||
{
|
||||
|
||||
PTRACE(3, "RTP Channel Callback !");
|
||||
//h323 external rtp can be set from here
|
||||
return new FSExternalRTPChannel(*this, capability, dir, sessionID);
|
||||
}
|
||||
*/
|
51
src/mod/endpoints/mod_opal/opal_h323con.h
Normal file
51
src/mod/endpoints/mod_opal/opal_h323con.h
Normal file
@ -0,0 +1,51 @@
|
||||
|
||||
#ifndef __OPAL_H323_CONNECTION__
|
||||
#define __OPAL_H323_CONNECTION__
|
||||
|
||||
#include "opal_h323.h"
|
||||
#include "fsep.h"
|
||||
#include "fsmanager.h"
|
||||
|
||||
class FSH323EndPoint;
|
||||
|
||||
|
||||
class FSExternalRTPChannel : public H323_ExternalRTPChannel
|
||||
{
|
||||
PCLASSINFO(FSExternalRTPChannel, H323_ExternalRTPChannel);
|
||||
public:
|
||||
FSExternalRTPChannel(H323Connection & connection, ///< Connection to endpoint for channel
|
||||
const H323Capability & capability, ///< Capability channel is using
|
||||
Directions direction, ///< Direction of channel
|
||||
unsigned sessionID ); ///< Session ID for channel
|
||||
|
||||
virtual BOOL Start();
|
||||
|
||||
protected:
|
||||
BYTE payloadCode;
|
||||
};
|
||||
|
||||
|
||||
class FSH323Connection : public H323Connection
|
||||
{
|
||||
PCLASSINFO(FSH323Connection, H323Connection);
|
||||
public:
|
||||
FSH323Connection(OpalCall &call, FSH323EndPoint &endpoint,
|
||||
const PString & token,const PString &alias,
|
||||
const H323TransportAddress & address,unsigned options = 0);
|
||||
|
||||
//External H323 RTP
|
||||
/*
|
||||
H323Channel* CreateRealTimeLogicalChannel(const H323Capability & capability,
|
||||
H323Channel::Directions dir,
|
||||
unsigned sessionID,
|
||||
const H245_H2250LogicalChannelParameters * param,
|
||||
RTP_QOS * rtpqos);
|
||||
*/
|
||||
|
||||
virtual OpalMediaFormatList GetMediaFormats();
|
||||
|
||||
~FSH323Connection();
|
||||
|
||||
};
|
||||
|
||||
#endif // __FREESWITCH_H323_CONNECTION__
|
42
src/mod/endpoints/mod_opal/opal_sip.cxx
Normal file
42
src/mod/endpoints/mod_opal/opal_sip.cxx
Normal file
@ -0,0 +1,42 @@
|
||||
|
||||
#include "opal_sip.h"
|
||||
|
||||
FSSIPEndPoint::FSSIPEndPoint(OpalManager & manager)
|
||||
:SIPEndPoint(manager)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
FSSIPEndPoint::~FSSIPEndPoint()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
BOOL FSSIPEndPoint::OnIncomingConnection (OpalConnection &connection)
|
||||
{
|
||||
const char *destination = connection.GetCalledDestinationNumber();
|
||||
|
||||
|
||||
PTRACE(3, "FSSIPEndPoint: Answering Incomming Call "<< "' To '" << destination << "'");
|
||||
|
||||
GetManager().MakeConnection(connection.GetCall(), "fs:", (void *) destination);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
OpalConnection::AnswerCallResponse FSSIPEndPoint::OnAnswerCall(OpalConnection & connection,
|
||||
const PString & caller)
|
||||
{
|
||||
const char *destination = connection.GetCalledDestinationNumber();
|
||||
|
||||
|
||||
PTRACE(3, "FSSIPEndPoint: Answering Incomming Call from '" << caller << "' To '" << destination << "'");
|
||||
|
||||
//OpalManager &manager = connection.GetEndPoint().GetManager();
|
||||
//OpalCall & call = connection.GetCall();
|
||||
|
||||
|
||||
//manager.MakeConnection(call, "fs", (void *) destination);
|
||||
|
||||
return OpalConnection::AnswerCallPending;
|
||||
}
|
25
src/mod/endpoints/mod_opal/opal_sip.h
Normal file
25
src/mod/endpoints/mod_opal/opal_sip.h
Normal file
@ -0,0 +1,25 @@
|
||||
|
||||
#ifndef __OPAL_SIP_ENDPOINT__
|
||||
#define __OPAL_SIP_ENDPOINT__
|
||||
|
||||
#include <ptlib.h>
|
||||
#include <opal/buildopts.h>
|
||||
#include <opal/endpoint.h>
|
||||
#include <sip/sipep.h>
|
||||
|
||||
|
||||
|
||||
class FSSIPEndPoint : public SIPEndPoint
|
||||
{
|
||||
PCLASSINFO(FSSIPEndPoint, SIPEndPoint);
|
||||
public:
|
||||
FSSIPEndPoint(OpalManager & manager);
|
||||
~FSSIPEndPoint();
|
||||
|
||||
virtual BOOL OnIncomingConnection (OpalConnection &connection);
|
||||
virtual OpalConnection::AnswerCallResponse OnAnswerCall(OpalConnection & connection,
|
||||
const PString & caller);
|
||||
};
|
||||
|
||||
|
||||
#endif //__OPAL_SIP_ENDPOINT__
|
Loading…
Reference in New Issue
Block a user