mirror of
https://github.com/asterisk/asterisk.git
synced 2025-10-14 16:33:34 +00:00
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:
@@ -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;
|
||||||
}
|
}
|
||||||
|
@@ -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 {
|
||||||
|
@@ -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")) {
|
||||||
|
@@ -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
|
||||||
|
@@ -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);
|
||||||
|
@@ -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
|
||||||
|
Reference in New Issue
Block a user