Fixed call parking, added separate paramater to allow/disallow call parking on

Zaptel interfaces (canpark=yes/no in zapata.conf), added urlbase paramater to
Monitor so that a url can optionally be included in CDR (user field), cleaned up a couple of minor things


git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@4413 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
Jim Dixon
2004-12-09 22:39:14 +00:00
parent 9f1a7379cc
commit 998621f76a
6 changed files with 82 additions and 15 deletions

View File

@@ -330,7 +330,7 @@ static int disa_exec(struct ast_channel *chan, void *data)
strncpy(chan->context, ourcontext, sizeof(chan->context) - 1); strncpy(chan->context, ourcontext, sizeof(chan->context) - 1);
strncpy(chan->accountcode, acctcode, sizeof(chan->accountcode) - 1); strncpy(chan->accountcode, acctcode, sizeof(chan->accountcode) - 1);
chan->priority = 0; chan->priority = 0;
ast_cdr_init(chan->cdr,chan); ast_cdr_reset(chan->cdr,AST_CDR_FLAG_POSTED);
LOCAL_USER_REMOVE(u); LOCAL_USER_REMOVE(u);
return 0; return 0;
} }

View File

@@ -1366,9 +1366,14 @@ static int __login_exec(struct ast_channel *chan, void *data, int callbackmode)
exten = NULL; exten = NULL;
} }
} }
if ( options ) { if (options) {
while (*options) { while (*options) {
option = (char)options[0]; option = (char)options[0];
if ((option >= 0) && (option <= '9'))
{
options++;
continue;
}
if (option=='s') if (option=='s')
play_announcement = 0; play_announcement = 0;
else { else {

View File

@@ -196,6 +196,8 @@ static int threewaycalling = 0;
static int transfer = 0; static int transfer = 0;
static int canpark = 0;
static int cancallforward = 0; static int cancallforward = 0;
static float rxgain = 0.0; static float rxgain = 0.0;
@@ -521,6 +523,7 @@ static struct zt_pvt {
int callwaitingcallerid; int callwaitingcallerid;
int threewaycalling; int threewaycalling;
int transfer; int transfer;
int canpark;
int digital; int digital;
int outgoing; int outgoing;
int dnd; int dnd;
@@ -5129,7 +5132,7 @@ static void *ss_thread(void *data)
getforward = 0; getforward = 0;
memset(exten, 0, sizeof(exten)); memset(exten, 0, sizeof(exten));
len = 0; len = 0;
} else if (p->transfer && !strcmp(exten, ast_parking_ext()) && } else if ((p->transfer || p->canpark) && !strcmp(exten, ast_parking_ext()) &&
p->subs[SUB_THREEWAY].owner && p->subs[SUB_THREEWAY].owner &&
ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) { ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) {
/* This is a three way call, the main call being a real channel, /* This is a three way call, the main call being a real channel,
@@ -6596,6 +6599,7 @@ static struct zt_pvt *mkintf(int channel, int signalling, int radio, struct zt_p
tmp->confno = -1; tmp->confno = -1;
tmp->propconfno = -1; tmp->propconfno = -1;
} }
tmp->canpark = canpark;
tmp->transfer = transfer; tmp->transfer = transfer;
strncpy(tmp->defcontext,context,sizeof(tmp->defcontext)-1); strncpy(tmp->defcontext,context,sizeof(tmp->defcontext)-1);
strncpy(tmp->language, language, sizeof(tmp->language)-1); strncpy(tmp->language, language, sizeof(tmp->language)-1);
@@ -9333,6 +9337,8 @@ static int setup_zap(int reload)
adsi = ast_true(v->value); adsi = ast_true(v->value);
} else if (!strcasecmp(v->name, "transfer")) { } else if (!strcasecmp(v->name, "transfer")) {
transfer = ast_true(v->value); transfer = ast_true(v->value);
} else if (!strcasecmp(v->name, "canpark")) {
canpark = ast_true(v->value);
} else if (!strcasecmp(v->name, "echocancelwhenbridged")) { } else if (!strcasecmp(v->name, "echocancelwhenbridged")) {
echocanbridged = ast_true(v->value); echocanbridged = ast_true(v->value);
} else if (!strcasecmp(v->name, "busydetect")) { } else if (!strcasecmp(v->name, "busydetect")) {

View File

@@ -193,9 +193,15 @@ callwaitingcallerid=yes
threewaycalling=yes threewaycalling=yes
; ;
; Support flash-hook call transfer (requires three way calling) ; Support flash-hook call transfer (requires three way calling)
; Also enables call parking (overrides the 'canpark' parameter)
; ;
transfer=yes transfer=yes
; ;
; Allow call parking
; ('canpark=no' is overridden by 'transfer=yes')
;
canpark=yes
;
; Support call forward variable ; Support call forward variable
; ;
cancallforward=yes cancallforward=yes

View File

@@ -28,6 +28,7 @@
#include <asterisk/manager.h> #include <asterisk/manager.h>
#include <asterisk/utils.h> #include <asterisk/utils.h>
#include <asterisk/adsi.h> #include <asterisk/adsi.h>
#include <pthread.h>
#include <stdlib.h> #include <stdlib.h>
#include <errno.h> #include <errno.h>
#include <unistd.h> #include <unistd.h>
@@ -49,6 +50,9 @@ static int parkingtime = DEFAULT_PARK_TIME;
/* Context for which parking is made accessible */ /* Context for which parking is made accessible */
static char parking_con[AST_MAX_EXTENSION] = "parkedcalls"; static char parking_con[AST_MAX_EXTENSION] = "parkedcalls";
/* Context for dialback for parking (KLUDGE) */
static char parking_con_dial[AST_MAX_EXTENSION] = "park-dial";
/* Extension you type to park the call */ /* Extension you type to park the call */
static char parking_ext[AST_MAX_EXTENSION] = "700"; static char parking_ext[AST_MAX_EXTENSION] = "700";
@@ -103,6 +107,7 @@ struct parkeduser {
int priority; int priority;
int parkingtime; int parkingtime;
int notquiteyet; int notquiteyet;
char peername[1024];
struct parkeduser *next; struct parkeduser *next;
}; };
@@ -152,6 +157,7 @@ int ast_park_call(struct ast_channel *chan, struct ast_channel *peer, int timeou
struct ast_context *con; struct ast_context *con;
pu = malloc(sizeof(struct parkeduser)); pu = malloc(sizeof(struct parkeduser));
if (pu) { if (pu) {
memset(pu,0,sizeof(struct parkeduser));
ast_mutex_lock(&parking_lock); ast_mutex_lock(&parking_lock);
for (x=parking_start;x<=parking_stop;x++) { for (x=parking_start;x<=parking_stop;x++) {
cur = parkinglot; cur = parkinglot;
@@ -179,6 +185,10 @@ int ast_park_call(struct ast_channel *chan, struct ast_channel *peer, int timeou
pu->parkingtime = parkingtime; pu->parkingtime = parkingtime;
if (extout) if (extout)
*extout = x; *extout = x;
if (peer)
{
strncpy(pu->peername,peer->name,sizeof(pu->peername) - 1);
}
/* Remember what had been dialed, so that if the parking /* Remember what had been dialed, so that if the parking
expires, we try to come back to the same place */ expires, we try to come back to the same place */
if (!ast_strlen_zero(chan->macrocontext)) if (!ast_strlen_zero(chan->macrocontext))
@@ -196,7 +206,7 @@ int ast_park_call(struct ast_channel *chan, struct ast_channel *peer, int timeou
pu->next = parkinglot; pu->next = parkinglot;
parkinglot = pu; parkinglot = pu;
/* If parking a channel directly, don't quiet yet get parking running on it */ /* If parking a channel directly, don't quiet yet get parking running on it */
if (peer == chan) if (peer == chan)
pu->notquiteyet = 1; pu->notquiteyet = 1;
ast_mutex_unlock(&parking_lock); ast_mutex_unlock(&parking_lock);
/* Wake up the (presumably select()ing) thread */ /* Wake up the (presumably select()ing) thread */
@@ -221,7 +231,6 @@ int ast_park_call(struct ast_channel *chan, struct ast_channel *peer, int timeou
if (adsipark && adsi_available(peer)) { if (adsipark && adsi_available(peer)) {
adsi_announce_park(peer, pu->parkingnum); adsi_announce_park(peer, pu->parkingnum);
} }
ast_say_digits(peer, pu->parkingnum, "", peer->language);
if (adsipark && adsi_available(peer)) { if (adsipark && adsi_available(peer)) {
adsi_unload_session(peer); adsi_unload_session(peer);
} }
@@ -243,6 +252,7 @@ int ast_park_call(struct ast_channel *chan, struct ast_channel *peer, int timeou
snprintf(exten, sizeof(exten), "%d", x); snprintf(exten, sizeof(exten), "%d", x);
ast_add_extension2(con, 1, exten, 1, NULL, NULL, parkedcall, strdup(exten), free, registrar); ast_add_extension2(con, 1, exten, 1, NULL, NULL, parkedcall, strdup(exten), free, registrar);
} }
if (peer) ast_say_digits(peer, pu->parkingnum, "", peer->language);
return 0; return 0;
} else { } else {
ast_log(LOG_WARNING, "No more parking spaces\n"); ast_log(LOG_WARNING, "No more parking spaces\n");
@@ -558,6 +568,7 @@ static void *do_parking_thread(void *ignore)
struct timeval tv; struct timeval tv;
struct ast_frame *f; struct ast_frame *f;
char exten[AST_MAX_EXTENSION]; char exten[AST_MAX_EXTENSION];
char *peername,*cp;
struct ast_context *con; struct ast_context *con;
int x; int x;
int gc=0; int gc=0;
@@ -565,13 +576,13 @@ static void *do_parking_thread(void *ignore)
fd_set nrfds, nefds; fd_set nrfds, nefds;
FD_ZERO(&rfds); FD_ZERO(&rfds);
FD_ZERO(&efds); FD_ZERO(&efds);
for (;;) { for (;;) {
ms = -1; ms = -1;
max = -1; max = -1;
ast_mutex_lock(&parking_lock); ast_mutex_lock(&parking_lock);
pl = NULL; pl = NULL;
pu = parkinglot; pu = parkinglot;
gettimeofday(&tv, NULL);
FD_ZERO(&nrfds); FD_ZERO(&nrfds);
FD_ZERO(&nefds); FD_ZERO(&nefds);
while(pu) { while(pu) {
@@ -585,17 +596,40 @@ static void *do_parking_thread(void *ignore)
gc++; gc++;
ast_moh_start(pu->chan,NULL); ast_moh_start(pu->chan,NULL);
} }
gettimeofday(&tv, NULL);
tms = (tv.tv_sec - pu->start.tv_sec) * 1000 + (tv.tv_usec - pu->start.tv_usec) / 1000; tms = (tv.tv_sec - pu->start.tv_sec) * 1000 + (tv.tv_usec - pu->start.tv_usec) / 1000;
if (tms > pu->parkingtime) { if (tms > pu->parkingtime) {
/* They've been waiting too long, send them back to where they came. Theoretically they
should have their original extensions and such, but we copy to be on the safe side */
strncpy(pu->chan->exten, pu->exten, sizeof(pu->chan->exten)-1);
strncpy(pu->chan->context, pu->context, sizeof(pu->chan->context)-1);
pu->chan->priority = pu->priority;
if (option_verbose > 1)
ast_verbose(VERBOSE_PREFIX_2 "Timeout for %s parked on %d. Returning to %s,%s,%d\n", pu->chan->name, pu->parkingnum, pu->chan->context, pu->chan->exten, pu->chan->priority);
/* Stop music on hold */ /* Stop music on hold */
ast_moh_stop(pu->chan); ast_moh_stop(pu->chan);
/* Get chan, exten from derived kludge */
if (pu->peername[0])
{
peername = strdupa(pu->peername);
cp = strrchr(peername,'-');
if (cp) *cp = 0;
con = ast_context_find(parking_con_dial);
if (!con) {
con = ast_context_create(NULL,parking_con_dial, registrar);
if (!con) {
ast_log(LOG_ERROR, "Parking dial context '%s' does not exist and unable to create\n", parking_con_dial);
}
}
if (con) {
ast_add_extension2(con, 1, peername, 1, NULL, NULL, "Dial", strdup(peername), free, registrar);
}
strncpy(pu->chan->exten, peername, sizeof(pu->chan->exten)-1);
strncpy(pu->chan->context, parking_con_dial, sizeof(pu->chan->context)-1);
pu->chan->priority = 1;
} else {
/* They've been waiting too long, send them back to where they came. Theoretically they
should have their original extensions and such, but we copy to be on the safe side */
strncpy(pu->chan->exten, pu->exten, sizeof(pu->chan->exten)-1);
strncpy(pu->chan->context, pu->context, sizeof(pu->chan->context)-1);
pu->chan->priority = pu->priority;
}
if (option_verbose > 1)
ast_verbose(VERBOSE_PREFIX_2 "Timeout for %s parked on %d. Returning to %s,%s,%d\n", pu->chan->name, pu->parkingnum, pu->chan->context, pu->chan->exten, pu->chan->priority);
/* Start up the PBX, or hang them up */ /* Start up the PBX, or hang them up */
if (ast_pbx_start(pu->chan)) { if (ast_pbx_start(pu->chan)) {
ast_log(LOG_WARNING, "Unable to restart the PBX for user on '%s', hanging them up...\n", pu->chan->name); ast_log(LOG_WARNING, "Unable to restart the PBX for user on '%s', hanging them up...\n", pu->chan->name);

View File

@@ -29,7 +29,7 @@ static unsigned long seq = 0;
static char *monitor_synopsis = "Monitor a channel"; static char *monitor_synopsis = "Monitor a channel";
static char *monitor_descrip = "Monitor([file_format|[fname_base]|[options]]):\n" static char *monitor_descrip = "Monitor([file_format[:urlbase]|[fname_base]|[options]]):\n"
"Used to start monitoring a channel. The channel's input and output\n" "Used to start monitoring a channel. The channel's input and output\n"
"voice packets are logged to files until the channel hangs up or\n" "voice packets are logged to files until the channel hangs up or\n"
"monitoring is stopped by the StopMonitor application.\n" "monitoring is stopped by the StopMonitor application.\n"
@@ -307,6 +307,8 @@ static int start_monitor_exec(struct ast_channel *chan, void *data)
char *fname_base = NULL; char *fname_base = NULL;
char *options = NULL; char *options = NULL;
char *delay = NULL; char *delay = NULL;
char *urlprefix = NULL;
char tmp[256];
int joinfiles = 0; int joinfiles = 0;
int waitforbridge = 0; int waitforbridge = 0;
int res = 0; int res = 0;
@@ -315,6 +317,13 @@ static int start_monitor_exec(struct ast_channel *chan, void *data)
if (data && !ast_strlen_zero((char*)data)) { if (data && !ast_strlen_zero((char*)data)) {
arg = ast_strdupa((char*)data); arg = ast_strdupa((char*)data);
format = arg; format = arg;
arg = strchr(format,':');
if (arg)
{
*arg++ = 0;
urlprefix = arg;
}
else arg = format;
fname_base = strchr(arg, '|'); fname_base = strchr(arg, '|');
if (fname_base) { if (fname_base) {
*fname_base = 0; *fname_base = 0;
@@ -329,7 +338,14 @@ static int start_monitor_exec(struct ast_channel *chan, void *data)
} }
} }
} }
if (urlprefix)
{
snprintf(tmp,sizeof(tmp) - 1,"%s/%s.%s",urlprefix,fname_base,
((strcmp(format,"gsm")) ? "wav" : "gsm"));
if (!chan->cdr)
chan->cdr = ast_cdr_alloc();
ast_cdr_setuserfield(chan, tmp);
}
if (waitforbridge) { if (waitforbridge) {
/* We must remove the "b" option if listed. In principle none of /* We must remove the "b" option if listed. In principle none of
the following could give NULL results, but we check just to the following could give NULL results, but we check just to