diff --git a/src/mod/endpoints/mod_opal/mod_opalh323.cpp b/src/mod/endpoints/mod_opal/mod_opalh323.cpp index 7c44c3bee8..fae797cc45 100644 --- a/src/mod/endpoints/mod_opal/mod_opalh323.cpp +++ b/src/mod/endpoints/mod_opal/mod_opalh323.cpp @@ -32,13 +32,68 @@ #include "mod_opalh323.h" - -/* All gluer frontend function for Freeswitch must be - * "C" functions. Because OPAL is written in C++ - * I implemented module gluer functions as extern "C" +#inlcude "opalh323_backend.h" +#include + +/* + * IO routines handlers definitions */ -extern "C" { - +static switch_call_cause_t opalh323_outgoing_channel(switch_core_session_t *, switch_caller_profile_t *, switch_core_session_t **, switch_memory_pool_t **); +static switch_status_t opalh323_read_frame(switch_core_session_t *, switch_frame_t **, int, switch_io_flag_t, int); +static switch_status_t opalh323_write_frame(switch_core_session_t *, switch_frame_t *, int, switch_io_flag_t, int); +static switch_status_t opalh323_kill_channel(switch_core_session_t *, int); +static switch_status_t opalh323_waitfor_read(switch_core_session_t *, int, int); +static switch_status_t opalh323_waitfor_write(switch_core_session_t *, int, int); +static switch_status_t opalh323_send_dtmf(switch_core_session_t *, char *); +static switch_status_t opalh323_receive_message(switch_core_session_t *, switch_core_session_message_t *); +static switch_status_t opalh323_receive_event(switch_core_session_t *, switch_event_t *); +static switch_status_t opalh323_state_change(switch_core_session_t *); +static switch_status_t opalh323_read_video_frame(switch_core_session_t *, switch_frame_t **, int, switch_io_flag_t, int); +static switch_status_t opalh323_write_video_frame(switch_core_session_t *, switch_frame_t *, int, switch_io_flag_t, int); +/* + * Event handlers declaration + */ +static switch_status_t opalh323_on_init(switch_core_session_t *session); +static switch_status_t opalh323_on_ring(switch_core_session_t *session); +static switch_status_t opalh323_on_execute(switch_core_session_t *session); +static switch_status_t opalh323_on_hangup(switch_core_session_t *session); +static switch_status_t opalh323_on_loopback(switch_core_session_t *session); +static switch_status_t opalh323_on_transmit(switch_core_session_t *session); + +/** + * Declaration of private variables + */ +static FSOpalManager *opalh323_manager = NULL; +static switch_memory_pool_t *opalh323_pool = NULL; +static switch_endpoint_interface_t *opalh323_endpoint_interface; + +/* + * IO routines handlers set declaration + */ +static switch_io_routines_t opalh323_io_routines = { + /*.outgoing_channel */ opalh323_outgoing_channel, + /*.read_frame */ opalh323_read_frame, + /*.write_frame */ opalh323_write_frame, + /*.kill_channel */ opalh323_kill_channel, + /*.waitfor_read */ opalh323_waitfor_read, + /*.waitfor_read */ opalh323_waitfor_write, + /*.send_dtmf */ opalh323_send_dtmf, + /*.receive_message */ opalh323_receive_message, + /*.receive_event */ opalh323_receive_event, + /*.state_change*/ opalh323_state_change, + /*.read_video_frame*/ opalh323_read_video_frame, + /*.write_video_frame*/ opalh323_write_video_frame +}; + +static switch_state_handler_table_t opalh323_event_handlers = { + /*.on_init */ opalh323_on_init, + /*.on_ring */ opalh323_on_ring, + /*.on_execute */ opalh323_on_execute, + /*.on_hangup */ opalh323_on_hangup, + /*.on_loopback */ opalh323_on_loopback, + /*.on_transmit */ opalh323_on_transmit +}; + /* * Loadable FreeSWITCH module functions declaration */ @@ -61,6 +116,35 @@ switch_endpoint_interface_t *opalh323_endpoint_interface; */ SWITCH_MODULE_LOAD_FUNCTION(mod_opalh323_load) { + + /* frontend initialization*/ + *module_interface =NULL; + *module_interface = switch_loadable_module_create_module_interface(pool, modname); + + assert(*module_interface); + if(!module_interface) + { + return SWITCH_STATUS_MEMERR; + } + opalh323_endpoint_interface = switch_loadable_module_create_interface(*module_interface, SWITCH_ENDPOINT_INTERFACE); + opalh323_endpoint_interface->interface_name = "OPALH323"; + opalh323_endpoint_interface->io_routines = &opalh323_io_routines; + opalh323_endpoint_interface->state_handler = &opalh323_event_handlers; + + /* backend initialization */ + opalh323_manager = new FSOpalManager(); + assert(opalh323_manager); + if(!opalh323_manager) + { + return SWITCH_STATUS_MEMERR; + } + + if(!opalh323_manager->initialize(pool)) + { + delete opalh323_manager; + return SWITCH_STATUS_FALSE; /* if can't initialize return general error */ + } + /* indicate that the module should continue to be loaded */ return SWITCH_STATUS_SUCCESS; } @@ -71,29 +155,19 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_opalh323_load) * it dealocates OPAL core * */ -SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_sofia_shutdown) +SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_opalh323_shutdown) { + + /* deallocate OPAL manager */ + delete opalh323_manager; + return SWITCH_STATUS_SUCCESS; } -/* - * IO routines handlers - */ -static switch_io_routines_t opalh323_io_routines = { - /*.outgoing_channel */ opalh323_outgoing_channel, - /*.read_frame */ opalh323_read_frame, - /*.write_frame */ opalh323_write_frame, - /*.kill_channel */ opalh323_kill_channel, - /*.waitfor_read */ opalh323_waitfor_read, - /*.waitfor_read */ opalh323_waitfor_write, - /*.send_dtmf */ opalh323_send_dtmf, - /*.receive_message */ opalh323_receive_message, - /*.receive_event */ opalh323_receive_event, - /*.state_change*/ opalh323_state_change, - /*.read_video_frame*/ opalh323_read_video_frame, - /*.write_video_frame*/ opalh323_write_video_frame -}; +/* + * IO routines handlers definitions + */ static switch_call_cause_t opalh323_outgoing_channel(switch_core_session_t *, switch_caller_profile_t *, switch_core_session_t **, switch_memory_pool_t **) { return 0; @@ -157,14 +231,6 @@ static switch_status_t opalh323_write_video_frame(switch_core_session_t *, switc /* * Event handlers */ -static switch_state_handler_table_t opalh323_event_handlers = { - /*.on_init */ opalh323_on_init, - /*.on_ring */ opalh323_on_ring, - /*.on_execute */ opalh323_on_execute, - /*.on_hangup */ opalh323_on_hangup, - /*.on_loopback */ opalh323_on_loopback, - /*.on_transmit */ opalh323_on_transmit -}; static switch_status_t opalh323_on_init(switch_core_session_t *session) { @@ -195,7 +261,3 @@ static switch_status_t opalh323_on_transmit(switch_core_session_t *session) { return SWITCH_STATUS_SUCCESS; } - - - -} diff --git a/src/mod/endpoints/mod_opal/opalh323_backend.cpp b/src/mod/endpoints/mod_opal/opalh323_backend.cpp index 0e2eb7198a..9340c186d1 100644 --- a/src/mod/endpoints/mod_opal/opalh323_backend.cpp +++ b/src/mod/endpoints/mod_opal/opalh323_backend.cpp @@ -27,3 +27,227 @@ * Initial revision */ +#include +#include "opalh323_backend.h" +#include + +/** + * Private structre + */ + +typedef struct OpalH323Private_s +{ + OpalConnection *m_opalConnection; /** pointer to OpalConnection object */ + switch_mutex_t *m_mutex; /** mutex for synchonizing access to session object */ + +} OpalH323Private_t; + + + +/** Default constructor + * + */ +FSOpalManager::FSOpalManager() : + m_isInitialized(false), + m_pH323Endpoint(NULL); + m_pMemoryPool(NULL) +{ + +} + +/** Destructor + * + */ +~FSOpalManager::FSOpalManager() +{ + /** + * Destroy all allocated resources, if any + */ + if(m_isInitialized) + { + delete m_pH323Endpoint; + m_pH323Endpoint = NULL; + m_isInitialized = false; + } +} + + /** + * Method does real initialization of the manager + */ +bool FSOpalManager::initialize( + switch_memory_pool_t *i_memoryPool, + switch_endpoint_interface_t *i_endpointInterface + ) +{ + bool result = true; + + /* check if everything is not initialized */ + assert(m_isInitialized); + assert(!m_pH323Endpoint); + assert(!m_pMemoryPool) + + /* check input parameters */ + assert(i_memoryPool); + assert(i_endpointInterface); + + + + m_pMemoryPool = i_memoryPool; + m_pEndpointInterface = i_endpointInterface; + + /* create h323 endpoint */ + m_pH323Endpoint = new H323EndPoint(this); ///TODO, replace prefix and signaling port by values from configuration + if(!m_pH323Endpoint) + { + assert(0); + return false; + } + + /** + * To do-> add codecs to capabilities (for call contol) + * m_pH323Endpoint->AddCapability(); + */ + + m_pH323Endpoint->DisableFastStart(false); ///TODO this should be configurable + m_pH323Endpoint->DisableH245Tunneling(false); ///TODO this should be configurable + + ///TODO gatekeeper use should be configurable, I think that sevral options should be implemented in config file: use, dont use, use one of specified with priorities, try to reconnect to the topmost... + ///TODO m_pH323Endpoint->SetInitialBandwidth(initialBandwidth); + ///TODO m_pH323Endpoint->SetVendorIdentifierInfo() + + ///TODO address should be configurable, should allow creaeing listeners on multiple interfaces + OpalTransportAddress opalTransportAddress("0.0.0.0",1720); //for time being create listener on all ip's and default port + result = m_pH323Endpoint->StartListeners(opalTransportAddress); + assert(result); + if(!result) + { + delete m_pH323Endpoint: + return false; + } + + /* at this point OPAL is ready to go */ + m_isInitialized = true; + return true; +} + + +BOOL FSOpalManager::OnIncomingConnection( + OpalConnection & connection, ///< Connection that is calling + unsigned options, ///< options for new connection (can't use default as overrides will fail) + OpalConnection::StringOptions * stringOptions + ) +{ + //TODO check if options and stringOptions fields ever apply + retrun OnIncomingConnection(connection); +} + +BOOL FSOpalManager::OnIncomingConnection( + OpalConnection & connection, ///< Connection that is calling + unsigned options ///< options for new connection (can't use default as overrides will fail) + ) +{ + //TODO, check if options field ever applies + retrun OnIncomingConnection(connection); +} + +BOOL FSOpalManager::OnIncomingConnection( + OpalConnection & connection ///< Connection that is calling + ) +{ + /* allocate new session in switch core*/ + switch_core_session_t *session = switch_core_session_request(m_pEndpointInterface , NULL); + assert(session); + if(!sesion) + { + ///TODO add cause to the connection + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Could not allocate session object?\n"); + return FALSE; + } + + /* allocate private resources */ + OpalH323Private_t *tech_pvt = (OpalH323Private_t *)switch_core_session_alloc(session, sizeof(OpalH323Private_t)); + assert(tech_pvt); + if(!tech_pvt) + { + ///TODO add cause to the connection + switch_core_session_destroy(&session); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Could not allocate private object?\n"); + return false; + } + tech_pvt->m_opalConnection = &connection; + switch_mutex_init(&tech_pvt->m_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session)); + /** save private data under hash and in session */ + + /***Mark incoming call as AnsweredPending ??? */ + + +} + + + + + + + +/** + * FS ON_INIT callback handler + * + */ +switch_status_t FSOpalManager::callback_on_init(switch_core_session_t *io_session) +{ + assert(m_isInitialized); + return SWITCH_STATUS_SUCCESS; +} + +/** + * FS ON_INIT callback handler + * + */ +switch_status_t FSOpalManager::callback_on_ring(switch_core_session_t *io_session) +{ + assert(m_isInitialized); + return SWITCH_STATUS_SUCCESS; +} + +/** + * FS ON_EXECUTE callback handler + * + */ +switch_status_t FSOpalManager::callback_on_execute(switch_core_session_t *io_session) +{ + assert(m_isInitialized); + return SWITCH_STATUS_SUCCESS; +} + +/** + * FS ON_HANGUP callback handler + * + */ +switch_status_t FSOpalManager::callback_on_hangup(switch_core_session_t *io_session) +{ + assert(m_isInitialized); + return SWITCH_STATUS_SUCCESS; +} + +/** + * FS ON_LOOPBACK callback handler + * + */ + +switch_status_t FSOpalManager::callback_on_loopback(switch_core_session_t *io_session) +{ + assert(m_isInitialized); + return SWITCH_STATUS_SUCCESS; +} + +/** + * FS ON_TRANSMIT callback handler + * + */ +switch_status_t FSOpalManager::callback_on_transmit(switch_core_session_t *io_session) +{ + assert(m_isInitialized); + return SWITCH_STATUS_SUCCESS; +} + + diff --git a/src/mod/endpoints/mod_opal/opalh323_backend.h b/src/mod/endpoints/mod_opal/opalh323_backend.h index 560f44338d..d25d9c73dd 100644 --- a/src/mod/endpoints/mod_opal/opalh323_backend.h +++ b/src/mod/endpoints/mod_opal/opalh323_backend.h @@ -26,3 +26,68 @@ * Revision 1.00 2007/10/24 07:29:52 lzwierko * Initial revision */ + +#ifndef __FREESWITCH_OPALH323_BACKEND__ +#define __FREESWITCH_OPALH323_BACKEND__ + +#include +#include +#include +#include + + +class H323EndPoint; + +/** This class is OpalManager implementation + * for FreeSWITCH OpalH323 module. + * All methods are inherited from base OpalManagerClass. + * Event callbacks will be filed with valid code + * Additional functions have been implemented to be called, or called by + */ +class FSOpalManager : public OpalManager +{ + PCLASSINFO(FSOpalManager, PObject); + +public: + + /** Default constructor + * + */ + FSOpalManager(); + + /** Destructor + * + */ + ~FSOpalManager(); + + /** + * Method does real initialization of the manager + */ + bool initialize( + switch_memory_pool_t* i_memoryPool, + switch_endpoint_interface_t *i_endpointInterface + ); + + /** FS callback handlers declarations + * + */ + 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 *io_session); + switch_status_t callback_on_transmit(switch_core_session_t *io_session); + +private: + + bool m_isInitilized; /* true if module has been initialized properly */ + H323Endpoint *m_pH323Endpoint; /* h323 endpoint control */ + switch_memory_pool_t *m_pMemoryPool; /* FS memory pool */ + switch_endpoint_interface_t *m_pEndpointInterface; /* FS endpoint inerface */ + + +}; + + + +#endif