[asterisk-commits] murf: branch murf/CDRfix5 r69131 -
/team/murf/CDRfix5/funcs/func_cdr.c
asterisk-commits at lists.digium.com
asterisk-commits at lists.digium.com
Wed Jun 13 11:24:12 MST 2007
Author: murf
Date: Wed Jun 13 13:24:12 2007
New Revision: 69131
URL: http://svn.digium.com/view/asterisk?view=rev&rev=69131
Log:
Created the funcs CDRstart, CDRanswer, and CDRclose. They work. Modded CDR to take 3rd arg of handle, to set all cdr vals
Modified:
team/murf/CDRfix5/funcs/func_cdr.c
Modified: team/murf/CDRfix5/funcs/func_cdr.c
URL: http://svn.digium.com/view/asterisk/team/murf/CDRfix5/funcs/func_cdr.c?view=diff&rev=69131&r1=69130&r2=69131
==============================================================================
--- team/murf/CDRfix5/funcs/func_cdr.c (original)
+++ team/murf/CDRfix5/funcs/func_cdr.c Wed Jun 13 13:24:12 2007
@@ -63,6 +63,7 @@
AST_DECLARE_APP_ARGS(args,
AST_APP_ARG(variable);
AST_APP_ARG(options);
+ AST_APP_ARG(handle);
);
if (ast_strlen_zero(parse))
@@ -90,10 +91,12 @@
static int cdr_write(struct ast_channel *chan, const char *cmd, char *parse,
const char *value)
{
+ struct ast_cdr *cdr = 0;
struct ast_flags flags = { 0 };
AST_DECLARE_APP_ARGS(args,
AST_APP_ARG(variable);
AST_APP_ARG(options);
+ AST_APP_ARG(handle);
);
if (ast_strlen_zero(parse) || !value || !chan)
@@ -104,24 +107,78 @@
if (!ast_strlen_zero(args.options))
ast_app_parse_options(cdr_func_options, &flags, NULL, args.options);
- if (!strcasecmp(args.variable, "accountcode"))
- ast_cdr_setaccount(chan, value);
- else if (!strcasecmp(args.variable, "userfield"))
- ast_cdr_setuserfield(chan, value);
- else if (!strcasecmp(args.variable, "amaflags"))
- ast_cdr_setamaflags(chan, value);
- else if (chan->cdr)
- ast_cdr_setvar(chan->cdr, args.variable, value, ast_test_flag(&flags, OPT_RECURSIVE));
+ if (ast_strlen_zero(args.handle)) {
+ if (!strcasecmp(args.variable, "accountcode"))
+ ast_cdr_setaccount(chan, value);
+ else if (!strcasecmp(args.variable, "userfield"))
+ ast_cdr_setuserfield(chan, value);
+ else if (!strcasecmp(args.variable, "amaflags"))
+ ast_cdr_setamaflags(chan, value);
+ else if (chan->cdr)
+ ast_cdr_setvar(chan->cdr, args.variable, value, ast_test_flag(&flags, OPT_RECURSIVE));
/* No need to worry about the u flag, as all fields for which setting
* 'u' would do anything are marked as readonly. */
-
- return 0;
+
+ return 0;
+ } else {
+ cdr = (struct ast_cdr*)strtoul(args.handle, NULL, 10);
+
+ if (!cdr) /* safety valve */
+ return 0;
+
+ if (!strcasecmp(args.variable, "accountcode"))
+ ast_copy_string(cdr->accountcode, value, sizeof(cdr->accountcode));
+ else if (!strcasecmp(args.variable, "userfield"))
+ ast_copy_string(cdr->userfield, value, sizeof(cdr->userfield));
+ else if (!strcasecmp(args.variable, "amaflags"))
+ {
+ if (atoi(value) > 0 )
+ cdr->amaflags = atoi(value);
+ else
+ cdr->amaflags = ast_cdr_amaflags2int(value);
+ } else if (!strcasecmp(args.variable, "clid"))
+ ast_copy_string(cdr->clid, value, sizeof(cdr->clid));
+ else if (!strcasecmp(args.variable, "src"))
+ ast_copy_string(cdr->src, value, sizeof(cdr->src));
+ else if (!strcasecmp(args.variable, "dst"))
+ ast_copy_string(cdr->dst, value, sizeof(cdr->dst));
+ else if (!strcasecmp(args.variable, "dcontext"))
+ ast_copy_string(cdr->dcontext, value, sizeof(cdr->dcontext));
+ else if (!strcasecmp(args.variable, "channel"))
+ ast_copy_string(cdr->channel, value, sizeof(cdr->channel));
+ else if (!strcasecmp(args.variable, "dstchannel"))
+ ast_copy_string(cdr->dstchannel, value, sizeof(cdr->dstchannel));
+ else if (!strcasecmp(args.variable, "lastapp"))
+ ast_copy_string(cdr->lastapp, value, sizeof(cdr->lastapp));
+ else if (!strcasecmp(args.variable, "lastdata"))
+ ast_copy_string(cdr->lastdata, value, sizeof(cdr->lastdata));
+ else if (!strcasecmp(args.variable, "disposition")) {
+ if (atoi(value) > 0)
+ cdr->disposition = atoi(value);
+ else {
+ if (strcasecmp(value,"NO ANSWER") == 0)
+ cdr->disposition = AST_CDR_NOANSWER;
+ else if (strcasecmp(value,"BUSY") == 0)
+ cdr->disposition = AST_CDR_BUSY;
+ else if (strcasecmp(value,"ANSWERED") == 0)
+ cdr->disposition = AST_CDR_ANSWERED;
+ else if (strcasecmp(value,"FAILED") == 0)
+ cdr->disposition = AST_CDR_FAILED;
+ else if (strcasecmp(value,"NULL") == 0)
+ cdr->disposition = AST_CDR_NULL;
+ }
+ } else if (!strcasecmp(args.variable, "uniqueid"))
+ ast_copy_string(cdr->uniqueid, value, sizeof(cdr->uniqueid));
+ else
+ ast_cdr_setvar(cdr, args.variable, value, ast_test_flag(&flags, OPT_RECURSIVE));
+ return 0;
+ }
}
static struct ast_custom_function cdr_function = {
.name = "CDR",
.synopsis = "Gets or sets a CDR variable",
- .syntax = "CDR(<name>[|options])",
+ .syntax = "CDR(<name>[|options[|handle]])",
.read = cdr_read,
.write = cdr_write,
.desc =
@@ -132,37 +189,179 @@
" values, when the 'u' option is passed, but formatted as YYYY-MM-DD HH:MM:SS\n"
" otherwise. Similarly, disposition and amaflags will return their raw\n"
" integral values.\n"
-" Here is a list of all the available cdr field names:\n"
-" clid lastdata disposition\n"
-" src start amaflags\n"
-" dst answer accountcode\n"
-" dcontext end uniqueid\n"
-" dstchannel duration userfield\n"
-" lastapp billsec channel\n"
-" All of the above variables are read-only, except for accountcode,\n"
-" userfield, and amaflags. You may, however, supply\n"
-" a name not on the above list, and create your own\n"
-" variable, whose value can be changed with this function,\n"
-" and this variable will be stored on the cdr.\n"
+"Here is a list of all the available cdr field names:\n"
+" clid lastdata disposition\n"
+" src start amaflags\n"
+" dst answer accountcode\n"
+" dcontext end uniqueid\n"
+" dstchannel duration userfield\n"
+" lastapp billsec channel\n"
+"All of the above variables are read-only, except for accountcode,\n"
+"userfield, and amaflags. You may, however, supply\n"
+"a name not on the above list, and create your own\n"
+"variable, whose value can be changed with this function,\n"
+"and this variable will be stored on the cdr.\n"
" raw values for disposition:\n"
-" 1 = NO ANSWER\n"
-" 2 = BUSY\n"
-" 3 = FAILED\n"
-" 4 = ANSWERED\n"
+" 0 = NULL\n"
+" 1 = FAILED\n"
+" 2 = BUSY\n"
+" 4 = NO ANSWER\n"
+" 8 = ANSWERED\n"
" raw values for amaflags:\n"
-" 1 = OMIT\n"
-" 2 = BILLING\n"
-" 3 = DOCUMENTATION\n",
+" 1 = OMIT\n"
+" 2 = BILLING\n"
+" 3 = DOCUMENTATION\n"
+"If a third argument is supplied, it must be a handle that is returned\n"
+"by CDRstart(). In this case, any field can be set in the CDR associated\n"
+"with 'handle', except the start, answer and end times, which are set via the\n"
+"CDRstart(), CDRanswer() and CDRclose() functions, respectively. \n"
};
+static int function_cdr_create(struct ast_channel *chan, const char *cmd,
+ char *parse, char *buf, size_t len)
+{
+ struct ast_cdr *cdr = 0;
+ char *handle;
+
+ /* no args, no options so far */
+
+ cdr = calloc(sizeof(struct ast_cdr),1);
+
+ if (!cdr) {
+ ast_log(LOG_ERROR,"CDRcreate could not allocate CDR memory!\n");
+ } else {
+ ast_cdr_init(cdr, chan);
+
+ ast_cdr_start(cdr);
+ }
+
+ asprintf(&handle, "%lu", (unsigned long)cdr);
+
+ ast_copy_string(buf, handle, len);
+ free(handle);
+
+ return 0;
+}
+
+static struct ast_custom_function cdr_create_function = {
+ .name = "CDRstart",
+ .synopsis = "Create and Start a non-attached CDR",
+ .syntax = "CDRstart()",
+ .desc =
+ "This function will create a CDR. This CDR will be initialized from the current channel,\n"
+ "and its start time will be set to the current time.\n"
+ "It will return a 'handle' (a string of numbers) that can be used by the CDRanswer(),\n"
+ "the CDRclose() funcs to prepare and post a CDR. The CDR() function, given this handle,\n"
+ "can be used to modify any of the variables associated with this CDR.\n",
+ .read = function_cdr_create
+};
+
+static int function_cdr_answer(struct ast_channel *chan, const char *cmd,
+ char *parse, char *buf, size_t len)
+{
+ struct ast_cdr *cdr;
+
+ AST_DECLARE_APP_ARGS(args,
+ AST_APP_ARG(handle);
+ );
+
+ buf[0] = '\0';
+
+ if (ast_strlen_zero(parse)) {
+ ast_log(LOG_WARNING, "CDRanswer requires an argument, CDRanswer(<handle>)\n");
+ return -1;
+ }
+
+ AST_STANDARD_APP_ARGS(args, parse);
+
+ if (args.argc < 1) {
+ ast_log(LOG_WARNING, "CDRanswer requires an argument, CDRanswer(<handle>)\n");
+ return -1;
+ }
+
+ cdr = (struct ast_cdr*)strtoul(args.handle, NULL, 10);
+ ast_cdr_answer(cdr);
+
+ ast_copy_string(buf, args.handle, len);
+
+ return 0;
+}
+
+static struct ast_custom_function cdr_answer_function = {
+ .name = "CDRanswer",
+ .synopsis = "Sets the Answer time in the CDR associated with the supplied handle to the current time",
+ .syntax = "CDRanswer(handle)",
+ .desc =
+ "This function will Set the start time to the current time in the CDR associated with the argument 'handle'.\n"
+ " This func will return the handle.\n",
+ .read = function_cdr_answer
+};
+
+
+static int function_cdr_close(struct ast_channel *chan, const char *cmd,
+ char *parse, char *buf, size_t len)
+{
+ struct ast_cdr *cdr;
+
+ AST_DECLARE_APP_ARGS(args,
+ AST_APP_ARG(handle);
+ );
+
+ buf[0] = '\0';
+
+ if (ast_strlen_zero(parse)) {
+ ast_log(LOG_WARNING, "CDRclose requires an argument, CDRclose(<handle>)\n");
+ return -1;
+ }
+
+ AST_STANDARD_APP_ARGS(args, parse);
+
+ if (args.argc < 1) {
+ ast_log(LOG_WARNING, "CDRclose requires an argument, CDRclose(<handle>)\n");
+ return -1;
+ }
+
+ cdr = (struct ast_cdr*)strtoul(args.handle, NULL, 10);
+
+ ast_cdr_end(cdr);
+ ast_cdr_detach(cdr);
+
+ ast_copy_string(buf, args.handle, len);
+
+ return 0;
+}
+
+static struct ast_custom_function cdr_close_function = {
+ .name = "CDRclose",
+ .synopsis = "Sets the Answer time in the CDR associated with the supplied handle to the current time",
+ .syntax = "CDRclose(handle)",
+ .desc =
+ "This function will Set the start time to the current time in the CDR associated with the argument 'handle'.\n"
+ " This func will return the handle.\n",
+ .read = function_cdr_close
+};
+
+
static int unload_module(void)
{
- return ast_custom_function_unregister(&cdr_function);
+ int res = 0;
+
+ res = ast_custom_function_unregister(&cdr_function);
+ res |= ast_custom_function_unregister(&cdr_create_function);
+ res |= ast_custom_function_unregister(&cdr_answer_function);
+ res |= ast_custom_function_unregister(&cdr_close_function);
+ return res;
}
static int load_module(void)
{
- return ast_custom_function_register(&cdr_function);
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Call Detail Record (CDR) dialplan function");
+ int res = 0;
+
+ res = ast_custom_function_register(&cdr_function);
+ res |= ast_custom_function_register(&cdr_create_function);
+ res |= ast_custom_function_register(&cdr_answer_function);
+ res |= ast_custom_function_register(&cdr_close_function);
+ return res;
+}
+
+AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Call Detail Record (CDR) dialplan functions");
More information about the asterisk-commits
mailing list