+++ /dev/null
-/*
- * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
- * Copyright (C) 2005/2006, Anthony Minessale II <anthmct@yahoo.com>
- *
- * Version: MPL 1.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
- *
- * The Initial Developer of the Original Code is
- * Anthony Minessale II <anthmct@yahoo.com>
- * Portions created by the Initial Developer are Copyright (C)
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Anthony Minessale II <anthmct@yahoo.com>
- *
- *
- * mod_bridgecall.c -- Channel Bridge Application Module
- *
- */
-#include <switch.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-
-static const char modname[] = "mod_bridgecall";
-
-struct audio_bridge_data {
- switch_core_session *session_a;
- switch_core_session *session_b;
- int running;
-};
-
-static void *audio_bridge_thread(switch_thread *thread, void *obj)
-{
- struct switch_core_thread_session *data = obj;
-
- switch_channel *chan_a, *chan_b;
- switch_frame *read_frame;
- switch_core_session *session_a, *session_b;
-
- session_a = data->objs[0];
- session_b = data->objs[1];
-
- chan_a = switch_core_session_get_channel(session_a);
- chan_b = switch_core_session_get_channel(session_b);
-
- while(data->running > 0) {
- switch_channel_state b_state = switch_channel_get_state(chan_b);
-
- switch (b_state) {
-case CS_HANGUP:
- data->running = -1;
- continue;
- break;
-default:
- break;
- }
-
- if (switch_channel_has_dtmf(chan_a)) {
- char dtmf[128];
- switch_channel_dequeue_dtmf(chan_a, dtmf, sizeof(dtmf));
- switch_core_session_send_dtmf(session_b, dtmf);
- }
- if (switch_core_session_read_frame(session_a, &read_frame, -1) == SWITCH_STATUS_SUCCESS && read_frame->datalen) {
- if (switch_core_session_write_frame(session_b, read_frame, -1) != SWITCH_STATUS_SUCCESS) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "write: Bad Frame.... %d Bubye!\n", read_frame->datalen);
- data->running = -1;
- }
- } else {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "read: Bad Frame.... %d Bubye!\n", read_frame->datalen);
- data->running = -1;
- }
- }
-
- switch_channel_hangup(chan_b);
- data->running = 0;
-
- return NULL;
-}
-
-
-static switch_status audio_bridge_on_hangup(switch_core_session *session)
-{
- switch_core_session *other_session;
- switch_channel *channel = NULL, *other_channel = NULL;
-
- channel = switch_core_session_get_channel(session);
- assert(channel != NULL);
-
- other_session = switch_channel_get_private(channel);
- assert(other_session != NULL);
-
- other_channel = switch_core_session_get_channel(other_session);
- assert(other_channel != NULL);
-
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "CUSTOM HANGUP %s kill %s\n", switch_channel_get_name(channel), switch_channel_get_name(other_channel));
-
- switch_core_session_kill_channel(other_session, SWITCH_SIG_KILL);
- switch_core_session_kill_channel(session, SWITCH_SIG_KILL);
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-static switch_status audio_bridge_on_ring(switch_core_session *session)
-{
- switch_channel *channel = NULL;
-
- channel = switch_core_session_get_channel(session);
- assert(channel != NULL);
-
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "CUSTOM RING\n");
-
- /* put the channel in a passive state so we can loop audio to it */
- if (switch_channel_test_flag(channel, CF_OUTBOUND)) {
- switch_channel_set_state(channel, CS_TRANSMIT);
- return SWITCH_STATUS_FALSE;
- }
-
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-static const switch_event_handler_table audio_bridge_peer_event_handlers = {
- /*.on_init*/ NULL,
- /*.on_ring*/ audio_bridge_on_ring,
- /*.on_execute*/ NULL,
- /*.on_hangup*/ audio_bridge_on_hangup,
- /*.on_loopback*/ NULL,
- /*.on_transmit*/ NULL
-};
-
-static const switch_event_handler_table audio_bridge_caller_event_handlers = {
- /*.on_init*/ NULL,
- /*.on_ring*/ NULL,
- /*.on_execute*/ NULL,
- /*.on_hangup*/ audio_bridge_on_hangup,
- /*.on_loopback*/ NULL,
- /*.on_transmit*/ NULL
-};
-
-static void audio_bridge_function(switch_core_session *session, char *data)
-{
- switch_channel *caller_channel, *peer_channel;
- switch_core_session *peer_session;
- switch_caller_profile *caller_profile, *caller_caller_profile;
- char chan_type[128]= {'\0'}, *chan_data;
- int timelimit = 60; /* probably a useful option to pass in when there's time */
- caller_channel = switch_core_session_get_channel(session);
- assert(caller_channel != NULL);
-
-
- strncpy(chan_type, data, sizeof(chan_type));
-
- if ((chan_data = strchr(chan_type, '/'))) {
- *chan_data = '\0';
- chan_data++;
- }
-
- caller_caller_profile = switch_channel_get_caller_profile(caller_channel);
- caller_profile = switch_caller_profile_new(session,
- caller_caller_profile->dialplan,
- caller_caller_profile->caller_id_name,
- caller_caller_profile->caller_id_number,
- caller_caller_profile->network_addr,
- NULL,
- NULL,
- chan_data);
-
-
-
- if (switch_core_session_outgoing_channel(session, chan_type, caller_profile, &peer_session) != SWITCH_STATUS_SUCCESS) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "DOH!\n");
- switch_channel_hangup(caller_channel);
- return;
- } else {
- struct switch_core_thread_session this_audio_thread, other_audio_thread;
- time_t start;
-
- peer_channel = switch_core_session_get_channel(peer_session);
- memset(&other_audio_thread, 0, sizeof(other_audio_thread));
- memset(&this_audio_thread, 0, sizeof(this_audio_thread));
- other_audio_thread.objs[0] = session;
- other_audio_thread.objs[1] = peer_session;
- other_audio_thread.running = 5;
-
- this_audio_thread.objs[0] = peer_session;
- this_audio_thread.objs[1] = session;
- this_audio_thread.running = 2;
-
-
- switch_channel_set_private(caller_channel, peer_session);
- switch_channel_set_private(peer_channel, session);
- switch_channel_set_event_handlers(caller_channel, &audio_bridge_caller_event_handlers);
- switch_channel_set_event_handlers(peer_channel, &audio_bridge_peer_event_handlers);
- switch_core_session_thread_launch(peer_session);
-
- for(;;) {
- int state = switch_channel_get_state(peer_channel);
- if (state > CS_RING) {
- break;
- }
- switch_yield(1000);
- }
-
- time(&start);
- while(switch_channel_get_state(caller_channel) == CS_EXECUTE &&
- switch_channel_get_state(peer_channel) == CS_TRANSMIT &&
- !switch_channel_test_flag(peer_channel, CF_ANSWERED) &&
- ((time(NULL) - start) < timelimit)) {
- switch_yield(20000);
- }
-
- if (switch_channel_test_flag(peer_channel, CF_ANSWERED)) {
- switch_channel_answer(caller_channel);
-
- switch_core_session_launch_thread(session, audio_bridge_thread, (void *) &other_audio_thread);
- audio_bridge_thread(NULL, (void *) &this_audio_thread);
- switch_channel_hangup(peer_channel);
- if (other_audio_thread.running > 0) {
- other_audio_thread.running = -1;
- /* wait for the other audio thread */
- while (other_audio_thread.running) {
- switch_yield(1000);
- }
- }
-
-
- }
- }
-
- switch_channel_hangup(caller_channel);
- switch_channel_hangup(peer_channel);
-}
-
-
-static const switch_application_interface bridge_application_interface = {
- /*.interface_name*/ "bridge",
- /*.application_function*/ audio_bridge_function
-};
-
-
-static const switch_loadable_module_interface mod_bridgecall_module_interface = {
- /*.module_name = */ modname,
- /*.endpoint_interface = */ NULL,
- /*.timer_interface = */ NULL,
- /*.dialplan_interface = */ NULL,
- /*.codec_interface = */ NULL,
- /*.application_interface*/ &bridge_application_interface
-};
-
-SWITCH_MOD_DECLARE(switch_status) switch_module_load(const switch_loadable_module_interface **interface, char *filename) {
-
- /* connect my internal structure to the blank pointer passed to me */
- *interface = &mod_bridgecall_module_interface;
-
- /* indicate that the module should continue to be loaded */
- return SWITCH_STATUS_SUCCESS;
-}
+++ /dev/null
-<?xml version="1.0" encoding="Windows-1252"?>\r
-<VisualStudioProject\r
- ProjectType="Visual C++"\r
- Version="8.00"\r
- Name="mod_bridgecall"\r
- ProjectGUID="{E1794405-29D4-466D-9BE3-DD2344C2A663}"\r
- RootNamespace="mod_bridgecall"\r
- Keyword="Win32Proj"\r
- >\r
- <Platforms>\r
- <Platform\r
- Name="Win32"\r
- />\r
- </Platforms>\r
- <ToolFiles>\r
- </ToolFiles>\r
- <Configurations>\r
- <Configuration\r
- Name="Debug|Win32"\r
- OutputDirectory="Debug"\r
- IntermediateDirectory="Debug"\r
- ConfigurationType="2"\r
- InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
- CharacterSet="2"\r
- >\r
- <Tool\r
- Name="VCPreBuildEventTool"\r
- />\r
- <Tool\r
- Name="VCCustomBuildTool"\r
- />\r
- <Tool\r
- Name="VCXMLDataGeneratorTool"\r
- />\r
- <Tool\r
- Name="VCWebServiceProxyGeneratorTool"\r
- />\r
- <Tool\r
- Name="VCMIDLTool"\r
- />\r
- <Tool\r
- Name="VCCLCompilerTool"\r
- Optimization="0"\r
- AdditionalIncludeDirectories=""$(InputDir)..\..\include";"$(InputDir)include";"$(InputDir)..\..\..\libs\include""\r
- PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS"\r
- MinimalRebuild="true"\r
- BasicRuntimeChecks="3"\r
- RuntimeLibrary="1"\r
- UsePrecompiledHeader="0"\r
- WarningLevel="3"\r
- Detect64BitPortabilityProblems="true"\r
- DebugInformationFormat="4"\r
- />\r
- <Tool\r
- Name="VCManagedResourceCompilerTool"\r
- />\r
- <Tool\r
- Name="VCResourceCompilerTool"\r
- />\r
- <Tool\r
- Name="VCPreLinkEventTool"\r
- />\r
- <Tool\r
- Name="VCLinkerTool"\r
- OutputFile="..\..\..\w32\vsnet\$(OutDir)/mod/mod_bridgecall.dll"\r
- LinkIncremental="2"\r
- AdditionalLibraryDirectories="$(InputDir)..\..\libs\apr\Debug"\r
- GenerateDebugInformation="true"\r
- ProgramDatabaseFile="$(OutDir)/mod_bridgecall.pdb"\r
- SubSystem="2"\r
- ImportLibrary="$(OutDir)/mod_bridgecall.lib"\r
- TargetMachine="1"\r
- />\r
- <Tool\r
- Name="VCALinkTool"\r
- />\r
- <Tool\r
- Name="VCManifestTool"\r
- />\r
- <Tool\r
- Name="VCXDCMakeTool"\r
- />\r
- <Tool\r
- Name="VCBscMakeTool"\r
- />\r
- <Tool\r
- Name="VCFxCopTool"\r
- />\r
- <Tool\r
- Name="VCAppVerifierTool"\r
- />\r
- <Tool\r
- Name="VCWebDeploymentTool"\r
- />\r
- <Tool\r
- Name="VCPostBuildEventTool"\r
- />\r
- </Configuration>\r
- <Configuration\r
- Name="Release|Win32"\r
- OutputDirectory="Release"\r
- IntermediateDirectory="Release"\r
- ConfigurationType="2"\r
- InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
- CharacterSet="2"\r
- >\r
- <Tool\r
- Name="VCPreBuildEventTool"\r
- />\r
- <Tool\r
- Name="VCCustomBuildTool"\r
- />\r
- <Tool\r
- Name="VCXMLDataGeneratorTool"\r
- />\r
- <Tool\r
- Name="VCWebServiceProxyGeneratorTool"\r
- />\r
- <Tool\r
- Name="VCMIDLTool"\r
- />\r
- <Tool\r
- Name="VCCLCompilerTool"\r
- AdditionalIncludeDirectories=""$(InputDir)..\..\include";"$(InputDir)include";"$(InputDir)..\..\..\libs\include""\r
- PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS"\r
- RuntimeLibrary="0"\r
- UsePrecompiledHeader="0"\r
- WarningLevel="3"\r
- Detect64BitPortabilityProblems="true"\r
- DebugInformationFormat="3"\r
- />\r
- <Tool\r
- Name="VCManagedResourceCompilerTool"\r
- />\r
- <Tool\r
- Name="VCResourceCompilerTool"\r
- />\r
- <Tool\r
- Name="VCPreLinkEventTool"\r
- />\r
- <Tool\r
- Name="VCLinkerTool"\r
- OutputFile="..\..\..\w32\vsnet\$(OutDir)/mod/mod_bridgecall.dll"\r
- LinkIncremental="1"\r
- AdditionalLibraryDirectories=""$(InputDir)..\..\libs\apr\Release""\r
- GenerateDebugInformation="true"\r
- SubSystem="2"\r
- OptimizeReferences="2"\r
- EnableCOMDATFolding="2"\r
- ImportLibrary="$(OutDir)/mod_bridgecall.lib"\r
- TargetMachine="1"\r
- />\r
- <Tool\r
- Name="VCALinkTool"\r
- />\r
- <Tool\r
- Name="VCManifestTool"\r
- />\r
- <Tool\r
- Name="VCXDCMakeTool"\r
- />\r
- <Tool\r
- Name="VCBscMakeTool"\r
- />\r
- <Tool\r
- Name="VCFxCopTool"\r
- />\r
- <Tool\r
- Name="VCAppVerifierTool"\r
- />\r
- <Tool\r
- Name="VCWebDeploymentTool"\r
- />\r
- <Tool\r
- Name="VCPostBuildEventTool"\r
- />\r
- </Configuration>\r
- </Configurations>\r
- <References>\r
- </References>\r
- <Files>\r
- <Filter\r
- Name="Source Files"\r
- Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"\r
- UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"\r
- >\r
- <File\r
- RelativePath=".\mod_bridgecall.c"\r
- >\r
- </File>\r
- </Filter>\r
- <Filter\r
- Name="Header Files"\r
- Filter="h;hpp;hxx;hm;inl;inc;xsd"\r
- UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"\r
- >\r
- </Filter>\r
- <Filter\r
- Name="Resource Files"\r
- Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"\r
- UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"\r
- >\r
- </Filter>\r
- </Files>\r
- <Globals>\r
- </Globals>\r
-</VisualStudioProject>\r
+++ /dev/null
-CFLAGS += -I/usr/local/include/libg729
-LDFLAGS +=-lg729
-
-all: $(MOD).so
-
-$(MOD).so: $(MOD).c
- $(CC) $(CFLAGS) -fPIC -c $(MOD).c -o $(MOD).o
- $(CC) $(SOLINK) $(MOD).o -o $(MOD).so $(LDFLAGS) -lspeex
-
-clean:
- rm -fr *.so *.o *~
-
+++ /dev/null
-/* \r
- * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application\r
- * Copyright (C) 2005/2006, Anthony Minessale II <anthmct@yahoo.com>\r
- *\r
- * Version: MPL 1.1\r
- *\r
- * The contents of this file are subject to the Mozilla Public License Version\r
- * 1.1 (the "License"); you may not use this file except in compliance with\r
- * the License. You may obtain a copy of the License at\r
- * http://www.mozilla.org/MPL/\r
- *\r
- * Software distributed under the License is distributed on an "AS IS" basis,\r
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\r
- * for the specific language governing rights and limitations under the\r
- * License.\r
- *\r
- * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application\r
- *\r
- * The Initial Developer of the Original Code is\r
- * Anthony Minessale II <anthmct@yahoo.com>\r
- * Portions created by the Initial Developer are Copyright (C)\r
- * the Initial Developer. All Rights Reserved.\r
- *\r
- * Contributor(s):\r
- * \r
- * Anthony Minessale II <anthmct@yahoo.com>\r
- * Michael Jerris <mike@jerris.com>\r
- *\r
- * mod_codec_g729.c -- G729 Codec Module\r
- *\r
- */\r
-#include "switch.h"\r
-#include "g729.h"\r
-\r
-static const char modname[] = "mod_codec_g729";\r
-\r
-struct g729_context {\r
- struct dec_state decoder_object;\r
- struct cod_state encoder_object;\r
-};\r
-\r
-static switch_status switch_g729_init(switch_codec *codec, switch_codec_flag flags, const struct switch_codec_settings *codec_settings)\r
-{\r
- struct g729_context *context = NULL;\r
- int encoding, decoding;\r
-\r
- encoding = (flags & SWITCH_CODEC_FLAG_ENCODE);\r
- decoding = (flags & SWITCH_CODEC_FLAG_DECODE);\r
-\r
- if (!(encoding || decoding) || (!(context = switch_core_alloc(codec->memory_pool, sizeof(struct g729_context))))) {\r
- return SWITCH_STATUS_FALSE;\r
- } else {\r
- if (encoding) {\r
- g729_init_coder(&context->encoder_object, 0);\r
- }\r
- if (decoding) {\r
- g729_init_decoder(&context->decoder_object);\r
- }\r
-\r
- codec->private = context;\r
-\r
- return SWITCH_STATUS_SUCCESS;\r
- }\r
-}\r
-\r
-static switch_status switch_g729_destroy(switch_codec *codec)\r
-{\r
- codec->private = NULL;\r
- return SWITCH_STATUS_SUCCESS;\r
-}\r
-\r
-\r
-static switch_status switch_g729_encode(switch_codec *codec,\r
- switch_codec *other_codec,\r
- void *decoded_data,\r
- size_t decoded_data_len,\r
- int decoded_rate,\r
- void *encoded_data,\r
- size_t *encoded_data_len,\r
- int *encoded_rate,\r
- unsigned int *flag)\r
-{\r
- struct g729_context *context = codec->private;\r
- int cbret = 0;\r
-\r
- if (!context) {\r
- return SWITCH_STATUS_FALSE;\r
- }\r
- if (decoded_data_len % 160 == 0) {\r
- unsigned int new_len = 0;\r
- INT16 *ddp = decoded_data;\r
- char *edp = encoded_data;\r
- int x;\r
- int loops = (int) decoded_data_len / 160;\r
-\r
- for(x = 0; x < loops && new_len < *encoded_data_len; x++) {\r
- g729_coder(&context->encoder_object, ddp, edp, &cbret);\r
- edp += 10;\r
- ddp += 80;\r
- new_len += 10;\r
- }\r
- if( new_len <= *encoded_data_len ) {\r
- *encoded_data_len = new_len;\r
- } else {\r
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "buffer overflow!!! %u >= %u\n", new_len, *encoded_data_len);\r
- return SWITCH_STATUS_FALSE; \r
- }\r
- }\r
- return SWITCH_STATUS_SUCCESS;\r
-}\r
-\r
-\r
-static switch_status switch_g729_decode(switch_codec *codec,\r
- switch_codec *other_codec,\r
- void *encoded_data,\r
- size_t encoded_data_len,\r
- int encoded_rate,\r
- void *decoded_data,\r
- size_t *decoded_data_len,\r
- int *decoded_rate,\r
- unsigned int *flag) \r
-{\r
- struct g729_context *context = codec->private;\r
-\r
- if (!context) {\r
- return SWITCH_STATUS_FALSE;\r
- }\r
-\r
-\r
- if (encoded_data_len % 10 == 0) {\r
- int loops = (int) encoded_data_len / 10;\r
- char *edp = encoded_data;\r
- short *ddp = decoded_data;\r
- int x;\r
- unsigned int new_len = 0;\r
- for(x = 0; x < loops && new_len < *decoded_data_len; x++) {\r
- g729_decoder(&context->decoder_object, ddp, edp, 10);\r
- ddp += 80;\r
- edp += 10;\r
- new_len += 160;\r
- }\r
- if (new_len <= *decoded_data_len) {\r
- *decoded_data_len = new_len;\r
- } else {\r
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "buffer overflow!!!\n");\r
- return SWITCH_STATUS_FALSE;\r
- }\r
- } else {\r
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "yo this frame is an odd size [%d]\n", encoded_data_len);\r
- }\r
-\r
-\r
- return SWITCH_STATUS_SUCCESS;\r
-}\r
-\r
-/* Registration */\r
-\r
-static const switch_codec_implementation g729_8k_implementation = {\r
- /*.samples_per_second*/ 8000,\r
- /*.bits_per_second*/ 64000,\r
- /*.microseconds_per_frame*/ 20000,\r
- /*.samples_per_frame*/ 160,\r
- /*.bytes_per_frame*/ 320,\r
- /*.encoded_bytes_per_frame*/ 20,\r
- /*.number_of_channels*/ 1,\r
- /*.pref_frames_per_packet*/ 1,\r
- /*.max_frames_per_packet*/ 24,\r
- /*.init*/ switch_g729_init,\r
- /*.encode*/ switch_g729_encode,\r
- /*.decode*/ switch_g729_decode,\r
- /*.destroy*/ switch_g729_destroy,\r
-};\r
-\r
-static const switch_codec_interface g729_codec_interface = {\r
- /*.interface_name*/ "g729",\r
- /*.codec_type*/ SWITCH_CODEC_TYPE_AUDIO,\r
- /*.ianacode*/ 18,\r
- /*.iananame*/ "G729",\r
- /*.implementations*/ &g729_8k_implementation,\r
-};\r
-\r
-static switch_loadable_module_interface g729_module_interface = {\r
- /*.module_name*/ modname,\r
- /*.endpoint_interface*/ NULL,\r
- /*.timer_interface*/ NULL,\r
- /*.dialplan_interface*/ NULL,\r
- /*.codec_interface*/ &g729_codec_interface,\r
- /*.application_interface*/ NULL\r
-};\r
-\r
-\r
-SWITCH_MOD_DECLARE(switch_status) switch_module_load(const switch_loadable_module_interface **interface, char *filename) {\r
- /* connect my internal structure to the blank pointer passed to me */\r
- *interface = &g729_module_interface;\r
-\r
- /* indicate that the module should continue to be loaded */\r
- return SWITCH_STATUS_SUCCESS;\r
-}\r
-\r
-\r
-\r
-\r
-\r
+++ /dev/null
-<?xml version="1.0" encoding="Windows-1252"?>\r
-<VisualStudioProject\r
- ProjectType="Visual C++"\r
- Version="8.00"\r
- Name="mod_codec_g729"\r
- ProjectGUID="{1D95CD95-0DE2-48C3-AC23-D5C7D1C9C0F0}"\r
- RootNamespace="mod_codec_g729"\r
- Keyword="Win32Proj"\r
- >\r
- <Platforms>\r
- <Platform\r
- Name="Win32"\r
- />\r
- </Platforms>\r
- <ToolFiles>\r
- </ToolFiles>\r
- <Configurations>\r
- <Configuration\r
- Name="Debug|Win32"\r
- OutputDirectory="Debug"\r
- IntermediateDirectory="Debug"\r
- ConfigurationType="2"\r
- InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
- CharacterSet="2"\r
- >\r
- <Tool\r
- Name="VCPreBuildEventTool"\r
- CommandLine="cscript /nologo $(InputDir)..\..\..\w32\vsnet\getlibs.vbs Mod_CodecG729 Debug"\r
- />\r
- <Tool\r
- Name="VCCustomBuildTool"\r
- />\r
- <Tool\r
- Name="VCXMLDataGeneratorTool"\r
- />\r
- <Tool\r
- Name="VCWebServiceProxyGeneratorTool"\r
- />\r
- <Tool\r
- Name="VCMIDLTool"\r
- />\r
- <Tool\r
- Name="VCCLCompilerTool"\r
- Optimization="0"\r
- AdditionalIncludeDirectories=""$(InputDir)..\..\include";"$(InputDir)..\..\..\libs\include";"$(InputDir)..\..\..\libs\codec\libg729""\r
- PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS"\r
- MinimalRebuild="true"\r
- BasicRuntimeChecks="3"\r
- RuntimeLibrary="1"\r
- UsePrecompiledHeader="0"\r
- WarningLevel="3"\r
- Detect64BitPortabilityProblems="true"\r
- DebugInformationFormat="4"\r
- />\r
- <Tool\r
- Name="VCManagedResourceCompilerTool"\r
- />\r
- <Tool\r
- Name="VCResourceCompilerTool"\r
- />\r
- <Tool\r
- Name="VCPreLinkEventTool"\r
- />\r
- <Tool\r
- Name="VCLinkerTool"\r
- AdditionalDependencies="libg729.lib FreeSwitchCore.lib"\r
- OutputFile="..\..\..\w32\vsnet\$(OutDir)/mod/mod_codec_g729.dll"\r
- LinkIncremental="2"\r
- AdditionalLibraryDirectories=""$(InputDir)..\..\..\libs\apr\Debug";"$(InputDir)..\..\..\libs\codec\libg729\Debug";..\..\..\w32\vsnet\Debug"\r
- GenerateDebugInformation="true"\r
- ProgramDatabaseFile="$(OutDir)/mod_codec_g729.pdb"\r
- SubSystem="2"\r
- ImportLibrary="$(OutDir)/mod_codec_g729.lib"\r
- TargetMachine="1"\r
- />\r
- <Tool\r
- Name="VCALinkTool"\r
- />\r
- <Tool\r
- Name="VCManifestTool"\r
- />\r
- <Tool\r
- Name="VCXDCMakeTool"\r
- />\r
- <Tool\r
- Name="VCBscMakeTool"\r
- />\r
- <Tool\r
- Name="VCFxCopTool"\r
- />\r
- <Tool\r
- Name="VCAppVerifierTool"\r
- />\r
- <Tool\r
- Name="VCWebDeploymentTool"\r
- />\r
- <Tool\r
- Name="VCPostBuildEventTool"\r
- />\r
- </Configuration>\r
- <Configuration\r
- Name="Release|Win32"\r
- OutputDirectory="Release"\r
- IntermediateDirectory="Release"\r
- ConfigurationType="2"\r
- InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
- CharacterSet="2"\r
- >\r
- <Tool\r
- Name="VCPreBuildEventTool"\r
- CommandLine="cscript /nologo $(InputDir)..\..\..\w32\vsnet\getlibs.vbs Mod_CodecG729 Release"\r
- />\r
- <Tool\r
- Name="VCCustomBuildTool"\r
- />\r
- <Tool\r
- Name="VCXMLDataGeneratorTool"\r
- />\r
- <Tool\r
- Name="VCWebServiceProxyGeneratorTool"\r
- />\r
- <Tool\r
- Name="VCMIDLTool"\r
- />\r
- <Tool\r
- Name="VCCLCompilerTool"\r
- AdditionalIncludeDirectories=""$(InputDir)..\..\include";"$(InputDir)..\..\..\libs\include";"$(InputDir)..\..\..\libs\codec\libg729""\r
- PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS"\r
- RuntimeLibrary="0"\r
- UsePrecompiledHeader="0"\r
- WarningLevel="3"\r
- Detect64BitPortabilityProblems="true"\r
- DebugInformationFormat="3"\r
- />\r
- <Tool\r
- Name="VCManagedResourceCompilerTool"\r
- />\r
- <Tool\r
- Name="VCResourceCompilerTool"\r
- />\r
- <Tool\r
- Name="VCPreLinkEventTool"\r
- />\r
- <Tool\r
- Name="VCLinkerTool"\r
- AdditionalDependencies="libg729.lib FreeSwitchCore.lib"\r
- OutputFile="..\..\..\w32\vsnet\$(OutDir)/mod/mod_codec_g729.dll"\r
- LinkIncremental="1"\r
- AdditionalLibraryDirectories=""$(InputDir)..\..\..\libs\apr\Release";"$(InputDir)..\..\..\libs\codec\libg729\Release";..\..\..\w32\vsnet\Release"\r
- GenerateDebugInformation="true"\r
- SubSystem="2"\r
- OptimizeReferences="2"\r
- EnableCOMDATFolding="2"\r
- ImportLibrary="$(OutDir)/mod_codec_g729.lib"\r
- TargetMachine="1"\r
- />\r
- <Tool\r
- Name="VCALinkTool"\r
- />\r
- <Tool\r
- Name="VCManifestTool"\r
- />\r
- <Tool\r
- Name="VCXDCMakeTool"\r
- />\r
- <Tool\r
- Name="VCBscMakeTool"\r
- />\r
- <Tool\r
- Name="VCFxCopTool"\r
- />\r
- <Tool\r
- Name="VCAppVerifierTool"\r
- />\r
- <Tool\r
- Name="VCWebDeploymentTool"\r
- />\r
- <Tool\r
- Name="VCPostBuildEventTool"\r
- />\r
- </Configuration>\r
- </Configurations>\r
- <References>\r
- </References>\r
- <Files>\r
- <Filter\r
- Name="Source Files"\r
- Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"\r
- UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"\r
- >\r
- <File\r
- RelativePath="mod_codec_g729.c"\r
- >\r
- </File>\r
- </Filter>\r
- <Filter\r
- Name="Header Files"\r
- Filter="h;hpp;hxx;hm;inl;inc;xsd"\r
- UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"\r
- >\r
- </Filter>\r
- <Filter\r
- Name="Resource Files"\r
- Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"\r
- UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"\r
- >\r
- </Filter>\r
- </Files>\r
- <Globals>\r
- </Globals>\r
-</VisualStudioProject>\r
+++ /dev/null
-/*
- * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
- * Copyright (C) 2005/2006, Anthony Minessale II <anthmct@yahoo.com>
- *
- * Version: MPL 1.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
- *
- * The Initial Developer of the Original Code is
- * Anthony Minessale II <anthmct@yahoo.com>
- * Portions created by the Initial Developer are Copyright (C)
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Anthony Minessale II <anthmct@yahoo.com>
- *
- *
- * mod_dialplan_demo.c -- Example Dialplan Module
- *
- */
-#include <switch.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-
-static const char modname[] = "mod_dialplan_demo";
-
-
-switch_caller_extension *demo_dialplan_hunt(switch_core_session *session)
-{
- switch_caller_profile *caller_profile;
- switch_caller_extension *extension = NULL;
- switch_channel *channel;
- char *cf = "extensions.conf";
- switch_config cfg;
- char *var, *val;
- char app[1024];
-
- channel = switch_core_session_get_channel(session);
- caller_profile = switch_channel_get_caller_profile(channel);
- //switch_channel_set_variable(channel, "pleasework", "yay");
-
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Hello %s You Dialed %s!\n", caller_profile->caller_id_name, caller_profile->destination_number);
-
- if (!switch_config_open_file(&cfg, cf)) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "open of %s failed\n", cf);
- switch_channel_hangup(channel);
- return NULL;
- }
-
- while (switch_config_next_pair(&cfg, &var, &val)) {
- if (!strcasecmp(cfg.category, "extensions")) {
- if (!strcmp(var, caller_profile->destination_number) && val) {
- char *data;
-
- memset(app, 0, sizeof(app));
- strncpy(app, val, sizeof(app));
-
- if ((data = strchr(app, ' '))) {
- *data = '\0';
- data++;
- } else {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "invalid extension on line %d\n", cfg.lineno);
- continue;
- }
- if (!extension) {
- if (!(extension = switch_caller_extension_new(session, caller_profile->destination_number, caller_profile->destination_number))) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "memory error!\n");
- break;
- }
- }
-
- switch_caller_extension_add_application(session, extension, app, data);
- }
- }
- }
-
- switch_config_close_file(&cfg);
-
- if (extension) {
- switch_channel_set_state(channel, CS_EXECUTE);
- } else {
- switch_channel_hangup(channel);
- }
-
- return extension;
-}
-
-
-static const switch_dialplan_interface demo_dialplan_interface = {
- /*.interface_name =*/ "demo",
- /*.hunt_function = */ demo_dialplan_hunt
- /*.next = NULL */
-};
-
-static const switch_loadable_module_interface demo_dialplan_module_interface = {
- /*.module_name = */ modname,
- /*.endpoint_interface = */ NULL,
- /*.timer_interface = */ NULL,
- /*.dialplan_interface = */ &demo_dialplan_interface,
- /*.codec_interface = */ NULL,
- /*.application_interface =*/ NULL
-};
-
-SWITCH_MOD_DECLARE(switch_status) switch_module_load(const switch_loadable_module_interface **interface, char *filename) {
-
- /* connect my internal structure to the blank pointer passed to me */
- *interface = &demo_dialplan_module_interface;
-
- /* indicate that the module should continue to be loaded */
- return SWITCH_STATUS_SUCCESS;
-}
+++ /dev/null
-<?xml version="1.0" encoding="Windows-1252"?>\r
-<VisualStudioProject\r
- ProjectType="Visual C++"\r
- Version="8.00"\r
- Name="mod_dialplan_demo"\r
- ProjectGUID="{2988EB83-785F-45D4-8731-8E1E4345177E}"\r
- RootNamespace="mod_dialplan_demo"\r
- Keyword="Win32Proj"\r
- >\r
- <Platforms>\r
- <Platform\r
- Name="Win32"\r
- />\r
- </Platforms>\r
- <ToolFiles>\r
- </ToolFiles>\r
- <Configurations>\r
- <Configuration\r
- Name="Debug|Win32"\r
- OutputDirectory="Debug"\r
- IntermediateDirectory="Debug"\r
- ConfigurationType="2"\r
- InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
- CharacterSet="2"\r
- >\r
- <Tool\r
- Name="VCPreBuildEventTool"\r
- />\r
- <Tool\r
- Name="VCCustomBuildTool"\r
- />\r
- <Tool\r
- Name="VCXMLDataGeneratorTool"\r
- />\r
- <Tool\r
- Name="VCWebServiceProxyGeneratorTool"\r
- />\r
- <Tool\r
- Name="VCMIDLTool"\r
- />\r
- <Tool\r
- Name="VCCLCompilerTool"\r
- Optimization="0"\r
- AdditionalIncludeDirectories=""$(InputDir)..\..\include";"$(InputDir)include";"$(InputDir)..\..\..\libs\include""\r
- PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS"\r
- MinimalRebuild="true"\r
- BasicRuntimeChecks="3"\r
- RuntimeLibrary="1"\r
- UsePrecompiledHeader="0"\r
- WarningLevel="3"\r
- Detect64BitPortabilityProblems="true"\r
- DebugInformationFormat="4"\r
- />\r
- <Tool\r
- Name="VCManagedResourceCompilerTool"\r
- />\r
- <Tool\r
- Name="VCResourceCompilerTool"\r
- />\r
- <Tool\r
- Name="VCPreLinkEventTool"\r
- />\r
- <Tool\r
- Name="VCLinkerTool"\r
- OutputFile="..\..\..\w32\vsnet\$(OutDir)/mod/mod_dialplan_demo.dll"\r
- LinkIncremental="2"\r
- AdditionalLibraryDirectories="$(InputDir)..\..\libs\apr\Debug"\r
- GenerateDebugInformation="true"\r
- ProgramDatabaseFile="$(OutDir)/mod_dialplan_demo.pdb"\r
- SubSystem="2"\r
- ImportLibrary="$(OutDir)/mod_dialplan_demo.lib"\r
- TargetMachine="1"\r
- />\r
- <Tool\r
- Name="VCALinkTool"\r
- />\r
- <Tool\r
- Name="VCManifestTool"\r
- />\r
- <Tool\r
- Name="VCXDCMakeTool"\r
- />\r
- <Tool\r
- Name="VCBscMakeTool"\r
- />\r
- <Tool\r
- Name="VCFxCopTool"\r
- />\r
- <Tool\r
- Name="VCAppVerifierTool"\r
- />\r
- <Tool\r
- Name="VCWebDeploymentTool"\r
- />\r
- <Tool\r
- Name="VCPostBuildEventTool"\r
- />\r
- </Configuration>\r
- <Configuration\r
- Name="Release|Win32"\r
- OutputDirectory="Release"\r
- IntermediateDirectory="Release"\r
- ConfigurationType="2"\r
- InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
- CharacterSet="2"\r
- >\r
- <Tool\r
- Name="VCPreBuildEventTool"\r
- />\r
- <Tool\r
- Name="VCCustomBuildTool"\r
- />\r
- <Tool\r
- Name="VCXMLDataGeneratorTool"\r
- />\r
- <Tool\r
- Name="VCWebServiceProxyGeneratorTool"\r
- />\r
- <Tool\r
- Name="VCMIDLTool"\r
- />\r
- <Tool\r
- Name="VCCLCompilerTool"\r
- AdditionalIncludeDirectories=""$(InputDir)..\..\include";"$(InputDir)include";"$(InputDir)..\..\..\libs\include""\r
- PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS"\r
- RuntimeLibrary="0"\r
- UsePrecompiledHeader="0"\r
- WarningLevel="3"\r
- Detect64BitPortabilityProblems="true"\r
- DebugInformationFormat="3"\r
- />\r
- <Tool\r
- Name="VCManagedResourceCompilerTool"\r
- />\r
- <Tool\r
- Name="VCResourceCompilerTool"\r
- />\r
- <Tool\r
- Name="VCPreLinkEventTool"\r
- />\r
- <Tool\r
- Name="VCLinkerTool"\r
- OutputFile="..\..\..\w32\vsnet\$(OutDir)/mod/mod_dialplan_demo.dll"\r
- LinkIncremental="1"\r
- AdditionalLibraryDirectories=""$(InputDir)..\..\libs\apr\Release""\r
- GenerateDebugInformation="true"\r
- SubSystem="2"\r
- OptimizeReferences="2"\r
- EnableCOMDATFolding="2"\r
- ImportLibrary="$(OutDir)/mod_dialplan_demo.lib"\r
- TargetMachine="1"\r
- />\r
- <Tool\r
- Name="VCALinkTool"\r
- />\r
- <Tool\r
- Name="VCManifestTool"\r
- />\r
- <Tool\r
- Name="VCXDCMakeTool"\r
- />\r
- <Tool\r
- Name="VCBscMakeTool"\r
- />\r
- <Tool\r
- Name="VCFxCopTool"\r
- />\r
- <Tool\r
- Name="VCAppVerifierTool"\r
- />\r
- <Tool\r
- Name="VCWebDeploymentTool"\r
- />\r
- <Tool\r
- Name="VCPostBuildEventTool"\r
- />\r
- </Configuration>\r
- </Configurations>\r
- <References>\r
- </References>\r
- <Files>\r
- <Filter\r
- Name="Source Files"\r
- Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"\r
- UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"\r
- >\r
- <File\r
- RelativePath=".\mod_dialplan_demo.c"\r
- >\r
- </File>\r
- </Filter>\r
- <Filter\r
- Name="Header Files"\r
- Filter="h;hpp;hxx;hm;inl;inc;xsd"\r
- UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"\r
- >\r
- </Filter>\r
- <Filter\r
- Name="Resource Files"\r
- Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"\r
- UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"\r
- >\r
- </Filter>\r
- </Files>\r
- <Globals>\r
- </Globals>\r
-</VisualStudioProject>\r
+++ /dev/null
-/*
- * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
- * Copyright (C) 2005/2006, Anthony Minessale II <anthmct@yahoo.com>
- *
- * Version: MPL 1.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
- *
- * The Initial Developer of the Original Code is
- * Anthony Minessale II <anthmct@yahoo.com>
- * Portions created by the Initial Developer are Copyright (C)
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Anthony Minessale II <anthmct@yahoo.com>
- *
- *
- * mod_event_test.c -- Framework Demo Module
- *
- */
-#include <switch.h>
-
-static const char modname[] = "mod_event_test";
-
-static void event_handler (switch_event *event)
-{
- char buf[1024];
-
- switch(event->event_id) {
- case SWITCH_EVENT_LOG:
- return;
- break;
- default:
- switch_event_serialize(event, buf, sizeof(buf), NULL);
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "\nEVENT\n--------------------------------\n%s\n", buf);
- break;
- }
-}
-
-
-static switch_loadable_module_interface event_test_module_interface = {
- /*.module_name*/ modname,
- /*.endpoint_interface*/ NULL,
- /*.timer_interface*/ NULL,
- /*.dialplan_interface*/ NULL,
- /*.codec_interface*/ NULL,
- /*.application_interface*/ NULL
-};
-
-#define MY_EVENT_COOL "test::cool"
-
-
-//#define TORTURE_ME
-
-#ifdef TORTURE_ME
-#define TTHREADS 500
-static int THREADS = 0;
-
-static void *torture_thread(switch_thread *thread, void *obj)
-{
- int y = 0;
- int z = 0;
- switch_core_thread_session *ts = obj;
- switch_event *event;
-
- z = THREADS++;
-
- while(THREADS > 0) {
- int x;
- for(x = 0; x < 1; x++) {
- if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_COOL) == SWITCH_STATUS_SUCCESS) {
- switch_event_add_header(event, "event_info", "hello world %d %d", z, y++);
- switch_event_fire(&event);
- }
- }
- switch_yield(100000);
- }
-
- if (ts->pool) {
- switch_memory_pool *pool = ts->pool;
- switch_core_destroy_memory_pool(&pool);
- }
-
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Thread Ended\n");
-}
-
-SWITCH_MOD_DECLARE(switch_status) switch_module_shutdown(void)
-{
- THREADS = -1;
- switch_yield(100000);
- return SWITCH_STATUS_SUCCESS;
-}
-#endif
-
-
-SWITCH_MOD_DECLARE(switch_status) switch_module_load(switch_loadable_module_interface **interface, char *filename) {
- /* connect my internal structure to the blank pointer passed to me */
- *interface = &event_test_module_interface;
-
- if (switch_event_reserve_subclass(MY_EVENT_COOL) != SWITCH_STATUS_SUCCESS) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Couldn't register subclass!");
- return SWITCH_STATUS_GENERR;
- }
-
-#ifdef TORTURE_ME
- if (switch_event_bind((char *)modname, SWITCH_EVENT_ALL, SWITCH_EVENT_SUBCLASS_ANY, event_handler, NULL) != SWITCH_STATUS_SUCCESS) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Couldn't bind!\n");
- return SWITCH_STATUS_GENERR;
- }
-
- if (1) {
- int x = 0;
- for(x = 0 ; x < TTHREADS ; x++) {
- switch_core_launch_thread(torture_thread, NULL);
- }
- }
-#endif
-
- /* indicate that the module should continue to be loaded */
- return SWITCH_STATUS_SUCCESS;
-}
-
+++ /dev/null
-<?xml version="1.0" encoding="Windows-1252"?>\r
-<VisualStudioProject\r
- ProjectType="Visual C++"\r
- Version="8.00"\r
- Name="mod_event_test"\r
- ProjectGUID="{3A2A7795-C216-4FFF-B8EF-4D17A84BACCC}"\r
- RootNamespace="mod_event_test"\r
- Keyword="Win32Proj"\r
- >\r
- <Platforms>\r
- <Platform\r
- Name="Win32"\r
- />\r
- </Platforms>\r
- <ToolFiles>\r
- </ToolFiles>\r
- <Configurations>\r
- <Configuration\r
- Name="Debug|Win32"\r
- OutputDirectory="Debug"\r
- IntermediateDirectory="Debug"\r
- ConfigurationType="2"\r
- InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
- CharacterSet="2"\r
- >\r
- <Tool\r
- Name="VCPreBuildEventTool"\r
- />\r
- <Tool\r
- Name="VCCustomBuildTool"\r
- />\r
- <Tool\r
- Name="VCXMLDataGeneratorTool"\r
- />\r
- <Tool\r
- Name="VCWebServiceProxyGeneratorTool"\r
- />\r
- <Tool\r
- Name="VCMIDLTool"\r
- />\r
- <Tool\r
- Name="VCCLCompilerTool"\r
- Optimization="0"\r
- AdditionalIncludeDirectories=""$(InputDir)..\..\include";"$(InputDir)include";"$(InputDir)..\..\..\libs\include""\r
- PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS"\r
- MinimalRebuild="true"\r
- BasicRuntimeChecks="3"\r
- RuntimeLibrary="1"\r
- UsePrecompiledHeader="0"\r
- WarningLevel="3"\r
- Detect64BitPortabilityProblems="true"\r
- DebugInformationFormat="4"\r
- />\r
- <Tool\r
- Name="VCManagedResourceCompilerTool"\r
- />\r
- <Tool\r
- Name="VCResourceCompilerTool"\r
- />\r
- <Tool\r
- Name="VCPreLinkEventTool"\r
- />\r
- <Tool\r
- Name="VCLinkerTool"\r
- OutputFile="..\..\..\w32\vsnet\$(OutDir)/mod/mod_event_test.dll"\r
- LinkIncremental="2"\r
- AdditionalLibraryDirectories="$(InputDir)..\..\libs\apr\Debug"\r
- GenerateDebugInformation="true"\r
- ProgramDatabaseFile="$(OutDir)/mod_event_test.pdb"\r
- SubSystem="2"\r
- ImportLibrary="$(OutDir)/mod_event_test.lib"\r
- TargetMachine="1"\r
- />\r
- <Tool\r
- Name="VCALinkTool"\r
- />\r
- <Tool\r
- Name="VCManifestTool"\r
- />\r
- <Tool\r
- Name="VCXDCMakeTool"\r
- />\r
- <Tool\r
- Name="VCBscMakeTool"\r
- />\r
- <Tool\r
- Name="VCFxCopTool"\r
- />\r
- <Tool\r
- Name="VCAppVerifierTool"\r
- />\r
- <Tool\r
- Name="VCWebDeploymentTool"\r
- />\r
- <Tool\r
- Name="VCPostBuildEventTool"\r
- />\r
- </Configuration>\r
- <Configuration\r
- Name="Release|Win32"\r
- OutputDirectory="Release"\r
- IntermediateDirectory="Release"\r
- ConfigurationType="2"\r
- InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
- CharacterSet="2"\r
- >\r
- <Tool\r
- Name="VCPreBuildEventTool"\r
- />\r
- <Tool\r
- Name="VCCustomBuildTool"\r
- />\r
- <Tool\r
- Name="VCXMLDataGeneratorTool"\r
- />\r
- <Tool\r
- Name="VCWebServiceProxyGeneratorTool"\r
- />\r
- <Tool\r
- Name="VCMIDLTool"\r
- />\r
- <Tool\r
- Name="VCCLCompilerTool"\r
- AdditionalIncludeDirectories=""$(InputDir)..\..\include";"$(InputDir)include";"$(InputDir)..\..\..\libs\include""\r
- PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS"\r
- RuntimeLibrary="0"\r
- UsePrecompiledHeader="0"\r
- WarningLevel="3"\r
- Detect64BitPortabilityProblems="true"\r
- DebugInformationFormat="3"\r
- />\r
- <Tool\r
- Name="VCManagedResourceCompilerTool"\r
- />\r
- <Tool\r
- Name="VCResourceCompilerTool"\r
- />\r
- <Tool\r
- Name="VCPreLinkEventTool"\r
- />\r
- <Tool\r
- Name="VCLinkerTool"\r
- OutputFile="..\..\..\w32\vsnet\$(OutDir)/mod/mod_event_test.dll"\r
- LinkIncremental="1"\r
- AdditionalLibraryDirectories=""$(InputDir)..\..\libs\apr\Release""\r
- GenerateDebugInformation="true"\r
- SubSystem="2"\r
- OptimizeReferences="2"\r
- EnableCOMDATFolding="2"\r
- ImportLibrary="$(OutDir)/mod_event_test.lib"\r
- TargetMachine="1"\r
- />\r
- <Tool\r
- Name="VCALinkTool"\r
- />\r
- <Tool\r
- Name="VCManifestTool"\r
- />\r
- <Tool\r
- Name="VCXDCMakeTool"\r
- />\r
- <Tool\r
- Name="VCBscMakeTool"\r
- />\r
- <Tool\r
- Name="VCFxCopTool"\r
- />\r
- <Tool\r
- Name="VCAppVerifierTool"\r
- />\r
- <Tool\r
- Name="VCWebDeploymentTool"\r
- />\r
- <Tool\r
- Name="VCPostBuildEventTool"\r
- />\r
- </Configuration>\r
- </Configurations>\r
- <References>\r
- </References>\r
- <Files>\r
- <Filter\r
- Name="Source Files"\r
- Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"\r
- UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"\r
- >\r
- <File\r
- RelativePath=".\mod_event_test.c"\r
- >\r
- </File>\r
- </Filter>\r
- <Filter\r
- Name="Header Files"\r
- Filter="h;hpp;hxx;hm;inl;inc;xsd"\r
- UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"\r
- >\r
- </Filter>\r
- <Filter\r
- Name="Resource Files"\r
- Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"\r
- UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"\r
- >\r
- </Filter>\r
- </Files>\r
- <Globals>\r
- </Globals>\r
-</VisualStudioProject>\r
+++ /dev/null
-#CFLAGS += -I/usr/src/common/src
-LDFLAGS += -leXosip2 -ljrtp4c
-
-ifeq ($(OSARCH),Darwin)
- LINKER=g++
-else
- LINKER=$(CC)
-endif
-
-all: depends $(MOD).so
-
-depends:
- $(BASE)/buildlib.sh $(BASE) install jthread-1.1.2.tar.gz --prefix=$(PREFIX)
- $(BASE)/buildlib.sh $(BASE) install jrtplib-3.3.0.tar.gz --prefix=$(PREFIX)
- $(BASE)/buildlib.sh $(BASE) install jrtp4c --prefix=$(PREFIX)
- $(BASE)/buildlib.sh $(BASE) install libosip2-2.2.2.tar.gz --prefix=$(PREFIX)
- $(BASE)/buildlib.sh $(BASE) install libeXosip2-2.2.2.tar.gz --disable-josua --prefix=$(PREFIX)
-
-
-$(MOD).so: $(MOD).c
- $(CC) $(CFLAGS) -fPIC -c $(MOD).c -o $(MOD).o
- $(LINKER) $(SOLINK) -o $(MOD).so $(MOD).o $(LDFLAGS)
-
-clean:
- rm -fr *.so *.o *~
-
+++ /dev/null
-/*
- * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
- * Copyright (C) 2005/2006, Anthony Minessale II <anthmct@yahoo.com>
- *
- * Version: MPL 1.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
- *
- * The Initial Developer of the Original Code is
- * Anthony Minessale II <anthmct@yahoo.com>
- * Portions created by the Initial Developer are Copyright (C)
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Anthony Minessale II <anthmct@yahoo.com>
- *
- *
- * mod_exosip.c -- eXoSIP SIP Endpoint
- *
- */
-
-#define HAVE_APR
-#include <switch.h>
-#include <jrtp4c.h>
-#include <eXosip2/eXosip.h>
-#include <osip2/osip_mt.h>
-#include <osipparser2/osip_rfc3264.h>
-#include <osipparser2/osip_port.h>
-
-
-static const char modname[] = "mod_exosip";
-#define STRLEN 15
-
-static switch_memory_pool *module_pool;
-
-typedef enum {
- PFLAG_ANSWER = (1 << 0),
- PFLAG_HANGUP = (1 << 1),
-} PFLAGS;
-
-
-typedef enum {
- PPFLAG_RING = (1 << 0),
-} PPFLAGS;
-
-typedef enum {
- TFLAG_IO = (1 << 0),
- TFLAG_INBOUND = (1 << 1),
- TFLAG_OUTBOUND = (1 << 2),
- TFLAG_DTMF = (1 << 3),
- TFLAG_READING = (1 << 4),
- TFLAG_WRITING = (1 << 5),
- TFLAG_USING_CODEC = (1 << 6),
- TFLAG_RTP = (1 << 7),
- TFLAG_BYE = (1 << 8)
-} TFLAGS;
-
-
-#define PACKET_LEN 160
-#define DEFAULT_BYTES_PER_FRAME 160
-
-
-static const switch_endpoint_interface exosip_endpoint_interface;
-
-static struct {
- int debug;
- int bytes_per_frame;
- char *dialplan;
- int port;
- int rtp_start;
- int rtp_end;
- switch_hash *call_hash;
- switch_mutex_t *port_lock;
- int running;
- int codec_ms;
-} globals;
-
-struct private_object {
- unsigned int flags;
- switch_core_session *session;
- switch_frame read_frame;
- switch_codec read_codec;
- switch_codec write_codec;
- unsigned char read_buf[1024];
- switch_caller_profile *caller_profile;
- int cid;
- int did;
- int tid;
- int32_t timestamp_send;
- int32_t timestamp_recv;
- int payload_num;
- struct jrtp4c *rtp_session;
- struct osip_rfc3264 *sdp_config;
- sdp_message_t *remote_sdp;
- sdp_message_t *local_sdp;
- char remote_sdp_audio_ip[50];
- int remote_sdp_audio_port;
- char local_sdp_audio_ip[50];
- int local_sdp_audio_port;
- char call_id[50];
- int ssrc;
- switch_mutex_t *rtp_lock;
-};
-
-
-static int next_rtp_port(void)
-{
- int port;
-
- switch_mutex_lock(globals.port_lock);
- port = globals.rtp_start;
- globals.rtp_start += 2;
- if (port >= globals.rtp_end) {
- port = globals.rtp_start;
- }
- switch_mutex_unlock(globals.port_lock);
- return port;
-}
-
-
-static void set_global_dialplan(char *dialplan)
-{
- if (globals.dialplan) {
- free(globals.dialplan);
- globals.dialplan = NULL;
- }
-
- globals.dialplan = strdup(dialplan);
-}
-
-static void set_global_dialplan(char *dialplan);
-static switch_status exosip_on_init(switch_core_session *session);
-static switch_status exosip_on_hangup(switch_core_session *session);
-static switch_status exosip_on_loopback(switch_core_session *session);
-static switch_status exosip_on_transmit(switch_core_session *session);
-static switch_status exosip_outgoing_channel(switch_core_session *session, switch_caller_profile *outbound_profile, switch_core_session **new_session);
-static switch_status exosip_read_frame(switch_core_session *session, switch_frame **frame, int timeout, switch_io_flag flags);
-static switch_status exosip_write_frame(switch_core_session *session, switch_frame *frame, int timeout, switch_io_flag flags);
-static int config_exosip(int reload);
-static switch_status parse_sdp_media(sdp_media_t *media, char **dname, char **drate, char **dpayload);
-static switch_status exosip_kill_channel(switch_core_session *session, int sig);
-static void activate_rtp(struct private_object *tech_pvt);
-static void deactivate_rtp(struct private_object *tech_pvt);
-
-static struct private_object *get_pvt_by_call_id(int id)
-{
- char name[50];
- snprintf(name, sizeof(name), "%d", id);
- return (struct private_object *) switch_core_hash_find(globals.call_hash, name);
-}
-
-static switch_status exosip_on_execute(switch_core_session *session)
-{
- return SWITCH_STATUS_SUCCESS;
-}
-
-
-static int sdp_add_codec(struct osip_rfc3264 *cnf, int codec_type, int payload, char *attribute, int rate, int index)
-{
- char tmp[4] = "", string[32] = "";
- sdp_media_t *med = NULL;
- sdp_attribute_t *attr = NULL;
-
- sdp_media_init(&med);
- if (med == NULL)
- return -1;
-
- if (!index) {
- snprintf(tmp, sizeof(tmp), "%i", payload);
- med->m_proto = osip_strdup("RTP/AVP");
- osip_list_add(med->m_payloads, osip_strdup(tmp), -1);
- }
- if (attribute) {
- sdp_attribute_init(&attr);
- attr->a_att_field = osip_strdup("rtpmap");
- snprintf(string, sizeof(string), "%i %s/%i", payload, attribute, rate);
- attr->a_att_value = osip_strdup(string);
- osip_list_add(med->a_attributes, attr, -1);
- }
-
- switch (codec_type) {
-case SWITCH_CODEC_TYPE_AUDIO:
- med->m_media = osip_strdup("audio");
- osip_rfc3264_add_audio_media(cnf, med, -1);
- break;
-case SWITCH_CODEC_TYPE_VIDEO:
- med->m_media = osip_strdup("video");
- osip_rfc3264_add_video_media(cnf, med, -1);
- break;
-default:
- break;
- }
- return 0;
-}
-
-
-/*
-State methods they get called when the state changes to the specific state
-returning SWITCH_STATUS_SUCCESS tells the core to execute the standard state method next
-so if you fully implement the state you can return SWITCH_STATUS_FALSE to skip it.
-*/
-static switch_status exosip_on_init(switch_core_session *session)
-{
- struct private_object *tech_pvt;
- switch_channel *channel = NULL;
- char from_uri[512] = "", localip[128] = "", port[7] = "", *buf = NULL, tmp[512] = "";
- osip_message_t *invite = NULL;
-
- channel = switch_core_session_get_channel(session);
- assert(channel != NULL);
-
- tech_pvt = switch_core_session_get_private(session);
- assert(tech_pvt != NULL);
-
- tech_pvt->read_frame.data = tech_pvt->read_buf;
- tech_pvt->read_frame.buflen = sizeof(tech_pvt->read_buf);
-
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "EXOSIP INIT\n");
-
- if (switch_test_flag(tech_pvt, TFLAG_OUTBOUND)) {
- char *dest_uri;
- switch_codec_interface *codecs[SWITCH_MAX_CODECS];
- int num_codecs = 0;
- /* do SIP Goodies...*/
-
- /* Generate callerid URI */
- eXosip_guess_localip(AF_INET, localip, 128);
- snprintf(from_uri, sizeof(from_uri), "<sip:%s@%s>", tech_pvt->caller_profile->caller_id_number, localip);
- /* Setup codec negotiation stuffs */
- osip_rfc3264_init(&tech_pvt->sdp_config);
- /* Decide on local IP and rtp port */
- strncpy(tech_pvt->local_sdp_audio_ip, localip, sizeof(tech_pvt->local_sdp_audio_ip));
- tech_pvt->local_sdp_audio_port = next_rtp_port();
- /* Initialize SDP */
- sdp_message_init(&tech_pvt->local_sdp);
- sdp_message_v_version_set(tech_pvt->local_sdp, "0");
- sdp_message_o_origin_set(tech_pvt->local_sdp, "OpenSWITCH2", "0", "0", "IN", "IP4", tech_pvt->local_sdp_audio_ip);
- sdp_message_s_name_set(tech_pvt->local_sdp, "SIP Call");
- sdp_message_c_connection_add(tech_pvt->local_sdp, -1, "IN", "IP4", tech_pvt->local_sdp_audio_ip, NULL, NULL);
- sdp_message_t_time_descr_add(tech_pvt->local_sdp, "0", "0");
- snprintf(port, sizeof(port), "%i", tech_pvt->local_sdp_audio_port);
- sdp_message_m_media_add(tech_pvt->local_sdp, "audio", port, NULL, "RTP/AVP");
- /* Add in every codec we support on this outbound call */
- if ((num_codecs = loadable_module_get_codecs(switch_core_session_get_pool(session), codecs, sizeof(codecs)/sizeof(codecs[0]))) > 0) {
- int i;
- static const switch_codec_implementation *imp;
- for (i = 0; i < num_codecs; i++) {
- int x = 0;
-
- snprintf(tmp, sizeof(tmp), "%i", codecs[i]->ianacode);
- sdp_message_m_payload_add(tech_pvt->local_sdp, 0, osip_strdup(tmp));
- for (imp = codecs[i]->implementations ; imp ; imp = imp->next) {
- /* Add to SDP config */
- sdp_add_codec(tech_pvt->sdp_config, codecs[i]->codec_type, codecs[i]->ianacode, codecs[i]->iananame, imp->samples_per_second, x++);
- /* Add to SDP message */
-
- snprintf(tmp, sizeof(tmp), "%i %s/%i", codecs[i]->ianacode, codecs[i]->iananame, imp->samples_per_second);
- sdp_message_a_attribute_add(tech_pvt->local_sdp, 0, "rtpmap", osip_strdup(tmp));
- memset(tmp, 0, sizeof(tmp));
- }
- }
- }
- /* Setup our INVITE */
- eXosip_lock();
- if (!(dest_uri = (char *) switch_core_session_alloc(session, strlen(tech_pvt->caller_profile->destination_number) + 10))) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "AIEEEE!\n");
- assert(dest_uri != NULL);
- }
- sprintf(dest_uri, "sip:%s", tech_pvt->caller_profile->destination_number);
- eXosip_call_build_initial_invite(&invite, dest_uri, from_uri, NULL, NULL);
- osip_message_set_supported(invite, "100rel, replaces");
- /* Add SDP to the INVITE */
- sdp_message_to_str(tech_pvt->local_sdp, &buf);
- osip_message_set_body(invite, buf, strlen(buf));
- osip_message_set_content_type(invite, "application/sdp");
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "OUTBOUND SDP:\n%s\n", buf);
- free(buf);
- /* Send the INVITE */
- tech_pvt->cid = eXosip_call_send_initial_invite(invite);
- snprintf(tech_pvt->call_id, sizeof(tech_pvt->call_id), "%d", tech_pvt->cid);
- switch_core_hash_insert(globals.call_hash, tech_pvt->call_id, tech_pvt);
- tech_pvt->did = -1;
- eXosip_unlock();
- }
-
- /* Let Media Work */
- switch_set_flag(tech_pvt, TFLAG_IO);
-
- /* Move Channel's State Machine to RING */
- switch_channel_set_state(channel, CS_RING);
- return SWITCH_STATUS_SUCCESS;
-}
-
-static switch_status exosip_on_ring(switch_core_session *session)
-{
- switch_channel *channel = NULL;
- struct private_object *tech_pvt = NULL;
-
- channel = switch_core_session_get_channel(session);
- assert(channel != NULL);
-
- tech_pvt = switch_core_session_get_private(session);
- assert(tech_pvt != NULL);
-
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "EXOSIP RING\n");
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-static switch_status exosip_on_hangup(switch_core_session *session)
-{
- struct private_object *tech_pvt;
- switch_channel *channel = NULL;
- int i;
-
- channel = switch_core_session_get_channel(session);
- assert(channel != NULL);
-
- tech_pvt = switch_core_session_get_private(session);
- assert(tech_pvt != NULL);
-
-
- switch_core_hash_delete(globals.call_hash, tech_pvt->call_id);
-
-
- switch_set_flag(tech_pvt, TFLAG_BYE);
- switch_clear_flag(tech_pvt, TFLAG_IO);
-
- deactivate_rtp(tech_pvt);
-
- i = eXosip_call_terminate(tech_pvt->cid, tech_pvt->did);
-
- if (switch_test_flag(tech_pvt, TFLAG_USING_CODEC)) {
- switch_core_codec_destroy(&tech_pvt->read_codec);
- switch_core_codec_destroy(&tech_pvt->write_codec);
- }
-
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "EXOSIP HANGUP %s %d/%d=%d\n", switch_channel_get_name(channel), tech_pvt->cid, tech_pvt->did, i);
- return SWITCH_STATUS_SUCCESS;
-}
-
-static switch_status exosip_on_loopback(switch_core_session *session)
-{
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "EXOSIP LOOPBACK\n");
- return SWITCH_STATUS_SUCCESS;
-}
-
-static switch_status exosip_on_transmit(switch_core_session *session)
-{
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "EXOSIP TRANSMIT\n");
- return SWITCH_STATUS_SUCCESS;
-}
-
-static switch_status exosip_outgoing_channel(switch_core_session *session, switch_caller_profile *outbound_profile, switch_core_session **new_session)
-{
- if ((*new_session = switch_core_session_request(&exosip_endpoint_interface, NULL))) {
- struct private_object *tech_pvt;
- switch_channel *channel;
-
- if ((tech_pvt = (struct private_object *) switch_core_session_alloc(*new_session, sizeof(struct private_object)))) {
- memset(tech_pvt, 0, sizeof(*tech_pvt));
- channel = switch_core_session_get_channel(*new_session);
- switch_core_session_set_private(*new_session, tech_pvt);
- switch_mutex_init(&tech_pvt->rtp_lock, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(*new_session));
- tech_pvt->session = *new_session;
- } else {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Hey where is my memory pool?\n");
- switch_core_session_destroy(new_session);
- return SWITCH_STATUS_GENERR;
- }
-
- if (outbound_profile) {
- char name[128];
- switch_caller_profile *caller_profile;
-
- caller_profile = switch_caller_profile_clone(*new_session, outbound_profile);
- switch_channel_set_caller_profile(channel, caller_profile);
- tech_pvt->caller_profile = caller_profile;
- snprintf(name, sizeof(name), "Exosip/%s-%04x", caller_profile->destination_number, rand() & 0xffff);
- switch_channel_set_name(channel, name);
- } else {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Doh! no caller profile\n");
- switch_core_session_destroy(new_session);
- return SWITCH_STATUS_GENERR;
- }
-
- switch_channel_set_flag(channel, CF_OUTBOUND);
- switch_set_flag(tech_pvt, TFLAG_OUTBOUND);
- switch_channel_set_state(channel, CS_INIT);
- return SWITCH_STATUS_SUCCESS;
- }
-
- return SWITCH_STATUS_GENERR;
-}
-
-
-static void deactivate_rtp(struct private_object *tech_pvt)
-{
- int loops = 0;
- if (tech_pvt->rtp_session) {
- switch_mutex_lock(tech_pvt->rtp_lock);
-
- while(loops < 10 && (switch_test_flag(tech_pvt, TFLAG_READING) || switch_test_flag(tech_pvt, TFLAG_WRITING))) {
- switch_yield(10000);
- loops++;
- }
-
- jrtp4c_destroy(&tech_pvt->rtp_session);
- tech_pvt->rtp_session = NULL;
- switch_mutex_unlock(tech_pvt->rtp_lock);
- }
-}
-
-static void activate_rtp(struct private_object *tech_pvt)
-{
- int bw, ms;
- switch_channel *channel;
- const char *err;
-
- assert(tech_pvt != NULL);
-
- channel = switch_core_session_get_channel(tech_pvt->session);
- assert(channel != NULL);
-
- if (tech_pvt->rtp_session) {
- return;
- }
-
- switch_mutex_lock(tech_pvt->rtp_lock);
-
- if (tech_pvt->rtp_session) {
- switch_mutex_unlock(tech_pvt->rtp_lock);
- return;
- }
-
- if (switch_test_flag(tech_pvt, TFLAG_USING_CODEC)) {
- bw = tech_pvt->read_codec.implementation->bits_per_second;
- ms = tech_pvt->read_codec.implementation->microseconds_per_frame;
- } else {
- switch_channel_get_raw_mode(channel, NULL, NULL, NULL, &ms, &bw);
- bw *= 8;
- }
-
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Activating RTP %s:%d->%s:%d codec: %d ms: %d\n",
- tech_pvt->local_sdp_audio_ip,
- tech_pvt->local_sdp_audio_port,
- tech_pvt->remote_sdp_audio_ip,
- tech_pvt->remote_sdp_audio_port,
- tech_pvt->read_codec.codec_interface->ianacode,
- ms
- );
-
-
-
-
- tech_pvt->rtp_session = jrtp4c_new(
- tech_pvt->local_sdp_audio_ip,
- tech_pvt->local_sdp_audio_port,
- tech_pvt->remote_sdp_audio_ip,
- tech_pvt->remote_sdp_audio_port,
- tech_pvt->read_codec.codec_interface->ianacode,
- tech_pvt->read_codec.implementation->samples_per_second,
- &err);
-
- if (tech_pvt->rtp_session) {
- tech_pvt->ssrc = jrtp4c_get_ssrc(tech_pvt->rtp_session);
- jrtp4c_start(tech_pvt->rtp_session);
- switch_set_flag(tech_pvt, TFLAG_RTP);
- } else {
- switch_channel *channel = switch_core_session_get_channel(tech_pvt->session);
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Oh oh? [%s]\n", err);
- switch_channel_hangup(channel);
- switch_set_flag(tech_pvt, TFLAG_BYE);
- switch_clear_flag(tech_pvt, TFLAG_IO);
- }
-
- switch_mutex_unlock(tech_pvt->rtp_lock);
-}
-
-static switch_status exosip_answer_channel(switch_core_session *session)
-{
- struct private_object *tech_pvt;
- switch_channel *channel = NULL;
-
- channel = switch_core_session_get_channel(session);
- assert(channel != NULL);
-
- tech_pvt = switch_core_session_get_private(session);
- assert(tech_pvt != NULL);
-
- if (!switch_channel_test_flag(channel, CF_OUTBOUND)) {
- char *buf = NULL;
- osip_message_t *answer = NULL;
-
-
- /* Transmit 200 OK with SDP */
- eXosip_lock();
- eXosip_call_build_answer(tech_pvt->tid, 200, &answer);
- sdp_message_to_str(tech_pvt->local_sdp, &buf);
- osip_message_set_body(answer, buf, strlen(buf));
- osip_message_set_content_type(answer, "application/sdp");
- free(buf);
- eXosip_call_send_answer(tech_pvt->tid, 200, answer);
- eXosip_unlock();
- }
-
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-
-static switch_status exosip_read_frame(switch_core_session *session, switch_frame **frame, int timeout, switch_io_flag flags)
-{
- struct private_object *tech_pvt = NULL;
- size_t bytes = 0, samples = 0, frames=0, ms=0;
- switch_channel *channel = NULL;
-
- channel = switch_core_session_get_channel(session);
- assert(channel != NULL);
-
- tech_pvt = switch_core_session_get_private(session);
- assert(tech_pvt != NULL);
-
- tech_pvt->read_frame.datalen = 0;
- switch_set_flag(tech_pvt, TFLAG_READING);
-
- if (switch_test_flag(tech_pvt, TFLAG_USING_CODEC)) {
- bytes = tech_pvt->read_codec.implementation->encoded_bytes_per_frame;
- samples = tech_pvt->read_codec.implementation->samples_per_frame;
- ms = tech_pvt->read_codec.implementation->microseconds_per_frame;
- } else {
- assert(0);
- }
-
- if (switch_test_flag(tech_pvt, TFLAG_IO)) {
- if (!switch_test_flag(tech_pvt, TFLAG_RTP)) {
- return SWITCH_STATUS_GENERR;
- }
-
-
- assert(tech_pvt->rtp_session != NULL);
- tech_pvt->read_frame.datalen = 0;
-
- while(!switch_test_flag(tech_pvt, TFLAG_BYE) && switch_test_flag(tech_pvt, TFLAG_IO) && tech_pvt->read_frame.datalen == 0) {
- tech_pvt->read_frame.datalen = jrtp4c_read(tech_pvt->rtp_session,
- tech_pvt->read_frame.data,
- sizeof(tech_pvt->read_buf));
-
- if (tech_pvt->read_frame.datalen > 0) {
- bytes = tech_pvt->read_codec.implementation->encoded_bytes_per_frame;
- frames = (tech_pvt->read_frame.datalen / bytes);
- samples = frames * tech_pvt->read_codec.implementation->samples_per_frame;
- ms = frames * tech_pvt->read_codec.implementation->microseconds_per_frame;
- tech_pvt->timestamp_recv += (int32_t)samples;
- tech_pvt->read_frame.samples = (int)samples;
- break;
- }
-
- switch_yield(100);
- }
-
- //tech_pvt->timestamp_recv += samples;
-
-
- //printf("%s %s->%s recv %d bytes %d samples in %d frames taking up %d ms ts=%d\n", switch_channel_get_name(channel), tech_pvt->local_sdp_audio_ip, tech_pvt->local_sdp_audio_ip, tech_pvt->read_frame.datalen, samples, frames, ms, tech_pvt->timestamp_recv);
-
-
- //switch_mutex_unlock(tech_pvt->rtp_lock);
-
- } else {
- memset(tech_pvt->read_buf, 0, 160);
- tech_pvt->read_frame.datalen = 160;
- }
-
- switch_clear_flag(tech_pvt, TFLAG_READING);
-
- if (switch_test_flag(tech_pvt, TFLAG_BYE)) {
- switch_channel_hangup(channel);
- return SWITCH_STATUS_FALSE;
- }
-
- *frame = &tech_pvt->read_frame;
-
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-
-static switch_status exosip_write_frame(switch_core_session *session, switch_frame *frame, int timeout, switch_io_flag flags)
-{
- struct private_object *tech_pvt;
- switch_channel *channel = NULL;
- switch_status status = SWITCH_STATUS_SUCCESS;
- int bytes=0, samples=0, ms=0, frames=0;
-
- channel = switch_core_session_get_channel(session);
- assert(channel != NULL);
-
- tech_pvt = switch_core_session_get_private(session);
- assert(tech_pvt != NULL);
-
- if (!switch_test_flag(tech_pvt, TFLAG_RTP)) {
- return SWITCH_STATUS_GENERR;
- }
-
- if (!switch_test_flag(tech_pvt, TFLAG_IO)) {
- return SWITCH_STATUS_SUCCESS;
- }
-
- if (switch_test_flag(tech_pvt, TFLAG_BYE)) {
- switch_channel_hangup(channel);
- return SWITCH_STATUS_FALSE;
- }
-
- switch_set_flag(tech_pvt, TFLAG_WRITING);
- //switch_mutex_lock(tech_pvt->rtp_lock);
-
- if (switch_test_flag(tech_pvt, TFLAG_USING_CODEC)) {
- bytes = tech_pvt->read_codec.implementation->encoded_bytes_per_frame;
- frames = ((int)frame->datalen / bytes);
- samples = frames * tech_pvt->read_codec.implementation->samples_per_frame;
- ms = frames * tech_pvt->read_codec.implementation->microseconds_per_frame / 1000;
- } else {
- assert(0);
- }
-
-
- //printf("%s %s->%s send %d bytes %d samples in %d frames taking up %d ms ts=%d\n", switch_channel_get_name(channel), tech_pvt->local_sdp_audio_ip, tech_pvt->remote_sdp_audio_ip, frame->datalen, samples, frames, ms, tech_pvt->timestamp_send);
-
-
- jrtp4c_write(tech_pvt->rtp_session, frame->data, (int)frame->datalen, samples);
- tech_pvt->timestamp_send += (int)samples;
-
- switch_clear_flag(tech_pvt, TFLAG_WRITING);
- //switch_mutex_unlock(tech_pvt->rtp_lock);
- return status;
-}
-
-
-
-static switch_status exosip_kill_channel(switch_core_session *session, int sig)
-{
- struct private_object *tech_pvt;
- switch_channel *channel = NULL;
-
- channel = switch_core_session_get_channel(session);
- assert(channel != NULL);
-
- tech_pvt = switch_core_session_get_private(session);
- assert(tech_pvt != NULL);
-
-
- switch_clear_flag(tech_pvt, TFLAG_IO);
- switch_set_flag(tech_pvt, TFLAG_BYE);
-
- return SWITCH_STATUS_SUCCESS;
-
-}
-
-static switch_status exosip_waitfor_read(switch_core_session *session, int ms)
-{
- struct private_object *tech_pvt;
- switch_channel *channel = NULL;
-
- channel = switch_core_session_get_channel(session);
- assert(channel != NULL);
-
- tech_pvt = switch_core_session_get_private(session);
- assert(tech_pvt != NULL);
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-
-static switch_status exosip_waitfor_write(switch_core_session *session, int ms)
-{
- struct private_object *tech_pvt;
- switch_channel *channel = NULL;
-
- channel = switch_core_session_get_channel(session);
- assert(channel != NULL);
-
- tech_pvt = switch_core_session_get_private(session);
- assert(tech_pvt != NULL);
-
- return SWITCH_STATUS_SUCCESS;
-
-}
-
-static const switch_io_routines exosip_io_routines = {
- /*.outgoing_channel*/ exosip_outgoing_channel,
- /*.answer_channel*/ exosip_answer_channel,
- /*.read_frame*/ exosip_read_frame,
- /*.write_frame*/ exosip_write_frame,
- /*.kill_channel*/ exosip_kill_channel,
- /*.waitfor_read*/ exosip_waitfor_read,
- /*.waitfor_read*/ exosip_waitfor_write
-};
-
-static const switch_event_handler_table exosip_event_handlers = {
- /*.on_init*/ exosip_on_init,
- /*.on_ring*/ exosip_on_ring,
- /*.on_execute*/ exosip_on_execute,
- /*.on_hangup*/ exosip_on_hangup,
- /*.on_loopback*/ exosip_on_loopback,
- /*.on_transmit*/ exosip_on_transmit
-};
-
-static const switch_endpoint_interface exosip_endpoint_interface = {
- /*.interface_name*/ "exosip",
- /*.io_routines*/ &exosip_io_routines,
- /*.event_handlers*/ &exosip_event_handlers,
- /*.private*/ NULL,
- /*.next*/ NULL
-};
-
-static const switch_loadable_module_interface exosip_module_interface = {
- /*.module_name*/ modname,
- /*.endpoint_interface*/ &exosip_endpoint_interface,
- /*.timer_interface*/ NULL,
- /*.dialplan_interface*/ NULL,
- /*.codec_interface*/ NULL,
- /*.application_interface*/ NULL
-};
-
-
-SWITCH_MOD_DECLARE(switch_status) switch_module_shutdown(void)
-{
- if (globals.running) {
- globals.running = -1;
- while(globals.running) {
- switch_yield(1000);
- }
- }
- return SWITCH_STATUS_SUCCESS;
-}
-
-SWITCH_MOD_DECLARE(switch_status) switch_module_load(const switch_loadable_module_interface **interface, char *filename) {
- /* NOTE: **interface is **_interface because the common lib redefines interface to struct in some situations */
-
- if (switch_core_new_memory_pool(&module_pool) != SWITCH_STATUS_SUCCESS) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "OH OH no pool\n");
- return SWITCH_STATUS_TERM;
- }
-
- /* connect my internal structure to the blank pointer passed to me */
- *interface = &exosip_module_interface;
-
- /* indicate that the module should continue to be loaded */
- return SWITCH_STATUS_SUCCESS;
-}
-
-static switch_status exosip_create_call(eXosip_event_t *event)
-{
- switch_core_session *session;
- sdp_message_t *remote_sdp = NULL;
- sdp_connection_t *conn = NULL;
- sdp_media_t *remote_med = NULL, *audio_tab[10], *video_tab[10], *t38_tab[10], *app_tab[10];
- char local_sdp_str[8192] = "", port[8] = "";
- int mline = 0, pos = 0;
- switch_channel *channel = NULL;
- char name[128];
- char *dpayload, *dname, *drate;
- char *remote_sdp_str = NULL;
-
- if ((session = switch_core_session_request(&exosip_endpoint_interface, NULL))) {
- struct private_object *tech_pvt;
- switch_codec_interface *codecs[SWITCH_MAX_CODECS];
- int num_codecs = 0;
-
-
- if ((tech_pvt = (struct private_object *) switch_core_session_alloc(session, sizeof(struct private_object)))) {
- memset(tech_pvt, 0, sizeof(*tech_pvt));
- channel = switch_core_session_get_channel(session);
- switch_core_session_set_private(session, tech_pvt);
- tech_pvt->session = session;
- switch_mutex_init(&tech_pvt->rtp_lock, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session));
- } else {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Hey where is my memory pool?\n");
- switch_core_session_destroy(&session);
- return SWITCH_STATUS_MEMERR;
- }
-
- if ((tech_pvt->caller_profile = switch_caller_profile_new(session,
- globals.dialplan,
- event->request->from->displayname,
- event->request->from->url->username,
- event->request->from->url->host,
- NULL,
- NULL,
- event->request->req_uri->username))) {
- switch_channel_set_caller_profile(channel, tech_pvt->caller_profile);
- }
-
- switch_set_flag(tech_pvt, TFLAG_INBOUND);
- tech_pvt->did = event->did;
- tech_pvt->cid = event->cid;
- tech_pvt->tid = event->tid;
-
- snprintf(name, sizeof(name), "Exosip/%s-%04x", tech_pvt->caller_profile->destination_number, rand() & 0xffff);
- switch_channel_set_name(channel, name);
-
- if (!(remote_sdp = eXosip_get_sdp_info(event->request))) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Cannot Find Remote SDP!\n");
- exosip_on_hangup(session);
- switch_core_session_destroy(&session);
- return SWITCH_STATUS_GENERR;
- }
-
- eXosip_guess_localip(AF_INET, tech_pvt->local_sdp_audio_ip, 50);
- tech_pvt->local_sdp_audio_port = next_rtp_port();
- osip_rfc3264_init(&tech_pvt->sdp_config);
- /* Add in what codecs we support locally */
-
- if ((num_codecs = loadable_module_get_codecs(switch_core_session_get_pool(session), codecs, sizeof(codecs)/sizeof(codecs[0]))) > 0) {
- int i;
- static const switch_codec_implementation *imp;
-
- for (i = 0; i < num_codecs; i++) {
- int x = 0;
- for (imp = codecs[i]->implementations ; imp ; imp = imp->next) {
- sdp_add_codec(tech_pvt->sdp_config, codecs[i]->codec_type, codecs[i]->ianacode, codecs[i]->iananame, imp->samples_per_second, x++);
- }
- }
- }
- osip_rfc3264_prepare_answer(tech_pvt->sdp_config, remote_sdp, local_sdp_str, 8192);
- sdp_message_init(&tech_pvt->local_sdp);
- sdp_message_parse(tech_pvt->local_sdp, local_sdp_str);
-
- sdp_message_to_str(remote_sdp, &remote_sdp_str);
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "LOCAL SDP:\n%s\nREMOTE SDP:\n%s", local_sdp_str,remote_sdp_str);
-
- mline = 0;
- while (0==osip_rfc3264_match(tech_pvt->sdp_config, remote_sdp, audio_tab, video_tab, t38_tab, app_tab, mline)) {
- if (audio_tab[0] == NULL && video_tab[0] == NULL && t38_tab[0] == NULL && app_tab[0] == NULL) {
-
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Got no compatible codecs!\n");
- break;
- }
- for (pos=0; audio_tab[pos]!=NULL; pos++) {
- osip_rfc3264_complete_answer(tech_pvt->sdp_config, remote_sdp, tech_pvt->local_sdp, audio_tab[pos], mline);
- if (parse_sdp_media(audio_tab[pos], &dname, &drate, &dpayload) == SWITCH_STATUS_SUCCESS) {
- tech_pvt->payload_num = atoi(dpayload);
- break;
- }
- }
- mline++;
- }
- free(remote_sdp_str);
- sdp_message_o_origin_set(tech_pvt->local_sdp, "OpenSWITCH2", "0", "0", "IN", "IP4", tech_pvt->local_sdp_audio_ip);
- sdp_message_s_name_set(tech_pvt->local_sdp, "SIP Call");
- sdp_message_c_connection_add(tech_pvt->local_sdp, -1, "IN", "IP4", tech_pvt->local_sdp_audio_ip, NULL, NULL);
- snprintf(port, sizeof(port), "%i", tech_pvt->local_sdp_audio_port);
- sdp_message_m_port_set(tech_pvt->local_sdp, 0, osip_strdup(port));
-
- conn = eXosip_get_audio_connection(remote_sdp);
- remote_med = eXosip_get_audio_media(remote_sdp);
- snprintf(tech_pvt->remote_sdp_audio_ip, 50, conn->c_addr);
-
- tech_pvt->remote_sdp_audio_port = atoi(remote_med->m_port);
-
- snprintf(tech_pvt->call_id, sizeof(tech_pvt->call_id), "%d", event->cid);
- switch_core_hash_insert(globals.call_hash, tech_pvt->call_id, tech_pvt);
-
- if (!dname) {
- exosip_on_hangup(session);
- switch_core_session_destroy(&session);
- return SWITCH_STATUS_GENERR;
- }
-
- switch_channel_set_state(channel, CS_INIT);
-
-
- if (1) {
- int rate = atoi(drate);
-
- if (switch_core_codec_init(&tech_pvt->read_codec,
- dname,
- rate,
- globals.codec_ms,
- 1,
- SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
- NULL,
- switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Can't load codec?\n");
- switch_channel_hangup(channel);
- return SWITCH_STATUS_FALSE;
- } else {
- if (switch_core_codec_init(&tech_pvt->write_codec,
- dname,
- rate,
- globals.codec_ms,
- 1,
- SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
- NULL,
- switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Can't load codec?\n");
- switch_channel_hangup(channel);
- return SWITCH_STATUS_FALSE;
- } else {
- int ms;
- tech_pvt->read_frame.rate = rate;
- switch_set_flag(tech_pvt, TFLAG_USING_CODEC);
- ms = tech_pvt->write_codec.implementation->microseconds_per_frame / 1000;
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Activate Inbound Codec %s/%d %d ms\n", dname, rate, ms);
- tech_pvt->read_frame.codec = &tech_pvt->read_codec;
- switch_core_session_set_read_codec(session, &tech_pvt->read_codec);
- switch_core_session_set_write_codec(session, &tech_pvt->write_codec);
- }
- }
- }
-
- activate_rtp(tech_pvt);
-
- if (switch_test_flag(tech_pvt, TFLAG_RTP)) {
- switch_core_session_thread_launch(session);
- } else {
- switch_core_session_destroy(&session);
- return SWITCH_STATUS_FALSE;
- }
- } else {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Cannot Create new Inbound Channel!\n");
- }
-
-
- return 0;
-
-}
-
-static void destroy_call_by_event(eXosip_event_t *event)
-{
- struct private_object *tech_pvt;
- switch_channel *channel = NULL;
-
- if (!(tech_pvt = get_pvt_by_call_id(event->cid))) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Um in case you are interested, Can't find the pvt [%d]!\n", event->cid);
- return;
- }
-
- channel = switch_core_session_get_channel(tech_pvt->session);
- assert(channel != NULL);
-
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "destroy %s\n", switch_channel_get_name(channel));
- exosip_kill_channel(tech_pvt->session, SWITCH_SIG_KILL);
- switch_channel_hangup(channel);
-
-}
-
-static switch_status parse_sdp_media(sdp_media_t *media, char **dname, char **drate, char **dpayload)
-{
- int pos = 0;
- sdp_attribute_t *attr = NULL;
- char *name, *rate, *payload;
- switch_status status = SWITCH_STATUS_GENERR;
-
- while (osip_list_eol(media->a_attributes, pos) == 0) {
- attr = (sdp_attribute_t *)osip_list_get(media->a_attributes, pos);
- if (attr != NULL && strcasecmp(attr->a_att_field, "rtpmap") == 0) {
- payload = attr->a_att_value;
- if ((name = strchr(payload, ' '))) {
- *(name++) = '\0';
- /* Name and payload are required */
- *dpayload = strdup(payload);
- status = SWITCH_STATUS_SUCCESS;
- if ((rate = strchr(name, '/'))) {
- *(rate++) = '\0';
- *drate = strdup(rate);
- *dname = strdup(name);
- } else {
- *dname = strdup(name);
- *drate = strdup("8000");
- }
- } else {
- *dpayload = strdup("10");
- *dname = strdup("L16");
- *drate = strdup("8000");
- }
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Found negotiated codec Payload: %s Name: %s Rate: %s\n", *dpayload, *dname, *drate);
- break;
- }
- attr = NULL;
- pos++;
- }
-
- return status;
-}
-
-static void handle_answer(eXosip_event_t *event)
-{
- osip_message_t *ack = NULL;
- sdp_message_t *remote_sdp = NULL;
- sdp_connection_t *conn = NULL;
- sdp_media_t *remote_med = NULL;
- struct private_object *tech_pvt;
- char *dpayload = NULL, *dname = NULL, *drate = NULL;
- switch_channel *channel;
-
-
- if (!(tech_pvt = get_pvt_by_call_id(event->cid))) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Um in case you are interested, Can't find the pvt!\n");
- return;
- }
-
- channel = switch_core_session_get_channel(tech_pvt->session);
- assert(channel != NULL);
-
- if (!event->response) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Someone answered... with no SDP information - WTF?!?\n");
- switch_channel_hangup(channel);
- return;
- }
-
- /* Get all of the remote SDP elements... stuff */
- if (!(remote_sdp = eXosip_get_sdp_info(event->response))) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Cant Find SDP?\n");
- switch_channel_hangup(channel);
- return;
- }
-
-
- conn = eXosip_get_audio_connection(remote_sdp);
- remote_med = eXosip_get_audio_media(remote_sdp);
-
- /* Grab IP/port */
- tech_pvt->remote_sdp_audio_port = atoi(remote_med->m_port);
- snprintf(tech_pvt->remote_sdp_audio_ip, 50, conn->c_addr);
-
- /* Grab codec elements */
- if (parse_sdp_media(remote_med, &dname, &drate, &dpayload) == SWITCH_STATUS_SUCCESS) {
- tech_pvt->payload_num = atoi(dpayload);
- }
-
- /* Assign them thar IDs */
- tech_pvt->did = event->did;
- tech_pvt->tid = event->tid;
-
-
- if (1) {
- int rate = atoi(drate);
-
-
- if (switch_core_codec_init(&tech_pvt->read_codec,
- dname,
- rate,
- globals.codec_ms,
- 1,
- SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
- NULL,
- switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Can't load codec?\n");
- switch_channel_hangup(channel);
- return;
- } else {
- if (switch_core_codec_init(&tech_pvt->write_codec,
- dname,
- rate,
- globals.codec_ms,
- 1,
- SWITCH_CODEC_FLAG_ENCODE |SWITCH_CODEC_FLAG_DECODE,
- NULL,
- switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Can't load codec?\n");
- switch_channel_hangup(channel);
- return;
- } else {
- int ms;
- tech_pvt->read_frame.rate = rate;
- switch_set_flag(tech_pvt, TFLAG_USING_CODEC);
- ms = tech_pvt->write_codec.implementation->microseconds_per_frame / 1000;
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Activate Outbound Codec %s/%d %d ms\n", dname, rate, ms);
- tech_pvt->read_frame.codec = &tech_pvt->read_codec;
- switch_core_session_set_read_codec(tech_pvt->session, &tech_pvt->read_codec);
- switch_core_session_set_write_codec(tech_pvt->session, &tech_pvt->write_codec);
- }
- }
- }
-
-
- eXosip_lock();
- eXosip_call_build_ack(event->did, &ack);
- eXosip_call_send_ack(event->did, ack);
- eXosip_unlock();
-
- free(dname);
- free(drate);
- free(dpayload);
-
-
- activate_rtp(tech_pvt);
-
- if (switch_test_flag(tech_pvt, TFLAG_RTP)) {
- channel = switch_core_session_get_channel(tech_pvt->session);
- assert(channel != NULL);
- switch_channel_answer(channel);
- }
-}
-
-static void log_event(eXosip_event_t *je)
-{
- char buf[100];
-
- buf[0] = '\0';
- if (je->type == EXOSIP_CALL_NOANSWER) {
- snprintf (buf, 99, "<- (%i %i) No answer", je->cid, je->did);
- } else if (je->type == EXOSIP_CALL_CLOSED) {
- snprintf (buf, 99, "<- (%i %i) Call Closed", je->cid, je->did);
- } else if (je->type == EXOSIP_CALL_RELEASED) {
- snprintf (buf, 99, "<- (%i %i) Call released", je->cid, je->did);
- } else if (je->type == EXOSIP_MESSAGE_NEW
- && je->request!=NULL && MSG_IS_MESSAGE(je->request)) {
- char *tmp = NULL;
-
- if (je->request != NULL) {
- osip_body_t *body;
- osip_from_to_str (je->request->from, &tmp);
-
- osip_message_get_body (je->request, 0, &body);
- if (body != NULL && body->body != NULL) {
- snprintf (buf, 99, "<- (%i) from: %s TEXT: %s",
- je->tid, tmp, body->body);
- }
- osip_free (tmp);
- } else {
- snprintf (buf, 99, "<- (%i) New event for unknown request?", je->tid);
- }
- } else if (je->type == EXOSIP_MESSAGE_NEW) {
- char *tmp = NULL;
-
- osip_from_to_str (je->request->from, &tmp);
- snprintf (buf, 99, "<- (%i) %s from: %s",
- je->tid, je->request->sip_method, tmp);
- osip_free (tmp);
- } else if (je->type == EXOSIP_MESSAGE_PROCEEDING
- || je->type == EXOSIP_MESSAGE_ANSWERED
- || je->type == EXOSIP_MESSAGE_REDIRECTED
- || je->type == EXOSIP_MESSAGE_REQUESTFAILURE
- || je->type == EXOSIP_MESSAGE_SERVERFAILURE
- || je->type == EXOSIP_MESSAGE_GLOBALFAILURE) {
- if (je->response != NULL && je->request != NULL) {
- char *tmp = NULL;
-
- osip_to_to_str (je->request->to, &tmp);
- snprintf (buf, 99, "<- (%i) [%i %s for %s] to: %s",
- je->tid, je->response->status_code,
- je->response->reason_phrase, je->request->sip_method, tmp);
- osip_free (tmp);
- } else if (je->request != NULL) {
- snprintf (buf, 99, "<- (%i) Error for %s request",
- je->tid, je->request->sip_method);
- } else {
- snprintf (buf, 99, "<- (%i) Error for unknown request", je->tid);
- }
- } else if (je->response == NULL && je->request != NULL && je->cid > 0) {
- char *tmp = NULL;
-
- osip_from_to_str (je->request->from, &tmp);
- snprintf (buf, 99, "<- (%i %i) %s from: %s",
- je->cid, je->did, je->request->cseq->method, tmp);
- osip_free (tmp);
- } else if (je->response != NULL && je->cid > 0) {
- char *tmp = NULL;
-
- osip_to_to_str (je->request->to, &tmp);
- snprintf (buf, 99, "<- (%i %i) [%i %s] for %s to: %s",
- je->cid, je->did, je->response->status_code,
- je->response->reason_phrase, je->request->sip_method, tmp);
- osip_free (tmp);
- } else if (je->response == NULL && je->request != NULL && je->rid > 0) {
- char *tmp = NULL;
-
- osip_from_to_str (je->request->from, &tmp);
- snprintf (buf, 99, "<- (%i) %s from: %s",
- je->rid, je->request->cseq->method, tmp);
- osip_free (tmp);
- } else if (je->response != NULL && je->rid > 0) {
- char *tmp = NULL;
-
- osip_from_to_str (je->request->from, &tmp);
- snprintf (buf, 99, "<- (%i) [%i %s] from: %s",
- je->rid, je->response->status_code,
- je->response->reason_phrase, tmp);
- osip_free (tmp);
- } else if (je->response == NULL && je->request != NULL && je->sid > 0) {
- char *tmp = NULL;
- char *stat = NULL;
- osip_header_t *sub_state;
-
- osip_message_header_get_byname (je->request, "subscription-state",
- 0, &sub_state);
- if (sub_state != NULL && sub_state->hvalue != NULL)
- stat = sub_state->hvalue;
-
- osip_uri_to_str (je->request->from->url, &tmp);
- snprintf (buf, 99, "<- (%i) [%s] %s from: %s",
- je->sid, stat, je->request->cseq->method, tmp);
- osip_free (tmp);
- } else if (je->response != NULL && je->sid > 0) {
- char *tmp = NULL;
-
- osip_uri_to_str (je->request->to->url, &tmp);
- snprintf (buf, 99, "<- (%i) [%i %s] from: %s",
- je->sid, je->response->status_code,
- je->response->reason_phrase, tmp);
- osip_free (tmp);
- } else if (je->response == NULL && je->request != NULL) {
- char *tmp = NULL;
-
- osip_from_to_str (je->request->from, &tmp);
- snprintf (buf, 99, "<- (c=%i|d=%i|s=%i|n=%i) %s from: %s",
- je->cid, je->did, je->sid, je->nid,
- je->request->sip_method, tmp);
- osip_free (tmp);
- } else if (je->response != NULL) {
- char *tmp = NULL;
-
- osip_from_to_str (je->request->from, &tmp);
- snprintf (buf, 99, "<- (c=%i|d=%i|s=%i|n=%i) [%i %s] for %s from: %s",
- je->cid, je->did, je->sid, je->nid,
- je->response->status_code, je->response->reason_phrase,
- je->request->sip_method, tmp);
- osip_free (tmp);
- } else {
- snprintf (buf, 99, "<- (c=%i|d=%i|s=%i|n=%i|t=%i) %s",
- je->cid, je->did, je->sid, je->nid, je->tid, je->textinfo);
- }
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "\n%s\n", buf);
- /* Print it out */
-}
-
-
-
-static void *monitor_thread_run(void)
-{
- eXosip_event_t *event = NULL;
-
- globals.running = 1;
- while (globals.running > 0) {
- if (!(event = eXosip_event_wait(0,100))) {
- switch_yield(100);
- continue;
- }
-
- eXosip_lock();
- eXosip_automatic_action ();
- eXosip_unlock();
-
- log_event(event);
-
- switch(event->type) {
- case EXOSIP_CALL_INVITE:
- exosip_create_call(event);
- break;
- case EXOSIP_CALL_REINVITE:
- /* See what the reinvite is about - on hold or whatever */
- //handle_reinvite(event);
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Got a reinvite.\n");
- break;
- case EXOSIP_CALL_MESSAGE_NEW:
- if (event->request != NULL && MSG_IS_REFER(event->request)) {
- //handle_call_transfer(event);
- }
- break;
- case EXOSIP_CALL_ACK:
- /* If audio is not flowing and this has SDP - fire it up! */
- break;
- case EXOSIP_CALL_ANSWERED:
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "The call was answered.\n");
- handle_answer(event);
- break;
- case EXOSIP_CALL_PROCEEDING:
- /* This is like a 100 Trying... yeah */
- break;
- case EXOSIP_CALL_RINGING:
- //handle_ringing(event);
- break;
- case EXOSIP_CALL_REDIRECTED:
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Call was redirect\n");
- break;
- case EXOSIP_CALL_CLOSED:
- destroy_call_by_event(event);
- break;
- case EXOSIP_CALL_RELEASED:
- destroy_call_by_event(event);
- break;
- case EXOSIP_CALL_NOANSWER:
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "The call was not answered.\n");
- destroy_call_by_event(event);
- break;
- case EXOSIP_CALL_REQUESTFAILURE:
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Request failure\n");
- destroy_call_by_event(event);
- break;
- case EXOSIP_CALL_SERVERFAILURE:
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Server failure\n");
- destroy_call_by_event(event);
- break;
- case EXOSIP_CALL_GLOBALFAILURE:
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Global failure\n");
- destroy_call_by_event(event);
- break;
- /* Registration related stuff */
- case EXOSIP_REGISTRATION_NEW:
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Received registration attempt\n");
- break;
- default:
- /* Unknown event... casually absorb it for now */
- break;
- }
-
- //switch_console_printf(SWITCH_CHANNEL_CONSOLE, "There was an event (%d) [%s]\n", event->type, event->textinfo);
- /* Free the event */
- eXosip_event_free(event);
- }
-
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Monitor Thread Exiting\n");
- globals.running = 0;
- return NULL;
-}
-
-
-static int config_exosip(int reload)
-{
- switch_config cfg;
- char *var, *val;
- char *cf = "exosip.conf";
-
- globals.bytes_per_frame = DEFAULT_BYTES_PER_FRAME;
- switch_core_hash_init(&globals.call_hash, module_pool);
-
- if (!switch_config_open_file(&cfg, cf)) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "open of %s failed\n", cf);
- return SWITCH_STATUS_TERM;
- }
-
- globals.rtp_start = 16384;
- globals.rtp_end = 32768;
-
- while (switch_config_next_pair(&cfg, &var, &val)) {
- if (!strcasecmp(cfg.category, "settings")) {
- if (!strcmp(var, "debug")) {
- globals.debug = atoi(val);
- } else if (!strcmp(var, "port")) {
- globals.port = atoi(val);
- } else if (!strcmp(var, "dialplan")) {
- set_global_dialplan(val);
- } else if (!strcmp(var, "rtp_min_port")) {
- globals.rtp_start = atoi(val);
- } else if (!strcmp(var, "rtp_max_port")) {
- globals.rtp_end = atoi(val);
- } else if (!strcmp(var, "codec_ms")) {
- globals.codec_ms = atoi(val);
- }
- }
- }
-
- if (!globals.codec_ms) {
- globals.codec_ms = 20;
- }
-
- if (!globals.port) {
- globals.port = 5060;
- }
-
- switch_config_close_file(&cfg);
-
- if (!globals.dialplan) {
- set_global_dialplan("default");
- }
-
- if (eXosip_init ()) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "eXosip_init initialization failed!\n");
- return SWITCH_STATUS_GENERR;
- }
- if (eXosip_listen_addr (IPPROTO_UDP, NULL, globals.port, AF_INET, 0)) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "eXosip_listen_addr failed!\n");
- return SWITCH_STATUS_GENERR;
- }
-
- switch_mutex_init(&globals.port_lock, SWITCH_MUTEX_NESTED, module_pool);
-
- /* Setup the user agent */
- eXosip_set_user_agent("FreeSWITCH");
-
- monitor_thread_run();
-
- eXosip_quit();
-
- return 0;
-
-}
-
-
-SWITCH_MOD_DECLARE(switch_status) switch_module_runtime(void)
-{
- config_exosip(0);
- return SWITCH_STATUS_TERM;
-}
-
+++ /dev/null
-<?xml version="1.0" encoding="Windows-1252"?>\r
-<VisualStudioProject\r
- ProjectType="Visual C++"\r
- Version="8.00"\r
- Name="mod_exosip"\r
- ProjectGUID="{45DF84ED-D24A-4FF6-B5B0-0A9A5FDB9552}"\r
- RootNamespace="mod_exosip"\r
- Keyword="Win32Proj"\r
- >\r
- <Platforms>\r
- <Platform\r
- Name="Win32"\r
- />\r
- </Platforms>\r
- <ToolFiles>\r
- </ToolFiles>\r
- <Configurations>\r
- <Configuration\r
- Name="Debug|Win32"\r
- OutputDirectory="Debug"\r
- IntermediateDirectory="Debug"\r
- ConfigurationType="2"\r
- InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
- CharacterSet="2"\r
- >\r
- <Tool\r
- Name="VCPreBuildEventTool"\r
- CommandLine="cscript /nologo $(InputDir)..\..\..\w32\vsnet\getlibs.vbs Mod_Exosip Debug"\r
- />\r
- <Tool\r
- Name="VCCustomBuildTool"\r
- />\r
- <Tool\r
- Name="VCXMLDataGeneratorTool"\r
- />\r
- <Tool\r
- Name="VCWebServiceProxyGeneratorTool"\r
- />\r
- <Tool\r
- Name="VCMIDLTool"\r
- />\r
- <Tool\r
- Name="VCCLCompilerTool"\r
- AdditionalOptions="/D _CRT_SECURE_NO_DEPRECATE"\r
- Optimization="0"\r
- AdditionalIncludeDirectories="..\..\include;..\..\..\libs\include;..\..\..\libs\libeXosip2\include;..\..\..\libs\osip\include;..\..\..\libs\jrtp4c\src;..\..\..\libs\osip\src\osipparser2;..\..\..\libs\jrtplib\src;"..\..\..\libs\jthread-1.1.2\src""\r
- PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS"\r
- GeneratePreprocessedFile="0"\r
- MinimalRebuild="true"\r
- BasicRuntimeChecks="3"\r
- RuntimeLibrary="1"\r
- UsePrecompiledHeader="0"\r
- WarningLevel="3"\r
- Detect64BitPortabilityProblems="true"\r
- DebugInformationFormat="4"\r
- />\r
- <Tool\r
- Name="VCManagedResourceCompilerTool"\r
- />\r
- <Tool\r
- Name="VCResourceCompilerTool"\r
- />\r
- <Tool\r
- Name="VCPreLinkEventTool"\r
- />\r
- <Tool\r
- Name="VCLinkerTool"\r
- AdditionalOptions="/NODEFAULTLIB:LIBCMT"\r
- AdditionalDependencies="Ws2_32.lib Iphlpapi.lib libcpmt.lib eXosip.lib jrtplib.lib jthread.lib osipparser2.lib osip2.lib"\r
- ShowProgress="0"\r
- OutputFile="..\..\..\w32\vsnet\$(OutDir)/mod/mod_exosip.dll"\r
- LinkIncremental="2"\r
- AdditionalLibraryDirectories=""$(InputDir)..\..\..\libs\apr\Debug";"$(InputDir)..\..\..\libs\jrtp4c\w32\Debug";"$(InputDir)..\..\..\libs\jrtplib\Debug";"$(InputDir)..\..\..\libs\jthread-1.1.2\Debug";"$(InputDir)..\..\..\libs\libeXosip2\platform\vsnet\Debug";"$(InputDir)..\..\..\libs\osip\platform\vsnet\Debug""\r
- IgnoreAllDefaultLibraries="false"\r
- IgnoreDefaultLibraryNames=""\r
- GenerateDebugInformation="true"\r
- ProgramDatabaseFile="$(OutDir)/mod_exosip.pdb"\r
- SubSystem="2"\r
- ImportLibrary="$(OutDir)/mod_exosip.lib"\r
- TargetMachine="1"\r
- />\r
- <Tool\r
- Name="VCALinkTool"\r
- />\r
- <Tool\r
- Name="VCManifestTool"\r
- />\r
- <Tool\r
- Name="VCXDCMakeTool"\r
- />\r
- <Tool\r
- Name="VCBscMakeTool"\r
- />\r
- <Tool\r
- Name="VCFxCopTool"\r
- />\r
- <Tool\r
- Name="VCAppVerifierTool"\r
- />\r
- <Tool\r
- Name="VCWebDeploymentTool"\r
- />\r
- <Tool\r
- Name="VCPostBuildEventTool"\r
- />\r
- </Configuration>\r
- <Configuration\r
- Name="Release|Win32"\r
- OutputDirectory="Release"\r
- IntermediateDirectory="Release"\r
- ConfigurationType="2"\r
- InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
- CharacterSet="2"\r
- >\r
- <Tool\r
- Name="VCPreBuildEventTool"\r
- CommandLine="cscript /nologo $(InputDir)..\..\..\w32\vsnet\getlibs.vbs Mod_Exosip Release"\r
- />\r
- <Tool\r
- Name="VCCustomBuildTool"\r
- />\r
- <Tool\r
- Name="VCXMLDataGeneratorTool"\r
- />\r
- <Tool\r
- Name="VCWebServiceProxyGeneratorTool"\r
- />\r
- <Tool\r
- Name="VCMIDLTool"\r
- />\r
- <Tool\r
- Name="VCCLCompilerTool"\r
- AdditionalIncludeDirectories="..\..\include;..\..\..\libs\include;..\..\..\libs\libeXosip2\include;..\..\..\libs\osip\include;..\..\..\libs\jrtp4c\src;..\..\..\libs\osip\src\osipparser2;..\..\..\libs\jrtplib\src;"..\..\..\libs\jthread-1.1.2\src""\r
- PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS"\r
- RuntimeLibrary="0"\r
- UsePrecompiledHeader="0"\r
- WarningLevel="3"\r
- Detect64BitPortabilityProblems="true"\r
- DebugInformationFormat="3"\r
- />\r
- <Tool\r
- Name="VCManagedResourceCompilerTool"\r
- />\r
- <Tool\r
- Name="VCResourceCompilerTool"\r
- />\r
- <Tool\r
- Name="VCPreLinkEventTool"\r
- />\r
- <Tool\r
- Name="VCLinkerTool"\r
- AdditionalDependencies="Ws2_32.lib Iphlpapi.lib libcpmt.lib eXosip.lib jrtplib.lib jthread.lib osipparser2.lib osip2.lib"\r
- OutputFile="..\..\..\w32\vsnet\$(OutDir)/mod/mod_exosip.dll"\r
- LinkIncremental="1"\r
- AdditionalLibraryDirectories=""$(InputDir)..\..\..\libs\apr\Release";"$(InputDir)..\..\..\libs\jrtp4c\w32\Release";"$(InputDir)..\..\..\libs\jrtplib\Release";"$(InputDir)..\..\..\libs\jthread-1.1.2\Release";"$(InputDir)..\..\..\libs\libeXosip2\platform\vsnet\Release";"$(InputDir)..\..\..\libs\osip\platform\vsnet\Release""\r
- GenerateDebugInformation="true"\r
- SubSystem="2"\r
- OptimizeReferences="2"\r
- EnableCOMDATFolding="2"\r
- ImportLibrary="$(OutDir)/mod_exosip.lib"\r
- TargetMachine="1"\r
- />\r
- <Tool\r
- Name="VCALinkTool"\r
- />\r
- <Tool\r
- Name="VCManifestTool"\r
- />\r
- <Tool\r
- Name="VCXDCMakeTool"\r
- />\r
- <Tool\r
- Name="VCBscMakeTool"\r
- />\r
- <Tool\r
- Name="VCFxCopTool"\r
- />\r
- <Tool\r
- Name="VCAppVerifierTool"\r
- />\r
- <Tool\r
- Name="VCWebDeploymentTool"\r
- />\r
- <Tool\r
- Name="VCPostBuildEventTool"\r
- />\r
- </Configuration>\r
- </Configurations>\r
- <References>\r
- </References>\r
- <Files>\r
- <Filter\r
- Name="Source Files"\r
- Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"\r
- UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"\r
- >\r
- <File\r
- RelativePath="..\..\..\libs\jrtp4c\src\jrtp4c.cpp"\r
- >\r
- </File>\r
- <File\r
- RelativePath=".\mod_exosip.c"\r
- >\r
- </File>\r
- <File\r
- RelativePath="..\..\..\libs\osip\src\osipparser2\osip_rfc3264.c"\r
- >\r
- </File>\r
- </Filter>\r
- <Filter\r
- Name="Header Files"\r
- Filter="h;hpp;hxx;hm;inl;inc;xsd"\r
- UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"\r
- >\r
- <File\r
- RelativePath="..\..\..\libs\osip\src\osipparser2\osip_rfc3264i.h"\r
- >\r
- </File>\r
- </Filter>\r
- <Filter\r
- Name="Resource Files"\r
- Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"\r
- UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"\r
- >\r
- </Filter>\r
- </Files>\r
- <Globals>\r
- </Globals>\r
-</VisualStudioProject>\r
+++ /dev/null
-/*
- * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
- * Copyright (C) 2005/2006, Anthony Minessale II <anthmct@yahoo.com>
- *
- * Version: MPL 1.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
- *
- * The Initial Developer of the Original Code is
- * Anthony Minessale II <anthmct@yahoo.com>
- * Portions created by the Initial Developer are Copyright (C)
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Anthony Minessale II <anthmct@yahoo.com>
- *
- *
- * mod_exosip.c -- eXoSIP SIP Endpoint
- *
- */
-
-
-#define HAVE_APR
-#include <switch.h>
-#include <ccrtp4c.h>
-#include <eXosip2/eXosip.h>
-#include <osip2/osip_mt.h>
-#include <osipparser2/osip_rfc3264.h>
-#include <osipparser2/osip_port.h>
-
-
-static const char modname[] = "mod_exosip";
-#define STRLEN 15
-
-static switch_memory_pool *module_pool;
-
-typedef enum {
- PFLAG_ANSWER = (1 << 0),
- PFLAG_HANGUP = (1 << 1),
-} PFLAGS;
-
-
-typedef enum {
- PPFLAG_RING = (1 << 0),
-} PPFLAGS;
-
-typedef enum {
- TFLAG_IO = (1 << 0),
- TFLAG_INBOUND = (1 << 1),
- TFLAG_OUTBOUND = (1 << 2),
- TFLAG_DTMF = (1 << 3),
- TFLAG_READING = (1 << 4),
- TFLAG_WRITING = (1 << 5),
- TFLAG_USING_CODEC = (1 << 6),
- TFLAG_RTP = (1 << 7),
- TFLAG_BYE = (1 << 8)
-} TFLAGS;
-
-
-#define PACKET_LEN 160
-#define DEFAULT_BYTES_PER_FRAME 160
-
-
-static const switch_endpoint_interface exosip_endpoint_interface;
-
-static struct {
- int debug;
- int bytes_per_frame;
- char *dialplan;
- int port;
- int rtp_start;
- int rtp_end;
- switch_hash *call_hash;
- switch_mutex_t *port_lock;
- int running;
- int codec_ms;
-} globals;
-
-struct private_object {
- unsigned int flags;
- switch_core_session *session;
- switch_frame read_frame;
- switch_codec read_codec;
- switch_codec write_codec;
- unsigned char read_buf[1024];
- switch_caller_profile *caller_profile;
- int cid;
- int did;
- int tid;
- int32_t timestamp_send;
- int32_t timestamp_recv;
- int payload_num;
- struct ccrtp4c *rtp_session;
- struct osip_rfc3264 *sdp_config;
- sdp_message_t *remote_sdp;
- sdp_message_t *local_sdp;
- char remote_sdp_audio_ip[50];
- int remote_sdp_audio_port;
- char local_sdp_audio_ip[50];
- int local_sdp_audio_port;
- char call_id[50];
- int ssrc;
- //switch_mutex_t *rtp_lock;
-};
-
-
-static int next_rtp_port(void)
-{
- int port;
-
- switch_mutex_lock(globals.port_lock);
- port = globals.rtp_start;
- globals.rtp_start += 2;
- if (port >= globals.rtp_end) {
- port = globals.rtp_start;
- }
- switch_mutex_unlock(globals.port_lock);
- return port;
-}
-
-
-static void set_global_dialplan(char *dialplan)
-{
- if (globals.dialplan) {
- free(globals.dialplan);
- globals.dialplan = NULL;
- }
-
- globals.dialplan = strdup(dialplan);
-}
-
-static void set_global_dialplan(char *dialplan);
-static switch_status exosip_on_init(switch_core_session *session);
-static switch_status exosip_on_hangup(switch_core_session *session);
-static switch_status exosip_on_loopback(switch_core_session *session);
-static switch_status exosip_on_transmit(switch_core_session *session);
-static switch_status exosip_outgoing_channel(switch_core_session *session, switch_caller_profile *outbound_profile, switch_core_session **new_session);
-static switch_status exosip_read_frame(switch_core_session *session, switch_frame **frame, int timeout, switch_io_flag flags);
-static switch_status exosip_write_frame(switch_core_session *session, switch_frame *frame, int timeout, switch_io_flag flags);
-static int config_exosip(int reload);
-static switch_status parse_sdp_media(sdp_media_t *media, char **dname, char **drate, char **dpayload);
-static switch_status exosip_kill_channel(switch_core_session *session, int sig);
-static void activate_rtp(struct private_object *tech_pvt);
-static void deactivate_rtp(struct private_object *tech_pvt);
-
-static struct private_object *get_pvt_by_call_id(int id)
-{
- char name[50];
- snprintf(name, sizeof(name), "%d", id);
- return (struct private_object *) switch_core_hash_find(globals.call_hash, name);
-}
-
-static switch_status exosip_on_execute(switch_core_session *session)
-{
- return SWITCH_STATUS_SUCCESS;
-}
-
-
-static int sdp_add_codec(struct osip_rfc3264 *cnf, int codec_type, int payload, char *attribute, int rate, int index)
-{
- char tmp[4] = "", string[32] = "";
- sdp_media_t *med = NULL;
- sdp_attribute_t *attr = NULL;
-
- sdp_media_init(&med);
- if (med == NULL)
- return -1;
-
- if (!index) {
- snprintf(tmp, sizeof(tmp), "%i", payload);
- med->m_proto = osip_strdup("RTP/AVP");
- osip_list_add(med->m_payloads, osip_strdup(tmp), -1);
- }
- if (attribute) {
- sdp_attribute_init(&attr);
- attr->a_att_field = osip_strdup("rtpmap");
- snprintf(string, sizeof(string), "%i %s/%i", payload, attribute, rate);
- attr->a_att_value = osip_strdup(string);
- osip_list_add(med->a_attributes, attr, -1);
- }
-
- switch (codec_type) {
- case SWITCH_CODEC_TYPE_AUDIO:
- med->m_media = osip_strdup("audio");
- osip_rfc3264_add_audio_media(cnf, med, -1);
- break;
- case SWITCH_CODEC_TYPE_VIDEO:
- med->m_media = osip_strdup("video");
- osip_rfc3264_add_video_media(cnf, med, -1);
- break;
- default:
- break;
- }
- return 0;
-}
-
-
-/*
- State methods they get called when the state changes to the specific state
- returning SWITCH_STATUS_SUCCESS tells the core to execute the standard state method next
- so if you fully implement the state you can return SWITCH_STATUS_FALSE to skip it.
-*/
-static switch_status exosip_on_init(switch_core_session *session)
-{
- struct private_object *tech_pvt;
- switch_channel *channel = NULL;
- char from_uri[512] = "", localip[128] = "", port[7] = "", *buf = NULL, tmp[512] = "";
- osip_message_t *invite = NULL;
-
- channel = switch_core_session_get_channel(session);
- assert(channel != NULL);
-
- tech_pvt = switch_core_session_get_private(session);
- assert(tech_pvt != NULL);
-
- tech_pvt->read_frame.data = tech_pvt->read_buf;
-
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "EXOSIP INIT\n");
-
- if (switch_test_flag(tech_pvt, TFLAG_OUTBOUND)) {
- char *dest_uri;
- switch_codec_interface *codecs[512];
- int num_codecs = 0;
- /* do SIP Goodies...*/
-
- /* Generate callerid URI */
- eXosip_guess_localip(AF_INET, localip, 128);
- snprintf(from_uri, sizeof(from_uri), "<sip:%s@%s>", tech_pvt->caller_profile->caller_id_number, localip);
- /* Setup codec negotiation stuffs */
- osip_rfc3264_init(&tech_pvt->sdp_config);
- /* Decide on local IP and rtp port */
- strncpy(tech_pvt->local_sdp_audio_ip, localip, sizeof(tech_pvt->local_sdp_audio_ip));
- tech_pvt->local_sdp_audio_port = next_rtp_port();
- /* Initialize SDP */
- sdp_message_init(&tech_pvt->local_sdp);
- sdp_message_v_version_set(tech_pvt->local_sdp, "0");
- sdp_message_o_origin_set(tech_pvt->local_sdp, "OpenSWITCH2", "0", "0", "IN", "IP4", tech_pvt->local_sdp_audio_ip);
- sdp_message_s_name_set(tech_pvt->local_sdp, "SIP Call");
- sdp_message_c_connection_add(tech_pvt->local_sdp, -1, "IN", "IP4", tech_pvt->local_sdp_audio_ip, NULL, NULL);
- sdp_message_t_time_descr_add(tech_pvt->local_sdp, "0", "0");
- snprintf(port, sizeof(port), "%i", tech_pvt->local_sdp_audio_port);
- sdp_message_m_media_add(tech_pvt->local_sdp, "audio", port, NULL, "RTP/AVP");
- /* Add in every codec we support on this outbound call */
- if ((num_codecs = loadable_module_get_codecs(switch_core_session_get_pool(session), codecs, sizeof(codecs)/sizeof(codecs[0]))) > 0) {
- int i;
- static const switch_codec_implementation *imp;
- for (i = 0; i < num_codecs; i++) {
- int x = 0;
-
- snprintf(tmp, sizeof(tmp), "%i", codecs[i]->ianacode);
- sdp_message_m_payload_add(tech_pvt->local_sdp, 0, osip_strdup(tmp));
- for (imp = codecs[i]->implementations ; imp ; imp = imp->next) {
- /* Add to SDP config */
- sdp_add_codec(tech_pvt->sdp_config, codecs[i]->codec_type, codecs[i]->ianacode, codecs[i]->iananame, imp->samples_per_second, x++);
- /* Add to SDP message */
-
- snprintf(tmp, sizeof(tmp), "%i %s/%i", codecs[i]->ianacode, codecs[i]->iananame, imp->samples_per_second);
- sdp_message_a_attribute_add(tech_pvt->local_sdp, 0, "rtpmap", osip_strdup(tmp));
- memset(tmp, 0, sizeof(tmp));
- }
- }
- }
- /* Setup our INVITE */
- eXosip_lock();
- if (!(dest_uri = (char *) switch_core_session_alloc(session, strlen(tech_pvt->caller_profile->destination_number) + 10))) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "AIEEEE!\n");
- assert(dest_uri != NULL);
- }
- sprintf(dest_uri, "sip:%s", tech_pvt->caller_profile->destination_number);
- eXosip_call_build_initial_invite(&invite, dest_uri, from_uri, NULL, NULL);
- osip_message_set_supported(invite, "100rel, replaces");
- /* Add SDP to the INVITE */
- sdp_message_to_str(tech_pvt->local_sdp, &buf);
- osip_message_set_body(invite, buf, strlen(buf));
- osip_message_set_content_type(invite, "application/sdp");
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "OUTBOUND SDP:\n%s\n", buf);
- free(buf);
- /* Send the INVITE */
- tech_pvt->cid = eXosip_call_send_initial_invite(invite);
- snprintf(tech_pvt->call_id, sizeof(tech_pvt->call_id), "%d", tech_pvt->cid);
- switch_core_hash_insert(globals.call_hash, tech_pvt->call_id, tech_pvt);
- tech_pvt->did = -1;
- eXosip_unlock();
- }
-
- /* Let Media Work */
- switch_set_flag(tech_pvt, TFLAG_IO);
-
- /* Move Channel's State Machine to RING */
- switch_channel_set_state(channel, CS_RING);
- return SWITCH_STATUS_SUCCESS;
-}
-
-static switch_status exosip_on_ring(switch_core_session *session)
-{
- switch_channel *channel = NULL;
- struct private_object *tech_pvt = NULL;
-
- channel = switch_core_session_get_channel(session);
- assert(channel != NULL);
-
- tech_pvt = switch_core_session_get_private(session);
- assert(tech_pvt != NULL);
-
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "EXOSIP RING\n");
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-static switch_status exosip_on_hangup(switch_core_session *session)
-{
- struct private_object *tech_pvt;
- switch_channel *channel = NULL;
- int i;
-
- channel = switch_core_session_get_channel(session);
- assert(channel != NULL);
-
- tech_pvt = switch_core_session_get_private(session);
- assert(tech_pvt != NULL);
-
-
- switch_core_hash_delete(globals.call_hash, tech_pvt->call_id);
-
-
- switch_set_flag(tech_pvt, TFLAG_BYE);
- switch_clear_flag(tech_pvt, TFLAG_IO);
-
- deactivate_rtp(tech_pvt);
-
- i = eXosip_call_terminate(tech_pvt->cid, tech_pvt->did);
-
- if (switch_test_flag(tech_pvt, TFLAG_USING_CODEC)) {
- switch_core_codec_destroy(&tech_pvt->read_codec);
- switch_core_codec_destroy(&tech_pvt->write_codec);
- }
-
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "EXOSIP HANGUP %s %d/%d=%d\n", switch_channel_get_name(channel), tech_pvt->cid, tech_pvt->did, i);
- return SWITCH_STATUS_SUCCESS;
-}
-
-static switch_status exosip_on_loopback(switch_core_session *session)
-{
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "EXOSIP LOOPBACK\n");
- return SWITCH_STATUS_SUCCESS;
-}
-
-static switch_status exosip_on_transmit(switch_core_session *session)
-{
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "EXOSIP TRANSMIT\n");
- return SWITCH_STATUS_SUCCESS;
-}
-
-static switch_status exosip_outgoing_channel(switch_core_session *session, switch_caller_profile *outbound_profile, switch_core_session **new_session)
-{
- if ((*new_session = switch_core_session_request(&exosip_endpoint_interface, NULL))) {
- struct private_object *tech_pvt;
- switch_channel *channel, *orig_channel;
- switch_caller_profile *caller_profile, *originator_caller_profile = NULL;
-
- if ((tech_pvt = (struct private_object *) switch_core_session_alloc(*new_session, sizeof(struct private_object)))) {
- memset(tech_pvt, 0, sizeof(*tech_pvt));
- channel = switch_core_session_get_channel(*new_session);
- switch_core_session_set_private(*new_session, tech_pvt);
- //switch_mutex_init(&tech_pvt->rtp_lock, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(*new_session));
- tech_pvt->session = *new_session;
- } else {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Hey where is my memory pool?\n");
- switch_core_session_destroy(new_session);
- return SWITCH_STATUS_GENERR;
- }
-
- if (outbound_profile) {
- char name[128];
- caller_profile = switch_caller_profile_clone(*new_session, outbound_profile);
- switch_channel_set_caller_profile(channel, caller_profile);
- tech_pvt->caller_profile = caller_profile;
- snprintf(name, sizeof(name), "Exosip/%s-%04x", caller_profile->destination_number, rand() & 0xffff);
- switch_channel_set_name(channel, name);
- } else {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Doh! no caller profile\n");
- switch_core_session_destroy(new_session);
- return SWITCH_STATUS_GENERR;
- }
-
- /* (session == NULL) means it was originated from the core not from another channel */
- if (session && (orig_channel = switch_core_session_get_channel(session))) {
- switch_caller_profile *cloned_profile;
-
- if ((originator_caller_profile = switch_channel_get_caller_profile(orig_channel))) {
- cloned_profile = switch_caller_profile_clone(*new_session, originator_caller_profile);
- switch_channel_set_originator_caller_profile(channel, cloned_profile);
- }
- }
-
- switch_channel_set_flag(channel, CF_OUTBOUND);
- switch_set_flag(tech_pvt, TFLAG_OUTBOUND);
- switch_channel_set_state(channel, CS_INIT);
- return SWITCH_STATUS_SUCCESS;
- }
-
- return SWITCH_STATUS_GENERR;
-}
-
-
-static void deactivate_rtp(struct private_object *tech_pvt)
-{
- int loops = 0;
- if (tech_pvt->rtp_session) {
- //switch_mutex_lock(tech_pvt->rtp_lock);
-
- while(loops < 10 && (switch_test_flag(tech_pvt, TFLAG_READING) || switch_test_flag(tech_pvt, TFLAG_WRITING))) {
- switch_yield(10000);
- loops++;
- }
-
- ccrtp4c_destroy(&tech_pvt->rtp_session);
- tech_pvt->rtp_session = NULL;
- //switch_mutex_unlock(tech_pvt->rtp_lock);
- }
-}
-
-static void activate_rtp(struct private_object *tech_pvt)
-{
- int bw, ms;
- switch_channel *channel;
-
- assert(tech_pvt != NULL);
-
- channel = switch_core_session_get_channel(tech_pvt->session);
- assert(channel != NULL);
-
-
-
- //switch_mutex_lock(tech_pvt->rtp_lock);
- if (switch_test_flag(tech_pvt, TFLAG_USING_CODEC)) {
- bw = tech_pvt->read_codec.implementation->bits_per_second;
- ms = tech_pvt->read_codec.implementation->nanoseconds_per_frame;
- } else {
- switch_channel_get_raw_mode(channel, NULL, NULL, NULL, &ms, &bw);
- bw *= 8;
- }
-
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Activating RTP %s:%d->%s:%d codec: %d ms: %d\n",
- tech_pvt->local_sdp_audio_ip,
- tech_pvt->local_sdp_audio_port,
- tech_pvt->remote_sdp_audio_ip,
- tech_pvt->remote_sdp_audio_port,
- tech_pvt->read_codec.codec_interface->ianacode,
- ms
- );
-
-
-
-
- tech_pvt->rtp_session = ccrtp4c_new(
- tech_pvt->local_sdp_audio_ip,
- tech_pvt->local_sdp_audio_port,
- tech_pvt->remote_sdp_audio_ip,
- tech_pvt->remote_sdp_audio_port,
- tech_pvt->read_codec.codec_interface->ianacode,
- ms,
- ms * 15);
-
- if (tech_pvt->rtp_session) {
- tech_pvt->ssrc = ccrtp4c_get_ssrc(tech_pvt->rtp_session);
- ccrtp4c_start(tech_pvt->rtp_session);
- switch_set_flag(tech_pvt, TFLAG_RTP);
- } else {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Oh oh?\n");
- }
-
- //switch_mutex_unlock(tech_pvt->rtp_lock);
-}
-
-static switch_status exosip_answer_channel(switch_core_session *session)
-{
- struct private_object *tech_pvt;
- switch_channel *channel = NULL;
-
- channel = switch_core_session_get_channel(session);
- assert(channel != NULL);
-
- tech_pvt = switch_core_session_get_private(session);
- assert(tech_pvt != NULL);
-
- if (!switch_channel_test_flag(channel, CF_OUTBOUND)) {
- char *buf = NULL;
- osip_message_t *answer = NULL;
-
-
- /* Transmit 200 OK with SDP */
- eXosip_lock();
- eXosip_call_build_answer(tech_pvt->tid, 200, &answer);
- sdp_message_to_str(tech_pvt->local_sdp, &buf);
- osip_message_set_body(answer, buf, strlen(buf));
- osip_message_set_content_type(answer, "application/sdp");
- free(buf);
- eXosip_call_send_answer(tech_pvt->tid, 200, answer);
- eXosip_unlock();
- }
-
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-
-static switch_status exosip_read_frame(switch_core_session *session, switch_frame **frame, int timeout, switch_io_flag flags)
-{
- struct private_object *tech_pvt = NULL;
- size_t bytes = 0, samples = 0, frames=0, ms=0;
- switch_channel *channel = NULL;
-
- channel = switch_core_session_get_channel(session);
- assert(channel != NULL);
-
- tech_pvt = switch_core_session_get_private(session);
- assert(tech_pvt != NULL);
-
- tech_pvt->read_frame.datalen = 0;
- switch_set_flag(tech_pvt, TFLAG_READING);
-
- if (switch_test_flag(tech_pvt, TFLAG_USING_CODEC)) {
- bytes = tech_pvt->read_codec.implementation->encoded_bytes_per_frame;
- samples = tech_pvt->read_codec.implementation->samples_per_frame;
- } else {
- assert(0);
- }
-
- if (switch_test_flag(tech_pvt, TFLAG_IO)) {
- if (!switch_test_flag(tech_pvt, TFLAG_RTP)) {
- activate_rtp(tech_pvt);
- }
-
- assert(tech_pvt->rtp_session != NULL);
- tech_pvt->read_frame.datalen = 0;
-
- while(!switch_test_flag(tech_pvt, TFLAG_BYE) && switch_test_flag(tech_pvt, TFLAG_IO) && tech_pvt->read_frame.datalen == 0) {
- if ((tech_pvt->read_frame.datalen =
- ccrtp4c_read(tech_pvt->rtp_session,
- tech_pvt->read_frame.data,
- sizeof(tech_pvt->read_buf),
- &tech_pvt->timestamp_recv))) {
- bytes = tech_pvt->read_codec.implementation->encoded_bytes_per_frame;
- frames = (tech_pvt->read_frame.datalen / bytes);
- samples = frames * tech_pvt->read_codec.implementation->samples_per_frame;
- ms = frames * tech_pvt->read_codec.implementation->nanoseconds_per_frame / 1000;
- tech_pvt->timestamp_recv += samples;
- break;
- }
- switch_yield(100);
- }
-
- //printf("%s %s->%s recv %d bytes %d samples in %d frames taking up %d ms ts=%d\n", switch_channel_get_name(channel), tech_pvt->local_sdp_audio_ip, tech_pvt->local_sdp_audio_ip, tech_pvt->read_frame.datalen, samples, frames, ms, tech_pvt->timestamp_recv);
-
-
- //switch_mutex_unlock(tech_pvt->rtp_lock);
-
- } else {
- memset(tech_pvt->read_buf, 0, 160);
- tech_pvt->read_frame.datalen = 160;
- }
-
- switch_clear_flag(tech_pvt, TFLAG_READING);
-
- if (switch_test_flag(tech_pvt, TFLAG_BYE)) {
- switch_channel_hangup(channel);
- return SWITCH_STATUS_FALSE;
- }
-
- *frame = &tech_pvt->read_frame;
-
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-
-static switch_status exosip_write_frame(switch_core_session *session, switch_frame *frame, int timeout, switch_io_flag flags)
-{
- struct private_object *tech_pvt;
- switch_channel *channel = NULL;
- switch_status status = SWITCH_STATUS_SUCCESS;
- int bytes=0, samples=0, ms=0, frames=0;
-
- channel = switch_core_session_get_channel(session);
- assert(channel != NULL);
-
- tech_pvt = switch_core_session_get_private(session);
- assert(tech_pvt != NULL);
-
- if (!switch_test_flag(tech_pvt, TFLAG_RTP)) {
- activate_rtp(tech_pvt);
- }
-
- if (!switch_test_flag(tech_pvt, TFLAG_IO)) {
- return SWITCH_STATUS_SUCCESS;
- }
-
- if (switch_test_flag(tech_pvt, TFLAG_BYE)) {
- switch_channel_hangup(channel);
- return SWITCH_STATUS_FALSE;
- }
-
- switch_set_flag(tech_pvt, TFLAG_WRITING);
- //switch_mutex_lock(tech_pvt->rtp_lock);
-
- if (switch_test_flag(tech_pvt, TFLAG_USING_CODEC)) {
- bytes = tech_pvt->read_codec.implementation->encoded_bytes_per_frame;
- frames = (frame->datalen / bytes);
- samples = frames * tech_pvt->read_codec.implementation->samples_per_frame;
- ms = frames * tech_pvt->read_codec.implementation->nanoseconds_per_frame / 1000;
- } else {
- assert(0);
- }
-
-
- //printf("%s %s->%s send %d bytes %d samples in %d frames taking up %d ms ts=%d\n", switch_channel_get_name(channel), tech_pvt->local_sdp_audio_ip, tech_pvt->remote_sdp_audio_ip, frame->datalen, samples, frames, ms, tech_pvt->timestamp_send);
-
- tech_pvt->timestamp_send += (int)samples;
- ccrtp4c_write(tech_pvt->rtp_session, frame->data, frame->datalen, &tech_pvt->timestamp_send);
-
-
-
-
- switch_clear_flag(tech_pvt, TFLAG_WRITING);
- //switch_mutex_unlock(tech_pvt->rtp_lock);
- return status;
-}
-
-
-
-static switch_status exosip_kill_channel(switch_core_session *session, int sig)
-{
- struct private_object *tech_pvt;
- switch_channel *channel = NULL;
-
- channel = switch_core_session_get_channel(session);
- assert(channel != NULL);
-
- tech_pvt = switch_core_session_get_private(session);
- assert(tech_pvt != NULL);
-
-
- switch_clear_flag(tech_pvt, TFLAG_IO);
- switch_set_flag(tech_pvt, TFLAG_BYE);
-
- return SWITCH_STATUS_SUCCESS;
-
-}
-
-static switch_status exosip_waitfor_read(switch_core_session *session, int ms)
-{
- struct private_object *tech_pvt;
- switch_channel *channel = NULL;
-
- channel = switch_core_session_get_channel(session);
- assert(channel != NULL);
-
- tech_pvt = switch_core_session_get_private(session);
- assert(tech_pvt != NULL);
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-
-static switch_status exosip_waitfor_write(switch_core_session *session, int ms)
-{
- struct private_object *tech_pvt;
- switch_channel *channel = NULL;
-
- channel = switch_core_session_get_channel(session);
- assert(channel != NULL);
-
- tech_pvt = switch_core_session_get_private(session);
- assert(tech_pvt != NULL);
-
- return SWITCH_STATUS_SUCCESS;
-
-}
-
-static const switch_io_routines exosip_io_routines = {
- /*.outgoing_channel*/ exosip_outgoing_channel,
- /*.answer_channel*/ exosip_answer_channel,
- /*.read_frame*/ exosip_read_frame,
- /*.write_frame*/ exosip_write_frame,
- /*.kill_channel*/ exosip_kill_channel,
- /*.waitfor_read*/ exosip_waitfor_read,
- /*.waitfor_read*/ exosip_waitfor_write
-};
-
-static const switch_event_handler_table exosip_event_handlers = {
- /*.on_init*/ exosip_on_init,
- /*.on_ring*/ exosip_on_ring,
- /*.on_execute*/ exosip_on_execute,
- /*.on_hangup*/ exosip_on_hangup,
- /*.on_loopback*/ exosip_on_loopback,
- /*.on_transmit*/ exosip_on_transmit
-};
-
-static const switch_endpoint_interface exosip_endpoint_interface = {
- /*.interface_name*/ "exosip",
- /*.io_routines*/ &exosip_io_routines,
- /*.event_handlers*/ &exosip_event_handlers,
- /*.private*/ NULL,
- /*.next*/ NULL
-};
-
-static const switch_loadable_module_interface exosip_module_interface = {
- /*.module_name*/ modname,
- /*.endpoint_interface*/ &exosip_endpoint_interface,
- /*.timer_interface*/ NULL,
- /*.dialplan_interface*/ NULL,
- /*.codec_interface*/ NULL,
- /*.application_interface*/ NULL
-};
-
-
-SWITCH_MOD_DECLARE(switch_status) switch_module_shutdown(void)
-{
- if (globals.running) {
- globals.running = -1;
- while(globals.running) {
- switch_yield(1000);
- }
- }
- eXosip_quit();
- return SWITCH_STATUS_SUCCESS;
-}
-
-SWITCH_MOD_DECLARE(switch_status) switch_module_load(const switch_loadable_module_interface **interface, char *filename) {
- /* NOTE: **interface is **_interface because the common lib redefines interface to struct in some situations */
-
- if (switch_core_new_memory_pool(&module_pool) != SWITCH_STATUS_SUCCESS) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "OH OH no pool\n");
- return SWITCH_STATUS_TERM;
- }
-
- /* connect my internal structure to the blank pointer passed to me */
- *interface = &exosip_module_interface;
-
- /* indicate that the module should continue to be loaded */
- return SWITCH_STATUS_SUCCESS;
-}
-
-static switch_status exosip_create_call(eXosip_event_t *event)
-{
- switch_core_session *session;
- sdp_message_t *remote_sdp = NULL;
- sdp_connection_t *conn = NULL;
- sdp_media_t *remote_med = NULL, *audio_tab[10], *video_tab[10], *t38_tab[10], *app_tab[10];
- char local_sdp_str[8192] = "", port[8] = "";
- int mline = 0, pos = 0;
- switch_channel *channel = NULL;
- char name[128];
- char *dpayload, *dname, *drate;
- char *remote_sdp_str = NULL;
-
- if ((session = switch_core_session_request(&exosip_endpoint_interface, NULL))) {
- struct private_object *tech_pvt;
- switch_codec_interface *codecs[512];
- int num_codecs = 0;
-
-
- if ((tech_pvt = (struct private_object *) switch_core_session_alloc(session, sizeof(struct private_object)))) {
- memset(tech_pvt, 0, sizeof(*tech_pvt));
- channel = switch_core_session_get_channel(session);
- switch_core_session_set_private(session, tech_pvt);
- tech_pvt->session = session;
- //switch_mutex_init(&tech_pvt->rtp_lock, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session));
- } else {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Hey where is my memory pool?\n");
- switch_core_session_destroy(&session);
- return SWITCH_STATUS_MEMERR;
- }
-
- if ((tech_pvt->caller_profile = switch_caller_profile_new(session,
- globals.dialplan,
- event->request->from->displayname,
- event->request->from->url->username,
- event->request->from->url->username,
- NULL,
- event->request->req_uri->username))) {
- switch_channel_set_caller_profile(channel, tech_pvt->caller_profile);
- }
-
- switch_set_flag(tech_pvt, TFLAG_INBOUND);
- tech_pvt->did = event->did;
- tech_pvt->cid = event->cid;
- tech_pvt->tid = event->tid;
-
- snprintf(name, sizeof(name), "Exosip/%s-%04x", tech_pvt->caller_profile->destination_number, rand() & 0xffff);
- switch_channel_set_name(channel, name);
-
- if (!(remote_sdp = eXosip_get_sdp_info(event->request))) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Cannot Find Remote SDP!\n");
- exosip_on_hangup(session);
- switch_core_session_destroy(&session);
- return SWITCH_STATUS_GENERR;
- }
-
- eXosip_guess_localip(AF_INET, tech_pvt->local_sdp_audio_ip, 50);
- tech_pvt->local_sdp_audio_port = next_rtp_port();
- osip_rfc3264_init(&tech_pvt->sdp_config);
- /* Add in what codecs we support locally */
-
- if ((num_codecs = loadable_module_get_codecs(switch_core_session_get_pool(session), codecs, sizeof(codecs)/sizeof(codecs[0]))) > 0) {
- int i;
- static const switch_codec_implementation *imp;
-
- for (i = 0; i < num_codecs; i++) {
- int x = 0;
- for (imp = codecs[i]->implementations ; imp ; imp = imp->next) {
- sdp_add_codec(tech_pvt->sdp_config, codecs[i]->codec_type, codecs[i]->ianacode, codecs[i]->iananame, imp->samples_per_second, x++);
- }
- }
- }
- osip_rfc3264_prepare_answer(tech_pvt->sdp_config, remote_sdp, local_sdp_str, 8192);
- sdp_message_init(&tech_pvt->local_sdp);
- sdp_message_parse(tech_pvt->local_sdp, local_sdp_str);
-
- sdp_message_to_str(remote_sdp, &remote_sdp_str);
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "LOCAL SDP:\n%s\nREMOTE SDP:\n%s", local_sdp_str,remote_sdp_str);
-
- mline = 0;
- while (0==osip_rfc3264_match(tech_pvt->sdp_config, remote_sdp, audio_tab, video_tab, t38_tab, app_tab, mline)) {
- if (audio_tab[0] == NULL && video_tab[0] == NULL && t38_tab[0] == NULL && app_tab[0] == NULL) {
-
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Got no compatible codecs!\n");
- break;
- }
- for (pos=0; audio_tab[pos]!=NULL; pos++) {
- osip_rfc3264_complete_answer(tech_pvt->sdp_config, remote_sdp, tech_pvt->local_sdp, audio_tab[pos], mline);
- if (parse_sdp_media(audio_tab[pos], &dname, &drate, &dpayload) == SWITCH_STATUS_SUCCESS) {
- tech_pvt->payload_num = atoi(dpayload);
- break;
- }
- }
- mline++;
- }
- free(remote_sdp_str);
- sdp_message_o_origin_set(tech_pvt->local_sdp, "OpenSWITCH2", "0", "0", "IN", "IP4", tech_pvt->local_sdp_audio_ip);
- sdp_message_s_name_set(tech_pvt->local_sdp, "SIP Call");
- sdp_message_c_connection_add(tech_pvt->local_sdp, -1, "IN", "IP4", tech_pvt->local_sdp_audio_ip, NULL, NULL);
- snprintf(port, sizeof(port), "%i", tech_pvt->local_sdp_audio_port);
- sdp_message_m_port_set(tech_pvt->local_sdp, 0, osip_strdup(port));
-
- conn = eXosip_get_audio_connection(remote_sdp);
- remote_med = eXosip_get_audio_media(remote_sdp);
- snprintf(tech_pvt->remote_sdp_audio_ip, 50, conn->c_addr);
-
- tech_pvt->remote_sdp_audio_port = atoi(remote_med->m_port);
-
- snprintf(tech_pvt->call_id, sizeof(tech_pvt->call_id), "%d", event->cid);
- switch_core_hash_insert(globals.call_hash, tech_pvt->call_id, tech_pvt);
-
- if (!dname) {
- exosip_on_hangup(session);
- switch_core_session_destroy(&session);
- return SWITCH_STATUS_GENERR;
- }
-
- switch_channel_set_state(channel, CS_INIT);
-
-
- if (1) {
- int rate = atoi(drate);
-
- if (switch_core_codec_init(&tech_pvt->read_codec,
- dname,
- rate,
- globals.codec_ms,
- SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
- NULL) != SWITCH_STATUS_SUCCESS) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Can't load codec?\n");
- switch_channel_hangup(channel);
- return SWITCH_STATUS_FALSE;
- } else {
- if (switch_core_codec_init(&tech_pvt->write_codec,
- dname,
- rate,
- globals.codec_ms,
- SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
- NULL) != SWITCH_STATUS_SUCCESS) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Can't load codec?\n");
- switch_channel_hangup(channel);
- return SWITCH_STATUS_FALSE;
- } else {
- int ms;
- switch_set_flag(tech_pvt, TFLAG_USING_CODEC);
- ms = tech_pvt->write_codec.implementation->nanoseconds_per_frame / 1000;
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Activate Inbound Codec %s/%d %d ms\n", dname, rate, ms);
- tech_pvt->read_frame.codec = &tech_pvt->read_codec;
- switch_core_session_set_read_codec(session, &tech_pvt->read_codec);
- switch_core_session_set_write_codec(session, &tech_pvt->write_codec);
- }
- }
- }
-
- switch_core_session_thread_launch(session);
- } else {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Cannot Create new Inbound Channel!\n");
- }
-
-
- return 0;
-
-
-
-}
-
-static void destroy_call_by_event(eXosip_event_t *event)
-{
- struct private_object *tech_pvt;
- switch_channel *channel = NULL;
-
- if (!(tech_pvt = get_pvt_by_call_id(event->cid))) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Um in case you are interested, Can't find the pvt [%d]!\n", event->cid);
- return;
- }
-
- channel = switch_core_session_get_channel(tech_pvt->session);
- assert(channel != NULL);
-
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "destroy %s\n", switch_channel_get_name(channel));
- exosip_kill_channel(tech_pvt->session, SWITCH_SIG_KILL);
- switch_channel_hangup(channel);
-
-}
-
-static switch_status parse_sdp_media(sdp_media_t *media, char **dname, char **drate, char **dpayload)
-{
- int pos = 0;
- sdp_attribute_t *attr = NULL;
- char *name, *rate, *payload;
- switch_status status = SWITCH_STATUS_GENERR;
-
- while (osip_list_eol(media->a_attributes, pos) == 0) {
- attr = (sdp_attribute_t *)osip_list_get(media->a_attributes, pos);
- if (attr != NULL && strcasecmp(attr->a_att_field, "rtpmap") == 0) {
- payload = attr->a_att_value;
- if ((name = strchr(payload, ' '))) {
- *(name++) = '\0';
- /* Name and payload are required */
- *dpayload = strdup(payload);
- status = SWITCH_STATUS_SUCCESS;
- if ((rate = strchr(name, '/'))) {
- *(rate++) = '\0';
- *drate = strdup(rate);
- *dname = strdup(name);
- } else {
- *dname = strdup(name);
- *drate = strdup("8000");
- }
- } else {
- *dpayload = strdup("10");
- *dname = strdup("L16");
- *drate = strdup("8000");
- }
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Found negotiated codec Payload: %s Name: %s Rate: %s\n", *dpayload, *dname, *drate);
- break;
- }
- attr = NULL;
- pos++;
- }
-
- return status;
-}
-
-static void handle_answer(eXosip_event_t *event)
-{
- osip_message_t *ack = NULL;
- sdp_message_t *remote_sdp = NULL;
- sdp_connection_t *conn = NULL;
- sdp_media_t *remote_med = NULL;
- struct private_object *tech_pvt;
- char *dpayload = NULL, *dname = NULL, *drate = NULL;
- switch_channel *channel;
-
-
- if (!(tech_pvt = get_pvt_by_call_id(event->cid))) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Um in case you are interested, Can't find the pvt!\n");
- return;
- }
-
- channel = switch_core_session_get_channel(tech_pvt->session);
- assert(channel != NULL);
-
- if (!event->response) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Someone answered... with no SDP information - WTF?!?\n");
- switch_channel_hangup(channel);
- return;
- }
-
- /* Get all of the remote SDP elements... stuff */
- if (!(remote_sdp = eXosip_get_sdp_info(event->response))) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Cant Find SDP?\n");
- switch_channel_hangup(channel);
- return;
- }
-
-
- conn = eXosip_get_audio_connection(remote_sdp);
- remote_med = eXosip_get_audio_media(remote_sdp);
-
- /* Grab IP/port */
- tech_pvt->remote_sdp_audio_port = atoi(remote_med->m_port);
- snprintf(tech_pvt->remote_sdp_audio_ip, 50, conn->c_addr);
-
- /* Grab codec elements */
- if (parse_sdp_media(remote_med, &dname, &drate, &dpayload) == SWITCH_STATUS_SUCCESS) {
- tech_pvt->payload_num = atoi(dpayload);
- }
-
- /* Assign them thar IDs */
- tech_pvt->did = event->did;
- tech_pvt->tid = event->tid;
-
-
- if (1) {
- int rate = atoi(drate);
-
-
- if (switch_core_codec_init(&tech_pvt->read_codec, dname, rate, globals.codec_ms, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL) != SWITCH_STATUS_SUCCESS) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Can't load codec?\n");
- switch_channel_hangup(channel);
- return;
- } else {
- if (switch_core_codec_init(&tech_pvt->write_codec, dname, rate, globals.codec_ms, SWITCH_CODEC_FLAG_ENCODE |SWITCH_CODEC_FLAG_DECODE, NULL) != SWITCH_STATUS_SUCCESS) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Can't load codec?\n");
- switch_channel_hangup(channel);
- return;
- } else {
- int ms;
- switch_set_flag(tech_pvt, TFLAG_USING_CODEC);
- ms = tech_pvt->write_codec.implementation->nanoseconds_per_frame / 1000;
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Activate Outbound Codec %s/%d %d ms\n", dname, rate, ms);
- tech_pvt->read_frame.codec = &tech_pvt->read_codec;
- switch_core_session_set_read_codec(tech_pvt->session, &tech_pvt->read_codec);
- switch_core_session_set_write_codec(tech_pvt->session, &tech_pvt->write_codec);
- }
- }
- }
-
-
- eXosip_lock();
- eXosip_call_build_ack(event->did, &ack);
- eXosip_call_send_ack(event->did, ack);
- eXosip_unlock();
-
- free(dname);
- free(drate);
- free(dpayload);
-
-
-
- channel = switch_core_session_get_channel(tech_pvt->session);
- assert(channel != NULL);
-
- switch_channel_answer(channel);
-
-}
-
-static void log_event(eXosip_event_t *je)
-{
- char buf[100];
-
- buf[0] = '\0';
- if (je->type == EXOSIP_CALL_NOANSWER) {
- snprintf (buf, 99, "<- (%i %i) No answer", je->cid, je->did);
- } else if (je->type == EXOSIP_CALL_CLOSED) {
- snprintf (buf, 99, "<- (%i %i) Call Closed", je->cid, je->did);
- } else if (je->type == EXOSIP_CALL_RELEASED) {
- snprintf (buf, 99, "<- (%i %i) Call released", je->cid, je->did);
- } else if (je->type == EXOSIP_MESSAGE_NEW
- && je->request!=NULL && MSG_IS_MESSAGE(je->request)) {
- char *tmp = NULL;
-
- if (je->request != NULL) {
- osip_body_t *body;
- osip_from_to_str (je->request->from, &tmp);
-
- osip_message_get_body (je->request, 0, &body);
- if (body != NULL && body->body != NULL) {
- snprintf (buf, 99, "<- (%i) from: %s TEXT: %s",
- je->tid, tmp, body->body);
- }
- osip_free (tmp);
- } else {
- snprintf (buf, 99, "<- (%i) New event for unknown request?", je->tid);
- }
- } else if (je->type == EXOSIP_MESSAGE_NEW) {
- char *tmp = NULL;
-
- osip_from_to_str (je->request->from, &tmp);
- snprintf (buf, 99, "<- (%i) %s from: %s",
- je->tid, je->request->sip_method, tmp);
- osip_free (tmp);
- } else if (je->type == EXOSIP_MESSAGE_PROCEEDING
- || je->type == EXOSIP_MESSAGE_ANSWERED
- || je->type == EXOSIP_MESSAGE_REDIRECTED
- || je->type == EXOSIP_MESSAGE_REQUESTFAILURE
- || je->type == EXOSIP_MESSAGE_SERVERFAILURE
- || je->type == EXOSIP_MESSAGE_GLOBALFAILURE) {
- if (je->response != NULL && je->request != NULL) {
- char *tmp = NULL;
-
- osip_to_to_str (je->request->to, &tmp);
- snprintf (buf, 99, "<- (%i) [%i %s for %s] to: %s",
- je->tid, je->response->status_code,
- je->response->reason_phrase, je->request->sip_method, tmp);
- osip_free (tmp);
- } else if (je->request != NULL) {
- snprintf (buf, 99, "<- (%i) Error for %s request",
- je->tid, je->request->sip_method);
- } else {
- snprintf (buf, 99, "<- (%i) Error for unknown request", je->tid);
- }
- } else if (je->response == NULL && je->request != NULL && je->cid > 0) {
- char *tmp = NULL;
-
- osip_from_to_str (je->request->from, &tmp);
- snprintf (buf, 99, "<- (%i %i) %s from: %s",
- je->cid, je->did, je->request->cseq->method, tmp);
- osip_free (tmp);
- } else if (je->response != NULL && je->cid > 0) {
- char *tmp = NULL;
-
- osip_to_to_str (je->request->to, &tmp);
- snprintf (buf, 99, "<- (%i %i) [%i %s] for %s to: %s",
- je->cid, je->did, je->response->status_code,
- je->response->reason_phrase, je->request->sip_method, tmp);
- osip_free (tmp);
- } else if (je->response == NULL && je->request != NULL && je->rid > 0) {
- char *tmp = NULL;
-
- osip_from_to_str (je->request->from, &tmp);
- snprintf (buf, 99, "<- (%i) %s from: %s",
- je->rid, je->request->cseq->method, tmp);
- osip_free (tmp);
- } else if (je->response != NULL && je->rid > 0) {
- char *tmp = NULL;
-
- osip_from_to_str (je->request->from, &tmp);
- snprintf (buf, 99, "<- (%i) [%i %s] from: %s",
- je->rid, je->response->status_code,
- je->response->reason_phrase, tmp);
- osip_free (tmp);
- } else if (je->response == NULL && je->request != NULL && je->sid > 0) {
- char *tmp = NULL;
- char *stat = NULL;
- osip_header_t *sub_state;
-
- osip_message_header_get_byname (je->request, "subscription-state",
- 0, &sub_state);
- if (sub_state != NULL && sub_state->hvalue != NULL)
- stat = sub_state->hvalue;
-
- osip_uri_to_str (je->request->from->url, &tmp);
- snprintf (buf, 99, "<- (%i) [%s] %s from: %s",
- je->sid, stat, je->request->cseq->method, tmp);
- osip_free (tmp);
- } else if (je->response != NULL && je->sid > 0) {
- char *tmp = NULL;
-
- osip_uri_to_str (je->request->to->url, &tmp);
- snprintf (buf, 99, "<- (%i) [%i %s] from: %s",
- je->sid, je->response->status_code,
- je->response->reason_phrase, tmp);
- osip_free (tmp);
- } else if (je->response == NULL && je->request != NULL) {
- char *tmp = NULL;
-
- osip_from_to_str (je->request->from, &tmp);
- snprintf (buf, 99, "<- (c=%i|d=%i|s=%i|n=%i) %s from: %s",
- je->cid, je->did, je->sid, je->nid,
- je->request->sip_method, tmp);
- osip_free (tmp);
- } else if (je->response != NULL) {
- char *tmp = NULL;
-
- osip_from_to_str (je->request->from, &tmp);
- snprintf (buf, 99, "<- (c=%i|d=%i|s=%i|n=%i) [%i %s] for %s from: %s",
- je->cid, je->did, je->sid, je->nid,
- je->response->status_code, je->response->reason_phrase,
- je->request->sip_method, tmp);
- osip_free (tmp);
- } else {
- snprintf (buf, 99, "<- (c=%i|d=%i|s=%i|n=%i|t=%i) %s",
- je->cid, je->did, je->sid, je->nid, je->tid, je->textinfo);
- }
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "\n%s\n", buf);
- /* Print it out */
-}
-
-
-
-static void *monitor_thread_run(void)
-{
- eXosip_event_t *event = NULL;
-
- globals.running = 1;
- while (globals.running > 0) {
- if (!(event = eXosip_event_wait(0,100))) {
- switch_yield(100);
- continue;
- }
-
- eXosip_lock();
- eXosip_automatic_action ();
- eXosip_unlock();
-
- log_event(event);
-
- switch(event->type) {
- case EXOSIP_CALL_INVITE:
- exosip_create_call(event);
- break;
- case EXOSIP_CALL_REINVITE:
- /* See what the reinvite is about - on hold or whatever */
- //handle_reinvite(event);
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Got a reinvite.\n");
- break;
- case EXOSIP_CALL_MESSAGE_NEW:
- if (event->request != NULL && MSG_IS_REFER(event->request)) {
- //handle_call_transfer(event);
- }
- break;
- case EXOSIP_CALL_ACK:
- /* If audio is not flowing and this has SDP - fire it up! */
- break;
- case EXOSIP_CALL_ANSWERED:
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "The call was answered.\n");
- handle_answer(event);
- break;
- case EXOSIP_CALL_PROCEEDING:
- /* This is like a 100 Trying... yeah */
- break;
- case EXOSIP_CALL_RINGING:
- //handle_ringing(event);
- break;
- case EXOSIP_CALL_REDIRECTED:
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Call was redirect\n");
- break;
- case EXOSIP_CALL_CLOSED:
- destroy_call_by_event(event);
- break;
- case EXOSIP_CALL_RELEASED:
- destroy_call_by_event(event);
- break;
- case EXOSIP_CALL_NOANSWER:
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "The call was not answered.\n");
- destroy_call_by_event(event);
- break;
- case EXOSIP_CALL_REQUESTFAILURE:
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Request failure\n");
- destroy_call_by_event(event);
- break;
- case EXOSIP_CALL_SERVERFAILURE:
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Server failure\n");
- destroy_call_by_event(event);
- break;
- case EXOSIP_CALL_GLOBALFAILURE:
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Global failure\n");
- destroy_call_by_event(event);
- break;
- /* Registration related stuff */
- case EXOSIP_REGISTRATION_NEW:
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Received registration attempt\n");
- break;
- default:
- /* Unknown event... casually absorb it for now */
- break;
- }
-
- //switch_console_printf(SWITCH_CHANNEL_CONSOLE, "There was an event (%d) [%s]\n", event->type, event->textinfo);
- /* Free the event */
- eXosip_event_free(event);
- }
-
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Monitor Thread Exiting\n");
- globals.running = 0;
- return NULL;
-}
-
-
-static int config_exosip(int reload)
-{
- switch_config cfg;
- char *var, *val;
- char *cf = "exosip.conf";
-
- globals.bytes_per_frame = DEFAULT_BYTES_PER_FRAME;
- switch_core_hash_init(&globals.call_hash, module_pool);
-
- if (!switch_config_open_file(&cfg, cf)) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "open of %s failed\n", cf);
- return SWITCH_STATUS_TERM;
- }
-
- globals.rtp_start = 16384;
- globals.rtp_end = 32768;
-
- while (switch_config_next_pair(&cfg, &var, &val)) {
- if (!strcasecmp(cfg.category, "settings")) {
- if (!strcmp(var, "debug")) {
- globals.debug = atoi(val);
- } else if (!strcmp(var, "port")) {
- globals.port = atoi(val);
- } else if (!strcmp(var, "dialplan")) {
- set_global_dialplan(val);
- } else if (!strcmp(var, "rtp_min_port")) {
- globals.rtp_start = atoi(val);
- } else if (!strcmp(var, "rtp_max_port")) {
- globals.rtp_end = atoi(val);
- } else if (!strcmp(var, "codec_ms")) {
- globals.codec_ms = atoi(val);
- }
- }
- }
-
- if (!globals.codec_ms) {
- globals.codec_ms = 20;
- }
-
- if (!globals.port) {
- globals.port = 5060;
- }
-
- switch_config_close_file(&cfg);
-
- if (!globals.dialplan) {
- set_global_dialplan("default");
- }
-
- if (eXosip_init ()) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "eXosip_init initialization failed!\n");
- return SWITCH_STATUS_GENERR;
- }
- if (eXosip_listen_addr (IPPROTO_UDP, NULL, globals.port, AF_INET, 0)) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "eXosip_listen_addr failed!\n");
- return SWITCH_STATUS_GENERR;
- }
-
- switch_mutex_init(&globals.port_lock, SWITCH_MUTEX_NESTED, module_pool);
-
-
- /* Setup the user agent */
- eXosip_set_user_agent("OPENSWITCH 2.0");
-
-
- monitor_thread_run();
- return 0;
-
-}
-
-
-SWITCH_MOD_DECLARE(switch_status) switch_module_runtime(void)
-{
- config_exosip(0);
- return SWITCH_STATUS_TERM;
-}
-
+++ /dev/null
-/*
- * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
- * Copyright (C) 2005/2006, Anthony Minessale II <anthmct@yahoo.com>
- *
- * Version: MPL 1.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
- *
- * The Initial Developer of the Original Code is
- * Anthony Minessale II <anthmct@yahoo.com>
- * Portions created by the Initial Developer are Copyright (C)
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Anthony Minessale II <anthmct@yahoo.com>
- *
- *
- * mod_exosip.c -- eXoSIP SIP Endpoint
- *
- */
-
-
-#define HAVE_APR
-
-#include <config_unix.h>
-#include <config_win32.h>
-
-#include <switch.h>
-
-#include <debug.h>
-#include <memory.h>
-#include <rtp.h>
-
-#include <eXosip2/eXosip.h>
-#include <osip2/osip_mt.h>
-#include <osipparser2/osip_rfc3264.h>
-#include <osipparser2/osip_port.h>
-
-
-
-//#include <sys/queue.h>
-//#include <ctype.h>
-//#include <string.h>
-//#include <byteswap.h>
-//#include <uclconf.h>
-
-static const char modname[] = "mod_exosip";
-#define STRLEN 15
-
-static switch_memory_pool *module_pool;
-
-typedef enum {
- PFLAG_ANSWER = (1 << 0),
- PFLAG_HANGUP = (1 << 1),
-} PFLAGS;
-
-
-typedef enum {
- PPFLAG_RING = (1 << 0),
-} PPFLAGS;
-
-typedef enum {
- TFLAG_IO = (1 << 0),
- TFLAG_INBOUND = (1 << 1),
- TFLAG_OUTBOUND = (1 << 2),
- TFLAG_DTMF = (1 << 3),
- TFLAG_READING = (1 << 4),
- TFLAG_WRITING = (1 << 5),
- TFLAG_USING_CODEC = (1 << 6),
- TFLAG_RTP = (1 << 7),
- TFLAG_BYE = (1 << 8)
-} TFLAGS;
-
-
-#define PACKET_LEN 160
-#define DEFAULT_BYTES_PER_FRAME 160
-
-
-static const switch_endpoint_interface exosip_endpoint_interface;
-
-static struct {
- int debug;
- int bytes_per_frame;
- char *dialplan;
- int port;
- int rtp_start;
- int rtp_end;
- switch_hash *call_hash;
- switch_mutex_t *port_lock;
- int running;
- int codec_ms;
-} globals;
-
-struct private_object {
- unsigned int flags;
- switch_core_session *session;
- switch_frame read_frame;
- switch_codec read_codec;
- switch_codec write_codec;
- unsigned char read_buf[RTP_MAX_PACKET_LEN];
- switch_caller_profile *caller_profile;
- int cid;
- int did;
- int tid;
- int32_t timestamp_send;
- int32_t timestamp_recv;
- int payload_num;
- struct rtp *rtp_session;
- struct osip_rfc3264 *sdp_config;
- sdp_message_t *remote_sdp;
- sdp_message_t *local_sdp;
- char remote_sdp_audio_ip[50];
- int remote_sdp_audio_port;
- char local_sdp_audio_ip[50];
- int local_sdp_audio_port;
- char call_id[50];
- int ssrc;
- //switch_mutex_t *rtp_lock;
-};
-
-
-static int next_rtp_port(void)
-{
- int port;
-
- switch_mutex_lock(globals.port_lock);
- port = globals.rtp_start;
- globals.rtp_start += 2;
- if (port >= globals.rtp_end) {
- port = globals.rtp_start;
- }
- switch_mutex_unlock(globals.port_lock);
- return port;
-}
-
-
-static void set_global_dialplan(char *dialplan)
-{
- if (globals.dialplan) {
- free(globals.dialplan);
- globals.dialplan = NULL;
- }
-
- globals.dialplan = strdup(dialplan);
-}
-
-static void set_global_dialplan(char *dialplan);
-static switch_status exosip_on_init(switch_core_session *session);
-static switch_status exosip_on_hangup(switch_core_session *session);
-static switch_status exosip_on_loopback(switch_core_session *session);
-static switch_status exosip_on_transmit(switch_core_session *session);
-static switch_status exosip_outgoing_channel(switch_core_session *session, switch_caller_profile *outbound_profile, switch_core_session **new_session);
-static switch_status exosip_read_frame(switch_core_session *session, switch_frame **frame, int timeout, switch_io_flag flags);
-static switch_status exosip_write_frame(switch_core_session *session, switch_frame *frame, int timeout, switch_io_flag flags);
-static int config_exosip(int reload);
-static switch_status parse_sdp_media(sdp_media_t *media, char **dname, char **drate, char **dpayload);
-static switch_status exosip_kill_channel(switch_core_session *session, int sig);
-static void activate_rtp(struct private_object *tech_pvt);
-static void deactivate_rtp(struct private_object *tech_pvt);
-
-static struct private_object *get_pvt_by_call_id(int id)
-{
- char name[50];
- snprintf(name, sizeof(name), "%d", id);
- return (struct private_object *) switch_core_hash_find(globals.call_hash, name);
-}
-
-static switch_status exosip_on_execute(switch_core_session *session)
-{
- return SWITCH_STATUS_SUCCESS;
-}
-
-
-static int sdp_add_codec(struct osip_rfc3264 *cnf, int codec_type, int payload, char *attribute, int rate, int index)
-{
- char tmp[4] = "", string[32] = "";
- sdp_media_t *med = NULL;
- sdp_attribute_t *attr = NULL;
-
- sdp_media_init(&med);
- if (med == NULL)
- return -1;
-
- if (!index) {
- snprintf(tmp, sizeof(tmp), "%i", payload);
- med->m_proto = osip_strdup("RTP/AVP");
- osip_list_add(med->m_payloads, osip_strdup(tmp), -1);
- }
- if (attribute) {
- sdp_attribute_init(&attr);
- attr->a_att_field = osip_strdup("rtpmap");
- snprintf(string, sizeof(string), "%i %s/%i", payload, attribute, rate);
- attr->a_att_value = osip_strdup(string);
- osip_list_add(med->a_attributes, attr, -1);
- }
-
- switch (codec_type) {
- case SWITCH_CODEC_TYPE_AUDIO:
- med->m_media = osip_strdup("audio");
- osip_rfc3264_add_audio_media(cnf, med, -1);
- break;
- case SWITCH_CODEC_TYPE_VIDEO:
- med->m_media = osip_strdup("video");
- osip_rfc3264_add_video_media(cnf, med, -1);
- break;
- default:
- break;
- }
- return 0;
-}
-
-
-/*
- State methods they get called when the state changes to the specific state
- returning SWITCH_STATUS_SUCCESS tells the core to execute the standard state method next
- so if you fully implement the state you can return SWITCH_STATUS_FALSE to skip it.
-*/
-static switch_status exosip_on_init(switch_core_session *session)
-{
- struct private_object *tech_pvt;
- switch_channel *channel = NULL;
- char from_uri[512] = "", localip[128] = "", port[7] = "", *buf = NULL, tmp[512] = "";
- osip_message_t *invite = NULL;
-
- channel = switch_core_session_get_channel(session);
- assert(channel != NULL);
-
- tech_pvt = switch_core_session_get_private(session);
- assert(tech_pvt != NULL);
-
- tech_pvt->read_frame.data = tech_pvt->read_buf;
-
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "EXOSIP INIT\n");
-
- if (switch_test_flag(tech_pvt, TFLAG_OUTBOUND)) {
- char *dest_uri;
- switch_codec_interface *codecs[512];
- int num_codecs = 0;
- /* do SIP Goodies...*/
-
- /* Generate callerid URI */
- eXosip_guess_localip(AF_INET, localip, 128);
- snprintf(from_uri, sizeof(from_uri), "<sip:%s@%s>", tech_pvt->caller_profile->caller_id_number, localip);
- /* Setup codec negotiation stuffs */
- osip_rfc3264_init(&tech_pvt->sdp_config);
- /* Decide on local IP and rtp port */
- strncpy(tech_pvt->local_sdp_audio_ip, localip, sizeof(tech_pvt->local_sdp_audio_ip));
- tech_pvt->local_sdp_audio_port = next_rtp_port();
- /* Initialize SDP */
- sdp_message_init(&tech_pvt->local_sdp);
- sdp_message_v_version_set(tech_pvt->local_sdp, "0");
- sdp_message_o_origin_set(tech_pvt->local_sdp, "OpenSWITCH2", "0", "0", "IN", "IP4", tech_pvt->local_sdp_audio_ip);
- sdp_message_s_name_set(tech_pvt->local_sdp, "SIP Call");
- sdp_message_c_connection_add(tech_pvt->local_sdp, -1, "IN", "IP4", tech_pvt->local_sdp_audio_ip, NULL, NULL);
- sdp_message_t_time_descr_add(tech_pvt->local_sdp, "0", "0");
- snprintf(port, sizeof(port), "%i", tech_pvt->local_sdp_audio_port);
- sdp_message_m_media_add(tech_pvt->local_sdp, "audio", port, NULL, "RTP/AVP");
- /* Add in every codec we support on this outbound call */
- if ((num_codecs = loadable_module_get_codecs(switch_core_session_get_pool(session), codecs, sizeof(codecs)/sizeof(codecs[0]))) > 0) {
- int i;
- static const switch_codec_implementation *imp;
- for (i = 0; i < num_codecs; i++) {
- int x = 0;
-
- snprintf(tmp, sizeof(tmp), "%i", codecs[i]->ianacode);
- sdp_message_m_payload_add(tech_pvt->local_sdp, 0, osip_strdup(tmp));
- for (imp = codecs[i]->implementations ; imp ; imp = imp->next) {
- /* Add to SDP config */
- sdp_add_codec(tech_pvt->sdp_config, codecs[i]->codec_type, codecs[i]->ianacode, codecs[i]->iananame, imp->samples_per_second, x++);
- /* Add to SDP message */
-
- snprintf(tmp, sizeof(tmp), "%i %s/%i", codecs[i]->ianacode, codecs[i]->iananame, imp->samples_per_second);
- sdp_message_a_attribute_add(tech_pvt->local_sdp, 0, "rtpmap", osip_strdup(tmp));
- memset(tmp, 0, sizeof(tmp));
- }
- }
- }
- /* Setup our INVITE */
- eXosip_lock();
- if (!(dest_uri = (char *) switch_core_session_alloc(session, strlen(tech_pvt->caller_profile->destination_number) + 10))) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "AIEEEE!\n");
- assert(dest_uri != NULL);
- }
- sprintf(dest_uri, "sip:%s", tech_pvt->caller_profile->destination_number);
- eXosip_call_build_initial_invite(&invite, dest_uri, from_uri, NULL, NULL);
- osip_message_set_supported(invite, "100rel, replaces");
- /* Add SDP to the INVITE */
- sdp_message_to_str(tech_pvt->local_sdp, &buf);
- osip_message_set_body(invite, buf, strlen(buf));
- osip_message_set_content_type(invite, "application/sdp");
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "OUTBOUND SDP:\n%s\n", buf);
- free(buf);
- /* Send the INVITE */
- tech_pvt->cid = eXosip_call_send_initial_invite(invite);
- snprintf(tech_pvt->call_id, sizeof(tech_pvt->call_id), "%d", tech_pvt->cid);
- switch_core_hash_insert(globals.call_hash, tech_pvt->call_id, tech_pvt);
- tech_pvt->did = -1;
- eXosip_unlock();
- }
-
-
- /* Let Media Work */
- switch_set_flag(tech_pvt, TFLAG_IO);
-
- /* Move Channel's State Machine to RING */
- switch_channel_set_state(channel, CS_RING);
- return SWITCH_STATUS_SUCCESS;
-}
-
-static switch_status exosip_on_ring(switch_core_session *session)
-{
- switch_channel *channel = NULL;
- struct private_object *tech_pvt = NULL;
-
- channel = switch_core_session_get_channel(session);
- assert(channel != NULL);
-
- tech_pvt = switch_core_session_get_private(session);
- assert(tech_pvt != NULL);
-
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "EXOSIP RING\n");
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-static switch_status exosip_on_hangup(switch_core_session *session)
-{
- struct private_object *tech_pvt;
- switch_channel *channel = NULL;
- int i;
-
- channel = switch_core_session_get_channel(session);
- assert(channel != NULL);
-
- tech_pvt = switch_core_session_get_private(session);
- assert(tech_pvt != NULL);
-
-
- switch_core_hash_delete(globals.call_hash, tech_pvt->call_id);
-
-
- switch_set_flag(tech_pvt, TFLAG_BYE);
- switch_clear_flag(tech_pvt, TFLAG_IO);
-
- deactivate_rtp(tech_pvt);
-
- i = eXosip_call_terminate(tech_pvt->cid, tech_pvt->did);
-
- if (switch_test_flag(tech_pvt, TFLAG_USING_CODEC)) {
- switch_core_codec_destroy(&tech_pvt->read_codec);
- switch_core_codec_destroy(&tech_pvt->write_codec);
- }
-
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "EXOSIP HANGUP %s %d/%d=%d\n", switch_channel_get_name(channel), tech_pvt->cid, tech_pvt->did, i);
- return SWITCH_STATUS_SUCCESS;
-}
-
-static switch_status exosip_on_loopback(switch_core_session *session)
-{
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "EXOSIP LOOPBACK\n");
- return SWITCH_STATUS_SUCCESS;
-}
-
-static switch_status exosip_on_transmit(switch_core_session *session)
-{
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "EXOSIP TRANSMIT\n");
- return SWITCH_STATUS_SUCCESS;
-}
-
-static switch_status exosip_outgoing_channel(switch_core_session *session, switch_caller_profile *outbound_profile, switch_core_session **new_session)
-{
- if ((*new_session = switch_core_session_request(&exosip_endpoint_interface, NULL))) {
- struct private_object *tech_pvt;
- switch_channel *channel, *orig_channel;
- switch_caller_profile *caller_profile, *originator_caller_profile = NULL;
-
- if ((tech_pvt = (struct private_object *) switch_core_session_alloc(*new_session, sizeof(struct private_object)))) {
- memset(tech_pvt, 0, sizeof(*tech_pvt));
- channel = switch_core_session_get_channel(*new_session);
- switch_core_session_set_private(*new_session, tech_pvt);
- //switch_mutex_init(&tech_pvt->rtp_lock, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(*new_session));
- tech_pvt->session = *new_session;
- } else {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Hey where is my memory pool?\n");
- switch_core_session_destroy(new_session);
- return SWITCH_STATUS_GENERR;
- }
-
- if (outbound_profile) {
- char name[128];
- caller_profile = switch_caller_profile_clone(*new_session, outbound_profile);
- switch_channel_set_caller_profile(channel, caller_profile);
- tech_pvt->caller_profile = caller_profile;
- snprintf(name, sizeof(name), "Exosip/%s-%04x", caller_profile->destination_number, rand() & 0xffff);
- switch_channel_set_name(channel, name);
- } else {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Doh! no caller profile\n");
- switch_core_session_destroy(new_session);
- return SWITCH_STATUS_GENERR;
- }
-
- /* (session == NULL) means it was originated from the core not from another channel */
- if (session && (orig_channel = switch_core_session_get_channel(session))) {
- switch_caller_profile *cloned_profile;
-
- if ((originator_caller_profile = switch_channel_get_caller_profile(orig_channel))) {
- cloned_profile = switch_caller_profile_clone(*new_session, originator_caller_profile);
- switch_channel_set_originator_caller_profile(channel, cloned_profile);
- }
- }
-
- switch_channel_set_flag(channel, CF_OUTBOUND);
- switch_set_flag(tech_pvt, TFLAG_OUTBOUND);
- switch_channel_set_state(channel, CS_INIT);
- return SWITCH_STATUS_SUCCESS;
- }
-
- return SWITCH_STATUS_GENERR;
-}
-
-#if 0
-static const char *event_names[] = {
- "RX_RTP",
- "RX_SR",
- "RX_RR",
- "RX_SDES",
- "RX_BYE",
- "SOURCE_CREATED",
- "SOURCE_DELETED",
- "RX_RR_EMPTY",
- "RX_RTCP_START",
- "RX_RTCP_FINISH",
- "RR_TIMEOUT",
- "RX_APP"
-};
-#endif
-
-static void rtp_event_handler(struct rtp *session, rtp_event *event)
-{
- rtp_packet *packet;
- struct private_object *tech_pvt = (struct private_object *) rtp_get_userdata(session);
-
- if (!session) {
- return;
- }
-
-
- //switch_console_printf(SWITCH_CHANNEL_CONSOLE, "RTP EVENT (%s)\n", event_names[event->type]);
-
- switch(event->type) {
- case RX_RTP:
- if((packet = (rtp_packet *) event->data)) {
- if (packet->data_len < 10000) {
- memcpy(tech_pvt->read_buf, packet->data, packet->data_len);
- tech_pvt->read_frame.datalen = packet->data_len;
- } else {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "WTF PACKET LEN %d\n", packet->data_len);
- }
- free(packet); /* xfree() is mandatory to release RTP packet data */
- }
- break;
- case RR_TIMEOUT:
- case RX_BYE:
- switch_set_flag(tech_pvt, TFLAG_BYE);
- default:
- break;
- }
-}
-
-static void deactivate_rtp(struct private_object *tech_pvt)
-{
- int loops = 0;
- if (tech_pvt->rtp_session) {
- //switch_mutex_lock(tech_pvt->rtp_lock);
-
- while(loops < 10 && (switch_test_flag(tech_pvt, TFLAG_READING) || switch_test_flag(tech_pvt, TFLAG_WRITING))) {
- switch_yield(10000);
- loops++;
- }
- rtp_send_bye(tech_pvt->rtp_session);
- rtp_done(tech_pvt->rtp_session);
- tech_pvt->rtp_session = NULL;
- //switch_mutex_unlock(tech_pvt->rtp_lock);
- }
-}
-
-static void activate_rtp(struct private_object *tech_pvt)
-{
- int bw, ms;
- switch_channel *channel;
-
- assert(tech_pvt != NULL);
-
- channel = switch_core_session_get_channel(tech_pvt->session);
- assert(channel != NULL);
-
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Activating RTP %d->%s:%d\n",
- tech_pvt->local_sdp_audio_port,
- tech_pvt->remote_sdp_audio_ip,
- tech_pvt->remote_sdp_audio_port);
-
-
- //switch_mutex_lock(tech_pvt->rtp_lock);
- if (switch_test_flag(tech_pvt, TFLAG_USING_CODEC)) {
- bw = tech_pvt->read_codec.implementation->bits_per_second;
- ms = tech_pvt->read_codec.implementation->nanoseconds_per_frame / 1000;
- } else {
- switch_channel_get_raw_mode(channel, NULL, NULL, NULL, &ms, &bw);
- bw *= 8;
- }
-
- tech_pvt->rtp_session = rtp_init(tech_pvt->remote_sdp_audio_ip, /* Host/Group IP address */
- tech_pvt->local_sdp_audio_port, /* receive port */
- tech_pvt->remote_sdp_audio_port, /* transmit port */
- ms * 2, /* time-to-live */
- bw, /* B/W estimate */
- rtp_event_handler, /* RTP event callback */
- (void *) tech_pvt); /* App. specific data */
-
-
- if (tech_pvt->rtp_session) {
- tech_pvt->ssrc = rtp_my_ssrc(tech_pvt->rtp_session);
- rtp_set_option(tech_pvt->rtp_session, RTP_OPT_PROMISC, 1);
- /* Set local participant info */
- rtp_set_sdes(tech_pvt->rtp_session, tech_pvt->ssrc, RTCP_SDES_NAME, "test", 4);
- rtp_set_sdes(tech_pvt->rtp_session, tech_pvt->ssrc, RTCP_SDES_PHONE, "test", 4);
- rtp_set_sdes(tech_pvt->rtp_session, tech_pvt->ssrc, RTCP_SDES_TOOL, "test", 4);
- switch_set_flag(tech_pvt, TFLAG_RTP);
- } else {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Oh oh is your port even?\n");
- }
- //switch_mutex_unlock(tech_pvt->rtp_lock);
-}
-
-static switch_status exosip_answer_channel(switch_core_session *session)
-{
- struct private_object *tech_pvt;
- switch_channel *channel = NULL;
-
- channel = switch_core_session_get_channel(session);
- assert(channel != NULL);
-
- tech_pvt = switch_core_session_get_private(session);
- assert(tech_pvt != NULL);
-
- if (!switch_channel_test_flag(channel, CF_OUTBOUND)) {
- char *buf = NULL;
- osip_message_t *answer = NULL;
-
-
- /* Transmit 200 OK with SDP */
- eXosip_lock();
- eXosip_call_build_answer(tech_pvt->tid, 200, &answer);
- sdp_message_to_str(tech_pvt->local_sdp, &buf);
- osip_message_set_body(answer, buf, strlen(buf));
- osip_message_set_content_type(answer, "application/sdp");
- free(buf);
- eXosip_call_send_answer(tech_pvt->tid, 200, answer);
- eXosip_unlock();
- }
-
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-
-static switch_status exosip_read_frame(switch_core_session *session, switch_frame **frame, int timeout, switch_io_flag flags)
-{
- struct private_object *tech_pvt = NULL;
- size_t bytes = 0, samples = 0, frames, ms, x;
- switch_channel *channel = NULL;
- int ns=0;
- struct timeval tv;
-
- channel = switch_core_session_get_channel(session);
- assert(channel != NULL);
-
- tech_pvt = switch_core_session_get_private(session);
- assert(tech_pvt != NULL);
-
- tech_pvt->read_frame.datalen = 0;
- switch_set_flag(tech_pvt, TFLAG_READING);
-
- if (switch_test_flag(tech_pvt, TFLAG_USING_CODEC)) {
- bytes = tech_pvt->read_codec.implementation->encoded_bytes_per_frame;
- samples = tech_pvt->read_codec.implementation->samples_per_frame;
- } else {
- assert(0);
- }
-
- if (timeout > 0) {
- ns = timeout * 10000;
- } else {
- ns = tech_pvt->read_codec.implementation->nanoseconds_per_frame;
- }
-
- if (switch_test_flag(tech_pvt, TFLAG_IO)) {
- if (!switch_test_flag(tech_pvt, TFLAG_RTP)) {
- activate_rtp(tech_pvt);
- }
-
- assert(tech_pvt->rtp_session != NULL);
- tech_pvt->read_frame.datalen = 0;
- //switch_mutex_lock(tech_pvt->rtp_lock);
- tv.tv_sec = 0;
- tv.tv_usec = ns;
- while(switch_test_flag(tech_pvt, TFLAG_IO) && !switch_test_flag(tech_pvt, TFLAG_BYE)) {
- x = rtp_recv(tech_pvt->rtp_session, &tv, tech_pvt->timestamp_recv);
- if(x < 0) {
- break;
- }
- if (tech_pvt->read_frame.datalen) {
- bytes = tech_pvt->read_codec.implementation->encoded_bytes_per_frame;
- frames = (tech_pvt->read_frame.datalen / bytes);
- samples = frames * tech_pvt->read_codec.implementation->samples_per_frame;
- ms = frames * tech_pvt->read_codec.implementation->nanoseconds_per_frame / 1000;
- break;
- }
- }
- tech_pvt->timestamp_recv += (int)samples;
- //printf("%s\trecv %d bytes %d samples in %d frames taking up %d ms ts=%d\n", switch_channel_get_name(channel), tech_pvt->read_frame.datalen, samples, frames, ms, tech_pvt->timestamp_recv);
- //switch_mutex_unlock(tech_pvt->rtp_lock);
-
- } else {
- memset(tech_pvt->read_buf, 0, 160);
- tech_pvt->read_frame.datalen = 160;
- }
-
- switch_clear_flag(tech_pvt, TFLAG_READING);
-
- if (switch_test_flag(tech_pvt, TFLAG_BYE)) {
- switch_channel_hangup(channel);
- return SWITCH_STATUS_FALSE;
- }
-
- *frame = &tech_pvt->read_frame;
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-
-static switch_status exosip_write_frame(switch_core_session *session, switch_frame *frame, int timeout, switch_io_flag flags)
-{
- struct private_object *tech_pvt;
- switch_channel *channel = NULL;
- switch_status status = SWITCH_STATUS_SUCCESS;
- size_t x, bytes, samples, ms, frames;
-
- channel = switch_core_session_get_channel(session);
- assert(channel != NULL);
-
- tech_pvt = switch_core_session_get_private(session);
- assert(tech_pvt != NULL);
-
- if (!switch_test_flag(tech_pvt, TFLAG_RTP)) {
- activate_rtp(tech_pvt);
- }
-
- if (!switch_test_flag(tech_pvt, TFLAG_IO)) {
- return SWITCH_STATUS_SUCCESS;
- }
-
- if (switch_test_flag(tech_pvt, TFLAG_BYE)) {
- switch_channel_hangup(channel);
- return SWITCH_STATUS_FALSE;
- }
-
- switch_set_flag(tech_pvt, TFLAG_WRITING);
- //switch_mutex_lock(tech_pvt->rtp_lock);
-
- if (switch_test_flag(tech_pvt, TFLAG_USING_CODEC)) {
- bytes = tech_pvt->read_codec.implementation->encoded_bytes_per_frame;
- frames = (frame->datalen / bytes);
- samples = frames * tech_pvt->read_codec.implementation->samples_per_frame;
- ms = frames * tech_pvt->read_codec.implementation->nanoseconds_per_frame / 1000;
- } else {
- assert(0);
- }
- tech_pvt->timestamp_send += (int)samples;
-
-
- //printf("%s %s->%s send %d bytes %d samples in %d frames taking up %d ms ts=%d\n", switch_channel_get_name(channel), tech_pvt->local_sdp_audio_ip, tech_pvt->remote_sdp_audio_ip, frame->datalen, samples, frames, ms, tech_pvt->timestamp_recv);
-
- rtp_send_ctrl(tech_pvt->rtp_session, tech_pvt->timestamp_send, NULL);
- x = rtp_send_data(tech_pvt->rtp_session, tech_pvt->timestamp_send, tech_pvt->payload_num,
- 0, 0, 0,
- (char *)frame->data, (int)frame->datalen,
- 0, 0, 0);
-
-
- switch_clear_flag(tech_pvt, TFLAG_WRITING);
- //switch_mutex_unlock(tech_pvt->rtp_lock);
- return status;
-}
-
-
-
-static switch_status exosip_kill_channel(switch_core_session *session, int sig)
-{
- struct private_object *tech_pvt;
- switch_channel *channel = NULL;
-
- channel = switch_core_session_get_channel(session);
- assert(channel != NULL);
-
- tech_pvt = switch_core_session_get_private(session);
- assert(tech_pvt != NULL);
-
-
- switch_clear_flag(tech_pvt, TFLAG_IO);
- switch_set_flag(tech_pvt, TFLAG_BYE);
- //rtp_kill(tech_pvt->rtp_session);
-
- return SWITCH_STATUS_SUCCESS;
-
-}
-
-static switch_status exosip_waitfor_read(switch_core_session *session, int ms)
-{
- struct private_object *tech_pvt;
- switch_channel *channel = NULL;
-
- channel = switch_core_session_get_channel(session);
- assert(channel != NULL);
-
- tech_pvt = switch_core_session_get_private(session);
- assert(tech_pvt != NULL);
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-
-static switch_status exosip_waitfor_write(switch_core_session *session, int ms)
-{
- struct private_object *tech_pvt;
- switch_channel *channel = NULL;
-
- channel = switch_core_session_get_channel(session);
- assert(channel != NULL);
-
- tech_pvt = switch_core_session_get_private(session);
- assert(tech_pvt != NULL);
-
- return SWITCH_STATUS_SUCCESS;
-
-}
-
-static const switch_io_routines exosip_io_routines = {
- /*.outgoing_channel*/ exosip_outgoing_channel,
- /*.answer_channel*/ exosip_answer_channel,
- /*.read_frame*/ exosip_read_frame,
- /*.write_frame*/ exosip_write_frame,
- /*.kill_channel*/ exosip_kill_channel,
- /*.waitfor_read*/ exosip_waitfor_read,
- /*.waitfor_read*/ exosip_waitfor_write
-};
-
-static const switch_event_handler_table exosip_event_handlers = {
- /*.on_init*/ exosip_on_init,
- /*.on_ring*/ exosip_on_ring,
- /*.on_execute*/ exosip_on_execute,
- /*.on_hangup*/ exosip_on_hangup,
- /*.on_loopback*/ exosip_on_loopback,
- /*.on_transmit*/ exosip_on_transmit
-};
-
-static const switch_endpoint_interface exosip_endpoint_interface = {
- /*.interface_name*/ "exosip",
- /*.io_routines*/ &exosip_io_routines,
- /*.event_handlers*/ &exosip_event_handlers,
- /*.private*/ NULL,
- /*.next*/ NULL
-};
-
-static const switch_loadable_module_interface exosip_module_interface = {
- /*.module_name*/ modname,
- /*.endpoint_interface*/ &exosip_endpoint_interface,
- /*.timer_interface*/ NULL,
- /*.dialplan_interface*/ NULL,
- /*.codec_interface*/ NULL,
- /*.application_interface*/ NULL
-};
-
-
-SWITCH_MOD_DECLARE(switch_status) switch_module_shutdown(void)
-{
- if (globals.running) {
- globals.running = -1;
- while(globals.running) {
- switch_yield(1000);
- }
- }
- eXosip_quit();
- return SWITCH_STATUS_SUCCESS;
-}
-
-SWITCH_MOD_DECLARE(switch_status) switch_module_load(const switch_loadable_module_interface **_interface, char *filename) {
- /* NOTE: **interface is **_interface because the common lib redefines interface to struct in some situations */
-
- if (switch_core_new_memory_pool(&module_pool) != SWITCH_STATUS_SUCCESS) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "OH OH no pool\n");
- return SWITCH_STATUS_TERM;
- }
-
- /* connect my internal structure to the blank pointer passed to me */
- *_interface = &exosip_module_interface;
-
- /* indicate that the module should continue to be loaded */
- return SWITCH_STATUS_SUCCESS;
-}
-
-static switch_status exosip_create_call(eXosip_event_t *event)
-{
- switch_core_session *session;
- sdp_message_t *remote_sdp = NULL;
- sdp_connection_t *conn = NULL;
- sdp_media_t *remote_med = NULL, *audio_tab[10], *video_tab[10], *t38_tab[10], *app_tab[10];
- char local_sdp_str[8192] = "", port[8] = "";
- int mline = 0, pos = 0;
- switch_channel *channel = NULL;
- char name[128];
- char *dpayload, *dname, *drate;
- char *remote_sdp_str = NULL;
-
- if ((session = switch_core_session_request(&exosip_endpoint_interface, NULL))) {
- struct private_object *tech_pvt;
- switch_codec_interface *codecs[512];
- int num_codecs = 0;
-
-
- if ((tech_pvt = (struct private_object *) switch_core_session_alloc(session, sizeof(struct private_object)))) {
- memset(tech_pvt, 0, sizeof(*tech_pvt));
- channel = switch_core_session_get_channel(session);
- switch_core_session_set_private(session, tech_pvt);
- tech_pvt->session = session;
- //switch_mutex_init(&tech_pvt->rtp_lock, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session));
- } else {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Hey where is my memory pool?\n");
- switch_core_session_destroy(&session);
- return SWITCH_STATUS_MEMERR;
- }
-
- if ((tech_pvt->caller_profile = switch_caller_profile_new(session,
- globals.dialplan,
- event->request->from->displayname,
- event->request->from->url->username,
- event->request->from->url->username,
- NULL,
- event->request->req_uri->username))) {
- switch_channel_set_caller_profile(channel, tech_pvt->caller_profile);
- }
-
- switch_set_flag(tech_pvt, TFLAG_INBOUND);
- tech_pvt->did = event->did;
- tech_pvt->cid = event->cid;
- tech_pvt->tid = event->tid;
-
- snprintf(name, sizeof(name), "Exosip/%s-%04x", tech_pvt->caller_profile->destination_number, rand() & 0xffff);
- switch_channel_set_name(channel, name);
-
- if (!(remote_sdp = eXosip_get_sdp_info(event->request))) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Cannot Find Remote SDP!\n");
- exosip_on_hangup(session);
- switch_core_session_destroy(&session);
- return SWITCH_STATUS_GENERR;
- }
-
- eXosip_guess_localip(AF_INET, tech_pvt->local_sdp_audio_ip, 50);
- tech_pvt->local_sdp_audio_port = next_rtp_port();
- osip_rfc3264_init(&tech_pvt->sdp_config);
- /* Add in what codecs we support locally */
-
- if ((num_codecs = loadable_module_get_codecs(switch_core_session_get_pool(session), codecs, sizeof(codecs)/sizeof(codecs[0]))) > 0) {
- int i;
- static const switch_codec_implementation *imp;
-
- for (i = 0; i < num_codecs; i++) {
- int x = 0;
- for (imp = codecs[i]->implementations ; imp ; imp = imp->next) {
- sdp_add_codec(tech_pvt->sdp_config, codecs[i]->codec_type, codecs[i]->ianacode, codecs[i]->iananame, imp->samples_per_second, x++);
- }
- }
- }
- osip_rfc3264_prepare_answer(tech_pvt->sdp_config, remote_sdp, local_sdp_str, 8192);
- sdp_message_init(&tech_pvt->local_sdp);
- sdp_message_parse(tech_pvt->local_sdp, local_sdp_str);
-
- sdp_message_to_str(remote_sdp, &remote_sdp_str);
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "LOCAL SDP:\n%s\nREMOTE SDP:\n%s", local_sdp_str,remote_sdp_str);
-
- mline = 0;
- while (0==osip_rfc3264_match(tech_pvt->sdp_config, remote_sdp, audio_tab, video_tab, t38_tab, app_tab, mline)) {
- if (audio_tab[0] == NULL && video_tab[0] == NULL && t38_tab[0] == NULL && app_tab[0] == NULL) {
-
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Got no compatible codecs!\n");
- break;
- }
- for (pos=0; audio_tab[pos]!=NULL; pos++) {
- osip_rfc3264_complete_answer(tech_pvt->sdp_config, remote_sdp, tech_pvt->local_sdp, audio_tab[pos], mline);
- if (parse_sdp_media(audio_tab[pos], &dname, &drate, &dpayload) == SWITCH_STATUS_SUCCESS) {
- tech_pvt->payload_num = atoi(dpayload);
- break;
- }
- }
- mline++;
- }
- free(remote_sdp_str);
- sdp_message_o_origin_set(tech_pvt->local_sdp, "OpenSWITCH2", "0", "0", "IN", "IP4", tech_pvt->local_sdp_audio_ip);
- sdp_message_s_name_set(tech_pvt->local_sdp, "SIP Call");
- sdp_message_c_connection_add(tech_pvt->local_sdp, -1, "IN", "IP4", tech_pvt->local_sdp_audio_ip, NULL, NULL);
- snprintf(port, sizeof(port), "%i", tech_pvt->local_sdp_audio_port);
- sdp_message_m_port_set(tech_pvt->local_sdp, 0, osip_strdup(port));
-
- conn = eXosip_get_audio_connection(remote_sdp);
- remote_med = eXosip_get_audio_media(remote_sdp);
- snprintf(tech_pvt->remote_sdp_audio_ip, 50, conn->c_addr);
-
- tech_pvt->remote_sdp_audio_port = atoi(remote_med->m_port);
-
- snprintf(tech_pvt->call_id, sizeof(tech_pvt->call_id), "%d", event->cid);
- switch_core_hash_insert(globals.call_hash, tech_pvt->call_id, tech_pvt);
-
- if (!dname) {
- exosip_on_hangup(session);
- switch_core_session_destroy(&session);
- return SWITCH_STATUS_GENERR;
- }
-
- switch_channel_set_state(channel, CS_INIT);
-
-
- if (1) {
- int rate = atoi(drate);
-
- if (switch_core_codec_init(&tech_pvt->read_codec,
- dname,
- rate,
- globals.codec_ms,
- SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
- NULL) != SWITCH_STATUS_SUCCESS) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Can't load codec?\n");
- switch_channel_hangup(channel);
- return SWITCH_STATUS_FALSE;
- } else {
- if (switch_core_codec_init(&tech_pvt->write_codec,
- dname,
- rate,
- globals.codec_ms,
- SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
- NULL) != SWITCH_STATUS_SUCCESS) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Can't load codec?\n");
- switch_channel_hangup(channel);
- return SWITCH_STATUS_FALSE;
- } else {
- int ms;
- switch_set_flag(tech_pvt, TFLAG_USING_CODEC);
- ms = tech_pvt->write_codec.implementation->nanoseconds_per_frame / 1000;
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Activate Inbound Codec %s/%d %d ms\n", dname, rate, ms);
- tech_pvt->read_frame.codec = &tech_pvt->read_codec;
- switch_core_session_set_read_codec(session, &tech_pvt->read_codec);
- switch_core_session_set_write_codec(session, &tech_pvt->write_codec);
- }
- }
- }
-
- switch_core_session_thread_launch(session);
- } else {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Cannot Create new Inbound Channel!\n");
- }
-
-
- return 0;
-
-
-
-}
-
-static void destroy_call_by_event(eXosip_event_t *event)
-{
- struct private_object *tech_pvt;
- switch_channel *channel = NULL;
-
- if (!(tech_pvt = get_pvt_by_call_id(event->cid))) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Um in case you are interested, Can't find the pvt [%d]!\n", event->cid);
- return;
- }
-
- channel = switch_core_session_get_channel(tech_pvt->session);
- assert(channel != NULL);
-
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "destroy %s\n", switch_channel_get_name(channel));
- exosip_kill_channel(tech_pvt->session, SWITCH_SIG_KILL);
- switch_channel_hangup(channel);
-
-}
-
-static switch_status parse_sdp_media(sdp_media_t *media, char **dname, char **drate, char **dpayload)
-{
- int pos = 0;
- sdp_attribute_t *attr = NULL;
- char *name, *rate, *payload;
- switch_status status = SWITCH_STATUS_GENERR;
-
- while (osip_list_eol(media->a_attributes, pos) == 0) {
- attr = (sdp_attribute_t *)osip_list_get(media->a_attributes, pos);
- if (attr != NULL && strcasecmp(attr->a_att_field, "rtpmap") == 0) {
- payload = attr->a_att_value;
- if ((name = strchr(payload, ' '))) {
- *(name++) = '\0';
- /* Name and payload are required */
- *dpayload = strdup(payload);
- status = SWITCH_STATUS_SUCCESS;
- if ((rate = strchr(name, '/'))) {
- *(rate++) = '\0';
- *drate = strdup(rate);
- *dname = strdup(name);
- } else {
- *dname = strdup(name);
- *drate = strdup("8000");
- }
- } else {
- *dpayload = strdup("10");
- *dname = strdup("L16");
- *drate = strdup("8000");
- }
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Found negotiated codec Payload: %s Name: %s Rate: %s\n", *dpayload, *dname, *drate);
- break;
- }
- attr = NULL;
- pos++;
- }
-
- return status;
-}
-
-static void handle_answer(eXosip_event_t *event)
-{
- osip_message_t *ack = NULL;
- sdp_message_t *remote_sdp = NULL;
- sdp_connection_t *conn = NULL;
- sdp_media_t *remote_med = NULL;
- struct private_object *tech_pvt;
- char *dpayload = NULL, *dname = NULL, *drate = NULL;
- switch_channel *channel;
-
-
- if (!(tech_pvt = get_pvt_by_call_id(event->cid))) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Um in case you are interested, Can't find the pvt!\n");
- return;
- }
-
- channel = switch_core_session_get_channel(tech_pvt->session);
- assert(channel != NULL);
-
- if (!event->response) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Someone answered... with no SDP information - WTF?!?\n");
- switch_channel_hangup(channel);
- return;
- }
-
- /* Get all of the remote SDP elements... stuff */
- if (!(remote_sdp = eXosip_get_sdp_info(event->response))) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Cant Find SDP?\n");
- switch_channel_hangup(channel);
- return;
- }
-
-
- conn = eXosip_get_audio_connection(remote_sdp);
- remote_med = eXosip_get_audio_media(remote_sdp);
-
- /* Grab IP/port */
- tech_pvt->remote_sdp_audio_port = atoi(remote_med->m_port);
- snprintf(tech_pvt->remote_sdp_audio_ip, 50, conn->c_addr);
-
- /* Grab codec elements */
- if (parse_sdp_media(remote_med, &dname, &drate, &dpayload) == SWITCH_STATUS_SUCCESS) {
- tech_pvt->payload_num = atoi(dpayload);
- }
-
- /* Assign them thar IDs */
- tech_pvt->did = event->did;
- tech_pvt->tid = event->tid;
-
-
- if (1) {
- int rate = atoi(drate);
-
-
- if (switch_core_codec_init(&tech_pvt->read_codec, dname, rate, globals.codec_ms, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL) != SWITCH_STATUS_SUCCESS) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Can't load codec?\n");
- switch_channel_hangup(channel);
- return;
- } else {
- if (switch_core_codec_init(&tech_pvt->write_codec, dname, rate, globals.codec_ms, SWITCH_CODEC_FLAG_ENCODE |SWITCH_CODEC_FLAG_DECODE, NULL) != SWITCH_STATUS_SUCCESS) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Can't load codec?\n");
- switch_channel_hangup(channel);
- return;
- } else {
- int ms;
- switch_set_flag(tech_pvt, TFLAG_USING_CODEC);
- ms = tech_pvt->write_codec.implementation->nanoseconds_per_frame / 1000;
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Activate Outbound Codec %s/%d %d ms\n", dname, rate, ms);
- tech_pvt->read_frame.codec = &tech_pvt->read_codec;
- switch_core_session_set_read_codec(tech_pvt->session, &tech_pvt->read_codec);
- switch_core_session_set_write_codec(tech_pvt->session, &tech_pvt->write_codec);
- }
- }
- }
-
-
- eXosip_lock();
- eXosip_call_build_ack(event->did, &ack);
- eXosip_call_send_ack(event->did, ack);
- eXosip_unlock();
-
- free(dname);
- free(drate);
- free(dpayload);
-
- channel = switch_core_session_get_channel(tech_pvt->session);
- assert(channel != NULL);
-
- switch_channel_answer(channel);
-
-}
-
-static void log_event(eXosip_event_t *je)
-{
- char buf[100];
-
- buf[0] = '\0';
- if (je->type == EXOSIP_CALL_NOANSWER) {
- snprintf (buf, 99, "<- (%i %i) No answer", je->cid, je->did);
- } else if (je->type == EXOSIP_CALL_CLOSED) {
- snprintf (buf, 99, "<- (%i %i) Call Closed", je->cid, je->did);
- } else if (je->type == EXOSIP_CALL_RELEASED) {
- snprintf (buf, 99, "<- (%i %i) Call released", je->cid, je->did);
- } else if (je->type == EXOSIP_MESSAGE_NEW
- && je->request!=NULL && MSG_IS_MESSAGE(je->request)) {
- char *tmp = NULL;
-
- if (je->request != NULL) {
- osip_body_t *body;
- osip_from_to_str (je->request->from, &tmp);
-
- osip_message_get_body (je->request, 0, &body);
- if (body != NULL && body->body != NULL) {
- snprintf (buf, 99, "<- (%i) from: %s TEXT: %s",
- je->tid, tmp, body->body);
- }
- osip_free (tmp);
- } else {
- snprintf (buf, 99, "<- (%i) New event for unknown request?", je->tid);
- }
- } else if (je->type == EXOSIP_MESSAGE_NEW) {
- char *tmp = NULL;
-
- osip_from_to_str (je->request->from, &tmp);
- snprintf (buf, 99, "<- (%i) %s from: %s",
- je->tid, je->request->sip_method, tmp);
- osip_free (tmp);
- } else if (je->type == EXOSIP_MESSAGE_PROCEEDING
- || je->type == EXOSIP_MESSAGE_ANSWERED
- || je->type == EXOSIP_MESSAGE_REDIRECTED
- || je->type == EXOSIP_MESSAGE_REQUESTFAILURE
- || je->type == EXOSIP_MESSAGE_SERVERFAILURE
- || je->type == EXOSIP_MESSAGE_GLOBALFAILURE) {
- if (je->response != NULL && je->request != NULL) {
- char *tmp = NULL;
-
- osip_to_to_str (je->request->to, &tmp);
- snprintf (buf, 99, "<- (%i) [%i %s for %s] to: %s",
- je->tid, je->response->status_code,
- je->response->reason_phrase, je->request->sip_method, tmp);
- osip_free (tmp);
- } else if (je->request != NULL) {
- snprintf (buf, 99, "<- (%i) Error for %s request",
- je->tid, je->request->sip_method);
- } else {
- snprintf (buf, 99, "<- (%i) Error for unknown request", je->tid);
- }
- } else if (je->response == NULL && je->request != NULL && je->cid > 0) {
- char *tmp = NULL;
-
- osip_from_to_str (je->request->from, &tmp);
- snprintf (buf, 99, "<- (%i %i) %s from: %s",
- je->cid, je->did, je->request->cseq->method, tmp);
- osip_free (tmp);
- } else if (je->response != NULL && je->cid > 0) {
- char *tmp = NULL;
-
- osip_to_to_str (je->request->to, &tmp);
- snprintf (buf, 99, "<- (%i %i) [%i %s] for %s to: %s",
- je->cid, je->did, je->response->status_code,
- je->response->reason_phrase, je->request->sip_method, tmp);
- osip_free (tmp);
- } else if (je->response == NULL && je->request != NULL && je->rid > 0) {
- char *tmp = NULL;
-
- osip_from_to_str (je->request->from, &tmp);
- snprintf (buf, 99, "<- (%i) %s from: %s",
- je->rid, je->request->cseq->method, tmp);
- osip_free (tmp);
- } else if (je->response != NULL && je->rid > 0) {
- char *tmp = NULL;
-
- osip_from_to_str (je->request->from, &tmp);
- snprintf (buf, 99, "<- (%i) [%i %s] from: %s",
- je->rid, je->response->status_code,
- je->response->reason_phrase, tmp);
- osip_free (tmp);
- } else if (je->response == NULL && je->request != NULL && je->sid > 0) {
- char *tmp = NULL;
- char *stat = NULL;
- osip_header_t *sub_state;
-
- osip_message_header_get_byname (je->request, "subscription-state",
- 0, &sub_state);
- if (sub_state != NULL && sub_state->hvalue != NULL)
- stat = sub_state->hvalue;
-
- osip_uri_to_str (je->request->from->url, &tmp);
- snprintf (buf, 99, "<- (%i) [%s] %s from: %s",
- je->sid, stat, je->request->cseq->method, tmp);
- osip_free (tmp);
- } else if (je->response != NULL && je->sid > 0) {
- char *tmp = NULL;
-
- osip_uri_to_str (je->request->to->url, &tmp);
- snprintf (buf, 99, "<- (%i) [%i %s] from: %s",
- je->sid, je->response->status_code,
- je->response->reason_phrase, tmp);
- osip_free (tmp);
- } else if (je->response == NULL && je->request != NULL) {
- char *tmp = NULL;
-
- osip_from_to_str (je->request->from, &tmp);
- snprintf (buf, 99, "<- (c=%i|d=%i|s=%i|n=%i) %s from: %s",
- je->cid, je->did, je->sid, je->nid,
- je->request->sip_method, tmp);
- osip_free (tmp);
- } else if (je->response != NULL) {
- char *tmp = NULL;
-
- osip_from_to_str (je->request->from, &tmp);
- snprintf (buf, 99, "<- (c=%i|d=%i|s=%i|n=%i) [%i %s] for %s from: %s",
- je->cid, je->did, je->sid, je->nid,
- je->response->status_code, je->response->reason_phrase,
- je->request->sip_method, tmp);
- osip_free (tmp);
- } else {
- snprintf (buf, 99, "<- (c=%i|d=%i|s=%i|n=%i|t=%i) %s",
- je->cid, je->did, je->sid, je->nid, je->tid, je->textinfo);
- }
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "\n%s\n", buf);
- /* Print it out */
-}
-
-
-
-static void *monitor_thread_run(void)
-{
- eXosip_event_t *event = NULL;
-
- globals.running = 1;
- while (globals.running > 0) {
- if (!(event = eXosip_event_wait(0,100))) {
- switch_yield(100);
- continue;
- }
-
- eXosip_lock();
- eXosip_automatic_action ();
- eXosip_unlock();
-
- log_event(event);
-
- switch(event->type) {
- case EXOSIP_CALL_INVITE:
- exosip_create_call(event);
- break;
- case EXOSIP_CALL_REINVITE:
- /* See what the reinvite is about - on hold or whatever */
- //handle_reinvite(event);
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Got a reinvite.\n");
- break;
- case EXOSIP_CALL_MESSAGE_NEW:
- if (event->request != NULL && MSG_IS_REFER(event->request)) {
- //handle_call_transfer(event);
- }
- break;
- case EXOSIP_CALL_ACK:
- /* If audio is not flowing and this has SDP - fire it up! */
- break;
- case EXOSIP_CALL_ANSWERED:
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "The call was answered.\n");
- handle_answer(event);
- break;
- case EXOSIP_CALL_PROCEEDING:
- /* This is like a 100 Trying... yeah */
- break;
- case EXOSIP_CALL_RINGING:
- //handle_ringing(event);
- break;
- case EXOSIP_CALL_REDIRECTED:
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Call was redirect\n");
- break;
- case EXOSIP_CALL_CLOSED:
- destroy_call_by_event(event);
- break;
- case EXOSIP_CALL_RELEASED:
- destroy_call_by_event(event);
- break;
- case EXOSIP_CALL_NOANSWER:
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "The call was not answered.\n");
- destroy_call_by_event(event);
- break;
- case EXOSIP_CALL_REQUESTFAILURE:
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Request failure\n");
- destroy_call_by_event(event);
- break;
- case EXOSIP_CALL_SERVERFAILURE:
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Server failure\n");
- destroy_call_by_event(event);
- break;
- case EXOSIP_CALL_GLOBALFAILURE:
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Global failure\n");
- destroy_call_by_event(event);
- break;
- /* Registration related stuff */
- case EXOSIP_REGISTRATION_NEW:
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Received registration attempt\n");
- break;
- default:
- /* Unknown event... casually absorb it for now */
- break;
- }
-
- //switch_console_printf(SWITCH_CHANNEL_CONSOLE, "There was an event (%d) [%s]\n", event->type, event->textinfo);
- /* Free the event */
- eXosip_event_free(event);
- }
-
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Monitor Thread Exiting\n");
- globals.running = 0;
- return NULL;
-}
-
-
-static int config_exosip(int reload)
-{
- switch_config cfg;
- char *var, *val;
- char *cf = "exosip.conf";
-
- globals.bytes_per_frame = DEFAULT_BYTES_PER_FRAME;
- switch_core_hash_init(&globals.call_hash, module_pool);
-
- if (!switch_config_open_file(&cfg, cf)) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "open of %s failed\n", cf);
- return SWITCH_STATUS_TERM;
- }
-
- globals.rtp_start = 16384;
- globals.rtp_end = 32768;
-
- while (switch_config_next_pair(&cfg, &var, &val)) {
- if (!strcasecmp(cfg.category, "settings")) {
- if (!strcmp(var, "debug")) {
- globals.debug = atoi(val);
- } else if (!strcmp(var, "port")) {
- globals.port = atoi(val);
- } else if (!strcmp(var, "dialplan")) {
- set_global_dialplan(val);
- } else if (!strcmp(var, "rtp_min_port")) {
- globals.rtp_start = atoi(val);
- } else if (!strcmp(var, "rtp_max_port")) {
- globals.rtp_end = atoi(val);
- } else if (!strcmp(var, "codec_ms")) {
- globals.codec_ms = atoi(val);
- }
- }
- }
-
- if (!globals.codec_ms) {
- globals.codec_ms = 20;
- }
-
- if (!globals.port) {
- globals.port = 5060;
- }
-
- switch_config_close_file(&cfg);
-
- if (!globals.dialplan) {
- set_global_dialplan("default");
- }
-
- if (eXosip_init ()) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "eXosip_init initialization failed!\n");
- return SWITCH_STATUS_GENERR;
- }
- if (eXosip_listen_addr (IPPROTO_UDP, NULL, globals.port, AF_INET, 0)) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "eXosip_listen_addr failed!\n");
- return SWITCH_STATUS_GENERR;
- }
-
- switch_mutex_init(&globals.port_lock, SWITCH_MUTEX_NESTED, module_pool);
-
-
- /* Setup the user agent */
- eXosip_set_user_agent("OPENSWITCH 2.0");
-
-
- monitor_thread_run();
- return 0;
-
-}
-
-
-SWITCH_MOD_DECLARE(switch_status) switch_module_runtime(void)
-{
- config_exosip(0);
- return SWITCH_STATUS_TERM;
-}
-
+++ /dev/null
-
-all: $(MOD).so
-
-g711.o: g711.c g711.h
- $(CC) -c -O2 -pthread -DLINUX=2 -D_REENTRANT -D_GNU_SOURCE -D_LARGEFILE64_SOURCE g711.c -o g711.o
-
-$(MOD).so: $(MOD).c g711.o
- $(CC) $(CFLAGS) -fPIC -c $(MOD).c -o $(MOD).o
- $(CC) $(SOLINK) g711.o $(MOD).o -o $(MOD).so $(LDFLAGS)
-
-
-
-clean:
- rm -fr *.so *.o *~
-
+++ /dev/null
-/*
- * This source code is a product of Sun Microsystems, Inc. and is provided
- * for unrestricted use. Users may copy or modify this source code without
- * charge.
- *
- * SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING
- * THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
- *
- * Sun source code is provided with no support and without any obligation on
- * the part of Sun Microsystems, Inc. to assist in its use, correction,
- * modification or enhancement.
- *
- * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
- * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE
- * OR ANY PART THEREOF.
- *
- * In no event will Sun Microsystems, Inc. be liable for any lost revenue
- * or profits or other special, indirect and consequential damages, even if
- * Sun has been advised of the possibility of such damages.
- *
- * Sun Microsystems, Inc.
- * 2550 Garcia Avenue
- * Mountain View, California 94043
- */
-/*
- * December 30, 1994:
- * Functions linear2alaw, linear2ulaw have been updated to correctly
- * convert unquantized 16 bit values.
- * Tables for direct u- to A-law and A- to u-law conversions have been
- * corrected.
- * Borge Lindberg, Center for PersonKommunikation, Aalborg University.
- * bli@cpk.auc.dk
- *
- */
-/*
- * Downloaded from comp.speech site in Cambridge.
- *
- */
-
-#include "g711.h"
-
-/*
- * g711.c
- *
- * u-law, A-law and linear PCM conversions.
- */
-#define SIGN_BIT (0x80) /* Sign bit for a A-law byte. */
-#define QUANT_MASK (0xf) /* Quantization field mask. */
-#define NSEGS (8) /* Number of A-law segments. */
-#define SEG_SHIFT (4) /* Left shift for segment number. */
-#define SEG_MASK (0x70) /* Segment field mask. */
-
-static short seg_aend[8] = {0x1F, 0x3F, 0x7F, 0xFF,
- 0x1FF, 0x3FF, 0x7FF, 0xFFF};
-static short seg_uend[8] = {0x3F, 0x7F, 0xFF, 0x1FF,
- 0x3FF, 0x7FF, 0xFFF, 0x1FFF};
-
-/* copy from CCITT G.711 specifications */
-unsigned char _u2a[128] = { /* u- to A-law conversions */
- 1, 1, 2, 2, 3, 3, 4, 4,
- 5, 5, 6, 6, 7, 7, 8, 8,
- 9, 10, 11, 12, 13, 14, 15, 16,
- 17, 18, 19, 20, 21, 22, 23, 24,
- 25, 27, 29, 31, 33, 34, 35, 36,
- 37, 38, 39, 40, 41, 42, 43, 44,
- 46, 48, 49, 50, 51, 52, 53, 54,
- 55, 56, 57, 58, 59, 60, 61, 62,
- 64, 65, 66, 67, 68, 69, 70, 71,
- 72, 73, 74, 75, 76, 77, 78, 79,
-/* corrected:
- 81, 82, 83, 84, 85, 86, 87, 88,
- should be: */
- 80, 82, 83, 84, 85, 86, 87, 88,
- 89, 90, 91, 92, 93, 94, 95, 96,
- 97, 98, 99, 100, 101, 102, 103, 104,
- 105, 106, 107, 108, 109, 110, 111, 112,
- 113, 114, 115, 116, 117, 118, 119, 120,
- 121, 122, 123, 124, 125, 126, 127, 128};
-
-unsigned char _a2u[128] = { /* A- to u-law conversions */
- 1, 3, 5, 7, 9, 11, 13, 15,
- 16, 17, 18, 19, 20, 21, 22, 23,
- 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 32, 33, 33, 34, 34, 35, 35,
- 36, 37, 38, 39, 40, 41, 42, 43,
- 44, 45, 46, 47, 48, 48, 49, 49,
- 50, 51, 52, 53, 54, 55, 56, 57,
- 58, 59, 60, 61, 62, 63, 64, 64,
- 65, 66, 67, 68, 69, 70, 71, 72,
-/* corrected:
- 73, 74, 75, 76, 77, 78, 79, 79,
- should be: */
- 73, 74, 75, 76, 77, 78, 79, 80,
- 80, 81, 82, 83, 84, 85, 86, 87,
- 88, 89, 90, 91, 92, 93, 94, 95,
- 96, 97, 98, 99, 100, 101, 102, 103,
- 104, 105, 106, 107, 108, 109, 110, 111,
- 112, 113, 114, 115, 116, 117, 118, 119,
- 120, 121, 122, 123, 124, 125, 126, 127};
-
-static short search(
- short val,
- short *table,
- short size)
-{
- short i;
-
- for (i = 0; i < size; i++) {
- if (val <= *table++)
- return (i);
- }
- return (size);
-}
-
-/*
- * linear2alaw() - Convert a 16-bit linear PCM value to 8-bit A-law
- *
- * linear2alaw() accepts an 16-bit integer and encodes it as A-law data.
- *
- * Linear Input Code Compressed Code
- * ------------------------ ---------------
- * 0000000wxyza 000wxyz
- * 0000001wxyza 001wxyz
- * 000001wxyzab 010wxyz
- * 00001wxyzabc 011wxyz
- * 0001wxyzabcd 100wxyz
- * 001wxyzabcde 101wxyz
- * 01wxyzabcdef 110wxyz
- * 1wxyzabcdefg 111wxyz
- *
- * For further information see John C. Bellamy's Digital Telephony, 1982,
- * John Wiley & Sons, pps 98-111 and 472-476.
- */
-unsigned char
-linear2alaw(short pcm_val) /* 2's complement (16-bit range) */
-{
- short mask;
- short seg;
- unsigned char aval;
-
- pcm_val = pcm_val >> 3;
-
- if (pcm_val >= 0) {
- mask = 0xD5; /* sign (7th) bit = 1 */
- } else {
- mask = 0x55; /* sign bit = 0 */
- pcm_val = -pcm_val - 1;
- }
-
- /* Convert the scaled magnitude to segment number. */
- seg = search(pcm_val, seg_aend, 8);
-
- /* Combine the sign, segment, and quantization bits. */
-
- if (seg >= 8) /* out of range, return maximum value. */
- return (unsigned char) (0x7F ^ mask);
- else {
- aval = (unsigned char) seg << SEG_SHIFT;
- if (seg < 2)
- aval |= (pcm_val >> 1) & QUANT_MASK;
- else
- aval |= (pcm_val >> seg) & QUANT_MASK;
- return (aval ^ mask);
- }
-}
-
-/*
- * alaw2linear() - Convert an A-law value to 16-bit linear PCM
- *
- */
-short
-alaw2linear(
- unsigned char a_val)
-{
- short t;
- short seg;
-
- a_val ^= 0x55;
-
- t = (a_val & QUANT_MASK) << 4;
- seg = ((unsigned)a_val & SEG_MASK) >> SEG_SHIFT;
- switch (seg) {
- case 0:
- t += 8;
- break;
- case 1:
- t += 0x108;
- break;
- default:
- t += 0x108;
- t <<= seg - 1;
- }
- return ((a_val & SIGN_BIT) ? t : -t);
-}
-
-#define BIAS (0x84) /* Bias for linear code. */
-#define CLIP 8159
-
-/*
-* linear2ulaw() - Convert a linear PCM value to u-law
-*
-* In order to simplify the encoding process, the original linear magnitude
-* is biased by adding 33 which shifts the encoding range from (0 - 8158) to
-* (33 - 8191). The result can be seen in the following encoding table:
-*
-* Biased Linear Input Code Compressed Code
-* ------------------------ ---------------
-* 00000001wxyza 000wxyz
-* 0000001wxyzab 001wxyz
-* 000001wxyzabc 010wxyz
-* 00001wxyzabcd 011wxyz
-* 0001wxyzabcde 100wxyz
-* 001wxyzabcdef 101wxyz
-* 01wxyzabcdefg 110wxyz
-* 1wxyzabcdefgh 111wxyz
-*
-* Each biased linear code has a leading 1 which identifies the segment
-* number. The value of the segment number is equal to 7 minus the number
-* of leading 0's. The quantization interval is directly available as the
-* four bits wxyz. * The trailing bits (a - h) are ignored.
-*
-* Ordinarily the complement of the resulting code word is used for
-* transmission, and so the code word is complemented before it is returned.
-*
-* For further information see John C. Bellamy's Digital Telephony, 1982,
-* John Wiley & Sons, pps 98-111 and 472-476.
-*/
-unsigned char
-linear2ulaw(
- short pcm_val) /* 2's complement (16-bit range) */
-{
- short mask;
- short seg;
- unsigned char uval;
-
- /* Get the sign and the magnitude of the value. */
- pcm_val = pcm_val >> 2;
- if (pcm_val < 0) {
- pcm_val = -pcm_val;
- mask = 0x7F;
- } else {
- mask = 0xFF;
- }
- if ( pcm_val > CLIP ) pcm_val = CLIP; /* clip the magnitude */
- pcm_val += (BIAS >> 2);
-
- /* Convert the scaled magnitude to segment number. */
- seg = search(pcm_val, seg_uend, 8);
-
- /*
- * Combine the sign, segment, quantization bits;
- * and complement the code word.
- */
- if (seg >= 8) /* out of range, return maximum value. */
- return (unsigned char) (0x7F ^ mask);
- else {
- uval = (unsigned char) (seg << 4) | ((pcm_val >> (seg + 1)) & 0xF);
- return (uval ^ mask);
- }
-
-}
-
-/*
- * ulaw2linear() - Convert a u-law value to 16-bit linear PCM
- *
- * First, a biased linear code is derived from the code word. An unbiased
- * output can then be obtained by subtracting 33 from the biased code.
- *
- * Note that this function expects to be passed the complement of the
- * original code word. This is in keeping with ISDN conventions.
- */
-short
-ulaw2linear(
- unsigned char u_val)
-{
- short t;
-
- /* Complement to obtain normal u-law value. */
- u_val = ~u_val;
-
- /*
- * Extract and bias the quantization bits. Then
- * shift up by the segment number and subtract out the bias.
- */
- t = ((u_val & QUANT_MASK) << 3) + BIAS;
- t <<= ((unsigned)u_val & SEG_MASK) >> SEG_SHIFT;
-
- return ((u_val & SIGN_BIT) ? (BIAS - t) : (t - BIAS));
-}
-
-/* A-law to u-law conversion */
-unsigned char
-alaw2ulaw(
- unsigned char aval)
-{
- aval &= 0xff;
- return (unsigned char) ((aval & 0x80) ? (0xFF ^ _a2u[aval ^ 0xD5]) :
- (0x7F ^ _a2u[aval ^ 0x55]));
-}
-
-/* u-law to A-law conversion */
-unsigned char
-ulaw2alaw(
- unsigned char uval)
-{
- uval &= 0xff;
- return (unsigned char) ((uval & 0x80) ? (0xD5 ^ (_u2a[0xFF ^ uval] - 1)) :
- (0x55 ^ (_u2a[0x7F ^ uval] - 1)));
-}
-
-/* ---------- end of g711.c ----------------------------------------------------- */
+++ /dev/null
-/*
- * This source code is a product of Sun Microsystems, Inc. and is provided
- * for unrestricted use. Users may copy or modify this source code without
- * charge.
- *
- * SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING
- * THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
- *
- * Sun source code is provided with no support and without any obligation on
- * the part of Sun Microsystems, Inc. to assist in its use, correction,
- * modification or enhancement.
- *
- * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
- * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE
- * OR ANY PART THEREOF.
- *
- * In no event will Sun Microsystems, Inc. be liable for any lost revenue
- * or profits or other special, indirect and consequential damages, even if
- * Sun has been advised of the possibility of such damages.
- *
- * Sun Microsystems, Inc.
- * 2550 Garcia Avenue
- * Mountain View, California 94043
- */
-/*
- * December 30, 1994:
- * Functions linear2alaw, linear2ulaw have been updated to correctly
- * convert unquantized 16 bit values.
- * Tables for direct u- to A-law and A- to u-law conversions have been
- * corrected.
- * Borge Lindberg, Center for PersonKommunikation, Aalborg University.
- * bli@cpk.auc.dk
- *
- */
-/*
- * Downloaded from comp.speech site in Cambridge.
- *
- */
-
-#ifndef _G711_H_
-#define _G711_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-unsigned char linear2alaw(short pcm_val);
-short alaw2linear(unsigned char a_val);
-unsigned char linear2ulaw(short pcm_val);
-short ulaw2linear(unsigned char u_val);
-unsigned char alaw2ulaw(unsigned char aval);
-unsigned char ulaw2alaw(unsigned char uval);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _G711_H_ */
+++ /dev/null
-/*
- * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
- * Copyright (C) 2005/2006, Anthony Minessale II <anthmct@yahoo.com>
- *
- * Version: MPL 1.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
- *
- * The Initial Developer of the Original Code is
- * Anthony Minessale II <anthmct@yahoo.com>
- * Portions created by the Initial Developer are Copyright (C)
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Anthony Minessale II <anthmct@yahoo.com>
- *
- *
- * mod_g711codec.c -- G711 Ulaw/Alaw Codec Module
- *
- */
-#include <switch.h>
-#include "g711.h"
-
-
-static const char modname[] = "mod_g711codec";
-
-
-static switch_status switch_g711u_init(switch_codec *codec, switch_codec_flag flags, const struct switch_codec_settings *codec_settings)
-{
- int encoding, decoding;
-
- encoding = (flags & SWITCH_CODEC_FLAG_ENCODE);
- decoding = (flags & SWITCH_CODEC_FLAG_DECODE);
-
- if (!(encoding || decoding)) {
- return SWITCH_STATUS_FALSE;
- } else {
- return SWITCH_STATUS_SUCCESS;
- }
-}
-
-
-static switch_status switch_g711u_encode(switch_codec *codec,
- switch_codec *other_codec,
- void *decoded_data,
- size_t decoded_data_len,
- int decoded_rate,
- void *encoded_data,
- size_t *encoded_data_len,
- int *encoded_rate,
- unsigned int *flag)
-{
- short *dbuf;
- unsigned char *ebuf;
- size_t i;
-
- dbuf = decoded_data;
- ebuf = encoded_data;
-
- for (i = 0; i < decoded_data_len / sizeof(short); i++) {
- ebuf[i] = linear2ulaw(dbuf[i]);
- }
-
- *encoded_data_len = i;
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-static switch_status switch_g711u_decode(switch_codec *codec,
- switch_codec *other_codec,
- void *encoded_data,
- size_t encoded_data_len,
- int encoded_rate,
- void *decoded_data,
- size_t *decoded_data_len,
- int *decoded_rate,
- unsigned int *flag)
-{
- short *dbuf;
- unsigned char *ebuf;
- size_t i;
-
- dbuf = decoded_data;
- ebuf = encoded_data;
-
- if (*flag & SWITCH_CODEC_FLAG_SILENCE) {
- memset(dbuf, 0, codec->implementation->bytes_per_frame);
- *decoded_data_len = codec->implementation->bytes_per_frame;
- } else {
- for (i = 0; i < encoded_data_len; i++) {
- dbuf[i] = ulaw2linear(ebuf[i]);
- }
-
- *decoded_data_len = i * 2;
- }
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-static switch_status switch_g711u_destroy(switch_codec *codec)
-{
- return SWITCH_STATUS_SUCCESS;
-}
-
-
-static switch_status switch_g711a_init(switch_codec *codec, switch_codec_flag flags, const struct switch_codec_settings *codec_settings)
-{
- int encoding, decoding;
-
- encoding = (flags & SWITCH_CODEC_FLAG_ENCODE);
- decoding = (flags & SWITCH_CODEC_FLAG_DECODE);
-
- if (!(encoding || decoding)) {
- return SWITCH_STATUS_FALSE;
- } else {
- return SWITCH_STATUS_SUCCESS;
- }
-}
-
-
-static switch_status switch_g711a_encode(switch_codec *codec,
- switch_codec *other_codec,
- void *decoded_data,
- size_t decoded_data_len,
- int decoded_rate,
- void *encoded_data,
- size_t *encoded_data_len,
- int *encoded_rate,
- unsigned int *flag)
-{
- short *dbuf;
- unsigned char *ebuf;
- size_t i;
-
- dbuf = decoded_data;
- ebuf = encoded_data;
-
- for (i = 0; i < decoded_data_len / sizeof(short); i++) {
- ebuf[i] = linear2alaw(dbuf[i]);
- }
-
- *encoded_data_len = i;
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-static switch_status switch_g711a_decode(switch_codec *codec,
- switch_codec *other_codec,
- void *encoded_data,
- size_t encoded_data_len,
- int encoded_rate,
- void *decoded_data,
- size_t *decoded_data_len,
- int *decoded_rate,
- unsigned int *flag)
-{
- short *dbuf;
- unsigned char *ebuf;
- size_t i;
-
- dbuf = decoded_data;
- ebuf = encoded_data;
-
- if (*flag & SWITCH_CODEC_FLAG_SILENCE) {
- memset(dbuf, 0, codec->implementation->bytes_per_frame);
- *decoded_data_len = codec->implementation->bytes_per_frame;
- } else {
- for (i = 0; i < encoded_data_len; i++) {
- dbuf[i] = alaw2linear(ebuf[i]);
- }
-
- *decoded_data_len = i * 2;
- }
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-static switch_status switch_g711a_destroy(switch_codec *codec)
-{
- return SWITCH_STATUS_SUCCESS;
-}
-
-/* Registration */
-
-
-static const switch_codec_implementation g711u_8k_60ms_implementation = {
- /*.samples_per_second*/ 8000,
- /*.bits_per_second*/ 19200,
- /*.microseconds_per_frame*/ 60000,
- /*.samples_per_frame*/ 480,
- /*.bytes_per_frame*/ 960,
- /*.encoded_bytes_per_frame*/ 480,
- /*.number_of_channels*/ 1,
- /*.pref_frames_per_packet*/ 1,
- /*.max_frames_per_packet*/ 1,
- /*.init*/ switch_g711u_init,
- /*.encode*/ switch_g711u_encode,
- /*.decode*/ switch_g711u_decode,
- /*.destroy*/ switch_g711u_destroy
-};
-
-static const switch_codec_implementation g711u_8k_30ms_implementation = {
- /*.samples_per_second*/ 8000,
- /*.bits_per_second*/ 96000,
- /*.microseconds_per_frame*/ 30000,
- /*.samples_per_frame*/ 240,
- /*.bytes_per_frame*/ 480,
- /*.encoded_bytes_per_frame*/ 240,
- /*.number_of_channels*/ 1,
- /*.pref_frames_per_packet*/ 1,
- /*.max_frames_per_packet*/ 1,
- /*.init*/ switch_g711u_init,
- /*.encode*/ switch_g711u_encode,
- /*.decode*/ switch_g711u_decode,
- /*.destroy*/ switch_g711u_destroy,
- /*.next*/ &g711u_8k_60ms_implementation
-};
-
-static const switch_codec_implementation g711u_8k_implementation = {
- /*.samples_per_second*/ 8000,
- /*.bits_per_second*/ 64000,
- /*.microseconds_per_frame*/ 20000,
- /*.samples_per_frame*/ 160,
- /*.bytes_per_frame*/ 320,
- /*.encoded_bytes_per_frame*/ 160,
- /*.number_of_channels*/ 1,
- /*.pref_frames_per_packet*/ 1,
- /*.max_frames_per_packet*/ 1,
- /*.init*/ switch_g711u_init,
- /*.encode*/ switch_g711u_encode,
- /*.decode*/ switch_g711u_decode,
- /*.destroy*/ switch_g711u_destroy,
- ///*.next*/ &g711u_8k_30ms_implementation
-};
-
-
-static const switch_codec_implementation g711a_8k_implementation = {
- /*.samples_per_second*/ 8000,
- /*.bits_per_second*/ 64000,
- /*.microseconds_per_frame*/ 20000,
- /*.samples_per_frame*/ 160,
- /*.bytes_per_frame*/ 320,
- /*.encoded_bytes_per_frame*/ 160,
- /*.number_of_channels*/ 1,
- /*.pref_frames_per_packet*/ 1,
- /*.max_frames_per_packet*/ 1,
- /*.init*/ switch_g711a_init,
- /*.encode*/ switch_g711a_encode,
- /*.decode*/ switch_g711a_decode,
- /*.destroy*/ switch_g711a_destroy
-};
-
-
-static const switch_codec_interface g711a_codec_interface = {
- /*.interface_name*/ "g711 alaw",
- /*.codec_type*/ SWITCH_CODEC_TYPE_AUDIO,
- /*.ianacode*/ 8,
- /*.iananame*/ "PCMA",
- /*.implementations*/ &g711a_8k_implementation
-};
-
-static const switch_codec_interface g711u_codec_interface = {
- /*.interface_name*/ "g711 ulaw",
- /*.codec_type*/ SWITCH_CODEC_TYPE_AUDIO,
- /*.ianacode*/ 0,
- /*.iananame*/ "PCMU",
- /*.implementations*/ &g711u_8k_implementation,
- /*.next*/ &g711a_codec_interface
-};
-
-static switch_loadable_module_interface g711_module_interface = {
- /*.module_name*/ modname,
- /*.endpoint_interface*/ NULL,
- /*.timer_interface*/ NULL,
- /*.dialplan_interface*/ NULL,
- /*.codec_interface*/ &g711u_codec_interface,
- /*.application_interface*/ NULL
-};
-
-
-SWITCH_MOD_DECLARE(switch_status) switch_module_load(const switch_loadable_module_interface **interface, char *filename) {
- /* connect my internal structure to the blank pointer passed to me */
- *interface = &g711_module_interface;
-
- /* indicate that the module should continue to be loaded */
- return SWITCH_STATUS_SUCCESS;
-}
-
-
-
-
-
+++ /dev/null
-<?xml version="1.0" encoding="Windows-1252"?>\r
-<VisualStudioProject\r
- ProjectType="Visual C++"\r
- Version="8.00"\r
- Name="mod_g711codec"\r
- ProjectGUID="{B1FE4613-3F4B-4DAF-9714-2472BF8F56AE}"\r
- RootNamespace="mod_g711codec"\r
- Keyword="Win32Proj"\r
- >\r
- <Platforms>\r
- <Platform\r
- Name="Win32"\r
- />\r
- </Platforms>\r
- <ToolFiles>\r
- </ToolFiles>\r
- <Configurations>\r
- <Configuration\r
- Name="Debug|Win32"\r
- OutputDirectory="Debug"\r
- IntermediateDirectory="Debug"\r
- ConfigurationType="2"\r
- InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
- CharacterSet="2"\r
- >\r
- <Tool\r
- Name="VCPreBuildEventTool"\r
- />\r
- <Tool\r
- Name="VCCustomBuildTool"\r
- />\r
- <Tool\r
- Name="VCXMLDataGeneratorTool"\r
- />\r
- <Tool\r
- Name="VCWebServiceProxyGeneratorTool"\r
- />\r
- <Tool\r
- Name="VCMIDLTool"\r
- />\r
- <Tool\r
- Name="VCCLCompilerTool"\r
- Optimization="0"\r
- AdditionalIncludeDirectories=""$(InputDir)..\..\include";"$(InputDir)include";"$(InputDir)..\..\..\libs\include""\r
- PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS"\r
- MinimalRebuild="true"\r
- BasicRuntimeChecks="3"\r
- RuntimeLibrary="1"\r
- UsePrecompiledHeader="0"\r
- WarningLevel="3"\r
- Detect64BitPortabilityProblems="true"\r
- DebugInformationFormat="4"\r
- />\r
- <Tool\r
- Name="VCManagedResourceCompilerTool"\r
- />\r
- <Tool\r
- Name="VCResourceCompilerTool"\r
- />\r
- <Tool\r
- Name="VCPreLinkEventTool"\r
- />\r
- <Tool\r
- Name="VCLinkerTool"\r
- OutputFile="..\..\..\w32\vsnet\$(OutDir)/mod/mod_g711codec.dll"\r
- LinkIncremental="2"\r
- AdditionalLibraryDirectories="$(InputDir)..\..\libs\apr\Debug"\r
- GenerateDebugInformation="true"\r
- ProgramDatabaseFile="$(OutDir)/mod_g711codec.pdb"\r
- SubSystem="2"\r
- ImportLibrary="$(OutDir)/mod_g711codec.lib"\r
- TargetMachine="1"\r
- />\r
- <Tool\r
- Name="VCALinkTool"\r
- />\r
- <Tool\r
- Name="VCManifestTool"\r
- />\r
- <Tool\r
- Name="VCXDCMakeTool"\r
- />\r
- <Tool\r
- Name="VCBscMakeTool"\r
- />\r
- <Tool\r
- Name="VCFxCopTool"\r
- />\r
- <Tool\r
- Name="VCAppVerifierTool"\r
- />\r
- <Tool\r
- Name="VCWebDeploymentTool"\r
- />\r
- <Tool\r
- Name="VCPostBuildEventTool"\r
- />\r
- </Configuration>\r
- <Configuration\r
- Name="Release|Win32"\r
- OutputDirectory="Release"\r
- IntermediateDirectory="Release"\r
- ConfigurationType="2"\r
- InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
- CharacterSet="2"\r
- >\r
- <Tool\r
- Name="VCPreBuildEventTool"\r
- />\r
- <Tool\r
- Name="VCCustomBuildTool"\r
- />\r
- <Tool\r
- Name="VCXMLDataGeneratorTool"\r
- />\r
- <Tool\r
- Name="VCWebServiceProxyGeneratorTool"\r
- />\r
- <Tool\r
- Name="VCMIDLTool"\r
- />\r
- <Tool\r
- Name="VCCLCompilerTool"\r
- AdditionalIncludeDirectories=""$(InputDir)..\..\include";"$(InputDir)include";"$(InputDir)..\..\..\libs\include""\r
- PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS"\r
- RuntimeLibrary="0"\r
- UsePrecompiledHeader="0"\r
- WarningLevel="3"\r
- Detect64BitPortabilityProblems="true"\r
- DebugInformationFormat="3"\r
- />\r
- <Tool\r
- Name="VCManagedResourceCompilerTool"\r
- />\r
- <Tool\r
- Name="VCResourceCompilerTool"\r
- />\r
- <Tool\r
- Name="VCPreLinkEventTool"\r
- />\r
- <Tool\r
- Name="VCLinkerTool"\r
- OutputFile="..\..\..\w32\vsnet\$(OutDir)/mod/mod_g711codec.dll"\r
- LinkIncremental="1"\r
- AdditionalLibraryDirectories=""$(InputDir)..\..\libs\apr\Release""\r
- GenerateDebugInformation="true"\r
- SubSystem="2"\r
- OptimizeReferences="2"\r
- EnableCOMDATFolding="2"\r
- ImportLibrary="$(OutDir)/mod_g711codec.lib"\r
- TargetMachine="1"\r
- />\r
- <Tool\r
- Name="VCALinkTool"\r
- />\r
- <Tool\r
- Name="VCManifestTool"\r
- />\r
- <Tool\r
- Name="VCXDCMakeTool"\r
- />\r
- <Tool\r
- Name="VCBscMakeTool"\r
- />\r
- <Tool\r
- Name="VCFxCopTool"\r
- />\r
- <Tool\r
- Name="VCAppVerifierTool"\r
- />\r
- <Tool\r
- Name="VCWebDeploymentTool"\r
- />\r
- <Tool\r
- Name="VCPostBuildEventTool"\r
- />\r
- </Configuration>\r
- </Configurations>\r
- <References>\r
- </References>\r
- <Files>\r
- <Filter\r
- Name="Source Files"\r
- Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"\r
- UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"\r
- >\r
- <File\r
- RelativePath=".\g711.c"\r
- >\r
- </File>\r
- <File\r
- RelativePath=".\mod_g711codec.c"\r
- >\r
- </File>\r
- </Filter>\r
- <Filter\r
- Name="Header Files"\r
- Filter="h;hpp;hxx;hm;inl;inc;xsd"\r
- UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"\r
- >\r
- <File\r
- RelativePath=".\g711.h"\r
- >\r
- </File>\r
- </Filter>\r
- <Filter\r
- Name="Resource Files"\r
- Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"\r
- UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"\r
- >\r
- </Filter>\r
- </Files>\r
- <Globals>\r
- </Globals>\r
-</VisualStudioProject>\r
+++ /dev/null
-LDFLAGS += -liax -L/usr/local/lib
-
-all: depends $(MOD).so
-
-depends:
- $(BASE)/buildlib.sh $(BASE) install iax --enable-newjb --prefix=$(PREFIX)
-
-$(MOD).so: $(MOD).c
- $(CC) $(CFLAGS) -fPIC -c $(MOD).c -o $(MOD).o
- $(CC) $(SOLINK) -o $(MOD).so $(MOD).o $(LDFLAGS)
-
-
-clean:
- rm -fr *.so *.o *~
-
+++ /dev/null
-<?xml version="1.0" encoding="Windows-1252"?>\r
-<VisualStudioProject\r
- ProjectType="Visual C++"\r
- Version="8.00"\r
- Name="mod_IaxChan"\r
- ProjectGUID="{3A5B9131-F20C-4A85-9447-6C1610941CEE}"\r
- RootNamespace="mod_IaxChan"\r
- Keyword="Win32Proj"\r
- >\r
- <Platforms>\r
- <Platform\r
- Name="Win32"\r
- />\r
- </Platforms>\r
- <ToolFiles>\r
- </ToolFiles>\r
- <Configurations>\r
- <Configuration\r
- Name="Debug|Win32"\r
- OutputDirectory="Debug"\r
- IntermediateDirectory="Debug"\r
- ConfigurationType="2"\r
- InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
- CharacterSet="2"\r
- >\r
- <Tool\r
- Name="VCPreBuildEventTool"\r
- CommandLine="cscript /nologo $(InputDir)..\..\..\w32\vsnet\getlibs.vbs Mod_IaxChan Debug"\r
- />\r
- <Tool\r
- Name="VCCustomBuildTool"\r
- />\r
- <Tool\r
- Name="VCXMLDataGeneratorTool"\r
- />\r
- <Tool\r
- Name="VCWebServiceProxyGeneratorTool"\r
- />\r
- <Tool\r
- Name="VCMIDLTool"\r
- />\r
- <Tool\r
- Name="VCCLCompilerTool"\r
- Optimization="0"\r
- AdditionalIncludeDirectories=""$(InputDir)..\..\include";"$(InputDir)include";"$(InputDir)..\..\..\libs\include";"$(InputDir)..\..\..\libs\iax\src""\r
- PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS"\r
- MinimalRebuild="true"\r
- BasicRuntimeChecks="3"\r
- RuntimeLibrary="3"\r
- UsePrecompiledHeader="0"\r
- WarningLevel="3"\r
- Detect64BitPortabilityProblems="true"\r
- DebugInformationFormat="4"\r
- />\r
- <Tool\r
- Name="VCManagedResourceCompilerTool"\r
- />\r
- <Tool\r
- Name="VCResourceCompilerTool"\r
- />\r
- <Tool\r
- Name="VCPreLinkEventTool"\r
- />\r
- <Tool\r
- Name="VCLinkerTool"\r
- AdditionalDependencies="Ws2_32.lib Iphlpapi.lib libiax2.lib Winmm.lib"\r
- OutputFile="..\..\..\w32\vsnet\$(OutDir)/mod/mod_IaxChan.dll"\r
- LinkIncremental="2"\r
- AdditionalLibraryDirectories="$(InputDir)..\..\..\libs\iax\Debug"\r
- GenerateDebugInformation="true"\r
- ProgramDatabaseFile="$(OutDir)/mod_IaxChan.pdb"\r
- SubSystem="2"\r
- ImportLibrary="$(OutDir)/mod_IaxChan.lib"\r
- TargetMachine="1"\r
- />\r
- <Tool\r
- Name="VCALinkTool"\r
- />\r
- <Tool\r
- Name="VCManifestTool"\r
- />\r
- <Tool\r
- Name="VCXDCMakeTool"\r
- />\r
- <Tool\r
- Name="VCBscMakeTool"\r
- />\r
- <Tool\r
- Name="VCFxCopTool"\r
- />\r
- <Tool\r
- Name="VCAppVerifierTool"\r
- />\r
- <Tool\r
- Name="VCWebDeploymentTool"\r
- />\r
- <Tool\r
- Name="VCPostBuildEventTool"\r
- />\r
- </Configuration>\r
- <Configuration\r
- Name="Release|Win32"\r
- OutputDirectory="Release"\r
- IntermediateDirectory="Release"\r
- ConfigurationType="2"\r
- InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
- CharacterSet="2"\r
- >\r
- <Tool\r
- Name="VCPreBuildEventTool"\r
- CommandLine="cscript /nologo $(InputDir)..\..\..\w32\vsnet\getlibs.vbs Mod_IaxChan Release"\r
- />\r
- <Tool\r
- Name="VCCustomBuildTool"\r
- />\r
- <Tool\r
- Name="VCXMLDataGeneratorTool"\r
- />\r
- <Tool\r
- Name="VCWebServiceProxyGeneratorTool"\r
- />\r
- <Tool\r
- Name="VCMIDLTool"\r
- />\r
- <Tool\r
- Name="VCCLCompilerTool"\r
- AdditionalIncludeDirectories=""$(InputDir)..\..\include";"$(InputDir)include";"$(InputDir)..\..\..\libs\include";"$(InputDir)..\..\..\libs\iax\src""\r
- PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS"\r
- RuntimeLibrary="2"\r
- UsePrecompiledHeader="0"\r
- WarningLevel="3"\r
- Detect64BitPortabilityProblems="true"\r
- DebugInformationFormat="3"\r
- />\r
- <Tool\r
- Name="VCManagedResourceCompilerTool"\r
- />\r
- <Tool\r
- Name="VCResourceCompilerTool"\r
- />\r
- <Tool\r
- Name="VCPreLinkEventTool"\r
- />\r
- <Tool\r
- Name="VCLinkerTool"\r
- AdditionalDependencies="Ws2_32.lib Iphlpapi.lib libiax2.lib Winmm.lib"\r
- OutputFile="..\..\..\w32\vsnet\$(OutDir)/mod/mod_IaxChan.dll"\r
- LinkIncremental="1"\r
- AdditionalLibraryDirectories=""$(InputDir)..\..\..\libs\iax\Release""\r
- GenerateDebugInformation="true"\r
- SubSystem="2"\r
- OptimizeReferences="2"\r
- EnableCOMDATFolding="2"\r
- LinkTimeCodeGeneration="1"\r
- ImportLibrary="$(OutDir)/mod_IaxChan.lib"\r
- TargetMachine="1"\r
- />\r
- <Tool\r
- Name="VCALinkTool"\r
- />\r
- <Tool\r
- Name="VCManifestTool"\r
- />\r
- <Tool\r
- Name="VCXDCMakeTool"\r
- />\r
- <Tool\r
- Name="VCBscMakeTool"\r
- />\r
- <Tool\r
- Name="VCFxCopTool"\r
- />\r
- <Tool\r
- Name="VCAppVerifierTool"\r
- />\r
- <Tool\r
- Name="VCWebDeploymentTool"\r
- />\r
- <Tool\r
- Name="VCPostBuildEventTool"\r
- />\r
- </Configuration>\r
- </Configurations>\r
- <References>\r
- </References>\r
- <Files>\r
- <Filter\r
- Name="Source Files"\r
- Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"\r
- UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"\r
- >\r
- <File\r
- RelativePath=".\mod_iaxchan.c"\r
- >\r
- </File>\r
- </Filter>\r
- <Filter\r
- Name="Header Files"\r
- Filter="h;hpp;hxx;hm;inl;inc;xsd"\r
- UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"\r
- >\r
- </Filter>\r
- <Filter\r
- Name="Resource Files"\r
- Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"\r
- UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"\r
- >\r
- </Filter>\r
- </Files>\r
- <Globals>\r
- </Globals>\r
-</VisualStudioProject>\r
+++ /dev/null
-/*
- * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
- * Copyright (C) 2005/2006, Anthony Minessale II <anthmct@yahoo.com>
- *
- * Version: MPL 1.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
- *
- * The Initial Developer of the Original Code is
- * Anthony Minessale II <anthmct@yahoo.com>
- * Portions created by the Initial Developer are Copyright (C)
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Anthony Minessale II <anthmct@yahoo.com>
- *
- *
- * mod_iaxchan.c -- IAX2 Endpoint Module
- *
- */
-#include <switch.h>
-
-#ifdef WIN32
-#include <iax2.h>
-#include <iax-client.h>
-#include <iax2-parser.h>
-#include <sys/timeb.h>
-#else
-#include <iax/iax2.h>
-#include <iax/iax-client.h>
-#include <iax/iax2-parser.h>
-#endif
-
-static const char modname[] = "mod_iaxchan";
-
-static switch_memory_pool *module_pool;
-static int running = 1;
-
-
-typedef enum {
- TFLAG_IO = (1 << 0),
- TFLAG_INBOUND = (1 << 1),
- TFLAG_OUTBOUND = (1 << 2),
- TFLAG_DTMF = (1 << 3),
- TFLAG_VOICE = (1 << 4),
- TFLAG_HANGUP = (1 << 5),
- TFLAG_LINEAR = (1 << 6)
-} TFLAGS;
-
-typedef enum {
- GFLAG_MY_CODEC_PREFS = (1 << 0)
-} GFLAGS;
-
-static struct {
- int debug;
- int port;
- char *dialplan;
- char *codec_string;
- char *codec_order[SWITCH_MAX_CODECS];
- int codec_order_last;
- unsigned int flags;
-} globals;
-
-struct private_object {
- unsigned int flags;
- switch_codec read_codec;
- switch_codec write_codec;
- struct switch_frame read_frame;
- unsigned char databuf[1024];
- switch_core_session *session;
- struct iax_session *iax_session;
- switch_caller_profile *caller_profile;
- unsigned int codec;
- unsigned int codecs;
- switch_mutex_t *mutex;
- switch_thread_cond_t *cond;
-};
-
-SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_dialplan, globals.dialplan)
-SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_codec_string, globals.codec_string)
-
-
-static char *IAXNAMES[] = {"IAX_EVENT_CONNECT","IAX_EVENT_ACCEPT","IAX_EVENT_HANGUP","IAX_EVENT_REJECT","IAX_EVENT_VOICE",
- "IAX_EVENT_DTMF","IAX_EVENT_TIMEOUT","IAX_EVENT_LAGRQ","IAX_EVENT_LAGRP","IAX_EVENT_RINGA",
- "IAX_EVENT_PING","IAX_EVENT_PONG","IAX_EVENT_BUSY","IAX_EVENT_ANSWER","IAX_EVENT_IMAGE",
- "IAX_EVENT_AUTHRQ","IAX_EVENT_AUTHRP","IAX_EVENT_REGREQ","IAX_EVENT_REGACK",
- "IAX_EVENT_URL","IAX_EVENT_LDCOMPLETE","IAX_EVENT_TRANSFER","IAX_EVENT_DPREQ",
- "IAX_EVENT_DPREP","IAX_EVENT_DIAL","IAX_EVENT_QUELCH","IAX_EVENT_UNQUELCH",
- "IAX_EVENT_UNLINK","IAX_EVENT_LINKREJECT","IAX_EVENT_TEXT","IAX_EVENT_REGREJ",
- "IAX_EVENT_LINKURL","IAX_EVENT_CNG","IAX_EVENT_REREQUEST","IAX_EVENT_TXREPLY",
- "IAX_EVENT_TXREJECT","IAX_EVENT_TXACCEPT","IAX_EVENT_TXREADY"};
-
-
-struct ast_iana {
- const unsigned int ast;
- const int iana;
- char *name;
-};
-
-//999 means it's wrong nad i dont know the real one
-static struct ast_iana AST_IANA[] =
- {{AST_FORMAT_G723_1, 4, "g723.1"},
- {AST_FORMAT_GSM, 3, "gsm"},
- {AST_FORMAT_ULAW, 0, "ulaw"},
- {AST_FORMAT_ALAW, 8, "alaw"},
- {AST_FORMAT_G726, 999, "g726"},
- {AST_FORMAT_ADPCM, 999, "adpcm"},
- {AST_FORMAT_SLINEAR, 10, "slinear"},
- {AST_FORMAT_LPC10, 7, "lpc10"},
- {AST_FORMAT_G729A, 18, "g729"},
- {AST_FORMAT_SPEEX, 98, "speex"},
- {AST_FORMAT_ILBC, 999, "ilbc"},
- {AST_FORMAT_MAX_AUDIO, 999, ""},
- {AST_FORMAT_JPEG, 999, ""},
- {AST_FORMAT_PNG, 999, ""},
- {AST_FORMAT_H261, 999, ""},
- {AST_FORMAT_H263, 999, ""},
- {AST_FORMAT_MAX_VIDEO, 999, ""},
- {0,0}
- };
-
-static char *ast2str(unsigned int ast)
-{
- int x;
- for(x = 0; x < 32; x++) {
- if ((1 << x) == ast) {
- return AST_IANA[x].name;
- }
- }
- return "";
-}
-
-static unsigned int iana2ast(int iana)
-{
- int x = 0;
- unsigned int ast = 0;
-
- for(x = 0; AST_IANA[x].ast; x++) {
- if (AST_IANA[x].iana == iana) {
- ast = AST_IANA[x].ast;
- break;
- }
- }
-
- return ast;
-}
-
-typedef enum {
- IAX_SET = 1,
- IAX_QUERY = 2
-} iax_io_t;
-
-static switch_status iax_set_codec(struct private_object *tech_pvt, struct iax_session *iax_session, unsigned int *format, unsigned int *cababilities, iax_io_t io)
-{
- char *dname = NULL;
- //int rate = 8000;
- //int codec_ms = 20;
- switch_channel *channel;
- switch_codec_interface *codecs[SWITCH_MAX_CODECS];
- int num_codecs = 0;
- unsigned int local_cap = 0, mixed_cap = 0, chosen = 0, leading = 0;
- int x;
-
- if (globals.codec_string) {
- if (!(num_codecs = loadable_module_get_codecs_sorted(switch_core_session_get_pool(tech_pvt->session),
- codecs,
- SWITCH_MAX_CODECS,
- globals.codec_order,
- globals.codec_order_last)) > 0) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "NO codecs?\n");
- return SWITCH_STATUS_GENERR;
- }
- } else if (!(num_codecs = loadable_module_get_codecs(switch_core_session_get_pool(tech_pvt->session), codecs, SWITCH_MAX_CODECS)) > 0) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "NO codecs?\n");
- return SWITCH_STATUS_GENERR;
- }
-
- for (x = 0; x < num_codecs; x++) {
- unsigned int codec = iana2ast(codecs[x]->ianacode);
- if (io == IAX_QUERY) {
- iax_pref_codec_add(iax_session, codec);
- }
- local_cap |= codec;
- }
-
- if (io == IAX_SET) {
- mixed_cap = (local_cap & *cababilities);
- } else {
- mixed_cap = local_cap;
- }
-
- leading = iana2ast(codecs[0]->ianacode);
- if (io == IAX_QUERY) {
- chosen = leading;
- *format = chosen;
- *cababilities = local_cap;
- return SWITCH_STATUS_SUCCESS;
- } else if (switch_test_flag(&globals, GFLAG_MY_CODEC_PREFS) && (leading & mixed_cap)) {
- chosen = leading;
- dname = codecs[0]->iananame;
- } else {
- unsigned int prefs[32];
- int len = 0;
-
- if (!switch_test_flag(&globals, GFLAG_MY_CODEC_PREFS)) {
- len = iax_pref_codec_get(iax_session, prefs, sizeof(prefs));
- }
-
- if (len) { /*they sent us a pref and we don't want to be codec master*/
- char pref_str[256] = "(";
-
- for (x = 0; x < len; x++) {
- strncat(pref_str, ast2str(prefs[x]), sizeof(pref_str));
- strncat(pref_str, x == len - 1 ? ")" : ",", sizeof(pref_str));
- }
-
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Codec Prefs Detected: %s\n", pref_str);
-
- for (x = 0; x < len; x++) {
- if ((prefs[x] & mixed_cap)) {
- int z;
- chosen = prefs[x];
- for (z = 0; z < num_codecs; z++) {
- if (prefs[x] == iana2ast(codecs[z]->ianacode)) {
- dname = codecs[z]->iananame;
- }
- }
- break;
- }
- }
- } else {
- if (*format & mixed_cap) { /* is the one we asked for here? */
- chosen = *format;
- for (x = 0; x < num_codecs; x++) {
- unsigned int cap = iana2ast(codecs[x]->ianacode);
- if (cap == chosen) {
- dname = codecs[x]->iananame;
- }
- }
- } else { /* c'mon there has to be SOMETHING...*/
- for (x = 0; x < num_codecs; x++) {
- unsigned int cap = iana2ast(codecs[x]->ianacode);
- if (cap & mixed_cap) {
- chosen = cap;
- dname = codecs[x]->iananame;
- }
- }
- }
- }
- }
-
- if (!dname && !chosen) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "NO codecs?\n");
- return SWITCH_STATUS_GENERR;
- }
-
- channel = switch_core_session_get_channel(tech_pvt->session);
- assert(channel != NULL);
-
- if (!strcasecmp(dname, "l16")) {
- switch_set_flag(tech_pvt, TFLAG_LINEAR);
- }
- if (switch_core_codec_init(&tech_pvt->read_codec,
- dname,
- 0,
- 0,
- 1,
- SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
- NULL,
- switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Can't load codec?\n");
- return SWITCH_STATUS_GENERR;
- } else {
- if (switch_core_codec_init(&tech_pvt->write_codec,
- dname,
- 0,
- 0,
- 1,
- SWITCH_CODEC_FLAG_ENCODE |SWITCH_CODEC_FLAG_DECODE,
- NULL,
- switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Can't load codec?\n");
- switch_core_codec_destroy(&tech_pvt->read_codec);
- return SWITCH_STATUS_GENERR;
- } else {
- int ms;
- int rate;
- ms = tech_pvt->write_codec.implementation->microseconds_per_frame / 1000;
- rate = tech_pvt->write_codec.implementation->samples_per_second;
- tech_pvt->read_frame.rate = rate;
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Activate Codec %s/%d %d ms\n", dname, rate, ms);
- tech_pvt->read_frame.codec = &tech_pvt->read_codec;
- switch_core_session_set_read_codec(tech_pvt->session, &tech_pvt->read_codec);
- switch_core_session_set_write_codec(tech_pvt->session, &tech_pvt->write_codec);
- }
- tech_pvt->codec = chosen;
- tech_pvt->codecs = local_cap;
- }
-
- if (io == IAX_QUERY) {
- *format = tech_pvt->codec;
- *cababilities = local_cap;
- }
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-
-static const switch_endpoint_interface channel_endpoint_interface;
-
-static switch_status channel_on_init(switch_core_session *session);
-static switch_status channel_on_hangup(switch_core_session *session);
-static switch_status channel_on_ring(switch_core_session *session);
-static switch_status channel_on_loopback(switch_core_session *session);
-static switch_status channel_on_transmit(switch_core_session *session);
-static switch_status channel_outgoing_channel(switch_core_session *session, switch_caller_profile *outbound_profile, switch_core_session **new_session);
-static switch_status channel_read_frame(switch_core_session *session, switch_frame **frame, int timeout, switch_io_flag flags);
-static switch_status channel_write_frame(switch_core_session *session, switch_frame *frame, int timeout, switch_io_flag flags);
-static switch_status channel_kill_channel(switch_core_session *session, int sig);
-
-
-static void iax_err_cb(const char *s)
-{
- switch_console_printf(SWITCH_CHANNEL_CONSOLE_CLEAN, "IAX ERR: %s", s);
-}
-
-static void iax_out_cb(const char *s)
-{
- if (globals.debug) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE_CLEAN, "IAX INFO: %s", s);
- }
-}
-
-
-/*
-State methods they get called when the state changes to the specific state
-returning SWITCH_STATUS_SUCCESS tells the core to execute the standard state method next
-so if you fully implement the state you can return SWITCH_STATUS_FALSE to skip it.
-*/
-static switch_status channel_on_init(switch_core_session *session)
-{
- switch_channel *channel;
- struct private_object *tech_pvt = NULL;
-
- tech_pvt = switch_core_session_get_private(session);
- assert(tech_pvt != NULL);
-
- channel = switch_core_session_get_channel(session);
- assert(channel != NULL);
-
- tech_pvt->read_frame.data = tech_pvt->databuf;
- tech_pvt->read_frame.buflen = sizeof(tech_pvt->databuf);
- iax_set_private(tech_pvt->iax_session, tech_pvt);
-
- switch_set_flag(tech_pvt, TFLAG_IO);
-
- switch_mutex_init(&tech_pvt->mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session));
- switch_thread_cond_create(&tech_pvt->cond, switch_core_session_get_pool(session));
- switch_mutex_lock(tech_pvt->mutex);
-
- /* Move Channel's State Machine to RING */
- switch_channel_set_state(channel, CS_RING);
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-static switch_status channel_on_ring(switch_core_session *session)
-{
- switch_channel *channel = NULL;
- struct private_object *tech_pvt = NULL;
-
- channel = switch_core_session_get_channel(session);
- assert(channel != NULL);
-
- tech_pvt = switch_core_session_get_private(session);
- assert(tech_pvt != NULL);
-
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "%s CHANNEL RING\n", switch_channel_get_name(channel));
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-static switch_status channel_on_execute(switch_core_session *session)
-{
-
- switch_channel *channel = NULL;
- struct private_object *tech_pvt = NULL;
-
- channel = switch_core_session_get_channel(session);
- assert(channel != NULL);
-
- tech_pvt = switch_core_session_get_private(session);
- assert(tech_pvt != NULL);
-
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "%s CHANNEL EXECUTE\n", switch_channel_get_name(channel));
-
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-static switch_status channel_on_hangup(switch_core_session *session)
-{
- switch_channel *channel = NULL;
- struct private_object *tech_pvt = NULL;
-
- channel = switch_core_session_get_channel(session);
- assert(channel != NULL);
-
- tech_pvt = switch_core_session_get_private(session);
- assert(tech_pvt != NULL);
-
- switch_clear_flag(tech_pvt, TFLAG_IO);
- switch_thread_cond_signal(tech_pvt->cond);
-
- switch_core_codec_destroy(&tech_pvt->read_codec);
- switch_core_codec_destroy(&tech_pvt->write_codec);
-
- if (tech_pvt->iax_session) {
- if (!switch_test_flag(tech_pvt, TFLAG_HANGUP)) {
- iax_hangup(tech_pvt->iax_session, "Hangup");
- switch_set_flag(tech_pvt, TFLAG_HANGUP);
- }
- iax_session_destroy(&tech_pvt->iax_session);
- }
-
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "%s CHANNEL HANGUP\n", switch_channel_get_name(channel));
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-static switch_status channel_kill_channel(switch_core_session *session, int sig)
-{
- switch_channel *channel = NULL;
- struct private_object *tech_pvt = NULL;
-
- channel = switch_core_session_get_channel(session);
- assert(channel != NULL);
-
- tech_pvt = switch_core_session_get_private(session);
- assert(tech_pvt != NULL);
-
- switch_clear_flag(tech_pvt, TFLAG_IO);
- switch_clear_flag(tech_pvt, TFLAG_VOICE);
- switch_channel_hangup(channel);
- switch_thread_cond_signal(tech_pvt->cond);
-
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "%s CHANNEL KILL\n", switch_channel_get_name(channel));
-
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-static switch_status channel_on_loopback(switch_core_session *session)
-{
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "CHANNEL LOOPBACK\n");
- return SWITCH_STATUS_SUCCESS;
-}
-
-static switch_status channel_on_transmit(switch_core_session *session)
-{
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "CHANNEL TRANSMIT\n");
- return SWITCH_STATUS_SUCCESS;
-}
-
-
-/* Make sure when you have 2 sessions in the same scope that you pass the appropriate one to the routines
-that allocate memory or you will have 1 channel with memory allocated from another channel's pool!
-*/
-static switch_status channel_outgoing_channel(switch_core_session *session, switch_caller_profile *outbound_profile, switch_core_session **new_session)
-{
- if ((*new_session = switch_core_session_request(&channel_endpoint_interface, NULL))) {
- struct private_object *tech_pvt;
- switch_channel *channel;
- switch_caller_profile *caller_profile;
- unsigned int req = 0, cap = 0;
-
- if ((tech_pvt = (struct private_object *) switch_core_session_alloc(*new_session, sizeof(struct private_object)))) {
- memset(tech_pvt, 0, sizeof(*tech_pvt));
- channel = switch_core_session_get_channel(*new_session);
- switch_core_session_set_private(*new_session, tech_pvt);
- tech_pvt->session = *new_session;
- } else {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Hey where is my memory pool?\n");
- switch_core_session_destroy(new_session);
- return SWITCH_STATUS_GENERR;
- }
-
- if (outbound_profile) {
- char name[128];
- caller_profile = switch_caller_profile_clone(*new_session, outbound_profile);
- switch_channel_set_caller_profile(channel, caller_profile);
- tech_pvt->caller_profile = caller_profile;
- snprintf(name, sizeof(name), "IAX/%s-%04x", caller_profile->destination_number, rand() & 0xffff);
- switch_channel_set_name(channel, name);
- } else {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Doh! no caller profile\n");
- switch_core_session_destroy(new_session);
- return SWITCH_STATUS_GENERR;
- }
-
- if (!(tech_pvt->iax_session = iax_session_new())) {
- switch_core_session_destroy(new_session);
- return SWITCH_STATUS_GENERR;
- }
-
-
- if (iax_set_codec(tech_pvt, tech_pvt->iax_session, &req, &cap, IAX_QUERY) != SWITCH_STATUS_SUCCESS) {
- switch_core_session_destroy(new_session);
- return SWITCH_STATUS_GENERR;
- }
-
-
-
- iax_call(tech_pvt->iax_session,
- caller_profile->caller_id_number,
- caller_profile->caller_id_name,
- caller_profile->destination_number,
- NULL, 0, req, cap);
-
- switch_channel_set_flag(channel, CF_OUTBOUND);
- switch_set_flag(tech_pvt, TFLAG_OUTBOUND);
- switch_channel_set_state(channel, CS_INIT);
- return SWITCH_STATUS_SUCCESS;
- }
-
- return SWITCH_STATUS_GENERR;
-
-}
-
-static switch_status channel_waitfor_read(switch_core_session *session, int ms)
-{
- struct private_object *tech_pvt = NULL;
-
- tech_pvt = switch_core_session_get_private(session);
- assert(tech_pvt != NULL);
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-static switch_status channel_waitfor_write(switch_core_session *session, int ms)
-{
- struct private_object *tech_pvt = NULL;
-
- tech_pvt = switch_core_session_get_private(session);
- assert(tech_pvt != NULL);
-
- return SWITCH_STATUS_SUCCESS;
-
-}
-
-static switch_status channel_send_dtmf(switch_core_session *session, char *dtmf)
-{
- struct private_object *tech_pvt = NULL;
- char *digit;
-
- tech_pvt = switch_core_session_get_private(session);
- assert(tech_pvt != NULL);
- if (tech_pvt->iax_session) {
- for(digit = dtmf; *digit; digit++) {
- iax_send_dtmf(tech_pvt->iax_session, *digit);
- }
- }
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-static switch_status channel_read_frame(switch_core_session *session, switch_frame **frame, int timeout, switch_io_flag flags)
-{
- switch_channel *channel = NULL;
- struct private_object *tech_pvt = NULL;
-
- channel = switch_core_session_get_channel(session);
- assert(channel != NULL);
-
- tech_pvt = switch_core_session_get_private(session);
- assert(tech_pvt != NULL);
-
- for(;;) {
- if (switch_test_flag(tech_pvt, TFLAG_IO)) {
- switch_thread_cond_wait(tech_pvt->cond, tech_pvt->mutex);
- if (!switch_test_flag(tech_pvt, TFLAG_IO)) {
- return SWITCH_STATUS_FALSE;
- }
-
- if (switch_test_flag(tech_pvt, TFLAG_IO)) {
- switch_clear_flag(tech_pvt, TFLAG_VOICE);
- if(!tech_pvt->read_frame.datalen) {
- continue;
- }
-
- *frame = &tech_pvt->read_frame;
- return SWITCH_STATUS_SUCCESS;
- }
- }
- break;
- }
- return SWITCH_STATUS_FALSE;
-}
-
-static switch_status channel_write_frame(switch_core_session *session, switch_frame *frame, int timeout, switch_io_flag flags)
-{
- switch_channel *channel = NULL;
- struct private_object *tech_pvt = NULL;
- //switch_frame *pframe;
-
- channel = switch_core_session_get_channel(session);
- assert(channel != NULL);
-
- tech_pvt = switch_core_session_get_private(session);
- assert(tech_pvt != NULL);
-
- if(!switch_test_flag(tech_pvt, TFLAG_IO)) {
- return SWITCH_STATUS_FALSE;
- }
-
-#ifndef BIGENDIAN
- if (switch_test_flag(tech_pvt, TFLAG_LINEAR)) {
- switch_swap_linear(frame->data, (int)frame->datalen / 2);
- }
-#endif
- iax_send_voice(tech_pvt->iax_session, tech_pvt->codec, frame->data, (int)frame->datalen, tech_pvt->write_codec.implementation->samples_per_frame);
-
- return SWITCH_STATUS_SUCCESS;
-
-}
-
-static switch_status channel_answer_channel(switch_core_session *session)
-{
- struct private_object *tech_pvt;
- switch_channel *channel = NULL;
-
- channel = switch_core_session_get_channel(session);
- assert(channel != NULL);
-
- tech_pvt = switch_core_session_get_private(session);
- assert(tech_pvt != NULL);
-
- iax_answer(tech_pvt->iax_session);
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-static const switch_event_handler_table channel_event_handlers = {
- /*.on_init*/ channel_on_init,
- /*.on_ring*/ channel_on_ring,
- /*.on_execute*/ channel_on_execute,
- /*.on_hangup*/ channel_on_hangup,
- /*.on_loopback*/ channel_on_loopback,
- /*.on_transmit*/ channel_on_transmit
-};
-
-static const switch_io_routines channel_io_routines = {
- /*.outgoing_channel*/ channel_outgoing_channel,
- /*.answer_channel*/ channel_answer_channel,
- /*.read_frame*/ channel_read_frame,
- /*.write_frame*/ channel_write_frame,
- /*.kill_channel*/ channel_kill_channel,
- /*.waitfor_read*/ channel_waitfor_read,
- /*.waitfor_write*/ channel_waitfor_write,
- /*.send_dtmf*/ channel_send_dtmf
-};
-
-static const switch_endpoint_interface channel_endpoint_interface = {
- /*.interface_name*/ "iax",
- /*.io_routines*/ &channel_io_routines,
- /*.event_handlers*/ &channel_event_handlers,
- /*.private*/ NULL,
- /*.next*/ NULL
-};
-
-static const switch_loadable_module_interface channel_module_interface = {
- /*.module_name*/ modname,
- /*.endpoint_interface*/ &channel_endpoint_interface,
- /*.timer_interface*/ NULL,
- /*.dialplan_interface*/ NULL,
- /*.codec_interface*/ NULL,
- /*.application_interface*/ NULL
-};
-
-
-SWITCH_MOD_DECLARE(switch_status) switch_module_load(const switch_loadable_module_interface **interface, char *filename) {
-
- if (switch_core_new_memory_pool(&module_pool) != SWITCH_STATUS_SUCCESS) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "OH OH no pool\n");
- return SWITCH_STATUS_TERM;
- }
-
- /* connect my internal structure to the blank pointer passed to me */
- *interface = &channel_module_interface;
-
- /* indicate that the module should continue to be loaded */
- return SWITCH_STATUS_SUCCESS;
-}
-
-#define PHONE_FREED 0
-#define PHONE_CALLACCEPTED 1
-#define PHONE_RINGING 2
-#define PHONE_ANSWERED 3
-#define PHONE_CONNECTED 4
-
-#define UNREGISTERED 0
-#define REGISTERED 1
-
-
-static switch_status load_config(void)
-{
- switch_config cfg;
- char *var, *val;
- char *cf = "iax.conf";
-
- memset(&globals, 0, sizeof(globals));
-
- if (!switch_config_open_file(&cfg, cf)) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "open of %s failed\n", cf);
- return SWITCH_STATUS_TERM;
- }
-
- while (switch_config_next_pair(&cfg, &var, &val)) {
- if (!strcasecmp(cfg.category, "settings")) {
- if (!strcmp(var, "debug")) {
- globals.debug = atoi(val);
- } else if (!strcmp(var, "port")) {
- globals.port = atoi(val);
- } else if (!strcmp(var, "codec_master")) {
- if (!strcasecmp(val, "us")) {
- switch_set_flag(&globals, GFLAG_MY_CODEC_PREFS);
- }
- } else if (!strcmp(var, "dialplan")) {
- set_global_dialplan(val);
- } else if (!strcmp(var, "codec_prefs")) {
- set_global_codec_string(val);
- globals.codec_order_last = switch_separate_string(globals.codec_string, ',', globals.codec_order, SWITCH_MAX_CODECS);
- }
- }
- }
-
- if (!globals.dialplan) {
- set_global_dialplan("default");
- }
- if (!globals.port) {
- globals.port = 4569;
- }
-
- switch_config_close_file(&cfg);
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-
-SWITCH_MOD_DECLARE(switch_status) switch_module_runtime(void)
-{
- int res;
- int netfd;
- int refresh;
- struct iax_event *iaxevent = NULL;
-
- load_config();
-
- if (globals.debug) {
- iax_enable_debug();
- }
- if ((res = iax_init(globals.port) < 0)) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Error Binding Port!\n");
- return SWITCH_STATUS_TERM;
- }
-
- iax_set_error(iax_err_cb);
- iax_set_output(iax_out_cb);
- netfd = iax_get_fd();
-
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "IAX Ready Port %d\n", globals.port);
-
- for(;;) {
-
- if (running == -1) {
- break;
- }
-
- /* Wait for an event.*/
- if ((iaxevent = iax_get_event(0)) == NULL) {
- switch_yield(1000);
- continue;
- } else if (iaxevent) {
- struct private_object *tech_pvt = iax_get_private(iaxevent->session);
-
- if (globals.debug && iaxevent->etype != IAX_EVENT_VOICE) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Event %d [%s]!\n",
- iaxevent->etype, IAXNAMES[iaxevent->etype]);
- }
- switch (iaxevent->etype) {
- case IAX_EVENT_REGACK:
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Registration completed successfully.\n");
- if (iaxevent->ies.refresh) refresh = iaxevent->ies.refresh;
- break;
- case IAX_EVENT_REGREJ:
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Registration failed.\n");
- break;
- case IAX_EVENT_TIMEOUT:
- break;
- case IAX_EVENT_ACCEPT:
- if (tech_pvt) {
- unsigned int cap = iax_session_get_capability(iaxevent->session);
- unsigned int format = iaxevent->ies.format;
-
- if (iax_set_codec(tech_pvt, iaxevent->session, &format, &cap, IAX_SET) != SWITCH_STATUS_SUCCESS) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "WTF? %d %d\n",iaxevent->ies.format, iaxevent->ies.capability);
- }
- }
-
-
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Call accepted.\n");
- break;
- case IAX_EVENT_RINGA:
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Ringing heard.\n");
- break;
- case IAX_EVENT_PONG:
- // informative only
- break;
- case IAX_EVENT_ANSWER:
- // the other side answered our call
- if (tech_pvt) {
- switch_channel *channel;
- if ((channel = switch_core_session_get_channel(tech_pvt->session))) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Answer %s\n", switch_channel_get_name(channel));
- switch_channel_answer(channel);
- }
- }
-
- break;
- case IAX_EVENT_CONNECT:
- // incoming call detected
- switch_console_printf(SWITCH_CHANNEL_CONSOLE,
- "Incoming call connected %s, %s, %s %d/%d\n",
- iaxevent->ies.called_number,
- iaxevent->ies.calling_number,
- iaxevent->ies.calling_name,
- iaxevent->ies.format,
- iaxevent->ies.capability);
-
- if (iaxevent) {
- switch_core_session *session;
-
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "New Inbound Channel %s!\n", iaxevent->ies.calling_name);
- if ((session = switch_core_session_request(&channel_endpoint_interface, NULL))) {
- struct private_object *tech_pvt;
- switch_channel *channel;
-
- if ((tech_pvt = (struct private_object *) switch_core_session_alloc(session, sizeof(struct private_object)))) {
- memset(tech_pvt, 0, sizeof(*tech_pvt));
- channel = switch_core_session_get_channel(session);
- switch_core_session_set_private(session, tech_pvt);
- tech_pvt->session = session;
- } else {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Hey where is my memory pool?\n");
- switch_core_session_destroy(&session);
- break;
- }
-
-
- if ((tech_pvt->caller_profile = switch_caller_profile_new(session,
- globals.dialplan,
- iaxevent->ies.calling_name,
- iaxevent->ies.calling_number,
- iax_get_peer_ip(iaxevent->session),
- iaxevent->ies.calling_ani,
- NULL,
- iaxevent->ies.called_number))) {
- char name[128];
- switch_channel_set_caller_profile(channel, tech_pvt->caller_profile);
- snprintf(name, sizeof(name), "IAX/%s-%04x", tech_pvt->caller_profile->destination_number, rand() & 0xffff);
- switch_channel_set_name(channel, name);
- }
-
- if (iax_set_codec(tech_pvt, iaxevent->session,
- &iaxevent->ies.format,
- &iaxevent->ies.capability,
- IAX_SET) != SWITCH_STATUS_SUCCESS) {
- iax_reject(iaxevent->session, "Codec Error!");
- switch_core_session_destroy(&session);
- } else {
- tech_pvt->iax_session = iaxevent->session;
- tech_pvt->session = session;
- iax_accept(tech_pvt->iax_session, tech_pvt->codec);
- iax_ring_announce(tech_pvt->iax_session);
- switch_channel_set_state(channel, CS_INIT);
- switch_core_session_thread_launch(session);
- }
- }
- }
- break;
- case IAX_EVENT_REJECT:
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Rejected call.\n");
- case IAX_EVENT_BUSY:
- case IAX_EVENT_HANGUP:
- if (tech_pvt) {
- switch_channel *channel;
-
- switch_clear_flag(tech_pvt, TFLAG_IO);
- switch_clear_flag(tech_pvt, TFLAG_VOICE);
- if ((channel = switch_core_session_get_channel(tech_pvt->session))) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Hangup %s\n", switch_channel_get_name(channel));
- switch_set_flag(tech_pvt, TFLAG_HANGUP);
- switch_channel_hangup(channel);
- switch_thread_cond_signal(tech_pvt->cond);
- iaxevent->session = NULL;
- } else {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "No Session? %s\n", switch_test_flag(tech_pvt, TFLAG_VOICE) ? "yes" : "no");
- }
- }
- break;
- case IAX_EVENT_CNG:
- // pseudo-silence
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "sending silence\n");
- break;
- case IAX_EVENT_VOICE:
- if (tech_pvt && (tech_pvt->read_frame.datalen = iaxevent->datalen)) {
- int bytes = tech_pvt->read_codec.implementation->encoded_bytes_per_frame;
- int frames = (int)(tech_pvt->read_frame.datalen / bytes);
- tech_pvt->read_frame.samples = frames * tech_pvt->read_codec.implementation->samples_per_frame;
- memcpy(tech_pvt->read_frame.data, iaxevent->data, iaxevent->datalen);
- /* wake up the i/o thread*/
- switch_set_flag(tech_pvt, TFLAG_VOICE);
- switch_thread_cond_signal(tech_pvt->cond);
- }
- break;
- case IAX_EVENT_TRANSFER:
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Call transfer occurred.\n");
- //session[0] = iaxevent->session;
- break;
- case IAX_EVENT_DTMF:
- if (tech_pvt) {
- switch_channel *channel;
- if ((channel = switch_core_session_get_channel(tech_pvt->session))) {
- char str[2] = {iaxevent->subclass};
- if (globals.debug) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "%s DTMF %s\n", str, switch_channel_get_name(channel));
- }
- switch_channel_queue_dtmf(channel, str);
- }
- }
-
- break;
- default:
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Don't know what to do with IAX event %d.\n", iaxevent->etype);
- break;
- }
-
- iax_event_free(iaxevent);
- }
-
- }
-
- running = 0;
-
- return SWITCH_STATUS_TERM;
-}
-
-
-SWITCH_MOD_DECLARE(switch_status) switch_module_shutdown(void)
-{
- int x = 0;
-
- running = -1;
-
- iax_shutdown();
-
- while (running) {
- if (x++ > 100) {
- break;
- }
- switch_yield(20000);
- }
- return SWITCH_STATUS_SUCCESS;
-}
-
+++ /dev/null
-#CFLAGS += -I/usr/src/common/src
-LDFLAGS += -liax
-
-all: $(MOD).so
-
-$(MOD).so: $(MOD).c
- $(CC) $(CFLAGS) -fPIC -c $(MOD).c -o $(MOD).o
- $(CC) $(SOLINK) -o $(MOD).so $(MOD).o $(LDFLAGS)
-
-clean:
- rm -fr *.so *.o *~
-
+++ /dev/null
-/*
- * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
- * Copyright (C) 2005/2006, Anthony Minessale II <anthmct@yahoo.com>
- *
- * Version: MPL 1.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
- *
- * The Initial Developer of the Original Code is
- * Anthony Minessale II <anthmct@yahoo.com>
- * Portions created by the Initial Developer are Copyright (C)
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Anthony Minessale II <anthmct@yahoo.com>
- *
- *
- * mod_opalchan.c -- OPAL2 Endpoint Module
- *
- */
-#include <switch.h>
-
-
-static const char modname[] = "mod_woomera";
-
-static switch_memory_pool *module_pool;
-
-
-typedef enum {
- TFLAG_IO = (1 << 0),
- TFLAG_INBOUND = (1 << 1),
- TFLAG_OUTBOUND = (1 << 2),
- TFLAG_DTMF = (1 << 3),
-} TFLAGS;
-
-static struct {
- int debug;
- int port;
-} globals;
-
-struct private_object {
- unsigned int flags;
- struct switch_frame frame;
- unsigned char databuf[1024];
- switch_core_session *session;
- switch_caller_profile *caller_profile;
-};
-
-
-static const switch_endpoint_interface channel_endpoint_interface;
-
-static switch_status channel_on_init(switch_core_session *session);
-static switch_status channel_on_hangup(switch_core_session *session);
-static switch_status channel_on_ring(switch_core_session *session);
-static switch_status channel_on_loopback(switch_core_session *session);
-static switch_status channel_on_transmit(switch_core_session *session);
-static switch_status channel_outgoing_channel(switch_core_session *session, switch_caller_profile *outbound_profile, switch_core_session **new_session);
-static switch_status channel_read_frame(switch_core_session *session, switch_frame **frame, int timeout, switch_io_flag flags);
-static switch_status channel_write_frame(switch_core_session *session, switch_frame *frame, int timeout, switch_io_flag flags);
-static switch_status channel_kill_channel(switch_core_session *session, int sig);
-
-
-/*
- State methods they get called when the state changes to the specific state
- returning SWITCH_STATUS_SUCCESS tells the core to execute the standard state method next
- so if you fully implement the state you can return SWITCH_STATUS_FALSE to skip it.
-*/
-static switch_status channel_on_init(switch_core_session *session)
-{
- switch_channel *channel;
- struct private_object *tech_pvt = NULL;
-
- tech_pvt = switch_core_session_get_private(session);
- assert(tech_pvt != NULL);
-
- channel = switch_core_session_get_channel(session);
- assert(channel != NULL);
-
- tech_pvt->frame.data = tech_pvt->databuf;
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-static switch_status channel_on_ring(switch_core_session *session)
-{
- switch_channel *channel = NULL;
- struct private_object *tech_pvt = NULL;
-
- channel = switch_core_session_get_channel(session);
- assert(channel != NULL);
-
- tech_pvt = switch_core_session_get_private(session);
- assert(tech_pvt != NULL);
-
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "%s CHANNEL RING\n", switch_channel_get_name(channel));
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-static switch_status channel_on_execute(switch_core_session *session)
-{
-
- switch_channel *channel = NULL;
- struct private_object *tech_pvt = NULL;
-
- channel = switch_core_session_get_channel(session);
- assert(channel != NULL);
-
- tech_pvt = switch_core_session_get_private(session);
- assert(tech_pvt != NULL);
-
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "%s CHANNEL EXECUTE\n", switch_channel_get_name(channel));
-
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-static switch_status channel_on_hangup(switch_core_session *session)
-{
- switch_channel *channel = NULL;
- struct private_object *tech_pvt = NULL;
-
- channel = switch_core_session_get_channel(session);
- assert(channel != NULL);
-
- tech_pvt = switch_core_session_get_private(session);
- assert(tech_pvt != NULL);
-
-
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "%s CHANNEL HANGUP\n", switch_channel_get_name(channel));
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-static switch_status channel_kill_channel(switch_core_session *session, int sig)
-{
- switch_channel *channel = NULL;
- struct private_object *tech_pvt = NULL;
-
- channel = switch_core_session_get_channel(session);
- assert(channel != NULL);
-
- tech_pvt = switch_core_session_get_private(session);
- assert(tech_pvt != NULL);
-
- switch_channel_hangup(channel);
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "%s CHANNEL KILL\n", switch_channel_get_name(channel));
-
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-static switch_status channel_on_loopback(switch_core_session *session)
-{
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "CHANNEL LOOPBACK\n");
- return SWITCH_STATUS_SUCCESS;
-}
-
-static switch_status channel_on_transmit(switch_core_session *session)
-{
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "CHANNEL TRANSMIT\n");
- return SWITCH_STATUS_SUCCESS;
-}
-
-
-/* Make sure when you have 2 sessions in the same scope that you pass the appropriate one to the routines
- that allocate memory or you will have 1 channel with memory allocated from another channel's pool!
-*/
-static switch_status channel_outgoing_channel(switch_core_session *session, switch_caller_profile *outbound_profile, switch_core_session **new_session)
-{
- if ((*new_session = switch_core_session_request(&channel_endpoint_interface, NULL))) {
- struct private_object *tech_pvt;
- switch_channel *channel, *orig_channel;
- switch_caller_profile *caller_profile, *originator_caller_profile = NULL;
-
- if ((tech_pvt = (struct private_object *) switch_core_session_alloc(*new_session, sizeof(struct private_object)))) {
- memset(tech_pvt, 0, sizeof(*tech_pvt));
- channel = switch_core_session_get_channel(*new_session);
- switch_core_session_set_private(*new_session, tech_pvt);
- tech_pvt->session = *new_session;
- } else {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Hey where is my memory pool?\n");
- switch_core_session_destroy(new_session);
- return SWITCH_STATUS_GENERR;
- }
-
- if (outbound_profile) {
- char name[128];
- caller_profile = switch_caller_profile_clone(*new_session, outbound_profile);
- switch_channel_set_caller_profile(channel, caller_profile);
- tech_pvt->caller_profile = caller_profile;
- snprintf(name, sizeof(name), "Opal/%s-%04x", caller_profile->destination_number, rand() & 0xffff);
- switch_channel_set_name(channel, name);
- } else {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Doh! no caller profile\n");
- switch_core_session_destroy(new_session);
- return SWITCH_STATUS_GENERR;
- }
-
- /* (session == NULL) means it was originated from the core not from another channel */
- if (session && (orig_channel = switch_core_session_get_channel(session))) {
- switch_caller_profile *cloned_profile;
-
- if ((originator_caller_profile = switch_channel_get_caller_profile(orig_channel))) {
- cloned_profile = switch_caller_profile_clone(*new_session, originator_caller_profile);
- switch_channel_set_originator_caller_profile(channel, cloned_profile);
- }
- }
-
- switch_channel_set_flag(channel, CF_OUTBOUND);
- switch_set_flag(tech_pvt, TFLAG_OUTBOUND);
- switch_channel_set_state(channel, CS_INIT);
- return SWITCH_STATUS_SUCCESS;
- }
-
- return SWITCH_STATUS_GENERR;
-
-}
-
-static switch_status channel_waitfor_read(switch_core_session *session, int ms)
-{
- struct private_object *tech_pvt = NULL;
-
- tech_pvt = switch_core_session_get_private(session);
- assert(tech_pvt != NULL);
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-static switch_status channel_waitfor_write(switch_core_session *session, int ms)
-{
- struct private_object *tech_pvt = NULL;
-
- tech_pvt = switch_core_session_get_private(session);
- assert(tech_pvt != NULL);
-
- return SWITCH_STATUS_SUCCESS;
-
-}
-
-static switch_status channel_read_frame(switch_core_session *session, switch_frame **frame, int timeout, switch_io_flag flags)
-{
- switch_channel *channel = NULL;
- struct private_object *tech_pvt = NULL;
- //switch_frame *pframe;
- //switch_status status;
-
- channel = switch_core_session_get_channel(session);
- assert(channel != NULL);
-
- tech_pvt = switch_core_session_get_private(session);
- assert(tech_pvt != NULL);
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-static switch_status channel_write_frame(switch_core_session *session, switch_frame *frame, int timeout, switch_io_flag flags)
-{
- switch_channel *channel = NULL;
- struct private_object *tech_pvt = NULL;
- //switch_frame *pframe;
-
- channel = switch_core_session_get_channel(session);
- assert(channel != NULL);
-
- tech_pvt = switch_core_session_get_private(session);
- assert(tech_pvt != NULL);
-
- return SWITCH_STATUS_SUCCESS;
-
-}
-
-static const switch_event_handler_table channel_event_handlers = {
- /*.on_init*/ channel_on_init,
- /*.on_ring*/ channel_on_ring,
- /*.on_execute*/ channel_on_execute,
- /*.on_hangup*/ channel_on_hangup,
- /*.on_loopback*/ channel_on_loopback,
- /*.on_transmit*/ channel_on_transmit
-};
-
-static const switch_io_routines channel_io_routines = {
- /*.outgoing_channel*/ channel_outgoing_channel,
- /*.answer_channel*/ NULL,
- /*.read_frame*/ channel_read_frame,
- /*.write_frame*/ channel_write_frame,
- /*.kill_channel*/ channel_kill_channel,
- /*.waitfor_read*/ channel_waitfor_read,
- /*.waitfor_write*/ channel_waitfor_write
-};
-
-static const switch_endpoint_interface channel_endpoint_interface = {
- /*.interface_name*/ "opal",
- /*.io_routines*/ &channel_io_routines,
- /*.event_handlers*/ &channel_event_handlers,
- /*.private*/ NULL,
- /*.next*/ NULL
-};
-
-static const switch_loadable_module_interface channel_module_interface = {
- /*.module_name*/ modname,
- /*.endpoint_interface*/ &channel_endpoint_interface,
- /*.timer_interface*/ NULL,
- /*.dialplan_interface*/ NULL,
- /*.codec_interface*/ NULL,
- /*.application_interface*/ NULL
-};
-
-
-/*
-
-
-
-SWITCH_MOD_DECLARE(switch_status) switch_module_shutdown(void)
-{
- int x = 0;
- opal_profile_thread_running(&default_profile, 1, 0);
- while (!opal_profile_thread_running(&default_profile, 0, 0)) {
- opal_socket_close(&default_profile.opal_socket);
- if (x++ > 10) {
- break;
- }
- switch_yield(1);
- }
- return SWITCH_STATUS_SUCCESS;
-}
-*/
-
-SWITCH_MOD_DECLARE(switch_status) switch_module_load(const switch_loadable_module_interface **interface, char *filename) {
-
- switch_config cfg;
- char *var, *val;
- char *cf = "opal.conf";
-
- memset(&globals, 0, sizeof(globals));
-
- if (!switch_config_open_file(&cfg, cf)) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "open of %s failed\n", cf);
- return SWITCH_STATUS_TERM;
- }
-
-
- while (switch_config_next_pair(&cfg, &var, &val)) {
- if (!strcasecmp(cfg.category, "settings")) {
- if (!strcmp(var, "debug")) {
- globals.debug = atoi(val);
- } else if (!strcmp(var, "port")) {
- globals.port = atoi(val);
- }
- }
- }
-
- switch_config_close_file(&cfg);
-
-
- if (switch_core_new_memory_pool(&module_pool) != SWITCH_STATUS_SUCCESS) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "OH OH no pool\n");
- return SWITCH_STATUS_TERM;
- }
-
- /* connect my internal structure to the blank pointer passed to me */
- *interface = &channel_module_interface;
-
- /* indicate that the module should continue to be loaded */
- return SWITCH_STATUS_SUCCESS;
-}
-
-
-
-SWITCH_MOD_DECLARE(switch_status) switch_module_runtime(void)
-{
-
- return SWITCH_STATUS_TERM;
-}
+++ /dev/null
-/*
- * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
- * Copyright (C) 2005/2006, Anthony Minessale II <anthmct@yahoo.com>
- *
- * Version: MPL 1.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
- *
- * The Initial Developer of the Original Code is
- * Anthony Minessale II <anthmct@yahoo.com>
- * Portions created by the Initial Developer are Copyright (C)
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Anthony Minessale II <anthmct@yahoo.com>
- *
- *
- * mod_playback.c -- Raw Audio File Streaming Application Module
- *
- */
-#include <switch.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-
-static const char modname[] = "mod_playback";
-
-
-void playback_function(switch_core_session *session, char *data)
-{
- switch_channel *channel;
- short buf[960];
- char dtmf[128];
- int interval = 0, samples = 0;
- size_t len = 0, ilen = 0;
- switch_frame write_frame;
- switch_timer timer;
- switch_core_thread_session thread_session;
- switch_codec codec;
- switch_memory_pool *pool = switch_core_session_get_pool(session);
- switch_file_handle fh;
- char *codec_name;
- int x;
-
- channel = switch_core_session_get_channel(session);
- assert(channel != NULL);
-
- if (switch_core_file_open(&fh,
- data,
- SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT,
- switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
- switch_channel_hangup(channel);
- return;
- }
-
- switch_channel_answer(channel);
-
- write_frame.data = buf;
- write_frame.buflen = sizeof(buf);
-
-
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "OPEN FILE %s %dhz %d channels\n", data, fh.samplerate, fh.channels);
-
- interval = 20;
- samples = (fh.samplerate / 50) * fh.channels;
- len = samples * 2;
-
- codec_name = "L16";
-
- if (switch_core_codec_init(&codec,
- codec_name,
- fh.samplerate,
- interval,
- fh.channels,
- SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
- NULL,
- pool) == SWITCH_STATUS_SUCCESS) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Raw Codec Activated\n");
- write_frame.codec = &codec;
- } else {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Raw Codec Activation Failed %s@%dhz %d channels %dms\n", codec_name, fh.samplerate, fh.channels, interval);
- switch_core_file_close(&fh);
- switch_channel_hangup(channel);
- return;
- }
-
- if (switch_core_timer_init(&timer, "soft", interval, samples, pool) != SWITCH_STATUS_SUCCESS) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "setup timer failed!\n");
- switch_core_codec_destroy(&codec);
- switch_core_file_close(&fh);
- switch_channel_hangup(channel);
- return;
- }
- write_frame.rate = fh.samplerate;
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "setup timer success %d bytes per %d ms!\n", len, interval);
-
- /* start a thread to absorb incoming audio */
- switch_core_service_session(session, &thread_session);
- ilen = samples;
- while(switch_channel_get_state(channel) == CS_EXECUTE) {
- int done = 0;
-
- if (switch_channel_has_dtmf(channel)) {
- switch_channel_dequeue_dtmf(channel, dtmf, sizeof(dtmf));
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "DTMF [%s]\n", dtmf);
-
- switch (*dtmf) {
- case '*':
- done = 1;
- break;
- default:
- break;
- }
- }
-
- if (done) {
- break;
- }
-
- switch_core_file_read(&fh, buf, &ilen);
-
- if (ilen <= 0) {
- break;
- }
-
- write_frame.datalen = ilen * 2;
- write_frame.samples = (int)ilen;
-#ifdef SWAP_LINEAR
- switch_swap_linear(write_frame.data, (int)write_frame.datalen / 2);
-#endif
- if (switch_core_session_write_frame(session, &write_frame, -1) != SWITCH_STATUS_SUCCESS) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Bad Write\n");
- break;
- }
-
- if ((x = switch_core_timer_next(&timer)) < 0) {
- break;
- }
- }
-
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "done playing file\n");
- switch_core_file_close(&fh);
-
- /* End the audio absorbing thread */
- switch_core_thread_session_end(&thread_session);
-
- switch_core_timer_destroy(&timer);
-
- switch_core_codec_destroy(&codec);
-
- switch_channel_hangup(channel);
-}
-
-static const switch_application_interface playback_application_interface = {
- /*.interface_name*/ "playback",
- /*.application_function*/ playback_function
-};
-
-static const switch_loadable_module_interface mod_playback_module_interface = {
- /*.module_name = */ modname,
- /*.endpoint_interface = */ NULL,
- /*.timer_interface = */ NULL,
- /*.dialplan_interface = */ NULL,
- /*.codec_interface = */ NULL,
- /*.application_interface*/ &playback_application_interface
-};
-
-SWITCH_MOD_DECLARE(switch_status) switch_module_load(const switch_loadable_module_interface **interface, char *filename) {
-
- /* connect my internal structure to the blank pointer passed to me */
- *interface = &mod_playback_module_interface;
-
-
- /* indicate that the module should continue to be loaded */
- return SWITCH_STATUS_SUCCESS;
-}
-
-/* 'switch_module_runtime' will start up in a thread by itself just by having it exist
-if it returns anything but SWITCH_STATUS_TERM it will be called again automaticly
-*/
-
-
-//switch_status switch_module_runtime(void)
-
-
-
-
+++ /dev/null
-<?xml version="1.0" encoding="Windows-1252"?>\r
-<VisualStudioProject\r
- ProjectType="Visual C++"\r
- Version="8.00"\r
- Name="mod_playback"\r
- ProjectGUID="{78100236-7CEA-4948-96CC-E8ED3160329C}"\r
- RootNamespace="mod_playback"\r
- Keyword="Win32Proj"\r
- >\r
- <Platforms>\r
- <Platform\r
- Name="Win32"\r
- />\r
- </Platforms>\r
- <ToolFiles>\r
- </ToolFiles>\r
- <Configurations>\r
- <Configuration\r
- Name="Debug|Win32"\r
- OutputDirectory="Debug"\r
- IntermediateDirectory="Debug"\r
- ConfigurationType="2"\r
- InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
- CharacterSet="2"\r
- >\r
- <Tool\r
- Name="VCPreBuildEventTool"\r
- />\r
- <Tool\r
- Name="VCCustomBuildTool"\r
- />\r
- <Tool\r
- Name="VCXMLDataGeneratorTool"\r
- />\r
- <Tool\r
- Name="VCWebServiceProxyGeneratorTool"\r
- />\r
- <Tool\r
- Name="VCMIDLTool"\r
- />\r
- <Tool\r
- Name="VCCLCompilerTool"\r
- Optimization="0"\r
- AdditionalIncludeDirectories=""$(InputDir)..\..\include";"$(InputDir)include";"$(InputDir)..\..\..\libs\include""\r
- PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS"\r
- MinimalRebuild="true"\r
- BasicRuntimeChecks="3"\r
- RuntimeLibrary="1"\r
- UsePrecompiledHeader="0"\r
- WarningLevel="3"\r
- Detect64BitPortabilityProblems="true"\r
- DebugInformationFormat="4"\r
- />\r
- <Tool\r
- Name="VCManagedResourceCompilerTool"\r
- />\r
- <Tool\r
- Name="VCResourceCompilerTool"\r
- />\r
- <Tool\r
- Name="VCPreLinkEventTool"\r
- />\r
- <Tool\r
- Name="VCLinkerTool"\r
- OutputFile="..\..\..\w32\vsnet\$(OutDir)/mod/mod_playback.dll"\r
- LinkIncremental="2"\r
- AdditionalLibraryDirectories="$(InputDir)..\..\libs\apr\Debug"\r
- GenerateDebugInformation="true"\r
- ProgramDatabaseFile="$(OutDir)/mod_playback.pdb"\r
- SubSystem="2"\r
- ImportLibrary="$(OutDir)/mod_playback.lib"\r
- TargetMachine="1"\r
- />\r
- <Tool\r
- Name="VCALinkTool"\r
- />\r
- <Tool\r
- Name="VCManifestTool"\r
- />\r
- <Tool\r
- Name="VCXDCMakeTool"\r
- />\r
- <Tool\r
- Name="VCBscMakeTool"\r
- />\r
- <Tool\r
- Name="VCFxCopTool"\r
- />\r
- <Tool\r
- Name="VCAppVerifierTool"\r
- />\r
- <Tool\r
- Name="VCWebDeploymentTool"\r
- />\r
- <Tool\r
- Name="VCPostBuildEventTool"\r
- />\r
- </Configuration>\r
- <Configuration\r
- Name="Release|Win32"\r
- OutputDirectory="Release"\r
- IntermediateDirectory="Release"\r
- ConfigurationType="2"\r
- InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
- CharacterSet="2"\r
- >\r
- <Tool\r
- Name="VCPreBuildEventTool"\r
- />\r
- <Tool\r
- Name="VCCustomBuildTool"\r
- />\r
- <Tool\r
- Name="VCXMLDataGeneratorTool"\r
- />\r
- <Tool\r
- Name="VCWebServiceProxyGeneratorTool"\r
- />\r
- <Tool\r
- Name="VCMIDLTool"\r
- />\r
- <Tool\r
- Name="VCCLCompilerTool"\r
- AdditionalIncludeDirectories=""$(InputDir)..\..\include";"$(InputDir)include";"$(InputDir)..\..\..\libs\include""\r
- PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS"\r
- RuntimeLibrary="0"\r
- UsePrecompiledHeader="0"\r
- WarningLevel="3"\r
- Detect64BitPortabilityProblems="true"\r
- DebugInformationFormat="3"\r
- />\r
- <Tool\r
- Name="VCManagedResourceCompilerTool"\r
- />\r
- <Tool\r
- Name="VCResourceCompilerTool"\r
- />\r
- <Tool\r
- Name="VCPreLinkEventTool"\r
- />\r
- <Tool\r
- Name="VCLinkerTool"\r
- OutputFile="..\..\..\w32\vsnet\$(OutDir)/mod/mod_playback.dll"\r
- LinkIncremental="1"\r
- AdditionalLibraryDirectories=""$(InputDir)..\..\libs\apr\Release""\r
- GenerateDebugInformation="true"\r
- SubSystem="2"\r
- OptimizeReferences="2"\r
- EnableCOMDATFolding="2"\r
- ImportLibrary="$(OutDir)/mod_playback.lib"\r
- TargetMachine="1"\r
- />\r
- <Tool\r
- Name="VCALinkTool"\r
- />\r
- <Tool\r
- Name="VCManifestTool"\r
- />\r
- <Tool\r
- Name="VCXDCMakeTool"\r
- />\r
- <Tool\r
- Name="VCBscMakeTool"\r
- />\r
- <Tool\r
- Name="VCFxCopTool"\r
- />\r
- <Tool\r
- Name="VCAppVerifierTool"\r
- />\r
- <Tool\r
- Name="VCWebDeploymentTool"\r
- />\r
- <Tool\r
- Name="VCPostBuildEventTool"\r
- />\r
- </Configuration>\r
- </Configurations>\r
- <References>\r
- </References>\r
- <Files>\r
- <Filter\r
- Name="Source Files"\r
- Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"\r
- UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"\r
- >\r
- <File\r
- RelativePath=".\mod_playback.c"\r
- >\r
- </File>\r
- </Filter>\r
- <Filter\r
- Name="Header Files"\r
- Filter="h;hpp;hxx;hm;inl;inc;xsd"\r
- UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"\r
- >\r
- </Filter>\r
- <Filter\r
- Name="Resource Files"\r
- Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"\r
- UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"\r
- >\r
- </Filter>\r
- </Files>\r
- <Globals>\r
- </Globals>\r
-</VisualStudioProject>\r
+++ /dev/null
-LDFLAGS += -lportaudio -L/usr/local/lib
-MYOBJS = pablio.o ringbuffer.o
-
-all: depends $(MOD).so
-
-depends:
- $(BASE)/buildlib.sh $(BASE) install portaudio.tar.gz --prefix=$(PREFIX)
-%.o: %.c
- $(CC) -fPIC $(CFLAGS) -c -o $@ $<
-
-$(MOD).so: $(MOD).c $(MYOBJS)
- $(CC) $(CFLAGS) -fPIC -c $(MOD).c -o $(MOD).o
- $(CC) $(SOLINK) -o $(MOD).so $(MOD).o $(MYOBJS) $(LDFLAGS)
-
-
-
-clean:
- rm -fr *.so *.o *~
-
+++ /dev/null
-<?xml version="1.0" encoding="Windows-1252"?>\r
-<VisualStudioProject\r
- ProjectType="Visual C++"\r
- Version="8.00"\r
- Name="mod_PortAudio"\r
- ProjectGUID="{5FD31A25-5D83-4794-8BEE-904DAD84CE71}"\r
- RootNamespace="mod_PortAudio"\r
- Keyword="Win32Proj"\r
- >\r
- <Platforms>\r
- <Platform\r
- Name="Win32"\r
- />\r
- </Platforms>\r
- <ToolFiles>\r
- </ToolFiles>\r
- <Configurations>\r
- <Configuration\r
- Name="Debug|Win32"\r
- OutputDirectory="Debug"\r
- IntermediateDirectory="Debug"\r
- ConfigurationType="2"\r
- InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
- CharacterSet="2"\r
- >\r
- <Tool\r
- Name="VCPreBuildEventTool"\r
- CommandLine="cscript /nologo $(InputDir)..\..\..\w32\vsnet\getlibs.vbs Mod_PortAudio Debug"\r
- />\r
- <Tool\r
- Name="VCCustomBuildTool"\r
- />\r
- <Tool\r
- Name="VCXMLDataGeneratorTool"\r
- />\r
- <Tool\r
- Name="VCWebServiceProxyGeneratorTool"\r
- />\r
- <Tool\r
- Name="VCMIDLTool"\r
- />\r
- <Tool\r
- Name="VCCLCompilerTool"\r
- Optimization="0"\r
- AdditionalIncludeDirectories=""$(InputDir)..\..\include";"$(InputDir)";"$(InputDir)..\..\..\libs\include";"$(InputDir)..\..\..\libs\portaudio\pa_common";"$(InputDir)..\..\..\libs\portaudio\pa_win_wmme""\r
- PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS"\r
- MinimalRebuild="true"\r
- BasicRuntimeChecks="3"\r
- RuntimeLibrary="1"\r
- UsePrecompiledHeader="0"\r
- WarningLevel="3"\r
- Detect64BitPortabilityProblems="true"\r
- DebugInformationFormat="4"\r
- />\r
- <Tool\r
- Name="VCManagedResourceCompilerTool"\r
- />\r
- <Tool\r
- Name="VCResourceCompilerTool"\r
- />\r
- <Tool\r
- Name="VCPreLinkEventTool"\r
- />\r
- <Tool\r
- Name="VCLinkerTool"\r
- AdditionalOptions="/NODEFAULTLIB:LIMBCTD"\r
- AdditionalDependencies="Ws2_32.lib Iphlpapi.lib PAStaticWMMED.lib Winmm.lib"\r
- OutputFile="..\..\..\w32\vsnet\$(OutDir)/mod/mod_PortAudio.dll"\r
- LinkIncremental="2"\r
- AdditionalLibraryDirectories=""$(InputDir)..\..\..\libs\portaudio\winvc\Lib""\r
- GenerateDebugInformation="true"\r
- ProgramDatabaseFile="$(OutDir)/mod_PortAudio.pdb"\r
- SubSystem="2"\r
- ImportLibrary="$(OutDir)/mod_PortAudio.lib"\r
- TargetMachine="1"\r
- />\r
- <Tool\r
- Name="VCALinkTool"\r
- />\r
- <Tool\r
- Name="VCManifestTool"\r
- />\r
- <Tool\r
- Name="VCXDCMakeTool"\r
- />\r
- <Tool\r
- Name="VCBscMakeTool"\r
- />\r
- <Tool\r
- Name="VCFxCopTool"\r
- />\r
- <Tool\r
- Name="VCAppVerifierTool"\r
- />\r
- <Tool\r
- Name="VCWebDeploymentTool"\r
- />\r
- <Tool\r
- Name="VCPostBuildEventTool"\r
- />\r
- </Configuration>\r
- <Configuration\r
- Name="Release|Win32"\r
- OutputDirectory="Release"\r
- IntermediateDirectory="Release"\r
- ConfigurationType="2"\r
- InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
- CharacterSet="2"\r
- >\r
- <Tool\r
- Name="VCPreBuildEventTool"\r
- CommandLine="cscript /nologo $(InputDir)..\..\..\w32\vsnet\getlibs.vbs Mod_PortAudio Release"\r
- />\r
- <Tool\r
- Name="VCCustomBuildTool"\r
- />\r
- <Tool\r
- Name="VCXMLDataGeneratorTool"\r
- />\r
- <Tool\r
- Name="VCWebServiceProxyGeneratorTool"\r
- />\r
- <Tool\r
- Name="VCMIDLTool"\r
- />\r
- <Tool\r
- Name="VCCLCompilerTool"\r
- AdditionalIncludeDirectories=""$(InputDir)..\..\include";"$(InputDir)";"$(InputDir)..\..\..\libs\include";"$(InputDir)..\..\..\libs\portaudio\pa_common";"$(InputDir)..\..\..\libs\portaudio\pa_win_wmme""\r
- PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS"\r
- RuntimeLibrary="0"\r
- UsePrecompiledHeader="0"\r
- WarningLevel="3"\r
- Detect64BitPortabilityProblems="true"\r
- DebugInformationFormat="3"\r
- />\r
- <Tool\r
- Name="VCManagedResourceCompilerTool"\r
- />\r
- <Tool\r
- Name="VCResourceCompilerTool"\r
- />\r
- <Tool\r
- Name="VCPreLinkEventTool"\r
- />\r
- <Tool\r
- Name="VCLinkerTool"\r
- AdditionalDependencies="Ws2_32.lib Iphlpapi.lib PAStaticWMME.lib Winmm.lib"\r
- OutputFile="..\..\..\w32\vsnet\$(OutDir)/mod/mod_PortAudio.dll"\r
- LinkIncremental="1"\r
- AdditionalLibraryDirectories=""$(InputDir)..\..\..\libs\portaudio\winvc\Lib""\r
- GenerateDebugInformation="true"\r
- SubSystem="2"\r
- OptimizeReferences="2"\r
- EnableCOMDATFolding="2"\r
- ImportLibrary="$(OutDir)/mod_PortAudio.lib"\r
- TargetMachine="1"\r
- />\r
- <Tool\r
- Name="VCALinkTool"\r
- />\r
- <Tool\r
- Name="VCManifestTool"\r
- />\r
- <Tool\r
- Name="VCXDCMakeTool"\r
- />\r
- <Tool\r
- Name="VCBscMakeTool"\r
- />\r
- <Tool\r
- Name="VCFxCopTool"\r
- />\r
- <Tool\r
- Name="VCAppVerifierTool"\r
- />\r
- <Tool\r
- Name="VCWebDeploymentTool"\r
- />\r
- <Tool\r
- Name="VCPostBuildEventTool"\r
- />\r
- </Configuration>\r
- </Configurations>\r
- <References>\r
- </References>\r
- <Files>\r
- <Filter\r
- Name="Source Files"\r
- Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"\r
- UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"\r
- >\r
- <File\r
- RelativePath=".\mod_PortAudio.c"\r
- >\r
- </File>\r
- <File\r
- RelativePath=".\pablio.c"\r
- >\r
- </File>\r
- <File\r
- RelativePath=".\ringbuffer.c"\r
- >\r
- </File>\r
- </Filter>\r
- <Filter\r
- Name="Header Files"\r
- Filter="h;hpp;hxx;hm;inl;inc;xsd"\r
- UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"\r
- >\r
- <File\r
- RelativePath=".\pablio.h"\r
- >\r
- </File>\r
- <File\r
- RelativePath=".\ringbuffer.h"\r
- >\r
- </File>\r
- </Filter>\r
- <Filter\r
- Name="Resource Files"\r
- Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"\r
- UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"\r
- >\r
- </Filter>\r
- </Files>\r
- <Globals>\r
- </Globals>\r
-</VisualStudioProject>\r
+++ /dev/null
-/*
- * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
- * Copyright (C) 2005/2006, Anthony Minessale II <anthmct@yahoo.com>
- *
- * Version: MPL 1.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
- *
- * The Initial Developer of the Original Code is
- * Anthony Minessale II <anthmct@yahoo.com>
- * Portions created by the Initial Developer are Copyright (C)
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Anthony Minessale II <anthmct@yahoo.com>
- *
- *
- * mod_portaudio.c -- PortAudio Endpoint Module
- *
- */
-#include <switch.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <math.h>
-#include "pablio.h"
-#include <string.h>
-
-#define MY_EVENT_RINGING "portaudio::ringing"
-
-static const char modname[] = "mod_portaudio";
-
-static switch_memory_pool *module_pool;
-//static int running = 1;
-
-#define SAMPLE_TYPE paInt16
-//#define SAMPLE_TYPE paFloat32
-typedef short SAMPLE;
-
-typedef enum {
- TFLAG_IO = (1 << 0),
- TFLAG_INBOUND = (1 << 1),
- TFLAG_OUTBOUND = (1 << 2),
- TFLAG_DTMF = (1 << 3),
- TFLAG_VOICE = (1 << 4),
- TFLAG_HANGUP = (1 << 5),
- TFLAG_LINEAR = (1 << 6),
- TFLAG_ANSWER = (1 << 7)
-} TFLAGS;
-
-typedef enum {
- GFLAG_MY_CODEC_PREFS = (1 << 0)
-} GFLAGS;
-
-static struct {
- int debug;
- int port;
- char *cid_name;
- char *cid_num;
- char *dialplan;
- unsigned int flags;
- int indev;
- int outdev;
- int call_id;
- switch_hash *call_hash;
- switch_mutex_t *device_lock;
- int sample_rate;
-} globals;
-
-struct private_object {
- unsigned int flags;
- switch_codec read_codec;
- switch_codec write_codec;
- struct switch_frame read_frame;
- unsigned char databuf[1024];
- switch_core_session *session;
- switch_caller_profile *caller_profile;
- char call_id[50];
- PaError err;
- PABLIO_Stream *audio_in;
- PABLIO_Stream *audio_out;
- int indev;
- int outdev;
-};
-
-SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_dialplan, globals.dialplan)
-SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_cid_name, globals.cid_name)
-SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_cid_num, globals.cid_num)
-
-
-static const switch_endpoint_interface channel_endpoint_interface;
-
-static switch_status channel_on_init(switch_core_session *session);
-static switch_status channel_on_hangup(switch_core_session *session);
-static switch_status channel_on_ring(switch_core_session *session);
-static switch_status channel_on_loopback(switch_core_session *session);
-static switch_status channel_on_transmit(switch_core_session *session);
-static switch_status channel_outgoing_channel(switch_core_session *session, switch_caller_profile *outbound_profile, switch_core_session **new_session);
-static switch_status channel_read_frame(switch_core_session *session, switch_frame **frame, int timeout, switch_io_flag flags);
-static switch_status channel_write_frame(switch_core_session *session, switch_frame *frame, int timeout, switch_io_flag flags);
-static switch_status channel_kill_channel(switch_core_session *session, int sig);
-static switch_status engage_device(struct private_object *tech_pvt);
-static int dump_info(void);
-static switch_status load_config(void);
-static int get_dev_by_name(char *name, int in);
-static switch_status place_call(char *dest, char *out, size_t outlen);
-static switch_status hup_call(char *callid, char *out, size_t outlen);
-static switch_status call_info(char *callid, char *out, size_t outlen);
-static switch_status send_dtmf(char *callid, char *out, size_t outlen);
-static switch_status answer_call(char *callid, char *out, size_t outlen);
-
-/*
- State methods they get called when the state changes to the specific state
- returning SWITCH_STATUS_SUCCESS tells the core to execute the standard state method next
- so if you fully implement the state you can return SWITCH_STATUS_FALSE to skip it.
-*/
-static switch_status channel_on_init(switch_core_session *session)
-{
- switch_channel *channel;
- struct private_object *tech_pvt = NULL;
-
- tech_pvt = switch_core_session_get_private(session);
- assert(tech_pvt != NULL);
-
- channel = switch_core_session_get_channel(session);
- assert(channel != NULL);
-
- tech_pvt->read_frame.data = tech_pvt->databuf;
- tech_pvt->read_frame.buflen = sizeof(tech_pvt->databuf);
-
- switch_set_flag(tech_pvt, TFLAG_IO);
-
- /* Move Channel's State Machine to RING */
- switch_channel_set_state(channel, CS_RING);
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-static switch_status channel_on_ring(switch_core_session *session)
-{
- switch_channel *channel = NULL;
- struct private_object *tech_pvt = NULL;
-
- channel = switch_core_session_get_channel(session);
- assert(channel != NULL);
-
- tech_pvt = switch_core_session_get_private(session);
- assert(tech_pvt != NULL);
-
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "%s CHANNEL RING\n", switch_channel_get_name(channel));
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-static switch_status channel_on_execute(switch_core_session *session)
-{
-
- switch_channel *channel = NULL;
- struct private_object *tech_pvt = NULL;
-
- channel = switch_core_session_get_channel(session);
- assert(channel != NULL);
-
- tech_pvt = switch_core_session_get_private(session);
- assert(tech_pvt != NULL);
-
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "%s CHANNEL EXECUTE\n", switch_channel_get_name(channel));
-
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-static void deactivate_audio_device(struct private_object *tech_pvt)
-{
- switch_mutex_lock(globals.device_lock);
- if (tech_pvt->audio_in) {
- CloseAudioStream(tech_pvt->audio_in);
- tech_pvt->audio_in = NULL;
- }
- if (tech_pvt->audio_out) {
- CloseAudioStream(tech_pvt->audio_out);
- tech_pvt->audio_out = NULL;
- }
- switch_mutex_unlock(globals.device_lock);
-}
-
-static switch_status channel_on_hangup(switch_core_session *session)
-{
- switch_channel *channel = NULL;
- struct private_object *tech_pvt = NULL;
-
- channel = switch_core_session_get_channel(session);
- assert(channel != NULL);
-
- tech_pvt = switch_core_session_get_private(session);
- assert(tech_pvt != NULL);
-
- switch_clear_flag(tech_pvt, TFLAG_IO);
- switch_core_hash_delete(globals.call_hash, tech_pvt->call_id);
-
- switch_core_codec_destroy(&tech_pvt->read_codec);
- switch_core_codec_destroy(&tech_pvt->write_codec);
-
- deactivate_audio_device(tech_pvt);
-
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "%s CHANNEL HANGUP\n", switch_channel_get_name(channel));
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-static switch_status channel_kill_channel(switch_core_session *session, int sig)
-{
- switch_channel *channel = NULL;
- struct private_object *tech_pvt = NULL;
-
- channel = switch_core_session_get_channel(session);
- assert(channel != NULL);
-
- tech_pvt = switch_core_session_get_private(session);
- assert(tech_pvt != NULL);
-
- switch_clear_flag(tech_pvt, TFLAG_IO);
- deactivate_audio_device(tech_pvt);
- switch_channel_hangup(channel);
-
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "%s CHANNEL KILL\n", switch_channel_get_name(channel));
-
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-static switch_status channel_on_loopback(switch_core_session *session)
-{
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "CHANNEL LOOPBACK\n");
- return SWITCH_STATUS_SUCCESS;
-}
-
-static switch_status channel_on_transmit(switch_core_session *session)
-{
- switch_channel *channel = NULL;
- struct private_object *tech_pvt = NULL;
- switch_time_t last;
- int waitsec = 5 * 1000000;
-
- channel = switch_core_session_get_channel(session);
- assert(channel != NULL);
-
- tech_pvt = switch_core_session_get_private(session);
- assert(tech_pvt != NULL);
-
- last = switch_time_now() - waitsec;
-
- /* Turn on the device */
- engage_device(tech_pvt);
-
- while(switch_channel_get_state(channel) == CS_TRANSMIT && !switch_test_flag(tech_pvt, TFLAG_ANSWER)) {
- if (switch_time_now() - last >= waitsec) {
- char buf[512];
- switch_event *event;
-
- snprintf(buf, sizeof(buf), "BRRRRING! BRRRRING! call %s\n", tech_pvt->call_id);
-
- if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_RINGING) == SWITCH_STATUS_SUCCESS) {
- switch_event_add_header(event, SWITCH_STACK_BOTTOM, "event_info", buf);
- switch_event_fire(&event);
- }
-
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "%s\n", buf);
- last = switch_time_now();
- }
- switch_yield(50000);
- }
-
-
-
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "CHANNEL TRANSMIT\n");
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-
-/* Make sure when you have 2 sessions in the same scope that you pass the appropriate one to the routines
- that allocate memory or you will have 1 channel with memory allocated from another channel's pool!
-*/
-static switch_status channel_outgoing_channel(switch_core_session *session, switch_caller_profile *outbound_profile, switch_core_session **new_session)
-{
- if ((*new_session = switch_core_session_request(&channel_endpoint_interface, NULL))) {
- struct private_object *tech_pvt;
- switch_channel *channel;
- switch_caller_profile *caller_profile;
-
- if ((tech_pvt = (struct private_object *) switch_core_session_alloc(*new_session, sizeof(struct private_object)))) {
- memset(tech_pvt, 0, sizeof(*tech_pvt));
- channel = switch_core_session_get_channel(*new_session);
- switch_core_session_set_private(*new_session, tech_pvt);
- tech_pvt->session = *new_session;
- } else {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Hey where is my memory pool?\n");
- switch_core_session_destroy(new_session);
- return SWITCH_STATUS_GENERR;
- }
-
- if (outbound_profile) {
- char name[128];
- caller_profile = switch_caller_profile_clone(*new_session, outbound_profile);
- switch_channel_set_caller_profile(channel, caller_profile);
- tech_pvt->caller_profile = caller_profile;
- snprintf(name, sizeof(name), "PortAudio/%s-%04x", caller_profile->destination_number ? caller_profile->destination_number : modname, rand() & 0xffff);
- switch_channel_set_name(channel, name);
- } else {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Doh! no caller profile\n");
- switch_core_session_destroy(new_session);
- return SWITCH_STATUS_GENERR;
- }
-
- switch_channel_set_flag(channel, CF_OUTBOUND);
- switch_set_flag(tech_pvt, TFLAG_OUTBOUND);
- switch_channel_set_state(channel, CS_INIT);
- return SWITCH_STATUS_SUCCESS;
- }
-
- return SWITCH_STATUS_GENERR;
-
-}
-
-static switch_status channel_waitfor_read(switch_core_session *session, int ms)
-{
- struct private_object *tech_pvt = NULL;
-
- tech_pvt = switch_core_session_get_private(session);
- assert(tech_pvt != NULL);
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-static switch_status channel_waitfor_write(switch_core_session *session, int ms)
-{
- struct private_object *tech_pvt = NULL;
-
- tech_pvt = switch_core_session_get_private(session);
- assert(tech_pvt != NULL);
-
- return SWITCH_STATUS_SUCCESS;
-
-}
-
-static switch_status channel_send_dtmf(switch_core_session *session, char *dtmf)
-{
- struct private_object *tech_pvt = NULL;
-
- tech_pvt = switch_core_session_get_private(session);
- assert(tech_pvt != NULL);
-
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "DTMF ON CALL %s [%s]\n", tech_pvt->call_id, dtmf);
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-static switch_status channel_read_frame(switch_core_session *session, switch_frame **frame, int timeout, switch_io_flag flags)
-{
- switch_channel *channel = NULL;
- struct private_object *tech_pvt = NULL;
- int samples;
- switch_status status = SWITCH_STATUS_FALSE;
-
- channel = switch_core_session_get_channel(session);
- assert(channel != NULL);
-
- tech_pvt = switch_core_session_get_private(session);
- assert(tech_pvt != NULL);
-
- if (!switch_test_flag(tech_pvt, TFLAG_IO)) {
- return SWITCH_STATUS_FALSE;
- }
-
-
- switch_mutex_lock(globals.device_lock);
- if (tech_pvt->audio_in &&
- (samples = ReadAudioStream(tech_pvt->audio_in, tech_pvt->read_frame.data, tech_pvt->read_codec.implementation->samples_per_frame))) {
- tech_pvt->read_frame.datalen = samples * 2;
- tech_pvt->read_frame.samples = samples;
- *frame = &tech_pvt->read_frame;
- status = SWITCH_STATUS_SUCCESS;
- }
- switch_mutex_unlock(globals.device_lock);
-
- return status;
-}
-
-static switch_status channel_write_frame(switch_core_session *session, switch_frame *frame, int timeout, switch_io_flag flags)
-{
- switch_channel *channel = NULL;
- struct private_object *tech_pvt = NULL;
- switch_status status = SWITCH_STATUS_FALSE;
- channel = switch_core_session_get_channel(session);
- assert(channel != NULL);
-
- tech_pvt = switch_core_session_get_private(session);
- assert(tech_pvt != NULL);
-
- if(!switch_test_flag(tech_pvt, TFLAG_IO)) {
- return SWITCH_STATUS_FALSE;
- }
-
- //switch_mutex_lock(globals.device_lock);
- if (tech_pvt->audio_out) {
- WriteAudioStream(tech_pvt->audio_out, (short *)frame->data, (int)(frame->datalen / sizeof(SAMPLE)));
- status = SWITCH_STATUS_SUCCESS;
- }
- //switch_mutex_unlock(globals.device_lock);
-
- return status;
-
-}
-
-static switch_status channel_answer_channel(switch_core_session *session)
-{
- struct private_object *tech_pvt;
- switch_channel *channel = NULL;
-
- channel = switch_core_session_get_channel(session);
- assert(channel != NULL);
-
- tech_pvt = switch_core_session_get_private(session);
- assert(tech_pvt != NULL);
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-
-static struct switch_api_interface send_dtmf_interface = {
- /*.interface_name*/ "padtmf",
- /*.desc*/ "PortAudio Dial DTMF",
- /*.function*/ send_dtmf,
- /*.next*/ NULL
-};
-
-static struct switch_api_interface answer_call_interface = {
- /*.interface_name*/ "paoffhook",
- /*.desc*/ "PortAudio Answer Call",
- /*.function*/ answer_call,
- /*.next*/ &send_dtmf_interface
-};
-
-static struct switch_api_interface channel_info_interface = {
- /*.interface_name*/ "painfo",
- /*.desc*/ "PortAudio Call Info",
- /*.function*/ call_info,
- /*.next*/ &answer_call_interface
-};
-
-static struct switch_api_interface channel_hup_interface = {
- /*.interface_name*/ "pahup",
- /*.desc*/ "PortAudio Hangup Call",
- /*.function*/ hup_call,
- /*.next*/ &channel_info_interface
-};
-
-static struct switch_api_interface channel_api_interface = {
- /*.interface_name*/ "pacall",
- /*.desc*/ "PortAudio Call",
- /*.function*/ place_call,
- /*.next*/ &channel_hup_interface
-};
-
-static const switch_event_handler_table channel_event_handlers = {
- /*.on_init*/ channel_on_init,
- /*.on_ring*/ channel_on_ring,
- /*.on_execute*/ channel_on_execute,
- /*.on_hangup*/ channel_on_hangup,
- /*.on_loopback*/ channel_on_loopback,
- /*.on_transmit*/ channel_on_transmit
-};
-
-static const switch_io_routines channel_io_routines = {
- /*.outgoing_channel*/ channel_outgoing_channel,
- /*.answer_channel*/ channel_answer_channel,
- /*.read_frame*/ channel_read_frame,
- /*.write_frame*/ channel_write_frame,
- /*.kill_channel*/ channel_kill_channel,
- /*.waitfor_read*/ channel_waitfor_read,
- /*.waitfor_write*/ channel_waitfor_write,
- /*.send_dtmf*/ channel_send_dtmf
-};
-
-static const switch_endpoint_interface channel_endpoint_interface = {
- /*.interface_name*/ "portaudio",
- /*.io_routines*/ &channel_io_routines,
- /*.event_handlers*/ &channel_event_handlers,
- /*.private*/ NULL,
- /*.next*/ NULL
-};
-
-static const switch_loadable_module_interface channel_module_interface = {
- /*.module_name*/ modname,
- /*.endpoint_interface*/ &channel_endpoint_interface,
- /*.timer_interface*/ NULL,
- /*.dialplan_interface*/ NULL,
- /*.codec_interface*/ NULL,
- /*.application_interface*/ NULL,
- /*.api_interface*/ &channel_api_interface
-};
-
-
-
-
-SWITCH_MOD_DECLARE(switch_status) switch_module_load(const switch_loadable_module_interface **interface, char *filename) {
-
- if (switch_core_new_memory_pool(&module_pool) != SWITCH_STATUS_SUCCESS) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "OH OH no pool\n");
- return SWITCH_STATUS_TERM;
- }
-
-
- Pa_Initialize();
- load_config();
- switch_core_hash_init(&globals.call_hash, module_pool);
- switch_mutex_init(&globals.device_lock, SWITCH_MUTEX_NESTED, module_pool);
-
- dump_info();
-
- if (switch_event_reserve_subclass(MY_EVENT_RINGING) != SWITCH_STATUS_SUCCESS) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Couldn't register subclass!");
- return SWITCH_STATUS_GENERR;
- }
-
- /* connect my internal structure to the blank pointer passed to me */
- *interface = &channel_module_interface;
-
- /* indicate that the module should continue to be loaded */
- return SWITCH_STATUS_SUCCESS;
-}
-
-
-static switch_status load_config(void)
-{
- switch_config cfg;
- char *var, *val;
- char *cf = "portaudio.conf";
-
- memset(&globals, 0, sizeof(globals));
-
- if (!switch_config_open_file(&cfg, cf)) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "open of %s failed\n", cf);
- return SWITCH_STATUS_TERM;
- }
-
- while (switch_config_next_pair(&cfg, &var, &val)) {
- if (!strcasecmp(cfg.category, "settings")) {
- if (!strcmp(var, "debug")) {
- globals.debug = atoi(val);
- } else if (!strcmp(var, "sample_rate")) {
- globals.sample_rate = atoi(val);
- } else if (!strcmp(var, "dialplan")) {
- set_global_dialplan(val);
- } else if (!strcmp(var, "cid_name")) {
- set_global_cid_name(val);
- } else if (!strcmp(var, "cid_num")) {
- set_global_cid_num(val);
- } else if (!strcmp(var, "indev")) {
- if (*val == '#') {
- globals.indev = atoi(val+1);
- } else {
- globals.indev = get_dev_by_name(val, 1);
- }
- } else if (!strcmp(var, "outdev")) {
- if (*val == '#') {
- globals.outdev = atoi(val+1);
- } else {
- globals.outdev = get_dev_by_name(val, 0);
- }
- }
- }
- }
-
- if (!globals.dialplan) {
- set_global_dialplan("default");
- }
-
- if (!globals.sample_rate) {
- globals.sample_rate = 8000;
- }
-
- switch_config_close_file(&cfg);
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-/*
-SWITCH_MOD_DECLARE(switch_status) switch_module_runtime(void)
-{
-
- switch_yield(50000);
- make_call("8888");
- return SWITCH_STATUS_TERM;
-}
-*/
-
-SWITCH_MOD_DECLARE(switch_status) switch_module_shutdown(void)
-{
- Pa_Terminate();
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-
-static int get_dev_by_name(char *name, int in)
-{
- int i;
- int numDevices;
- const PaDeviceInfo *pdi;
- numDevices = Pa_CountDevices();
-
- if( numDevices < 0 ) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE_CLEAN, "ERROR: Pa_CountDevices returned 0x%x\n", numDevices );
- return -2;
- }
-
- for( i=0; i<numDevices; i++ ) {
- pdi = Pa_GetDeviceInfo( i );
- if(strstr(pdi->name, name)) {
- if(in && pdi->maxInputChannels) {
- return i;
- } else if (!in && pdi->maxOutputChannels) {
- return i;
- }
- }
- }
- return -1;
-}
-
-
-static int dump_info(void)
-{
- int i,j;
- int numDevices;
- const PaDeviceInfo *pdi;
- PaError err;
- numDevices = Pa_CountDevices();
- if( numDevices < 0 )
- {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE_CLEAN, "ERROR: Pa_CountDevices returned 0x%x\n", numDevices );
- err = numDevices;
- goto error;
- }
- switch_console_printf(SWITCH_CHANNEL_CONSOLE_CLEAN, "Number of devices = %d\n", numDevices );
- for( i=0; i<numDevices; i++ )
- {
- pdi = Pa_GetDeviceInfo( i );
- switch_console_printf(SWITCH_CHANNEL_CONSOLE_CLEAN, "---------------------------------------------- #%d", i );
- if( i == Pa_GetDefaultInputDeviceID() ) switch_console_printf(SWITCH_CHANNEL_CONSOLE_CLEAN, " DefaultInput");
- if( i == Pa_GetDefaultOutputDeviceID() ) switch_console_printf(SWITCH_CHANNEL_CONSOLE_CLEAN, " DefaultOutput");
- switch_console_printf(SWITCH_CHANNEL_CONSOLE_CLEAN, "\nName = %s\n", pdi->name );
- switch_console_printf(SWITCH_CHANNEL_CONSOLE_CLEAN, "Max Inputs = %d", pdi->maxInputChannels );
- switch_console_printf(SWITCH_CHANNEL_CONSOLE_CLEAN, ", Max Outputs = %d\n", pdi->maxOutputChannels );
- if( pdi->numSampleRates == -1 )
- {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE_CLEAN, "Sample Rate Range = %f to %f\n", pdi->sampleRates[0], pdi->sampleRates[1] );
- }
- else
- {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE_CLEAN, "Sample Rates =");
- for( j=0; j<pdi->numSampleRates; j++ )
- {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE_CLEAN, " %8.2f,", pdi->sampleRates[j] );
- }
- switch_console_printf(SWITCH_CHANNEL_CONSOLE_CLEAN, "\n");
- }
- switch_console_printf(SWITCH_CHANNEL_CONSOLE_CLEAN, "Native Sample Formats = ");
- if( pdi->nativeSampleFormats & paInt8 ) switch_console_printf(SWITCH_CHANNEL_CONSOLE_CLEAN, "paInt8, ");
- if( pdi->nativeSampleFormats & paUInt8 ) switch_console_printf(SWITCH_CHANNEL_CONSOLE_CLEAN, "paUInt8, ");
- if( pdi->nativeSampleFormats & paInt16 ) switch_console_printf(SWITCH_CHANNEL_CONSOLE_CLEAN, "paInt16, ");
- if( pdi->nativeSampleFormats & paInt32 ) switch_console_printf(SWITCH_CHANNEL_CONSOLE_CLEAN, "paInt32, ");
- if( pdi->nativeSampleFormats & paFloat32 ) switch_console_printf(SWITCH_CHANNEL_CONSOLE_CLEAN, "paFloat32, ");
- if( pdi->nativeSampleFormats & paInt24 ) switch_console_printf(SWITCH_CHANNEL_CONSOLE_CLEAN, "paInt24, ");
- if( pdi->nativeSampleFormats & paPackedInt24 ) switch_console_printf(SWITCH_CHANNEL_CONSOLE_CLEAN, "paPackedInt24, ");
- switch_console_printf(SWITCH_CHANNEL_CONSOLE_CLEAN, "\n");
- }
-
- switch_console_printf(SWITCH_CHANNEL_CONSOLE_CLEAN, "----------------------------------------------\n");
- return 0;
-error:
- switch_console_printf(SWITCH_CHANNEL_CONSOLE_CLEAN, "An error occured while using the portaudio stream\n" );
- switch_console_printf(SWITCH_CHANNEL_CONSOLE_CLEAN, "Error number: %d\n", err );
- switch_console_printf(SWITCH_CHANNEL_CONSOLE_CLEAN, "Error message: %s\n", Pa_GetErrorText( err ) );
- return err;
-}
-
-static switch_status engage_device(struct private_object *tech_pvt)
-{
- int sample_rate = globals.sample_rate;
- int codec_ms = 20;
-
- switch_channel *channel;
- channel = switch_core_session_get_channel(tech_pvt->session);
- assert(channel != NULL);
-
- if (switch_core_codec_init(&tech_pvt->read_codec,
- "L16",
- sample_rate,
- codec_ms,
- 1,
- SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
- NULL,
- switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Can't load codec?\n");
- return SWITCH_STATUS_FALSE;
- } else {
- if (switch_core_codec_init(&tech_pvt->write_codec,
- "L16",
- sample_rate,
- codec_ms,
- 1,
- SWITCH_CODEC_FLAG_ENCODE |SWITCH_CODEC_FLAG_DECODE,
- NULL,
- switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Can't load codec?\n");
- switch_core_codec_destroy(&tech_pvt->read_codec);
- return SWITCH_STATUS_FALSE;
- }
- }
- tech_pvt->read_frame.rate = sample_rate;
- tech_pvt->read_frame.codec = &tech_pvt->read_codec;
- switch_core_session_set_read_codec(tech_pvt->session, &tech_pvt->read_codec);
- switch_core_session_set_write_codec(tech_pvt->session, &tech_pvt->write_codec);
-
- tech_pvt->indev = globals.indev;
- tech_pvt->outdev = globals.outdev;
-
- switch_mutex_lock(globals.device_lock);
- if ((tech_pvt->err = OpenAudioStream( &tech_pvt->audio_in, sample_rate, SAMPLE_TYPE, PABLIO_READ | PABLIO_MONO, tech_pvt->indev, -1)) == paNoError) {
- if ((tech_pvt->err = OpenAudioStream(&tech_pvt->audio_out, sample_rate, SAMPLE_TYPE, PABLIO_WRITE | PABLIO_MONO, -1, tech_pvt->outdev)) != paNoError) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Can't open audio out [%d]!\n", tech_pvt->outdev);
- CloseAudioStream(tech_pvt->audio_in);
- tech_pvt->audio_in = NULL;
- }
- } else {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Can't open audio in [%d]!\n", tech_pvt->indev);
- }
- switch_mutex_unlock(globals.device_lock);
-
- if (tech_pvt->err == paNoError) {
- snprintf(tech_pvt->call_id, sizeof(tech_pvt->call_id), "%d", globals.call_id++);
- switch_core_hash_insert(globals.call_hash, tech_pvt->call_id, tech_pvt);
- return SWITCH_STATUS_SUCCESS;
- } else {
- switch_core_codec_destroy(&tech_pvt->read_codec);
- switch_core_codec_destroy(&tech_pvt->write_codec);
- switch_core_session_destroy(&tech_pvt->session);
- }
-
- return SWITCH_STATUS_FALSE;
-}
-
-static switch_status place_call(char *dest, char *out, size_t outlen)
-{
- switch_core_session *session;
- switch_status status = SWITCH_STATUS_FALSE;
-
- if (!dest) {
- strncpy(out, "Usage: pacall <exten>", outlen - 1);
- return SWITCH_STATUS_FALSE;
- }
-
- strncpy(out, "FAIL", outlen - 1);
-
- if ((session = switch_core_session_request(&channel_endpoint_interface, NULL))) {
- struct private_object *tech_pvt;
- switch_channel *channel;
- if ((tech_pvt = (struct private_object *) switch_core_session_alloc(session, sizeof(struct private_object)))) {
- memset(tech_pvt, 0, sizeof(*tech_pvt));
- channel = switch_core_session_get_channel(session);
- switch_core_session_set_private(session, tech_pvt);
- tech_pvt->session = session;
- } else {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Hey where is my memory pool?\n");
- switch_core_session_destroy(&session);
- return SWITCH_STATUS_FALSE;
- }
-
- if ((tech_pvt->caller_profile = switch_caller_profile_new(session,
- globals.dialplan,
- globals.cid_name,
- globals.cid_num,
- NULL,
- NULL,
- NULL,
- dest))) {
- char name[128];
- switch_channel_set_caller_profile(channel, tech_pvt->caller_profile);
- snprintf(name, sizeof(name), "PortAudio/%s-%04x", tech_pvt->caller_profile->destination_number ? tech_pvt->caller_profile->destination_number : modname, rand() & 0xffff);
- switch_channel_set_name(channel, name);
- }
- tech_pvt->session = session;
- if ((status = engage_device(tech_pvt)) == SWITCH_STATUS_SUCCESS) {
- switch_channel_set_state(channel, CS_INIT);
- switch_core_session_thread_launch(tech_pvt->session);
- snprintf(out, outlen, "SUCCESS: %s", tech_pvt->call_id);
- }
- }
- return status;
-}
-
-
-static switch_status hup_call(char *callid, char *out, size_t outlen)
-{
- struct private_object *tech_pvt;
- switch_channel *channel = NULL;
- char tmp[50];
-
- if (callid && !strcasecmp(callid, "last")) {
- snprintf(tmp, sizeof(tmp), "%d", globals.call_id - 1);
- callid = tmp;
- }
- if (!callid || !strcasecmp(callid, "all")) {
- switch_hash_index_t* hi;
- void *val;
- int i = 0;
-
- for (hi = apr_hash_first(module_pool, globals.call_hash); hi; hi = switch_hash_next(hi)) {
- switch_hash_this(hi, NULL, NULL, &val);
- tech_pvt = val;
- channel = switch_core_session_get_channel(tech_pvt->session);
- assert(channel != NULL);
- switch_channel_hangup(channel);
- i++;
- }
-
- snprintf(out, outlen, "HUNGUP: %d", i);
-
- return SWITCH_STATUS_SUCCESS;
- }
-
- if ((tech_pvt = switch_core_hash_find(globals.call_hash, callid))) {
-
- channel = switch_core_session_get_channel(tech_pvt->session);
- assert(channel != NULL);
-
- switch_channel_hangup(channel);
- strncpy(out, "OK", outlen - 1);
- } else {
- strncpy(out, "NO SUCH CALL", outlen - 1);
- }
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-
-static switch_status send_dtmf(char *callid, char *out, size_t outlen)
-{
- struct private_object *tech_pvt = NULL;
- switch_channel *channel = NULL;
- char *dtmf;
-
- if ((dtmf = strchr(callid, ' '))) {
- *dtmf++ = '\0';
- } else {
- dtmf = "";
- }
-
- if ((tech_pvt = switch_core_hash_find(globals.call_hash, callid))) {
- channel = switch_core_session_get_channel(tech_pvt->session);
- assert(channel != NULL);
- switch_channel_queue_dtmf(channel, dtmf);
- strncpy(out, "OK", outlen - 1);
- } else {
- strncpy(out, "NO SUCH CALL", outlen - 1);
- }
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-static switch_status answer_call(char *callid, char *out, size_t outlen)
-{
- struct private_object *tech_pvt = NULL;
- switch_channel *channel = NULL;
-
- if ((tech_pvt = switch_core_hash_find(globals.call_hash, callid))) {
- channel = switch_core_session_get_channel(tech_pvt->session);
- assert(channel != NULL);
- switch_set_flag(tech_pvt, TFLAG_ANSWER);
- switch_channel_answer(channel);
- } else {
- strncpy(out, "NO SUCH CALL", outlen - 1);
- }
- return SWITCH_STATUS_SUCCESS;
-}
-
-
-static void print_info(struct private_object *tech_pvt, char *out, size_t outlen)
-{
- switch_channel *channel = NULL;
- channel = switch_core_session_get_channel(tech_pvt->session);
- assert(channel != NULL);
-
- snprintf(out, outlen, "CALL %s\t%s\t%s\t%s\t%s\n",
- tech_pvt->call_id,
- tech_pvt->caller_profile->caller_id_name ? tech_pvt->caller_profile->caller_id_name : "n/a",
- tech_pvt->caller_profile->caller_id_number ? tech_pvt->caller_profile->caller_id_number : "n/a",
- tech_pvt->caller_profile->destination_number ? tech_pvt->caller_profile->destination_number : "n/a",
- switch_channel_get_name(channel));
-
-}
-
-static switch_status call_info(char *callid, char *out, size_t outlen)
-{
- struct private_object *tech_pvt;
- switch_hash_index_t* hi;
- void *val;
- if (!callid || !strcasecmp(callid, "all")) {
- for (hi = apr_hash_first(module_pool, globals.call_hash); hi; hi = switch_hash_next(hi)) {
- switch_hash_this(hi, NULL, NULL, &val);
- tech_pvt = val;
- print_info(tech_pvt, out + strlen(out), outlen - strlen(out));
- }
- } else if ((tech_pvt = switch_core_hash_find(globals.call_hash, callid))) {
- print_info(tech_pvt, out, outlen);
- } else {
- strncpy(out, "NO SUCH CALL", outlen - 1);
- }
-
- return SWITCH_STATUS_SUCCESS;
-}
+++ /dev/null
-/*\r
- * $Id: pablio.c,v 1.1.1.1.4.4 2003/03/13 17:28:33 philburk Exp $\r
- * pablio.c\r
- * Portable Audio Blocking Input/Output utility.\r
- *\r
- * Author: Phil Burk, http://www.softsynth.com\r
- *\r
- * This program uses the PortAudio Portable Audio Library.\r
- * For more information see: http://www.audiomulch.com/portaudio/\r
- * Copyright (c) 1999-2000 Ross Bencina and Phil Burk\r
- *\r
- * Permission is hereby granted, free of charge, to any person obtaining\r
- * a copy of this software and associated documentation files\r
- * (the "Software"), to deal in the Software without restriction,\r
- * including without limitation the rights to use, copy, modify, merge,\r
- * publish, distribute, sublicense, and/or sell copies of the Software,\r
- * and to permit persons to whom the Software is furnished to do so,\r
- * subject to the following conditions:\r
- *\r
- * The above copyright notice and this permission notice shall be\r
- * included in all copies or substantial portions of the Software.\r
- *\r
- * Any person wishing to distribute modifications to the Software is\r
- * requested to send the modifications to the original developer so that\r
- * they can be incorporated into the canonical version.\r
- *\r
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\r
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR\r
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF\r
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\r
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
- *\r
- */\r
-\r
-/* History:\r
- * PLB021214 - check for valid stream in CloseAudioStream() to prevent hang.\r
- * add timeOutMSec to CloseAudioStream() to prevent hang.\r
- */\r
-#include <stdio.h>\r
-#include <stdlib.h>\r
-#include <math.h>\r
-#include "portaudio.h"\r
-#include "ringbuffer.h"\r
-#include "pablio.h"\r
-#include <string.h>\r
-\r
-/************************************************************************/\r
-/******** Constants *****************************************************/\r
-/************************************************************************/\r
-\r
-#define FRAMES_PER_BUFFER (256)\r
-\r
-/************************************************************************/\r
-/******** Prototypes ****************************************************/\r
-/************************************************************************/\r
-\r
-static int blockingIOCallback( void *inputBuffer, void *outputBuffer,\r
- unsigned long framesPerBuffer,\r
- PaTimestamp outTime, void *userData );\r
-static PaError PABLIO_InitFIFO( RingBuffer *rbuf, long numFrames, long bytesPerFrame );\r
-static PaError PABLIO_TermFIFO( RingBuffer *rbuf );\r
-\r
-/************************************************************************/\r
-/******** Functions *****************************************************/\r
-/************************************************************************/\r
-\r
-/* Called from PortAudio.\r
- * Read and write data only if there is room in FIFOs.\r
- */\r
-static int blockingIOCallback( void *inputBuffer, void *outputBuffer,\r
- unsigned long framesPerBuffer,\r
- PaTimestamp outTime, void *userData )\r
-{\r
- PABLIO_Stream *data = (PABLIO_Stream*)userData;\r
- long numBytes = data->bytesPerFrame * framesPerBuffer;\r
- (void) outTime;\r
-\r
- /* This may get called with NULL inputBuffer during initial setup. */\r
- if( inputBuffer != NULL )\r
- {\r
- RingBuffer_Write( &data->inFIFO, inputBuffer, numBytes );\r
- }\r
- if( outputBuffer != NULL )\r
- {\r
- int i;\r
- int numRead = RingBuffer_Read( &data->outFIFO, outputBuffer, numBytes );\r
- /* Zero out remainder of buffer if we run out of data. */\r
- for( i=numRead; i<numBytes; i++ )\r
- {\r
- ((char *)outputBuffer)[i] = 0;\r
- }\r
- }\r
-\r
- return 0;\r
-}\r
-\r
-/* Allocate buffer. */\r
-static PaError PABLIO_InitFIFO( RingBuffer *rbuf, long numFrames, long bytesPerFrame )\r
-{\r
- long numBytes = numFrames * bytesPerFrame;\r
- char *buffer = (char *) malloc( numBytes );\r
- if( buffer == NULL ) return paInsufficientMemory;\r
- memset( buffer, 0, numBytes );\r
- return (PaError) RingBuffer_Init( rbuf, numBytes, buffer );\r
-}\r
-\r
-/* Free buffer. */\r
-static PaError PABLIO_TermFIFO( RingBuffer *rbuf )\r
-{\r
- if( rbuf->buffer ) free( rbuf->buffer );\r
- rbuf->buffer = NULL;\r
- return paNoError;\r
-}\r
-\r
-/************************************************************\r
- * Write data to ring buffer.\r
- * Will not return until all the data has been written.\r
- */\r
-long WriteAudioStream( PABLIO_Stream *aStream, void *data, long numFrames )\r
-{\r
- long bytesWritten;\r
- char *p = (char *) data;\r
- long numBytes = aStream->bytesPerFrame * numFrames;\r
- while( numBytes > 0)\r
- {\r
- bytesWritten = RingBuffer_Write( &aStream->outFIFO, p, numBytes );\r
- numBytes -= bytesWritten;\r
- p += bytesWritten;\r
- if( numBytes > 0) Pa_Sleep(10);\r
- }\r
- return numFrames;\r
-}\r
-\r
-/************************************************************\r
- * Read data from ring buffer.\r
- * Will not return until all the data has been read.\r
- */\r
-long ReadAudioStream( PABLIO_Stream *aStream, void *data, long numFrames )\r
-{\r
- long bytesRead;\r
- char *p = (char *) data;\r
- long numBytes = aStream->bytesPerFrame * numFrames;\r
- while( numBytes > 0)\r
- {\r
- bytesRead = RingBuffer_Read( &aStream->inFIFO, p, numBytes );\r
- numBytes -= bytesRead;\r
- p += bytesRead;\r
- if( numBytes > 0) Pa_Sleep(10);\r
- }\r
- return numFrames;\r
-}\r
-\r
-/************************************************************\r
- * Return the number of frames that could be written to the stream without\r
- * having to wait.\r
- */\r
-long GetAudioStreamWriteable( PABLIO_Stream *aStream )\r
-{\r
- int bytesEmpty = RingBuffer_GetWriteAvailable( &aStream->outFIFO );\r
- return bytesEmpty / aStream->bytesPerFrame;\r
-}\r
-\r
-/************************************************************\r
- * Return the number of frames that are available to be read from the\r
- * stream without having to wait.\r
- */\r
-long GetAudioStreamReadable( PABLIO_Stream *aStream )\r
-{\r
- int bytesFull = RingBuffer_GetReadAvailable( &aStream->inFIFO );\r
- return bytesFull / aStream->bytesPerFrame;\r
-}\r
-\r
-/************************************************************/\r
-static unsigned long RoundUpToNextPowerOf2( unsigned long n )\r
-{\r
- long numBits = 0;\r
- if( ((n-1) & n) == 0) return n; /* Already Power of two. */\r
- while( n > 0 )\r
- {\r
- n= n>>1;\r
- numBits++;\r
- }\r
- return (1<<numBits);\r
-}\r
-\r
-/************************************************************\r
- * Opens a PortAudio stream with default characteristics.\r
- * Allocates PABLIO_Stream structure.\r
- *\r
- * flags parameter can be an ORed combination of:\r
- * PABLIO_READ, PABLIO_WRITE, or PABLIO_READ_WRITE,\r
- * and either PABLIO_MONO or PABLIO_STEREO\r
- */\r
-PaError OpenAudioStream( PABLIO_Stream **rwblPtr, double sampleRate,\r
- PaSampleFormat format, long flags, int indev, int outdev )\r
-{\r
- long bytesPerSample;\r
- long doRead = 0;\r
- long doWrite = 0;\r
- PaError err;\r
- PABLIO_Stream *aStream;\r
- long minNumBuffers;\r
- long numFrames;\r
-\r
- /* Allocate PABLIO_Stream structure for caller. */\r
- aStream = (PABLIO_Stream *) malloc( sizeof(PABLIO_Stream) );\r
- if( aStream == NULL ) return paInsufficientMemory;\r
- memset( aStream, 0, sizeof(PABLIO_Stream) );\r
-\r
- /* Determine size of a sample. */\r
- bytesPerSample = Pa_GetSampleSize( format );\r
- if( bytesPerSample < 0 )\r
- {\r
- err = (PaError) bytesPerSample;\r
- goto error;\r
- }\r
- aStream->samplesPerFrame = ((flags&PABLIO_MONO) != 0) ? 1 : 2;\r
- aStream->bytesPerFrame = bytesPerSample * aStream->samplesPerFrame;\r
-\r
- /* Initialize PortAudio */\r
- err = Pa_Initialize();\r
- if( err != paNoError ) goto error;\r
-\r
- /* Warning: numFrames must be larger than amount of data processed per interrupt\r
- * inside PA to prevent glitches. Just to be safe, adjust size upwards.\r
- */\r
- minNumBuffers = 2 * Pa_GetMinNumBuffers( FRAMES_PER_BUFFER, sampleRate );\r
- numFrames = minNumBuffers * FRAMES_PER_BUFFER;\r
- /* The PortAudio callback runs in a high priority thread. But PABLIO\r
- * runs in a normal foreground thread. So we may have much worse\r
- * latency in PABLIO. So adjust latency to a safe level.\r
- */\r
- {\r
- const int safeLatencyMSec = 200;\r
- int minLatencyMSec = (int) ((1000 * numFrames) / sampleRate);\r
- if( minLatencyMSec < safeLatencyMSec )\r
- {\r
- numFrames = (int) ((safeLatencyMSec * sampleRate) / 1000);\r
- }\r
- }\r
- numFrames = RoundUpToNextPowerOf2( numFrames );\r
-\r
- /* Initialize Ring Buffers */\r
- doRead = ((flags & PABLIO_READ) != 0);\r
- doWrite = ((flags & PABLIO_WRITE) != 0);\r
- if(doRead)\r
- {\r
- err = PABLIO_InitFIFO( &aStream->inFIFO, numFrames, aStream->bytesPerFrame );\r
- if( err != paNoError ) goto error;\r
- }\r
- if(doWrite)\r
- {\r
- long numBytes;\r
- err = PABLIO_InitFIFO( &aStream->outFIFO, numFrames, aStream->bytesPerFrame );\r
- if( err != paNoError ) goto error;\r
- /* Make Write FIFO appear full initially. */\r
- numBytes = RingBuffer_GetWriteAvailable( &aStream->outFIFO );\r
- RingBuffer_AdvanceWriteIndex( &aStream->outFIFO, numBytes );\r
- }\r
-\r
- /* Open a PortAudio stream that we will use to communicate with the underlying\r
- * audio drivers. */\r
- err = Pa_OpenStream(\r
- &aStream->stream,\r
- (doRead ? (indev > -1) ? indev : Pa_GetDefaultInputDeviceID() : paNoDevice),\r
- (doRead ? aStream->samplesPerFrame : 0 ),\r
- format,\r
- NULL,\r
- (doWrite ? (outdev > -1) ? outdev : Pa_GetDefaultOutputDeviceID() : paNoDevice),\r
- (doWrite ? aStream->samplesPerFrame : 0 ),\r
- format,\r
- NULL,\r
- sampleRate,\r
- FRAMES_PER_BUFFER,\r
- minNumBuffers,\r
- paClipOff, /* we won't output out of range samples so don't bother clipping them */\r
- blockingIOCallback,\r
- aStream );\r
- if( err != paNoError ) goto error;\r
-\r
- err = Pa_StartStream( aStream->stream );\r
- if( err != paNoError ) goto error;\r
-\r
- *rwblPtr = aStream;\r
- return paNoError;\r
-\r
-error:\r
- CloseAudioStream( aStream );\r
- *rwblPtr = NULL;\r
- return err;\r
-}\r
-\r
-/************************************************************/\r
-PaError CloseAudioStream( PABLIO_Stream *aStream )\r
-{\r
- PaError err = paNoError;\r
- int bytesEmpty;\r
- int byteSize = aStream->outFIFO.bufferSize;\r
-\r
- if( aStream->stream != NULL ) /* Make sure stream was opened. PLB021214 */\r
- {\r
- /* If we are writing data, make sure we play everything written. */\r
- if( byteSize > 0 )\r
- {\r
- int timeOutMSec = 2000;\r
- bytesEmpty = RingBuffer_GetWriteAvailable( &aStream->outFIFO );\r
- while( (bytesEmpty < byteSize) && (timeOutMSec > 0) )\r
- {\r
- Pa_Sleep( 20 );\r
- timeOutMSec -= 20;\r
- bytesEmpty = RingBuffer_GetWriteAvailable( &aStream->outFIFO );\r
- }\r
- }\r
- err = Pa_StopStream( aStream->stream );\r
- if( err != paNoError ) goto error;\r
- err = Pa_CloseStream( aStream->stream );\r
- }\r
-\r
-error:\r
- Pa_Terminate();\r
- PABLIO_TermFIFO( &aStream->inFIFO );\r
- PABLIO_TermFIFO( &aStream->outFIFO );\r
- free( aStream );\r
- return err;\r
-}\r
+++ /dev/null
-#ifndef _PABLIO_H\r
-#define _PABLIO_H\r
-\r
-#ifdef __cplusplus\r
-extern "C"\r
-{\r
-#endif /* __cplusplus */\r
-\r
-/*\r
- * $Id: pablio.h,v 1.1.1.1 2002/01/22 00:52:53 phil Exp $\r
- * PABLIO.h\r
- * Portable Audio Blocking read/write utility.\r
- *\r
- * Author: Phil Burk, http://www.softsynth.com/portaudio/\r
- *\r
- * Include file for PABLIO, the Portable Audio Blocking I/O Library.\r
- * PABLIO is built on top of PortAudio, the Portable Audio Library.\r
- * For more information see: http://www.audiomulch.com/portaudio/\r
- * Copyright (c) 1999-2000 Ross Bencina and Phil Burk\r
- *\r
- * Permission is hereby granted, free of charge, to any person obtaining\r
- * a copy of this software and associated documentation files\r
- * (the "Software"), to deal in the Software without restriction,\r
- * including without limitation the rights to use, copy, modify, merge,\r
- * publish, distribute, sublicense, and/or sell copies of the Software,\r
- * and to permit persons to whom the Software is furnished to do so,\r
- * subject to the following conditions:\r
- *\r
- * The above copyright notice and this permission notice shall be\r
- * included in all copies or substantial portions of the Software.\r
- *\r
- * Any person wishing to distribute modifications to the Software is\r
- * requested to send the modifications to the original developer so that\r
- * they can be incorporated into the canonical version.\r
- *\r
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\r
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR\r
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF\r
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\r
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
- *\r
- */\r
-#include <stdio.h>\r
-#include <stdlib.h>\r
-#include <math.h>\r
-#include "portaudio.h"\r
-#include "ringbuffer.h"\r
-#include <string.h>\r
-\r
-typedef struct\r
-{\r
- RingBuffer inFIFO;\r
- RingBuffer outFIFO;\r
- PortAudioStream *stream;\r
- int bytesPerFrame;\r
- int samplesPerFrame;\r
-}\r
-PABLIO_Stream;\r
-\r
-/* Values for flags for OpenAudioStream(). */\r
-#define PABLIO_READ (1<<0)\r
-#define PABLIO_WRITE (1<<1)\r
-#define PABLIO_READ_WRITE (PABLIO_READ|PABLIO_WRITE)\r
-#define PABLIO_MONO (1<<2)\r
-#define PABLIO_STEREO (1<<3)\r
-\r
-/************************************************************\r
- * Write data to ring buffer.\r
- * Will not return until all the data has been written.\r
- */\r
-long WriteAudioStream( PABLIO_Stream *aStream, void *data, long numFrames );\r
-\r
-/************************************************************\r
- * Read data from ring buffer.\r
- * Will not return until all the data has been read.\r
- */\r
-long ReadAudioStream( PABLIO_Stream *aStream, void *data, long numFrames );\r
-\r
-/************************************************************\r
- * Return the number of frames that could be written to the stream without\r
- * having to wait.\r
- */\r
-long GetAudioStreamWriteable( PABLIO_Stream *aStream );\r
-\r
-/************************************************************\r
- * Return the number of frames that are available to be read from the\r
- * stream without having to wait.\r
- */\r
-long GetAudioStreamReadable( PABLIO_Stream *aStream );\r
-\r
-/************************************************************\r
- * Opens a PortAudio stream with default characteristics.\r
- * Allocates PABLIO_Stream structure.\r
- *\r
- * flags parameter can be an ORed combination of:\r
- * PABLIO_READ, PABLIO_WRITE, or PABLIO_READ_WRITE,\r
- * and either PABLIO_MONO or PABLIO_STEREO\r
- */\r
-PaError OpenAudioStream( PABLIO_Stream **aStreamPtr, double sampleRate,\r
- PaSampleFormat format, long flags, int indev, int outdev );\r
-\r
-PaError CloseAudioStream( PABLIO_Stream *aStream );\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif /* __cplusplus */\r
-#endif /* _PABLIO_H */\r
+++ /dev/null
-/*\r
- * $Id: ringbuffer.c,v 1.1.1.1 2002/01/22 00:52:53 phil Exp $\r
- * ringbuffer.c\r
- * Ring Buffer utility..\r
- *\r
- * Author: Phil Burk, http://www.softsynth.com\r
- *\r
- * This program uses the PortAudio Portable Audio Library.\r
- * For more information see: http://www.audiomulch.com/portaudio/\r
- * Copyright (c) 1999-2000 Ross Bencina and Phil Burk\r
- *\r
- * Permission is hereby granted, free of charge, to any person obtaining\r
- * a copy of this software and associated documentation files\r
- * (the "Software"), to deal in the Software without restriction,\r
- * including without limitation the rights to use, copy, modify, merge,\r
- * publish, distribute, sublicense, and/or sell copies of the Software,\r
- * and to permit persons to whom the Software is furnished to do so,\r
- * subject to the following conditions:\r
- *\r
- * The above copyright notice and this permission notice shall be\r
- * included in all copies or substantial portions of the Software.\r
- *\r
- * Any person wishing to distribute modifications to the Software is\r
- * requested to send the modifications to the original developer so that\r
- * they can be incorporated into the canonical version.\r
- *\r
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\r
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR\r
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF\r
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\r
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
- *\r
- */\r
-#include <stdio.h>\r
-#include <stdlib.h>\r
-#include <math.h>\r
-#include "ringbuffer.h"\r
-#include <string.h>\r
-\r
-/***************************************************************************\r
- * Initialize FIFO.\r
- * numBytes must be power of 2, returns -1 if not.\r
- */\r
-long RingBuffer_Init( RingBuffer *rbuf, long numBytes, void *dataPtr )\r
-{\r
- if( ((numBytes-1) & numBytes) != 0) return -1; /* Not Power of two. */\r
- rbuf->bufferSize = numBytes;\r
- rbuf->buffer = (char *)dataPtr;\r
- RingBuffer_Flush( rbuf );\r
- rbuf->bigMask = (numBytes*2)-1;\r
- rbuf->smallMask = (numBytes)-1;\r
- return 0;\r
-}\r
-/***************************************************************************\r
-** Return number of bytes available for reading. */\r
-long RingBuffer_GetReadAvailable( RingBuffer *rbuf )\r
-{\r
- return ( (rbuf->writeIndex - rbuf->readIndex) & rbuf->bigMask );\r
-}\r
-/***************************************************************************\r
-** Return number of bytes available for writing. */\r
-long RingBuffer_GetWriteAvailable( RingBuffer *rbuf )\r
-{\r
- return ( rbuf->bufferSize - RingBuffer_GetReadAvailable(rbuf));\r
-}\r
-\r
-/***************************************************************************\r
-** Clear buffer. Should only be called when buffer is NOT being read. */\r
-void RingBuffer_Flush( RingBuffer *rbuf )\r
-{\r
- rbuf->writeIndex = rbuf->readIndex = 0;\r
-}\r
-\r
-/***************************************************************************\r
-** Get address of region(s) to which we can write data.\r
-** If the region is contiguous, size2 will be zero.\r
-** If non-contiguous, size2 will be the size of second region.\r
-** Returns room available to be written or numBytes, whichever is smaller.\r
-*/\r
-long RingBuffer_GetWriteRegions( RingBuffer *rbuf, long numBytes,\r
- void **dataPtr1, long *sizePtr1,\r
- void **dataPtr2, long *sizePtr2 )\r
-{\r
- long index;\r
- long available = RingBuffer_GetWriteAvailable( rbuf );\r
- if( numBytes > available ) numBytes = available;\r
- /* Check to see if write is not contiguous. */\r
- index = rbuf->writeIndex & rbuf->smallMask;\r
- if( (index + numBytes) > rbuf->bufferSize )\r
- {\r
- /* Write data in two blocks that wrap the buffer. */\r
- long firstHalf = rbuf->bufferSize - index;\r
- *dataPtr1 = &rbuf->buffer[index];\r
- *sizePtr1 = firstHalf;\r
- *dataPtr2 = &rbuf->buffer[0];\r
- *sizePtr2 = numBytes - firstHalf;\r
- }\r
- else\r
- {\r
- *dataPtr1 = &rbuf->buffer[index];\r
- *sizePtr1 = numBytes;\r
- *dataPtr2 = NULL;\r
- *sizePtr2 = 0;\r
- }\r
- return numBytes;\r
-}\r
-\r
-\r
-/***************************************************************************\r
-*/\r
-long RingBuffer_AdvanceWriteIndex( RingBuffer *rbuf, long numBytes )\r
-{\r
- return rbuf->writeIndex = (rbuf->writeIndex + numBytes) & rbuf->bigMask;\r
-}\r
-\r
-/***************************************************************************\r
-** Get address of region(s) from which we can read data.\r
-** If the region is contiguous, size2 will be zero.\r
-** If non-contiguous, size2 will be the size of second region.\r
-** Returns room available to be written or numBytes, whichever is smaller.\r
-*/\r
-long RingBuffer_GetReadRegions( RingBuffer *rbuf, long numBytes,\r
- void **dataPtr1, long *sizePtr1,\r
- void **dataPtr2, long *sizePtr2 )\r
-{\r
- long index;\r
- long available = RingBuffer_GetReadAvailable( rbuf );\r
- if( numBytes > available ) numBytes = available;\r
- /* Check to see if read is not contiguous. */\r
- index = rbuf->readIndex & rbuf->smallMask;\r
- if( (index + numBytes) > rbuf->bufferSize )\r
- {\r
- /* Write data in two blocks that wrap the buffer. */\r
- long firstHalf = rbuf->bufferSize - index;\r
- *dataPtr1 = &rbuf->buffer[index];\r
- *sizePtr1 = firstHalf;\r
- *dataPtr2 = &rbuf->buffer[0];\r
- *sizePtr2 = numBytes - firstHalf;\r
- }\r
- else\r
- {\r
- *dataPtr1 = &rbuf->buffer[index];\r
- *sizePtr1 = numBytes;\r
- *dataPtr2 = NULL;\r
- *sizePtr2 = 0;\r
- }\r
- return numBytes;\r
-}\r
-/***************************************************************************\r
-*/\r
-long RingBuffer_AdvanceReadIndex( RingBuffer *rbuf, long numBytes )\r
-{\r
- return rbuf->readIndex = (rbuf->readIndex + numBytes) & rbuf->bigMask;\r
-}\r
-\r
-/***************************************************************************\r
-** Return bytes written. */\r
-long RingBuffer_Write( RingBuffer *rbuf, void *data, long numBytes )\r
-{\r
- long size1, size2, numWritten;\r
- void *data1, *data2;\r
- numWritten = RingBuffer_GetWriteRegions( rbuf, numBytes, &data1, &size1, &data2, &size2 );\r
- if( size2 > 0 )\r
- {\r
-\r
- memcpy( data1, data, size1 );\r
- data = ((char *)data) + size1;\r
- memcpy( data2, data, size2 );\r
- }\r
- else\r
- {\r
- memcpy( data1, data, size1 );\r
- }\r
- RingBuffer_AdvanceWriteIndex( rbuf, numWritten );\r
- return numWritten;\r
-}\r
-\r
-/***************************************************************************\r
-** Return bytes read. */\r
-long RingBuffer_Read( RingBuffer *rbuf, void *data, long numBytes )\r
-{\r
- long size1, size2, numRead;\r
- void *data1, *data2;\r
- numRead = RingBuffer_GetReadRegions( rbuf, numBytes, &data1, &size1, &data2, &size2 );\r
- if( size2 > 0 )\r
- {\r
- memcpy( data, data1, size1 );\r
- data = ((char *)data) + size1;\r
- memcpy( data, data2, size2 );\r
- }\r
- else\r
- {\r
- memcpy( data, data1, size1 );\r
- }\r
- RingBuffer_AdvanceReadIndex( rbuf, numRead );\r
- return numRead;\r
-}\r
+++ /dev/null
-#ifndef _RINGBUFFER_H\r
-#define _RINGBUFFER_H\r
-#ifdef __cplusplus\r
-extern "C"\r
-{\r
-#endif /* __cplusplus */\r
-\r
-/*\r
- * $Id: ringbuffer.h,v 1.1.1.1.4.2 2003/04/28 17:45:34 philburk Exp $\r
- * ringbuffer.h\r
- * Ring Buffer utility..\r
- *\r
- * Author: Phil Burk, http://www.softsynth.com\r
- *\r
- * This program is distributed with the PortAudio Portable Audio Library.\r
- * For more information see: http://www.audiomulch.com/portaudio/\r
- * Copyright (c) 1999-2000 Ross Bencina and Phil Burk\r
- *\r
- * Permission is hereby granted, free of charge, to any person obtaining\r
- * a copy of this software and associated documentation files\r
- * (the "Software"), to deal in the Software without restriction,\r
- * including without limitation the rights to use, copy, modify, merge,\r
- * publish, distribute, sublicense, and/or sell copies of the Software,\r
- * and to permit persons to whom the Software is furnished to do so,\r
- * subject to the following conditions:\r
- *\r
- * The above copyright notice and this permission notice shall be\r
- * included in all copies or substantial portions of the Software.\r
- *\r
- * Any person wishing to distribute modifications to the Software is\r
- * requested to send the modifications to the original developer so that\r
- * they can be incorporated into the canonical version.\r
- *\r
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\r
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR\r
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF\r
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\r
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
- *\r
- */\r
-#define PortAudioStream PaStream\r
-#include <stdio.h>\r
-#include <stdlib.h>\r
-#include <math.h>\r
-#include "ringbuffer.h"\r
-#include <string.h>\r
-\r
-typedef struct\r
-{\r
- long bufferSize; /* Number of bytes in FIFO. Power of 2. Set by RingBuffer_Init. */\r
-/* These are declared volatile because they are written by a different thread than the reader. */\r
- volatile long writeIndex; /* Index of next writable byte. Set by RingBuffer_AdvanceWriteIndex. */\r
- volatile long readIndex; /* Index of next readable byte. Set by RingBuffer_AdvanceReadIndex. */\r
- long bigMask; /* Used for wrapping indices with extra bit to distinguish full/empty. */\r
- long smallMask; /* Used for fitting indices to buffer. */\r
- char *buffer;\r
-}\r
-RingBuffer;\r
-/*\r
- * Initialize Ring Buffer.\r
- * numBytes must be power of 2, returns -1 if not.\r
- */\r
-long RingBuffer_Init( RingBuffer *rbuf, long numBytes, void *dataPtr );\r
-\r
-/* Clear buffer. Should only be called when buffer is NOT being read. */\r
-void RingBuffer_Flush( RingBuffer *rbuf );\r
-\r
-/* Return number of bytes available for writing. */\r
-long RingBuffer_GetWriteAvailable( RingBuffer *rbuf );\r
-/* Return number of bytes available for read. */\r
-long RingBuffer_GetReadAvailable( RingBuffer *rbuf );\r
-/* Return bytes written. */\r
-long RingBuffer_Write( RingBuffer *rbuf, void *data, long numBytes );\r
-/* Return bytes read. */\r
-long RingBuffer_Read( RingBuffer *rbuf, void *data, long numBytes );\r
-\r
-/* Get address of region(s) to which we can write data.\r
-** If the region is contiguous, size2 will be zero.\r
-** If non-contiguous, size2 will be the size of second region.\r
-** Returns room available to be written or numBytes, whichever is smaller.\r
-*/\r
-long RingBuffer_GetWriteRegions( RingBuffer *rbuf, long numBytes,\r
- void **dataPtr1, long *sizePtr1,\r
- void **dataPtr2, long *sizePtr2 );\r
-long RingBuffer_AdvanceWriteIndex( RingBuffer *rbuf, long numBytes );\r
-\r
-/* Get address of region(s) from which we can read data.\r
-** If the region is contiguous, size2 will be zero.\r
-** If non-contiguous, size2 will be the size of second region.\r
-** Returns room available to be read or numBytes, whichever is smaller.\r
-*/\r
-long RingBuffer_GetReadRegions( RingBuffer *rbuf, long numBytes,\r
- void **dataPtr1, long *sizePtr1,\r
- void **dataPtr2, long *sizePtr2 );\r
-\r
-long RingBuffer_AdvanceReadIndex( RingBuffer *rbuf, long numBytes );\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif /* __cplusplus */\r
-#endif /* _RINGBUFFER_H */\r
+++ /dev/null
-/*
- * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
- * Copyright (C) 2005/2006, Anthony Minessale II <anthmct@yahoo.com>
- *
- * Version: MPL 1.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
- *
- * The Initial Developer of the Original Code is
- * Anthony Minessale II <anthmct@yahoo.com>
- * Portions created by the Initial Developer are Copyright (C)
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Anthony Minessale II <anthmct@yahoo.com>
- *
- *
- * mod_rawaudio.c -- Raw Signed Linear Codec
- *
- */
-#include <switch.h>
-#include <libresample.h>
-
-static const char modname[] = "mod_rawaudio";
-
-
-static switch_status switch_raw_init(switch_codec *codec, switch_codec_flag flags, const struct switch_codec_settings *codec_settings)
-{
- int encoding, decoding;
- struct raw_context *context = NULL;
-
- encoding = (flags & SWITCH_CODEC_FLAG_ENCODE);
- decoding = (flags & SWITCH_CODEC_FLAG_DECODE);
-
- if (!(encoding || decoding)) {
- return SWITCH_STATUS_FALSE;
- } else {
- return SWITCH_STATUS_SUCCESS;
- }
-}
-
-static switch_status switch_raw_encode(switch_codec *codec,
- switch_codec *other_codec,
- void *decoded_data,
- size_t decoded_data_len,
- int decoded_rate,
- void *encoded_data,
- size_t *encoded_data_len,
- int *encoded_rate,
- unsigned int *flag)
-{
-
- /* NOOP indicates that the audio in is already the same as the audio out, so no conversion was necessary.*/
- if (decoded_rate != codec->implementation->samples_per_second) {
- memcpy(encoded_data, decoded_data, decoded_data_len);
- *encoded_data_len = decoded_data_len;
- return SWITCH_STATUS_RESAMPLE;
- }
- return SWITCH_STATUS_NOOP;
-}
-
-static switch_status switch_raw_decode(switch_codec *codec,
- switch_codec *other_codec,
- void *encoded_data,
- size_t encoded_data_len,
- int encoded_rate,
- void *decoded_data,
- size_t *decoded_data_len,
- int *decoded_rate,
- unsigned int *flag)
-{
- if (encoded_rate != other_codec->implementation->samples_per_second) {
- memcpy(decoded_data, encoded_data, encoded_data_len);
- *decoded_data_len = encoded_data_len;
- return SWITCH_STATUS_RESAMPLE;
- }
- return SWITCH_STATUS_NOOP;
-}
-
-
-static switch_status switch_raw_destroy(switch_codec *codec)
-{
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-static const switch_codec_implementation raw_32k_implementation = {
- /*.samples_per_second = */ 32000,
- /*.bits_per_second = */ 512000,
- /*.microseconds_per_frame = */ 20000,
- /*.samples_per_frame = */ 640,
- /*.bytes_per_frame = */ 1280,
- /*.encoded_bytes_per_frame = */ 1280,
- /*.number_of_channels = */ 1,
- /*.pref_frames_per_packet = */ 1,
- /*.max_frames_per_packet = */ 1,
- /*.init = */ switch_raw_init,
- /*.encode = */ switch_raw_encode,
- /*.decode = */ switch_raw_decode,
- /*.destroy = */ switch_raw_destroy
-};
-
-static const switch_codec_implementation raw_22k_implementation = {
- /*.samples_per_second = */ 22050,
- /*.bits_per_second = */ 352800,
- /*.microseconds_per_frame = */ 20000,
- /*.samples_per_frame = */ 441,
- /*.bytes_per_frame = */ 882,
- /*.encoded_bytes_per_frame = */ 882,
- /*.number_of_channels = */ 1,
- /*.pref_frames_per_packet = */ 1,
- /*.max_frames_per_packet = */ 1,
- /*.init = */ switch_raw_init,
- /*.encode = */ switch_raw_encode,
- /*.decode = */ switch_raw_decode,
- /*.destroy = */ switch_raw_destroy,
- /*.next = */ &raw_32k_implementation
-};
-
-static const switch_codec_implementation raw_16k_implementation = {
- /*.samples_per_second = */ 16000,
- /*.bits_per_second = */ 256000,
- /*.microseconds_per_frame = */ 20000,
- /*.samples_per_frame = */ 320,
- /*.bytes_per_frame = */ 640,
- /*.encoded_bytes_per_frame = */ 640,
- /*.number_of_channels = */ 1,
- /*.pref_frames_per_packet = */ 1,
- /*.max_frames_per_packet = */ 1,
- /*.init = */ switch_raw_init,
- /*.encode = */ switch_raw_encode,
- /*.decode = */ switch_raw_decode,
- /*.destroy = */ switch_raw_destroy,
- /*.next = */ &raw_22k_implementation
-};
-
-static const switch_codec_implementation raw_8k_implementation = {
- /*.samples_per_second = */ 8000,
- /*.bits_per_second = */ 128000,
- /*.microseconds_per_frame = */ 20000,
- /*.samples_per_frame = */ 160,
- /*.bytes_per_frame = */ 320,
- /*.encoded_bytes_per_frame = */ 320,
- /*.number_of_channels = */ 1,
- /*.pref_frames_per_packet = */ 1,
- /*.max_frames_per_packet = */ 1,
- /*.init = */ switch_raw_init,
- /*.encode = */ switch_raw_encode,
- /*.decode = */ switch_raw_decode,
- /*.destroy = */ switch_raw_destroy,
- /*.next = */ &raw_16k_implementation
-};
-
-
-static const switch_codec_implementation raw_8k_30ms_implementation = {
- /*.samples_per_second*/ 8000,
- /*.bits_per_second*/ 128000,
- /*.microseconds_per_frame*/ 30000,
- /*.samples_per_frame*/ 240,
- /*.bytes_per_frame*/ 480,
- /*.encoded_bytes_per_frame*/ 480,
- /*.number_of_channels*/ 1,
- /*.pref_frames_per_packet*/ 1,
- /*.max_frames_per_packet*/ 1,
- /*.init*/ switch_raw_init,
- /*.encode*/ switch_raw_encode,
- /*.decode*/ switch_raw_decode,
- /*.destroy*/ switch_raw_destroy,
- /*.next*/ &raw_8k_implementation
-};
-
-
-static const switch_codec_interface raw_codec_interface = {
- /*.interface_name*/ "raw signed linear (16 bit)",
- /*.codec_type*/ SWITCH_CODEC_TYPE_AUDIO,
- /*.ianacode*/ 10,
- /*.iananame*/ "L16",
- /*.implementations*/ &raw_8k_30ms_implementation
-};
-
-static switch_loadable_module_interface raw_module_interface = {
- /*.module_name*/ modname,
- /*.endpoint_interface*/ NULL,
- /*.timer_interface*/ NULL,
- /*.dialplan_interface*/ NULL,
- /*.codec_interface*/ &raw_codec_interface,
- /*.application_interface*/ NULL,
- /*.api_interface*/ NULL,
- ///*.file_interface*/ &raw_file_interface
-};
-
-
-SWITCH_MOD_DECLARE(switch_status) switch_module_load(const switch_loadable_module_interface **interface, char *filename) {
- /* connect my internal structure to the blank pointer passed to me */
- *interface = &raw_module_interface;
-
- /* indicate that the module should continue to be loaded */
- return SWITCH_STATUS_SUCCESS;
-}
-
-
-
-
-
+++ /dev/null
-<?xml version="1.0" encoding="Windows-1252"?>\r
-<VisualStudioProject\r
- ProjectType="Visual C++"\r
- Version="8.00"\r
- Name="mod_rawaudio"\r
- ProjectGUID="{5844AFE1-AA3E-4BDB-A9EF-119AEF19DF88}"\r
- RootNamespace="mod_rawaudio"\r
- Keyword="Win32Proj"\r
- >\r
- <Platforms>\r
- <Platform\r
- Name="Win32"\r
- />\r
- </Platforms>\r
- <ToolFiles>\r
- </ToolFiles>\r
- <Configurations>\r
- <Configuration\r
- Name="Debug|Win32"\r
- OutputDirectory="Debug"\r
- IntermediateDirectory="Debug"\r
- ConfigurationType="2"\r
- InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
- CharacterSet="2"\r
- >\r
- <Tool\r
- Name="VCPreBuildEventTool"\r
- CommandLine="cscript /nologo $(InputDir)..\..\..\w32\vsnet\getlibs.vbs Mod_rawaudio Debug"\r
- />\r
- <Tool\r
- Name="VCCustomBuildTool"\r
- />\r
- <Tool\r
- Name="VCXMLDataGeneratorTool"\r
- />\r
- <Tool\r
- Name="VCWebServiceProxyGeneratorTool"\r
- />\r
- <Tool\r
- Name="VCMIDLTool"\r
- />\r
- <Tool\r
- Name="VCCLCompilerTool"\r
- Optimization="0"\r
- AdditionalIncludeDirectories=""$(InputDir)..\..\include";"$(InputDir)include";"$(InputDir)..\..\..\libs\include";"$(InputDir)..\..\..\libs\libresample\include""\r
- PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS"\r
- MinimalRebuild="true"\r
- BasicRuntimeChecks="3"\r
- RuntimeLibrary="1"\r
- UsePrecompiledHeader="0"\r
- WarningLevel="3"\r
- Detect64BitPortabilityProblems="true"\r
- DebugInformationFormat="4"\r
- />\r
- <Tool\r
- Name="VCManagedResourceCompilerTool"\r
- />\r
- <Tool\r
- Name="VCResourceCompilerTool"\r
- />\r
- <Tool\r
- Name="VCPreLinkEventTool"\r
- />\r
- <Tool\r
- Name="VCLinkerTool"\r
- AdditionalDependencies="libresampled.lib"\r
- OutputFile="..\..\..\w32\vsnet\$(OutDir)/mod/mod_rawaudio.dll"\r
- LinkIncremental="2"\r
- AdditionalLibraryDirectories=""$(InputDir)..\..\..\libs\libresample\win""\r
- GenerateDebugInformation="true"\r
- ProgramDatabaseFile="$(OutDir)/mod_rawaudio.pdb"\r
- SubSystem="2"\r
- ImportLibrary="$(OutDir)/mod_rawaudio.lib"\r
- TargetMachine="1"\r
- />\r
- <Tool\r
- Name="VCALinkTool"\r
- />\r
- <Tool\r
- Name="VCManifestTool"\r
- />\r
- <Tool\r
- Name="VCXDCMakeTool"\r
- />\r
- <Tool\r
- Name="VCBscMakeTool"\r
- />\r
- <Tool\r
- Name="VCFxCopTool"\r
- />\r
- <Tool\r
- Name="VCAppVerifierTool"\r
- />\r
- <Tool\r
- Name="VCWebDeploymentTool"\r
- />\r
- <Tool\r
- Name="VCPostBuildEventTool"\r
- />\r
- </Configuration>\r
- <Configuration\r
- Name="Release|Win32"\r
- OutputDirectory="Release"\r
- IntermediateDirectory="Release"\r
- ConfigurationType="2"\r
- InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
- CharacterSet="2"\r
- >\r
- <Tool\r
- Name="VCPreBuildEventTool"\r
- CommandLine="cscript /nologo $(InputDir)..\..\..\w32\vsnet\getlibs.vbs Mod_rawaudio Release"\r
- />\r
- <Tool\r
- Name="VCCustomBuildTool"\r
- />\r
- <Tool\r
- Name="VCXMLDataGeneratorTool"\r
- />\r
- <Tool\r
- Name="VCWebServiceProxyGeneratorTool"\r
- />\r
- <Tool\r
- Name="VCMIDLTool"\r
- />\r
- <Tool\r
- Name="VCCLCompilerTool"\r
- AdditionalIncludeDirectories=""$(InputDir)..\..\include";"$(InputDir)include";"$(InputDir)..\..\..\libs\include";"$(InputDir)..\..\..\libs\libresample\include""\r
- PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS"\r
- RuntimeLibrary="0"\r
- UsePrecompiledHeader="0"\r
- WarningLevel="3"\r
- Detect64BitPortabilityProblems="true"\r
- DebugInformationFormat="3"\r
- />\r
- <Tool\r
- Name="VCManagedResourceCompilerTool"\r
- />\r
- <Tool\r
- Name="VCResourceCompilerTool"\r
- />\r
- <Tool\r
- Name="VCPreLinkEventTool"\r
- />\r
- <Tool\r
- Name="VCLinkerTool"\r
- AdditionalDependencies="libresample.lib"\r
- OutputFile="..\..\..\w32\vsnet\$(OutDir)/mod/mod_rawaudio.dll"\r
- LinkIncremental="1"\r
- AdditionalLibraryDirectories=""$(InputDir)..\..\..\libs\libresample\win""\r
- GenerateDebugInformation="true"\r
- SubSystem="2"\r
- OptimizeReferences="2"\r
- EnableCOMDATFolding="2"\r
- ImportLibrary="$(OutDir)/mod_rawaudio.lib"\r
- TargetMachine="1"\r
- />\r
- <Tool\r
- Name="VCALinkTool"\r
- />\r
- <Tool\r
- Name="VCManifestTool"\r
- />\r
- <Tool\r
- Name="VCXDCMakeTool"\r
- />\r
- <Tool\r
- Name="VCBscMakeTool"\r
- />\r
- <Tool\r
- Name="VCFxCopTool"\r
- />\r
- <Tool\r
- Name="VCAppVerifierTool"\r
- />\r
- <Tool\r
- Name="VCWebDeploymentTool"\r
- />\r
- <Tool\r
- Name="VCPostBuildEventTool"\r
- />\r
- </Configuration>\r
- </Configurations>\r
- <References>\r
- </References>\r
- <Files>\r
- <Filter\r
- Name="Source Files"\r
- Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"\r
- UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"\r
- >\r
- <File\r
- RelativePath=".\mod_rawaudio.c"\r
- >\r
- </File>\r
- </Filter>\r
- <Filter\r
- Name="Header Files"\r
- Filter="h;hpp;hxx;hm;inl;inc;xsd"\r
- UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"\r
- >\r
- </Filter>\r
- <Filter\r
- Name="Resource Files"\r
- Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"\r
- UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"\r
- >\r
- </Filter>\r
- </Files>\r
- <Globals>\r
- </Globals>\r
-</VisualStudioProject>\r
+++ /dev/null
-/*
- * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
- * Copyright (C) 2005/2006, Anthony Minessale II <anthmct@yahoo.com>
- *
- * Version: MPL 1.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
- *
- * The Initial Developer of the Original Code is
- * Anthony Minessale II <anthmct@yahoo.com>
- * Portions created by the Initial Developer are Copyright (C)
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Anthony Minessale II <anthmct@yahoo.com>
- *
- *
- * mod_skel.c -- Framework Demo Module
- *
- */
-#include <switch.h>
-
-static const char modname[] = "mod_skel";
-
-static switch_loadable_module_interface skel_module_interface = {
- /*.module_name*/ modname,
- /*.endpoint_interface*/ NULL,
- /*.timer_interface*/ NULL,
- /*.dialplan_interface*/ NULL,
- /*.codec_interface*/ NULL,
- /*.application_interface*/ NULL
-};
-
-switch_status switch_module_load(switch_loadable_module_interface **interface, char *filename) {
- /* connect my internal structure to the blank pointer passed to me */
- *interface = &skel_module_interface;
-
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Hello World!\n");
-
- /* indicate that the module should continue to be loaded */
- return SWITCH_STATUS_SUCCESS;
-}
-
+++ /dev/null
-LDFLAGS += -lsndfile -L/usr/local/lib
-
-all: depends $(MOD).so
-
-depends:
- $(BASE)/buildlib.sh $(BASE) install libsndfile-1.0.12.tar.gz --prefix=$(PREFIX)
-
-$(MOD).so: $(MOD).c
- $(CC) $(CFLAGS) -fPIC -c $(MOD).c -o $(MOD).o
- $(CC) $(SOLINK) -o $(MOD).so $(MOD).o $(LDFLAGS)
-
-
-clean:
- rm -fr *.so *.o *~
-
+++ /dev/null
-/*
- * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
- * Copyright (C) 2005/2006, Anthony Minessale II <anthmct@yahoo.com>
- *
- * Version: MPL 1.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
- *
- * The Initial Developer of the Original Code is
- * Anthony Minessale II <anthmct@yahoo.com>
- * Portions created by the Initial Developer are Copyright (C)
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Anthony Minessale II <anthmct@yahoo.com>
- *
- *
- * mod_sndfile.c -- Framework Demo Module
- *
- */
-#include <switch.h>
-#include <sndfile.h>
-
-static const char modname[] = "mod_sndfile";
-
-struct sndfile_context {
- SF_INFO sfinfo;
- SNDFILE* handle;
-};
-
-typedef struct sndfile_context sndfile_context;
-
-switch_status sndfile_file_open(switch_file_handle *handle, char *path)
-{
- sndfile_context *context;
- int mode = 0;
- char *ext;
-
- if (!(ext = strrchr(path, '.'))) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Invalid Format\n");
- return SWITCH_STATUS_GENERR;
- }
- ext++;
-
-
- if (switch_test_flag(handle, SWITCH_FILE_FLAG_READ)) {
- mode += SFM_READ;
- }
-
- if (switch_test_flag(handle, SWITCH_FILE_FLAG_WRITE)) {
- mode += SFM_WRITE;
- }
-
- if (!mode) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Invalid Mode!\n");
- return SWITCH_STATUS_GENERR;
- }
-
-
- if (!(context = switch_core_alloc(handle->memory_pool, sizeof(*context)))) {
- return SWITCH_STATUS_MEMERR;
- }
-
- if (!strcmp(ext, "r8") || !strcmp(ext, "raw")) {
- context->sfinfo.format = SF_FORMAT_RAW | SF_FORMAT_PCM_16;
- context->sfinfo.channels = 1;
- context->sfinfo.samplerate = 8000;
- }
-
- if (!strcmp(ext, "r16")) {
- context->sfinfo.format = SF_FORMAT_RAW | SF_FORMAT_PCM_16;
- context->sfinfo.channels = 1;
- context->sfinfo.samplerate = 16000;
- }
-
- if (!strcmp(ext, "r24")) {
- context->sfinfo.format = SF_FORMAT_RAW | SF_FORMAT_PCM_24;
- context->sfinfo.channels = 1;
- context->sfinfo.samplerate = 24000;
- }
-
- if (!strcmp(ext, "r32")) {
- context->sfinfo.format = SF_FORMAT_RAW | SF_FORMAT_PCM_32;
- context->sfinfo.channels = 1;
- context->sfinfo.samplerate = 32000;
- }
-
- if (!strcmp(ext, "gsm")) {
- context->sfinfo.format = SF_FORMAT_RAW |SF_FORMAT_GSM610;
- context->sfinfo.channels = 1;
- context->sfinfo.samplerate = 8000;
- }
-
- if (!(context->handle = sf_open(path, mode, &context->sfinfo))) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Error Opening File [%s] [%s]\n", path, sf_strerror(context->handle));
- return SWITCH_STATUS_GENERR;
- }
-
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Opening File [%s] %dhz\n", path, context->sfinfo.samplerate);
- handle->samples = (unsigned int)context->sfinfo.frames;
- handle->samplerate = context->sfinfo.samplerate;
- handle->channels = context->sfinfo.channels;
- handle->format = context->sfinfo.format;
- handle->sections = context->sfinfo.sections;
- handle->seekable = context->sfinfo.seekable;
-
- handle->private = context;
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-switch_status sndfile_file_close(switch_file_handle *handle)
-{
- sndfile_context *context = handle->private;
-
- sf_close(context->handle);
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-switch_status sndfile_file_seek(switch_file_handle *handle, unsigned int *cur_sample, unsigned int samples, int whence)
-{
- sndfile_context *context = handle->private;
-
- if (!handle->seekable) {
- return SWITCH_STATUS_NOTIMPL;
- }
-
- *cur_sample = (unsigned int)sf_seek(context->handle, samples, whence);
-
- return SWITCH_STATUS_SUCCESS;
-
-}
-
-switch_status sndfile_file_read (switch_file_handle *handle, void *data, size_t *len)
-{
- size_t inlen = *len;
- sndfile_context *context = handle->private;
-
- if (switch_test_flag(handle, SWITCH_FILE_DATA_RAW)) {
- *len = (size_t)sf_read_raw (context->handle, data, inlen);
- } else if (switch_test_flag(handle, SWITCH_FILE_DATA_INT)) {
- *len = (size_t)sf_readf_int(context->handle, (int *) data, inlen);
- } else if (switch_test_flag(handle, SWITCH_FILE_DATA_SHORT)) {
- *len = (size_t)sf_readf_short(context->handle, (short *) data, inlen);
- } else if (switch_test_flag(handle, SWITCH_FILE_DATA_FLOAT)) {
- *len = (size_t)sf_readf_float(context->handle, (float *) data, inlen);
- } else if (switch_test_flag(handle, SWITCH_FILE_DATA_DOUBLE)) {
- *len = (size_t)sf_readf_double(context->handle, (double *) data, inlen);
- } else {
- *len = (size_t)sf_readf_int(context->handle, (int *) data, inlen);
- }
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-switch_status sndfile_file_write (switch_file_handle *handle, void *data, size_t *len)
-{
- size_t inlen = *len;
- sndfile_context *context = handle->private;
-
- if (switch_test_flag(handle, SWITCH_FILE_DATA_RAW)) {
- *len = (size_t)sf_write_raw (context->handle, data, inlen);
- } else if (switch_test_flag(handle, SWITCH_FILE_DATA_INT)) {
- *len = (size_t)sf_writef_int(context->handle, (int *) data, inlen);
- } else if (switch_test_flag(handle, SWITCH_FILE_DATA_SHORT)) {
- *len = (size_t)sf_writef_short(context->handle, (short *) data, inlen);
- } else if (switch_test_flag(handle, SWITCH_FILE_DATA_FLOAT)) {
- *len = (size_t)sf_writef_float(context->handle, (float *) data, inlen);
- } else if (switch_test_flag(handle, SWITCH_FILE_DATA_DOUBLE)) {
- *len = (size_t)sf_writef_double(context->handle, (double *) data, inlen);
- } else {
- *len = (size_t)sf_writef_int(context->handle, (int *) data, inlen);
- }
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-/* Registration */
-
-static char **supported_formats;
-
-static switch_file_interface sndfile_file_interface = {
- /*.interface_name*/ modname,
- /*.file_open*/ sndfile_file_open,
- /*.file_close*/ sndfile_file_close,
- /*.file_read*/ sndfile_file_read,
- /*.file_write*/ sndfile_file_write,
- /*.file_seek*/ sndfile_file_seek,
- /*.extens*/ NULL,
- /*.next*/ NULL,
-};
-
-static switch_loadable_module_interface sndfile_module_interface = {
- /*.module_name*/ modname,
- /*.endpoint_interface*/ NULL,
- /*.timer_interface*/ NULL,
- /*.dialplan_interface*/ NULL,
- /*.codec_interface*/ NULL,
- /*.application_interface*/ NULL,
- /*.api_interface*/ NULL,
- /*.file_interface*/ &sndfile_file_interface
-};
-
-static switch_status setup_formats(void)
-{
- SF_FORMAT_INFO info ;
- SF_INFO sfinfo ;
- char buffer [128] ;
- int format, major_count, subtype_count, m, s ;
- int len,x,skip;
- char *extras[] = {"r8", "r16", "r24", "r32", "gsm", NULL};
- int exlen = (sizeof(extras) / sizeof(extras[0]));
- buffer [0] = 0 ;
- sf_command (NULL, SFC_GET_LIB_VERSION, buffer, sizeof (buffer)) ;
- if (strlen (buffer) < 1) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE_CLEAN, "Line %d: could not retrieve lib version.\n", __LINE__) ;
- return SWITCH_STATUS_FALSE;
- }
-
-
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "\nLibSndFile Version : %s Supported Formats\n", buffer) ;
- switch_console_printf(SWITCH_CHANNEL_CONSOLE_CLEAN, "================================================================================\n");
- sf_command (NULL, SFC_GET_FORMAT_MAJOR_COUNT, &major_count, sizeof (int)) ;
- sf_command (NULL, SFC_GET_FORMAT_SUBTYPE_COUNT, &subtype_count, sizeof (int)) ;
-
- sfinfo.channels = 1 ;
- len = ((major_count + (exlen + 2)) * sizeof(char *));
- supported_formats = switch_core_permenant_alloc(len);
-
- len = 0;
- for (m = 0 ; m < major_count ; m++) {
- skip = 0;
- info.format = m ;
- sf_command (NULL, SFC_GET_FORMAT_MAJOR, &info, sizeof (info)) ;
- switch_console_printf(SWITCH_CHANNEL_CONSOLE_CLEAN, "%s (extension \"%s\")\n", info.name, info.extension) ;
- for (x = 0 ; x < len ; x++) {
- if (supported_formats[x] == info.extension) {
- skip++;
- break;
- }
- }
- if (!skip) {
- supported_formats[len++] = (char *) info.extension;
- }
- format = info.format;
-
- for (s = 0 ; s < subtype_count ; s++) {
- info.format = s ;
- sf_command (NULL, SFC_GET_FORMAT_SUBTYPE, &info, sizeof (info)) ;
- format = (format & SF_FORMAT_TYPEMASK) | info.format ;
- sfinfo.format = format ;
- if (sf_format_check (&sfinfo)) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE_CLEAN, " %s\n", info.name) ;
- }
- }
-
- }
- for(m=0; m< exlen; m++) {
- supported_formats[len++] = extras[m];
- }
-
-
-
- switch_console_printf(SWITCH_CHANNEL_CONSOLE_CLEAN, "================================================================================\n");
- return SWITCH_STATUS_SUCCESS;
-}
-
-SWITCH_MOD_DECLARE(switch_status) switch_module_load(switch_loadable_module_interface **interface, char *filename) {
-
-
- if (setup_formats() != SWITCH_STATUS_SUCCESS) {
- return SWITCH_STATUS_FALSE;
- }
-
- /* connect my internal structure to the blank pointer passed to me */
- sndfile_file_interface.extens = supported_formats;
- *interface = &sndfile_module_interface;
-
- /* indicate that the module should continue to be loaded */
- return SWITCH_STATUS_SUCCESS;
-}
-
+++ /dev/null
-<?xml version="1.0" encoding="Windows-1252"?>\r
-<VisualStudioProject\r
- ProjectType="Visual C++"\r
- Version="8.00"\r
- Name="mod_sndfile"\r
- ProjectGUID="{AFAC0568-7548-42D5-9F6A-8D3400A1E4F6}"\r
- RootNamespace="mod_sndfile"\r
- Keyword="Win32Proj"\r
- >\r
- <Platforms>\r
- <Platform\r
- Name="Win32"\r
- />\r
- </Platforms>\r
- <ToolFiles>\r
- </ToolFiles>\r
- <Configurations>\r
- <Configuration\r
- Name="Debug|Win32"\r
- OutputDirectory="Debug"\r
- IntermediateDirectory="Debug"\r
- ConfigurationType="2"\r
- InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
- CharacterSet="2"\r
- >\r
- <Tool\r
- Name="VCPreBuildEventTool"\r
- CommandLine="cscript /nologo $(InputDir)..\..\..\w32\vsnet\getlibs.vbs Mod_sndfile Debug"\r
- />\r
- <Tool\r
- Name="VCCustomBuildTool"\r
- />\r
- <Tool\r
- Name="VCXMLDataGeneratorTool"\r
- />\r
- <Tool\r
- Name="VCWebServiceProxyGeneratorTool"\r
- />\r
- <Tool\r
- Name="VCMIDLTool"\r
- />\r
- <Tool\r
- Name="VCCLCompilerTool"\r
- Optimization="0"\r
- AdditionalIncludeDirectories=""$(InputDir)..\..\include";"$(InputDir)..\..\..\libs\include";"$(InputDir)..\..\..\libs\libsndfile\Win32""\r
- PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS"\r
- MinimalRebuild="true"\r
- BasicRuntimeChecks="3"\r
- RuntimeLibrary="3"\r
- UsePrecompiledHeader="0"\r
- WarningLevel="3"\r
- Detect64BitPortabilityProblems="true"\r
- DebugInformationFormat="4"\r
- />\r
- <Tool\r
- Name="VCManagedResourceCompilerTool"\r
- />\r
- <Tool\r
- Name="VCResourceCompilerTool"\r
- />\r
- <Tool\r
- Name="VCPreLinkEventTool"\r
- />\r
- <Tool\r
- Name="VCLinkerTool"\r
- AdditionalDependencies="libsndfile.lib"\r
- OutputFile="..\..\..\w32\vsnet\$(OutDir)/mod/mod_sndfile.dll"\r
- LinkIncremental="2"\r
- AdditionalLibraryDirectories="$(InputDir)..\..\..\libs\libsndfile\Win32\Debug"\r
- GenerateDebugInformation="true"\r
- ProgramDatabaseFile="$(OutDir)/mod_sndfile.pdb"\r
- SubSystem="2"\r
- ImportLibrary="$(OutDir)/mod_sndfile.lib"\r
- TargetMachine="1"\r
- />\r
- <Tool\r
- Name="VCALinkTool"\r
- />\r
- <Tool\r
- Name="VCManifestTool"\r
- />\r
- <Tool\r
- Name="VCXDCMakeTool"\r
- />\r
- <Tool\r
- Name="VCBscMakeTool"\r
- />\r
- <Tool\r
- Name="VCFxCopTool"\r
- />\r
- <Tool\r
- Name="VCAppVerifierTool"\r
- />\r
- <Tool\r
- Name="VCWebDeploymentTool"\r
- />\r
- <Tool\r
- Name="VCPostBuildEventTool"\r
- />\r
- </Configuration>\r
- <Configuration\r
- Name="Release|Win32"\r
- OutputDirectory="Release"\r
- IntermediateDirectory="Release"\r
- ConfigurationType="2"\r
- InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
- CharacterSet="2"\r
- >\r
- <Tool\r
- Name="VCPreBuildEventTool"\r
- CommandLine="cscript /nologo $(InputDir)..\..\..\w32\vsnet\getlibs.vbs Mod_sndfile Release"\r
- />\r
- <Tool\r
- Name="VCCustomBuildTool"\r
- />\r
- <Tool\r
- Name="VCXMLDataGeneratorTool"\r
- />\r
- <Tool\r
- Name="VCWebServiceProxyGeneratorTool"\r
- />\r
- <Tool\r
- Name="VCMIDLTool"\r
- />\r
- <Tool\r
- Name="VCCLCompilerTool"\r
- AdditionalIncludeDirectories=""$(InputDir)..\..\include";"$(InputDir)..\..\..\libs\include";"$(InputDir)..\..\..\libs\libsndfile\Win32""\r
- PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS"\r
- RuntimeLibrary="2"\r
- UsePrecompiledHeader="0"\r
- WarningLevel="3"\r
- Detect64BitPortabilityProblems="true"\r
- DebugInformationFormat="3"\r
- />\r
- <Tool\r
- Name="VCManagedResourceCompilerTool"\r
- />\r
- <Tool\r
- Name="VCResourceCompilerTool"\r
- />\r
- <Tool\r
- Name="VCPreLinkEventTool"\r
- />\r
- <Tool\r
- Name="VCLinkerTool"\r
- AdditionalDependencies="libsndfile.lib"\r
- OutputFile="..\..\..\w32\vsnet\$(OutDir)/mod/mod_sndfile.dll"\r
- LinkIncremental="1"\r
- AdditionalLibraryDirectories="$(InputDir)..\..\..\libs\libsndfile\Win32\Release"\r
- GenerateDebugInformation="true"\r
- SubSystem="2"\r
- OptimizeReferences="2"\r
- EnableCOMDATFolding="2"\r
- LinkTimeCodeGeneration="1"\r
- ImportLibrary="$(OutDir)/mod_sndfile.lib"\r
- TargetMachine="1"\r
- />\r
- <Tool\r
- Name="VCALinkTool"\r
- />\r
- <Tool\r
- Name="VCManifestTool"\r
- />\r
- <Tool\r
- Name="VCXDCMakeTool"\r
- />\r
- <Tool\r
- Name="VCBscMakeTool"\r
- />\r
- <Tool\r
- Name="VCFxCopTool"\r
- />\r
- <Tool\r
- Name="VCAppVerifierTool"\r
- />\r
- <Tool\r
- Name="VCWebDeploymentTool"\r
- />\r
- <Tool\r
- Name="VCPostBuildEventTool"\r
- />\r
- </Configuration>\r
- </Configurations>\r
- <References>\r
- </References>\r
- <Files>\r
- <Filter\r
- Name="Source Files"\r
- Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"\r
- UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"\r
- >\r
- <File\r
- RelativePath=".\mod_sndfile.c"\r
- >\r
- </File>\r
- </Filter>\r
- <Filter\r
- Name="Header Files"\r
- Filter="h;hpp;hxx;hm;inl;inc;xsd"\r
- UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"\r
- >\r
- </Filter>\r
- <Filter\r
- Name="Resource Files"\r
- Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"\r
- UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"\r
- >\r
- </Filter>\r
- </Files>\r
- <Globals>\r
- </Globals>\r
-</VisualStudioProject>\r
+++ /dev/null
-/*
- * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
- * Copyright (C) 2005/2006, Anthony Minessale II <anthmct@yahoo.com>
- *
- * Version: MPL 1.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
- *
- * The Initial Developer of the Original Code is
- * Anthony Minessale II <anthmct@yahoo.com>
- * Portions created by the Initial Developer are Copyright (C)
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Anthony Minessale II <anthmct@yahoo.com>
- *
- *
- * mod_softtimer.c -- Software Timer Module
- *
- */
-#include <switch.h>
-#include <stdio.h>
-
-static const char modname[] = "mod_softtimer";
-
-#ifdef WIN32
-//#define WINTIMER
-#endif
-
-struct timer_private {
-#ifdef WINTIMER
- LARGE_INTEGER freq;
- LARGE_INTEGER base;
- LARGE_INTEGER now;
-#else
- switch_time_t reference;
-#endif
-};
-
-static switch_status soft_timer_init(switch_timer *timer)
-{
- struct timer_private *private;
-
- private = switch_core_alloc(timer->memory_pool, sizeof(*private));
- timer->private = private;
-
-#ifdef WINTIMER
- QueryPerformanceFrequency(&private->freq);
- QueryPerformanceCounter(&private->base);
-#else
- private->reference = switch_time_now();
-#endif
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-static switch_status soft_timer_next(switch_timer *timer)
-{
- struct timer_private *private = timer->private;
-
-#ifdef WINTIMER
- private->base.QuadPart += timer->interval * (private->freq.QuadPart / 1000);
- for(;;) {
- QueryPerformanceCounter(&private->now);
- if(private->now.QuadPart >= private->base.QuadPart) {
- break;
- }
- switch_yield(100);
- }
-#else
- private->reference += timer->interval * 1000;
-
- while (switch_time_now() < private->reference) {
- switch_yield(1000);
- }
-#endif
-
- timer->samplecount += timer->samples;
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-static switch_status soft_timer_destroy(switch_timer *timer)
-{
- timer->private = NULL;
- return SWITCH_STATUS_SUCCESS;
-}
-
-static const switch_timer_interface soft_timer_interface = {
- /*.interface_name*/ "soft",
- /*.timer_init*/ soft_timer_init,
- /*.timer_next*/ soft_timer_next,
- /*.timer_destroy*/ soft_timer_destroy
-};
-
-static const switch_loadable_module_interface mod_timers_module_interface = {
- /*.module_name*/ modname,
- /*.endpoint_interface*/ NULL,
- /*.timer_interface*/ &soft_timer_interface,
- /*.switch_dialplan_interface*/ NULL,
- /*.switch_codec_interface*/ NULL,
- /*.switch_application_interface*/ NULL
-};
-
-SWITCH_MOD_DECLARE(switch_status) switch_module_load(const switch_loadable_module_interface **interface, char *filename) {
-
- /* connect my internal structure to the blank pointer passed to me */
- *interface = &mod_timers_module_interface;
-
- /* indicate that the module should continue to be loaded */
- return SWITCH_STATUS_SUCCESS;
-}
-
-
-
-
-
+++ /dev/null
-<?xml version="1.0" encoding="Windows-1252"?>\r
-<VisualStudioProject\r
- ProjectType="Visual C++"\r
- Version="8.00"\r
- Name="mod_softtimer"\r
- ProjectGUID="{DCC13474-28DF-47CA-A8EB-72F8CE9A78C5}"\r
- RootNamespace="mod_softtimer"\r
- Keyword="Win32Proj"\r
- >\r
- <Platforms>\r
- <Platform\r
- Name="Win32"\r
- />\r
- </Platforms>\r
- <ToolFiles>\r
- </ToolFiles>\r
- <Configurations>\r
- <Configuration\r
- Name="Debug|Win32"\r
- OutputDirectory="Debug"\r
- IntermediateDirectory="Debug"\r
- ConfigurationType="2"\r
- InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
- CharacterSet="2"\r
- >\r
- <Tool\r
- Name="VCPreBuildEventTool"\r
- />\r
- <Tool\r
- Name="VCCustomBuildTool"\r
- />\r
- <Tool\r
- Name="VCXMLDataGeneratorTool"\r
- />\r
- <Tool\r
- Name="VCWebServiceProxyGeneratorTool"\r
- />\r
- <Tool\r
- Name="VCMIDLTool"\r
- />\r
- <Tool\r
- Name="VCCLCompilerTool"\r
- Optimization="0"\r
- AdditionalIncludeDirectories=""$(InputDir)..\..\include";"$(InputDir)include";"$(InputDir)..\..\..\libs\include""\r
- PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS"\r
- MinimalRebuild="true"\r
- BasicRuntimeChecks="3"\r
- RuntimeLibrary="1"\r
- UsePrecompiledHeader="0"\r
- WarningLevel="3"\r
- Detect64BitPortabilityProblems="true"\r
- DebugInformationFormat="4"\r
- />\r
- <Tool\r
- Name="VCManagedResourceCompilerTool"\r
- />\r
- <Tool\r
- Name="VCResourceCompilerTool"\r
- />\r
- <Tool\r
- Name="VCPreLinkEventTool"\r
- />\r
- <Tool\r
- Name="VCLinkerTool"\r
- OutputFile="..\..\..\w32\vsnet\$(OutDir)/mod/mod_softtimer.dll"\r
- LinkIncremental="2"\r
- AdditionalLibraryDirectories="$(InputDir)..\..\libs\apr\Debug"\r
- GenerateDebugInformation="true"\r
- ProgramDatabaseFile="$(OutDir)/mod_softtimer.pdb"\r
- SubSystem="2"\r
- ImportLibrary="$(OutDir)/mod_softtimer.lib"\r
- TargetMachine="1"\r
- />\r
- <Tool\r
- Name="VCALinkTool"\r
- />\r
- <Tool\r
- Name="VCManifestTool"\r
- />\r
- <Tool\r
- Name="VCXDCMakeTool"\r
- />\r
- <Tool\r
- Name="VCBscMakeTool"\r
- />\r
- <Tool\r
- Name="VCFxCopTool"\r
- />\r
- <Tool\r
- Name="VCAppVerifierTool"\r
- />\r
- <Tool\r
- Name="VCWebDeploymentTool"\r
- />\r
- <Tool\r
- Name="VCPostBuildEventTool"\r
- />\r
- </Configuration>\r
- <Configuration\r
- Name="Release|Win32"\r
- OutputDirectory="Release"\r
- IntermediateDirectory="Release"\r
- ConfigurationType="2"\r
- InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
- CharacterSet="2"\r
- >\r
- <Tool\r
- Name="VCPreBuildEventTool"\r
- />\r
- <Tool\r
- Name="VCCustomBuildTool"\r
- />\r
- <Tool\r
- Name="VCXMLDataGeneratorTool"\r
- />\r
- <Tool\r
- Name="VCWebServiceProxyGeneratorTool"\r
- />\r
- <Tool\r
- Name="VCMIDLTool"\r
- />\r
- <Tool\r
- Name="VCCLCompilerTool"\r
- AdditionalIncludeDirectories=""$(InputDir)..\..\include";"$(InputDir)include";"$(InputDir)..\..\..\libs\include""\r
- PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS"\r
- RuntimeLibrary="0"\r
- UsePrecompiledHeader="0"\r
- WarningLevel="3"\r
- Detect64BitPortabilityProblems="true"\r
- DebugInformationFormat="3"\r
- />\r
- <Tool\r
- Name="VCManagedResourceCompilerTool"\r
- />\r
- <Tool\r
- Name="VCResourceCompilerTool"\r
- />\r
- <Tool\r
- Name="VCPreLinkEventTool"\r
- />\r
- <Tool\r
- Name="VCLinkerTool"\r
- OutputFile="..\..\..\w32\vsnet\$(OutDir)/mod/mod_softtimer.dll"\r
- LinkIncremental="1"\r
- AdditionalLibraryDirectories=""$(InputDir)..\..\libs\apr\Release""\r
- GenerateDebugInformation="true"\r
- SubSystem="2"\r
- OptimizeReferences="2"\r
- EnableCOMDATFolding="2"\r
- ImportLibrary="$(OutDir)/mod_softtimer.lib"\r
- TargetMachine="1"\r
- />\r
- <Tool\r
- Name="VCALinkTool"\r
- />\r
- <Tool\r
- Name="VCManifestTool"\r
- />\r
- <Tool\r
- Name="VCXDCMakeTool"\r
- />\r
- <Tool\r
- Name="VCBscMakeTool"\r
- />\r
- <Tool\r
- Name="VCFxCopTool"\r
- />\r
- <Tool\r
- Name="VCAppVerifierTool"\r
- />\r
- <Tool\r
- Name="VCWebDeploymentTool"\r
- />\r
- <Tool\r
- Name="VCPostBuildEventTool"\r
- />\r
- </Configuration>\r
- </Configurations>\r
- <References>\r
- </References>\r
- <Files>\r
- <Filter\r
- Name="Source Files"\r
- Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"\r
- UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"\r
- >\r
- <File\r
- RelativePath=".\mod_softtimer.c"\r
- >\r
- </File>\r
- </Filter>\r
- <Filter\r
- Name="Header Files"\r
- Filter="h;hpp;hxx;hm;inl;inc;xsd"\r
- UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"\r
- >\r
- </Filter>\r
- <Filter\r
- Name="Resource Files"\r
- Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"\r
- UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"\r
- >\r
- </Filter>\r
- </Files>\r
- <Globals>\r
- </Globals>\r
-</VisualStudioProject>\r
+++ /dev/null
-all: depends $(MOD).so
-
-depends:
- $(BASE)/buildlib.sh $(BASE) install speex-1.1.11.1.tar.gz --prefix=$(PREFIX)
-
-$(MOD).so: $(MOD).c
- $(CC) $(CFLAGS) -fPIC -c $(MOD).c -o $(MOD).o
- $(CC) $(SOLINK) $(MOD).o -o $(MOD).so $(LDFLAGS) -lspeex
-
-clean:
- rm -fr *.so *.o *~
-
+++ /dev/null
-/*
- * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
- * Copyright (C) 2005/2006, Anthony Minessale II <anthmct@yahoo.com>
- *
- * Version: MPL 1.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
- *
- * The Initial Developer of the Original Code is
- * Anthony Minessale II <anthmct@yahoo.com>
- * Portions created by the Initial Developer are Copyright (C)
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Anthony Minessale II <anthmct@yahoo.com>
- *
- *
- * mod_speexcodec.c -- Speex Codec Module
- *
- */
-#include <switch.h>
-#include <speex/speex.h>
-#include <speex/speex_preprocess.h>
-
-static const char modname[] = "mod_speexcodec";
-
-const struct switch_codec_settings default_codec_settings = {
- /*.quality*/ 5,
- /*.complexity*/ 5,
- /*.enhancement*/ 1,
- /*.vad*/ 0,
- /*.vbr*/ 0,
- /*.vbr_quality*/ 4,
- /*.abr*/ 0,
- /*.dtx*/ 0,
- /*.preproc*/ 0,
- /*.pp_vad*/ 0,
- /*.pp_agc*/ 0,
- /*.pp_agc_level*/ 8000,
- /*.pp_denoise*/ 0,
- /*.pp_dereverb*/ 0,
- /*.pp_dereverb_decay*/ 0.4f,
- /*.pp_dereverb_level*/ 0.3f,
-};
-
-struct speex_context {
- switch_codec *codec;
- unsigned int flags;
-
- /* Encoder */
- void *encoder_state;
- struct SpeexBits encoder_bits;
- unsigned int encoder_frame_size;
- int encoder_mode;
- SpeexPreprocessState *pp;
-
- /* Decoder */
- void *decoder_state;
- struct SpeexBits decoder_bits;
- unsigned int decoder_frame_size;
- int decoder_mode;
-};
-
-static switch_status switch_speex_init(switch_codec *codec, switch_codec_flag flags, const struct switch_codec_settings *codec_settings)
-{
- struct speex_context *context = NULL;
- int encoding, decoding;
-
- encoding = (flags & SWITCH_CODEC_FLAG_ENCODE);
- decoding = (flags & SWITCH_CODEC_FLAG_DECODE);
-
- if (!codec_settings) {
- codec_settings = &default_codec_settings;
- }
-
- memcpy(&codec->codec_settings, codec_settings, sizeof(codec->codec_settings));
-
- if (!(encoding || decoding) || (!(context = switch_core_alloc(codec->memory_pool, sizeof(*context))))) {
- return SWITCH_STATUS_FALSE;
- } else {
- const SpeexMode *mode = NULL;
-
- context->codec = codec;
- if (codec->implementation->samples_per_second == 8000) {
- mode = &speex_nb_mode;
- } else if (codec->implementation->samples_per_second == 16000) {
- mode = &speex_wb_mode;
- } else if (codec->implementation->samples_per_second == 32000) {
- mode = &speex_uwb_mode;
- }
-
- if (!mode) {
- return SWITCH_STATUS_FALSE;
- }
-
- if (encoding) {
- speex_bits_init(&context->encoder_bits);
- context->encoder_state = speex_encoder_init(mode);
- speex_encoder_ctl(context->encoder_state, SPEEX_GET_FRAME_SIZE, &context->encoder_frame_size);
- speex_encoder_ctl(context->encoder_state, SPEEX_SET_COMPLEXITY, &codec->codec_settings.complexity);
- if (codec->codec_settings.preproc) {
- context->pp = speex_preprocess_state_init(context->encoder_frame_size, codec->implementation->samples_per_second);
- speex_preprocess_ctl(context->pp, SPEEX_PREPROCESS_SET_VAD, &codec->codec_settings.pp_vad);
- speex_preprocess_ctl(context->pp, SPEEX_PREPROCESS_SET_AGC, &codec->codec_settings.pp_agc);
- speex_preprocess_ctl(context->pp, SPEEX_PREPROCESS_SET_AGC_LEVEL, &codec->codec_settings.pp_agc_level);
- speex_preprocess_ctl(context->pp, SPEEX_PREPROCESS_SET_DENOISE, &codec->codec_settings.pp_denoise);
- speex_preprocess_ctl(context->pp, SPEEX_PREPROCESS_SET_DEREVERB, &codec->codec_settings.pp_dereverb);
- speex_preprocess_ctl(context->pp, SPEEX_PREPROCESS_SET_DEREVERB_DECAY, &codec->codec_settings.pp_dereverb_decay);
- speex_preprocess_ctl(context->pp, SPEEX_PREPROCESS_SET_DEREVERB_LEVEL, &codec->codec_settings.pp_dereverb_level);
- }
-
- if (!codec->codec_settings.abr && !codec->codec_settings.vbr) {
- speex_encoder_ctl(context->encoder_state, SPEEX_SET_QUALITY, &codec->codec_settings.quality);
- if (codec->codec_settings.vad) {
- speex_encoder_ctl(context->encoder_state, SPEEX_SET_VAD, &codec->codec_settings.vad);
- }
- }
- if (codec->codec_settings.vbr) {
- speex_encoder_ctl(context->encoder_state, SPEEX_SET_VBR, &codec->codec_settings.vbr);
- speex_encoder_ctl(context->encoder_state, SPEEX_SET_VBR_QUALITY, &codec->codec_settings.vbr_quality);
- }
- if (codec->codec_settings.abr) {
- speex_encoder_ctl(context->encoder_state, SPEEX_SET_ABR, &codec->codec_settings.abr);
- }
- if (codec->codec_settings.dtx) {
- speex_encoder_ctl(context->encoder_state, SPEEX_SET_DTX, &codec->codec_settings.dtx);
- }
- }
-
- if (decoding) {
- speex_bits_init(&context->decoder_bits);
- context->decoder_state = speex_decoder_init(mode);
- if (codec->codec_settings.enhancement) {
- speex_decoder_ctl(context->decoder_state, SPEEX_SET_ENH, &codec->codec_settings.enhancement);
- }
- }
-
-
-
- codec->private = context;
- return SWITCH_STATUS_SUCCESS;
- }
-}
-
-static switch_status switch_speex_encode(switch_codec *codec,
- switch_codec *other_codec,
- void *decoded_data,
- size_t decoded_data_len,
- int decoded_rate,
- void *encoded_data,
- size_t *encoded_data_len,
- int *encoded_rate,
- unsigned int *flag)
-{
- struct speex_context *context = codec->private;
- short *buf;
- int is_speech = 1;
-
- if (!context) {
- return SWITCH_STATUS_FALSE;
- }
-
- buf = decoded_data;
-
- if (context->pp) {
- is_speech = speex_preprocess(context->pp, buf, NULL);
- }
-
- if (is_speech) {
- is_speech = speex_encode_int(context->encoder_state, buf, &context->encoder_bits) || ! context->codec->codec_settings.dtx;
- } else {
- speex_bits_pack(&context->encoder_bits, 0, 5);
- }
-
-
- if (is_speech) {
- switch_clear_flag(context, SWITCH_CODEC_FLAG_SILENCE);
- *flag |= SWITCH_CODEC_FLAG_SILENCE_STOP;
- } else {
- if (switch_test_flag(context, SWITCH_CODEC_FLAG_SILENCE)) {
- *encoded_data_len = 0;
- *flag |= SWITCH_CODEC_FLAG_SILENCE;
- return SWITCH_STATUS_SUCCESS;
- }
-
- switch_set_flag(context, SWITCH_CODEC_FLAG_SILENCE);
- *flag |= SWITCH_CODEC_FLAG_SILENCE_START;
- }
-
-
-
-
- speex_bits_pack(&context->encoder_bits, 15, 5);
- *encoded_data_len = speex_bits_write(&context->encoder_bits, (char *)encoded_data, context->encoder_frame_size);
- speex_bits_reset(&context->encoder_bits);
-
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-static switch_status switch_speex_decode(switch_codec *codec,
- switch_codec *other_codec,
- void *encoded_data,
- size_t encoded_data_len,
- int encoded_rate,
- void *decoded_data,
- size_t *decoded_data_len,
- int *decoded_rate,
- unsigned int *flag)
-{
- struct speex_context *context = codec->private;
- short *buf;
-
- if (!context) {
- return SWITCH_STATUS_FALSE;
- }
-
- buf = decoded_data;
- if (*flag & SWITCH_CODEC_FLAG_SILENCE) {
- speex_decode_int(context->decoder_state, NULL, buf);
- } else {
- speex_bits_read_from(&context->decoder_bits, (char *)encoded_data, (int)*decoded_data_len);
- speex_decode_int(context->decoder_state, &context->decoder_bits, buf);
- }
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-
-static switch_status switch_speex_destroy(switch_codec *codec)
-{
- int encoding, decoding;
- struct speex_context *context = codec->private;
-
- if (!context) {
- return SWITCH_STATUS_FALSE;
- }
-
- encoding = (codec->flags & SWITCH_CODEC_FLAG_ENCODE);
- decoding = (codec->flags & SWITCH_CODEC_FLAG_DECODE);
-
- if (encoding) {
- speex_bits_destroy(&context->encoder_bits);
- speex_encoder_destroy(context->encoder_state);
- }
-
- if (decoding) {
- speex_bits_destroy(&context->decoder_bits);
- speex_decoder_destroy(context->decoder_state);
- }
-
- codec->private = NULL;
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-/* Registration */
-static const switch_codec_implementation speex_32k_implementation = {
- /*.samples_per_second*/ 32000,
- /*.bits_per_second*/ 512000,
- /*.nanoseconds_per_frame*/ 20000,
- /*.samples_per_frame*/ 640,
- /*.bytes_per_frame*/ 1280,
- /*.encoded_bytes_per_frame*/ 1280,
- /*.number_of_channels*/ 1,
- /*.pref_frames_per_packet*/ 1,
- /*.max_frames_per_packet*/ 1,
- /*.init*/ switch_speex_init,
- /*.encode*/ switch_speex_encode,
- /*.decode*/ switch_speex_decode,
- /*.destroy*/ switch_speex_destroy
-};
-
-static const switch_codec_implementation speex_16k_implementation = {
- /*.samples_per_second*/ 16000,
- /*.bits_per_second*/ 256000,
- /*.nanoseconds_per_frame*/ 20000,
- /*.samples_per_frame*/ 320,
- /*.bytes_per_frame*/ 640,
- /*.encoded_bytes_per_frame*/ 640,
- /*.number_of_channels*/ 1,
- /*.pref_frames_per_packet*/ 1,
- /*.max_frames_per_packet*/ 1,
- /*.init*/ switch_speex_init,
- /*.encode*/ switch_speex_encode,
- /*.decode*/ switch_speex_decode,
- /*.destroy*/ switch_speex_destroy,
- /*.next*/ &speex_32k_implementation
-};
-
-static const switch_codec_implementation speex_8k_implementation = {
- /*.samples_per_second*/ 8000,
- /*.bits_per_second*/ 128000,
- /*.nanoseconds_per_frame*/ 20000,
- /*.samples_per_frame*/ 160,
- /*.bytes_per_frame*/ 320,
- /*.encoded_bytes_per_frame*/ 320,
- /*.number_of_channels*/ 1,
- /*.pref_frames_per_packet*/ 1,
- /*.max_frames_per_packet*/ 1,
- /*.init*/ switch_speex_init,
- /*.encode*/ switch_speex_encode,
- /*.decode*/ switch_speex_decode,
- /*.destroy*/ switch_speex_destroy,
- /*.next*/ &speex_16k_implementation
-};
-
-static const switch_codec_interface speex_codec_interface = {
- /*.interface_name*/ "speex",
- /*.codec_type*/ SWITCH_CODEC_TYPE_AUDIO,
- /*.ianacode*/ 98,
- /*.iananame*/ "speex",
- /*.implementations*/ &speex_8k_implementation
-};
-
-static switch_loadable_module_interface speex_module_interface = {
- /*.module_name*/ modname,
- /*.endpoint_interface*/ NULL,
- /*.timer_interface*/ NULL,
- /*.dialplan_interface*/ NULL,
- /*.codec_interface*/ &speex_codec_interface,
- /*.application_interface*/ NULL
-};
-
-SWITCH_MOD_DECLARE(switch_status) switch_module_load(switch_loadable_module_interface **interface, char *filename) {
- /* connect my internal structure to the blank pointer passed to me */
- *interface = &speex_module_interface;
-
- /* indicate that the module should continue to be loaded */
- return SWITCH_STATUS_SUCCESS;
-}
+++ /dev/null
-<?xml version="1.0" encoding="Windows-1252"?>\r
-<VisualStudioProject\r
- ProjectType="Visual C++"\r
- Version="8.00"\r
- Name="mod_speexcodec"\r
- ProjectGUID="{5580D60E-0F77-4716-9CD4-B8E5986FA375}"\r
- RootNamespace="mod_speexcodec"\r
- Keyword="Win32Proj"\r
- >\r
- <Platforms>\r
- <Platform\r
- Name="Win32"\r
- />\r
- </Platforms>\r
- <ToolFiles>\r
- </ToolFiles>\r
- <Configurations>\r
- <Configuration\r
- Name="Debug|Win32"\r
- OutputDirectory="Debug"\r
- IntermediateDirectory="Debug"\r
- ConfigurationType="2"\r
- InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
- CharacterSet="2"\r
- >\r
- <Tool\r
- Name="VCPreBuildEventTool"\r
- CommandLine="cscript /nologo $(InputDir)..\..\..\w32\vsnet\getlibs.vbs Mod_SpeexCodec Debug"\r
- />\r
- <Tool\r
- Name="VCCustomBuildTool"\r
- />\r
- <Tool\r
- Name="VCXMLDataGeneratorTool"\r
- />\r
- <Tool\r
- Name="VCWebServiceProxyGeneratorTool"\r
- />\r
- <Tool\r
- Name="VCMIDLTool"\r
- />\r
- <Tool\r
- Name="VCCLCompilerTool"\r
- Optimization="0"\r
- AdditionalIncludeDirectories=""$(InputDir)..\..\include";"$(InputDir)include";"$(InputDir)..\..\..\libs\include";"$(InputDir)..\..\..\libs\speex\include";"$(InputDir)..\..\..\libs\speex\include\speex""\r
- PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS"\r
- MinimalRebuild="true"\r
- BasicRuntimeChecks="3"\r
- RuntimeLibrary="1"\r
- UsePrecompiledHeader="0"\r
- WarningLevel="3"\r
- Detect64BitPortabilityProblems="true"\r
- DebugInformationFormat="4"\r
- />\r
- <Tool\r
- Name="VCManagedResourceCompilerTool"\r
- />\r
- <Tool\r
- Name="VCResourceCompilerTool"\r
- />\r
- <Tool\r
- Name="VCPreLinkEventTool"\r
- />\r
- <Tool\r
- Name="VCLinkerTool"\r
- AdditionalDependencies="libspeex.lib"\r
- OutputFile="..\..\..\w32\vsnet\$(OutDir)/mod/mod_speexcodec.dll"\r
- LinkIncremental="2"\r
- AdditionalLibraryDirectories=""$(InputDir)..\..\..\libs\speex\win32\libspeex\Debug""\r
- GenerateDebugInformation="true"\r
- ProgramDatabaseFile="$(OutDir)/mod_speexcodec.pdb"\r
- SubSystem="2"\r
- ImportLibrary="$(OutDir)/mod_speexcodec.lib"\r
- TargetMachine="1"\r
- />\r
- <Tool\r
- Name="VCALinkTool"\r
- />\r
- <Tool\r
- Name="VCManifestTool"\r
- />\r
- <Tool\r
- Name="VCXDCMakeTool"\r
- />\r
- <Tool\r
- Name="VCBscMakeTool"\r
- />\r
- <Tool\r
- Name="VCFxCopTool"\r
- />\r
- <Tool\r
- Name="VCAppVerifierTool"\r
- />\r
- <Tool\r
- Name="VCWebDeploymentTool"\r
- />\r
- <Tool\r
- Name="VCPostBuildEventTool"\r
- />\r
- </Configuration>\r
- <Configuration\r
- Name="Release|Win32"\r
- OutputDirectory="Release"\r
- IntermediateDirectory="Release"\r
- ConfigurationType="2"\r
- InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
- CharacterSet="2"\r
- >\r
- <Tool\r
- Name="VCPreBuildEventTool"\r
- CommandLine="cscript /nologo $(InputDir)..\..\..\w32\vsnet\getlibs.vbs Mod_SpeexCodec Release"\r
- />\r
- <Tool\r
- Name="VCCustomBuildTool"\r
- />\r
- <Tool\r
- Name="VCXMLDataGeneratorTool"\r
- />\r
- <Tool\r
- Name="VCWebServiceProxyGeneratorTool"\r
- />\r
- <Tool\r
- Name="VCMIDLTool"\r
- />\r
- <Tool\r
- Name="VCCLCompilerTool"\r
- AdditionalIncludeDirectories=""$(InputDir)..\..\include";"$(InputDir)include";"$(InputDir)..\..\..\libs\include";"$(InputDir)..\..\..\libs\speex\include";"$(InputDir)..\..\..\libs\speex\include\speex""\r
- PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS"\r
- RuntimeLibrary="0"\r
- UsePrecompiledHeader="0"\r
- WarningLevel="3"\r
- Detect64BitPortabilityProblems="true"\r
- DebugInformationFormat="3"\r
- />\r
- <Tool\r
- Name="VCManagedResourceCompilerTool"\r
- />\r
- <Tool\r
- Name="VCResourceCompilerTool"\r
- />\r
- <Tool\r
- Name="VCPreLinkEventTool"\r
- />\r
- <Tool\r
- Name="VCLinkerTool"\r
- AdditionalDependencies="libspeex.lib"\r
- OutputFile="..\..\..\w32\vsnet\$(OutDir)/mod/mod_speexcodec.dll"\r
- LinkIncremental="1"\r
- AdditionalLibraryDirectories=""$(InputDir)..\..\..\libs\speex\win32\libspeex\Release""\r
- GenerateDebugInformation="true"\r
- SubSystem="2"\r
- OptimizeReferences="2"\r
- EnableCOMDATFolding="2"\r
- ImportLibrary="$(OutDir)/mod_speexcodec.lib"\r
- TargetMachine="1"\r
- />\r
- <Tool\r
- Name="VCALinkTool"\r
- />\r
- <Tool\r
- Name="VCManifestTool"\r
- />\r
- <Tool\r
- Name="VCXDCMakeTool"\r
- />\r
- <Tool\r
- Name="VCBscMakeTool"\r
- />\r
- <Tool\r
- Name="VCFxCopTool"\r
- />\r
- <Tool\r
- Name="VCAppVerifierTool"\r
- />\r
- <Tool\r
- Name="VCWebDeploymentTool"\r
- />\r
- <Tool\r
- Name="VCPostBuildEventTool"\r
- />\r
- </Configuration>\r
- </Configurations>\r
- <References>\r
- </References>\r
- <Files>\r
- <Filter\r
- Name="Source Files"\r
- Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"\r
- UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"\r
- >\r
- <File\r
- RelativePath=".\mod_speexcodec.c"\r
- >\r
- </File>\r
- </Filter>\r
- <Filter\r
- Name="Header Files"\r
- Filter="h;hpp;hxx;hm;inl;inc;xsd"\r
- UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"\r
- >\r
- </Filter>\r
- <Filter\r
- Name="Resource Files"\r
- Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"\r
- UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"\r
- >\r
- </Filter>\r
- </Files>\r
- <Globals>\r
- </Globals>\r
-</VisualStudioProject>\r
+++ /dev/null
-/*
- * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
- * Copyright (C) 2005/2006, Anthony Minessale II <anthmct@yahoo.com>
- *
- * Version: MPL 1.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
- *
- * The Initial Developer of the Original Code is
- * Anthony Minessale II <anthmct@yahoo.com>
- * Portions created by the Initial Developer are Copyright (C)
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Anthony Minessale II <anthmct@yahoo.com>
- *
- *
- * mod_wanchan.c -- WANPIPE PRI Channel Module
- *
- */
-#include <switch.h>
-#include <sys/types.h>
-#include <sys/time.h>
-#include <sys/queue.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <ctype.h>
-#include <string.h>
-#include <libsangoma.h>
-#include <sangoma_pri.h>
-
-static const char modname[] = "mod_wanchan";
-#define STRLEN 15
-
-static switch_memory_pool *module_pool;
-
-typedef enum {
- PFLAG_ANSWER = (1 << 0),
- PFLAG_HANGUP = (1 << 1),
-} PFLAGS;
-
-
-typedef enum {
- PPFLAG_RING = (1 << 0),
-} PPFLAGS;
-
-typedef enum {
- TFLAG_MEDIA = (1 << 0),
- TFLAG_INBOUND = (1 << 1),
- TFLAG_OUTBOUND = (1 << 2),
- TFLAG_INCOMING = (1 << 3),
- TFLAG_PARSE_INCOMING = (1 << 4),
- TFLAG_ACTIVATE = (1 << 5),
- TFLAG_DTMF = (1 << 6),
- TFLAG_DESTROY = (1 << 7),
- TFLAG_ABORT = (1 << 8),
- TFLAG_SWITCH = (1 << 9),
-} TFLAGS;
-
-#define PACKET_LEN 160
-#define DEFAULT_BYTES_PER_FRAME 160
-
-static struct {
- int debug;
- int panic;
- int span;
- int dchan;
- int node;
- int pswitch;
- int bytes_per_frame;
- char *dialplan;
-} globals;
-
-
-
-struct private_object {
- unsigned int flags; /* FLAGS */
- struct switch_frame frame; /* Frame for Writing */
- unsigned char databuf[1024];
- struct sangoma_pri *spri;
- pri_event ring_event;
- pri_event hangup_event;
- sangoma_api_hdr_t hdrframe;
- switch_caller_profile *caller_profile;
- int socket;
- int callno;
- int cause;
-};
-
-struct channel_map {
- switch_core_session *map[36];
-};
-
-
-static void set_global_dialplan(char *dialplan)
-{
- if (globals.dialplan) {
- free(globals.dialplan);
- globals.dialplan = NULL;
- }
-
- globals.dialplan = strdup(dialplan);
-}
-
-
-
-static int str2node(char *node)
-{
- if (!strcasecmp(node, "cpe"))
- return PRI_CPE;
- if (!strcasecmp(node, "network"))
- return PRI_NETWORK;
- return -1;
-}
-
-static int str2switch(char *swtype)
-{
- if (!strcasecmp(swtype, "ni2"))
- return PRI_SWITCH_NI2;
- if (!strcasecmp(swtype, "dms100"))
- return PRI_SWITCH_DMS100;
- if (!strcasecmp(swtype, "lucent5e"))
- return PRI_SWITCH_LUCENT5E;
- if (!strcasecmp(swtype, "att4ess"))
- return PRI_SWITCH_ATT4ESS;
- if (!strcasecmp(swtype, "euroisdn"))
- return PRI_SWITCH_EUROISDN_E1;
- if (!strcasecmp(swtype, "gr303eoc"))
- return PRI_SWITCH_GR303_EOC;
- if (!strcasecmp(swtype, "gr303tmc"))
- return PRI_SWITCH_GR303_TMC;
- return -1;
-}
-
-
-
-static void set_global_dialplan(char *dialplan);
-static int str2node(char *node);
-static int str2switch(char *swtype);
-static switch_status wanchan_on_init(switch_core_session *session);
-static switch_status wanchan_on_hangup(switch_core_session *session);
-static switch_status wanchan_on_loopback(switch_core_session *session);
-static switch_status wanchan_on_transmit(switch_core_session *session);
-static switch_status wanchan_outgoing_channel(switch_core_session *session, switch_caller_profile *outbound_profile, switch_core_session **new_session);
-static switch_status wanchan_read_frame(switch_core_session *session, switch_frame **frame, int timeout, switch_io_flag flags);
-static switch_status wanchan_write_frame(switch_core_session *session, switch_frame *frame, int timeout, switch_io_flag flags);
-static int on_info(struct sangoma_pri *spri, sangoma_pri_event_t event_type, pri_event *event);
-static int on_hangup(struct sangoma_pri *spri, sangoma_pri_event_t event_type, pri_event *event);
-static int on_ring(struct sangoma_pri *spri, sangoma_pri_event_t event_type, pri_event *event);
-static int check_flags(struct sangoma_pri *spri);
-static int on_restart(struct sangoma_pri *spri, sangoma_pri_event_t event_type, pri_event *event);
-static int on_anything(struct sangoma_pri *spri, sangoma_pri_event_t event_type, pri_event *event);
-static void *pri_thread_run(switch_thread *thread, void *obj);
-static int config_wanpipe(int reload);
-
-
-
-/*
- State methods they get called when the state changes to the specific state
- returning SWITCH_STATUS_SUCCESS tells the core to execute the standard state method next
- so if you fully implement the state you can return SWITCH_STATUS_FALSE to skip it.
-*/
-static switch_status wanchan_on_init(switch_core_session *session)
-{
- struct private_object *tech_pvt;
- switch_channel *channel = NULL;
-
- channel = switch_core_session_get_channel(session);
- assert(channel != NULL);
-
- tech_pvt = switch_core_session_get_private(session);
- assert(tech_pvt != NULL);
-
- tech_pvt->frame.data = tech_pvt->databuf;
-
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "WANCHAN INIT\n");
-
-
- /* Move Channel's State Machine to RING */
- switch_channel_set_state(channel, CS_RING);
- return SWITCH_STATUS_SUCCESS;
-}
-
-static switch_status wanchan_on_ring(switch_core_session *session)
-{
- switch_channel *channel = NULL;
- struct private_object *tech_pvt = NULL;
-
- channel = switch_core_session_get_channel(session);
- assert(channel != NULL);
-
- tech_pvt = switch_core_session_get_private(session);
- assert(tech_pvt != NULL);
-
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "WANCHAN RING\n");
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-static switch_status wanchan_on_hangup(switch_core_session *session)
-{
- struct private_object *tech_pvt;
- switch_channel *channel = NULL;
-
- channel = switch_core_session_get_channel(session);
- assert(channel != NULL);
-
- tech_pvt = switch_core_session_get_private(session);
- assert(tech_pvt != NULL);
-
- switch_socket_close(&tech_pvt->socket);
-
- pri_hangup(tech_pvt->spri->pri, tech_pvt->hangup_event.hangup.call ? tech_pvt->hangup_event.hangup.call : tech_pvt->ring_event.ring.call, tech_pvt->cause);
- pri_destroycall(tech_pvt->spri->pri, tech_pvt->hangup_event.hangup.call ? tech_pvt->hangup_event.hangup.call : tech_pvt->ring_event.ring.call);
-
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "WANCHAN HANGUP\n");
- return SWITCH_STATUS_SUCCESS;
-}
-
-static switch_status wanchan_on_loopback(switch_core_session *session)
-{
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "WANCHAN LOOPBACK\n");
- return SWITCH_STATUS_SUCCESS;
-}
-
-static switch_status wanchan_on_transmit(switch_core_session *session)
-{
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "WANCHAN TRANSMIT\n");
- return SWITCH_STATUS_SUCCESS;
-}
-
-static switch_status wanchan_outgoing_channel(switch_core_session *session, switch_caller_profile *outbound_profile, switch_core_session **new_session)
-{
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "NOT IMPLEMENTED\n");
-
- return SWITCH_STATUS_GENERR;
-}
-
-static switch_status wanchan_answer_channel(switch_core_session *session)
-{
- struct private_object *tech_pvt;
- switch_channel *channel = NULL;
-
- channel = switch_core_session_get_channel(session);
- assert(channel != NULL);
-
- tech_pvt = switch_core_session_get_private(session);
- assert(tech_pvt != NULL);
-
- pri_answer(tech_pvt->spri->pri, tech_pvt->ring_event.ring.call, 0, 1);
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-
-
-static switch_status wanchan_read_frame(switch_core_session *session, switch_frame **frame, int timeout, switch_io_flag flags)
-{
- struct private_object *tech_pvt;
- switch_channel *channel = NULL;
- void *bp;
- int bytes = 0, res = 0;
-
- channel = switch_core_session_get_channel(session);
- assert(channel != NULL);
-
- tech_pvt = switch_core_session_get_private(session);
- assert(tech_pvt != NULL);
-
- bp = tech_pvt->databuf;
-
- *frame = NULL;
- memset(tech_pvt->databuf, 0, sizeof(tech_pvt->databuf));
- while (bytes < globals.bytes_per_frame) {
- if ((res = switch_socket_waitfor(tech_pvt->socket, timeout, POLLIN|POLLERR)) < 0) {
- return SWITCH_STATUS_GENERR;
- } else if (res == 0) {
- tech_pvt->frame.datalen = 0;
- return SWITCH_STATUS_SUCCESS;
- }
-
- if ((res = sangoma_readmsg_socket(
- tech_pvt->socket,
- &tech_pvt->hdrframe,
- sizeof(tech_pvt->hdrframe),
- bp,
- sizeof(tech_pvt->databuf) - bytes, 0)) < 0) {
- if (errno == EBUSY) {
- continue;
- } else {
- return SWITCH_STATUS_GENERR;
- }
- }
- bytes += res;
- bp += bytes;
- }
- tech_pvt->frame.datalen = bytes;
-
- *frame = &tech_pvt->frame;
- return SWITCH_STATUS_SUCCESS;
-}
-
-static switch_status wanchan_write_frame(switch_core_session *session, switch_frame *frame, int timeout, switch_io_flag flags)
-{
- struct private_object *tech_pvt;
- switch_channel *channel = NULL;
- int res = 0;
- int bytes = frame->datalen;
- void *bp = frame->data;
- switch_status status = SWITCH_STATUS_SUCCESS;
-
- channel = switch_core_session_get_channel(session);
- assert(channel != NULL);
-
- tech_pvt = switch_core_session_get_private(session);
- assert(tech_pvt != NULL);
-
- while (bytes > 0) {
- switch_socket_waitfor(tech_pvt->socket, -1, POLLOUT | POLLERR | POLLHUP);
- res = sangoma_sendmsg_socket(
- tech_pvt->socket,
- &tech_pvt->hdrframe,
- sizeof(tech_pvt->hdrframe),
- bp,
- PACKET_LEN, 0);
- if (res < 0) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Bad Write frame len %d write %d bytes returned %d errno %d!\n", frame->datalen, PACKET_LEN, res, errno);
- if (errno == EBUSY) {
- continue;
- }
- status = SWITCH_STATUS_GENERR;
- break;
- } else {
- bytes -= res;
- bp += res;
- res = 0;
- }
- }
-
- return status;
-}
-
-static const switch_io_routines wanchan_io_routines*/ {
- /*.outgoing_channel*/ wanchan_outgoing_channel,
- /*.answer_channel*/ wanchan_answer_channel,
- /*.read_frame*/ wanchan_read_frame,
- /*.write_frame*/ wanchan_write_frame
-};
-
-static const switch_event_handler_table wanchan_event_handlers = {
- /*.on_init*/ wanchan_on_init,
- /*.on_ring*/ wanchan_on_ring,
- /*.on_execute*/ NULL,
- /*.on_hangup*/ wanchan_on_hangup,
- /*.on_loopback*/ wanchan_on_loopback,
- /*.on_transmit*/ wanchan_on_transmit
-};
-
-static const switch_endpoint_interface wanchan_endpoint_interface = {
- /*.interface_name*/ "wanchan",
- /*.io_routines*/ &wanchan_io_routines,
- /*.event_handlers*/ &wanchan_event_handlers,
- /*.private*/ NULL,
- /*.next*/ NULL
-};
-
-static const switch_loadable_module_interface wanchan_module_interface = {
- /*.module_name*/ modname,
- /*.endpoint_interface*/ &wanchan_endpoint_interface,
- /*.timer_interface*/ NULL,
- /*.dialplan_interface*/ NULL,
- /*.codec_interface*/ NULL,
- /*.application_interface*/ NULL
-};
-
-Public switch_status switch_module_load(const switch_loadable_module_interface **interface, chanr *filename) {
-
-
- if (switch_core_new_memory_pool(&module_pool) != SWITCH_STATUS_SUCCESS) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "OH OH no pool\n");
- return SWITCH_STATUS_TERM;
- }
-
- /* connect my internal structure to the blank pointer passed to me */
- *interface = &wanchan_module_interface;
-
- /* indicate that the module should continue to be loaded */
- return SWITCH_STATUS_SUCCESS;
-}
-
-
-
-
-
-/* Event Handlers */
-
-static int on_info(struct sangoma_pri *spri, sangoma_pri_event_t event_type, pri_event *event)
-{
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "number is: %s\n", event->ring.callednum);
- if (strlen(event->ring.callednum) > 3) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "final number is: %s\n", event->ring.callednum);
- pri_answer(spri->pri, event->ring.call, 0, 1);
- }
- return 0;
-}
-
-static int on_hangup(struct sangoma_pri *spri, sangoma_pri_event_t event_type, pri_event *event)
-{
- struct channel_map *chanmap;
- switch_core_session *session;
- struct private_object *tech_pvt;
-
- chanmap = spri->private;
- if ((session = chanmap->map[event->hangup.channel])) {
- switch_channel *channel = NULL;
-
- channel = switch_core_session_get_channel(session);
- assert(channel != NULL);
-
- tech_pvt = switch_core_session_get_private(session);
- assert(tech_pvt != NULL);
-
- tech_pvt->cause = event->hangup.cause;
- memcpy(&tech_pvt->hangup_event, event, sizeof(*event));
-
- switch_channel_set_state(channel, CS_HANGUP);
- }
-
- switch_console_printf(SWITCH_CHANNEL_CONSOLE,"-- Hanging up channel %d\n", event->hangup.channel);
- return 0;
-}
-
-static int on_ring(struct sangoma_pri *spri, sangoma_pri_event_t event_type, pri_event *event)
-{
- char name[128];
- switch_core_session *session;
- switch_channel *channel;
- struct channel_map *chanmap;
-
-
-
- chanmap = spri->private;
- if (chanmap->map[event->ring.channel]) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE,"--Duplicate Ring on channel %d (ignored)\n", event->ring.channel);
- return 0;
- }
-
- switch_console_printf(SWITCH_CHANNEL_CONSOLE,"-- Ring on channel %d (from %s to %s)\n", event->ring.channel, event->ring.callingnum, event->ring.callednum);
-
- sprintf(name, "w%dg%d", globals.span, event->ring.channel);
- if ((session = switch_core_session_request(&wanchan_endpoint_interface, NULL))) {
- struct private_object *tech_pvt;
- int fd;
- char ani2str[4] = "";
- //wanpipe_tdm_api_t tdm_api;
-
- if ((tech_pvt = (struct private_object *) switch_core_session_alloc(session, sizeof(struct private_object)))) {
- memset(tech_pvt, 0, sizeof(*tech_pvt));
- channel = switch_core_session_get_channel(session);
- switch_core_session_set_private(session, tech_pvt);
- } else {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Hey where is my memory pool?\n");
- switch_core_session_destroy(&session);
- return 0;
- }
-
- if (event->ring.ani2 >= 0) {
- snprintf(ani2str, 5, "%.2d", event->ring.ani2);
- }
-
- if ((tech_pvt->caller_profile = switch_caller_profile_new(session,
- globals.dialplan,
- "wanchan fixme",
- event->ring.callingnum,
- event->ring.callingani,
- switch_strlen_zero(ani2str) ? NULL : ani2str,
- event->ring.callednum))) {
- switch_channel_set_caller_profile(channel, tech_pvt->caller_profile);
- }
-
- switch_set_flag(tech_pvt, TFLAG_INBOUND);
- tech_pvt->spri = spri;
- tech_pvt->cause = -1;
-
- memcpy(&tech_pvt->ring_event, event, sizeof(*event));
-
- tech_pvt->callno = event->ring.channel;
-
- if ((fd = sangoma_create_socket_intr(spri->span, event->ring.channel)) < 0) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Can't open fd!\n");
- }
-
- //sangoma_tdm_set_hw_period(fd, &tdm_api, 480);
-
- tech_pvt->socket = fd;
- chanmap->map[event->ring.channel] = session;
-
- switch_channel_set_state(channel, CS_INIT);
- switch_core_session_thread_launch(session);
- } else {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Cannot Create new Inbound Channel!\n");
- }
-
-
- return 0;
-}
-
-static int check_flags(struct sangoma_pri *spri)
-{
-
- return 0;
-}
-
-static int on_restart(struct sangoma_pri *spri, sangoma_pri_event_t event_type, pri_event *event)
-{
- int fd;
-
- switch_console_printf(SWITCH_CHANNEL_CONSOLE,"-- Restarting channel %d\n", event->restart.channel);
-
- if ((fd = sangoma_create_socket_intr(spri->span, event->restart.channel)) < 0) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE,"Can't open fd!\n");
- } else {
- close(fd);
- }
- return 0;
-}
-
-static int on_anything(struct sangoma_pri *spri, sangoma_pri_event_t event_type, pri_event *event)
-{
- switch_console_printf(SWITCH_CHANNEL_CONSOLE,"Caught Event %d (%s)\n", event_type, sangoma_pri_event_str(event_type));
- return 0;
-}
-
-
-static void *pri_thread_run(switch_thread *thread, void *obj)
-{
- struct sangoma_pri *spri = obj;
- struct channel_map chanmap;
-
- SANGOMA_MAP_PRI_EVENT((*spri), SANGOMA_PRI_EVENT_ANY, on_anything);
- SANGOMA_MAP_PRI_EVENT((*spri), SANGOMA_PRI_EVENT_RING, on_ring);
- SANGOMA_MAP_PRI_EVENT((*spri), SANGOMA_PRI_EVENT_HANGUP_REQ, on_hangup);
- SANGOMA_MAP_PRI_EVENT((*spri), SANGOMA_PRI_EVENT_INFO_RECEIVED, on_info);
- SANGOMA_MAP_PRI_EVENT((*spri), SANGOMA_PRI_EVENT_RESTART, on_restart);
-
- spri->on_loop = check_flags;
- spri->private = &chanmap;
- sangoma_run_pri(spri);
-
- free(spri);
- return NULL;
-}
-
-
-static int config_wanpipe(int reload)
-{
- switch_config cfg;
- char *var, *val;
- int count = 0;
- struct sangoma_pri *spri;
- char *cf = "wanchan.conf";
-
- globals.bytes_per_frame = DEFAULT_BYTES_PER_FRAME;
-
- if (!switch_config_open_file(&cfg, cf)) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "open of %s failed\n", cf);
- return SWITCH_STATUS_TERM;
- }
-
- while (switch_config_next_pair(&cfg, &var, &val)) {
- if (!strcasecmp(cfg.category, "settings")) {
- if (!strcmp(var, "debug")) {
- globals.debug = atoi(val);
- } else if (!strcmp(var, "span")) {
- globals.span = atoi(val);
- } else if (!strcmp(var, "dchan")) {
- globals.dchan = atoi(val);
- } else if (!strcmp(var, "node")) {
- globals.node = str2node(val);
- } else if (!strcmp(var, "switch")) {
- globals.pswitch = str2switch(val);
- } else if (!strcmp(var, "bpf")) {
- globals.bytes_per_frame = atoi(val);
- } else if (!strcmp(var, "dialplan")) {
- set_global_dialplan(val);
- }
- }
- }
-
- switch_config_close_file(&cfg);
-
- if (!globals.dialplan) {
- set_global_dialplan("default");
- }
-
- if ((spri=switch_core_alloc(module_pool, sizeof(*spri)))) {
- memset(spri, 0, sizeof(*spri));
- sangoma_init_pri(spri,
- globals.span,
- globals.dchan,
- 23,
- globals.pswitch,
- globals.node,
- globals.debug);
-
- pri_thread_run(NULL, spri);
-
- } else {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "error!\n");
- }
-
- return count;
-
-}
-
-
-Public switch_status switch_module_runtime(void)
-{
- config_wanpipe(0);
- return SWITCH_STATUS_TERM;
-}
-
+++ /dev/null
-/*
- * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
- * Copyright (C) 2005/2006, Anthony Minessale II <anthmct@yahoo.com>
- *
- * Version: MPL 1.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
- *
- * The Initial Developer of the Original Code is
- * Anthony Minessale II <anthmct@yahoo.com>
- * Portions created by the Initial Developer are Copyright (C)
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Anthony Minessale II <anthmct@yahoo.com>
- *
- *
- * mod_woomerachan.c -- Woomera Endpoint Module
- *
- */
-#include <switch.h>
-
-#define WOOMERA_STRLEN 256
-#define WOOMERA_ARRAY_LEN 50
-#define WOOMERA_MIN_PORT 9900
-#define WOOMERA_MAX_PORT 9999
-#define WOOMERA_BODYLEN 2048
-#define WOOMERA_LINE_SEPERATOR "\r\n"
-#define WOOMERA_RECORD_SEPERATOR "\r\n\r\n"
-#define WOOMERA_DEBUG_PREFIX "**[DEBUG]** "
-#define WOOMERA_DEBUG_LINE "--------------------------------------------------------------------------------"
-#define WOOMERA_HARD_TIMEOUT -10000
-#define WOOMERA_QLEN 10
-#define WOOMERA_RECONNECT_TIME 5000000
-#define MEDIA_ANSWER "ANSWER"
-// THE ONE ABOVE OR THE 2 BELOW BUT NOT BOTH
-//#define MEDIA_ANSWER "ANSWER"
-//#define USE_ANSWER 1
-
-static const char modname[] = "mod_woomera";
-
-static switch_memory_pool *module_pool;
-
-#define STRLEN 15
-#define FRAME_LEN 480
-//static int WFORMAT = AST_FORMAT_SLINEAR;
-
-typedef enum {
- WFLAG_EXISTS = (1 << 0),
- WFLAG_EVENT = (1 << 1),
- WFLAG_CONTENT = (1 << 2),
-} WFLAGS;
-
-
-typedef enum {
- WCFLAG_NOWAIT = (1 << 0)
-} WCFLAGS;
-
-
-typedef enum {
- PFLAG_INBOUND = (1 << 0),
- PFLAG_OUTBOUND = (1 << 1),
- PFLAG_DYNAMIC = (1 << 2),
- PFLAG_DISABLED = (1 << 3)
-} PFLAGS;
-
-typedef enum {
- TFLAG_MEDIA = (1 << 0),
- TFLAG_INBOUND = (1 << 1),
- TFLAG_OUTBOUND = (1 << 2),
- TFLAG_INCOMING = (1 << 3),
- TFLAG_PARSE_INCOMING = (1 << 4),
- TFLAG_ACTIVATE = (1 << 5),
- TFLAG_DTMF = (1 << 6),
- TFLAG_DESTROY = (1 << 7),
- TFLAG_ABORT = (1 << 8),
- TFLAG_SWITCH = (1 << 9),
- TFLAG_ANSWER = (1 << 10),
-} TFLAGS;
-
-struct woomera_message {
- char callid[WOOMERA_STRLEN];
- int mval;
- char command[WOOMERA_STRLEN];
- char command_args[WOOMERA_STRLEN];
- char names[WOOMERA_STRLEN][WOOMERA_ARRAY_LEN];
- char values[WOOMERA_STRLEN][WOOMERA_ARRAY_LEN];
- char body[WOOMERA_BODYLEN];
- unsigned int flags;
- int last;
- struct woomera_message *next;
-};
-
-
-static struct {
- int next_woomera_port;
- int debug;
- int panic;
- int rtpmode;
-} globals;
-
-struct woomera_event_queue {
- struct woomera_message *head;
-};
-
-struct woomera_profile {
- char *name;
- switch_socket_t *woomera_socket;
- apr_thread_mutex_t *iolock;
- char woomera_host[WOOMERA_STRLEN];
- int woomera_port;
- char audio_ip[WOOMERA_STRLEN];
- char dialplan[WOOMERA_STRLEN];
-// pthread_t thread;
- unsigned int flags;
- int thread_running;
- struct woomera_event_queue event_queue;
-};
-
-
-struct private_object {
- char *name;
- switch_frame frame;
- switch_codec read_codec;
- switch_codec write_codec;
- switch_core_session *session;
- switch_pollfd_t read_poll;
- switch_pollfd_t write_poll;
- switch_pollfd_t command_poll;
- unsigned char databuf[2048];
- switch_mutex_t *iolock;
- switch_sockaddr_t *udpread;
- switch_sockaddr_t *udpwrite;
- switch_socket_t *command_channel;
- switch_socket_t *udp_socket;
- unsigned int flags;
- short fdata[FRAME_LEN];
- struct woomera_message call_info;
- struct woomera_profile *profile;
- char dest[WOOMERA_STRLEN];
- int port;
- switch_time_t started;
- int timeout;
- char dtmfbuf[WOOMERA_STRLEN];
- switch_caller_profile *caller_profile;
- struct woomera_event_queue event_queue;
-};
-
-typedef struct private_object private_object;
-typedef struct woomera_message woomera_message;
-typedef struct woomera_profile woomera_profile;
-typedef struct woomera_event_queue woomera_event_queue;
-
-static woomera_profile default_profile;
-
-static const switch_endpoint_interface woomerachan_endpoint_interface;
-
-static switch_status woomerachan_on_init(switch_core_session *session);
-static switch_status woomerachan_on_hangup(switch_core_session *session);
-static switch_status woomerachan_on_ring(switch_core_session *session);
-static switch_status woomerachan_on_loopback(switch_core_session *session);
-static switch_status woomerachan_on_transmit(switch_core_session *session);
-static switch_status woomerachan_outgoing_channel(switch_core_session *session, switch_caller_profile *outbound_profile, switch_core_session **new_session);
-static switch_status woomerachan_read_frame(switch_core_session *session, switch_frame **frame, int timeout, switch_io_flag flags);
-static switch_status woomerachan_write_frame(switch_core_session *session, switch_frame *frame, int timeout, switch_io_flag flags);
-static switch_status woomerachan_kill_channel(switch_core_session *session, int sig);
-static void tech_destroy(private_object *tech_pvt);
-static void woomera_printf(woomera_profile *profile, switch_socket_t *socket, char *fmt, ...);
-static char *woomera_message_header(woomera_message *wmsg, char *key);
-static int woomera_enqueue_event(woomera_event_queue *event_queue, woomera_message *wmsg);
-static int woomera_dequeue_event(woomera_event_queue *event_queue, woomera_message *wmsg);
-static int woomera_message_parse(switch_socket_t *fd, woomera_message *wmsg, int timeout, woomera_profile *profile, woomera_event_queue *event_queue);
-static int connect_woomera(switch_socket_t **new_sock, woomera_profile *profile, int flags);
-static int woomera_profile_thread_running(woomera_profile *profile, int set, int new);
-static int woomera_locate_socket(woomera_profile *profile, switch_socket_t **woomera_socket);
-static int tech_create_read_socket(private_object *tech_pvt);
-static void *woomera_channel_thread_run(switch_thread *thread, void *obj);
-static void *woomera_thread_run(void *obj);
-static int tech_activate(private_object *tech_pvt);
-
-/*
- State methods they get called when the state changes to the specific state
- returning SWITCH_STATUS_SUCCESS tells the core to execute the standard state method next
- so if you fully implement the state you can return SWITCH_STATUS_FALSE to skip it.
-*/
-static switch_status woomerachan_on_init(switch_core_session *session)
-{
- switch_channel *channel;
- struct private_object *tech_pvt = NULL;
- int rate = 8000;
-
- tech_pvt = switch_core_session_get_private(session);
- assert(tech_pvt != NULL);
-
- channel = switch_core_session_get_channel(session);
- assert(channel != NULL);
-
- tech_pvt->frame.data = tech_pvt->databuf;
-
- if (switch_core_codec_init(&tech_pvt->read_codec, "L16", rate, 30, 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "%s Cannot set read codec\n", switch_channel_get_name(channel));
- switch_channel_hangup(channel);
- return SWITCH_STATUS_FALSE;
- }
-
- if (switch_core_codec_init(&tech_pvt->write_codec, "L16", rate, 30, 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "%s Cannot set read codec\n", switch_channel_get_name(channel));
- switch_channel_hangup(channel);
- return SWITCH_STATUS_FALSE;
- }
- tech_pvt->frame.rate = rate;
- tech_pvt->frame.codec = &tech_pvt->read_codec;
- switch_core_session_set_read_codec(session, &tech_pvt->read_codec);
- switch_core_session_set_write_codec(session, &tech_pvt->write_codec);
-
-
- switch_set_flag(tech_pvt, TFLAG_ACTIVATE);
-
- switch_core_session_launch_thread(session, woomera_channel_thread_run, session);
-
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "%s WOOMERACHAN INIT\n", switch_channel_get_name(channel));
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-static switch_status woomerachan_on_ring(switch_core_session *session)
-{
- switch_channel *channel = NULL;
- struct private_object *tech_pvt = NULL;
-
- channel = switch_core_session_get_channel(session);
- assert(channel != NULL);
-
- tech_pvt = switch_core_session_get_private(session);
- assert(tech_pvt != NULL);
-
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "%s WOOMERACHAN RING\n", switch_channel_get_name(channel));
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-static switch_status woomerachan_on_execute(switch_core_session *session)
-{
-
- switch_channel *channel = NULL;
- struct private_object *tech_pvt = NULL;
-
- channel = switch_core_session_get_channel(session);
- assert(channel != NULL);
-
- tech_pvt = switch_core_session_get_private(session);
- assert(tech_pvt != NULL);
-
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "%s WOOMERACHAN EXECUTE\n", switch_channel_get_name(channel));
-
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-static switch_status woomerachan_on_hangup(switch_core_session *session)
-{
- switch_channel *channel = NULL;
- struct private_object *tech_pvt = NULL;
-
- channel = switch_core_session_get_channel(session);
- assert(channel != NULL);
-
- tech_pvt = switch_core_session_get_private(session);
- assert(tech_pvt != NULL);
-
-
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "%s WOOMERACHAN HANGUP\n", switch_channel_get_name(channel));
- tech_destroy(tech_pvt);
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-static void woomera_socket_close(switch_socket_t **socket)
-{
- if (*socket) {
- switch_socket_close(*socket);
- *socket = NULL;
- }
-}
-
-
-static void udp_socket_close(struct private_object *tech_pvt)
-{
- if (tech_pvt->udp_socket) {
- apr_socket_shutdown(tech_pvt->udp_socket, APR_SHUTDOWN_READWRITE);
- woomera_socket_close(&tech_pvt->udp_socket);
- }
-}
-
-
-static switch_status woomerachan_kill_channel(switch_core_session *session, int sig)
-{
- switch_channel *channel = NULL;
- struct private_object *tech_pvt = NULL;
-
- channel = switch_core_session_get_channel(session);
- assert(channel != NULL);
-
- tech_pvt = switch_core_session_get_private(session);
- assert(tech_pvt != NULL);
-
- if (!tech_pvt->udp_socket) {
- return SWITCH_STATUS_FALSE;
- }
-
- udp_socket_close(tech_pvt);
-
- switch_channel_hangup(channel);
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "%s WOOMERACHAN KILL %d\n", switch_channel_get_name(channel), tech_pvt->udp_socket);
-
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-static switch_status woomerachan_on_loopback(switch_core_session *session)
-{
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "WOOMERACHAN LOOPBACK\n");
- return SWITCH_STATUS_SUCCESS;
-}
-
-static switch_status woomerachan_on_transmit(switch_core_session *session)
-{
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "WOOMERACHAN TRANSMIT\n");
- return SWITCH_STATUS_SUCCESS;
-}
-
-
-/* Make sure when you have 2 sessions in the same scope that you pass the appropriate one to the routines
- that allocate memory or you will have 1 channel with memory allocated from another channel's pool!
-*/
-static switch_status woomerachan_outgoing_channel(switch_core_session *session, switch_caller_profile *outbound_profile, switch_core_session **new_session)
-{
- if ((*new_session = switch_core_session_request(&woomerachan_endpoint_interface, NULL))) {
- struct private_object *tech_pvt;
- switch_channel *channel;
-
-
- if ((tech_pvt = (struct private_object *) switch_core_session_alloc(*new_session, sizeof(struct private_object)))) {
- memset(tech_pvt, 0, sizeof(*tech_pvt));
- tech_pvt->profile = &default_profile;
- channel = switch_core_session_get_channel(*new_session);
- switch_core_session_set_private(*new_session, tech_pvt);
- tech_pvt->session = *new_session;
- } else {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Hey where is my memory pool?\n");
- switch_core_session_destroy(new_session);
- return SWITCH_STATUS_GENERR;
- }
-
- if (outbound_profile) {
- char name[128];
- switch_caller_profile *caller_profile;
-
- caller_profile = switch_caller_profile_clone(*new_session, outbound_profile);
- switch_channel_set_caller_profile(channel, caller_profile);
- tech_pvt->caller_profile = caller_profile;
- snprintf(name, sizeof(name), "Woomera/%s-%04x", caller_profile->destination_number, rand() & 0xffff);
- switch_channel_set_name(channel, name);
- } else {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Doh! no caller profile\n");
- switch_core_session_destroy(new_session);
- return SWITCH_STATUS_GENERR;
- }
-
- switch_channel_set_flag(channel, CF_OUTBOUND);
- switch_set_flag(tech_pvt, TFLAG_OUTBOUND);
- switch_channel_set_state(channel, CS_INIT);
- return SWITCH_STATUS_SUCCESS;
- }
-
- return SWITCH_STATUS_GENERR;
-
-}
-
-static switch_status woomerachan_waitfor_read(switch_core_session *session, int ms)
-{
- struct private_object *tech_pvt = NULL;
-
- tech_pvt = switch_core_session_get_private(session);
- assert(tech_pvt != NULL);
-
- return switch_socket_waitfor(&tech_pvt->read_poll, ms);
-}
-
-static switch_status woomerachan_waitfor_write(switch_core_session *session, int ms)
-{
- struct private_object *tech_pvt = NULL;
-
- tech_pvt = switch_core_session_get_private(session);
- assert(tech_pvt != NULL);
-
- return SWITCH_STATUS_SUCCESS;
- return switch_socket_waitfor(&tech_pvt->write_poll, ms);
-}
-
-static switch_status woomerachan_read_frame(switch_core_session *session, switch_frame **frame, int timeout, switch_io_flag flags)
-{
- switch_channel *channel = NULL;
- struct private_object *tech_pvt = NULL;
- switch_frame *pframe;
- switch_status status;
-
- channel = switch_core_session_get_channel(session);
- assert(channel != NULL);
-
- tech_pvt = switch_core_session_get_private(session);
- assert(tech_pvt != NULL);
-
- if (!tech_pvt->udp_socket) {
- return SWITCH_STATUS_GENERR;
- }
- /*
- if ((status = woomerachan_waitfor_read(session, -1)) != SWITCH_STATUS_SUCCESS) {
- return status;
- }1<
- */
- pframe = &tech_pvt->frame;
- *frame = pframe;
-
- pframe->datalen = sizeof(tech_pvt->databuf);
- if ((status = switch_socket_recvfrom (tech_pvt->udpread, tech_pvt->udp_socket, 0, tech_pvt->databuf, &pframe->datalen)) == SWITCH_STATUS_SUCCESS) {
- pframe->samples = (int)pframe->datalen / 2;
- }
- return status;
-}
-
-static switch_status woomerachan_write_frame(switch_core_session *session, switch_frame *frame, int timeout, switch_io_flag flags)
-{
- switch_channel *channel = NULL;
- struct private_object *tech_pvt = NULL;
- switch_frame *pframe;
-
- channel = switch_core_session_get_channel(session);
- assert(channel != NULL);
-
- tech_pvt = switch_core_session_get_private(session);
- assert(tech_pvt != NULL);
-
- if (!tech_pvt->udp_socket) {
- return SWITCH_STATUS_GENERR;
- }
-
- pframe = &tech_pvt->frame;
- return switch_socket_sendto(tech_pvt->udp_socket, tech_pvt->udpwrite, 0, frame->data, &frame->datalen);
-
-}
-
-static const switch_event_handler_table woomerachan_event_handlers = {
- /*.on_init*/ woomerachan_on_init,
- /*.on_ring*/ woomerachan_on_ring,
- /*.on_execute*/ woomerachan_on_execute,
- /*.on_hangup*/ woomerachan_on_hangup,
- /*.on_loopback*/ woomerachan_on_loopback,
- /*.on_transmit*/ woomerachan_on_transmit
-};
-
-static const switch_io_routines woomerachan_io_routines = {
- /*.outgoing_channel*/ woomerachan_outgoing_channel,
- /*.answer_channel*/ NULL,
- /*.read_frame*/ woomerachan_read_frame,
- /*.write_frame*/ woomerachan_write_frame,
- /*.kill_channel*/ woomerachan_kill_channel,
- /*.waitfor_read*/ woomerachan_waitfor_read,
- /*.waitfor_write*/ woomerachan_waitfor_write
-};
-
-static const switch_endpoint_interface woomerachan_endpoint_interface = {
- /*.interface_name*/ "woomera",
- /*.io_routines*/ &woomerachan_io_routines,
- /*.event_handlers*/ &woomerachan_event_handlers,
- /*.private*/ NULL,
- /*.next*/ NULL
-};
-
-static const switch_loadable_module_interface woomerachan_module_interface = {
- /*.module_name*/ modname,
- /*.endpoint_interface*/ &woomerachan_endpoint_interface,
- /*.timer_interface*/ NULL,
- /*.dialplan_interface*/ NULL,
- /*.codec_interface*/ NULL,
- /*.application_interface*/ NULL
-};
-
-
-static void tech_destroy(private_object *tech_pvt)
-{
- woomera_message wmsg;
-
- if (globals.debug > 1) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, WOOMERA_DEBUG_PREFIX "+++DESTROY\n");
- }
-
-
- woomera_printf(tech_pvt->profile, tech_pvt->command_channel, "hangup %s%s", tech_pvt->call_info.callid, WOOMERA_RECORD_SEPERATOR);
- if(woomera_message_parse(tech_pvt->command_channel,
- &wmsg,
- WOOMERA_HARD_TIMEOUT,
- tech_pvt->profile,
- &tech_pvt->event_queue
- ) < 0) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "{%s} Already Disconnected\n", tech_pvt->profile->name);
- }
-
- woomera_printf(tech_pvt->profile, tech_pvt->command_channel, "bye%s", WOOMERA_RECORD_SEPERATOR);
- woomera_socket_close(&tech_pvt->command_channel);
- udp_socket_close(tech_pvt);
-}
-
-
-static void woomera_printf(woomera_profile *profile, switch_socket_t *socket, char *fmt, ...)
-{
- char *stuff;
- size_t res = 0, len = 0;
-
- va_list ap;
- va_start(ap, fmt);
-#ifndef vasprintf
- stuff = (char *)malloc(10240);
- vsnprintf(stuff, 10240, fmt, ap);
-#else
- res = vasprintf(&stuff, fmt, ap);
-#endif
- va_end(ap);
- if (res == -1) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Out of memory\n");
- } else {
- if (profile && globals.debug) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Send Message: {%s} [%s/%d]\n%s\n%s", profile->name, profile->woomera_host, profile->woomera_port, WOOMERA_DEBUG_LINE, stuff);
- }
- len = strlen(stuff);
- switch_socket_send(socket, stuff, &len);
-
- free(stuff);
- }
-
-}
-
-static char *woomera_message_header(woomera_message *wmsg, char *key)
-{
- int x = 0;
- char *value = NULL;
-
- for (x = 0 ; x < wmsg->last ; x++) {
- if (!strcasecmp(wmsg->names[x], key)) {
- value = wmsg->values[x];
- break;
- }
- }
-
- return value;
-}
-
-static int woomera_enqueue_event(woomera_event_queue *event_queue, woomera_message *wmsg)
-{
- woomera_message *new, *mptr;
-
- if ((new = malloc(sizeof(woomera_message)))) {
- memcpy(new, wmsg, sizeof(woomera_message));
- new->next = NULL;
-
- if (!event_queue->head) {
- event_queue->head = new;
- } else {
- for (mptr = event_queue->head; mptr && mptr->next ; mptr = mptr->next);
- mptr->next = new;
- }
- return 1;
- } else {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Memory Allocation Error!\n");
- }
-
- return 0;
-}
-
-static int woomera_dequeue_event(woomera_event_queue *event_queue, woomera_message *wmsg)
-{
- woomera_message *mptr = NULL;
-
- if (event_queue->head) {
- mptr = event_queue->head;
- event_queue->head = mptr->next;
- }
-
- if (mptr) {
- memcpy(wmsg, mptr, sizeof(woomera_message));
- free(mptr);
- return 1;
- } else {
- memset(wmsg, 0, sizeof(woomera_message));
- }
-
- return 0;
-}
-
-static int woomera_message_parse(switch_socket_t *fd, woomera_message *wmsg, int timeout, woomera_profile *profile, woomera_event_queue *event_queue)
-{
- char *cur, *cr, *next = NULL, *eor = NULL;
- char buf[2048] = "", *ptr;
- int bytes = 0;
- int failto = 0;
-
- memset(wmsg, 0, sizeof(woomera_message));
-
- if (fd < 0 ) {
- return -1;
- }
-
- if (timeout < 0) {
- timeout = abs(timeout);
- failto = 1;
- } else if (timeout == 0) {
- timeout = -1;
- }
-
- ptr = buf;
- bytes = 0;
- while (!(eor = strstr(buf, WOOMERA_RECORD_SEPERATOR))) {
- size_t len = 1;
-
- if (!profile->thread_running) {
- return -1;
- }
-
- if (switch_socket_recv(fd, ptr, &len) != SWITCH_STATUS_SUCCESS) {
- return -1;
- }
- ptr++;
- bytes++;
- }
- //*eor = '\0';
- next = buf;
-
- if (globals.debug) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Receive Message: {%s} [%s/%d]\n%s\n%s", profile->name, profile->woomera_host, profile->woomera_port, WOOMERA_DEBUG_LINE, buf);
- }
-
- while((cur = next)) {
- if ((cr = strstr(cur, WOOMERA_LINE_SEPERATOR))) {
- *cr = '\0';
- next = cr + (sizeof(WOOMERA_LINE_SEPERATOR) - 1);
- if (!strcmp(next, WOOMERA_RECORD_SEPERATOR)) {
- break;
- }
- }
-
- if (!cur || !cur[0]) {
- break;
- }
-
- if (!wmsg->last) {
- switch_set_flag(wmsg, WFLAG_EXISTS);
- if (!strncasecmp(cur, "EVENT", 5)) {
- cur += 6;
- switch_set_flag(wmsg, WFLAG_EVENT);
-
- if (cur && (cr = strchr(cur, ' '))) {
- char *id;
-
- *cr = '\0';
- cr++;
- id = cr;
- if (cr && (cr = strchr(cr, ' '))) {
- *cr = '\0';
- cr++;
- strncpy(wmsg->command_args, cr, WOOMERA_STRLEN);
- }
- if (id) {
- strncpy(wmsg->callid, id, sizeof(wmsg->callid) - 1);
- }
- }
- } else {
- if (cur && (cur = strchr(cur, ' '))) {
- *cur = '\0';
- cur++;
- wmsg->mval = atoi(buf);
- } else {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Malformed Message!\n");
- break;
- }
- }
- if (cur) {
- strncpy(wmsg->command, cur, WOOMERA_STRLEN);
- } else {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Malformed Message!\n");
- break;
- }
- } else {
- char *name, *val;
- name = cur;
- if ((val = strchr(name, ':'))) {
- *val = '\0';
- val++;
- while (*val == ' ') {
- *val = '\0';
- val++;
- }
- strncpy(wmsg->values[wmsg->last-1], val, WOOMERA_STRLEN);
- }
- strncpy(wmsg->names[wmsg->last-1], name, WOOMERA_STRLEN);
- if (name && val && !strcasecmp(name, "content-type")) {
- switch_set_flag(wmsg, WFLAG_CONTENT);
- bytes = atoi(val);
- }
-
- }
- wmsg->last++;
- }
-
- wmsg->last--;
-
- if (bytes && switch_test_flag(wmsg, WFLAG_CONTENT)) {
- size_t len = (bytes > sizeof(wmsg->body)) ? sizeof(wmsg->body) : bytes;
- switch_socket_recv(fd, wmsg->body, &len);
-
- if (globals.debug) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "%s\n", wmsg->body);
- }
- }
-
- if (event_queue && switch_test_flag(wmsg, WFLAG_EVENT)) {
- if (globals.debug) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Queue Event: {%s} [%s]\n", profile->name, wmsg->command);
- }
- /* we don't want events we want a reply so we will stash them for later */
- woomera_enqueue_event(event_queue, wmsg);
-
- /* call ourself recursively to find the reply. we'll keep doing this as long we get events.
- * wmsg will be overwritten but it's ok we just queued it.
- */
- return woomera_message_parse(fd, wmsg, timeout, profile, event_queue);
-
- } else if (wmsg->mval > 99 && wmsg->mval < 200) {
- /* reply in the 100's are nice but we need to wait for another reply
- call ourself recursively to find the reply > 199 and forget this reply.
- */
- return woomera_message_parse(fd, wmsg, timeout, profile, event_queue);
- } else {
- return switch_test_flag(wmsg, WFLAG_EXISTS);
- }
-}
-
-
-static int connect_woomera(switch_socket_t **new_sock, woomera_profile *profile, int flags)
-{
-
- switch_sockaddr_t *sa;
- switch_status status;
-
- status = switch_sockaddr_info_get(&sa, profile->woomera_host, AF_INET, profile->woomera_port, 0, module_pool);
- if (status != SWITCH_STATUS_SUCCESS) {
- return -1;
- }
- status = switch_socket_create(new_sock, AF_INET, SOCK_STREAM, 0, module_pool);
- if (status != SWITCH_STATUS_SUCCESS) {
- return -1;
- }
- /*
- status = switch_socket_bind((*new_sock), sa);
- if (0 && status != SWITCH_STATUS_SUCCESS) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Can't Bind to %s:%d!\n", profile->woomera_host, profile->woomera_port);
- return -1;
- }
- */
- status = switch_socket_connect((*new_sock), sa);
- if (status != SWITCH_STATUS_SUCCESS) {
- return -1;
- }
-
- return 1;
-}
-
-static int woomera_profile_thread_running(woomera_profile *profile, int set, int new)
-{
- int running = 0;
-
- switch_mutex_lock(profile->iolock);
- if (set) {
- profile->thread_running = new;
- }
- running = profile->thread_running;
- switch_mutex_unlock(profile->iolock);
- return running;
-
-}
-
-static int woomera_locate_socket(woomera_profile *profile, switch_socket_t **woomera_socket)
-{
- woomera_message wmsg;
-
- for (;;) {
-
- while (connect_woomera(woomera_socket, profile, 0) < 0) {
- if (!woomera_profile_thread_running(profile, 0, 0)) {
- break;
- }
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "{%s} Cannot Reconnect to Woomera! retry in 5 seconds\n", profile->name);
- switch_sleep(WOOMERA_RECONNECT_TIME);
- }
-
- if (*woomera_socket) {
- if (switch_test_flag(profile, PFLAG_INBOUND)) {
- woomera_printf(profile, *woomera_socket, "LISTEN%s", WOOMERA_RECORD_SEPERATOR);
- if (woomera_message_parse(*woomera_socket,
- &wmsg,
- WOOMERA_HARD_TIMEOUT,
- profile,
- &profile->event_queue
- ) < 0) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "{%s} HELP! Woomera is broken!\n", profile->name);
- globals.panic = 1;
- woomera_profile_thread_running(&default_profile, 1, 0);
- switch_sleep(WOOMERA_RECONNECT_TIME);
- if (*woomera_socket) {
- woomera_socket_close(woomera_socket);
- }
-
- continue;
- }
- }
-
- }
- switch_sleep(100);
- break;
- }
- return *woomera_socket ? 1 : 0;
-}
-
-
-
-static int tech_create_read_socket(private_object *tech_pvt)
-{
- switch_memory_pool *pool = switch_core_session_get_pool(tech_pvt->session);
-
- if ((tech_pvt->port = globals.next_woomera_port++) >= WOOMERA_MAX_PORT) {
- tech_pvt->port = globals.next_woomera_port = WOOMERA_MIN_PORT;
- }
-
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "connect %s:%d\n", tech_pvt->profile->audio_ip, tech_pvt->port);
- //tech_pvt->udp_socket = create_udp_socket(tech_pvt->profile->audio_ip, tech_pvt->port, &tech_pvt->udpread, 0);
-
- switch_sockaddr_info_get(&tech_pvt->udpread, tech_pvt->profile->audio_ip, SWITCH_UNSPEC, tech_pvt->port, 0, pool);
- if (switch_socket_create(&tech_pvt->udp_socket, AF_INET, SOCK_DGRAM, 0, pool) == SWITCH_STATUS_SUCCESS) {
- switch_socket_bind(tech_pvt->udp_socket, tech_pvt->udpread);
- switch_socket_create_pollfd(&tech_pvt->read_poll, tech_pvt->udp_socket, SWITCH_POLLIN|SWITCH_POLLERR, pool);
- switch_socket_create_pollfd(&tech_pvt->write_poll, tech_pvt->udp_socket, SWITCH_POLLOUT|SWITCH_POLLERR, pool);
- }
-
- return 0;
-}
-
-
-static int tech_activate(private_object *tech_pvt)
-{
- woomera_message wmsg;
-
- if (tech_pvt) {
- if((connect_woomera(&tech_pvt->command_channel, tech_pvt->profile, 0))) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "connected to woomera!\n");
- } else {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Can't connect to woomera!\n");
- switch_sleep(WOOMERA_RECONNECT_TIME);
- return -1;
- }
-
- if (switch_test_flag(tech_pvt, TFLAG_OUTBOUND)) {
-
- woomera_printf(tech_pvt->profile,
- tech_pvt->command_channel,
- "CALL %s%sRaw-Audio: %s/%d%sLocal-Name: %s!%s%s",
- tech_pvt->caller_profile->destination_number,
- WOOMERA_LINE_SEPERATOR,
- tech_pvt->profile->audio_ip,
- tech_pvt->port,
- WOOMERA_LINE_SEPERATOR,
- tech_pvt->caller_profile->caller_id_name,
- tech_pvt->caller_profile->caller_id_number,
- WOOMERA_RECORD_SEPERATOR
- );
-
- woomera_message_parse(tech_pvt->command_channel,
- &wmsg,
- WOOMERA_HARD_TIMEOUT,
- tech_pvt->profile,
- &tech_pvt->event_queue
- );
- } else {
- switch_set_flag(tech_pvt, TFLAG_PARSE_INCOMING);
- woomera_printf(tech_pvt->profile, tech_pvt->command_channel, "LISTEN%s", WOOMERA_RECORD_SEPERATOR);
- if (woomera_message_parse(tech_pvt->command_channel,
- &wmsg,
- WOOMERA_HARD_TIMEOUT,
- tech_pvt->profile,
- &tech_pvt->event_queue
- ) < 0) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "{%s} HELP! Woomera is broken!\n", tech_pvt->profile->name);
- switch_set_flag(tech_pvt, TFLAG_ABORT);
- globals.panic = 1;
- }
- }
- } else {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Where's my tech_pvt?\n");
- }
-
- return 0;
-}
-
-
-
-static void *woomera_channel_thread_run(switch_thread *thread, void *obj)
-{
- switch_core_session *session = obj;
- switch_channel *channel = NULL;
- struct private_object *tech_pvt = NULL;
- woomera_message wmsg;
- int res = 0;
-
- assert(session != NULL);
-
- channel = switch_core_session_get_channel(session);
- assert(channel != NULL);
-
- tech_pvt = switch_core_session_get_private(session);
- assert(tech_pvt != NULL);
-
- if (!tech_pvt->udp_socket) {
- tech_create_read_socket(tech_pvt);
- }
-
-
- for(;;) {
- if (globals.panic) {
- switch_set_flag(tech_pvt, TFLAG_ABORT);
- }
-
- if (switch_test_flag(tech_pvt, TFLAG_ABORT)) {
- if (switch_channel_get_state(channel) < CS_HANGUP) {
- switch_channel_set_state(channel, CS_HANGUP);
- }
- udp_socket_close(tech_pvt);
- break;
- }
-
- if (switch_test_flag(tech_pvt, TFLAG_ACTIVATE)) {
- switch_clear_flag(tech_pvt, TFLAG_ACTIVATE);
- tech_activate(tech_pvt);
- }
-
- if (switch_test_flag(tech_pvt, TFLAG_ANSWER)) {
- switch_clear_flag(tech_pvt, TFLAG_ANSWER);
-#ifdef USE_ANSWER
- woomera_printf(tech_pvt->profile, tech_pvt->command_channel, "ANSWER %s%s",tech_pvt->call_info.callid, WOOMERA_RECORD_SEPERATOR);
- if(woomera_message_parse(tech_pvt->command_channel,
- &wmsg,
- WOOMERA_HARD_TIMEOUT,
- tech_pvt->profile,
- &tech_pvt->event_queue
- ) < 0) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "{%s} HELP! Woomera is broken!\n", tech_pvt->profile->name);
- switch_set_flag(tech_pvt, TFLAG_ABORT);
- globals.panic = 1;
- continue;
- }
-#endif
- }
-
- if (switch_test_flag(tech_pvt, TFLAG_DTMF)) {
- switch_mutex_lock(tech_pvt->iolock);
- woomera_printf(tech_pvt->profile, tech_pvt->command_channel, "DTMF %s %s%s",tech_pvt->call_info.callid, tech_pvt->dtmfbuf, WOOMERA_RECORD_SEPERATOR);
- if(woomera_message_parse(tech_pvt->command_channel,
- &wmsg,
- WOOMERA_HARD_TIMEOUT,
- tech_pvt->profile,
- &tech_pvt->event_queue
- ) < 0) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "{%s} HELP! Woomera is broken!\n", tech_pvt->profile->name);
- switch_set_flag(tech_pvt, TFLAG_ABORT);
- globals.panic = 1;
- continue;
- }
- switch_clear_flag(tech_pvt, TFLAG_DTMF);
- memset(tech_pvt->dtmfbuf, 0, sizeof(tech_pvt->dtmfbuf));
- switch_mutex_unlock(tech_pvt->iolock);
- }
-
-#if 1==0 /*convert to use switch_time_now */
- if(tech_pvt->timeout) {
- struct timeval now;
- int elapsed;
- gettimeofday(&now, NULL);
- elapsed = (((now.tv_sec * 1000) + now.tv_usec / 1000) - ((tech_pvt->started.tv_sec * 1000) + tech_pvt->started.tv_usec / 1000));
- if (elapsed > tech_pvt->timeout) {
- /* call timed out! */
- switch_set_flag(tech_pvt, TFLAG_ABORT);
- }
- }
-#endif
-
- if (!tech_pvt->command_channel) {
- break;
- }
- /* Check for events */
- if((res = woomera_dequeue_event(&tech_pvt->event_queue, &wmsg)) ||
- (res = woomera_message_parse(tech_pvt->command_channel,
- &wmsg,
- 100,
- tech_pvt->profile,
- NULL
- ))) {
-
- if (res < 0 || !strcasecmp(wmsg.command, "HANGUP")) {
- switch_set_flag(tech_pvt, TFLAG_ABORT);
- continue;
- } else if (!strcasecmp(wmsg.command, "DTMF")) {
- /*
- struct ast_frame dtmf_frame = {AST_FRAME_DTMF};
- int x = 0;
- for (x = 0; x < strlen(wmsg.command_args); x++) {
- dtmf_frame.subclass = wmsg.command_args[x];
- ast_queue_frame(tech_pvt->owner, ast_frdup(&dtmf_frame));
- if (globals.debug > 1) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, WOOMERA_DEBUG_PREFIX "SEND DTMF [%c] to %s\n", dtmf_frame.subclass, tech_pvt->owner->name);
- }
- }
- */
- } else if (!strcasecmp(wmsg.command, "PROCEED")) {
- /* This packet has lots of info so well keep it */
- tech_pvt->call_info = wmsg;
- } else if (switch_test_flag(tech_pvt, TFLAG_PARSE_INCOMING) && !strcasecmp(wmsg.command, "INCOMING")) {
- char *exten;
- char cid_name[512];
- char *cid_num;
- char *ip;
- char *p;
- switch_clear_flag(tech_pvt, TFLAG_PARSE_INCOMING);
- switch_set_flag(tech_pvt, TFLAG_INCOMING);
- tech_pvt->call_info = wmsg;
-
- exten = woomera_message_header(&wmsg, "Local-Number");
- if (switch_strlen_zero(exten)) {
- exten = "s";
- }
-
- if ((p = woomera_message_header(&wmsg, "Remote-Name"))) {
- strncpy(cid_name, p, sizeof(cid_name));
- }
-
- if ((cid_num = strchr(cid_name, '!'))) {
- *cid_num = '\0';
- cid_num++;
- } else {
- cid_num = woomera_message_header(&wmsg, "Remote-Number");
- }
- ip = woomera_message_header(&wmsg, "Remote-Address");
-
- if ((tech_pvt->caller_profile = switch_caller_profile_new(session,
- tech_pvt->profile->dialplan,
- cid_name,
- cid_num,
- ip,
- NULL,
- NULL,
- exten))) {
- char name[128];
- switch_channel_set_caller_profile(channel, tech_pvt->caller_profile);
- snprintf(name, sizeof(name), "Woomera/%s-%04x", tech_pvt->caller_profile->destination_number, rand() & 0xffff);
- switch_channel_set_name(channel, name);
- }
-
- woomera_printf(tech_pvt->profile, tech_pvt->command_channel,
- "%s %s%s"
- "Raw-Audio: %s/%d%s",
- MEDIA_ANSWER,
- wmsg.callid,
- WOOMERA_LINE_SEPERATOR,
- tech_pvt->profile->audio_ip,
- tech_pvt->port,
- WOOMERA_RECORD_SEPERATOR);
-
- if(woomera_message_parse(tech_pvt->command_channel,
- &wmsg,
- WOOMERA_HARD_TIMEOUT,
- tech_pvt->profile,
- &tech_pvt->event_queue
- ) < 0) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "{%s} HELP! Woomera is broken!\n", tech_pvt->profile->name);
- switch_set_flag(tech_pvt, TFLAG_ABORT);
- globals.panic = 1;
- continue;
- }
-
- } else if (!strcasecmp(wmsg.command, "CONNECT")) {
-
- } else if (!strcasecmp(wmsg.command, "MEDIA")) {
- char *raw_audio_header;
-
- if ((raw_audio_header = woomera_message_header(&wmsg, "Raw-Audio"))) {
- char ip[25];
- char *ptr;
- int port = 0;
-
- strncpy(ip, raw_audio_header, sizeof(ip) - 1);
- if ((ptr=strchr(ip, '/'))) {
- *ptr = '\0';
- ptr++;
- port = atoi(ptr);
- }
- /* Move Channel's State Machine to RING */
- switch_channel_answer(channel);
- switch_channel_set_state(channel, CS_RING);
-
- if (switch_sockaddr_info_get(&tech_pvt->udpwrite,
- ip,
- SWITCH_UNSPEC,
- port,
- 0,
- switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) {
- if (globals.debug) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, WOOMERA_DEBUG_PREFIX "{%s} Cannot resolve %s\n", tech_pvt->profile->name, ip);
- }
- switch_channel_hangup(channel);
- }
- }
- }
- }
- if (globals.debug > 2) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, WOOMERA_DEBUG_PREFIX "CHECK {%s}(%d)\n", tech_pvt->profile->name, res);
- }
- }
- if (globals.debug > 1) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, WOOMERA_DEBUG_PREFIX "Monitor thread for %s done.\n", tech_pvt->profile->name);
- }
-
- return NULL;
-}
-
-
-
-
-static void *woomera_thread_run(void *obj)
-{
-
- int res = 0;
- woomera_message wmsg;
- woomera_profile *profile;
-
- profile = obj;
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Started Woomera Thread {%s}.\n", profile->name);
-
- profile->thread_running = 1;
- profile->woomera_socket = NULL;
-
-
- while(woomera_profile_thread_running(profile, 0, 0)) {
- /* listen on socket and handle events */
- if (globals.panic == 2) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Woomera is disabled!\n");
- switch_sleep(WOOMERA_RECONNECT_TIME);
- continue;
- }
-
- if (! profile->woomera_socket) {
- if (woomera_locate_socket(profile, &profile->woomera_socket)) {
- globals.panic = 0;
- }
- if (!woomera_profile_thread_running(profile, 0, 0)) {
- break;
- }
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Woomera Thread Up {%s} %s/%d\n", profile->name, profile->woomera_host, profile->woomera_port);
-
- }
-
- if (globals.panic) {
- if (globals.panic != 2) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Help I'm in a state of panic!\n");
- globals.panic = 0;//fix
- }
- woomera_socket_close(&profile->woomera_socket);
-
-
- continue;
- }
-
- if ((res = woomera_dequeue_event(&profile->event_queue, &wmsg) ||
- (res = woomera_message_parse(profile->woomera_socket,
- &wmsg,
- /* if we are not stingy with threads we can block forever */
- 0,
- profile,
- NULL
- )))) {
- if (res < 0) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "{%s} HELP! I lost my connection to woomera!\n", profile->name);
- woomera_socket_close(&profile->woomera_socket);
-
- //global_set_flag(TFLAG_ABORT);
- globals.panic = 1;
- continue;
-
- if (profile->woomera_socket) {
- if (switch_test_flag(profile, PFLAG_INBOUND)) {
- woomera_printf(profile, profile->woomera_socket, "LISTEN%s", WOOMERA_RECORD_SEPERATOR);
- if (woomera_message_parse(profile->woomera_socket,
- &wmsg,
- WOOMERA_HARD_TIMEOUT,
- profile,
- &profile->event_queue
- ) < 0) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "{%s} HELP! Woomera is broken!\n", profile->name);
- globals.panic = 1;
- woomera_socket_close(&profile->woomera_socket);
- }
- }
- if (profile->woomera_socket) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Woomera Thread Up {%s} %s/%d\n", profile->name, profile->woomera_host, profile->woomera_port);
- }
- }
- continue;
- }
-
- if (!strcasecmp(wmsg.command, "INCOMING")) {
- char *name;
- switch_core_session *session;
-
- if (!(name = woomera_message_header(&wmsg, "Remote-Address"))) {
- name = woomera_message_header(&wmsg, "Channel-Name");
- }
-
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "New Inbound Channel %s!\n", name);
- if ((session = switch_core_session_request(&woomerachan_endpoint_interface, NULL))) {
- struct private_object *tech_pvt;
- switch_channel *channel;
-
- if ((tech_pvt = (struct private_object *) switch_core_session_alloc(session, sizeof(struct private_object)))) {
- memset(tech_pvt, 0, sizeof(*tech_pvt));
- tech_pvt->profile = &default_profile;
- channel = switch_core_session_get_channel(session);
- switch_core_session_set_private(session, tech_pvt);
- tech_pvt->session = session;
- } else {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Hey where is my memory pool?\n");
- switch_core_session_destroy(&session);
- break;
- }
- switch_channel_set_state(channel, CS_INIT);
- switch_core_session_thread_launch(session);
- }
- }
- }
-
- if (globals.debug > 2) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Main Thread {%s} Select Return %d\n", profile->name, res);
- }
-
- switch_yield(100);
- }
-
-
- if (profile->woomera_socket) {
- woomera_printf(profile, profile->woomera_socket, "BYE%s", WOOMERA_RECORD_SEPERATOR);
- woomera_socket_close(&profile->woomera_socket);
- }
-
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Ended Woomera Thread {%s}.\n", profile->name);
- woomera_profile_thread_running(profile, 1, -1);
- return NULL;
-}
-
-SWITCH_MOD_DECLARE(switch_status) switch_module_runtime(void)
-{
-
- woomera_thread_run(&default_profile);
-
- return SWITCH_STATUS_TERM;
-}
-
-SWITCH_MOD_DECLARE(switch_status) switch_module_shutdown(void)
-{
- int x = 0;
- woomera_profile_thread_running(&default_profile, 1, 0);
- while (!woomera_profile_thread_running(&default_profile, 0, 0)) {
- woomera_socket_close(&default_profile.woomera_socket);
- if (x++ > 10) {
- break;
- }
- switch_yield(1);
- }
- return SWITCH_STATUS_SUCCESS;
-}
-
-SWITCH_MOD_DECLARE(switch_status) switch_module_load(const switch_loadable_module_interface **interface, char *filename) {
-
- switch_config cfg;
- char *var, *val;
- struct woomera_profile *profile = &default_profile;
- char *cf = "woomera.conf";
-
- memset(&globals, 0, sizeof(globals));
- globals.next_woomera_port = WOOMERA_MIN_PORT;
-
- if (!switch_config_open_file(&cfg, cf)) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "open of %s failed\n", cf);
- return SWITCH_STATUS_TERM;
- }
-
- switch_set_flag(profile, PFLAG_INBOUND | PFLAG_OUTBOUND);
- profile->name = "main";
- strncpy(profile->dialplan, "default", sizeof(profile->dialplan) - 1);
-
- while (switch_config_next_pair(&cfg, &var, &val)) {
- if (!strcasecmp(cfg.category, "settings")) {
- if (!strcmp(var, "noload") && atoi(val)) {
- return SWITCH_STATUS_TERM;
- }
- if (!strcmp(var, "debug")) {
- globals.debug = atoi(val);
- }
- } else if (!strcasecmp(cfg.category, "profile")) {
- if (!strcmp(var, "audio_ip")) {
- strncpy(profile->audio_ip, val, sizeof(profile->audio_ip) - 1);
- } else if (!strcmp(var, "host")) {
- strncpy(profile->woomera_host, val, sizeof(profile->woomera_host) - 1);
- } else if (!strcmp(var, "port")) {
- profile->woomera_port = atoi(val);
- } else if (!strcmp(var, "disabled")) {
- if (atoi(val) > 0) {
- switch_set_flag(profile, PFLAG_DISABLED);
- }
- } else if (!strcmp(var, "inbound")) {
- if (atoi(val) < 1) {
- switch_clear_flag(profile, PFLAG_INBOUND);
- }
- } else if (!strcmp(var, "outbound")) {
- if (atoi(val) < 1) {
- switch_clear_flag(profile, PFLAG_OUTBOUND);
- }
- } else if (!strcmp(var, "dialplan")) {
- strncpy(profile->dialplan, val, sizeof(profile->dialplan) - 1);
- }
- }
- }
-
- switch_config_close_file(&cfg);
-
-
- if (switch_core_new_memory_pool(&module_pool) != SWITCH_STATUS_SUCCESS) {
- //switch_console_printf(SWITCH_CHANNEL_CONSOLE, "OH OH no pool\n");
-
- if (switch_core_new_memory_pool(&module_pool) != SWITCH_STATUS_SUCCESS) {
- //switch_console_printf(SWITCH_CHANNEL_CONSOLE, "OH OH no pool\n");
- return SWITCH_STATUS_MEMERR;
- }
- return SWITCH_STATUS_MEMERR;
- }
-
-
-
- if (switch_mutex_init(&default_profile.iolock, SWITCH_MUTEX_NESTED, module_pool) != SWITCH_STATUS_SUCCESS) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "OH OH no lock\n");
- return SWITCH_STATUS_TERM;
- }
-
-
- /* connect my internal structure to the blank pointer passed to me */
- *interface = &woomerachan_module_interface;
-
- /* indicate that the module should continue to be loaded */
- return SWITCH_STATUS_SUCCESS;
-}
-
-
-
+++ /dev/null
-<?xml version="1.0" encoding="Windows-1252"?>\r
-<VisualStudioProject\r
- ProjectType="Visual C++"\r
- Version="8.00"\r
- Name="mod_woomerachan"\r
- ProjectGUID="{FE3540C5-3303-46E0-A69E-D92F775687F1}"\r
- RootNamespace="mod_woomerachan"\r
- Keyword="Win32Proj"\r
- >\r
- <Platforms>\r
- <Platform\r
- Name="Win32"\r
- />\r
- </Platforms>\r
- <ToolFiles>\r
- </ToolFiles>\r
- <Configurations>\r
- <Configuration\r
- Name="Debug|Win32"\r
- OutputDirectory="Debug"\r
- IntermediateDirectory="Debug"\r
- ConfigurationType="2"\r
- InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
- CharacterSet="2"\r
- >\r
- <Tool\r
- Name="VCPreBuildEventTool"\r
- />\r
- <Tool\r
- Name="VCCustomBuildTool"\r
- />\r
- <Tool\r
- Name="VCXMLDataGeneratorTool"\r
- />\r
- <Tool\r
- Name="VCWebServiceProxyGeneratorTool"\r
- />\r
- <Tool\r
- Name="VCMIDLTool"\r
- />\r
- <Tool\r
- Name="VCCLCompilerTool"\r
- Optimization="0"\r
- AdditionalIncludeDirectories=""$(InputDir)..\..\include";"$(InputDir)include";"$(InputDir)..\..\..\libs\include""\r
- PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS"\r
- MinimalRebuild="true"\r
- BasicRuntimeChecks="3"\r
- RuntimeLibrary="1"\r
- UsePrecompiledHeader="0"\r
- WarningLevel="3"\r
- Detect64BitPortabilityProblems="true"\r
- DebugInformationFormat="4"\r
- />\r
- <Tool\r
- Name="VCManagedResourceCompilerTool"\r
- />\r
- <Tool\r
- Name="VCResourceCompilerTool"\r
- />\r
- <Tool\r
- Name="VCPreLinkEventTool"\r
- />\r
- <Tool\r
- Name="VCLinkerTool"\r
- OutputFile="..\..\..\w32\vsnet\$(OutDir)/mod/mod_woomerachan.dll"\r
- LinkIncremental="2"\r
- AdditionalLibraryDirectories="$(InputDir)..\..\libs\apr\Debug"\r
- GenerateDebugInformation="true"\r
- ProgramDatabaseFile="$(OutDir)/mod_woomerachan.pdb"\r
- SubSystem="2"\r
- ImportLibrary="$(OutDir)/mod_woomerachan.lib"\r
- TargetMachine="1"\r
- />\r
- <Tool\r
- Name="VCALinkTool"\r
- />\r
- <Tool\r
- Name="VCManifestTool"\r
- />\r
- <Tool\r
- Name="VCXDCMakeTool"\r
- />\r
- <Tool\r
- Name="VCBscMakeTool"\r
- />\r
- <Tool\r
- Name="VCFxCopTool"\r
- />\r
- <Tool\r
- Name="VCAppVerifierTool"\r
- />\r
- <Tool\r
- Name="VCWebDeploymentTool"\r
- />\r
- <Tool\r
- Name="VCPostBuildEventTool"\r
- />\r
- </Configuration>\r
- <Configuration\r
- Name="Release|Win32"\r
- OutputDirectory="Release"\r
- IntermediateDirectory="Release"\r
- ConfigurationType="2"\r
- InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
- CharacterSet="2"\r
- >\r
- <Tool\r
- Name="VCPreBuildEventTool"\r
- />\r
- <Tool\r
- Name="VCCustomBuildTool"\r
- />\r
- <Tool\r
- Name="VCXMLDataGeneratorTool"\r
- />\r
- <Tool\r
- Name="VCWebServiceProxyGeneratorTool"\r
- />\r
- <Tool\r
- Name="VCMIDLTool"\r
- />\r
- <Tool\r
- Name="VCCLCompilerTool"\r
- AdditionalIncludeDirectories=""$(InputDir)..\..\include";"$(InputDir)include";"$(InputDir)..\..\..\libs\include""\r
- PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS"\r
- RuntimeLibrary="0"\r
- UsePrecompiledHeader="0"\r
- WarningLevel="3"\r
- Detect64BitPortabilityProblems="true"\r
- DebugInformationFormat="3"\r
- />\r
- <Tool\r
- Name="VCManagedResourceCompilerTool"\r
- />\r
- <Tool\r
- Name="VCResourceCompilerTool"\r
- />\r
- <Tool\r
- Name="VCPreLinkEventTool"\r
- />\r
- <Tool\r
- Name="VCLinkerTool"\r
- OutputFile="..\..\..\w32\vsnet\$(OutDir)/mod/mod_woomerachan.dll"\r
- LinkIncremental="1"\r
- AdditionalLibraryDirectories=""$(InputDir)..\..\libs\apr\Release""\r
- GenerateDebugInformation="true"\r
- SubSystem="2"\r
- OptimizeReferences="2"\r
- EnableCOMDATFolding="2"\r
- ImportLibrary="$(OutDir)/mod_woomerachan.lib"\r
- TargetMachine="1"\r
- />\r
- <Tool\r
- Name="VCALinkTool"\r
- />\r
- <Tool\r
- Name="VCManifestTool"\r
- />\r
- <Tool\r
- Name="VCXDCMakeTool"\r
- />\r
- <Tool\r
- Name="VCBscMakeTool"\r
- />\r
- <Tool\r
- Name="VCFxCopTool"\r
- />\r
- <Tool\r
- Name="VCAppVerifierTool"\r
- />\r
- <Tool\r
- Name="VCWebDeploymentTool"\r
- />\r
- <Tool\r
- Name="VCPostBuildEventTool"\r
- />\r
- </Configuration>\r
- </Configurations>\r
- <References>\r
- </References>\r
- <Files>\r
- <Filter\r
- Name="Source Files"\r
- Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"\r
- UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"\r
- >\r
- <File\r
- RelativePath=".\mod_woomerachan.c"\r
- >\r
- </File>\r
- </Filter>\r
- <Filter\r
- Name="Header Files"\r
- Filter="h;hpp;hxx;hm;inl;inc;xsd"\r
- UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"\r
- >\r
- </Filter>\r
- <Filter\r
- Name="Resource Files"\r
- Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"\r
- UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"\r
- >\r
- </Filter>\r
- </Files>\r
- <Globals>\r
- </Globals>\r
-</VisualStudioProject>\r
+++ /dev/null
-LDFLAGS += -liksemel -L/usr/local/lib
-
-all: depends $(MOD).so
-
-depends:
- $(BASE)/buildlib.sh $(BASE) install iksemel-1.2.tar.gz --prefix=$(PREFIX)
-
-$(MOD).so: $(MOD).c
- $(CC) $(CFLAGS) -fPIC -c $(MOD).c -o $(MOD).o
- $(CC) $(SOLINK) -o $(MOD).so $(MOD).o $(LDFLAGS)
-
-clean:
- rm -fr *.so *.o *~
-
+++ /dev/null
-/*
- * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
- * Copyright (C) 2005/2006, Anthony Minessale II <anthmct@yahoo.com>
- *
- * Version: MPL 1.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
- *
- * The Initial Developer of the Original Code is
- * Anthony Minessale II <anthmct@yahoo.com>
- * Portions created by the Initial Developer are Copyright (C)
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Anthony Minessale II <anthmct@yahoo.com>
- *
- *
- * mod_xmpp_event.c -- XMPP Event Logger
- *
- */
-#include <switch.h>
-#include <iksemel.h>
-
-static const char modname[] = "mod_xmpp_event";
-
-static int RUNNING = 0;
-static iksfilter *my_filter;
-static int opt_timeout = 30;
-static int opt_use_tls = 0;
-
-/* stuff we keep per session */
-struct session {
- iksparser *parser;
- iksid *acc;
- char *pass;
- int features;
- int authorized;
- int counter;
- int job_done;
-};
-
-static struct {
- char *jid;
- char *passwd;
- char *target_jid;
- int debug;
- struct session session;
-} globals;
-
-static void event_handler (switch_event *event)
-{
- char buf[1024];
- iks *msg;
- int loops = 0;
-
- if (!RUNNING) {
- return;
- }
-
- while (!globals.session.authorized) {
- switch_yield(100000);
- if (loops++ > 5) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Nothing to do with this Event!\n");
- return;
- }
- }
-
- switch(event->event_id) {
- default:
- switch_event_serialize(event, buf, sizeof(buf), NULL);
- //switch_console_printf(SWITCH_CHANNEL_CONSOLE, "\nEVENT\n--------------------------------\n%s\n", buf);
- msg = iks_make_msg(IKS_TYPE_NONE, globals.target_jid, buf);
- iks_insert_attrib(msg, "subject", "Event");
- iks_send(globals.session.parser, msg);
-
- break;
- }
-}
-
-
-
-SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_jid, globals.jid)
- SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_target_jid, globals.target_jid)
- SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_passwd, globals.passwd)
-
-
- static switch_status load_config(void)
-{
- switch_config cfg;
- switch_status status = SWITCH_STATUS_FALSE;
- char *var, *val;
- char *cf = "xmpp_event.conf";
- int count = 0;
-
- memset(&globals, 0, sizeof(globals));
-
- if (!switch_config_open_file(&cfg, cf)) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "open of %s failed\n", cf);
- return SWITCH_STATUS_TERM;
- }
-
- while (switch_config_next_pair(&cfg, &var, &val)) {
- if (!strcasecmp(cfg.category, "settings")) {
- if (!strcmp(var, "jid")) {
- set_global_jid(val);
- count++;
- } else if (!strcmp(var, "target_jid")) {
- set_global_target_jid(val);
- count++;
- } else if (!strcmp(var, "passwd")) {
- set_global_passwd(val);
- count++;
- } else if (!strcmp(var, "debug")) {
- globals.debug = atoi(val);
- }
- }
- }
-
- switch_config_close_file(&cfg);
-
- if (count == 3) {
- /* TBD use config to pick what events to bind to */
- if (switch_event_bind((char *)modname, SWITCH_EVENT_ALL, SWITCH_EVENT_SUBCLASS_ANY, event_handler, NULL) != SWITCH_STATUS_SUCCESS) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Couldn't bind!\n");
- return SWITCH_STATUS_GENERR;
- }
-
- status = SWITCH_STATUS_SUCCESS;
- }
-
- return status;
-
-}
-
-int on_result (struct session *sess, ikspak *pak)
-{
-
- return IKS_FILTER_EAT;
-}
-
-int on_stream (struct session *sess, int type, iks *node)
-{
- sess->counter = opt_timeout;
-
- switch (type) {
- case IKS_NODE_START:
- if (opt_use_tls && !iks_is_secure (sess->parser)) {
- iks_start_tls (sess->parser);
- }
- break;
- case IKS_NODE_NORMAL:
- if (strcmp ("stream:features", iks_name (node)) == 0) {
- sess->features = iks_stream_features (node);
- if (opt_use_tls && !iks_is_secure (sess->parser)) break;
- if (sess->authorized) {
- iks *t;
- if (sess->features & IKS_STREAM_BIND) {
- t = iks_make_resource_bind (sess->acc);
- iks_send (sess->parser, t);
- iks_delete (t);
- }
- if (sess->features & IKS_STREAM_SESSION) {
- t = iks_make_session ();
- iks_insert_attrib (t, "id", "auth");
- iks_send (sess->parser, t);
- iks_delete (t);
- }
- } else {
- if (sess->features & IKS_STREAM_SASL_MD5)
- iks_start_sasl (sess->parser, IKS_SASL_DIGEST_MD5, sess->acc->user, sess->pass);
- else if (sess->features & IKS_STREAM_SASL_PLAIN)
- iks_start_sasl (sess->parser, IKS_SASL_PLAIN, sess->acc->user, sess->pass);
- }
- } else if (strcmp ("failure", iks_name (node)) == 0) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "sasl authentication failed\n");
- } else if (strcmp ("success", iks_name (node)) == 0) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "server connected\n");
- sess->authorized = 1;
- iks_send_header (sess->parser, sess->acc->server);
- } else {
- ikspak *pak;
-
- pak = iks_packet (node);
- iks_filter_packet (my_filter, pak);
- if (sess->job_done == 1) return IKS_HOOK;
- }
- break;
-#if 0
- case IKS_NODE_STOP:
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "server disconnected\n");
- break;
-
- case IKS_NODE_ERROR:
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "stream error\n");
- break;
-#endif
-
- }
-
- if (node) iks_delete (node);
- return IKS_OK;
-}
-
-int on_msg (void *user_data, ikspak *pak)
-{
- char *cmd = iks_find_cdata (pak->x, "body");
- char *arg = NULL;
- char retbuf[1024] = "";
- char *p;
-
- if ((p = strchr(cmd, '\r'))) {
- *p++ = '\0';
- } else if ((p = strchr(cmd, '\n'))) {
- *p++ = '\0';
- }
-
- if ((arg = strchr(cmd, ' '))) {
- *arg++ = '\0';
- }
-
- switch_api_execute(cmd, arg, retbuf, sizeof(retbuf));
-
- return 0;
-}
-
-int on_error (void *user_data, ikspak *pak)
-{
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "authorization failed\n");
- return IKS_FILTER_EAT;
-}
-
-void on_log (struct session *sess, const char *data, size_t size, int is_incoming)
-{
- if (iks_is_secure (sess->parser)) fprintf (stderr, "Sec");
- if (is_incoming) fprintf (stderr, "RECV"); else fprintf (stderr, "SEND");
- fprintf (stderr, "[%s]\n", data);
-}
-
-void j_setup_filter (struct session *sess)
-{
- if (my_filter) iks_filter_delete (my_filter);
- my_filter = iks_filter_new ();
- iks_filter_add_rule (my_filter, on_msg, 0,
- IKS_RULE_TYPE, IKS_PAK_MESSAGE,
- IKS_RULE_SUBTYPE, IKS_TYPE_CHAT,
- IKS_RULE_FROM, globals.target_jid,
- IKS_RULE_DONE);
- iks_filter_add_rule (my_filter, (iksFilterHook *) on_result, sess,
- IKS_RULE_TYPE, IKS_PAK_IQ,
- IKS_RULE_SUBTYPE, IKS_TYPE_RESULT,
- IKS_RULE_ID, "auth",
- IKS_RULE_DONE);
- iks_filter_add_rule (my_filter, on_error, sess,
- IKS_RULE_TYPE, IKS_PAK_IQ,
- IKS_RULE_SUBTYPE, IKS_TYPE_ERROR,
- IKS_RULE_ID, "auth",
- IKS_RULE_DONE);
-}
-
-static void xmpp_connect (char *jabber_id, char *pass)
-{
- while (RUNNING == 1) {
- int e;
-
- memset (&globals.session, 0, sizeof (globals.session));
- globals.session.parser = iks_stream_new (IKS_NS_CLIENT, &globals.session, (iksStreamHook *) on_stream);
- if (globals.debug) iks_set_log_hook (globals.session.parser, (iksLogHook *) on_log);
- globals.session.acc = iks_id_new (iks_parser_stack (globals.session.parser), jabber_id);
- if (NULL == globals.session.acc->resource) {
- /* user gave no resource name, use the default */
- char tmp[512];
- sprintf (tmp, "%s@%s/%s", globals.session.acc->user, globals.session.acc->server, modname);
- globals.session.acc = iks_id_new (iks_parser_stack (globals.session.parser), tmp);
- }
- globals.session.pass = pass;
-
- j_setup_filter (&globals.session);
-
- e = iks_connect_tcp (globals.session.parser, globals.session.acc->server, IKS_JABBER_PORT);
- switch (e) {
- case IKS_OK:
- break;
- case IKS_NET_NODNS:
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "hostname lookup failed\n");
- case IKS_NET_NOCONN:
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "connection failed\n");
- default:
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "io error\n");
- switch_sleep(5000000);
- continue;
- }
-
- globals.session.counter = opt_timeout;
- while (RUNNING == 1) {
- e = iks_recv (globals.session.parser, 1);
-
- if(globals.session.job_done) {
- break;
- }
-
- if (IKS_HOOK == e) {
- break;
- }
-
- if (IKS_OK != e) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "io error %d\n", e);
- switch_sleep(5000000);
- break;
- }
-
- if (!globals.session.authorized) {
- if (IKS_NET_TLSFAIL == e) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "tls handshake failed\n");
- switch_sleep(5000000);
- break;
- }
-
- if (globals.session.counter == 0) {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "network timeout\n");
- switch_sleep(5000000);
- break;
- }
- }
- }
-
- iks_disconnect(globals.session.parser);
- iks_parser_delete (globals.session.parser);
- globals.session.authorized = 0;
- }
- RUNNING = 0;
-
-}
-
-static switch_loadable_module_interface xmpp_event_module_interface = {
- /*.module_name*/ modname,
- /*.endpoint_interface*/ NULL,
- /*.timer_interface*/ NULL,
- /*.dialplan_interface*/ NULL,
- /*.codec_interface*/ NULL,
- /*.application_interface*/ NULL
-};
-
-SWITCH_MOD_DECLARE(switch_status) switch_module_load(switch_loadable_module_interface **interface, char *filename) {
- /* connect my internal structure to the blank pointer passed to me */
- *interface = &xmpp_event_module_interface;
-
- if (load_config() != SWITCH_STATUS_SUCCESS) {
- return SWITCH_STATUS_FALSE;
- }
-
- /* indicate that the module should continue to be loaded */
- return SWITCH_STATUS_SUCCESS;
-}
-
-
-SWITCH_MOD_DECLARE(switch_status) switch_module_shutdown(void)
-{
-
- if (RUNNING) {
- RUNNING = -1;
- while (RUNNING) {
- switch_yield(1000);
- }
- }
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-SWITCH_MOD_DECLARE(switch_status) switch_module_runtime(void)
-{
- RUNNING = 1;
- xmpp_connect(globals.jid, globals.passwd);
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "disconnecting client %d\n", RUNNING);
- return RUNNING ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_TERM;
-}
+++ /dev/null
-<?xml version="1.0" encoding="Windows-1252"?>\r
-<VisualStudioProject\r
- ProjectType="Visual C++"\r
- Version="8.00"\r
- Name="mod_xmpp_event"\r
- ProjectGUID="{F10BE67C-A8FF-4CB2-AF29-D46D2590DC59}"\r
- RootNamespace="mod_xmpp_event"\r
- Keyword="Win32Proj"\r
- >\r
- <Platforms>\r
- <Platform\r
- Name="Win32"\r
- />\r
- </Platforms>\r
- <ToolFiles>\r
- </ToolFiles>\r
- <Configurations>\r
- <Configuration\r
- Name="Debug|Win32"\r
- OutputDirectory="Debug"\r
- IntermediateDirectory="Debug"\r
- ConfigurationType="2"\r
- InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
- CharacterSet="2"\r
- >\r
- <Tool\r
- Name="VCPreBuildEventTool"\r
- CommandLine="cscript /nologo $(InputDir)..\..\..\w32\vsnet\getlibs.vbs Mod_XMPPEvent Debug"\r
- />\r
- <Tool\r
- Name="VCCustomBuildTool"\r
- />\r
- <Tool\r
- Name="VCXMLDataGeneratorTool"\r
- />\r
- <Tool\r
- Name="VCWebServiceProxyGeneratorTool"\r
- />\r
- <Tool\r
- Name="VCMIDLTool"\r
- />\r
- <Tool\r
- Name="VCCLCompilerTool"\r
- Optimization="0"\r
- AdditionalIncludeDirectories=""$(InputDir)..\..\include";"$(InputDir)..\..\..\libs\include";"$(InputDir)..\..\..\libs\iksemel\include""\r
- PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS"\r
- MinimalRebuild="true"\r
- BasicRuntimeChecks="3"\r
- RuntimeLibrary="3"\r
- UsePrecompiledHeader="0"\r
- WarningLevel="3"\r
- Detect64BitPortabilityProblems="true"\r
- DebugInformationFormat="4"\r
- />\r
- <Tool\r
- Name="VCManagedResourceCompilerTool"\r
- />\r
- <Tool\r
- Name="VCResourceCompilerTool"\r
- />\r
- <Tool\r
- Name="VCPreLinkEventTool"\r
- />\r
- <Tool\r
- Name="VCLinkerTool"\r
- AdditionalDependencies="FreeSwitchCore.lib iksemel.lib Ws2_32.lib"\r
- OutputFile="..\..\..\w32\vsnet\$(OutDir)/mod/mod_xmpp_event.dll"\r
- LinkIncremental="2"\r
- AdditionalLibraryDirectories="..\..\..\w32\vsnet\Debug;..\..\..\libs\iksemel\Debug"\r
- GenerateDebugInformation="true"\r
- ProgramDatabaseFile="$(OutDir)/mod_xmpp_event.pdb"\r
- SubSystem="2"\r
- ImportLibrary="$(OutDir)/mod_xmpp_event.lib"\r
- TargetMachine="1"\r
- />\r
- <Tool\r
- Name="VCALinkTool"\r
- />\r
- <Tool\r
- Name="VCManifestTool"\r
- />\r
- <Tool\r
- Name="VCXDCMakeTool"\r
- />\r
- <Tool\r
- Name="VCBscMakeTool"\r
- />\r
- <Tool\r
- Name="VCFxCopTool"\r
- />\r
- <Tool\r
- Name="VCAppVerifierTool"\r
- />\r
- <Tool\r
- Name="VCWebDeploymentTool"\r
- />\r
- <Tool\r
- Name="VCPostBuildEventTool"\r
- />\r
- </Configuration>\r
- <Configuration\r
- Name="Release|Win32"\r
- OutputDirectory="Release"\r
- IntermediateDirectory="Release"\r
- ConfigurationType="2"\r
- InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
- CharacterSet="2"\r
- >\r
- <Tool\r
- Name="VCPreBuildEventTool"\r
- CommandLine="cscript /nologo $(InputDir)..\..\..\w32\vsnet\getlibs.vbs Mod_XMPPEvent Release"\r
- />\r
- <Tool\r
- Name="VCCustomBuildTool"\r
- />\r
- <Tool\r
- Name="VCXMLDataGeneratorTool"\r
- />\r
- <Tool\r
- Name="VCWebServiceProxyGeneratorTool"\r
- />\r
- <Tool\r
- Name="VCMIDLTool"\r
- />\r
- <Tool\r
- Name="VCCLCompilerTool"\r
- AdditionalIncludeDirectories=""$(InputDir)..\..\include";"$(InputDir)..\..\..\libs\include";"$(InputDir)..\..\..\libs\iksemel\include""\r
- PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS"\r
- RuntimeLibrary="2"\r
- UsePrecompiledHeader="0"\r
- WarningLevel="3"\r
- Detect64BitPortabilityProblems="true"\r
- DebugInformationFormat="3"\r
- />\r
- <Tool\r
- Name="VCManagedResourceCompilerTool"\r
- />\r
- <Tool\r
- Name="VCResourceCompilerTool"\r
- />\r
- <Tool\r
- Name="VCPreLinkEventTool"\r
- />\r
- <Tool\r
- Name="VCLinkerTool"\r
- AdditionalDependencies="FreeSwitchCore.lib iksemel.lib Ws2_32.lib"\r
- OutputFile="..\..\..\w32\vsnet\$(OutDir)/mod/mod_xmpp_event.dll"\r
- LinkIncremental="1"\r
- AdditionalLibraryDirectories="..\..\..\w32\vsnet\Release;..\..\..\libs\iksemel\Release"\r
- GenerateDebugInformation="true"\r
- SubSystem="2"\r
- OptimizeReferences="2"\r
- EnableCOMDATFolding="2"\r
- LinkTimeCodeGeneration="1"\r
- ImportLibrary="$(OutDir)/mod_xmpp_event.lib"\r
- TargetMachine="1"\r
- />\r
- <Tool\r
- Name="VCALinkTool"\r
- />\r
- <Tool\r
- Name="VCManifestTool"\r
- />\r
- <Tool\r
- Name="VCXDCMakeTool"\r
- />\r
- <Tool\r
- Name="VCBscMakeTool"\r
- />\r
- <Tool\r
- Name="VCFxCopTool"\r
- />\r
- <Tool\r
- Name="VCAppVerifierTool"\r
- />\r
- <Tool\r
- Name="VCWebDeploymentTool"\r
- />\r
- <Tool\r
- Name="VCPostBuildEventTool"\r
- />\r
- </Configuration>\r
- </Configurations>\r
- <References>\r
- </References>\r
- <Files>\r
- <Filter\r
- Name="Source Files"\r
- Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"\r
- UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"\r
- >\r
- <File\r
- RelativePath="mod_xmpp_event.c"\r
- >\r
- </File>\r
- </Filter>\r
- <Filter\r
- Name="Header Files"\r
- Filter="h;hpp;hxx;hm;inl;inc;xsd"\r
- UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"\r
- >\r
- </Filter>\r
- <Filter\r
- Name="Resource Files"\r
- Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"\r
- UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"\r
- >\r
- </Filter>\r
- </Files>\r
- <Globals>\r
- </Globals>\r
-</VisualStudioProject>\r