diff --git a/build/standalone_module/Makefile.am b/build/standalone_module/Makefile.am new file mode 100644 index 0000000000..a7ca836b36 --- /dev/null +++ b/build/standalone_module/Makefile.am @@ -0,0 +1,6 @@ +AUTOMAKE_OPTIONS = foreign subdir-objects + +mod_LTLIBRARIES = mod_skel.la +mod_skel_la_SOURCES = mod_skel.c +mod_skel_la_CFLAGS = $(FREESWITCH_CFLAGS) +mod_skel_la_LDFLAGS = -avoid-version -module -no-undefined -shared $(FREESWITCH_LDFLAGS) diff --git a/build/standalone_module/README b/build/standalone_module/README new file mode 100644 index 0000000000..af5f435444 --- /dev/null +++ b/build/standalone_module/README @@ -0,0 +1,7 @@ +This is a sample build system for a stand alone FreeSWITCH module. + +To build and install: +./bootstrap.sh +./configure +make +make install diff --git a/build/standalone_module/bootstrap.sh b/build/standalone_module/bootstrap.sh new file mode 100644 index 0000000000..1c0649307c --- /dev/null +++ b/build/standalone_module/bootstrap.sh @@ -0,0 +1,2 @@ +#!/bin/bash +autoreconf -i diff --git a/build/standalone_module/configure.ac b/build/standalone_module/configure.ac new file mode 100644 index 0000000000..9aa3b08031 --- /dev/null +++ b/build/standalone_module/configure.ac @@ -0,0 +1,20 @@ +AC_INIT([freeswitch_standalone_module], [1.7.0], bugs@freeswitch.org) + +AM_INIT_AUTOMAKE + +m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) + +AM_PROG_CC_C_O + +AC_PROG_LIBTOOL + +PKG_CHECK_MODULES([FREESWITCH],[freeswitch],[],[]) +PKG_CHECK_VAR([moddir],[freeswitch],[modulesdir]) + +AC_SUBST(FREESWITCH_CFLAGS) +AC_SUBST(FREESWITCH_LDFLAGS) +AC_SUBST(moddir) + +AC_CONFIG_FILES([Makefile]) + +AC_OUTPUT diff --git a/build/standalone_module/mod_skel.c b/build/standalone_module/mod_skel.c new file mode 100644 index 0000000000..38bf4ac099 --- /dev/null +++ b/build/standalone_module/mod_skel.c @@ -0,0 +1,293 @@ +/* + * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * Copyright (C) 2005-2014, 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 + * Neal Horman + * + * + * mod_skel.c -- Framework Demo Module + * + */ +#include + +/* Prototypes */ +SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_skel_shutdown); +SWITCH_MODULE_RUNTIME_FUNCTION(mod_skel_runtime); +SWITCH_MODULE_LOAD_FUNCTION(mod_skel_load); + +/* SWITCH_MODULE_DEFINITION(name, load, shutdown, runtime) + * Defines a switch_loadable_module_function_table_t and a static const char[] modname + */ +SWITCH_MODULE_DEFINITION(mod_skel, mod_skel_load, mod_skel_shutdown, NULL); + +typedef enum { + CODEC_NEGOTIATION_GREEDY = 1, + CODEC_NEGOTIATION_GENEROUS = 2, + CODEC_NEGOTIATION_EVIL = 3 +} codec_negotiation_t; + +static struct { + char *codec_negotiation_str; + codec_negotiation_t codec_negotiation; + switch_bool_t sip_trace; + int integer; +} globals; + +static switch_status_t config_callback_siptrace(switch_xml_config_item_t *data, switch_config_callback_type_t callback_type, switch_bool_t changed) +{ + switch_bool_t value = *(switch_bool_t *) data->ptr; + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "In siptrace callback: value %s changed %s\n", + value ? "true" : "false", changed ? "true" : "false"); + + + /* + if ((callback_type == CONFIG_LOG || callback_type == CONFIG_RELOAD) && changed) { + nua_set_params(((sofia_profile_t*)data->functiondata)->nua, TPTAG_LOG(value), TAG_END()); + } + */ + + return SWITCH_STATUS_SUCCESS; +} + +static switch_xml_config_string_options_t config_opt_codec_negotiation = { NULL, 0, "greedy|generous|evil" }; + +/* enforce_min, min, enforce_max, max */ +static switch_xml_config_int_options_t config_opt_integer = { SWITCH_TRUE, 0, SWITCH_TRUE, 10 }; +static switch_xml_config_enum_item_t config_opt_codec_negotiation_enum[] = { + {"greedy", CODEC_NEGOTIATION_GREEDY}, + {"generous", CODEC_NEGOTIATION_GENEROUS}, + {"evil", CODEC_NEGOTIATION_EVIL}, + {NULL, 0} +}; + +static switch_xml_config_item_t instructions[] = { + /* parameter name type reloadable pointer default value options structure */ + SWITCH_CONFIG_ITEM("codec-negotiation-str", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE, &globals.codec_negotiation_str, "greedy", + &config_opt_codec_negotiation, + "greedy|generous|evil", "Specifies the codec negotiation scheme to be used."), + SWITCH_CONFIG_ITEM("codec-negotiation", SWITCH_CONFIG_ENUM, CONFIG_RELOADABLE, &globals.codec_negotiation, (void *) CODEC_NEGOTIATION_GREEDY, + &config_opt_codec_negotiation_enum, + "greedy|generous|evil", "Specifies the codec negotiation scheme to be used."), + SWITCH_CONFIG_ITEM_CALLBACK("sip-trace", SWITCH_CONFIG_BOOL, CONFIG_RELOADABLE, &globals.sip_trace, (void *) SWITCH_FALSE, + (switch_xml_config_callback_t) config_callback_siptrace, NULL, + "yes|no", "If enabled, print out sip messages on the console."), + SWITCH_CONFIG_ITEM("integer", SWITCH_CONFIG_INT, CONFIG_RELOADABLE, &globals.integer, (void *) 100, &config_opt_integer, + NULL, NULL), + SWITCH_CONFIG_ITEM_END() +}; + +static switch_status_t do_config(switch_bool_t reload) +{ + memset(&globals, 0, sizeof(globals)); + + if (switch_xml_config_parse_module_settings("skel.conf", reload, instructions) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Could not open skel.conf\n"); + return SWITCH_STATUS_FALSE; + } + + return SWITCH_STATUS_SUCCESS; +} +#include "switch_stun.h" + +#define _switch_stun_packet_next_attribute(attribute, end) (attribute && (attribute = (switch_stun_packet_attribute_t *) (attribute->value + ntohs(attribute->length))) && ((void *)attribute < end) && ntohs(attribute->length) && ((void *)(attribute + ntohs(attribute->length)) < end)) + +#define _switch_stun_attribute_padded_length(attribute) ((uint16_t)(ntohs(attribute->length) + (sizeof(uint32_t)-1)) & ~sizeof(uint32_t)) + +//#define _switch_stun_packet_next_attribute(attribute, end) (attribute && (attribute = (switch_stun_packet_attribute_t *) (attribute->value + _switch_stun_attribute_padded_length(attribute))) && ((void *)attribute < end) && ((void *)(attribute + _switch_stun_attribute_padded_length(attribute)) < end)) + +SWITCH_STANDARD_API(skel_function) +{ + switch_event_t *event; + unsigned char frame_buffer[8192] = {0}; + uint8_t buf[256] = { 0 }; + switch_stun_packet_t *packet; + char user_name[] = "0000000000000000:1111111111111111"; + //char user_name[] = "0000000000000000"; + void *end_buf; + switch_stun_packet_attribute_t *attr; + int xlen = 0; + + packet = switch_stun_packet_build_header(SWITCH_STUN_BINDING_REQUEST, NULL, buf); + + printf("1len %d %d\n", ntohs(packet->header.length), xlen); + + switch_stun_packet_attribute_add_username(packet, user_name, strlen(user_name)); + printf("2len %d %d\n", ntohs(packet->header.length), xlen); + + switch_stun_packet_attribute_add_controlled(packet); + + //switch_stun_packet_attribute_add_password(packet, user_name, strlen(user_name)); + //printf("3len %d %d\n", ntohs(packet->header.length), xlen); + + //switch_stun_packet_attribute_add_use_candidate(packet); + + switch_stun_packet_attribute_add_integrity(packet, "FUCK"); + switch_stun_packet_attribute_add_fingerprint(packet); + + + end_buf = buf + ((sizeof(buf) > packet->header.length) ? packet->header.length : sizeof(buf)); + + + + switch_stun_packet_first_attribute(packet, attr); + + xlen = sizeof(switch_stun_packet_header_t); + + printf("len %d %d\n", ntohs(packet->header.length), xlen); + + do { + printf("WTF %p %d %d:(%d)\n", (void *)attr, ntohs(attr->type), ntohs(attr->length), switch_stun_attribute_padded_length_hbo(attr)); + + if (!switch_stun_packet_next_attribute_hbo(attr, end_buf)) { + break; + } + + xlen += 4+switch_stun_attribute_padded_length_hbo(attr); + } while (xlen <= ntohs(packet->header.length)); + + + + + return SWITCH_STATUS_SUCCESS; + + do_config(SWITCH_TRUE); + + if (switch_event_create(&event, SWITCH_EVENT_TRAP) == SWITCH_STATUS_SUCCESS) { + switch_size_t len = 0; + int x = 0; + + /* populate the event with some headers */ + + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "testing", "true"); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "foo", "bar"); + + for (x = 0; x < 10; x++) { + char name[128]; + switch_snprintf(name, sizeof(name), "test-header-%d", x); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, name, "value-%d", x); + } + + + /* Nothing up my sleeve, here is the event */ + + DUMP_EVENT(event); + + + /* ok, serialize it into frame_buffer and destroy the event *poof* */ + len = sizeof(frame_buffer); + switch_event_binary_serialize(event, (void *)frame_buffer, &len); + switch_event_destroy(&event); + + + /* wave the magic wand and feed frame_buffer to deserialize */ + switch_event_binary_deserialize(&event, (void *)frame_buffer, len, SWITCH_FALSE); + + /* TA DA */ + DUMP_EVENT(event); + + switch_event_destroy(&event); + } + + + return SWITCH_STATUS_SUCCESS; +} + +static void mycb(switch_core_session_t *session, switch_channel_callstate_t callstate, switch_device_record_t *drec) +{ + switch_channel_t *channel = switch_core_session_get_channel(session); + + switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_CRIT, + "%s device: %s\nState: %s Dev State: %s/%s Total:%u Offhook:%u Active:%u Held:%u Hungup:%u Dur: %u %s\n", + switch_channel_get_name(channel), + drec->device_id, + switch_channel_callstate2str(callstate), + switch_channel_device_state2str(drec->last_state), + switch_channel_device_state2str(drec->state), + drec->stats.total, + drec->stats.offhook, + drec->stats.active, + drec->stats.held, + drec->stats.hup, + drec->active_stop ? (uint32_t)(drec->active_stop - drec->active_start) / 1000 : 0, + switch_channel_test_flag(channel, CF_FINAL_DEVICE_LEG) ? "FINAL LEG" : ""); + +} + + +/* Macro expands to: switch_status_t mod_skel_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool) */ +SWITCH_MODULE_LOAD_FUNCTION(mod_skel_load) +{ + switch_api_interface_t *api_interface; + /* connect my internal structure to the blank pointer passed to me */ + *module_interface = switch_loadable_module_create_module_interface(pool, modname); + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Hello World!\n"); + + do_config(SWITCH_FALSE); + + SWITCH_ADD_API(api_interface, "skel", "Skel API", skel_function, "syntax"); + + switch_channel_bind_device_state_handler(mycb, NULL); + + /* indicate that the module should continue to be loaded */ + return SWITCH_STATUS_SUCCESS; +} + +/* + Called when the system shuts down + Macro expands to: switch_status_t mod_skel_shutdown() */ +SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_skel_shutdown) +{ + /* Cleanup dynamically allocated config settings */ + switch_channel_unbind_device_state_handler(mycb); + switch_xml_config_cleanup(instructions); + return SWITCH_STATUS_SUCCESS; +} + + +/* + If it exists, this is called in it's own thread when the module-load completes + If it returns anything but SWITCH_STATUS_TERM it will be called again automatically + Macro expands to: switch_status_t mod_skel_runtime() +SWITCH_MODULE_RUNTIME_FUNCTION(mod_skel_runtime) +{ + while(looping) + { + switch_cond_next(); + } + return SWITCH_STATUS_TERM; +} +*/ + +/* For Emacs: + * Local Variables: + * mode:c + * indent-tabs-mode:t + * tab-width:4 + * c-basic-offset:4 + * End: + * For VIM: + * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet + */