]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
new codebase, does not work for now, but does the things in opal way
authorTuyan Özipek <tuyanozipek@gmail.com>
Mon, 12 Nov 2007 23:14:55 +0000 (23:14 +0000)
committerTuyan Özipek <tuyanozipek@gmail.com>
Mon, 12 Nov 2007 23:14:55 +0000 (23:14 +0000)
and media flows in rtp.

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@6225 d0543943-73ff-0310-b7d9-9358b9ac24b2

16 files changed:
src/mod/endpoints/mod_opal/fscon.cxx [new file with mode: 0644]
src/mod/endpoints/mod_opal/fscon.h [new file with mode: 0644]
src/mod/endpoints/mod_opal/fsep.cxx [new file with mode: 0644]
src/mod/endpoints/mod_opal/fsep.h [new file with mode: 0644]
src/mod/endpoints/mod_opal/fsmanager.cxx [new file with mode: 0644]
src/mod/endpoints/mod_opal/fsmanager.h [new file with mode: 0644]
src/mod/endpoints/mod_opal/fsmediastream.cxx [new file with mode: 0644]
src/mod/endpoints/mod_opal/fsmediastream.h [new file with mode: 0644]
src/mod/endpoints/mod_opal/mod_opal.cpp [new file with mode: 0644]
src/mod/endpoints/mod_opal/mod_opal.h [new file with mode: 0644]
src/mod/endpoints/mod_opal/opal_h323.cxx [new file with mode: 0644]
src/mod/endpoints/mod_opal/opal_h323.h [new file with mode: 0644]
src/mod/endpoints/mod_opal/opal_h323con.cxx [new file with mode: 0644]
src/mod/endpoints/mod_opal/opal_h323con.h [new file with mode: 0644]
src/mod/endpoints/mod_opal/opal_sip.cxx [new file with mode: 0644]
src/mod/endpoints/mod_opal/opal_sip.h [new file with mode: 0644]

diff --git a/src/mod/endpoints/mod_opal/fscon.cxx b/src/mod/endpoints/mod_opal/fscon.cxx
new file mode 100644 (file)
index 0000000..9dfd13b
--- /dev/null
@@ -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;
+}
+
diff --git a/src/mod/endpoints/mod_opal/fscon.h b/src/mod/endpoints/mod_opal/fscon.h
new file mode 100644 (file)
index 0000000..0f3bf52
--- /dev/null
@@ -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__
+
diff --git a/src/mod/endpoints/mod_opal/fsep.cxx b/src/mod/endpoints/mod_opal/fsep.cxx
new file mode 100644 (file)
index 0000000..9ed21dd
--- /dev/null
@@ -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;        
+}
diff --git a/src/mod/endpoints/mod_opal/fsep.h b/src/mod/endpoints/mod_opal/fsep.h
new file mode 100644 (file)
index 0000000..60ed4d3
--- /dev/null
@@ -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__
diff --git a/src/mod/endpoints/mod_opal/fsmanager.cxx b/src/mod/endpoints/mod_opal/fsmanager.cxx
new file mode 100644 (file)
index 0000000..f731bf3
--- /dev/null
@@ -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;
+}
diff --git a/src/mod/endpoints/mod_opal/fsmanager.h b/src/mod/endpoints/mod_opal/fsmanager.h
new file mode 100644 (file)
index 0000000..50f491b
--- /dev/null
@@ -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__
diff --git a/src/mod/endpoints/mod_opal/fsmediastream.cxx b/src/mod/endpoints/mod_opal/fsmediastream.cxx
new file mode 100644 (file)
index 0000000..57a2611
--- /dev/null
@@ -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()
+{
+
+}
diff --git a/src/mod/endpoints/mod_opal/fsmediastream.h b/src/mod/endpoints/mod_opal/fsmediastream.h
new file mode 100644 (file)
index 0000000..f7ce283
--- /dev/null
@@ -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__
diff --git a/src/mod/endpoints/mod_opal/mod_opal.cpp b/src/mod/endpoints/mod_opal/mod_opal.cpp
new file mode 100644 (file)
index 0000000..b1f225f
--- /dev/null
@@ -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;
+}
+
+
+
+
+
+
diff --git a/src/mod/endpoints/mod_opal/mod_opal.h b/src/mod/endpoints/mod_opal/mod_opal.h
new file mode 100644 (file)
index 0000000..39a290f
--- /dev/null
@@ -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__ */
diff --git a/src/mod/endpoints/mod_opal/opal_h323.cxx b/src/mod/endpoints/mod_opal/opal_h323.cxx
new file mode 100644 (file)
index 0000000..d8dfe42
--- /dev/null
@@ -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);
+}
diff --git a/src/mod/endpoints/mod_opal/opal_h323.h b/src/mod/endpoints/mod_opal/opal_h323.h
new file mode 100644 (file)
index 0000000..9d51952
--- /dev/null
@@ -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__
diff --git a/src/mod/endpoints/mod_opal/opal_h323con.cxx b/src/mod/endpoints/mod_opal/opal_h323con.cxx
new file mode 100644 (file)
index 0000000..15fe137
--- /dev/null
@@ -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);     
+}
+*/
diff --git a/src/mod/endpoints/mod_opal/opal_h323con.h b/src/mod/endpoints/mod_opal/opal_h323con.h
new file mode 100644 (file)
index 0000000..695c63d
--- /dev/null
@@ -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__
diff --git a/src/mod/endpoints/mod_opal/opal_sip.cxx b/src/mod/endpoints/mod_opal/opal_sip.cxx
new file mode 100644 (file)
index 0000000..6d6ee4b
--- /dev/null
@@ -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;
+}
diff --git a/src/mod/endpoints/mod_opal/opal_sip.h b/src/mod/endpoints/mod_opal/opal_sip.h
new file mode 100644 (file)
index 0000000..85061b1
--- /dev/null
@@ -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__