add mod_perl

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@740 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Anthony Minessale 2006-03-03 16:57:21 +00:00
parent 9d8a280cde
commit 32a7b3c2ca
11 changed files with 1929 additions and 58 deletions

View File

@ -219,6 +219,13 @@ SWITCH_DECLARE(switch_status) switch_channel_clear_flag(switch_channel *channel,
*/
SWITCH_DECLARE(switch_status) switch_channel_answer(switch_channel *channel);
/*!
\brief Indicate progress on a channel to attempt early media
\param channel channel to pre-answer
\return SWITCH_STATUS_SUCCESS
*/
SWITCH_DECLARE(switch_status) switch_channel_pre_answer(switch_channel *channel);
/*!
\brief add a state handler table to a given channel
\param channel channel on which to add the state handler table

View File

@ -271,6 +271,13 @@ SWITCH_DECLARE(void) switch_core_session_signal_state_change(switch_core_session
*/
SWITCH_DECLARE(char *) switch_core_session_get_uuid(switch_core_session *session);
/*!
\brief Locate a session based on it's uuiid
\param uuid_str the unique id of the session you want to find
\return the session or NULL
*/
SWITCH_DECLARE(switch_core_session *) switch_core_session_locate(char *uuid_str);
/*!
\brief Send a message to another session using it's uuid
\param uuid_str the unique id of the session you want to send a message to
@ -921,14 +928,6 @@ SWITCH_DECLARE(void) switch_core_launch_thread(void *(*func)(switch_thread *, vo
SWITCH_DECLARE(void) switch_core_set_globals(void);
///\}
#ifdef USE_PERL
/*!
\brief Execute some perl when compiled with perl support
\return SWITCH_STATUS_SUCCESS on success
*/
SWITCH_DECLARE(switch_status) switch_core_do_perl(char *txt);
#endif
/*!
\}
*/

View File

@ -46,7 +46,7 @@ static switch_loadable_module_interface skel_module_interface = {
/*.directory_interface */ NULL
};
switch_status switch_module_load(const switch_loadable_module_interface **interface, char *filename)
SWITCH_MOD_DECLARE(switch_status) switch_module_load(const switch_loadable_module_interface **interface, char *filename)
{
/* connect my internal structure to the blank pointer passed to me */
*interface = &skel_module_interface;
@ -56,3 +56,19 @@ switch_status switch_module_load(const switch_loadable_module_interface **interf
/* indicate that the module should continue to be loaded */
return SWITCH_STATUS_SUCCESS;
}
/*
Called when the system shuts down
SWITCH_MOD_DECLARE(switch_status) switch_module_shutdown(void)
{
return SWITCH_STATUS_SUCCESS;
}
*/
/*
If it exists, this is called in it's own thread when the module-load completes
SWITCH_MOD_DECLARE(switch_status) switch_module_shutdown(void)
{
return SWITCH_STATUS_SUCCESS;
}
*/

View File

@ -0,0 +1,46 @@
PERL =/usr/local/bin/perl
PERL_LIBDIR =-L$(shell perl -MConfig -e 'print $$Config{archlib}')/CORE
PERL_LIBS =$(shell perl -MConfig -e 'print $$Config{libs}')
CFLAGS += -DMULTIPLICITY $(shell $(PERL) -MExtUtils::Embed -e ccopts)
CFLAGS += -DEMBED_PERL
LDFLAGS += $(shell $(PERL) -MExtUtils::Embed -e ldopts)
LDFLAGS += $(shell $(PERL) -MConfig -e 'print $$Config{libs}')
OBJS += perlxsi.o
all: depends $(MODNAME).so fs_perl.so
.perlok:
@(${PERL} -V | grep -i usemultiplicity=define >/dev/null && echo Phew, You have the right perl.) \
|| ((echo Sorry, you need to compile perl with threads and multiplicity.&& exit 1))
@touch .perlok
perlxsi.c: .perlok
perl -MExtUtils::Embed -e xsinit
depends: perlxsi.c
%.o: %.c
$(CC) $(CFLAGS) -fPIC -c $< -o $@
reswig:
rm switch_swig_wrap.c
swig -DMULTIPLICITY -perl5 -module fs_perl switch_swig.c
switch_swig_wrap.o: switch_swig_wrap.c
$(CC) -w $(CFLAGS) -fPIC -c $< -o $@
fs_perl.so: $(MODNAME).so switch_swig_wrap.o switch_swig.o perlxsi.o
$(CC) $(SOLINK) -o fs_perl.so switch_swig_wrap.o switch_swig.o perlxsi.o $(LDFLAGS)
$(MODNAME).so: $(MODNAME).c $(MODNAME).o $(OBJS)
$(CC) $(SOLINK) -o $(MODNAME).so $(MODNAME).o $(OBJS) $(LDFLAGS)
clean:
rm -fr *.so *.o *~ perlxsi.c .perlok
install:
mkdir -p $(PREFIX)/perl
cp -f $(MODNAME).so $(PREFIX)/mod
cp -f fs_perl.so fs_perl.pm $(PREFIX)/perl

View File

@ -0,0 +1,11 @@
package fs_perl;
use Data::Dumper;
sub wazzup() {
fs_console_log("WOOHOO!\n");
$session = fs_core_session_locate($SWITCH_ENV{UUID});
fs_channel_answer($session);
fs_ivr_play_file($session, "/root/siriusraw.raw", "");
}
1;

View File

@ -0,0 +1,63 @@
# This file was automatically generated by SWIG
package fs_perl;
require Exporter;
require DynaLoader;
@ISA = qw(Exporter DynaLoader);
package fs_perlc;
bootstrap fs_perl;
package fs_perl;
@EXPORT = qw( );
# ---------- BASE METHODS -------------
package fs_perl;
sub TIEHASH {
my ($classname,$obj) = @_;
return bless $obj, $classname;
}
sub CLEAR { }
sub FIRSTKEY { }
sub NEXTKEY { }
sub FETCH {
my ($self,$field) = @_;
my $member_func = "swig_${field}_get";
$self->$member_func();
}
sub STORE {
my ($self,$field,$newval) = @_;
my $member_func = "swig_${field}_set";
$self->$member_func($newval);
}
sub this {
my $ptr = shift;
return tied(%$ptr);
}
# ------- FUNCTION WRAPPERS --------
package fs_perl;
*fs_console_log = *fs_perlc::fs_console_log;
*fs_console_clean = *fs_perlc::fs_console_clean;
*fs_core_session_locate = *fs_perlc::fs_core_session_locate;
*fs_channel_answer = *fs_perlc::fs_channel_answer;
*fs_channel_pre_answer = *fs_perlc::fs_channel_pre_answer;
*fs_channel_hangup = *fs_perlc::fs_channel_hangup;
*fs_channel_set_variable = *fs_perlc::fs_channel_set_variable;
*fs_channel_get_variable = *fs_perlc::fs_channel_get_variable;
*fs_channel_set_state = *fs_perlc::fs_channel_set_state;
*fs_ivr_play_file = *fs_perlc::fs_ivr_play_file;
# ------- VARIABLE STUBS --------
package fs_perl;
1;

View File

@ -0,0 +1,132 @@
/*
* 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_perl.c -- Perl
*
*/
#include <switch.h>
#include <EXTERN.h>
#include <perl.h>
static char *embedding[] = { "", "-e", "" };
EXTERN_C void xs_init(pTHX);
static const char modname[] = "mod_perl";
static struct {
PerlInterpreter *my_perl;
} globals;
static void destroy_perl(PerlInterpreter **to_destroy)
{
perl_destruct(*to_destroy);
perl_free(*to_destroy);
*to_destroy = NULL;
}
static PerlInterpreter *clone_perl(void)
{
return perl_clone(globals.my_perl, CLONEf_COPY_STACKS|CLONEf_KEEP_PTR_TABLE);
}
static void perl_function(switch_core_session *session, char *data)
{
char *uuid = switch_core_session_get_uuid(session);
char code[1024];
PerlInterpreter *my_perl = clone_perl();
sprintf(code, "package fs_perl;\n"
"$SWITCH_ENV{UUID} = \"%s\";\n"
"chdir(\"%s/perl\");\n",
uuid, SWITCH_GLOBAL_dirs.base_dir);
Perl_eval_pv(my_perl, code, TRUE);
Perl_eval_pv(my_perl, data, TRUE);
destroy_perl(&my_perl);
}
static const switch_application_interface perl_application_interface = {
/*.interface_name */ "perl",
/*.application_function */ perl_function
};
static switch_loadable_module_interface perl_module_interface = {
/*.module_name */ modname,
/*.endpoint_interface */ NULL,
/*.timer_interface */ NULL,
/*.dialplan_interface */ NULL,
/*.codec_interface */ NULL,
/*.application_interface */ &perl_application_interface,
/*.api_interface */ NULL,
/*.file_interface */ NULL,
/*.speech_interface */ NULL,
/*.directory_interface */ NULL
};
SWITCH_MOD_DECLARE(switch_status) switch_module_shutdown(void)
{
if (globals.my_perl) {
perl_destruct(globals.my_perl);
perl_free(globals.my_perl);
globals.my_perl = NULL;
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Unallocated perl interpreter.\n");
}
return SWITCH_STATUS_SUCCESS;
}
SWITCH_MOD_DECLARE(switch_status) switch_module_load(const switch_loadable_module_interface **interface, char *filename)
{
PerlInterpreter *my_perl;
char code[1024];
if (!(my_perl = perl_alloc())) {
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Could not allocate perl intrepreter\n");
switch_core_destroy();
return SWITCH_STATUS_MEMERR;
}
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Allocated perl intrepreter.\n");
PERL_SET_CONTEXT(my_perl);
perl_construct(my_perl);
perl_parse(my_perl, xs_init, 3, embedding, NULL);
perl_run(my_perl);
globals.my_perl = my_perl;
sprintf(code, "use lib '%s/perl';use fs_perl;use freeswitch\n", SWITCH_GLOBAL_dirs.base_dir);
Perl_eval_pv(my_perl, code, TRUE);
/* connect my internal structure to the blank pointer passed to me */
*interface = &perl_module_interface;
/* indicate that the module should continue to be loaded */
return SWITCH_STATUS_SUCCESS;
}

View File

@ -0,0 +1,68 @@
#include <switch.h>
void fs_console_log(char *msg)
{
switch_console_printf(SWITCH_CHANNEL_CONSOLE, msg);
}
void fs_console_clean(char *msg)
{
switch_console_printf(SWITCH_CHANNEL_CONSOLE_CLEAN, msg);
}
struct switch_core_session *fs_core_session_locate(char *uuid)
{
return switch_core_session_locate(uuid);
}
void fs_channel_answer(struct switch_core_session *session)
{
switch_channel *channel = switch_core_session_get_channel(session);
switch_channel_answer(channel);
}
void fs_channel_pre_answer(struct switch_core_session *session)
{
switch_channel *channel = switch_core_session_get_channel(session);
switch_channel_pre_answer(channel);
}
void fs_channel_hangup(struct switch_core_session *session)
{
switch_channel *channel = switch_core_session_get_channel(session);
switch_channel_hangup(channel);
}
void fs_channel_set_variable(struct switch_core_session *session, char *var, char *val)
{
switch_channel *channel = switch_core_session_get_channel(session);
switch_channel_set_variable(channel, var, val);
}
void fs_channel_get_variable(struct switch_core_session *session, char *var)
{
switch_channel *channel = switch_core_session_get_channel(session);
switch_channel_get_variable(channel, var);
}
void fs_channel_set_state(struct switch_core_session *session, char *state)
{
switch_channel *channel = switch_core_session_get_channel(session);
switch_channel_state fs_state = switch_channel_get_state(channel);
if (!strcmp(state, "EXECUTE")) {
fs_state = CS_EXECUTE;
} else if (!strcmp(state, "TRANSMIT")) {
fs_state = CS_TRANSMIT;
}
switch_channel_set_state(channel, fs_state);
}
int fs_ivr_play_file(struct switch_core_session *session, char *file, char *timer_name_in)
{
char *timer_name = switch_strlen_zero(timer_name_in) ? NULL : timer_name;
switch_status status = switch_ivr_play_file(session, NULL, file, timer_name, NULL, NULL, 0);
return status == SWITCH_STATUS_SUCCESS ? 1 : 0;
}

File diff suppressed because it is too large Load Diff

View File

@ -565,6 +565,21 @@ SWITCH_DECLARE(switch_status) switch_channel_hangup(switch_channel *channel)
return channel->state;
}
SWITCH_DECLARE(switch_status) switch_channel_pre_answer(switch_channel *channel)
{
switch_core_session_message msg;
char *uuid = switch_core_session_get_uuid(channel->session);
switch_status status;
assert(channel != NULL);
msg.message_id = SWITCH_MESSAGE_INDICATE_PROGRESS;
msg.from = channel->name;
status = switch_core_session_message_send(uuid, &msg);
switch_channel_set_flag(channel, CF_EARLY_MEDIA);
return status;
}
SWITCH_DECLARE(switch_status) switch_channel_answer(switch_channel *channel)
{
assert(channel != NULL);

View File

@ -31,14 +31,6 @@
*/
#include <switch.h>
#ifdef EMBED_PERL
#include <EXTERN.h>
#include <perl.h>
static char *embedding[] = { "", "-e", "" };
EXTERN_C void xs_init(pTHX);
#endif
struct switch_core_session {
unsigned long id;
char name[80];
@ -87,9 +79,6 @@ struct switch_core_runtime {
switch_core_db *db;
const struct switch_state_handler_table *state_handlers[SWITCH_MAX_STATE_HANDLERS];
int state_handler_index;
#ifdef EMBED_PERL
PerlInterpreter *my_perl;
#endif
FILE *console;
};
@ -163,17 +152,6 @@ SWITCH_DECLARE(FILE *) switch_core_data_channel(switch_text_channel channel)
return handle;
}
#ifdef EMBED_PERL
/* test frontend to the perl interpreter */
SWITCH_DECLARE(switch_status) switch_core_do_perl(char *txt)
{
PerlInterpreter *my_perl = runtime.my_perl;
eval_pv(txt, TRUE);
return SWITCH_STATUS_SUCCESS;
}
#endif
SWITCH_DECLARE(int) switch_core_add_state_handler(const switch_state_handler_table *state_handler)
{
int index = runtime.state_handler_index++;
@ -196,6 +174,13 @@ SWITCH_DECLARE(const switch_state_handler_table *) switch_core_get_state_handler
return runtime.state_handlers[index];
}
SWITCH_DECLARE(switch_core_session *) switch_core_session_locate(char *uuid_str)
{
switch_core_session *session;
session = switch_core_hash_find(runtime.session_table, uuid_str);
return session;
}
SWITCH_DECLARE(switch_status) switch_core_session_message_send(char *uuid_str, switch_core_session_message *message)
{
switch_core_session *session = NULL;
@ -2230,9 +2215,6 @@ SWITCH_DECLARE(switch_status) switch_core_init(char *console)
switch_core_set_globals();
#ifdef EMBED_PERL
PerlInterpreter *my_perl;
#endif
if(console) {
if (*console != '/') {
char path[265];
@ -2274,21 +2256,6 @@ SWITCH_DECLARE(switch_status) switch_core_init(char *console)
}
}
#ifdef EMBED_PERL
if (!(my_perl = perl_alloc())) {
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Could not allocate perl intrepreter\n");
switch_core_destroy();
return SWITCH_STATUS_MEMERR;
}
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Allocated perl intrepreter.\n");
PERL_SET_CONTEXT(my_perl);
perl_construct(my_perl);
perl_parse(my_perl, xs_init, 3, embedding, NULL);
perl_run(my_perl);
runtime.my_perl = my_perl;
#endif
runtime.session_id = 1;
switch_core_hash_init(&runtime.session_table, runtime.memory_pool);
@ -2301,15 +2268,6 @@ SWITCH_DECLARE(switch_status) switch_core_init(char *console)
SWITCH_DECLARE(switch_status) switch_core_destroy(void)
{
#ifdef EMBED_PERL
if (runtime.my_perl) {
perl_destruct(runtime.my_perl);
perl_free(runtime.my_perl);
runtime.my_perl = NULL;
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Unallocated perl interpreter.\n");
}
#endif
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Closing Event Engine.\n");
switch_event_shutdown();