From ebfc333dc63e1763c9ace85b02adb3167372746b Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 14 Feb 2006 21:18:27 +0000 Subject: [PATCH] add files to go with previous commit git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@617 d0543943-73ff-0310-b7d9-9358b9ac24b2 --- conf/event_multicast.conf | 3 + scripts/multicast/recv.pl | 12 + scripts/multicast/send.pl | 15 ++ .../mod_event_multicast/mod_event_multicast.c | 239 ++++++++++++++++++ .../mod_event_multicast.vcproj | 207 +++++++++++++++ 5 files changed, 476 insertions(+) create mode 100644 conf/event_multicast.conf create mode 100644 scripts/multicast/recv.pl create mode 100755 scripts/multicast/send.pl create mode 100644 src/mod/event_handlers/mod_event_multicast/mod_event_multicast.c create mode 100644 src/mod/event_handlers/mod_event_multicast/mod_event_multicast.vcproj diff --git a/conf/event_multicast.conf b/conf/event_multicast.conf new file mode 100644 index 0000000000..48087dcfb8 --- /dev/null +++ b/conf/event_multicast.conf @@ -0,0 +1,3 @@ +[settings] +address => 225.0.0.37 +port => 12345 diff --git a/scripts/multicast/recv.pl b/scripts/multicast/recv.pl new file mode 100644 index 0000000000..ec55daf840 --- /dev/null +++ b/scripts/multicast/recv.pl @@ -0,0 +1,12 @@ +use IO::Socket::Multicast; +my ($ip,$port) = @ARGV; + +$ip and $port or die "Usage $0: \n"; + +# create a new UDP socket and add a multicast group +my $socket = IO::Socket::Multicast->new( LocalPort => $port, ReuseAddr => 1 ); +$socket->mcast_add($ip); + +while($socket->recv($data,1024)) { + print $data; +} diff --git a/scripts/multicast/send.pl b/scripts/multicast/send.pl new file mode 100755 index 0000000000..047c70d6cb --- /dev/null +++ b/scripts/multicast/send.pl @@ -0,0 +1,15 @@ +#!/usr/local/bin/perl +use IO::Socket::INET; + +my ($ip, $port, $file) = @ARGV; + +$ip and $port or die "Usage $0: \n"; + +$socket = new IO::Socket::INET->new( PeerPort => $port, + Proto => 'udp', + PeerAddr => $ip); + +my $buf = `cat $file`; + +$socket->send("$buf\n"); + diff --git a/src/mod/event_handlers/mod_event_multicast/mod_event_multicast.c b/src/mod/event_handlers/mod_event_multicast/mod_event_multicast.c new file mode 100644 index 0000000000..2884788fcd --- /dev/null +++ b/src/mod/event_handlers/mod_event_multicast/mod_event_multicast.c @@ -0,0 +1,239 @@ +/* + * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * Copyright (C) 2005/2006, 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 + * + * + * mod_event_multicast.c -- Multicast Events + * + */ +#include + +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; +} + + + diff --git a/src/mod/event_handlers/mod_event_multicast/mod_event_multicast.vcproj b/src/mod/event_handlers/mod_event_multicast/mod_event_multicast.vcproj new file mode 100644 index 0000000000..edf9f9d5f2 --- /dev/null +++ b/src/mod/event_handlers/mod_event_multicast/mod_event_multicast.vcproj @@ -0,0 +1,207 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +