mirror of
https://github.com/asterisk/asterisk.git
synced 2025-11-09 03:18:30 +00:00
applied final release of bug 1353 per Mark's permission
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@2782 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
105
apps/app_dial.c
105
apps/app_dial.c
@@ -20,6 +20,7 @@
|
|||||||
#include <asterisk/module.h>
|
#include <asterisk/module.h>
|
||||||
#include <asterisk/translate.h>
|
#include <asterisk/translate.h>
|
||||||
#include <asterisk/say.h>
|
#include <asterisk/say.h>
|
||||||
|
#include <asterisk/config.h>
|
||||||
#include <asterisk/parking.h>
|
#include <asterisk/parking.h>
|
||||||
#include <asterisk/musiconhold.h>
|
#include <asterisk/musiconhold.h>
|
||||||
#include <asterisk/callerid.h>
|
#include <asterisk/callerid.h>
|
||||||
@@ -68,6 +69,15 @@ static char *descrip =
|
|||||||
" 'g' -- goes on in context if the destination channel hangs up\n"
|
" 'g' -- goes on in context if the destination channel hangs up\n"
|
||||||
" 'A(x)' -- play an announcement to the called party, using x as file\n"
|
" 'A(x)' -- play an announcement to the called party, using x as file\n"
|
||||||
" 'S(x)' -- hangup the call after x seconds AFTER called party picked up\n"
|
" 'S(x)' -- hangup the call after x seconds AFTER called party picked up\n"
|
||||||
|
" 'L(x[:y][:z])' -- Limit the call to 'x' ms warning when 'y' ms are left (repeated every 'z' ms)\n"
|
||||||
|
" -- Only 'x' is required, 'y' and 'z' are optional.\n"
|
||||||
|
" -- The following special variables are optional:\n"
|
||||||
|
" ** LIMIT_PLAYAUDIO_CALLER (default yes) Play sounds to the caller.\n"
|
||||||
|
" ** LIMIT_PLAYAUDIO_CALLEE Play sounds to the callee.\n"
|
||||||
|
" ** LIMIT_TIMEOUT_FILE File to play when time is up.\n"
|
||||||
|
" ** LIMIT_CONNECT_FILE File to play when call begins.\n"
|
||||||
|
" ** LIMIT_WARNING_FILE File to play as warning if 'y' is defined.\n"
|
||||||
|
" -- 'timeleft' is a special sound macro to auto-say the time left and is the default.\n\n"
|
||||||
" In addition to transferring the call, a call may be parked and then picked\n"
|
" In addition to transferring the call, a call may be parked and then picked\n"
|
||||||
"up by another user.\n"
|
"up by another user.\n"
|
||||||
" The optional URL will be sent to the called party if the channel supports\n"
|
" The optional URL will be sent to the called party if the channel supports\n"
|
||||||
@@ -390,6 +400,18 @@ static int dial_exec(struct ast_channel *chan, void *data)
|
|||||||
unsigned int calldurationlimit=0;
|
unsigned int calldurationlimit=0;
|
||||||
char *cdl;
|
char *cdl;
|
||||||
time_t now;
|
time_t now;
|
||||||
|
struct ast_bridge_config config;
|
||||||
|
long timelimit = 0;
|
||||||
|
long play_warning = 0;
|
||||||
|
long warning_freq=0;
|
||||||
|
char *warning_sound=NULL;
|
||||||
|
char *end_sound=NULL;
|
||||||
|
char *start_sound=NULL;
|
||||||
|
char *limitptr;
|
||||||
|
char limitdata[256];
|
||||||
|
char *stack,*var;
|
||||||
|
int play_to_caller=0,play_to_callee=0;
|
||||||
|
int playargs=0;
|
||||||
|
|
||||||
if (!data) {
|
if (!data) {
|
||||||
ast_log(LOG_WARNING, "Dial requires an argument (technology1/number1&technology2/number2...|optional timeout|options)\n");
|
ast_log(LOG_WARNING, "Dial requires an argument (technology1/number1&technology2/number2...|optional timeout|options)\n");
|
||||||
@@ -430,6 +452,7 @@ static int dial_exec(struct ast_channel *chan, void *data)
|
|||||||
|
|
||||||
|
|
||||||
if (transfer) {
|
if (transfer) {
|
||||||
|
|
||||||
/* Extract call duration limit */
|
/* Extract call duration limit */
|
||||||
if ((cdl = strstr(transfer, "S("))) {
|
if ((cdl = strstr(transfer, "S("))) {
|
||||||
calldurationlimit=atoi(cdl+2);
|
calldurationlimit=atoi(cdl+2);
|
||||||
@@ -437,6 +460,73 @@ static int dial_exec(struct ast_channel *chan, void *data)
|
|||||||
ast_verbose(VERBOSE_PREFIX_3 "Setting call duration limit to %i seconds.\n",calldurationlimit);
|
ast_verbose(VERBOSE_PREFIX_3 "Setting call duration limit to %i seconds.\n",calldurationlimit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* XXX LIMIT SUPPORT */
|
||||||
|
if ((limitptr = strstr(transfer, "L("))) {
|
||||||
|
strncpy(limitdata, limitptr + 2, sizeof(limitdata) - 1);
|
||||||
|
/* Overwrite with X's what was the limit info */
|
||||||
|
while(*limitptr && (*limitptr != ')'))
|
||||||
|
*(limitptr++) = 'X';
|
||||||
|
if (*limitptr)
|
||||||
|
*limitptr = 'X';
|
||||||
|
/* Now find the end of the privdb */
|
||||||
|
limitptr = strchr(limitdata, ')');
|
||||||
|
if (limitptr)
|
||||||
|
*limitptr = '\0';
|
||||||
|
else {
|
||||||
|
ast_log(LOG_WARNING, "Limit Data lacking trailing ')'\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
var = pbx_builtin_getvar_helper(chan,"LIMIT_PLAYAUDIO_CALLER");
|
||||||
|
play_to_caller = var ? ast_true(var) : 1;
|
||||||
|
|
||||||
|
var = pbx_builtin_getvar_helper(chan,"LIMIT_PLAYAUDIO_CALLEE");
|
||||||
|
play_to_callee = var ? ast_true(var) : 0;
|
||||||
|
|
||||||
|
if(! play_to_caller && ! play_to_callee)
|
||||||
|
play_to_caller=1;
|
||||||
|
|
||||||
|
var = pbx_builtin_getvar_helper(chan,"LIMIT_WARNING_FILE");
|
||||||
|
warning_sound = var ? var : "timeleft";
|
||||||
|
|
||||||
|
var = pbx_builtin_getvar_helper(chan,"LIMIT_TIMEOUT_FILE");
|
||||||
|
end_sound = var ? var : NULL;
|
||||||
|
|
||||||
|
var = pbx_builtin_getvar_helper(chan,"LIMIT_CONNECT_FILE");
|
||||||
|
start_sound = var ? var : NULL;
|
||||||
|
|
||||||
|
var=stack=limitdata;
|
||||||
|
|
||||||
|
var = strsep(&stack, ":");
|
||||||
|
if(var) {
|
||||||
|
timelimit = atol(var);
|
||||||
|
playargs++;
|
||||||
|
}
|
||||||
|
var = strsep(&stack, ":");
|
||||||
|
if(var) {
|
||||||
|
play_warning = atol(var);
|
||||||
|
playargs++;
|
||||||
|
}
|
||||||
|
|
||||||
|
var = strsep(&stack, ":");
|
||||||
|
if(var) {
|
||||||
|
warning_freq = atol(var);
|
||||||
|
playargs++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(! timelimit) {
|
||||||
|
timelimit=play_to_caller=play_to_callee=play_warning=warning_freq=0;
|
||||||
|
warning_sound=NULL;
|
||||||
|
}
|
||||||
|
calldurationlimit=0; /* undo effect of S(x) in case they are both used */
|
||||||
|
if(! play_warning && ! start_sound && ! end_sound && timelimit) { /* more efficient do it like S(x) does since no advanced opts*/
|
||||||
|
calldurationlimit=timelimit/1000;
|
||||||
|
timelimit=play_to_caller=play_to_callee=play_warning=warning_freq=0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ast_verbose(VERBOSE_PREFIX_3"Limit Data: timelimit=%ld\n -- play_warning=%ld\n -- play_to_caller=%s\n -- play_to_callee=%s\n -- warning_freq=%ld\n -- warning_sound=%s\n -- end_sound=%s\n -- start_sound=%s\n",timelimit,play_warning,play_to_caller ? "yes" : "no",play_to_callee ? "yes" : "no",warning_freq,warning_sound ? warning_sound : "UNDEF",end_sound ? end_sound : "UNDEF",start_sound ? start_sound : "UNDEF");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* XXX ANNOUNCE SUPPORT */
|
/* XXX ANNOUNCE SUPPORT */
|
||||||
if ((ann = strstr(transfer, "A("))) {
|
if ((ann = strstr(transfer, "A("))) {
|
||||||
announce = 1;
|
announce = 1;
|
||||||
@@ -729,7 +819,20 @@ static int dial_exec(struct ast_channel *chan, void *data)
|
|||||||
time(&now);
|
time(&now);
|
||||||
chan->whentohangup = now + calldurationlimit;
|
chan->whentohangup = now + calldurationlimit;
|
||||||
}
|
}
|
||||||
res = ast_bridge_call(chan, peer, allowredir_in, allowredir_out, allowdisconnect);
|
|
||||||
|
memset(&config,0,sizeof(struct ast_bridge_config));
|
||||||
|
config.play_to_caller=play_to_caller;
|
||||||
|
config.play_to_callee=play_to_callee;
|
||||||
|
config.allowredirect_in = allowredir_in;
|
||||||
|
config.allowredirect_out = allowredir_out;
|
||||||
|
config.allowdisconnect = allowdisconnect;
|
||||||
|
config.timelimit = timelimit;
|
||||||
|
config.play_warning = play_warning;
|
||||||
|
config.warning_freq = warning_freq;
|
||||||
|
config.warning_sound = warning_sound;
|
||||||
|
config.end_sound = end_sound;
|
||||||
|
config.start_sound = start_sound;
|
||||||
|
res = ast_bridge_call(chan,peer,&config);
|
||||||
|
|
||||||
if (res != AST_PBX_NO_HANGUP_PEER)
|
if (res != AST_PBX_NO_HANGUP_PEER)
|
||||||
ast_hangup(peer);
|
ast_hangup(peer);
|
||||||
|
|||||||
@@ -874,6 +874,7 @@ static int try_calling(struct queue_ent *qe, char *options, char *announceoverri
|
|||||||
char digit = 0;
|
char digit = 0;
|
||||||
time_t callstart;
|
time_t callstart;
|
||||||
time_t now;
|
time_t now;
|
||||||
|
struct ast_bridge_config config;
|
||||||
/* Hold the lock while we setup the outgoing calls */
|
/* Hold the lock while we setup the outgoing calls */
|
||||||
ast_mutex_lock(&qe->parent->lock);
|
ast_mutex_lock(&qe->parent->lock);
|
||||||
strncpy(queuename, qe->parent->name, sizeof(queuename) - 1);
|
strncpy(queuename, qe->parent->name, sizeof(queuename) - 1);
|
||||||
@@ -1030,7 +1031,13 @@ static int try_calling(struct queue_ent *qe, char *options, char *announceoverri
|
|||||||
strncpy(oldcontext, qe->chan->context, sizeof(oldcontext) - 1);
|
strncpy(oldcontext, qe->chan->context, sizeof(oldcontext) - 1);
|
||||||
strncpy(oldexten, qe->chan->exten, sizeof(oldexten) - 1);
|
strncpy(oldexten, qe->chan->exten, sizeof(oldexten) - 1);
|
||||||
time(&callstart);
|
time(&callstart);
|
||||||
bridge = ast_bridge_call(qe->chan, peer, allowredir_in, allowredir_out, allowdisconnect);
|
|
||||||
|
memset(&config,0,sizeof(struct ast_bridge_config));
|
||||||
|
config.allowredirect_in = allowredir_in;
|
||||||
|
config.allowredirect_out = allowredir_out;
|
||||||
|
config.allowdisconnect = allowdisconnect;
|
||||||
|
bridge = ast_bridge_call(qe->chan,peer,&config);
|
||||||
|
|
||||||
if (strcasecmp(oldcontext, qe->chan->context) || strcasecmp(oldexten, qe->chan->exten)) {
|
if (strcasecmp(oldcontext, qe->chan->context) || strcasecmp(oldexten, qe->chan->exten)) {
|
||||||
ast_queue_log(queuename, qe->chan->uniqueid, peer->name, "TRANSFER", "%s|%s", qe->chan->exten, qe->chan->context);
|
ast_queue_log(queuename, qe->chan->uniqueid, peer->name, "TRANSFER", "%s|%s", qe->chan->exten, qe->chan->context);
|
||||||
} else if (qe->chan->_softhangup) {
|
} else if (qe->chan->_softhangup) {
|
||||||
|
|||||||
119
channel.c
119
channel.c
@@ -28,6 +28,7 @@
|
|||||||
#include <asterisk/channel.h>
|
#include <asterisk/channel.h>
|
||||||
#include <asterisk/channel_pvt.h>
|
#include <asterisk/channel_pvt.h>
|
||||||
#include <asterisk/logger.h>
|
#include <asterisk/logger.h>
|
||||||
|
#include <asterisk/say.h>
|
||||||
#include <asterisk/file.h>
|
#include <asterisk/file.h>
|
||||||
#include <asterisk/translate.h>
|
#include <asterisk/translate.h>
|
||||||
#include <asterisk/manager.h>
|
#include <asterisk/manager.h>
|
||||||
@@ -147,6 +148,8 @@ time_t myt;
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int ast_channel_register(char *type, char *description, int capabilities,
|
int ast_channel_register(char *type, char *description, int capabilities,
|
||||||
struct ast_channel *(*requester)(char *type, int format, void *data))
|
struct ast_channel *(*requester)(char *type, int format, void *data))
|
||||||
{
|
{
|
||||||
@@ -2327,16 +2330,73 @@ int ast_setstate(struct ast_channel *chan, int state)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ast_channel_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc)
|
|
||||||
{
|
static long tvdiff(struct timeval *now,struct timeval *then) {
|
||||||
|
return (((now->tv_sec * 1000) + now->tv_usec / 1000) - ((then->tv_sec * 1000) + then->tv_usec / 1000));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bridge_playfile(struct ast_channel *chan,char *sound,int remain) {
|
||||||
|
int res=0,min=0,sec=0;
|
||||||
|
|
||||||
|
if(remain > 0) {
|
||||||
|
if(remain / 60 > 1) {
|
||||||
|
min = remain / 60;
|
||||||
|
sec = remain % 60;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sec = remain;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!strcmp(sound,"timeleft")) {
|
||||||
|
res=ast_streamfile(chan,"vm-youhave",chan->language);
|
||||||
|
res = ast_waitstream(chan, "");
|
||||||
|
if(min) {
|
||||||
|
res = ast_say_number(chan,min, AST_DIGIT_ANY, chan->language);
|
||||||
|
res=ast_streamfile(chan,"minutes",chan->language);
|
||||||
|
res = ast_waitstream(chan, "");
|
||||||
|
}
|
||||||
|
if(sec) {
|
||||||
|
res = ast_say_number(chan,sec, AST_DIGIT_ANY, chan->language);
|
||||||
|
res=ast_streamfile(chan,"seconds",chan->language);
|
||||||
|
res = ast_waitstream(chan, "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
res=ast_streamfile(chan,sound,chan->language);
|
||||||
|
res = ast_waitstream(chan, "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int ast_channel_bridge(struct ast_channel *c0,struct ast_channel *c1,struct ast_bridge_config *config, struct ast_frame **fo, struct ast_channel **rc) {
|
||||||
/* Copy voice back and forth between the two channels. Give the peer
|
/* Copy voice back and forth between the two channels. Give the peer
|
||||||
the ability to transfer calls with '#<extension' syntax. */
|
the ability to transfer calls with '#<extension' syntax. */
|
||||||
|
int flags;
|
||||||
struct ast_channel *cs[3];
|
struct ast_channel *cs[3];
|
||||||
int to = -1;
|
int to = -1;
|
||||||
struct ast_frame *f;
|
struct ast_frame *f;
|
||||||
struct ast_channel *who = NULL;
|
struct ast_channel *who = NULL;
|
||||||
int res;
|
int res=0;
|
||||||
int nativefailed=0;
|
int nativefailed=0;
|
||||||
|
struct timeval start_time,precise_now;
|
||||||
|
long elapsed_ms=0,time_left_ms=0;
|
||||||
|
int playit=0,playitagain=1,first_time=1;
|
||||||
|
|
||||||
|
|
||||||
|
flags = (config->allowdisconnect||config->allowredirect_out ? AST_BRIDGE_DTMF_CHANNEL_0 : 0) + (config->allowredirect_in ? AST_BRIDGE_DTMF_CHANNEL_1 : 0);
|
||||||
|
|
||||||
|
/* timestamp */
|
||||||
|
gettimeofday(&start_time,NULL);
|
||||||
|
time_left_ms = config->timelimit;
|
||||||
|
|
||||||
|
if(config->play_to_caller && config->start_sound){
|
||||||
|
bridge_playfile(c0,config->start_sound,time_left_ms / 1000);
|
||||||
|
}
|
||||||
|
if(config->play_to_callee && config->start_sound){
|
||||||
|
bridge_playfile(c1,config->start_sound,time_left_ms / 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Stop if we're a zombie or need a soft hangup */
|
/* Stop if we're a zombie or need a soft hangup */
|
||||||
if (c0->zombie || ast_check_hangup_locked(c0) || c1->zombie || ast_check_hangup_locked(c1))
|
if (c0->zombie || ast_check_hangup_locked(c0) || c1->zombie || ast_check_hangup_locked(c1))
|
||||||
@@ -2366,6 +2426,57 @@ int ast_channel_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags
|
|||||||
c0->name, c1->name, c0->uniqueid, c1->uniqueid);
|
c0->name, c1->name, c0->uniqueid, c1->uniqueid);
|
||||||
|
|
||||||
for (/* ever */;;) {
|
for (/* ever */;;) {
|
||||||
|
|
||||||
|
/* timestamp */
|
||||||
|
if(config->timelimit) {
|
||||||
|
gettimeofday(&precise_now,NULL);
|
||||||
|
elapsed_ms = tvdiff(&precise_now,&start_time);
|
||||||
|
time_left_ms = config->timelimit - elapsed_ms;
|
||||||
|
|
||||||
|
if(playitagain && (config->play_to_caller || config->play_to_callee) && (config->play_warning && time_left_ms <= config->play_warning)) {
|
||||||
|
/* narrowing down to the end */
|
||||||
|
if(config->warning_freq == 0) {
|
||||||
|
playit = 1;
|
||||||
|
first_time=0;
|
||||||
|
playitagain=0;
|
||||||
|
}
|
||||||
|
else if(first_time) {
|
||||||
|
playit = 1;
|
||||||
|
first_time=0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if((time_left_ms % config->warning_freq) <= 50) {
|
||||||
|
playit = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(time_left_ms <= 0) {
|
||||||
|
if(config->play_to_caller && config->end_sound){
|
||||||
|
bridge_playfile(c0,config->end_sound,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(config->play_to_callee && config->end_sound){
|
||||||
|
bridge_playfile(c1,config->end_sound,0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(time_left_ms >= 5000 && playit) {
|
||||||
|
if(config->play_to_caller && config->warning_sound && config->play_warning){
|
||||||
|
bridge_playfile(c0,config->warning_sound,time_left_ms / 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(config->play_to_callee && config->warning_sound && config->play_warning){
|
||||||
|
bridge_playfile(c1,config->warning_sound,time_left_ms / 1000);
|
||||||
|
}
|
||||||
|
playit = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Stop if we're a zombie or need a soft hangup */
|
/* Stop if we're a zombie or need a soft hangup */
|
||||||
if (c0->zombie || ast_check_hangup_locked(c0) || c1->zombie || ast_check_hangup_locked(c1)) {
|
if (c0->zombie || ast_check_hangup_locked(c0) || c1->zombie || ast_check_hangup_locked(c1)) {
|
||||||
*fo = NULL;
|
*fo = NULL;
|
||||||
@@ -2374,7 +2485,7 @@ int ast_channel_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags
|
|||||||
ast_log(LOG_DEBUG, "Bridge stops because we're zombie or need a soft hangup: c0=%s, c1=%s, flags: %s,%s,%s,%s\n",c0->name,c1->name,c0->zombie?"Yes":"No",ast_check_hangup(c0)?"Yes":"No",c1->zombie?"Yes":"No",ast_check_hangup(c1)?"Yes":"No");
|
ast_log(LOG_DEBUG, "Bridge stops because we're zombie or need a soft hangup: c0=%s, c1=%s, flags: %s,%s,%s,%s\n",c0->name,c1->name,c0->zombie?"Yes":"No",ast_check_hangup(c0)?"Yes":"No",c1->zombie?"Yes":"No",ast_check_hangup(c1)?"Yes":"No");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (c0->pvt->bridge &&
|
if (c0->pvt->bridge && config->timelimit==0 &&
|
||||||
(c0->pvt->bridge == c1->pvt->bridge) && !nativefailed && !c0->monitor && !c1->monitor) {
|
(c0->pvt->bridge == c1->pvt->bridge) && !nativefailed && !c0->monitor && !c1->monitor) {
|
||||||
/* Looks like they share a bridge code */
|
/* Looks like they share a bridge code */
|
||||||
if (option_verbose > 2)
|
if (option_verbose > 2)
|
||||||
|
|||||||
114
contrib/scripts/astxs
Executable file
114
contrib/scripts/astxs
Executable file
@@ -0,0 +1,114 @@
|
|||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
|
my $astdir = $ENV{ASTSRC} or "/usr/src/asterisk";
|
||||||
|
|
||||||
|
|
||||||
|
sub esystem($) {
|
||||||
|
my $cmd = shift;
|
||||||
|
print "$cmd\n";
|
||||||
|
system($cmd);
|
||||||
|
}
|
||||||
|
sub usage($) {
|
||||||
|
my $str = shift;
|
||||||
|
print "\n$str\n\n";
|
||||||
|
print "Usage $0 [ <module.c> [-set=<varname>:<value>] [-append=<varname>:<value>] [-install] ] | [-help] \n\n";
|
||||||
|
|
||||||
|
print "varnames of interest:
|
||||||
|
===============================================================================
|
||||||
|
'INCLUDES' 'ASTLIBDIR' 'AGI_DIR' 'ASTVARRUNDIR' 'CC' 'ASTETCDIR' 'EXTOBJ'
|
||||||
|
'ASTSPOOLDIR' 'ASTLOGDIR' 'MODULES_DIR' 'ASTSBINDIR' 'ASTHEADERDIR' 'LDFLAGS'
|
||||||
|
'ASTVARLIBDIR' 'ASTBINDIR' 'INSTALL_PREFIX' 'ASTCONFPATH' 'ASTSRC' 'CFLAGS'
|
||||||
|
===============================================================================
|
||||||
|
";
|
||||||
|
|
||||||
|
exit;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
my %avars = ();
|
||||||
|
my %svars = ();
|
||||||
|
my %vars = ();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
my %args = ();
|
||||||
|
|
||||||
|
|
||||||
|
foreach(@ARGV) {
|
||||||
|
|
||||||
|
if(/^\-set=([^\:]+):(.*)/) {
|
||||||
|
$svars{$1} = $2;
|
||||||
|
}
|
||||||
|
elsif(/^\-append=([^\:]+):(.*)/) {
|
||||||
|
$avars{$1} .= " $2";
|
||||||
|
}
|
||||||
|
elsif(/^\-([^\=]+)=(.*)/) {
|
||||||
|
$args{$1} = $2;
|
||||||
|
}
|
||||||
|
elsif(/^\-([^\=]+)$/) {
|
||||||
|
$args{$1}++;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
push(@{$args{plain}},$_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if($args{help} or $args{h}) {
|
||||||
|
usage "Help";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
my $pwd = `/bin/pwd`;
|
||||||
|
chomp($pwd);
|
||||||
|
|
||||||
|
$vars{astdir} ||= $astdir;
|
||||||
|
|
||||||
|
chdir($vars{astdir});
|
||||||
|
my $type = $args{type} || "apps";
|
||||||
|
my $env = `make ${type}_env`;
|
||||||
|
chdir($pwd);
|
||||||
|
|
||||||
|
foreach(split("\n",$env)) {
|
||||||
|
my($var,$val) = /([^\=]+)\=(.*)/;
|
||||||
|
$vars{$var} = $val;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
foreach(keys %svars) {
|
||||||
|
$vars{$_} = $svars{$_};
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach(keys %avars) {
|
||||||
|
$vars{$_} .= $avars{$_};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if($args{print}) {
|
||||||
|
print "$vars{$args{print}}";
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
my($base,$ext);
|
||||||
|
my $cfile = $args{plain}->[0];
|
||||||
|
if($cfile) {
|
||||||
|
($base,$ext) = $cfile =~ /^([^\.]+)\.(.)/;
|
||||||
|
}
|
||||||
|
|
||||||
|
if($ext ne "c") {
|
||||||
|
usage "Bad Input File";
|
||||||
|
}
|
||||||
|
|
||||||
|
my $bad=0;
|
||||||
|
|
||||||
|
$bad = esystem("$vars{CC} $vars{CFLAGS} -c ${base}.c -o ${base}.o");
|
||||||
|
$bad = esystem("$vars{CC} $vars{SOLINK} -o $vars{LDFLAGS} ${base}.so $base.o $vars{EXTOBJ}") if(!$bad);
|
||||||
|
|
||||||
|
if($args{install} and $vars{MODULES_DIR}) {
|
||||||
|
$bad = esystem("/bin/cp -p ${base}.so $vars{MODULES_DIR}") if(!$bad);
|
||||||
|
}
|
||||||
|
|
||||||
@@ -267,6 +267,22 @@ static inline void ast_dup_flag(struct ast_channel *dstchan, struct ast_channel
|
|||||||
ast_clear_flag(dstchan, mode);
|
ast_clear_flag(dstchan, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct ast_bridge_config {
|
||||||
|
int play_to_caller;
|
||||||
|
int play_to_callee;
|
||||||
|
int allowredirect_in;
|
||||||
|
int allowredirect_out;
|
||||||
|
int allowdisconnect;
|
||||||
|
long timelimit;
|
||||||
|
long play_warning;
|
||||||
|
long warning_freq;
|
||||||
|
char *warning_sound;
|
||||||
|
char *end_sound;
|
||||||
|
char *start_sound;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
struct chanmon;
|
struct chanmon;
|
||||||
|
|
||||||
#define LOAD_OH(oh) { \
|
#define LOAD_OH(oh) { \
|
||||||
@@ -666,7 +682,9 @@ int ast_channel_make_compatible(struct ast_channel *c0, struct ast_channel *c1);
|
|||||||
* \param rc destination channel(?)
|
* \param rc destination channel(?)
|
||||||
* Bridge two channels (c0 and c1) together. If an important frame occurs, we return that frame in
|
* Bridge two channels (c0 and c1) together. If an important frame occurs, we return that frame in
|
||||||
*rf (remember, it could be NULL) and which channel (0 or 1) in rc */
|
*rf (remember, it could be NULL) and which channel (0 or 1) in rc */
|
||||||
int ast_channel_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc);
|
//int ast_channel_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc);
|
||||||
|
int ast_channel_bridge(struct ast_channel *c0,struct ast_channel *c1,struct ast_bridge_config *config, struct ast_frame **fo, struct ast_channel **rc);
|
||||||
|
|
||||||
|
|
||||||
//! Weird function made for call transfers
|
//! Weird function made for call transfers
|
||||||
/*!
|
/*!
|
||||||
|
|||||||
@@ -44,9 +44,13 @@ extern int ast_masq_park_call(struct ast_channel *rchan, struct ast_channel *hos
|
|||||||
extern char *ast_parking_ext(void);
|
extern char *ast_parking_ext(void);
|
||||||
extern char *ast_pickup_ext(void);
|
extern char *ast_pickup_ext(void);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//! Bridge a call, optionally allowing redirection
|
//! Bridge a call, optionally allowing redirection
|
||||||
|
|
||||||
extern int ast_bridge_call(struct ast_channel *chan, struct ast_channel *peer, int allowredirect_in, int allowredirect_out, int allowdisconnect);
|
extern int ast_bridge_call(struct ast_channel *chan, struct ast_channel *peer,struct ast_bridge_config *config);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
extern int ast_pickup_call(struct ast_channel *chan);
|
extern int ast_pickup_call(struct ast_channel *chan);
|
||||||
|
|
||||||
|
|||||||
@@ -214,10 +214,12 @@ int ast_masq_park_call(struct ast_channel *rchan, struct ast_channel *peer, int
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ast_bridge_call(struct ast_channel *chan, struct ast_channel *peer, int allowredirect_in, int allowredirect_out, int allowdisconnect)
|
|
||||||
|
int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast_bridge_config *config)
|
||||||
{
|
{
|
||||||
/* Copy voice back and forth between the two channels. Give the peer
|
/* Copy voice back and forth between the two channels. Give the peer
|
||||||
the ability to transfer calls with '#<extension' syntax. */
|
the ability to transfer calls with '#<extension' syntax. */
|
||||||
|
|
||||||
int len;
|
int len;
|
||||||
struct ast_frame *f;
|
struct ast_frame *f;
|
||||||
struct ast_channel *who;
|
struct ast_channel *who;
|
||||||
@@ -227,6 +229,11 @@ int ast_bridge_call(struct ast_channel *chan, struct ast_channel *peer, int allo
|
|||||||
struct ast_channel *transferer;
|
struct ast_channel *transferer;
|
||||||
struct ast_channel *transferee;
|
struct ast_channel *transferee;
|
||||||
char *transferer_real_context;
|
char *transferer_real_context;
|
||||||
|
int allowdisconnect,allowredirect_in,allowredirect_out;
|
||||||
|
|
||||||
|
allowdisconnect = config->allowdisconnect;
|
||||||
|
allowredirect_in = config->allowredirect_in;
|
||||||
|
allowredirect_out = config->allowredirect_out;
|
||||||
|
|
||||||
/* Answer if need be */
|
/* Answer if need be */
|
||||||
if (ast_answer(chan))
|
if (ast_answer(chan))
|
||||||
@@ -246,7 +253,7 @@ int ast_bridge_call(struct ast_channel *chan, struct ast_channel *peer, int allo
|
|||||||
peer->cdr = NULL;
|
peer->cdr = NULL;
|
||||||
}
|
}
|
||||||
for (;;) {
|
for (;;) {
|
||||||
res = ast_channel_bridge(chan, peer, (allowdisconnect||allowredirect_out ? AST_BRIDGE_DTMF_CHANNEL_0 : 0) + (allowredirect_in ? AST_BRIDGE_DTMF_CHANNEL_1 : 0), &f, &who);
|
res = ast_channel_bridge(chan,peer,config,&f, &who);
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
ast_log(LOG_WARNING, "Bridge failed on channels %s and %s\n", chan->name, peer->name);
|
ast_log(LOG_WARNING, "Bridge failed on channels %s and %s\n", chan->name, peer->name);
|
||||||
return -1;
|
return -1;
|
||||||
@@ -534,6 +541,8 @@ static int park_exec(struct ast_channel *chan, void *data)
|
|||||||
struct parkeduser *pu, *pl=NULL;
|
struct parkeduser *pu, *pl=NULL;
|
||||||
int park;
|
int park;
|
||||||
int dres;
|
int dres;
|
||||||
|
struct ast_bridge_config config;
|
||||||
|
|
||||||
if (!data) {
|
if (!data) {
|
||||||
ast_log(LOG_WARNING, "Park requires an argument (extension number)\n");
|
ast_log(LOG_WARNING, "Park requires an argument (extension number)\n");
|
||||||
return -1;
|
return -1;
|
||||||
@@ -575,7 +584,17 @@ static int park_exec(struct ast_channel *chan, void *data)
|
|||||||
were the person called. */
|
were the person called. */
|
||||||
if (option_verbose > 2)
|
if (option_verbose > 2)
|
||||||
ast_verbose(VERBOSE_PREFIX_3 "Channel %s connected to parked call %d\n", chan->name, park);
|
ast_verbose(VERBOSE_PREFIX_3 "Channel %s connected to parked call %d\n", chan->name, park);
|
||||||
res = ast_bridge_call(chan, peer, 1, 1, 0);
|
|
||||||
|
memset(&config,0,sizeof(struct ast_bridge_config));
|
||||||
|
config.allowredirect_in = 1;
|
||||||
|
config.allowredirect_out = 1;
|
||||||
|
config.allowdisconnect = 0;
|
||||||
|
config.timelimit = 0;
|
||||||
|
config.play_warning = 0;
|
||||||
|
config.warning_freq = 0;
|
||||||
|
config.warning_sound=NULL;
|
||||||
|
res = ast_bridge_call(chan,peer,&config);
|
||||||
|
|
||||||
/* Simulate the PBX hanging up */
|
/* Simulate the PBX hanging up */
|
||||||
if (res != AST_PBX_NO_HANGUP_PEER)
|
if (res != AST_PBX_NO_HANGUP_PEER)
|
||||||
ast_hangup(peer);
|
ast_hangup(peer);
|
||||||
|
|||||||
Reference in New Issue
Block a user