Author: anthm Date: Wed Jul 23 14:19:56 2008 New Revision: 9145 Added: freeswitch/trunk/src/mod/applications/mod_snom/ freeswitch/trunk/src/mod/applications/mod_snom/Makefile freeswitch/trunk/src/mod/applications/mod_snom/mod_snom.c Modified: freeswitch/trunk/build/modules.conf.in freeswitch/trunk/conf/autoload_configs/modules.conf.xml freeswitch/trunk/conf/dialplan/default.xml freeswitch/trunk/src/include/switch_types.h freeswitch/trunk/src/mod/applications/mod_dptools/mod_dptools.c freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia.c freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_presence.c freeswitch/trunk/src/switch_event.c Log: add mod_snom Modified: freeswitch/trunk/build/modules.conf.in ============================================================================== --- freeswitch/trunk/build/modules.conf.in (original) +++ freeswitch/trunk/build/modules.conf.in Wed Jul 23 14:19:56 2008 @@ -13,6 +13,7 @@ applications/mod_fsv #applications/mod_soundtouch #applications/mod_rss +#applications/mod_snom #asr_tts/mod_flite #asr_tts/mod_pocketsphinx #asr_tts/mod_cepstral Modified: freeswitch/trunk/conf/autoload_configs/modules.conf.xml ============================================================================== --- freeswitch/trunk/conf/autoload_configs/modules.conf.xml (original) +++ freeswitch/trunk/conf/autoload_configs/modules.conf.xml Wed Jul 23 14:19:56 2008 @@ -47,6 +47,9 @@ <load module="mod_esf"/> <load module="mod_fsv"/> + <!-- SNOM Module --> + <!--<load module="mod_snom"/>--> + <!-- Dialplan Interfaces --> <!-- <load module="mod_dialplan_directory"/> --> <load module="mod_dialplan_xml"/> Modified: freeswitch/trunk/conf/dialplan/default.xml ============================================================================== --- freeswitch/trunk/conf/dialplan/default.xml (original) +++ freeswitch/trunk/conf/dialplan/default.xml Wed Jul 23 14:19:56 2008 @@ -64,6 +64,29 @@ </condition> </extension> + + <!-- + snom button demo, call 9000 to make button 2 mapped to transfer the current call to a conference + --> + + <extension name="snom-demo-2"> + <condition field="destination_number" expression="^9001$"> + <action application="eval" data="${snom_bind_key(2 off DND ${sip_from_user} ${sip_from_host} ${sofia_profile_name} message notused)}"/> + <action application="transfer" data="3000"/> + </condition> + </extension> + + <extension name="snom-demo-1"> + <condition field="destination_number" expression="^9000$"> + <!--<key> <light> <label> <user> <host> <profile> <action_name> <action>--> + <action application="eval" data="${snom_bind_key(2 on DND ${sip_from_user} ${sip_from_host} ${sofia_profile_name} message api+uuid_transfer ${uuid} 9001)}"/> + <action application="playback" data="$${hold_music}"/> + </condition> + </extension> + + + + <extension name="eavesdrop"> <condition field="destination_number" expression="^88(.*)$|^\*0(.*)$"> <action application="answer"/> Modified: freeswitch/trunk/src/include/switch_types.h ============================================================================== --- freeswitch/trunk/src/include/switch_types.h (original) +++ freeswitch/trunk/src/include/switch_types.h Wed Jul 23 14:19:56 2008 @@ -1057,6 +1057,7 @@ SWITCH_EVENT_RELOADXML - XML registry has been reloaded SWITCH_EVENT_NOTIFY - Notification SWITCH_EVENT_SEND_MESSAGE - Message + SWITCH_EVENT_RECV_MESSAGE - Message SWITCH_EVENT_ALL - All events at once </pre> @@ -1113,6 +1114,7 @@ SWITCH_EVENT_RELOADXML, SWITCH_EVENT_NOTIFY, SWITCH_EVENT_SEND_MESSAGE, + SWITCH_EVENT_RECV_MESSAGE, SWITCH_EVENT_ALL } switch_event_types_t; Modified: freeswitch/trunk/src/mod/applications/mod_dptools/mod_dptools.c ============================================================================== --- freeswitch/trunk/src/mod/applications/mod_dptools/mod_dptools.c (original) +++ freeswitch/trunk/src/mod/applications/mod_dptools/mod_dptools.c Wed Jul 23 14:19:56 2008 @@ -2088,6 +2088,74 @@ } +static switch_status_t event_chat_send(char *proto, char *from, char *to, char *subject, char *body, char *hint) +{ + switch_event_t *event; + + if (switch_event_create(&event, SWITCH_EVENT_RECV_MESSAGE) == SWITCH_STATUS_SUCCESS) { + if (proto) switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Proto", "%s", proto); + if (from) switch_event_add_header(event, SWITCH_STACK_BOTTOM, "From", "%s", from); + if (subject) switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Subject", "%s", subject); + if (hint) switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Hint", "%s", hint); + if (body) switch_event_add_body(event, "%s", body); + if (to) { + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "To", "%s", to); + const char *v; + if ((v = switch_core_get_variable(to))) { + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Command", "%s", v); + } + } + + if (switch_event_fire(&event) == SWITCH_STATUS_SUCCESS) { + return SWITCH_STATUS_SUCCESS; + } + + switch_event_destroy(&event); + } + + return SWITCH_STATUS_MEMERR; +} + + +static switch_status_t api_chat_send(char *proto, char *from, char *to, char *subject, char *body, char *hint) +{ + + if (to) { + const char *v; + switch_stream_handle_t stream = { 0 }; + char *cmd, *arg; + switch_chat_interface_t *ci; + + if (!(v = switch_core_get_variable(to))) { + v = to; + } + + cmd = strdup(v); + switch_assert(cmd); + + switch_url_decode(cmd); + + if ((arg = strchr(cmd, ' '))) { + *arg++ = '\0'; + } + + SWITCH_STANDARD_STREAM(stream); + switch_api_execute(cmd, arg, NULL, &stream); + + if (proto && (ci = switch_loadable_module_get_chat_interface(proto))) { + ci->chat_send("api", to, hint && strchr(hint, '/') ? hint : from, "text/plain", (char *) stream.data, NULL); + } + + switch_safe_free(stream.data); + + free(cmd); + + } + + return SWITCH_STATUS_SUCCESS; +} + + #define SPEAK_DESC "Speak text to a channel via the tts interface" #define DISPLACE_DESC "Displace audio from a file to the channels input" #define SESS_REC_DESC "Starts a background recording of the entire session" @@ -2108,6 +2176,7 @@ switch_api_interface_t *api_interface; switch_application_interface_t *app_interface; switch_dialplan_interface_t *dp_interface; + switch_chat_interface_t *chat_interface; /* connect my internal structure to the blank pointer passed to me */ *module_interface = switch_loadable_module_create_module_interface(pool, modname); @@ -2116,6 +2185,10 @@ user_endpoint_interface->interface_name = "USER"; user_endpoint_interface->io_routines = &user_io_routines; + + SWITCH_ADD_CHAT(chat_interface, "event", event_chat_send); + SWITCH_ADD_CHAT(chat_interface, "api", api_chat_send); + SWITCH_ADD_API(api_interface, "strepoch", "Convert a date string into epoch time", strepoch_api_function, "<string>"); SWITCH_ADD_API(api_interface, "chat", "chat", chat_api_function, "<proto>|<from>|<to>|<message>"); SWITCH_ADD_API(api_interface, "strftime", "strftime", strftime_api_function, "<format_string>"); Added: freeswitch/trunk/src/mod/applications/mod_snom/Makefile ============================================================================== --- (empty file) +++ freeswitch/trunk/src/mod/applications/mod_snom/Makefile Wed Jul 23 14:19:56 2008 @@ -0,0 +1,2 @@ +BASE=../../../.. +include $(BASE)/build/modmake.rules Added: freeswitch/trunk/src/mod/applications/mod_snom/mod_snom.c ============================================================================== --- (empty file) +++ freeswitch/trunk/src/mod/applications/mod_snom/mod_snom.c Wed Jul 23 14:19:56 2008 @@ -0,0 +1,143 @@ +/* + * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * Copyright (C) 2005/2006, Anthony Minessale II <anthmct@yahoo.com> + * + * Version: MPL 1.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * + * The Initial Developer of the Original Code is + * Anthony Minessale II <anthmct@yahoo.com> + * Portions created by the Initial Developer are Copyright (C) + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Anthony Minessale II <anthmct@yahoo.com> + * + * mod_snom.c -- SNOM Specific Features + * + */ +#include <switch.h> + +SWITCH_MODULE_LOAD_FUNCTION(mod_snom_load); +SWITCH_MODULE_DEFINITION(mod_snom, mod_snom_load, NULL, NULL); + +static switch_bool_t snom_bind_key(const char *key, + const char *light, + const char *label, + const char *user, + const char *host, + const char *profile, + const char *action_name, + const char *action) +{ + switch_event_t *event; + + + if (user && host && profile) { + if (switch_event_create(&event, SWITCH_EVENT_SEND_MESSAGE) == SWITCH_STATUS_SUCCESS) { + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "user", "%s", user); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "host", "%s", host); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "profile", "%s", profile); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "content-type", "application/x-buttons"); + if (action && action_name) { + switch_event_add_body(event, "k=%s\nc=%s\nl=%s\nn=%s\na=%s\n", key, light, label, action, action_name); + } else { + switch_event_add_body(event, "k=%s\nc=%s\nl=%s\n\n", key, light, label); + } + + switch_event_fire(&event); + } + return SWITCH_TRUE; + } + + return SWITCH_FALSE; +} + + +#define URL_SYNTAX "" +SWITCH_STANDARD_API(snom_url_api_function) +{ +#if 0 + char *tmp; + switch_event_serialize(stream->param_event, &tmp, SWITCH_TRUE); + printf("W00t\n%s\n", tmp); + free(tmp); +#endif + + return SWITCH_STATUS_SUCCESS; + +} + +#define KEY_BIND_SYNTAX "<key> <light> <label> <user> <host> <profile> <action_name> <action>" +SWITCH_STANDARD_API(snom_bind_key_api_function) +{ + int argc; + char *mydata = NULL, *argv[8]; + + mydata = strdup(cmd); + argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); + + if (argc < 6) { + goto err; + } + + if (snom_bind_key(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7])) { + stream->write_function(stream, "+OK %s\n", cmd); + goto end; + } + + err: + + stream->write_function(stream, "-Error %s\n", KEY_BIND_SYNTAX); + + end: + + free(mydata); + + return SWITCH_STATUS_SUCCESS; +} + + +SWITCH_MODULE_LOAD_FUNCTION(mod_snom_load) +{ + + switch_api_interface_t *commands_api_interface; + + /* connect my internal structure to the blank pointer passed to me */ + *module_interface = switch_loadable_module_create_module_interface(pool, modname); + + + SWITCH_ADD_API(commands_api_interface, "snom_bind_key", "Bind a key", snom_bind_key_api_function, KEY_BIND_SYNTAX); + SWITCH_ADD_API(commands_api_interface, "snom_url", "url", snom_url_api_function, URL_SYNTAX); + + + /* indicate that the module should continue to be loaded */ + return SWITCH_STATUS_SUCCESS; +} + + + + + +/* 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 expandtab: + */ Modified: freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c ============================================================================== --- freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c (original) +++ freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c Wed Jul 23 14:19:56 2008 @@ -2120,11 +2120,17 @@ sofia_profile_t *profile; nua_handle_t *nh; - if (profile_name && ct && body && user && host && (profile = sofia_glue_find_profile(profile_name))) { + if (profile_name && ct && body && user && host) { char *id = NULL; char *contact, *p; char buf[512] = ""; + if (!(profile = sofia_glue_find_profile(profile_name))) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't find profile %s\n", profile_name); + return; + } + + if (!sofia_reg_find_reg_url(profile, user, host, buf, sizeof(buf))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't find user %s@%s\n", user, host); return; Modified: freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia.c ============================================================================== --- freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia.c (original) +++ freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia.c Wed Jul 23 14:19:56 2008 @@ -551,6 +551,7 @@ NUTAG_APPL_METHOD("INFO"), NUTAG_AUTOANSWER(0), NUTAG_AUTOALERT(0), + NUTAG_ENABLEMESSENGER(1), TAG_IF((profile->mflags & MFLAG_REGISTER), NUTAG_ALLOW("REGISTER")), TAG_IF((profile->mflags & MFLAG_REFER), NUTAG_ALLOW("REFER")), NUTAG_ALLOW("INFO"), Modified: freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_presence.c ============================================================================== --- freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_presence.c (original) +++ freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_presence.c Wed Jul 23 14:19:56 2008 @@ -58,6 +58,11 @@ nua_handle_t *msg_nh; char *contact; switch_status_t status = SWITCH_STATUS_FALSE; + const char *ct = "text/html"; + + if (subject && strchr(subject, '/')) { + ct = subject; + } if (!to) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing To: header.\n"); @@ -112,7 +117,7 @@ SIPTAG_CONTACT_STR(profile->url), TAG_END()); switch_safe_free(contact); - nua_message(msg_nh, SIPTAG_CONTENT_TYPE_STR("text/html"), SIPTAG_PAYLOAD_STR(body), TAG_END()); + nua_message(msg_nh, SIPTAG_CONTENT_TYPE_STR(ct), SIPTAG_PAYLOAD_STR(body), TAG_END()); end: Modified: freeswitch/trunk/src/switch_event.c ============================================================================== --- freeswitch/trunk/src/switch_event.c (original) +++ freeswitch/trunk/src/switch_event.c Wed Jul 23 14:19:56 2008 @@ -157,6 +157,7 @@ "RELOADXML", "NOTIFY", "SEND_MESSAGE", + "RECV_MESSAGE", "ALL" };