提交 76dde4b6 authored 作者: Leon de Rooij's avatar Leon de Rooij
...@@ -143,6 +143,9 @@ class fs_directory extends fs_curl { ...@@ -143,6 +143,9 @@ class fs_directory extends fs_curl {
* @return void * @return void
*/ */
private function write_params($user_id) { private function write_params($user_id) {
if (!is_array($this->users_params)) {
return;
}
if (array_key_exists($user_id, $this->users_params) if (array_key_exists($user_id, $this->users_params)
&& is_array($this->users_params[$user_id]) && is_array($this->users_params[$user_id])
&& count($this->users_params[$user_id]) > 0) { && count($this->users_params[$user_id]) > 0) {
...@@ -187,6 +190,9 @@ class fs_directory extends fs_curl { ...@@ -187,6 +190,9 @@ class fs_directory extends fs_curl {
* @return void * @return void
*/ */
private function write_variables($user_id) { private function write_variables($user_id) {
if (!is_array($this->users_vars)) {
return;
}
if (array_key_exists($user_id, $this->users_vars) if (array_key_exists($user_id, $this->users_vars)
&& is_array($this->users_vars[$user_id])) { && is_array($this->users_vars[$user_id])) {
$this -> xmlw -> startElement('variables'); $this -> xmlw -> startElement('variables');
......
<?php
class phpivr {
public $stdin;
public $stderr;
public $stdout;
public $CHANNEL_DATA;
private $hungup = false;
public function __construct() {
$this->stderr = fopen ( 'php://stderr', 'w' );
$this->stdout = fopen ( 'php://stdout', 'w' );
$this->stdin = fopen ( 'php://stdin', 'r' );
$this->ivrd_connect ();
$this->CHANNEL_DATA = $this->recv ();
//$this->debug ( print_r ( $this->CHANNEL_DATA, true ) );
}
public function __destruct() {
$this->debug ( "in function " . __FUNCTION__ );
$this->ivrd_exit();
}
public function __call($method, $args) {
$this->debug ( "in function " . __FUNCTION__ );
$this->debug ( print_r ( $method, true ) );
$this->debug ( print_r ( $args, true ) );
$arg_string = '';
$arg_count = count ( $args );
for($i = 0; $i < $arg_count; $i ++) {
if ($i == 0) {
if (strstr ( $args[$i], ' ' )) {
$arg_string = sprintf ( "'%s'", $args[$i] );
} else {
$arg_string = sprintf ( '%s', $args[$i] );
}
} else {
if (strstr($args[$i], ' ') || empty($args[$i])) {
$arg_string = sprintf ( "%s '%s'", $arg_string, $args[$i] );
} else {
$arg_string = sprintf ( '%s %s', $arg_string, $args[$i] );
}
}
}
if (! preg_match ( '/^(app|api|bgapi|config|directory|dialplan)_(.*)$/', $method, $matches )) {
$this->debug ( "RegEx didn't match for[$method]" );
return false;
}
$this->debug ( print_r ( $matches, true ) );
$this->debug(sprintf("calling %s [%s] with args [%s]", $matches[1], $matches[2], $arg_string));
switch ($matches[1]) {
case 'app' :
return $this->execute ( $matches[2], $arg_string );
case 'api' :
return $this->api ( $matches[2], $arg_string );
case 'bgapi' :
return $this->bgapi ( $matches[2], $arg_string );
case 'config':
return $this->fetch_config($matches[2], $arg_string);
case 'directory':
return $this->fetch_directory($matches[2], $arg_string);
case 'dialplan':
return $this->fetch_dialplan($matches[2], $arg_string);
default:
return false;
}
}
public function ready() {
if ($this->hungup) {
return false;
}
return true;
}
public function ivrd_connect() {
$this->debug ( "in function " . __FUNCTION__ );
$this->send ( "connect" );
}
public function ivrd_exit() {
$this->debug ( "in function " . __FUNCTION__ );
$this->send ( "exit" );
}
public function debug($info) {
fwrite ( $this->stderr, "$info\n" );
}
public function console_log($loglevel, $logdata) {
$loglevel = strtoupper($loglevel);
switch ($loglevel) {
case 'ERROR':
$loglevel = 'ERR';
break;
case 'WARN':
$loglevel = 'WARNING';
break;
case 'CRITICAL':
$loglevel = 'CRIT';
break;
}
$this->execute('log', "$loglevel $logdata");
}
public function send($data) {
if (!$this->stdout || !is_resource($this->stdout)) {
return false;
}
$data .= "\n\n";
fwrite ( $this->stdout, "$data" );
}
public function recv() {
$event = new phpivr_event ();
while ( $line = trim ( fgets ( $this->stdin ) ) ) {
if (! strlen ( $line )) {
break;
}
if (strstr ( $line, ':' )) {
$line_parts = explode ( ':', $line );
$key = trim ( array_shift ( $line_parts ) );
$value = trim ( implode ( ':', $line_parts ) );
$event->$key = $value;
}
}
$content_len = $event->{'Content-Length'};
if (! empty ( $content_len )) {
$body = $this->recv_content_len ( $content_len );
$event->set_body ( $body );
}
return $event;
}
public function recv_content_len($content_len) {
//$this->debug ( "in function " . __FUNCTION__ );
$recv_len = 0;
$body = '';
while ( $recv_len < $content_len ) {
if ($content_len < 4096) {
$len = ($content_len + 1);
} else {
$remainder = ($content_len - $recv_len);
if ($remainder < 4096) {
$len = ($remainder + 1);
} else {
$len = 4096;
}
}
$body .= fgets ( $this->stdin, $len );
$recv_len = strlen ( $body );
}
return $body;
}
public function send_msg($msg_data) {
//$this->debug ( "in function " . __FUNCTION__ );
$msg = sprintf ( "SendMsg %s\n%s\n", $this->CHANNEL_DATA->{"Unique-ID"}, $msg_data );
$this->send ( $msg );
return $this->recv ();
}
public function execute($app, $args) {
//$this->debug ( "in function " . __FUNCTION__ );
$msg = sprintf ( "call-command: execute\n" );
$msg .= sprintf ( "execute-app-name: %s\n", $app );
$msg .= sprintf ( "execute-app-arg: %s\n", $args );
$this->send_msg ( $msg );
}
public function api($api, $args) {
$api_cmd = sprintf ( 'api %s %s', $api, $args );
$this->send ( $api_cmd );
$event = $this->recv ();
$body = $event->get_body ();
return $body;
}
public function bgapi($api, $args) {
$api_cmd = sprintf ( 'bgapi %s %s', $api, $args );
$this->send ( $api_cmd );
$event = $this->recv ();
$body = $event->get_body ();
return $body;
}
public function fetch_config($config) {
$xml = $this->api_xml_locate('configuration', 'configuration', 'name', "$config.conf");
return new SimpleXMLElement($xml);
}
public function fetch_dialplan() {
$xml = $this->api_xml_locate();
return new SimpleXMLElement($xml);
}
public function fetch_directory() {
$xml = $this->api_xml_locate();
return new SimpleXMLElement($xml);
}
public function fetch_user($ext, $domain) {
$xml = $this->api_find_user_xml ( 'id', $ext, $domain );
return new SimpleXMLElement ( $xml );
}
public function app_play_and_get_digits($min, $max, $tries, $time, $terminators, $file, $errfile, $var, $re) {
$this->execute ( 'play_and_get_digits', "$min $max $tries $time $terminators $file $errfile $var $re" );
$uuid = $this->CHANNEL_DATA->{"Unique-ID"};
$this->debug ( "Var:[$var]" );
$digits = $this->api_uuid_getvar ( $uuid, $var );
return $digits;
}
public function var_undef($var) {
if (empty($var)) {
$this->debug('var is empty');
return true;
}
if ($var == '_undef_') {
$this->debug('var is _undef_');
return true;
}
}
public function app_hangup() {
$this->hungup = true;
$this->execute('app_hangup');
}
}
class phpivr_event {
private $stdin;
private $stdout;
private $stderr;
private $headers;
private $body;
public function __construct() {
$this->headers = new stdClass();
$this->stderr = fopen ( 'php://stderr', 'w' );
$this->stdout = fopen ( 'php://stdout', 'w' );
$this->stdin = fopen ( 'php://stdin', 'r' );
}
public function __get($item) {
$this->debug ( "in function " . __FUNCTION__ );
if (! empty ( $this->headers->$item )) {
return $this->headers->$item;
}
}
public function __set($item, $value) {
$this->debug ( "in function " . __FUNCTION__ );
$value = trim ( rawurldecode ( $value ) );
$this->debug ( "setting[$item] to[$value]" );
$this->headers->$item = $value;
}
public function get_headers() {
$this->debug ( "in function " . __FUNCTION__ );
return $this->headers;
}
public function set_body($body) {
$this->debug ( "in function " . __FUNCTION__ );
$this->debug ( "Setting Body to[$body]" );
$this->body = $body;
}
public function get_body() {
$this->debug ( "in function " . __FUNCTION__ );
$body = $this->body;
return $body;
}
public function debug($info) {
fwrite ( $this->stderr, "$info\n" );
}
}
差异被折叠。
PWD=$(shell pwd)
INCS=-I$(PWD)/src/include
LIBEDIT_DIR=../../libs/libedit
DEBUG=-g -ggdb
BASE_FLAGS=$(INCS) -DHAVE_EDITLINE $(DEBUG) -I$(LIBEDIT_DIR)/src/ -fPIC
PICKY=-O2 -ffast-math -Wall -Wunused-variable -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes
CFLAGS=$(BASE_FLAGS) $(PICKY)
CXXFLAGS=$(BASE_FLAGS) -Wall -Wno-unused-variable
MYLIB=libesl.a
LIBS=-lncurses -lpthread -lesl
LDFLAGS=-L.
OBJS=src/esl.o src/esl_event.o src/esl_threadmutex.o src/esl_config.o
SRC=src/esl.c src/esl_event.c src/esl_threadmutex.c src/esl_config.c src/esl_oop.cpp
HEADERS=src/include/esl_config.h src/include/esl_event.h src/include/esl.h src/include/esl_threadmutex.h src/include/esl_oop.h
SOLINK=-shared -Xlinker -x
# comment the next line to disable c++ (no swig mods for you then)
OBJS += src/esl_oop.o
all: $(MYLIB) fs_cli testclient testserver ivrd eventsd
$(MYLIB): $(OBJS) $(HEADERS) $(SRC)
ar rcs $(MYLIB) $(OBJS)
ranlib $(MYLIB)
testserver: $(MYLIB) testserver.c
$(CC) $(CC_CFLAGS) $(CFLAGS) testserver.c -o testserver $(LDFLAGS) $(LIBS)
ivrd: $(MYLIB) ivrd.c
$(CC) $(CC_CFLAGS) $(CFLAGS) ivrd.c -o ivrd $(LDFLAGS) $(LIBS)
eventsd: $(MYLIB) eventsd.c
$(CC) $(CC_CFLAGS) $(CFLAGS) eventsd.c -o fs_eventsd $(LDFLAGS) $(LIBS)
testclient: $(MYLIB) testclient.c
$(CC) $(CC_CFLAGS) $(CFLAGS) testclient.c -o testclient $(LDFLAGS) $(LIBS)
fs_cli: $(MYLIB) fs_cli.c
$(CC) $(CC_CFLAGS) $(CFLAGS) fs_cli.c -o fs_cli $(LDFLAGS) -L$(LIBEDIT_DIR)/src/.libs $(LIBS) -ledit
%.o: %.c
$(CC) $(CC_CFLAGS) $(CFLAGS) -c $< -o $@
%.o: %.cpp
$(CXX) $(CXX_CFLAGS) $(CXXFLAGS) -c $< -o $@
clean:
rm -f *.o src/*.o testclient testserver ivrd fs_cli libesl.a *~ src/*~ src/include/*~
$(MAKE) -C perl clean
$(MAKE) -C php clean
$(MAKE) -C lua clean
$(MAKE) -C python clean
$(MAKE) -C ruby clean
$(MAKE) -C java clean
$(MAKE) -C managed clean
reswig: swigclean
$(MAKE) -C perl reswig
$(MAKE) -C php reswig
$(MAKE) -C lua reswig
$(MAKE) -C python reswig
$(MAKE) -C ruby reswig
$(MAKE) -C java reswig
$(MAKE) -C managed reswig
swigclean: clean
$(MAKE) -C perl swigclean
$(MAKE) -C php swigclean
$(MAKE) -C lua swigclean
$(MAKE) -C python swigclean
$(MAKE) -C ruby swigclean
$(MAKE) -C java swigclean
$(MAKE) -C managed swigclean
perlmod: $(MYLIB)
$(MAKE) MYLIB="../$(MYLIB)" SOLINK="$(SOLINK)" CFLAGS="$(CFLAGS)" CXXFLAGS="$(CXXFLAGS)" CXX_CFLAGS="$(CXX_CFLAGS)" -C perl
phpmod: $(MYLIB)
$(MAKE) MYLIB="../$(MYLIB)" SOLINK="$(SOLINK)" CFLAGS="$(CFLAGS)" CXXFLAGS="$(CXXFLAGS)" CXX_CFLAGS="$(CXX_CFLAGS)" -C php
luamod: $(MYLIB)
$(MAKE) MYLIB="../$(MYLIB)" SOLINK="$(SOLINK)" CFLAGS="$(CFLAGS)" CXXFLAGS="$(CXXFLAGS)" CXX_CFLAGS="$(CXX_CFLAGS)" -C lua
pymod: $(MYLIB)
$(MAKE) MYLIB="../$(MYLIB)" SOLINK="$(SOLINK)" CFLAGS="$(CFLAGS)" CXXFLAGS="$(CXXFLAGS)" CXX_CFLAGS="$(CXX_CFLAGS)" -C python
tclmod: $(MYLIB)
$(MAKE) MYLIB="../$(MYLIB)" SOLINK="$(SOLINK)" CFLAGS="$(CFLAGS)" CXXFLAGS="$(CXXFLAGS)" CXX_CFLAGS="$(CXX_CFLAGS)" -C tcl
rubymod: $(MYLIB)
$(MAKE) MYLIB="../$(MYLIB)" SOLINK="$(SOLINK)" CFLAGS="$(CFLAGS)" CXXFLAGS="$(CXXFLAGS)" CXX_CFLAGS="$(CXX_CFLAGS)" -C ruby
javamod: $(MYLIB)
$(MAKE) MYLIB="../$(MYLIB)" SOLINK="$(SOLINK)" CFLAGS="$(CFLAGS)" CXXFLAGS="$(CXXFLAGS)" CXX_CFLAGS="$(CXX_CFLAGS)" -C java
managedmod: $(MYLIB)
$(MAKE) MYLIB="../$(MYLIB)" SOLINK="$(SOLINK)" CFLAGS="$(CFLAGS)" CXXFLAGS="$(CXXFLAGS)" CXX_CFLAGS="$(CXX_CFLAGS)" -C managed
phpmod-install: phpmod
$(MAKE) -C php install
everymod: perlmod phpmod luamod pymod rubymod javamod managedmod
Copy all those files to SRC/libs/esl and hit do make
This will spawn a new process with a script indicated on action tag to every new event received filtered by header and matched by category.
/*
* Copyright (c) 2010, Anthony Minessale II
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the original author; nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
* Contributed by João Mesquita <jmesquita@gmail.com>
*
*
* Sponsored by Gabpark
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <esl.h>
#include <getopt.h>
typedef struct {
char e_name[128];
char e_header[128];
char action[128];
} inbound_event_profile_t;
static inbound_event_profile_t profiles[128] = {{{0}}};
static int pcount = 0;
static void mycallback(esl_event_t *event, char * path)
{
int pipefd[2];
int pid;
char * serialized = NULL;
/*make a pipe (fds go in pipefd[0] and pipefd[1])*/
pipe(pipefd);
pid = fork();
if (pid == 0)
{
/* Wire fd to stdin */
dup2(pipefd[0], 0);
// close unused hald of pipe
close(pipefd[1]);
// execute grep
execl(path, path, (char *)NULL);
_exit(EXIT_SUCCESS);
}
else /* Parent */
{
// close unused unput half of pipe
close(pipefd[0]);
esl_event_serialize(event, &serialized, ESL_FALSE);
write(pipefd[1], serialized, strlen(serialized));
close(pipefd[1]);
esl_safe_free(serialized);
}
return;
}
static int usage(char *name){
printf("Usage: %s [-H <host>] [-P <port>] [-p <secret>] [-d <level>] [-c configuration]\n\n", name);
printf(" -?,-h --help Usage Information\n");
printf(" -H, --host=hostname Host to connect\n");
printf(" -P, --port=port Port to connect (1 - 65535)\n");
printf(" -u, --user=user@domain user@domain\n");
printf(" -p, --password=password Password\n");
printf(" -c, --conf=command Config file to use.\n");
printf(" -d, --debug=level Debug Level (0 - 7)\n\n");
return 1;
}
int main(int argc, char *argv[])
{
char host[128] = "127.0.0.1", conf[128] = "/etc/fs_eventsd.conf", pass[128] = "ClueCon";
int port = 8021;
esl_handle_t handle = {{0}};
esl_config_t cfg;
int rv = 0;
/* Vars for optargs */
int opt;
static struct option options[] = {
{"help", 0, 0, 'h'},
{"host", 1, 0, 'H'},
{"port", 1, 0, 'P'},
{"user", 1, 0, 'u'},
{"password", 1, 0, 'p'},
{"debug", 1, 0, 'd'},
{"conf", 1, 0, 'c'},
{0, 0, 0, 0}
};
char temp_host[128];
char temp_conf[128];
int argv_host = 0;
char temp_pass[128];
int argv_pass = 0 ;
int temp_port = 0;
int argv_port = 0;
int temp_log = -1;
int argv_error = 0;
int argv_conf = 0;
esl_global_set_default_logger(6);
for(;;) {
int option_index = 0;
opt = getopt_long(argc, argv, "H:U:P:S:p:d:c:h?", options, &option_index);
if (opt == -1) break;
switch (opt)
{
case 'H':
esl_set_string(temp_host, optarg);
argv_host = 1;
break;
case 'c':
esl_set_string(temp_conf, optarg);
argv_conf = 1;
break;
case 'P':
temp_port= atoi(optarg);
if (temp_port > 0 && temp_port < 65536){
argv_port = 1;
} else {
printf("ERROR: Port must be in range 1 - 65535\n");
argv_error = 1;
}
break;
case 'p':
esl_set_string(temp_pass, optarg);
argv_pass = 1;
break;
case 'd':
temp_log=atoi(optarg);
if (temp_log < 0 || temp_log > 7){
printf("ERROR: Debug level should be 0 - 7.\n");
argv_error = 1;
} else {
esl_global_set_default_logger(temp_log);
}
break;
case 'h':
case '?':
usage(argv[0]);
return 0;
default:
opt = 0;
}
}
if (argv_host){
esl_set_string(host, temp_host);
}
if (argv_pass){
esl_set_string(pass, temp_pass);
}
if (argv_port){
port = temp_port;
}
if (argv_conf){
esl_set_string(conf, temp_conf);
}
if (argv_error){
printf("\n");
return usage(argv[0]);
}
if (!(rv = esl_config_open_file(&cfg, conf)))
{
esl_log(ESL_LOG_ERROR, "No config file, nothing to be done then.\n");
return -1;
}
if (rv)
{
char *var, *val;
char cur_cat[128] = "";
while (esl_config_next_pair(&cfg, &var, &val))
{
if (strcmp(cur_cat, cfg.category))
{
esl_set_string(cur_cat, cfg.category);
esl_set_string(profiles[pcount].e_name, cur_cat);
pcount++;
}
if (!strcasecmp(var, "action"))
{
esl_set_string(profiles[pcount-1].action, val);
}
if (!strcasecmp(var, "header"))
{
esl_set_string(profiles[pcount-1].e_header, val);
}
}
}
esl_log(ESL_LOG_INFO, "Connecting...\n");
if (esl_connect(&handle, host, port, NULL, pass) != ESL_SUCCESS)
{
esl_log(ESL_LOG_ERROR, "Error Connecting [%s]\n", handle.err);
return -1;
}
esl_log(ESL_LOG_INFO, "OK!\n");
esl_events(&handle, ESL_EVENT_TYPE_PLAIN ,"all");
while (handle.connected)
{
if(esl_recv_event(&handle, 1, NULL) == ESL_SUCCESS)
{
int i;
for(i = 0; i < pcount; i++)
{
if (!strcasecmp(profiles[i].e_name,
esl_event_get_header(handle.last_ievent,
profiles[i].e_header)))
{
mycallback(handle.last_ievent,
profiles[i].action);
}
}
}
}
esl_log(ESL_LOG_INFO, "Disconnecting...\n");
esl_disconnect(&handle);
return 0;
}
[HEARTBEAT]
action=./test.py
header=Event-Name
[CHANNEL_CREATE]
action=./test.py
header=Event-Name
\ No newline at end of file
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论