Set ${DIALSTATUS} from app_dial, make zap return BUSY on a phone that is busy, update macro-stdexten to demo

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@3282 65c4cc65-6c06-0410-ace0-fbb531ad65f3
1.0
Mark Spencer 22 years ago
parent 0f6db9f939
commit 2187465cae

@ -122,12 +122,14 @@ static void hanguptree(struct localuser *outgoing, struct ast_channel *exception
#define AST_MAX_WATCHERS 256 #define AST_MAX_WATCHERS 256
static struct ast_channel *wait_for_answer(struct ast_channel *in, struct localuser *outgoing, int *to, int *allowredir_in, int *allowredir_out, int *allowdisconnect, int *sentringing) static struct ast_channel *wait_for_answer(struct ast_channel *in, struct localuser *outgoing, int *to, int *allowredir_in, int *allowredir_out, int *allowdisconnect, int *sentringing, char *status)
{ {
struct localuser *o; struct localuser *o;
int found; int found;
int numlines; int numlines;
int numbusies = 0; int numbusy = 0;
int numcongestion = 0;
int numnochan = 0;
int orig = *to; int orig = *to;
struct ast_frame *f; struct ast_frame *f;
struct ast_channel *peer = NULL; struct ast_channel *peer = NULL;
@ -162,9 +164,15 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in, struct localu
numlines++; numlines++;
} }
if (found < 0) { if (found < 0) {
if (numlines == numbusies) { if (numlines == (numbusy + numcongestion + numnochan)) {
if (option_verbose > 2) if (option_verbose > 2)
ast_verbose( VERBOSE_PREFIX_2 "Everyone is busy at this time\n"); ast_verbose( VERBOSE_PREFIX_2 "Everyone is busy/congested at this time\n");
if (numbusy)
strcpy(status, "BUSY");
else if (numcongestion)
strcpy(status, "CONGESTION");
else if (numnochan)
strcpy(status, "CHANUNAVAIL");
/* See if there is a special busy message */ /* See if there is a special busy message */
if (ast_exists_extension(in, in->context, in->exten, in->priority + 101, in->callerid)) if (ast_exists_extension(in, in->context, in->exten, in->priority + 101, in->callerid))
in->priority+=100; in->priority+=100;
@ -211,7 +219,7 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in, struct localu
if (!o->chan) { if (!o->chan) {
ast_log(LOG_NOTICE, "Unable to create local channel for call forward to '%s/%s'\n", tech, stuff); ast_log(LOG_NOTICE, "Unable to create local channel for call forward to '%s/%s'\n", tech, stuff);
o->stillgoing = 0; o->stillgoing = 0;
numbusies++; numnochan++;
} else { } else {
if (o->chan->callerid) if (o->chan->callerid)
free(o->chan->callerid); free(o->chan->callerid);
@ -255,7 +263,7 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in, struct localu
o->stillgoing = 0; o->stillgoing = 0;
ast_hangup(o->chan); ast_hangup(o->chan);
o->chan = NULL; o->chan = NULL;
numbusies++; numnochan++;
} }
} }
continue; continue;
@ -284,7 +292,7 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in, struct localu
o->stillgoing = 0; o->stillgoing = 0;
if (in->cdr) if (in->cdr)
ast_cdr_busy(in->cdr); ast_cdr_busy(in->cdr);
numbusies++; numbusy++;
break; break;
case AST_CONTROL_CONGESTION: case AST_CONTROL_CONGESTION:
if (option_verbose > 2) if (option_verbose > 2)
@ -295,7 +303,7 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in, struct localu
o->stillgoing = 0; o->stillgoing = 0;
if (in->cdr) if (in->cdr)
ast_cdr_busy(in->cdr); ast_cdr_busy(in->cdr);
numbusies++; numcongestion++;
break; break;
case AST_CONTROL_RINGING: case AST_CONTROL_RINGING:
if (option_verbose > 2) if (option_verbose > 2)
@ -418,6 +426,7 @@ static int dial_exec(struct ast_channel *chan, void *data)
char *sdtmfptr; char *sdtmfptr;
char sdtmfdata[256] = ""; char sdtmfdata[256] = "";
char *stack,*var; char *stack,*var;
char status[256];
int play_to_caller=0,play_to_callee=0; int play_to_caller=0,play_to_callee=0;
int playargs=0, sentringing=0, moh=0; int playargs=0, sentringing=0, moh=0;
int digit = 0; int digit = 0;
@ -816,6 +825,8 @@ static int dial_exec(struct ast_channel *chan, void *data)
to = -1; to = -1;
if (outgoing) { if (outgoing) {
/* Our status will at least be NOANSWER */
strcpy(status, "NOANSWER");
if (outgoing->musiconhold) { if (outgoing->musiconhold) {
moh=1; moh=1;
ast_moh_start(chan, NULL); ast_moh_start(chan, NULL);
@ -823,9 +834,10 @@ static int dial_exec(struct ast_channel *chan, void *data)
ast_indicate(chan, AST_CONTROL_RINGING); ast_indicate(chan, AST_CONTROL_RINGING);
sentringing++; sentringing++;
} }
} } else
strcpy(status, "CHANUNAVAIL");
peer = wait_for_answer(chan, outgoing, &to, &allowredir_in, &allowredir_out, &allowdisconnect, &sentringing); peer = wait_for_answer(chan, outgoing, &to, &allowredir_in, &allowredir_out, &allowdisconnect, &sentringing, status);
if (!peer) { if (!peer) {
if (to) if (to)
@ -838,6 +850,7 @@ static int dial_exec(struct ast_channel *chan, void *data)
goto out; goto out;
} }
if (peer) { if (peer) {
strcpy(status, "ANSWER");
/* Ah ha! Someone answered within the desired timeframe. Of course after this /* Ah ha! Someone answered within the desired timeframe. Of course after this
we will always return with -1 so that it is hung up properly after the we will always return with -1 so that it is hung up properly after the
conversation. */ conversation. */
@ -929,6 +942,8 @@ out:
ast_indicate(chan, -1); ast_indicate(chan, -1);
} }
hanguptree(outgoing, NULL); hanguptree(outgoing, NULL);
pbx_builtin_setvar_helper(chan, "DIALSTATUS", status);
LOCAL_USER_REMOVE(u); LOCAL_USER_REMOVE(u);
if((go_on>0) && (!chan->_softhangup)) if((go_on>0) && (!chan->_softhangup))

@ -1448,6 +1448,14 @@ static int zt_call(struct ast_channel *ast, char *rdest, int timeout)
ast_mutex_lock(&p->lock); ast_mutex_lock(&p->lock);
strncpy(dest, rdest, sizeof(dest) - 1); strncpy(dest, rdest, sizeof(dest) - 1);
strncpy(p->dialdest, rdest, sizeof(dest) - 1); strncpy(p->dialdest, rdest, sizeof(dest) - 1);
if ((ast->_state == AST_STATE_BUSY)) {
struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_BUSY };
/* If this is a placeholder frame for a busy channel,
return busy state immediately */
zap_queue_frame(p, &f);
ast_mutex_unlock(&p->lock);
return 0;
}
if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) { if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) {
ast_log(LOG_WARNING, "zt_call called on %s, neither down nor reserved\n", ast->name); ast_log(LOG_WARNING, "zt_call called on %s, neither down nor reserved\n", ast->name);
ast_mutex_unlock(&p->lock); ast_mutex_unlock(&p->lock);
@ -6136,7 +6144,7 @@ static struct zt_pvt *mkintf(int channel, int signalling, int radio, struct zt_p
return tmp; return tmp;
} }
static inline int available(struct zt_pvt *p, int channelmatch, int groupmatch) static inline int available(struct zt_pvt *p, int channelmatch, int groupmatch, int *busy)
{ {
int res; int res;
ZT_PARAMS par; ZT_PARAMS par;
@ -6146,6 +6154,11 @@ static inline int available(struct zt_pvt *p, int channelmatch, int groupmatch)
/* Check to see if we have a channel match */ /* Check to see if we have a channel match */
if ((channelmatch > 0) && (p->channel != channelmatch)) if ((channelmatch > 0) && (p->channel != channelmatch))
return 0; return 0;
/* We're at least busy at this point */
if ((p->sig == SIG_FXOKS) || (p->sig == SIG_FXOLS) || (p->sig == SIG_FXOGS)) {
if (busy)
*busy = 1;
}
/* If do not distrub, definitely not */ /* If do not distrub, definitely not */
if (p->dnd) if (p->dnd)
return 0; return 0;
@ -6293,6 +6306,7 @@ static struct ast_channel *zt_request(char *type, int format, void *data)
int channelmatch = -1; int channelmatch = -1;
int roundrobin = 0; int roundrobin = 0;
int callwait = 0; int callwait = 0;
int busy = 0;
struct zt_pvt *p; struct zt_pvt *p;
struct ast_channel *tmp = NULL; struct ast_channel *tmp = NULL;
char *dest=NULL; char *dest=NULL;
@ -6405,7 +6419,7 @@ static struct ast_channel *zt_request(char *type, int format, void *data)
#if 0 #if 0
ast_verbose("name = %s, %d\n",p->owner->name,p->channel); ast_verbose("name = %s, %d\n",p->owner->name,p->channel);
#endif #endif
if (p && available(p, channelmatch, groupmatch)) { if (p && available(p, channelmatch, groupmatch, &busy)) {
if (option_debug) if (option_debug)
ast_log(LOG_DEBUG, "Using channel %d\n", p->channel); ast_log(LOG_DEBUG, "Using channel %d\n", p->channel);
if (p->inalarm) if (p->inalarm)
@ -6483,6 +6497,19 @@ next:
} }
ast_mutex_unlock(lock); ast_mutex_unlock(lock);
restart_monitor(); restart_monitor();
if (!tmp) {
if (busy) {
tmp = zt_request("Zap", format, "pseudo");
if (tmp) {
char newname[80];
ast_mutex_lock(&tmp->lock);
snprintf(newname, sizeof(newname), "Zap/%s-busy-%d", (char *)data, rand());
ast_change_name(tmp, newname);
ast_setstate(tmp, AST_STATE_BUSY);
ast_mutex_unlock(&tmp->lock);
}
}
}
return tmp; return tmp;
} }

@ -181,10 +181,16 @@ include => iaxprovider
; ${ARG2} - Device(s) to ring ; ${ARG2} - Device(s) to ring
; ;
exten => s,1,Dial(${ARG2},20) ; Ring the interface, 20 seconds maximum exten => s,1,Dial(${ARG2},20) ; Ring the interface, 20 seconds maximum
exten => s,2,Voicemail(u${ARG1}) ; If unavailable, send to voicemail w/ unavail announce exten => s,2,Goto(s-${DIALSTATUS}) ; Jump based on status (NOANSWER,BUSY,CHANUNAVAIL,CONGESTION,ANSWER)
exten => s,3,Goto(default,s,1) ; If they press #, return to start
exten => s,102,Voicemail(b${ARG1}) ; If busy, send to voicemail w/ busy announce exten => s-NOANSWER,1,Voicemail(u${ARG1}) ; If unavailable, send to voicemail w/ unavail announce
exten => s,103,Goto(default,s,1) ; If they press #, return to start exten => s-NOANSWER,2,Goto(default,s,1) ; If they press #, return to start
exten => s-BUSY,1,Voicemail(b${ARG1}) ; If busy, send to voicemail w/ busy announce
exten => s-BUSY,2,Goto(default,s,1) ; If they press #, return to start
exten => s-.,1,Goto(s-NOANSWER,1) ; Treat anything else as no answer
exten => a,1,VoicemailMain(${ARG1}) ; If they press *, send the user into VoicemailMain exten => a,1,VoicemailMain(${ARG1}) ; If they press *, send the user into VoicemailMain
[demo] [demo]

Loading…
Cancel
Save