diff --git a/src/mod/mod_bridgecall/mod_bridgecall.c b/src/mod/mod_bridgecall/mod_bridgecall.c deleted file mode 100644 index facdca0734..0000000000 --- a/src/mod/mod_bridgecall/mod_bridgecall.c +++ /dev/null @@ -1,271 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005/2006, Anthony Minessale II - * - * 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 - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Anthony Minessale II - * - * - * mod_bridgecall.c -- Channel Bridge Application Module - * - */ -#include -#include -#include -#include - - -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; -} diff --git a/src/mod/mod_bridgecall/mod_bridgecall.vcproj b/src/mod/mod_bridgecall/mod_bridgecall.vcproj deleted file mode 100644 index 86366d09e7..0000000000 --- a/src/mod/mod_bridgecall/mod_bridgecall.vcproj +++ /dev/null @@ -1,207 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/mod/mod_codec_g729/Makefile b/src/mod/mod_codec_g729/Makefile deleted file mode 100644 index 6657b4c1fa..0000000000 --- a/src/mod/mod_codec_g729/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -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 *~ - diff --git a/src/mod/mod_codec_g729/mod_codec_g729.c b/src/mod/mod_codec_g729/mod_codec_g729.c deleted file mode 100644 index e85d461ea1..0000000000 --- a/src/mod/mod_codec_g729/mod_codec_g729.c +++ /dev/null @@ -1,203 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005/2006, Anthony Minessale II - * - * 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 - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Anthony Minessale II - * Michael Jerris - * - * mod_codec_g729.c -- G729 Codec Module - * - */ -#include "switch.h" -#include "g729.h" - -static const char modname[] = "mod_codec_g729"; - -struct g729_context { - struct dec_state decoder_object; - struct cod_state encoder_object; -}; - -static switch_status switch_g729_init(switch_codec *codec, switch_codec_flag flags, const struct switch_codec_settings *codec_settings) -{ - struct g729_context *context = NULL; - int encoding, decoding; - - encoding = (flags & SWITCH_CODEC_FLAG_ENCODE); - decoding = (flags & SWITCH_CODEC_FLAG_DECODE); - - if (!(encoding || decoding) || (!(context = switch_core_alloc(codec->memory_pool, sizeof(struct g729_context))))) { - return SWITCH_STATUS_FALSE; - } else { - if (encoding) { - g729_init_coder(&context->encoder_object, 0); - } - if (decoding) { - g729_init_decoder(&context->decoder_object); - } - - codec->private = context; - - return SWITCH_STATUS_SUCCESS; - } -} - -static switch_status switch_g729_destroy(switch_codec *codec) -{ - codec->private = NULL; - return SWITCH_STATUS_SUCCESS; -} - - -static switch_status switch_g729_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 g729_context *context = codec->private; - int cbret = 0; - - if (!context) { - return SWITCH_STATUS_FALSE; - } - if (decoded_data_len % 160 == 0) { - unsigned int new_len = 0; - INT16 *ddp = decoded_data; - char *edp = encoded_data; - int x; - int loops = (int) decoded_data_len / 160; - - for(x = 0; x < loops && new_len < *encoded_data_len; x++) { - g729_coder(&context->encoder_object, ddp, edp, &cbret); - edp += 10; - ddp += 80; - new_len += 10; - } - if( new_len <= *encoded_data_len ) { - *encoded_data_len = new_len; - } else { - switch_console_printf(SWITCH_CHANNEL_CONSOLE, "buffer overflow!!! %u >= %u\n", new_len, *encoded_data_len); - return SWITCH_STATUS_FALSE; - } - } - return SWITCH_STATUS_SUCCESS; -} - - -static switch_status switch_g729_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 g729_context *context = codec->private; - - if (!context) { - return SWITCH_STATUS_FALSE; - } - - - if (encoded_data_len % 10 == 0) { - int loops = (int) encoded_data_len / 10; - char *edp = encoded_data; - short *ddp = decoded_data; - int x; - unsigned int new_len = 0; - for(x = 0; x < loops && new_len < *decoded_data_len; x++) { - g729_decoder(&context->decoder_object, ddp, edp, 10); - ddp += 80; - edp += 10; - new_len += 160; - } - if (new_len <= *decoded_data_len) { - *decoded_data_len = new_len; - } else { - switch_console_printf(SWITCH_CHANNEL_CONSOLE, "buffer overflow!!!\n"); - return SWITCH_STATUS_FALSE; - } - } else { - switch_console_printf(SWITCH_CHANNEL_CONSOLE, "yo this frame is an odd size [%d]\n", encoded_data_len); - } - - - return SWITCH_STATUS_SUCCESS; -} - -/* Registration */ - -static const switch_codec_implementation g729_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*/ 20, - /*.number_of_channels*/ 1, - /*.pref_frames_per_packet*/ 1, - /*.max_frames_per_packet*/ 24, - /*.init*/ switch_g729_init, - /*.encode*/ switch_g729_encode, - /*.decode*/ switch_g729_decode, - /*.destroy*/ switch_g729_destroy, -}; - -static const switch_codec_interface g729_codec_interface = { - /*.interface_name*/ "g729", - /*.codec_type*/ SWITCH_CODEC_TYPE_AUDIO, - /*.ianacode*/ 18, - /*.iananame*/ "G729", - /*.implementations*/ &g729_8k_implementation, -}; - -static switch_loadable_module_interface g729_module_interface = { - /*.module_name*/ modname, - /*.endpoint_interface*/ NULL, - /*.timer_interface*/ NULL, - /*.dialplan_interface*/ NULL, - /*.codec_interface*/ &g729_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 = &g729_module_interface; - - /* indicate that the module should continue to be loaded */ - return SWITCH_STATUS_SUCCESS; -} - - - - - diff --git a/src/mod/mod_codec_g729/mod_codec_g729.vcproj b/src/mod/mod_codec_g729/mod_codec_g729.vcproj deleted file mode 100644 index 9b7ecdaa62..0000000000 --- a/src/mod/mod_codec_g729/mod_codec_g729.vcproj +++ /dev/null @@ -1,211 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/mod/mod_dialplan_demo/mod_dialplan_demo.c b/src/mod/mod_dialplan_demo/mod_dialplan_demo.c deleted file mode 100644 index c071f613bb..0000000000 --- a/src/mod/mod_dialplan_demo/mod_dialplan_demo.c +++ /dev/null @@ -1,124 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005/2006, Anthony Minessale II - * - * 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 - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Anthony Minessale II - * - * - * mod_dialplan_demo.c -- Example Dialplan Module - * - */ -#include -#include -#include -#include - - -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; -} diff --git a/src/mod/mod_dialplan_demo/mod_dialplan_demo.vcproj b/src/mod/mod_dialplan_demo/mod_dialplan_demo.vcproj deleted file mode 100644 index ecf5b98985..0000000000 --- a/src/mod/mod_dialplan_demo/mod_dialplan_demo.vcproj +++ /dev/null @@ -1,207 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/mod/mod_event_test/mod_event_test.c b/src/mod/mod_event_test/mod_event_test.c deleted file mode 100644 index 58c406c719..0000000000 --- a/src/mod/mod_event_test/mod_event_test.c +++ /dev/null @@ -1,133 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005/2006, Anthony Minessale II - * - * 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 - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Anthony Minessale II - * - * - * mod_event_test.c -- Framework Demo Module - * - */ -#include - -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; -} - diff --git a/src/mod/mod_event_test/mod_event_test.vcproj b/src/mod/mod_event_test/mod_event_test.vcproj deleted file mode 100644 index 6952239ce6..0000000000 --- a/src/mod/mod_event_test/mod_event_test.vcproj +++ /dev/null @@ -1,207 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/mod/mod_exosip/Makefile b/src/mod/mod_exosip/Makefile deleted file mode 100644 index 5e8906382f..0000000000 --- a/src/mod/mod_exosip/Makefile +++ /dev/null @@ -1,26 +0,0 @@ -#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 *~ - diff --git a/src/mod/mod_exosip/mod_exosip.c b/src/mod/mod_exosip/mod_exosip.c deleted file mode 100644 index 972797c379..0000000000 --- a/src/mod/mod_exosip/mod_exosip.c +++ /dev/null @@ -1,1409 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005/2006, Anthony Minessale II - * - * 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 - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Anthony Minessale II - * - * - * mod_exosip.c -- eXoSIP SIP Endpoint - * - */ - -#define HAVE_APR -#include -#include -#include -#include -#include -#include - - -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), "", 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; -} - diff --git a/src/mod/mod_exosip/mod_exosip.vcproj b/src/mod/mod_exosip/mod_exosip.vcproj deleted file mode 100644 index 014a0e56fb..0000000000 --- a/src/mod/mod_exosip/mod_exosip.vcproj +++ /dev/null @@ -1,229 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/mod/mod_exosip/mod_exosip_ccrtp.c b/src/mod/mod_exosip/mod_exosip_ccrtp.c deleted file mode 100644 index 4d895ca0fc..0000000000 --- a/src/mod/mod_exosip/mod_exosip_ccrtp.c +++ /dev/null @@ -1,1373 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005/2006, Anthony Minessale II - * - * 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 - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Anthony Minessale II - * - * - * mod_exosip.c -- eXoSIP SIP Endpoint - * - */ - - -#define HAVE_APR -#include -#include -#include -#include -#include -#include - - -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), "", 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; -} - diff --git a/src/mod/mod_exosip/mod_exosip_ucl.c b/src/mod/mod_exosip/mod_exosip_ucl.c deleted file mode 100644 index 54c3b0364c..0000000000 --- a/src/mod/mod_exosip/mod_exosip_ucl.c +++ /dev/null @@ -1,1438 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005/2006, Anthony Minessale II - * - * 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 - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Anthony Minessale II - * - * - * mod_exosip.c -- eXoSIP SIP Endpoint - * - */ - - -#define HAVE_APR - -#include -#include - -#include - -#include -#include -#include - -#include -#include -#include -#include - - - -//#include -//#include -//#include -//#include -//#include - -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), "", 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; -} - diff --git a/src/mod/mod_g711codec/Makefile b/src/mod/mod_g711codec/Makefile deleted file mode 100644 index 60ab1c465c..0000000000 --- a/src/mod/mod_g711codec/Makefile +++ /dev/null @@ -1,15 +0,0 @@ - -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 *~ - diff --git a/src/mod/mod_g711codec/g711.c b/src/mod/mod_g711codec/g711.c deleted file mode 100644 index b69eb4f912..0000000000 --- a/src/mod/mod_g711codec/g711.c +++ /dev/null @@ -1,312 +0,0 @@ -/* - * 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 ----------------------------------------------------- */ diff --git a/src/mod/mod_g711codec/g711.h b/src/mod/mod_g711codec/g711.h deleted file mode 100644 index 015c23267c..0000000000 --- a/src/mod/mod_g711codec/g711.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * 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_ */ diff --git a/src/mod/mod_g711codec/mod_g711codec.c b/src/mod/mod_g711codec/mod_g711codec.c deleted file mode 100644 index e1cd6fce69..0000000000 --- a/src/mod/mod_g711codec/mod_g711codec.c +++ /dev/null @@ -1,303 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005/2006, Anthony Minessale II - * - * 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 - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Anthony Minessale II - * - * - * mod_g711codec.c -- G711 Ulaw/Alaw Codec Module - * - */ -#include -#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; -} - - - - - diff --git a/src/mod/mod_g711codec/mod_g711codec.vcproj b/src/mod/mod_g711codec/mod_g711codec.vcproj deleted file mode 100644 index 2d79448078..0000000000 --- a/src/mod/mod_g711codec/mod_g711codec.vcproj +++ /dev/null @@ -1,215 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/mod/mod_iaxchan/Makefile b/src/mod/mod_iaxchan/Makefile deleted file mode 100644 index 6e4f38205a..0000000000 --- a/src/mod/mod_iaxchan/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -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 *~ - diff --git a/src/mod/mod_iaxchan/mod_IaxChan.vcproj b/src/mod/mod_iaxchan/mod_IaxChan.vcproj deleted file mode 100644 index 3b0a8f4d62..0000000000 --- a/src/mod/mod_iaxchan/mod_IaxChan.vcproj +++ /dev/null @@ -1,212 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/mod/mod_iaxchan/mod_iaxchan.c b/src/mod/mod_iaxchan/mod_iaxchan.c deleted file mode 100644 index b3faf65c5e..0000000000 --- a/src/mod/mod_iaxchan/mod_iaxchan.c +++ /dev/null @@ -1,986 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005/2006, Anthony Minessale II - * - * 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 - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Anthony Minessale II - * - * - * mod_iaxchan.c -- IAX2 Endpoint Module - * - */ -#include - -#ifdef WIN32 -#include -#include -#include -#include -#else -#include -#include -#include -#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; -} - diff --git a/src/mod/mod_opalchan/Makefile b/src/mod/mod_opalchan/Makefile deleted file mode 100644 index 709a5b7bc5..0000000000 --- a/src/mod/mod_opalchan/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -#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 *~ - diff --git a/src/mod/mod_opalchan/mod_opalchan.c b/src/mod/mod_opalchan/mod_opalchan.c deleted file mode 100644 index 8aae7ecb7d..0000000000 --- a/src/mod/mod_opalchan/mod_opalchan.c +++ /dev/null @@ -1,385 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005/2006, Anthony Minessale II - * - * 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 - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Anthony Minessale II - * - * - * mod_opalchan.c -- OPAL2 Endpoint Module - * - */ -#include - - -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; -} diff --git a/src/mod/mod_playback/mod_playback.c b/src/mod/mod_playback/mod_playback.c deleted file mode 100644 index 757f7e7906..0000000000 --- a/src/mod/mod_playback/mod_playback.c +++ /dev/null @@ -1,199 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005/2006, Anthony Minessale II - * - * 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 - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Anthony Minessale II - * - * - * mod_playback.c -- Raw Audio File Streaming Application Module - * - */ -#include -#include -#include -#include - - -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) - - - - diff --git a/src/mod/mod_playback/mod_playback.vcproj b/src/mod/mod_playback/mod_playback.vcproj deleted file mode 100644 index a63395a01c..0000000000 --- a/src/mod/mod_playback/mod_playback.vcproj +++ /dev/null @@ -1,207 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/mod/mod_portaudio/Makefile b/src/mod/mod_portaudio/Makefile deleted file mode 100644 index 0d78e0b06a..0000000000 --- a/src/mod/mod_portaudio/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -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 *~ - diff --git a/src/mod/mod_portaudio/mod_PortAudio.vcproj b/src/mod/mod_portaudio/mod_PortAudio.vcproj deleted file mode 100644 index 5afdc338d3..0000000000 --- a/src/mod/mod_portaudio/mod_PortAudio.vcproj +++ /dev/null @@ -1,228 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/mod/mod_portaudio/mod_portaudio.c b/src/mod/mod_portaudio/mod_portaudio.c deleted file mode 100644 index 51e7ec29bd..0000000000 --- a/src/mod/mod_portaudio/mod_portaudio.c +++ /dev/null @@ -1,934 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005/2006, Anthony Minessale II - * - * 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 - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Anthony Minessale II - * - * - * mod_portaudio.c -- PortAudio Endpoint Module - * - */ -#include - -#include -#include -#include -#include "pablio.h" -#include - -#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; iname, 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; iname ); - 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; jnumSampleRates; 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 ", 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; -} diff --git a/src/mod/mod_portaudio/pablio.c b/src/mod/mod_portaudio/pablio.c deleted file mode 100644 index b5735daea0..0000000000 --- a/src/mod/mod_portaudio/pablio.c +++ /dev/null @@ -1,327 +0,0 @@ -/* - * $Id: pablio.c,v 1.1.1.1.4.4 2003/03/13 17:28:33 philburk Exp $ - * pablio.c - * Portable Audio Blocking Input/Output utility. - * - * Author: Phil Burk, http://www.softsynth.com - * - * This program uses the PortAudio Portable Audio Library. - * For more information see: http://www.audiomulch.com/portaudio/ - * Copyright (c) 1999-2000 Ross Bencina and Phil Burk - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -/* History: - * PLB021214 - check for valid stream in CloseAudioStream() to prevent hang. - * add timeOutMSec to CloseAudioStream() to prevent hang. - */ -#include -#include -#include -#include "portaudio.h" -#include "ringbuffer.h" -#include "pablio.h" -#include - -/************************************************************************/ -/******** Constants *****************************************************/ -/************************************************************************/ - -#define FRAMES_PER_BUFFER (256) - -/************************************************************************/ -/******** Prototypes ****************************************************/ -/************************************************************************/ - -static int blockingIOCallback( void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, - PaTimestamp outTime, void *userData ); -static PaError PABLIO_InitFIFO( RingBuffer *rbuf, long numFrames, long bytesPerFrame ); -static PaError PABLIO_TermFIFO( RingBuffer *rbuf ); - -/************************************************************************/ -/******** Functions *****************************************************/ -/************************************************************************/ - -/* Called from PortAudio. - * Read and write data only if there is room in FIFOs. - */ -static int blockingIOCallback( void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, - PaTimestamp outTime, void *userData ) -{ - PABLIO_Stream *data = (PABLIO_Stream*)userData; - long numBytes = data->bytesPerFrame * framesPerBuffer; - (void) outTime; - - /* This may get called with NULL inputBuffer during initial setup. */ - if( inputBuffer != NULL ) - { - RingBuffer_Write( &data->inFIFO, inputBuffer, numBytes ); - } - if( outputBuffer != NULL ) - { - int i; - int numRead = RingBuffer_Read( &data->outFIFO, outputBuffer, numBytes ); - /* Zero out remainder of buffer if we run out of data. */ - for( i=numRead; ibuffer ) free( rbuf->buffer ); - rbuf->buffer = NULL; - return paNoError; -} - -/************************************************************ - * Write data to ring buffer. - * Will not return until all the data has been written. - */ -long WriteAudioStream( PABLIO_Stream *aStream, void *data, long numFrames ) -{ - long bytesWritten; - char *p = (char *) data; - long numBytes = aStream->bytesPerFrame * numFrames; - while( numBytes > 0) - { - bytesWritten = RingBuffer_Write( &aStream->outFIFO, p, numBytes ); - numBytes -= bytesWritten; - p += bytesWritten; - if( numBytes > 0) Pa_Sleep(10); - } - return numFrames; -} - -/************************************************************ - * Read data from ring buffer. - * Will not return until all the data has been read. - */ -long ReadAudioStream( PABLIO_Stream *aStream, void *data, long numFrames ) -{ - long bytesRead; - char *p = (char *) data; - long numBytes = aStream->bytesPerFrame * numFrames; - while( numBytes > 0) - { - bytesRead = RingBuffer_Read( &aStream->inFIFO, p, numBytes ); - numBytes -= bytesRead; - p += bytesRead; - if( numBytes > 0) Pa_Sleep(10); - } - return numFrames; -} - -/************************************************************ - * Return the number of frames that could be written to the stream without - * having to wait. - */ -long GetAudioStreamWriteable( PABLIO_Stream *aStream ) -{ - int bytesEmpty = RingBuffer_GetWriteAvailable( &aStream->outFIFO ); - return bytesEmpty / aStream->bytesPerFrame; -} - -/************************************************************ - * Return the number of frames that are available to be read from the - * stream without having to wait. - */ -long GetAudioStreamReadable( PABLIO_Stream *aStream ) -{ - int bytesFull = RingBuffer_GetReadAvailable( &aStream->inFIFO ); - return bytesFull / aStream->bytesPerFrame; -} - -/************************************************************/ -static unsigned long RoundUpToNextPowerOf2( unsigned long n ) -{ - long numBits = 0; - if( ((n-1) & n) == 0) return n; /* Already Power of two. */ - while( n > 0 ) - { - n= n>>1; - numBits++; - } - return (1<samplesPerFrame = ((flags&PABLIO_MONO) != 0) ? 1 : 2; - aStream->bytesPerFrame = bytesPerSample * aStream->samplesPerFrame; - - /* Initialize PortAudio */ - err = Pa_Initialize(); - if( err != paNoError ) goto error; - - /* Warning: numFrames must be larger than amount of data processed per interrupt - * inside PA to prevent glitches. Just to be safe, adjust size upwards. - */ - minNumBuffers = 2 * Pa_GetMinNumBuffers( FRAMES_PER_BUFFER, sampleRate ); - numFrames = minNumBuffers * FRAMES_PER_BUFFER; - /* The PortAudio callback runs in a high priority thread. But PABLIO - * runs in a normal foreground thread. So we may have much worse - * latency in PABLIO. So adjust latency to a safe level. - */ - { - const int safeLatencyMSec = 200; - int minLatencyMSec = (int) ((1000 * numFrames) / sampleRate); - if( minLatencyMSec < safeLatencyMSec ) - { - numFrames = (int) ((safeLatencyMSec * sampleRate) / 1000); - } - } - numFrames = RoundUpToNextPowerOf2( numFrames ); - - /* Initialize Ring Buffers */ - doRead = ((flags & PABLIO_READ) != 0); - doWrite = ((flags & PABLIO_WRITE) != 0); - if(doRead) - { - err = PABLIO_InitFIFO( &aStream->inFIFO, numFrames, aStream->bytesPerFrame ); - if( err != paNoError ) goto error; - } - if(doWrite) - { - long numBytes; - err = PABLIO_InitFIFO( &aStream->outFIFO, numFrames, aStream->bytesPerFrame ); - if( err != paNoError ) goto error; - /* Make Write FIFO appear full initially. */ - numBytes = RingBuffer_GetWriteAvailable( &aStream->outFIFO ); - RingBuffer_AdvanceWriteIndex( &aStream->outFIFO, numBytes ); - } - - /* Open a PortAudio stream that we will use to communicate with the underlying - * audio drivers. */ - err = Pa_OpenStream( - &aStream->stream, - (doRead ? (indev > -1) ? indev : Pa_GetDefaultInputDeviceID() : paNoDevice), - (doRead ? aStream->samplesPerFrame : 0 ), - format, - NULL, - (doWrite ? (outdev > -1) ? outdev : Pa_GetDefaultOutputDeviceID() : paNoDevice), - (doWrite ? aStream->samplesPerFrame : 0 ), - format, - NULL, - sampleRate, - FRAMES_PER_BUFFER, - minNumBuffers, - paClipOff, /* we won't output out of range samples so don't bother clipping them */ - blockingIOCallback, - aStream ); - if( err != paNoError ) goto error; - - err = Pa_StartStream( aStream->stream ); - if( err != paNoError ) goto error; - - *rwblPtr = aStream; - return paNoError; - -error: - CloseAudioStream( aStream ); - *rwblPtr = NULL; - return err; -} - -/************************************************************/ -PaError CloseAudioStream( PABLIO_Stream *aStream ) -{ - PaError err = paNoError; - int bytesEmpty; - int byteSize = aStream->outFIFO.bufferSize; - - if( aStream->stream != NULL ) /* Make sure stream was opened. PLB021214 */ - { - /* If we are writing data, make sure we play everything written. */ - if( byteSize > 0 ) - { - int timeOutMSec = 2000; - bytesEmpty = RingBuffer_GetWriteAvailable( &aStream->outFIFO ); - while( (bytesEmpty < byteSize) && (timeOutMSec > 0) ) - { - Pa_Sleep( 20 ); - timeOutMSec -= 20; - bytesEmpty = RingBuffer_GetWriteAvailable( &aStream->outFIFO ); - } - } - err = Pa_StopStream( aStream->stream ); - if( err != paNoError ) goto error; - err = Pa_CloseStream( aStream->stream ); - } - -error: - Pa_Terminate(); - PABLIO_TermFIFO( &aStream->inFIFO ); - PABLIO_TermFIFO( &aStream->outFIFO ); - free( aStream ); - return err; -} diff --git a/src/mod/mod_portaudio/pablio.h b/src/mod/mod_portaudio/pablio.h deleted file mode 100644 index 25bccf8998..0000000000 --- a/src/mod/mod_portaudio/pablio.h +++ /dev/null @@ -1,109 +0,0 @@ -#ifndef _PABLIO_H -#define _PABLIO_H - -#ifdef __cplusplus -extern "C" -{ -#endif /* __cplusplus */ - -/* - * $Id: pablio.h,v 1.1.1.1 2002/01/22 00:52:53 phil Exp $ - * PABLIO.h - * Portable Audio Blocking read/write utility. - * - * Author: Phil Burk, http://www.softsynth.com/portaudio/ - * - * Include file for PABLIO, the Portable Audio Blocking I/O Library. - * PABLIO is built on top of PortAudio, the Portable Audio Library. - * For more information see: http://www.audiomulch.com/portaudio/ - * Copyright (c) 1999-2000 Ross Bencina and Phil Burk - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ -#include -#include -#include -#include "portaudio.h" -#include "ringbuffer.h" -#include - -typedef struct -{ - RingBuffer inFIFO; - RingBuffer outFIFO; - PortAudioStream *stream; - int bytesPerFrame; - int samplesPerFrame; -} -PABLIO_Stream; - -/* Values for flags for OpenAudioStream(). */ -#define PABLIO_READ (1<<0) -#define PABLIO_WRITE (1<<1) -#define PABLIO_READ_WRITE (PABLIO_READ|PABLIO_WRITE) -#define PABLIO_MONO (1<<2) -#define PABLIO_STEREO (1<<3) - -/************************************************************ - * Write data to ring buffer. - * Will not return until all the data has been written. - */ -long WriteAudioStream( PABLIO_Stream *aStream, void *data, long numFrames ); - -/************************************************************ - * Read data from ring buffer. - * Will not return until all the data has been read. - */ -long ReadAudioStream( PABLIO_Stream *aStream, void *data, long numFrames ); - -/************************************************************ - * Return the number of frames that could be written to the stream without - * having to wait. - */ -long GetAudioStreamWriteable( PABLIO_Stream *aStream ); - -/************************************************************ - * Return the number of frames that are available to be read from the - * stream without having to wait. - */ -long GetAudioStreamReadable( PABLIO_Stream *aStream ); - -/************************************************************ - * Opens a PortAudio stream with default characteristics. - * Allocates PABLIO_Stream structure. - * - * flags parameter can be an ORed combination of: - * PABLIO_READ, PABLIO_WRITE, or PABLIO_READ_WRITE, - * and either PABLIO_MONO or PABLIO_STEREO - */ -PaError OpenAudioStream( PABLIO_Stream **aStreamPtr, double sampleRate, - PaSampleFormat format, long flags, int indev, int outdev ); - -PaError CloseAudioStream( PABLIO_Stream *aStream ); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ -#endif /* _PABLIO_H */ diff --git a/src/mod/mod_portaudio/ringbuffer.c b/src/mod/mod_portaudio/ringbuffer.c deleted file mode 100644 index 867b501965..0000000000 --- a/src/mod/mod_portaudio/ringbuffer.c +++ /dev/null @@ -1,199 +0,0 @@ -/* - * $Id: ringbuffer.c,v 1.1.1.1 2002/01/22 00:52:53 phil Exp $ - * ringbuffer.c - * Ring Buffer utility.. - * - * Author: Phil Burk, http://www.softsynth.com - * - * This program uses the PortAudio Portable Audio Library. - * For more information see: http://www.audiomulch.com/portaudio/ - * Copyright (c) 1999-2000 Ross Bencina and Phil Burk - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ -#include -#include -#include -#include "ringbuffer.h" -#include - -/*************************************************************************** - * Initialize FIFO. - * numBytes must be power of 2, returns -1 if not. - */ -long RingBuffer_Init( RingBuffer *rbuf, long numBytes, void *dataPtr ) -{ - if( ((numBytes-1) & numBytes) != 0) return -1; /* Not Power of two. */ - rbuf->bufferSize = numBytes; - rbuf->buffer = (char *)dataPtr; - RingBuffer_Flush( rbuf ); - rbuf->bigMask = (numBytes*2)-1; - rbuf->smallMask = (numBytes)-1; - return 0; -} -/*************************************************************************** -** Return number of bytes available for reading. */ -long RingBuffer_GetReadAvailable( RingBuffer *rbuf ) -{ - return ( (rbuf->writeIndex - rbuf->readIndex) & rbuf->bigMask ); -} -/*************************************************************************** -** Return number of bytes available for writing. */ -long RingBuffer_GetWriteAvailable( RingBuffer *rbuf ) -{ - return ( rbuf->bufferSize - RingBuffer_GetReadAvailable(rbuf)); -} - -/*************************************************************************** -** Clear buffer. Should only be called when buffer is NOT being read. */ -void RingBuffer_Flush( RingBuffer *rbuf ) -{ - rbuf->writeIndex = rbuf->readIndex = 0; -} - -/*************************************************************************** -** Get address of region(s) to which we can write data. -** If the region is contiguous, size2 will be zero. -** If non-contiguous, size2 will be the size of second region. -** Returns room available to be written or numBytes, whichever is smaller. -*/ -long RingBuffer_GetWriteRegions( RingBuffer *rbuf, long numBytes, - void **dataPtr1, long *sizePtr1, - void **dataPtr2, long *sizePtr2 ) -{ - long index; - long available = RingBuffer_GetWriteAvailable( rbuf ); - if( numBytes > available ) numBytes = available; - /* Check to see if write is not contiguous. */ - index = rbuf->writeIndex & rbuf->smallMask; - if( (index + numBytes) > rbuf->bufferSize ) - { - /* Write data in two blocks that wrap the buffer. */ - long firstHalf = rbuf->bufferSize - index; - *dataPtr1 = &rbuf->buffer[index]; - *sizePtr1 = firstHalf; - *dataPtr2 = &rbuf->buffer[0]; - *sizePtr2 = numBytes - firstHalf; - } - else - { - *dataPtr1 = &rbuf->buffer[index]; - *sizePtr1 = numBytes; - *dataPtr2 = NULL; - *sizePtr2 = 0; - } - return numBytes; -} - - -/*************************************************************************** -*/ -long RingBuffer_AdvanceWriteIndex( RingBuffer *rbuf, long numBytes ) -{ - return rbuf->writeIndex = (rbuf->writeIndex + numBytes) & rbuf->bigMask; -} - -/*************************************************************************** -** Get address of region(s) from which we can read data. -** If the region is contiguous, size2 will be zero. -** If non-contiguous, size2 will be the size of second region. -** Returns room available to be written or numBytes, whichever is smaller. -*/ -long RingBuffer_GetReadRegions( RingBuffer *rbuf, long numBytes, - void **dataPtr1, long *sizePtr1, - void **dataPtr2, long *sizePtr2 ) -{ - long index; - long available = RingBuffer_GetReadAvailable( rbuf ); - if( numBytes > available ) numBytes = available; - /* Check to see if read is not contiguous. */ - index = rbuf->readIndex & rbuf->smallMask; - if( (index + numBytes) > rbuf->bufferSize ) - { - /* Write data in two blocks that wrap the buffer. */ - long firstHalf = rbuf->bufferSize - index; - *dataPtr1 = &rbuf->buffer[index]; - *sizePtr1 = firstHalf; - *dataPtr2 = &rbuf->buffer[0]; - *sizePtr2 = numBytes - firstHalf; - } - else - { - *dataPtr1 = &rbuf->buffer[index]; - *sizePtr1 = numBytes; - *dataPtr2 = NULL; - *sizePtr2 = 0; - } - return numBytes; -} -/*************************************************************************** -*/ -long RingBuffer_AdvanceReadIndex( RingBuffer *rbuf, long numBytes ) -{ - return rbuf->readIndex = (rbuf->readIndex + numBytes) & rbuf->bigMask; -} - -/*************************************************************************** -** Return bytes written. */ -long RingBuffer_Write( RingBuffer *rbuf, void *data, long numBytes ) -{ - long size1, size2, numWritten; - void *data1, *data2; - numWritten = RingBuffer_GetWriteRegions( rbuf, numBytes, &data1, &size1, &data2, &size2 ); - if( size2 > 0 ) - { - - memcpy( data1, data, size1 ); - data = ((char *)data) + size1; - memcpy( data2, data, size2 ); - } - else - { - memcpy( data1, data, size1 ); - } - RingBuffer_AdvanceWriteIndex( rbuf, numWritten ); - return numWritten; -} - -/*************************************************************************** -** Return bytes read. */ -long RingBuffer_Read( RingBuffer *rbuf, void *data, long numBytes ) -{ - long size1, size2, numRead; - void *data1, *data2; - numRead = RingBuffer_GetReadRegions( rbuf, numBytes, &data1, &size1, &data2, &size2 ); - if( size2 > 0 ) - { - memcpy( data, data1, size1 ); - data = ((char *)data) + size1; - memcpy( data, data2, size2 ); - } - else - { - memcpy( data, data1, size1 ); - } - RingBuffer_AdvanceReadIndex( rbuf, numRead ); - return numRead; -} diff --git a/src/mod/mod_portaudio/ringbuffer.h b/src/mod/mod_portaudio/ringbuffer.h deleted file mode 100644 index 3cd559488b..0000000000 --- a/src/mod/mod_portaudio/ringbuffer.h +++ /dev/null @@ -1,103 +0,0 @@ -#ifndef _RINGBUFFER_H -#define _RINGBUFFER_H -#ifdef __cplusplus -extern "C" -{ -#endif /* __cplusplus */ - -/* - * $Id: ringbuffer.h,v 1.1.1.1.4.2 2003/04/28 17:45:34 philburk Exp $ - * ringbuffer.h - * Ring Buffer utility.. - * - * Author: Phil Burk, http://www.softsynth.com - * - * This program is distributed with the PortAudio Portable Audio Library. - * For more information see: http://www.audiomulch.com/portaudio/ - * Copyright (c) 1999-2000 Ross Bencina and Phil Burk - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ -#define PortAudioStream PaStream -#include -#include -#include -#include "ringbuffer.h" -#include - -typedef struct -{ - long bufferSize; /* Number of bytes in FIFO. Power of 2. Set by RingBuffer_Init. */ -/* These are declared volatile because they are written by a different thread than the reader. */ - volatile long writeIndex; /* Index of next writable byte. Set by RingBuffer_AdvanceWriteIndex. */ - volatile long readIndex; /* Index of next readable byte. Set by RingBuffer_AdvanceReadIndex. */ - long bigMask; /* Used for wrapping indices with extra bit to distinguish full/empty. */ - long smallMask; /* Used for fitting indices to buffer. */ - char *buffer; -} -RingBuffer; -/* - * Initialize Ring Buffer. - * numBytes must be power of 2, returns -1 if not. - */ -long RingBuffer_Init( RingBuffer *rbuf, long numBytes, void *dataPtr ); - -/* Clear buffer. Should only be called when buffer is NOT being read. */ -void RingBuffer_Flush( RingBuffer *rbuf ); - -/* Return number of bytes available for writing. */ -long RingBuffer_GetWriteAvailable( RingBuffer *rbuf ); -/* Return number of bytes available for read. */ -long RingBuffer_GetReadAvailable( RingBuffer *rbuf ); -/* Return bytes written. */ -long RingBuffer_Write( RingBuffer *rbuf, void *data, long numBytes ); -/* Return bytes read. */ -long RingBuffer_Read( RingBuffer *rbuf, void *data, long numBytes ); - -/* Get address of region(s) to which we can write data. -** If the region is contiguous, size2 will be zero. -** If non-contiguous, size2 will be the size of second region. -** Returns room available to be written or numBytes, whichever is smaller. -*/ -long RingBuffer_GetWriteRegions( RingBuffer *rbuf, long numBytes, - void **dataPtr1, long *sizePtr1, - void **dataPtr2, long *sizePtr2 ); -long RingBuffer_AdvanceWriteIndex( RingBuffer *rbuf, long numBytes ); - -/* Get address of region(s) from which we can read data. -** If the region is contiguous, size2 will be zero. -** If non-contiguous, size2 will be the size of second region. -** Returns room available to be read or numBytes, whichever is smaller. -*/ -long RingBuffer_GetReadRegions( RingBuffer *rbuf, long numBytes, - void **dataPtr1, long *sizePtr1, - void **dataPtr2, long *sizePtr2 ); - -long RingBuffer_AdvanceReadIndex( RingBuffer *rbuf, long numBytes ); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ -#endif /* _RINGBUFFER_H */ diff --git a/src/mod/mod_rawaudio/mod_rawaudio.c b/src/mod/mod_rawaudio/mod_rawaudio.c deleted file mode 100644 index 7dca8096a4..0000000000 --- a/src/mod/mod_rawaudio/mod_rawaudio.c +++ /dev/null @@ -1,215 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005/2006, Anthony Minessale II - * - * 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 - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Anthony Minessale II - * - * - * mod_rawaudio.c -- Raw Signed Linear Codec - * - */ -#include -#include - -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; -} - - - - - diff --git a/src/mod/mod_rawaudio/mod_rawaudio.vcproj b/src/mod/mod_rawaudio/mod_rawaudio.vcproj deleted file mode 100644 index 2fb53179c8..0000000000 --- a/src/mod/mod_rawaudio/mod_rawaudio.vcproj +++ /dev/null @@ -1,211 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/mod/mod_skel/mod_skel.c b/src/mod/mod_skel/mod_skel.c deleted file mode 100644 index 21126d1f3e..0000000000 --- a/src/mod/mod_skel/mod_skel.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005/2006, Anthony Minessale II - * - * 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 - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Anthony Minessale II - * - * - * mod_skel.c -- Framework Demo Module - * - */ -#include - -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; -} - diff --git a/src/mod/mod_sndfile/Makefile b/src/mod/mod_sndfile/Makefile deleted file mode 100644 index 1056e8fdd8..0000000000 --- a/src/mod/mod_sndfile/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -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 *~ - diff --git a/src/mod/mod_sndfile/mod_sndfile.c b/src/mod/mod_sndfile/mod_sndfile.c deleted file mode 100644 index 98a4f7dc25..0000000000 --- a/src/mod/mod_sndfile/mod_sndfile.c +++ /dev/null @@ -1,294 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005/2006, Anthony Minessale II - * - * 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 - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Anthony Minessale II - * - * - * mod_sndfile.c -- Framework Demo Module - * - */ -#include -#include - -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; -} - diff --git a/src/mod/mod_sndfile/mod_sndfilel.vcproj b/src/mod/mod_sndfile/mod_sndfilel.vcproj deleted file mode 100644 index 79db6aea16..0000000000 --- a/src/mod/mod_sndfile/mod_sndfilel.vcproj +++ /dev/null @@ -1,212 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/mod/mod_softtimer/mod_softtimer.c b/src/mod/mod_softtimer/mod_softtimer.c deleted file mode 100644 index c379436ab3..0000000000 --- a/src/mod/mod_softtimer/mod_softtimer.c +++ /dev/null @@ -1,128 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005/2006, Anthony Minessale II - * - * 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 - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Anthony Minessale II - * - * - * mod_softtimer.c -- Software Timer Module - * - */ -#include -#include - -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; -} - - - - - diff --git a/src/mod/mod_softtimer/mod_softtimer.vcproj b/src/mod/mod_softtimer/mod_softtimer.vcproj deleted file mode 100644 index b268d2fe5d..0000000000 --- a/src/mod/mod_softtimer/mod_softtimer.vcproj +++ /dev/null @@ -1,207 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/mod/mod_speexcodec/Makefile b/src/mod/mod_speexcodec/Makefile deleted file mode 100644 index 396db30128..0000000000 --- a/src/mod/mod_speexcodec/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -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 *~ - diff --git a/src/mod/mod_speexcodec/mod_speexcodec.c b/src/mod/mod_speexcodec/mod_speexcodec.c deleted file mode 100644 index d20d646cab..0000000000 --- a/src/mod/mod_speexcodec/mod_speexcodec.c +++ /dev/null @@ -1,342 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005/2006, Anthony Minessale II - * - * 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 - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Anthony Minessale II - * - * - * mod_speexcodec.c -- Speex Codec Module - * - */ -#include -#include -#include - -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; -} diff --git a/src/mod/mod_speexcodec/mod_speexcodec.vcproj b/src/mod/mod_speexcodec/mod_speexcodec.vcproj deleted file mode 100644 index 0abb26ac7c..0000000000 --- a/src/mod/mod_speexcodec/mod_speexcodec.vcproj +++ /dev/null @@ -1,211 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/mod/mod_wanchan/mod_wanchan.c b/src/mod/mod_wanchan/mod_wanchan.c deleted file mode 100644 index 3fd8080084..0000000000 --- a/src/mod/mod_wanchan/mod_wanchan.c +++ /dev/null @@ -1,634 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005/2006, Anthony Minessale II - * - * 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 - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Anthony Minessale II - * - * - * mod_wanchan.c -- WANPIPE PRI Channel Module - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -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; -} - diff --git a/src/mod/mod_woomerachan/mod_woomerachan.c b/src/mod/mod_woomerachan/mod_woomerachan.c deleted file mode 100644 index 9ecbf59f11..0000000000 --- a/src/mod/mod_woomerachan/mod_woomerachan.c +++ /dev/null @@ -1,1387 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005/2006, Anthony Minessale II - * - * 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 - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Anthony Minessale II - * - * - * mod_woomerachan.c -- Woomera Endpoint Module - * - */ -#include - -#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; -} - - - diff --git a/src/mod/mod_woomerachan/mod_woomerachan.vcproj b/src/mod/mod_woomerachan/mod_woomerachan.vcproj deleted file mode 100644 index 2d89ed1f2f..0000000000 --- a/src/mod/mod_woomerachan/mod_woomerachan.vcproj +++ /dev/null @@ -1,207 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/mod/mod_xmpp_event/Makefile b/src/mod/mod_xmpp_event/Makefile deleted file mode 100644 index e99f9650eb..0000000000 --- a/src/mod/mod_xmpp_event/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -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 *~ - diff --git a/src/mod/mod_xmpp_event/mod_xmpp_event.c b/src/mod/mod_xmpp_event/mod_xmpp_event.c deleted file mode 100644 index 6f983723d6..0000000000 --- a/src/mod/mod_xmpp_event/mod_xmpp_event.c +++ /dev/null @@ -1,386 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005/2006, Anthony Minessale II - * - * 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 - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Anthony Minessale II - * - * - * mod_xmpp_event.c -- XMPP Event Logger - * - */ -#include -#include - -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; -} diff --git a/src/mod/mod_xmpp_event/mod_xmpp_event.vcproj b/src/mod/mod_xmpp_event/mod_xmpp_event.vcproj deleted file mode 100644 index fa9167be6a..0000000000 --- a/src/mod/mod_xmpp_event/mod_xmpp_event.vcproj +++ /dev/null @@ -1,212 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -