]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
XMLification (wave 2)
authorAnthony Minessale <anthony.minessale@gmail.com>
Wed, 10 May 2006 03:27:00 +0000 (03:27 +0000)
committerAnthony Minessale <anthony.minessale@gmail.com>
Wed, 10 May 2006 03:27:00 +0000 (03:27 +0000)
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@1402 d0543943-73ff-0310-b7d9-9358b9ac24b2

src/mod/dialplans/mod_dialplan_xml/Makefile [new file with mode: 0644]
src/mod/dialplans/mod_dialplan_xml/mod_dialplan_xml.c [new file with mode: 0644]
src/mod/dialplans/mod_dialplan_xml/mod_dialplan_xml.vcproj [new file with mode: 0644]

diff --git a/src/mod/dialplans/mod_dialplan_xml/Makefile b/src/mod/dialplans/mod_dialplan_xml/Makefile
new file mode 100644 (file)
index 0000000..8a769aa
--- /dev/null
@@ -0,0 +1,17 @@
+LDFLAGS += -lpcre -L/usr/local/lib
+
+all:   depends $(MODNAME).$(DYNAMIC_LIB_EXTEN)
+
+depends:
+       MAKE=$(MAKE) $(BASE)/build/buildlib.sh $(BASE) install pcre-6.4.tar.gz --prefix=$(PREFIX)
+
+$(MODNAME).$(DYNAMIC_LIB_EXTEN): $(MODNAME).c
+       $(CC) $(CFLAGS) -fPIC -c $(MODNAME).c -o $(MODNAME).o 
+       $(CC) $(SOLINK) -o $(MODNAME).$(DYNAMIC_LIB_EXTEN)  $(MODNAME).o $(LDFLAGS)
+
+
+clean:
+       rm -fr *.$(DYNAMIC_LIB_EXTEN) *.o *~
+
+install:
+       cp -f $(MODNAME).$(DYNAMIC_LIB_EXTEN) $(PREFIX)/mod
diff --git a/src/mod/dialplans/mod_dialplan_xml/mod_dialplan_xml.c b/src/mod/dialplans/mod_dialplan_xml/mod_dialplan_xml.c
new file mode 100644 (file)
index 0000000..2d401a4
--- /dev/null
@@ -0,0 +1,249 @@
+/* 
+ * 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_xml.c -- XML/Regex Dialplan Module
+ *
+ */
+#include <switch.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <pcre.h>
+
+static const char modname[] = "mod_dialplan_xml";
+
+#define cleanre(re)    if (re) {\
+                               pcre_free(re);\
+                               re = NULL;\
+                       }
+
+
+static int perform_regex(switch_channel_t *channel, char *field, char *expression, pcre **new_re, int *ovector, uint32_t olen)
+{
+       const char *error = NULL;
+       int erroffset = 0;
+       pcre *re = NULL;
+       int match_count = 0;
+       
+       if (!(field && expression)) {
+               return 0;
+       }
+
+       re = pcre_compile(expression, /* the pattern */
+                                         0,              /* default options */
+                                         &error,         /* for error message */
+                                         &erroffset, /* for error offset */
+                                         NULL);          /* use default character tables */
+       if (error) {
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "COMPILE ERROR: %d [%s]\n", erroffset, error);
+               cleanre(re);
+               return 0;
+       }
+
+       match_count = pcre_exec(re,     /* result of pcre_compile() */
+                                                       NULL,   /* we didn't study the pattern */
+                                                       field,  /* the subject string */
+                                                       (int) strlen(field), /* the length of the subject string */
+                                                       0,      /* start at offset 0 in the subject */
+                                                       0,      /* default options */
+                                                       ovector,        /* vector of integers for substring information */
+                                                       olen); /* number of elements (NOT size in bytes) */
+
+       if (match_count <= 0) {
+               cleanre(re);
+               match_count = 0;
+       }
+
+       *new_re = re;
+
+       return match_count;
+}
+
+
+static void perform_substitution(pcre *re, int match_count, char *data, char *field_data, char *substituted, uint32_t len, int *ovector)
+{
+       char index[10] = "";
+       char replace[1024] = "";
+       uint32_t x, y = 0, z = 0, num = 0;
+
+       for (x = 0; x < (len-1) && x < strlen(data);) {
+               if (data[x] == '$') {
+                       x++;
+
+                       while (data[x] > 47 && data[x] < 58) {
+                               index[z++] = data[x];
+                               x++;
+                       }
+                       index[z++] = '\0';
+                       z = 0;
+                       num = atoi(index);
+                       
+                       if (pcre_copy_substring(field_data,
+                                                                       ovector,
+                                                                       match_count,
+                                                                       num,
+                                                                       replace,
+                                                                       sizeof(replace)) > 0) {
+                               unsigned int r;
+                               for (r = 0; r < strlen(replace); r++) {
+                                       substituted[y++] = replace[r];
+                               }
+                       }
+               } else {
+                       substituted[y++] = data[x];
+                       x++;
+               }
+       }
+       substituted[y++] = '\0';
+}
+
+static switch_caller_extension_t *dialplan_hunt(switch_core_session_t *session)
+{
+       switch_caller_profile_t *caller_profile;
+       switch_caller_extension_t *extension = NULL;
+       switch_channel_t *channel;
+       char *cf = "extensions.conf";
+       char *exten_name = NULL;
+       switch_xml_t cfg, xml, xcontext, xexten, xaction, xcond;
+       char *context = NULL;
+
+
+       channel = switch_core_session_get_channel(session);
+       if ((caller_profile = switch_channel_get_caller_profile(channel))) {
+               context = caller_profile->context ? caller_profile->context : "default";
+       } else {
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Obtaining Profile!\n");
+               return NULL;
+       }
+
+       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Processing %s->%s!\n", caller_profile->caller_id_name,
+                                                 caller_profile->destination_number);
+
+       
+       if (!(xml = switch_xml_open_cfg(cf, &cfg))) {
+               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;            
+       }
+       
+       if (!(xcontext = switch_xml_find_child(cfg, "context", "name", context))) {
+               if (!(xcontext = switch_xml_find_child(cfg, "context", "name", "global"))) {
+                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "context %s not found\n", context);
+                       switch_channel_hangup(channel, SWITCH_CAUSE_MESSAGE_TYPE_NONEXIST);
+                       return NULL;
+               }
+       }
+       
+       for (xexten = switch_xml_child(xcontext, "extension"); xexten; xexten = xexten->next) {
+               int proceed = 0;
+               char *cont = (char *) switch_xml_attr(xexten, "continue");
+
+               for (xcond = switch_xml_child(xexten, "condition"); xcond; xcond = xcond->next) {
+                       char *field = (char *) switch_xml_attr(xcond, "field");
+                       char *expression = (char *) switch_xml_attr(xcond, "expression");
+                       char *field_data = switch_caller_get_field_by_name(caller_profile, field);
+                       pcre *re = NULL;
+                       int ovector[30];
+                       
+                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "test conditions %s(%s) =~ /%s/\n", field, field_data, expression);
+                       if (!(proceed = perform_regex(channel, field_data, expression, &re, ovector, sizeof(ovector) / sizeof(ovector[0])))) {
+                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Regex mismatch\n");
+                               break;
+                       }
+
+                       assert(re != NULL);
+
+                       for (xaction = switch_xml_child(xcond, "action"); xaction; xaction = xaction->next) {
+                               char *application = (char*) switch_xml_attr(xaction, "application");
+                               char *data = (char *) switch_xml_attr(xaction, "data");
+                               char substituted[1024] = "";
+                               char *app_data = NULL;
+                               
+                               if (strchr(expression, '(')) {
+                                       perform_substitution(re, proceed, data, field_data, substituted, sizeof(substituted), ovector);
+                                       app_data = substituted;
+                               } else {
+                                       app_data = data;
+                               }
+
+                               if (!extension) {
+                                       if ((extension =
+                                                switch_caller_extension_new(session, exten_name, caller_profile->destination_number)) == 0) {
+                                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "memory error!\n");
+                                               return NULL;
+                                       }
+                               }
+
+                               switch_caller_extension_add_application(session, extension, application, app_data);
+                       }
+
+                       cleanre(re);
+               }
+               
+               if (proceed && !switch_true(cont)) {
+                       break;
+               }
+       }
+
+
+       switch_xml_free(xml);
+
+       if (extension) {
+               switch_channel_set_state(channel, CS_EXECUTE);
+       } else {
+               switch_channel_hangup(channel, SWITCH_CAUSE_MESSAGE_TYPE_NONEXIST);
+       }
+
+       return extension;
+}
+
+
+static const switch_dialplan_interface_t dialplan_interface = {
+       /*.interface_name = */ "XML",
+       /*.hunt_function = */ dialplan_hunt
+       /*.next = NULL */
+};
+
+static const switch_loadable_module_interface_t dialplan_module_interface = {
+       /*.module_name = */ modname,
+       /*.endpoint_interface = */ NULL,
+       /*.timer_interface = */ NULL,
+       /*.dialplan_interface = */ &dialplan_interface,
+       /*.codec_interface = */ NULL,
+       /*.application_interface = */ NULL
+};
+
+SWITCH_MOD_DECLARE(switch_status_t) switch_module_load(const switch_loadable_module_interface_t **module_interface, char *filename)
+{
+
+       /* connect my internal structure to the blank pointer passed to me */
+       *module_interface = &dialplan_module_interface;
+
+       /* indicate that the module should continue to be loaded */
+       return SWITCH_STATUS_SUCCESS;
+}
diff --git a/src/mod/dialplans/mod_dialplan_xml/mod_dialplan_xml.vcproj b/src/mod/dialplans/mod_dialplan_xml/mod_dialplan_xml.vcproj
new file mode 100644 (file)
index 0000000..3c5811d
--- /dev/null
@@ -0,0 +1,212 @@
+<?xml version="1.0" encoding="Windows-1252"?>\r
+<VisualStudioProject\r
+       ProjectType="Visual C++"\r
+       Version="8.00"\r
+       Name="mod_dialplan_xml"\r
+       ProjectGUID="{07113B25-D3AF-4E04-BA77-4CD1171F022C}"\r
+       RootNamespace="mod_dialplan_xml"\r
+       Keyword="Win32Proj"\r
+       >\r
+       <Platforms>\r
+               <Platform\r
+                       Name="Win32"\r
+               />\r
+       </Platforms>\r
+       <ToolFiles>\r
+       </ToolFiles>\r
+       <Configurations>\r
+               <Configuration\r
+                       Name="Debug|Win32"\r
+                       OutputDirectory="Debug"\r
+                       IntermediateDirectory="Debug"\r
+                       ConfigurationType="2"\r
+                       InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
+                       CharacterSet="2"\r
+                       >\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"\r
+                               CommandLine="cscript /nologo $(InputDir)..\..\..\..\w32\vsnet\getlibs.vbs Mod_dialplan_xml Debug"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="0"\r
+                               AdditionalIncludeDirectories="&quot;$(InputDir)..\..\..\include&quot;;&quot;$(InputDir)include&quot;;&quot;$(InputDir)..\..\..\..\libs\include&quot;;&quot;$(InputDir)..\..\..\..\libs\pcre&quot;;&quot;$(InputDir)..\..\..\..\libs\pcre\win32&quot;"\r
+                               PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS;PCRE_STATIC"\r
+                               MinimalRebuild="true"\r
+                               BasicRuntimeChecks="3"\r
+                               RuntimeLibrary="1"\r
+                               UsePrecompiledHeader="0"\r
+                               WarningLevel="4"\r
+                               WarnAsError="true"\r
+                               Detect64BitPortabilityProblems="true"\r
+                               DebugInformationFormat="4"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManagedResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               AdditionalDependencies="libpcre.lib"\r
+                               OutputFile="..\..\..\..\w32\vsnet\$(OutDir)/mod/mod_dialplan_xml.dll"\r
+                               LinkIncremental="2"\r
+                               AdditionalLibraryDirectories="$(InputDir)..\..\..\..\libs\pcre\win32\$(OutDir);..\..\..\..\w32\vsnet\$(OutDir)"\r
+                               GenerateDebugInformation="true"\r
+                               ProgramDatabaseFile="$(OutDir)/mod_dialplan_xml.pdb"\r
+                               SubSystem="2"\r
+                               ImportLibrary="$(OutDir)/mod_dialplan_xml.lib"\r
+                               TargetMachine="1"\r
+                       />\r
+                       <Tool\r
+                               Name="VCALinkTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManifestTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXDCMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCBscMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCFxCopTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCAppVerifierTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebDeploymentTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                       />\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="Release|Win32"\r
+                       OutputDirectory="Release"\r
+                       IntermediateDirectory="Release"\r
+                       ConfigurationType="2"\r
+                       InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
+                       CharacterSet="2"\r
+                       >\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"\r
+                               CommandLine="cscript /nologo $(InputDir)..\..\..\..\w32\vsnet\getlibs.vbs Mod_dialplan_xml Release"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               AdditionalIncludeDirectories="&quot;$(InputDir)..\..\..\include&quot;;&quot;$(InputDir)include&quot;;&quot;$(InputDir)..\..\..\..\libs\include&quot;;&quot;$(InputDir)..\..\..\..\libs\pcre&quot;;&quot;$(InputDir)..\..\..\..\libs\pcre\win32&quot;"\r
+                               PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS;PCRE_STATIC"\r
+                               RuntimeLibrary="0"\r
+                               UsePrecompiledHeader="0"\r
+                               WarningLevel="4"\r
+                               Detect64BitPortabilityProblems="true"\r
+                               DebugInformationFormat="3"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManagedResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               AdditionalDependencies="libpcre.lib"\r
+                               OutputFile="..\..\..\..\w32\vsnet\$(OutDir)/mod/mod_dialplan_xml.dll"\r
+                               LinkIncremental="1"\r
+                               AdditionalLibraryDirectories="$(InputDir)..\..\..\..\libs\pcre\win32\$(OutDir);..\..\..\..\w32\vsnet\$(OutDir)"\r
+                               GenerateDebugInformation="true"\r
+                               SubSystem="2"\r
+                               OptimizeReferences="2"\r
+                               EnableCOMDATFolding="2"\r
+                               ImportLibrary="$(OutDir)/mod_dialplan_xml.lib"\r
+                               TargetMachine="1"\r
+                       />\r
+                       <Tool\r
+                               Name="VCALinkTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManifestTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXDCMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCBscMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCFxCopTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCAppVerifierTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebDeploymentTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                       />\r
+               </Configuration>\r
+       </Configurations>\r
+       <References>\r
+       </References>\r
+       <Files>\r
+               <Filter\r
+                       Name="Source Files"\r
+                       Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"\r
+                       UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"\r
+                       >\r
+                       <File\r
+                               RelativePath=".\mod_dialplan_xml.c"\r
+                               >\r
+                       </File>\r
+               </Filter>\r
+               <Filter\r
+                       Name="Header Files"\r
+                       Filter="h;hpp;hxx;hm;inl;inc;xsd"\r
+                       UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"\r
+                       >\r
+               </Filter>\r
+               <Filter\r
+                       Name="Resource Files"\r
+                       Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"\r
+                       UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"\r
+                       >\r
+               </Filter>\r
+       </Files>\r
+       <Globals>\r
+       </Globals>\r
+</VisualStudioProject>\r