--- /dev/null
+/*
+ * 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_event_multicast.c -- Multicast Events
+ *
+ */
+#include <switch.h>
+
+static const char modname[] = "mod_event_multicast";
+
+static switch_memory_pool *module_pool;
+
+static struct {
+ char *address;
+ int port;
+ switch_sockaddr_t *addr;
+ switch_socket_t *udp_socket;
+ int running;
+} globals;
+
+SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_address, globals.address)
+
+#define MULTICAST_EVENT "multicast::event"
+
+
+static switch_status load_config(void)
+{
+ switch_config cfg;
+ switch_status status = SWITCH_STATUS_SUCCESS;
+ char *var, *val;
+ char *cf = "event_multicast.conf";
+
+ if (!switch_config_open_file(&cfg, cf)) {
+ switch_console_printf(SWITCH_CHANNEL_CONSOLE, "open of %s failed\n", cf);
+ return SWITCH_STATUS_TERM;
+ }
+
+ if (switch_event_reserve_subclass(MULTICAST_EVENT) != SWITCH_STATUS_SUCCESS) {
+ switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Couldn't register subclass!");
+ return SWITCH_STATUS_GENERR;
+ }
+
+ while (switch_config_next_pair(&cfg, &var, &val)) {
+ if (!strcasecmp(cfg.category, "settings")) {
+ if (!strcasecmp(var, "address")) {
+ set_global_address(val);
+ } else if (!strcasecmp(var, "port")) {
+ globals.port = atoi(val);
+ }
+ }
+ }
+
+ switch_config_close_file(&cfg);
+
+ return status;
+
+}
+
+static void event_handler(switch_event *event)
+{
+ char buf[1024];
+ int len;
+
+ if (event->subclass && !strcmp(event->subclass->name, MULTICAST_EVENT)) {
+ /* ignore our own events to avoid ping pong*/
+ return;
+ }
+
+
+ switch (event->event_id) {
+ case SWITCH_EVENT_LOG:
+ return;
+ break;
+ default:
+ switch_event_serialize(event, buf, sizeof(buf), NULL);
+ len = strlen(buf);
+ //switch_console_printf(SWITCH_CHANNEL_CONSOLE, "\nEVENT\n--------------------------------\n%s\n", buf);
+ switch_socket_sendto(globals.udp_socket, globals.addr, 0, buf, &len);
+ 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
+};
+
+
+SWITCH_MOD_DECLARE(switch_status) switch_module_load(const switch_loadable_module_interface **interface, char *filename)
+{
+ memset(&globals, 0, sizeof(globals));
+
+ if (load_config() != SWITCH_STATUS_SUCCESS) {
+ switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Cannot Configure\n");
+ return SWITCH_STATUS_TERM;
+ }
+
+ 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;
+ }
+
+ if (switch_sockaddr_info_get(&globals.addr, globals.address, SWITCH_UNSPEC, globals.port, 0, module_pool) != SWITCH_STATUS_SUCCESS) {
+ switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Cannot find address\n");
+ return SWITCH_STATUS_TERM;
+ }
+
+ if (switch_socket_create(&globals.udp_socket, AF_INET, SOCK_DGRAM, 0, module_pool) != SWITCH_STATUS_SUCCESS) {
+ switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Socket Error\n");
+ return SWITCH_STATUS_TERM;
+ }
+
+ if (switch_socket_opt_set(globals.udp_socket, SWITCH_SO_REUSEADDR, 1) != SWITCH_STATUS_SUCCESS) {
+ switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Socket Option Error\n");
+ switch_socket_close(globals.udp_socket);
+ return SWITCH_STATUS_TERM;
+ }
+
+ if (switch_mcast_join(globals.udp_socket, globals.addr, NULL, NULL) != SWITCH_STATUS_SUCCESS) {
+ switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Multicast Error\n");
+ switch_socket_close(globals.udp_socket);
+ return SWITCH_STATUS_TERM;
+ }
+
+ if (switch_socket_bind(globals.udp_socket, globals.addr) != SWITCH_STATUS_SUCCESS) {
+ switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Bind Error\n");
+ switch_socket_close(globals.udp_socket);
+ return SWITCH_STATUS_TERM;
+ }
+
+
+ /* connect my internal structure to the blank pointer passed to me */
+ *interface = &event_test_module_interface;
+
+ 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");
+ switch_socket_close(globals.udp_socket);
+ return SWITCH_STATUS_GENERR;
+ }
+
+ /* indicate that the module should continue to be loaded */
+ return SWITCH_STATUS_SUCCESS;
+}
+
+
+SWITCH_MOD_DECLARE(switch_status) switch_module_shutdown(void)
+{
+ int x = 0;
+
+ switch_socket_shutdown(globals.udp_socket, APR_SHUTDOWN_READWRITE);
+ globals.running = -1;
+ while(x < 100000 && globals.running) {
+ x++;
+ switch_yield(1000);
+ }
+ return SWITCH_STATUS_SUCCESS;
+}
+
+
+SWITCH_MOD_DECLARE(switch_status) switch_module_runtime(void)
+{
+ switch_event *local_event;
+ switch_status status;
+ char buf[1024];
+
+ globals.running = 1;
+ while(globals.running == 1) {
+ switch_sockaddr_t addr = {0};
+ int len = sizeof(buf);
+ memset(buf, 0, len);
+ if ((status = switch_socket_recvfrom(&addr, globals.udp_socket, 0, buf, &len)) == SWITCH_STATUS_SUCCESS) {
+ if (switch_event_create_subclass(&local_event, SWITCH_EVENT_CUSTOM, MULTICAST_EVENT) == SWITCH_STATUS_SUCCESS) {
+ char *var, *val, *term = NULL;
+ switch_event_add_header(local_event, SWITCH_STACK_BOTTOM, "Multicast", "yes");
+ var = buf;
+ while(*var) {
+ if ((val = strchr(var, ':'))) {
+ char varname[512];
+ *val++ = '\0';
+ while(*val == ' ') {
+ val++;
+ }
+ if ((term = strchr(val, '\r')) || (term=strchr(val, '\n'))) {
+ *term = '\0';
+ while(*term == '\r' || *term == '\n') {
+ term++;
+ }
+ }
+ snprintf(varname, sizeof(varname), "Remote-%s", var);
+ switch_event_add_header(local_event, SWITCH_STACK_BOTTOM, varname, val);
+ var = term + 1;
+ } else {
+ break;
+ }
+ }
+
+ switch_event_fire(&local_event);
+ }
+ }
+
+ }
+
+ globals.running = 0;
+ return SWITCH_STATUS_TERM;
+}
+
+
+
--- /dev/null
+<?xml version="1.0" encoding="Windows-1252"?>\r
+<VisualStudioProject\r
+ ProjectType="Visual C++"\r
+ Version="8.00"\r
+ Name="mod_event_multicast"\r
+ ProjectGUID="{3A2A7795-C216-4FFF-B8EF-4D17A84BACCC}"\r
+ RootNamespace="mod_event_multicast"\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
+ />\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=""$(InputDir)..\..\..\include";"$(InputDir)include";"$(InputDir)..\..\..\..\libs\include""\r
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS"\r
+ MinimalRebuild="true"\r
+ BasicRuntimeChecks="3"\r
+ RuntimeLibrary="1"\r
+ UsePrecompiledHeader="0"\r
+ WarningLevel="3"\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
+ OutputFile="..\..\..\..\w32\vsnet\$(OutDir)/mod/mod_event_multicast.dll"\r
+ LinkIncremental="2"\r
+ AdditionalLibraryDirectories="$(InputDir)..\..\..\libs\apr\Debug"\r
+ GenerateDebugInformation="true"\r
+ ProgramDatabaseFile="$(OutDir)/mod_event_multicast.pdb"\r
+ SubSystem="2"\r
+ ImportLibrary="$(OutDir)/mod_event_multicast.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
+ />\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=""$(InputDir)..\..\..\include";"$(InputDir)include";"$(InputDir)..\..\..\..\libs\include""\r
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS"\r
+ RuntimeLibrary="0"\r
+ UsePrecompiledHeader="0"\r
+ WarningLevel="3"\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
+ OutputFile="..\..\..\..\w32\vsnet\$(OutDir)/mod/mod_event_multicast.dll"\r
+ LinkIncremental="1"\r
+ AdditionalLibraryDirectories=""$(InputDir)..\..\..\libs\apr\Release""\r
+ GenerateDebugInformation="true"\r
+ SubSystem="2"\r
+ OptimizeReferences="2"\r
+ EnableCOMDATFolding="2"\r
+ ImportLibrary="$(OutDir)/mod_event_multicast.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_event_multicast.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