Thu Oct 11 06:47:16 2012

Asterisk developer's documentation


func_cdr.c

Go to the documentation of this file.
00001 /*
00002  * Asterisk -- An open source telephony toolkit.
00003  *
00004  * Copyright (C) 1999-2006, Digium, Inc.
00005  *
00006  * Portions Copyright (C) 2005, Anthony Minessale II
00007  *
00008  * See http://www.asterisk.org for more information about
00009  * the Asterisk project. Please do not directly contact
00010  * any of the maintainers of this project for assistance;
00011  * the project provides a web site, mailing lists and IRC
00012  * channels for your use.
00013  *
00014  * This program is free software, distributed under the terms of
00015  * the GNU General Public License Version 2. See the LICENSE file
00016  * at the top of the source tree.
00017  */
00018 
00019 /*! \file
00020  *
00021  * \brief  Call Detail Record related dialplan functions
00022  *
00023  * \author Anthony Minessale II 
00024  *
00025  * \ingroup functions
00026  */
00027 
00028 #include "asterisk.h"
00029 
00030 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 238234 $")
00031 
00032 #include "asterisk/module.h"
00033 #include "asterisk/channel.h"
00034 #include "asterisk/pbx.h"
00035 #include "asterisk/utils.h"
00036 #include "asterisk/app.h"
00037 #include "asterisk/cdr.h"
00038 
00039 /*** DOCUMENTATION
00040    <function name="CDR" language="en_US">
00041       <synopsis>
00042          Gets or sets a CDR variable.
00043       </synopsis> 
00044       <syntax>
00045          <parameter name="name" required="true">
00046             <para>CDR field name:</para>
00047             <enumlist>
00048                <enum name="clid">
00049                   <para>Caller ID.</para>
00050                </enum>
00051                <enum name="lastdata">
00052                   <para>Last application arguments.</para>
00053                </enum>
00054                <enum name="disposition">
00055                   <para>ANSWERED, NO ANSWER, BUSY, FAILED.</para>
00056                </enum>
00057                <enum name="src">
00058                   <para>Source.</para>
00059                </enum>
00060                <enum name="start">
00061                   <para>Time the call started.</para>
00062                </enum>
00063                <enum name="amaflags">
00064                   <para>DOCUMENTATION, BILL, IGNORE, etc.</para>
00065                </enum>
00066                <enum name="dst">
00067                   <para>Destination.</para>
00068                </enum>
00069                <enum name="answer">
00070                   <para>Time the call was answered.</para>
00071                </enum>
00072                <enum name="accountcode">
00073                   <para>The channel's account code.</para>
00074                </enum>
00075                <enum name="dcontext">
00076                   <para>Destination context.</para>
00077                </enum>
00078                <enum name="end">
00079                   <para>Time the call ended.</para>
00080                </enum>
00081                <enum name="uniqueid">
00082                   <para>The channel's unique id.</para>
00083                </enum>
00084                <enum name="dstchannel">
00085                   <para>Destination channel.</para>
00086                </enum>
00087                <enum name="duration">
00088                   <para>Duration of the call.</para>
00089                </enum>
00090                <enum name="userfield">
00091                   <para>The channel's user specified field.</para>
00092                </enum>
00093                <enum name="lastapp">
00094                   <para>Last application.</para>
00095                </enum>
00096                <enum name="billsec">
00097                   <para>Duration of the call once it was answered.</para>
00098                </enum>
00099                <enum name="channel">
00100                   <para>Channel name.</para>
00101                </enum>
00102             </enumlist>
00103          </parameter>
00104          <parameter name="options" required="false">
00105             <optionlist>
00106                <option name="l">
00107                   <para>Uses the most recent CDR on a channel with multiple records</para>
00108                </option>
00109                <option name="r">
00110                   <para>Searches the entire stack of CDRs on the channel.</para>
00111                </option>
00112                <option name="s">
00113                   <para>Skips any CDR's that are marked 'LOCKED' due to forkCDR() calls.
00114                   (on setting/writing CDR vars only)</para>
00115                </option>
00116                <option name="u">
00117                   <para>Retrieves the raw, unprocessed value.</para>
00118                   <para>For example, 'start', 'answer', and 'end' will be retrieved as epoch
00119                   values, when the <literal>u</literal> option is passed, but formatted as YYYY-MM-DD HH:MM:SS
00120                   otherwise.  Similarly, disposition and amaflags will return their raw
00121                   integral values.</para>
00122                </option>
00123             </optionlist>
00124          </parameter>
00125       </syntax>
00126       <description>
00127          <para>All of the CDR field names are read-only, except for <literal>accountcode</literal>,
00128          <literal>userfield</literal>, and <literal>amaflags</literal>. You may, however, supply
00129          a name not on the above list, and create your own variable, whose value can be changed
00130          with this function, and this variable will be stored on the cdr.</para>
00131          <note><para>For setting CDR values, the <literal>l</literal> flag does not apply to
00132          setting the <literal>accountcode</literal>, <literal>userfield</literal>, or
00133          <literal>amaflags</literal>.</para></note>
00134          <para>Raw values for <literal>disposition</literal>:</para>
00135          <enumlist>
00136             <enum name="0">
00137                <para>NO ANSWER</para>
00138             </enum>
00139             <enum name="1">
00140                <para>NO ANSWER (NULL record)</para>
00141             </enum>
00142             <enum name="2">
00143                <para>FAILED</para>
00144             </enum>
00145             <enum name="4">
00146                <para>BUSY</para>
00147             </enum>
00148             <enum name="8">
00149                <para>ANSWERED</para>
00150             </enum>
00151          </enumlist>
00152          <para>Raw values for <literal>amaflags</literal>:</para>
00153          <enumlist>
00154             <enum name="1">
00155                <para>OMIT</para>
00156             </enum>
00157             <enum name="2">
00158                <para>BILLING</para>
00159             </enum>
00160             <enum name="3">
00161                <para>DOCUMENTATION</para>
00162             </enum>
00163          </enumlist>
00164          <para>Example: exten => 1,1,Set(CDR(userfield)=test)</para>
00165       </description>
00166    </function>
00167  ***/
00168 
00169 enum {
00170    OPT_RECURSIVE = (1 << 0),
00171    OPT_UNPARSED = (1 << 1),
00172    OPT_LAST = (1 << 2),
00173    OPT_SKIPLOCKED = (1 << 3),
00174 } cdr_option_flags;
00175 
00176 AST_APP_OPTIONS(cdr_func_options, {
00177    AST_APP_OPTION('l', OPT_LAST),
00178    AST_APP_OPTION('r', OPT_RECURSIVE),
00179    AST_APP_OPTION('s', OPT_SKIPLOCKED),
00180    AST_APP_OPTION('u', OPT_UNPARSED),
00181 });
00182 
00183 static int cdr_read(struct ast_channel *chan, const char *cmd, char *parse,
00184           char *buf, size_t len)
00185 {
00186    char *ret;
00187    struct ast_flags flags = { 0 };
00188    struct ast_cdr *cdr = chan ? chan->cdr : NULL;
00189    AST_DECLARE_APP_ARGS(args,
00190               AST_APP_ARG(variable);
00191               AST_APP_ARG(options);
00192    );
00193 
00194    if (ast_strlen_zero(parse))
00195       return -1;
00196 
00197    if (!cdr)
00198       return -1;
00199 
00200    AST_STANDARD_APP_ARGS(args, parse);
00201 
00202    if (!ast_strlen_zero(args.options))
00203       ast_app_parse_options(cdr_func_options, &flags, NULL, args.options);
00204 
00205    if (ast_test_flag(&flags, OPT_LAST))
00206       while (cdr->next)
00207          cdr = cdr->next;
00208 
00209    if (ast_test_flag(&flags, OPT_SKIPLOCKED))
00210       while (ast_test_flag(cdr, AST_CDR_FLAG_LOCKED) && cdr->next)
00211          cdr = cdr->next;
00212 
00213    ast_cdr_getvar(cdr, args.variable, &ret, buf, len,
00214              ast_test_flag(&flags, OPT_RECURSIVE),
00215             ast_test_flag(&flags, OPT_UNPARSED));
00216 
00217    return ret ? 0 : -1;
00218 }
00219 
00220 static int cdr_write(struct ast_channel *chan, const char *cmd, char *parse,
00221            const char *value)
00222 {
00223    struct ast_cdr *cdr = chan ? chan->cdr : NULL;
00224    struct ast_flags flags = { 0 };
00225    AST_DECLARE_APP_ARGS(args,
00226               AST_APP_ARG(variable);
00227               AST_APP_ARG(options);
00228    );
00229 
00230    if (ast_strlen_zero(parse) || !value || !chan)
00231       return -1;
00232 
00233    if (!cdr)
00234       return -1;
00235 
00236    AST_STANDARD_APP_ARGS(args, parse);
00237 
00238    if (!ast_strlen_zero(args.options))
00239       ast_app_parse_options(cdr_func_options, &flags, NULL, args.options);
00240 
00241    if (ast_test_flag(&flags, OPT_LAST))
00242       while (cdr->next)
00243          cdr = cdr->next;
00244 
00245    if (!strcasecmp(args.variable, "accountcode"))  /* the 'l' flag doesn't apply to setting the accountcode, userfield, or amaflags */
00246       ast_cdr_setaccount(chan, value);
00247    else if (!strcasecmp(args.variable, "userfield"))
00248       ast_cdr_setuserfield(chan, value);
00249    else if (!strcasecmp(args.variable, "amaflags"))
00250       ast_cdr_setamaflags(chan, value);
00251    else
00252       ast_cdr_setvar(cdr, args.variable, value, ast_test_flag(&flags, OPT_RECURSIVE));
00253       /* No need to worry about the u flag, as all fields for which setting
00254        * 'u' would do anything are marked as readonly. */
00255 
00256    return 0;
00257 }
00258 
00259 static struct ast_custom_function cdr_function = {
00260    .name = "CDR",
00261    .read = cdr_read,
00262    .write = cdr_write,
00263 };
00264 
00265 static int unload_module(void)
00266 {
00267    return ast_custom_function_unregister(&cdr_function);
00268 }
00269 
00270 static int load_module(void)
00271 {
00272    return ast_custom_function_register(&cdr_function);
00273 }
00274 
00275 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Call Detail Record (CDR) dialplan function");

Generated on Thu Oct 11 06:47:16 2012 for Asterisk - the Open Source PBX by  doxygen 1.5.6