add mod_perl
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@740 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
parent
9d8a280cde
commit
32a7b3c2ca
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
/*!
|
||||
\}
|
||||
*/
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
*/
|
||||
|
|
|
@ -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
|
|
@ -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;
|
|
@ -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;
|
|
@ -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;
|
||||
}
|
|
@ -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
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
Loading…
Reference in New Issue