[Asterisk-Users] Call completion/error codes and extensions.conf call flow

John Todd
Sun, 06 Apr 2003 12:09:29 -0000

There was a conversation last night on the IRC channel between
myself, Corydon76, citats, and kram on the ability of a call process
to access the error (or success?) codes underlying a call.  I'm
uncertain if anything came out of it, but I'll re-hash here to
solicit other comments.

My idea: I'd like to be able to get to error codes when a call passes
through some kind of action (with perhaps the exception of "Trying"
or other "non-end-of-message" results) so that I can play error
messages or take actions that are appropriate to the event.  As an
example, currently Asterisk only supports "busy" or
"unavailable"
call codes back from any channel type.  However, chan_sip can provide
a large array of codes that are more meaningful, such as "403
Forbidden" or "480 Temporarily unavailable" which can be more
useful
for both my internal logging as well as can trigger an appropriate
recording to be played back to the user.  Why code individual cases
inside of chan_blah when this can be extracted to allow the admin to
handle them as required?

Two solutions were discussed, one method using an application and the
other simply setting a channel variable.

METHOD 1:
Corydon76 suggested creating an application that handled the
redirection of the call process flow.  This would look something like
this:

OnResultGoto(201:+100,405:+200,480:+250)

where "201", "405", and "480" are the numeric
response codes
corresponding to some useful error message from the channel.  This
would be called immediately the Dial application.  Jumps would be
done within the existing context, to the priority X within the same
context where X is represented by "+X".


METHOD 2:
Simply set a channel variable with the result code.  I'd suggest
handing out two different variables: one with the numeric response,
and one with the "human-readable" response.  $RESULTCODE and
$RESULTTEXT might work.  This way, the existing routines of Goto and
GotoIf can be used, and large numbers of errors can be handled in
generic ways.  Plus, I'll say that I prefer this method since it
doesn't involve relative jumps (+X) which I really dislike for
generic use.



Other items that need to be handled regardless of method above:

1) The error message needs to be passed out of chan_blah to the main
routines.  This implies an error insertion routine in each channel
that can provide more information.  This may or may not remove
existing code that parses results and puts them into one of the three
existing buckets of "busy", "unavailable", or
"OK".

2) A "standardized" result code might be desirable, since building
separate error trees for each channel type would be tedious (IF you
are using multiple channel types.)  However, it may be the case that
a standardized code is undesirable, as with standardization comes the
loss of data which we may want in the first place.  citats suggested
looking at RFC3398 for an ISDN->SIP response mapping table
(http://rfc3398.x42.com/)  This may be best mapped in another .conf
file, such as "resultcodes.conf" which creates a channel-by-channel
mapping of response codes to some "universal" code used by Asterisk.
There is an argument that says that this mapping is not needed as
part of Asterisk's code, though, and it should be the administrator's
job to create different error contexts for each type of channel that
they are using...  I'm really not of any particular opinion on which
way this is done.

3) It may be the case that people using either one of the two
call-redirection methods above will NOT want the normal +101 busy
routines to be in effect for their Dial calls.  This is due to the
fact that the "busy" determination (previously hidden inside of
chan_blah) will now be available to the programmer,and they may not
wish to have their call flow abruptly jumped to +101 from their Dial
routines.  Can this be a selectable trigger?  If I'm writing call
flow routines, I'd really rather handle all responses in the same
subroutines instead of creating a special case for "busy" to handle
the jump that could easily be short-circuited.

i.e., if we assume that we use the "variable" method above and
$RESULTCODE is a three-digit numeric result code, I'd like my dial
routines to look like the example below. Note that I handle "busy" in
the same way as the rest of the results; no special +101 jumping
required.

[default]
exten => 2223,1,Dial(SIP/2223)
exten => 2223,2,Goto(endofcall,${RESULTCODE})

[endofcall]
; Response to normal end-of-call "200 OK" message
200 => s,1,Playback(thanks-for-using-the-foofram-call-system)
200 => s,2,Playback(please-take-a-survey-on-your-call-experience)
200 => s,3,Goto(survey)

; Response to "Busy here" reply
486 => s,1,Voicemail(b${EXTEN})
486 => s,2,Hangup

; response to "Resource temporarily unavailable"
480 => s,1,Playback(sorry-resource-temp-unavailable)
480 => s,2,Playback(please-try-again-later)
480 => s,3,Hangup

; Response to "Server Error"
500 => s,1,Playback(remote-server-has-an-error)
500 => s,2,Hangup

; Response to "Busy everywhere" reply
600 => s,1,Playback(sorry-everything-busy)
600 => s,2,Playback(but-you-can-leave-a-message)
600 => s,3,Goto(endofcall,486)


JT