[asterisk-commits] murf: branch group/CDRfix5 r75032 - /team/group/CDRfix5/doc/tex/cdrbible.tex
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Fri Jul 13 09:26:26 CDT 2007
Author: murf
Date: Fri Jul 13 09:26:26 2007
New Revision: 75032
URL: http://svn.digium.com/view/asterisk?view=rev&rev=75032
Log:
Checking in work on the 'bible'
Modified:
team/group/CDRfix5/doc/tex/cdrbible.tex
Modified: team/group/CDRfix5/doc/tex/cdrbible.tex
URL: http://svn.digium.com/view/asterisk/team/group/CDRfix5/doc/tex/cdrbible.tex?view=diff&rev=75032&r1=75031&r2=75032
==============================================================================
--- team/group/CDRfix5/doc/tex/cdrbible.tex (original)
+++ team/group/CDRfix5/doc/tex/cdrbible.tex Fri Jul 13 09:26:26 2007
@@ -152,10 +152,195 @@
compatible ways!
\subsection{Making Your Own CDRs}
+
+The dialplan Function, CDR_CONTROL() is used to implement posting your own CDR records to the
+backends.
+
+Since Asterisk does not post unbridged calls, it's up to you to post such things if you
+want to keep track of them in your database.
+
+The CDR_CONTROL() function takes up to two arguments; the first is an action and should
+be one of:
+\begin{itemize}
+ \item start -- allocate a CDR struct, pass back a 'handle' to the struct.
+ \item answer -- Set the answer time in the CDR
+ \item close -- Set the end time for the CDR, post and free it.
+ \item abort -- Discard the CDR, free its memory.
+\end{itemize}
+
+The second argument to CDR_CONTROL() is the handle returned by the 'start' action. Thus,
+a call with the 'start' action requires no second argument, but all other actions will require a
+CDR 'handle' argument.
+
+The CDR() function has been modified to take an optional second argument, which should be the
+handle returned from CDR_CONTROL(start). You can set nearly every field in this allocated CDR.
+You can store the "handle" returned from CDR_CONTROL(start) in a channel or global variable.
+
+CDR_CONTROL(close,handle) will set the end time, calculate and set the duration and billsec
+times, and then post the CDR to the backends, and free the CDR.
+
+CDR_CONTROL(abort,handle) will free the CDR associated with the handle. If you change your mind
+about posting this CDR, pass its handle into this function, and you will free up its allocated
+memory for other purposes.
+
+
+As an example of how you might implement using CDRs to track 'unanswered' calls, I present the
+following annotated dialplan (in AEL, of course!)
+
+\begin{verbatim}
+context incoming
+{
+/* let's assume a ZAP FXO interface connects the PBX to the local phone company.
+ The context specified in zapata.conf for that interface is this context.
+ Calls coming in from the phone company will run the "s" extension of this context */
+
+ s => {
+ Set(myCDR=CDR_CONTROL(start); /* create and set the start time in myCDR */
+ Set(mySTATE=PRE_ANSWER); /* keep track of where we are in the dialplan */
+ Set(CDR(channel,${myCDR})=${CHANNEL});
+ Set(CDR(src,${myCDR})=${CALLERID(number)});
+
+ Answer(); /* the PBX answering a call is uninteresting from a billing perspective */
+ Set(mySTATE=PRE_ZAPATELLER);
+ Zapateller();
+ Set(mySTATE=PRE_PRIVMAN);
+ PrivacyManager();
+ Set(mySTATE=PRE_DIAL);
+ /* background some announcement here */
+ }
+
+ h => { /* THE HANG-UP EXTENSION */
+ switch(${mySTATE})
+ {
+ case PRE_ANSWER:
+ Set(CDR(lastapp,${myCDR})=PRE_ANSWER);
+ NoOp(${CDR_CONTROL(close,${myCDR}); /* publish it */
+ break;
+ case PRE_ZAPATELLER:
+ Set(CDR(lastapp,${myCDR})=ANSWER);
+ NoOp(${CDR_CONTROL(close,${myCDR}); /* publish it */
+ break;
+ case PRE_PRIVMAN:
+ Set(CDR(lastapp,${myCDR})=ZAPATELLER);
+ NoOp(${CDR_CONTROL(close,${myCDR}); /* publish it */
+ break;
+ case PRE_DIAL:
+ Set(CDR(lastapp,${myCDR})=PRIVMAN);
+ /* if we are in hangup in this state, we can assume that
+ we proceeded into DIAL, and never returned. The call must
+ have been bridged, and an Asterisk CDR was already generated */
+ NoOp(${CDR_CONTROL(abort,${myCDR}); /* so we don't need this one */
+ break;
+ case DIAL:
+ /* the disposition has already been set... it will not be ANSWERED */
+ NoOp(${CDR_CONTROL(close,${myCDR}); /* publish it */
+ break;
+ }
+ Set(myCDR=); /* null out the handle for safety */
+ }
+
+ _1XX => { /* the users dialed a 3 digit extension starting with 1 */
+
+ /* what a wild coincidence! The last two digits of the exten are also the
+ Zap channel numbers! */
+ Set(CDR(dst,${myCDR})=${EXTEN});
+ Set(CDR(dstchannel,${myCDR})=Zap/${EXTEN:1});
+
+ Dial(Zap/${EXTEN:1},30,t); /* assume that if the call is bridged, then, when it ends,
+ we will end up in the h exten */
+ Set(mySTATE=DIAL);
+ switch(${DIALSTATUS}) /* and if it is not bridged, we will end up here */
+ {
+ case CHANUNAVAIL:
+ Set(CDR(disposition,${myCDR})=1); /* FAILED */
+ break;
+ case CONGESTION:
+ Set(CDR(disposition,${myCDR})=1); /* FAILED */
+ break;
+ case NOANSWER:
+ Set(CDR(disposition,${myCDR})=4); /* NO ANSWER */
+ break;
+ case BUSY:
+ Set(CDR(disposition,${myCDR})=2); /* BUSY */
+ break;
+ case CANCEL:
+ Set(CDR(disposition,${myCDR})=1); /* FAILED */
+ break;
+ case DONTCALL:
+ Set(CDR(disposition,${myCDR})=4); /* NO ANSWER */
+ break;
+ case TORTURE:
+ Set(CDR(disposition,${myCDR})=4); /* NO ANSWER */
+ break;
+ case INVALIDARGS:
+ Set(CDR(disposition,${myCDR})=1); /* FAILED */
+ break;
+ }
+ /* at this point, the flow of control ends, and the PBX will hang up this channel */
+ }
+}
+\end{verbatim}
+
+The above dialplan will generate a clearly labeled CDR in case the calling party hangs up before
+talking to someone at an extension. If the call actually completes, then myCDR is not needed,
+and can be aborted.
+
+While most incoming conversations like this are of little interest for billing, the above code
+is a good example of how the CDR_CONTROL() function can be used to track such traffic.
+
+Sometimes, you might want to bill, or at least track, the usage of some application by incoming
+callers. Easy! Let's see how:
+
+\begin{verbatim}
+context incoming
+{
+/* let's assume a ZAP FXO interface connects the PBX to the local phone company.
+ The context specified in zapata.conf for that interface is this context.
+ Calls coming in from the phone company will run the "s" extension of this context */
+
+ s => {
+ /* background some announcement here */
+ }
+
+ h => { /* THE HANG-UP EXTENSION */
+ /* if the user hangs up before the app finishes, you still need to
+ publish myCDR */
+ if("${myCDR}" != "") {
+ NoOp(${CDR_CONTROL(close,${myCDR}); /* publish it */
+ Set(myCDR=); /* null out the handle for safety */
+ }
+ }
+
+ 103 => {
+ /* let's time how long someone spends in an app/agi/whatever! */
+ Set(myCDR=CDR_CONTROL(start); /* create and set the start time in myCDR */
+ Set(CDR(channel,${myCDR})=${CHANNEL}); /* these CDR's are blank sheets, best to fill in the blanks */
+ Set(CDR(src,${myCDR})=${CALLERID(number)});
+ Set(CDR(disposition,${myCDR})=8); /* ANSWER */
+ Set(CDR(lastapp,${myCDR})=SPECIAL_APP);
+ NoOp(${CDR_CONTROL(answer,${myCDR}); /* before the app runs, set the answer time */
+ SpecialApp(args);
+ NoOp(${CDR_CONTROL(close,${myCDR}); /* publish it */
+ Set(myCDR=); /* null out the handle for safety */
+ /* done */
+ }
+}
+\end{verbatim}
+
+In the above example, we publish a CDR to track time spent in SpecialApp(). If the incoming
+caller hangs up before SpecialApp() returns, we close the CDR in the "h" extension.
+
+
\subsection{Suppressing Asterisk-Generated CDRs}
+
+More to come.
+
\subsection{Gotchas and Complications}
+
+What happens in transfers.
+
\subsection{Backend Mappings}
-Here is a short snippet I spotted on IRC, in #asterisk, just this morning. I changed the names.
+Here is a short snippet I spotted on IRC, in #asterisk, just this morning.(I changed the names).
\begin{verbatim}
X: Y, also, can't you use cdr_tds for mssql?
Y: X: yes that is also possible
More information about the asterisk-commits
mailing list