[commit] r6205 - in freeswitch/trunk: . src src/include src/mod/dialplans/mod_dialplan_asterisk
Author: anthm Date: Fri Nov 9 14:25:46 2007 New Revision: 6205 Added: freeswitch/trunk/src/mod/dialplans/mod_dialplan_asterisk/ freeswitch/trunk/src/mod/dialplans/mod_dialplan_asterisk/Makefile freeswitch/trunk/src/mod/dialplans/mod_dialplan_asterisk/mod_dialplan_asterisk.c freeswitch/trunk/src/mod/dialplans/mod_dialplan_asterisk/mod_dialplan_asterisk.vcproj Modified: freeswitch/trunk/Makefile.am freeswitch/trunk/src/include/switch.h freeswitch/trunk/src/include/switch_utils.h freeswitch/trunk/src/switch_channel.c freeswitch/trunk/src/switch_utils.c Log: add a new dialplan module Modified: freeswitch/trunk/Makefile.am ============================================================================== --- freeswitch/trunk/Makefile.am (original) +++ freeswitch/trunk/Makefile.am Fri Nov 9 14:25:46 2007 @@ -55,6 +55,7 @@ src/switch_stun.c\ src/switch_log.c\ src/switch_xml.c\ +src/switch_config.c\ src/softtimer.c\ libs/stfu/stfu.c\ src/switch_cpp.cpp\ Modified: freeswitch/trunk/src/include/switch.h ============================================================================== --- freeswitch/trunk/src/include/switch.h (original) +++ freeswitch/trunk/src/include/switch.h Fri Nov 9 14:25:46 2007 @@ -105,6 +105,7 @@ #include <switch_xml.h> #include <switch_core_event_hook.h> #include <switch_scheduler.h> +#include <switch_config.h> #include <libteletone.h> /** \mainpage FreeSWITCH Modified: freeswitch/trunk/src/include/switch_utils.h ============================================================================== --- freeswitch/trunk/src/include/switch_utils.h (original) +++ freeswitch/trunk/src/include/switch_utils.h Fri Nov 9 14:25:46 2007 @@ -303,6 +303,7 @@ SWITCH_DECLARE(const char *) switch_stristr(const char *str, const char *instr); SWITCH_DECLARE(switch_bool_t) switch_is_lan_addr(const char *ip); SWITCH_DECLARE(char *) switch_replace_char(char *str, char from, char to, switch_bool_t dup); +SWITCH_DECLARE(switch_bool_t) switch_ast2regex(char *pat, char *rbuf, size_t len); /*! \brief Escape a string by prefixing a list of characters with an escape character Added: freeswitch/trunk/src/mod/dialplans/mod_dialplan_asterisk/Makefile ============================================================================== --- (empty file) +++ freeswitch/trunk/src/mod/dialplans/mod_dialplan_asterisk/Makefile Fri Nov 9 14:25:46 2007 @@ -0,0 +1,2 @@ +BASE=../../../.. +include /usr/src/freeswitch.trunk/build/modmake.rules Added: freeswitch/trunk/src/mod/dialplans/mod_dialplan_asterisk/mod_dialplan_asterisk.c ============================================================================== --- (empty file) +++ freeswitch/trunk/src/mod/dialplans/mod_dialplan_asterisk/mod_dialplan_asterisk.c Fri Nov 9 14:25:46 2007 @@ -0,0 +1,189 @@ +/* + * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * Copyright (C) 2005/2006, Anthony Minessale II <anthmct@yahoo.com> + * + * Version: MPL 1.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * + * The Initial Developer of the Original Code is + * Anthony Minessale II <anthmct@yahoo.com> + * Portions created by the Initial Developer are Copyright (C) + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Anthony Minessale II <anthmct@yahoo.com> + * + * mod_dialplan_asterisk.c -- Asterisk extensions.conf style dialplan parser. + * + */ +#include <switch.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> + +SWITCH_MODULE_LOAD_FUNCTION(mod_dialplan_asterisk_load); +SWITCH_MODULE_DEFINITION(mod_dialplan_asterisk, mod_dialplan_asterisk_load, NULL, NULL); + +SWITCH_STANDARD_DIALPLAN(asterisk_dialplan_hunt) +{ + switch_caller_extension_t *extension = NULL; + switch_channel_t *channel; + char *cf = "extensions.conf"; + switch_config_t cfg; + char *var, *val; + const char *context = NULL; + + if (arg) { + cf = arg; + } + + channel = switch_core_session_get_channel(session); + assert(channel != NULL); + + if (!caller_profile) { + caller_profile = switch_channel_get_caller_profile(channel); + } + + if (caller_profile) { + context = caller_profile->context ? caller_profile->context : "default"; + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Obtaining Profile!\n"); + return NULL; + } + + if (!switch_config_open_file(&cfg, cf)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "open of %s failed\n", cf); + switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); + return NULL; + } + + while (switch_config_next_pair(&cfg, &var, &val)) { + if (!strcasecmp(cfg.category, context)) { + if (!strcasecmp(var, "exten")) { + int argc; + char *argv[4] = { 0 }; + char *pattern = NULL; + char *pri = NULL; + char *app = NULL; + char *arg = NULL; + char expression[1024] = ""; + char substituted[2048] = ""; + char *field_data = caller_profile->destination_number; + int proceed = 0; + switch_regex_t *re = NULL; + int ovector[30] = {0}; + + + switch_replace_char(val, '|',',', SWITCH_FALSE); + argc = switch_separate_string(val, ',', argv, (sizeof(argv) / sizeof(argv[0]))); + if (argc < 3) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "parse error line %d!\n", cfg.lineno); + continue; + } + + pattern = argv[0]; + + if (*pattern == '_') { + pattern++; + if (switch_ast2regex(pattern, expression, sizeof(expression))) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "converting [%s] to real regex [%s] you should try them!\n", + pattern, expression); + } + if (!(proceed = switch_regex_perform(field_data, expression, &re, ovector, sizeof(ovector) / sizeof(ovector[0])))) { + switch_regex_safe_free(re); + continue; + } + + } else { + if (strcasecmp(pattern, caller_profile->destination_number)) { + continue; + } + } + + switch_channel_set_variable(channel, "EXTEN", caller_profile->destination_number); + switch_channel_set_variable(channel, "CHANNEL", switch_channel_get_name(channel)); + switch_channel_set_variable(channel, "UNIQUEID", switch_core_session_get_uuid(session)); + + pri = argv[1]; + app = argv[2]; + + if (argc == 4) { + arg = argv[3]; + } else { + if ((arg = strchr(app, '('))) { + *arg++ = '\0'; + char *p = strrchr(arg, ')'); + if (p) { + *p = '\0'; + } + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "parse error line %d!\n", cfg.lineno); + continue; + } + } + + if (strchr(expression, '(')) { + switch_perform_substitution(re, proceed, arg, field_data, substituted, sizeof(substituted), ovector); + arg = substituted; + } + switch_regex_safe_free(re); + + if (!extension) { + if ((extension = switch_caller_extension_new(session, caller_profile->destination_number, + caller_profile->destination_number)) == 0) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "memory error!\n"); + break; + } + } + + switch_caller_extension_add_application(session, extension, app, arg); + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "param '%s' not implemented at line %d!\n", var, cfg.lineno); + } + } + } + + switch_config_close_file(&cfg); + + if (extension) { + switch_channel_set_state(channel, CS_EXECUTE); + } + + return extension; +} + + +SWITCH_MODULE_LOAD_FUNCTION(mod_dialplan_asterisk_load) +{ + switch_dialplan_interface_t *dp_interface; + + /* connect my internal structure to the blank pointer passed to me */ + *module_interface = switch_loadable_module_create_module_interface(pool, modname); + SWITCH_ADD_DIALPLAN(dp_interface, "asterisk", asterisk_dialplan_hunt); + + /* 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: + */ Added: freeswitch/trunk/src/mod/dialplans/mod_dialplan_asterisk/mod_dialplan_asterisk.vcproj ============================================================================== --- (empty file) +++ freeswitch/trunk/src/mod/dialplans/mod_dialplan_asterisk/mod_dialplan_asterisk.vcproj Fri Nov 9 14:25:46 2007 @@ -0,0 +1,51 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="8.00" + Name="mod_dialplan_asterisk" + ProjectGUID="{07113B25-D3AF-4E04-BA77-4CD1171F022C}" + RootNamespace="mod_dialplan_asterisk" + Keyword="Win32Proj" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + ConfigurationType="2" + InheritedPropertySheets="..\..\..\..\w32\module_debug.vsprops" + CharacterSet="2" + > + <Tool + Name="VCCLCompilerTool" + UsePrecompiledHeader="0" + /> + </Configuration> + <Configuration + Name="Release|Win32" + ConfigurationType="2" + InheritedPropertySheets="..\..\..\..\w32\module_release.vsprops" + CharacterSet="2" + > + <Tool + Name="VCCLCompilerTool" + UsePrecompiledHeader="0" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <File + RelativePath=".\mod_dialplan_asterisk.c" + > + </File> + </Files> + <Globals> + </Globals> +</VisualStudioProject> Modified: freeswitch/trunk/src/switch_channel.c ============================================================================== --- freeswitch/trunk/src/switch_channel.c (original) +++ freeswitch/trunk/src/switch_channel.c Fri Nov 9 14:25:46 2007 @@ -1269,6 +1269,7 @@ char *data, *indup; size_t sp = 0, len = 0, olen = 0, vtype = 0, br = 0, cpos, block = 128; const char *sub_val = NULL; + char *cloned_sub_val = NULL; char *func_val = NULL; int nv = 0; @@ -1393,13 +1394,43 @@ if (vtype == 1) { char *expanded = NULL; - + int offset = 0; + int ooffset = 0; + char *p; + if ((expanded = switch_channel_expand_variables(channel, (char *)vname)) == vname) { expanded = NULL; } else { vname = expanded; } + if ((p = strchr(vname, ':'))) { + *p++ = '\0'; + offset = atoi(p); + if ((p = strchr(p, ':'))) { + p++; + ooffset = atoi(p); + } + } + sub_val = switch_channel_get_variable(channel, vname); + if (offset || ooffset) { + cloned_sub_val = strdup(sub_val); + assert(cloned_sub_val); + sub_val = cloned_sub_val; + } + + if (offset >= 0) { + sub_val += offset; + } else if (abs(offset) <= strlen(sub_val)) { + sub_val = cloned_sub_val + (strlen(cloned_sub_val) + offset); + } + + if (ooffset > 0 && ooffset < strlen(sub_val)) { + if ((p = (char *)sub_val + ooffset)) { + *p = '\0'; + } + } + switch_safe_free(expanded); } else { switch_stream_handle_t stream = { 0 }; @@ -1450,9 +1481,11 @@ } switch_safe_free(func_val); + switch_safe_free(cloned_sub_val); sub_val = NULL; vname = NULL; vtype = 0; + br = 0; } if (len + 1 >= olen) { resize(1); Modified: freeswitch/trunk/src/switch_utils.c ============================================================================== --- freeswitch/trunk/src/switch_utils.c (original) +++ freeswitch/trunk/src/switch_utils.c Fri Nov 9 14:25:46 2007 @@ -222,6 +222,28 @@ } +SWITCH_DECLARE(switch_bool_t) switch_ast2regex(char *pat, char *rbuf, size_t len) +{ + char *p = pat; + memset(rbuf, 0, len); + + while(p && *p) { + if (*p == 'N') { + strncat(rbuf, "[2-9]", len - strlen(rbuf)); + } else if (*p == 'X') { + strncat(rbuf, "[0-9]", len - strlen(rbuf)); + } else if (*p == 'Z') { + strncat(rbuf, "[1-9]", len - strlen(rbuf)); + } else if (*p == '.') { + strncat(rbuf, ".*", len - strlen(rbuf)); + } else if (strlen(rbuf) < len - 1) { + *(rbuf + strlen(rbuf)) = *p; + } + p++; + } + + return strcmp(pat,rbuf) ? SWITCH_TRUE : SWITCH_FALSE; +} SWITCH_DECLARE(char *) switch_replace_char(char *str, char from, char to, switch_bool_t dup) {
participants (1)
-
Freeswitch SVN