[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