Asterisk - The Open Source Telephony Project GIT-master-754dea3
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros Modules Pages
Data Structures | Enumerations | Functions | Variables
func_cdr.c File Reference

Call Detail Record related dialplan functions. More...

#include "asterisk.h"
#include "asterisk/module.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/utils.h"
#include "asterisk/app.h"
#include "asterisk/cdr.h"
#include "asterisk/stasis.h"
#include "asterisk/stasis_message_router.h"
Include dependency graph for func_cdr.c:

Go to the source code of this file.

Data Structures

struct  cdr_func_data
 
struct  cdr_func_payload
 

Enumerations

enum  cdr_option_flags { OPT_UNPARSED = (1 << 1) , OPT_FLOAT = (1 << 2) }
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
static int cdr_prop_write (struct ast_channel *chan, const char *cmd, char *parse, const char *value)
 
static void cdr_prop_write_callback (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 
static int cdr_read (struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t len)
 
static void cdr_read_callback (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 
static struct timeval cdr_retrieve_time (struct ast_channel *chan, const char *time_name)
 
static int cdr_write (struct ast_channel *chan, const char *cmd, char *arguments, const char *value)
 
static void cdr_write_callback (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 
static int load_module (void)
 
 STASIS_MESSAGE_TYPE_DEFN_LOCAL (cdr_prop_write_message_type)
 
 STASIS_MESSAGE_TYPE_DEFN_LOCAL (cdr_read_message_type)
 
 STASIS_MESSAGE_TYPE_DEFN_LOCAL (cdr_write_message_type)
 
static int unload_module (void)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Call Detail Record (CDR) dialplan functions" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .requires = "cdr", }
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static const struct ast_app_option cdr_func_options [128] = { [ 'f' ] = { .flag = OPT_FLOAT }, [ 'u' ] = { .flag = OPT_UNPARSED }, }
 
static struct ast_custom_function cdr_function
 
static struct ast_custom_function cdr_prop_function
 

Detailed Description

Call Detail Record related dialplan functions.

Author
Anthony Minessale II

Definition in file func_cdr.c.

Enumeration Type Documentation

◆ cdr_option_flags

Enumerator
OPT_UNPARSED 
OPT_FLOAT 

Definition at line 203 of file func_cdr.c.

203 {
204 OPT_UNPARSED = (1 << 1),
205 OPT_FLOAT = (1 << 2),
206};
@ OPT_FLOAT
Definition: func_cdr.c:205
@ OPT_UNPARSED
Definition: func_cdr.c:204

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 720 of file func_cdr.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 720 of file func_cdr.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

Definition at line 720 of file func_cdr.c.

◆ cdr_prop_write()

static int cdr_prop_write ( struct ast_channel chan,
const char *  cmd,
char *  parse,
const char *  value 
)
static

Definition at line 612 of file func_cdr.c.

614{
616 RAII_VAR(struct cdr_func_payload *, payload, NULL, ao2_cleanup);
618
619 if (!chan) {
620 ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
621 return -1;
622 }
623
624 if (!router) {
625 ast_log(AST_LOG_WARNING, "Failed to manipulate CDR for channel %s: no message router\n",
626 ast_channel_name(chan));
627 return -1;
628 }
629
630 if (!cdr_prop_write_message_type()) {
631 ast_log(AST_LOG_WARNING, "Failed to manipulate CDR for channel %s: message type not available\n",
632 ast_channel_name(chan));
633 return -1;
634 }
635
636 payload = ao2_alloc(sizeof(*payload), NULL);
637 if (!payload) {
638 return -1;
639 }
640 payload->chan = chan;
641 payload->cmd = cmd;
642 payload->arguments = parse;
643 payload->value = value;
644
645 message = stasis_message_create(cdr_prop_write_message_type(), payload);
646 if (!message) {
647 ast_log(AST_LOG_WARNING, "Failed to manipulate CDR for channel %s: unable to create message\n",
648 ast_channel_name(chan));
649 return -1;
650 }
652
653 return 0;
654}
#define ast_log
Definition: astobj2.c:42
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:409
struct stasis_message_router * ast_cdr_message_router(void)
Return the message router for the CDR engine.
Definition: cdr.c:4427
const char * ast_channel_name(const struct ast_channel *chan)
#define AST_LOG_WARNING
#define LOG_WARNING
static struct stasis_message_router * router
#define NULL
Definition: resample.c:96
struct stasis_message * stasis_message_create(struct stasis_message_type *type, void *data)
Create a new message.
void stasis_message_router_publish_sync(struct stasis_message_router *router, struct stasis_message *message)
Publish a message to a message router's subscription synchronously.
int value
Definition: syslog.c:37
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941

References ao2_alloc, ao2_cleanup, ast_cdr_message_router(), ast_channel_name(), ast_log, AST_LOG_WARNING, LOG_WARNING, NULL, RAII_VAR, router, stasis_message_create(), stasis_message_router_publish_sync(), and value.

◆ cdr_prop_write_callback()

static void cdr_prop_write_callback ( void *  data,
struct stasis_subscription sub,
struct stasis_message message 
)
static

Definition at line 408 of file func_cdr.c.

409{
411 enum ast_cdr_options option;
412 char *parse;
414 AST_APP_ARG(variable);
416 );
417
418 if (cdr_prop_write_message_type() != stasis_message_type(message)) {
419 return;
420 }
421
422 if (!payload) {
423 return;
424 }
425
426 if (ast_strlen_zero(payload->arguments)) {
427 ast_log(AST_LOG_WARNING, "%s requires a variable (%s(variable)=value)\n)",
428 payload->cmd, payload->cmd);
429 return;
430 }
431 if (ast_strlen_zero(payload->value)) {
432 ast_log(AST_LOG_WARNING, "%s requires a value (%s(variable)=value)\n)",
433 payload->cmd, payload->cmd);
434 return;
435 }
436 parse = ast_strdupa(payload->arguments);
438
439 if (!strcasecmp("party_a", args.variable)) {
440 option = AST_CDR_FLAG_PARTY_A;
441 } else if (!strcasecmp("disable", args.variable)) {
443 } else {
444 ast_log(AST_LOG_WARNING, "Unknown option %s used with %s\n", args.variable, payload->cmd);
445 return;
446 }
447
448 if (ast_true(payload->value)) {
449 ast_cdr_set_property(ast_channel_name(payload->chan), option);
450 } else {
452 }
453}
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
int ast_cdr_clear_property(const char *channel_name, enum ast_cdr_options option)
Clear a property on a CDR for a channel.
Definition: cdr.c:3708
ast_cdr_options
CDR manipulation options. Certain function calls will manipulate the state of a CDR object based on t...
Definition: cdr.h:242
@ AST_CDR_FLAG_DISABLE_ALL
Definition: cdr.h:245
@ AST_CDR_FLAG_PARTY_A
Definition: cdr.h:246
int ast_cdr_set_property(const char *channel_name, enum ast_cdr_options option)
Set a property on a CDR for a channel.
Definition: cdr.c:3681
#define AST_APP_ARG(name)
Define an application argument.
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application's arguments.
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the 'standard' argument separation process for an application.
struct stasis_message_type * stasis_message_type(const struct stasis_message *msg)
Get the message type for a stasis_message.
void * stasis_message_data(const struct stasis_message *msg)
Get the data contained in a message.
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true"....
Definition: utils.c:2199
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
const char * cmd
Definition: func_cdr.c:215
struct ast_channel * chan
Definition: func_cdr.c:214
const char * value
Definition: func_cdr.c:217
const char * arguments
Definition: func_cdr.c:216
const char * args
static struct test_options options

References args, cdr_func_payload::arguments, AST_APP_ARG, ast_cdr_clear_property(), AST_CDR_FLAG_DISABLE_ALL, AST_CDR_FLAG_PARTY_A, ast_cdr_set_property(), ast_channel_name(), AST_DECLARE_APP_ARGS, ast_log, AST_LOG_WARNING, AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), ast_true(), cdr_func_payload::chan, cdr_func_payload::cmd, options, stasis_message_data(), stasis_message_type(), and cdr_func_payload::value.

Referenced by load_module().

◆ cdr_read()

static int cdr_read ( struct ast_channel chan,
const char *  cmd,
char *  parse,
char *  buf,
size_t  len 
)
static

Definition at line 456 of file func_cdr.c.

458{
460 RAII_VAR(struct cdr_func_payload *, payload, NULL, ao2_cleanup);
461 struct cdr_func_data output = { 0, };
462
463 if (!chan) {
464 ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
465 return -1;
466 }
467
468 if (!cdr_read_message_type()) {
469 ast_log(AST_LOG_WARNING, "Failed to manipulate CDR for channel %s: message type not available\n",
470 ast_channel_name(chan));
471 return -1;
472 }
473
474 payload = ao2_alloc(sizeof(*payload), NULL);
475 if (!payload) {
476 return -1;
477 }
478 payload->chan = chan;
479 payload->cmd = cmd;
480 payload->arguments = parse;
481 payload->data = &output;
482
483 buf[0] = '\0';/* Ensure the buffer is initialized. */
484 output.buf = buf;
485 output.len = len;
486
487 message = stasis_message_create(cdr_read_message_type(), payload);
488 if (!message) {
489 ast_log(AST_LOG_WARNING, "Failed to manipulate CDR for channel %s: unable to create message\n",
490 ast_channel_name(chan));
491 return -1;
492 }
493
494 /* If this is a request on a dummy channel, we're doing post-processing on an
495 * already dispatched CDR. Simply call the callback to calculate the value and
496 * return, instead of posting to Stasis as we would for a running channel.
497 */
500 } else {
502
503 if (!router) {
504 ast_log(AST_LOG_WARNING, "Failed to manipulate CDR for channel %s: no message router\n",
505 ast_channel_name(chan));
506 return -1;
507 }
509 }
510
511 return 0;
512}
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
static void cdr_read_callback(void *data, struct stasis_subscription *sub, struct stasis_message *message)
Definition: func_cdr.c:256
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
const char * data
char * buf
Definition: func_cdr.c:222
size_t len
Definition: func_cdr.c:223

References ao2_alloc, ao2_cleanup, ast_cdr_message_router(), ast_channel_name(), ast_log, AST_LOG_WARNING, ast_strlen_zero(), buf, cdr_func_data::buf, cdr_read_callback(), ast_channel::data, cdr_func_data::len, len(), LOG_WARNING, NULL, RAII_VAR, router, stasis_message_create(), and stasis_message_router_publish_sync().

◆ cdr_read_callback()

static void cdr_read_callback ( void *  data,
struct stasis_subscription sub,
struct stasis_message message 
)
static

Definition at line 256 of file func_cdr.c.

257{
259 struct cdr_func_data *output;
260 char *info;
261 char *value = NULL;
262 struct ast_flags flags = { 0 };
263 char tempbuf[512];
265 AST_APP_ARG(variable);
267 );
268
269 if (cdr_read_message_type() != stasis_message_type(message)) {
270 return;
271 }
272
273 ast_assert(payload != NULL);
274 output = payload->data;
275 ast_assert(output != NULL);
276
277 if (ast_strlen_zero(payload->arguments)) {
278 ast_log(AST_LOG_WARNING, "%s requires a variable (%s(variable[,option]))\n)",
279 payload->cmd, payload->cmd);
280 return;
281 }
282 info = ast_strdupa(payload->arguments);
284
285 if (!ast_strlen_zero(args.options)) {
287 }
288
289 if (ast_strlen_zero(ast_channel_name(payload->chan))) {
290 /* Format request on a dummy channel */
291 ast_cdr_format_var(ast_channel_cdr(payload->chan), args.variable, &value, tempbuf, sizeof(tempbuf), ast_test_flag(&flags, OPT_UNPARSED));
292 if (ast_strlen_zero(value)) {
293 return;
294 }
295 ast_copy_string(tempbuf, value, sizeof(tempbuf));
297 } else if (ast_cdr_getvar(ast_channel_name(payload->chan), args.variable, tempbuf, sizeof(tempbuf))) {
298 return;
299 }
300
302 && (!strcasecmp("billsec", args.variable) || !strcasecmp("duration", args.variable))) {
303 struct timeval start = cdr_retrieve_time(payload->chan, !strcasecmp("billsec", args.variable) ? "answer" : "start");
304 struct timeval finish = cdr_retrieve_time(payload->chan, "end");
305 double delta;
306
307 if (ast_tvzero(finish)) {
308 finish = ast_tvnow();
309 }
310
311 if (ast_tvzero(start)) {
312 delta = 0.0;
313 } else {
314 delta = (double)(ast_tvdiff_us(finish, start) / 1000000.0);
315 }
316 snprintf(tempbuf, sizeof(tempbuf), "%lf", delta);
317
318 } else if (!ast_test_flag(&flags, OPT_UNPARSED)) {
319 if (!strcasecmp("start", args.variable)
320 || !strcasecmp("end", args.variable)
321 || !strcasecmp("answer", args.variable)) {
322 struct timeval fmt_time;
323 struct ast_tm tm;
324 /* tv_usec is suseconds_t, which could be int or long */
325 long int tv_sec;
326 long int tv_usec;
327
328 if (sscanf(tempbuf, "%ld.%ld", &tv_sec, &tv_usec) != 2) {
329 ast_log(AST_LOG_WARNING, "Unable to parse %s (%s) from the CDR for channel %s\n",
330 args.variable, tempbuf, ast_channel_name(payload->chan));
331 return;
332 }
333 if (tv_sec) {
334 fmt_time.tv_sec = tv_sec;
335 fmt_time.tv_usec = tv_usec;
336 ast_localtime(&fmt_time, &tm, NULL);
337 ast_strftime(tempbuf, sizeof(tempbuf), "%Y-%m-%d %T", &tm);
338 } else {
339 tempbuf[0] = '\0';
340 }
341 } else if (!strcasecmp("disposition", args.variable)) {
342 int disposition;
343
344 if (sscanf(tempbuf, "%8d", &disposition) != 1) {
345 ast_log(AST_LOG_WARNING, "Unable to parse %s (%s) from the CDR for channel %s\n",
346 args.variable, tempbuf, ast_channel_name(payload->chan));
347 return;
348 }
349 snprintf(tempbuf, sizeof(tempbuf), "%s", ast_cdr_disp2str(disposition));
350 } else if (!strcasecmp("amaflags", args.variable)) {
351 int amaflags;
352
353 if (sscanf(tempbuf, "%8d", &amaflags) != 1) {
354 ast_log(AST_LOG_WARNING, "Unable to parse %s (%s) from the CDR for channel %s\n",
355 args.variable, tempbuf, ast_channel_name(payload->chan));
356 return;
357 }
358 snprintf(tempbuf, sizeof(tempbuf), "%s", ast_channel_amaflags2string(amaflags));
359 }
360 }
361
362 ast_copy_string(output->buf, tempbuf, output->len);
363}
void ast_cdr_format_var(struct ast_cdr *cdr, const char *name, char **ret, char *workspace, int workspacelen, int raw)
Format a CDR variable from an already posted CDR.
Definition: cdr.c:3170
int ast_cdr_getvar(const char *channel_name, const char *name, char *value, size_t length)
Retrieve a CDR variable from a channel's current CDR.
Definition: cdr.c:3457
const char * ast_cdr_disp2str(int disposition)
Disposition to a string.
Definition: cdr.c:3563
static int amaflags
Definition: chan_iax2.c:500
struct ast_cdr * ast_channel_cdr(const struct ast_channel *chan)
const char * ast_channel_amaflags2string(enum ama_flags flags)
Convert the enum representation of an AMA flag to a string representation.
Definition: channel.c:4390
static const struct ast_app_option cdr_func_options[128]
Definition: func_cdr.c:211
static struct timeval cdr_retrieve_time(struct ast_channel *chan, const char *time_name)
Definition: func_cdr.c:230
int ast_app_parse_options(const struct ast_app_option *options, struct ast_flags *flags, char **args, char *optstr)
Parses a string containing application options and sets flags/arguments.
Definition: main/app.c:3066
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
int ast_strftime(char *buf, size_t len, const char *format, const struct ast_tm *tm)
Special version of strftime(3) that handles fractions of a second. Takes the same arguments as strfti...
Definition: localtime.c:2524
def info(msg)
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425
Structure used to handle boolean flags.
Definition: utils.h:199
unsigned int flags
Definition: utils.h:200
int64_t ast_tvdiff_us(struct timeval end, struct timeval start)
Computes the difference (in microseconds) between two struct timeval instances.
Definition: time.h:87
int ast_tvzero(const struct timeval t)
Returns true if the argument is 0,0.
Definition: time.h:117
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:159
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define ast_assert(a)
Definition: utils.h:739
#define ast_set_flag(p, flag)
Definition: utils.h:70

References amaflags, args, cdr_func_payload::arguments, AST_APP_ARG, ast_app_parse_options(), ast_assert, ast_cdr_disp2str(), ast_cdr_format_var(), ast_cdr_getvar(), ast_channel_amaflags2string(), ast_channel_cdr(), ast_channel_name(), ast_copy_string(), AST_DECLARE_APP_ARGS, ast_localtime(), ast_log, AST_LOG_WARNING, ast_set_flag, AST_STANDARD_APP_ARGS, ast_strdupa, ast_strftime(), ast_strlen_zero(), ast_test_flag, ast_tvdiff_us(), ast_tvnow(), ast_tvzero(), cdr_func_data::buf, cdr_func_options, cdr_retrieve_time(), cdr_func_payload::chan, cdr_func_payload::cmd, cdr_func_payload::data, ast_flags::flags, sip_to_pjsip::info(), cdr_func_data::len, NULL, OPT_FLOAT, OPT_UNPARSED, options, stasis_message_data(), stasis_message_type(), and value.

Referenced by cdr_read(), and load_module().

◆ cdr_retrieve_time()

static struct timeval cdr_retrieve_time ( struct ast_channel chan,
const char *  time_name 
)
static

Definition at line 230 of file func_cdr.c.

231{
232 struct timeval time = { 0 };
233 char *value = NULL;
234 char tempbuf[128];
235 long int tv_sec;
236 long int tv_usec;
237
239 /* Format request on a dummy channel */
240 ast_cdr_format_var(ast_channel_cdr(chan), time_name, &value, tempbuf, sizeof(tempbuf), 1);
241 } else {
242 ast_cdr_getvar(ast_channel_name(chan), time_name, tempbuf, sizeof(tempbuf));
243 }
244
245 /* time.tv_usec is suseconds_t, which could be int or long */
246 if (sscanf(tempbuf, "%ld.%ld", &tv_sec, &tv_usec) == 2) {
247 time.tv_sec = tv_sec;
248 time.tv_usec = tv_usec;
249 } else {
250 ast_log(AST_LOG_WARNING, "Failed to fully extract '%s' from CDR\n", time_name);
251 }
252
253 return time;
254}

References ast_cdr_format_var(), ast_cdr_getvar(), ast_channel_cdr(), ast_channel_name(), ast_log, AST_LOG_WARNING, ast_strlen_zero(), NULL, and value.

Referenced by cdr_read_callback().

◆ cdr_write()

static int cdr_write ( struct ast_channel chan,
const char *  cmd,
char *  arguments,
const char *  value 
)
static

Definition at line 514 of file func_cdr.c.

516{
517 struct stasis_message *message;
518 struct cdr_func_payload *payload;
521 AST_APP_ARG(variable);
523 );
524 char *parse;
525
526 if (!chan) {
527 ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
528 return -1;
529 }
530 if (ast_strlen_zero(arguments)) {
531 ast_log(LOG_WARNING, "%s requires a variable (%s(variable)=value)\n)",
532 cmd, cmd);
533 return -1;
534 }
535 if (!value) {
536 ast_log(LOG_WARNING, "%s requires a value (%s(variable)=value)\n)",
537 cmd, cmd);
538 return -1;
539 }
540
541 parse = ast_strdupa(arguments);
543
544 /* These CDR variables are no longer supported or set directly on the channel */
545 if (!strcasecmp(args.variable, "accountcode")) {
546 ast_log(LOG_WARNING, "Using the %s function to set 'accountcode' is deprecated. Please use the CHANNEL function instead.\n",
547 cmd);
548 ast_channel_lock(chan);
549 ast_channel_accountcode_set(chan, value);
550 ast_channel_unlock(chan);
551 return 0;
552 }
553 if (!strcasecmp(args.variable, "amaflags")) {
554 int amaflags;
555
556 ast_log(LOG_WARNING, "Using the %s function to set 'amaflags' is deprecated. Please use the CHANNEL function instead.\n",
557 cmd);
558 if (isdigit(*value)) {
559 if (sscanf(value, "%30d", &amaflags) != 1) {
561 }
562 } else {
564 }
565 ast_channel_lock(chan);
567 ast_channel_unlock(chan);
568 return 0;
569 }
570 if (!strcasecmp(args.variable, "peeraccount")) {
571 ast_log(LOG_WARNING, "The 'peeraccount' setting is not supported. Please set the 'accountcode' on the appropriate channel using the CHANNEL function.\n");
572 return 0;
573 }
574
575 /* The remaining CDR variables are handled by CDR processing code */
576 if (!cdr_write_message_type()) {
577 ast_log(LOG_WARNING, "Failed to manipulate CDR for channel %s: message type not available\n",
578 ast_channel_name(chan));
579 return -1;
580 }
581
582 payload = ao2_alloc(sizeof(*payload), NULL);
583 if (!payload) {
584 return -1;
585 }
586 payload->chan = chan;
587 payload->cmd = cmd;
588 payload->arguments = arguments;
589 payload->value = value;
590
591 message = stasis_message_create(cdr_write_message_type(), payload);
592 ao2_ref(payload, -1);
593 if (!message) {
594 ast_log(LOG_WARNING, "Failed to manipulate CDR for channel %s: unable to create message\n",
595 ast_channel_name(chan));
596 return -1;
597 }
599 if (!router) {
600 ast_log(LOG_WARNING, "Failed to manipulate CDR for channel %s: no message router\n",
601 ast_channel_name(chan));
602 ao2_ref(message, -1);
603 return -1;
604 }
606 ao2_ref(router, -1);
607 ao2_ref(message, -1);
608
609 return 0;
610}
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
#define ast_channel_lock(chan)
Definition: channel.h:2970
@ AST_AMA_NONE
Definition: channel.h:1198
void ast_channel_amaflags_set(struct ast_channel *chan, enum ama_flags value)
enum ama_flags ast_channel_string2amaflag(const char *flag)
Convert a string to a detail record AMA flag.
Definition: channel.c:4377
#define ast_channel_unlock(chan)
Definition: channel.h:2971

References amaflags, ao2_alloc, ao2_ref, args, cdr_func_payload::arguments, AST_AMA_NONE, AST_APP_ARG, ast_cdr_message_router(), ast_channel_amaflags_set(), ast_channel_lock, ast_channel_name(), ast_channel_string2amaflag(), ast_channel_unlock, AST_DECLARE_APP_ARGS, ast_log, AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), cdr_func_payload::chan, cdr_func_payload::cmd, LOG_WARNING, NULL, options, router, stasis_message_create(), stasis_message_router_publish_sync(), cdr_func_payload::value, and value.

◆ cdr_write_callback()

static void cdr_write_callback ( void *  data,
struct stasis_subscription sub,
struct stasis_message message 
)
static

Definition at line 365 of file func_cdr.c.

366{
367 struct cdr_func_payload *payload;
368 struct ast_flags flags = { 0 };
370 AST_APP_ARG(variable);
372 );
373 char *parse;
374
375 if (cdr_write_message_type() != stasis_message_type(message)) {
376 return;
377 }
378 payload = stasis_message_data(message);
379 if (!payload) {
380 return;
381 }
382 if (ast_strlen_zero(payload->arguments)
383 || !payload->value) {
384 /* Sanity check. cdr_write() could never send these bad messages */
385 ast_assert(0);
386 return;
387 }
388
389 parse = ast_strdupa(payload->arguments);
391
392 if (!ast_strlen_zero(args.options)) {
394 }
395
396 /* These are already handled by cdr_write() */
397 ast_assert(strcasecmp(args.variable, "accountcode")
398 && strcasecmp(args.variable, "peeraccount")
399 && strcasecmp(args.variable, "amaflags"));
400
401 if (!strcasecmp(args.variable, "userfield")) {
402 ast_cdr_setuserfield(ast_channel_name(payload->chan), payload->value);
403 } else {
404 ast_cdr_setvar(ast_channel_name(payload->chan), args.variable, payload->value);
405 }
406}
void ast_cdr_setuserfield(const char *channel_name, const char *userfield)
Set CDR user field for channel (stored in CDR)
Definition: cdr.c:3610
int ast_cdr_setvar(const char *channel_name, const char *name, const char *value)
Set a variable on a CDR.
Definition: cdr.c:3303

References args, cdr_func_payload::arguments, AST_APP_ARG, ast_app_parse_options(), ast_assert, ast_cdr_setuserfield(), ast_cdr_setvar(), ast_channel_name(), AST_DECLARE_APP_ARGS, AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), cdr_func_options, cdr_func_payload::chan, ast_flags::flags, NULL, options, stasis_message_data(), stasis_message_type(), and cdr_func_payload::value.

Referenced by load_module().

◆ load_module()

static int load_module ( void  )
static

Definition at line 687 of file func_cdr.c.

688{
690 int res = 0;
691
692 if (!router) {
694 }
695
696 res |= STASIS_MESSAGE_TYPE_INIT(cdr_read_message_type);
697 res |= STASIS_MESSAGE_TYPE_INIT(cdr_write_message_type);
698 res |= STASIS_MESSAGE_TYPE_INIT(cdr_prop_write_message_type);
701 res |= stasis_message_router_add(router, cdr_prop_write_message_type(),
703 res |= stasis_message_router_add(router, cdr_write_message_type(),
705 res |= stasis_message_router_add(router, cdr_read_message_type(),
707
708 if (res) {
711 }
713}
static void cdr_prop_write_callback(void *data, struct stasis_subscription *sub, struct stasis_message *message)
Definition: func_cdr.c:408
static struct ast_custom_function cdr_prop_function
Definition: func_cdr.c:662
static void cdr_write_callback(void *data, struct stasis_subscription *sub, struct stasis_message *message)
Definition: func_cdr.c:365
static int unload_module(void)
Definition: func_cdr.c:668
static struct ast_custom_function cdr_function
Definition: func_cdr.c:656
@ AST_MODULE_LOAD_SUCCESS
Definition: module.h:70
@ AST_MODULE_LOAD_DECLINE
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
#define ast_custom_function_register(acf)
Register a custom function.
Definition: pbx.h:1559
#define STASIS_MESSAGE_TYPE_INIT(name)
Boiler-plate messaging macro for initializing message types.
Definition: stasis.h:1493
int stasis_message_router_add(struct stasis_message_router *router, struct stasis_message_type *message_type, stasis_subscription_cb callback, void *data)
Add a route to a message router.

References ao2_cleanup, ast_cdr_message_router(), ast_custom_function_register, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, cdr_function, cdr_prop_function, cdr_prop_write_callback(), cdr_read_callback(), cdr_write_callback(), NULL, RAII_VAR, router, stasis_message_router_add(), STASIS_MESSAGE_TYPE_INIT, and unload_module().

◆ STASIS_MESSAGE_TYPE_DEFN_LOCAL() [1/3]

STASIS_MESSAGE_TYPE_DEFN_LOCAL ( cdr_prop_write_message_type  )

◆ STASIS_MESSAGE_TYPE_DEFN_LOCAL() [2/3]

STASIS_MESSAGE_TYPE_DEFN_LOCAL ( cdr_read_message_type  )

◆ STASIS_MESSAGE_TYPE_DEFN_LOCAL() [3/3]

STASIS_MESSAGE_TYPE_DEFN_LOCAL ( cdr_write_message_type  )

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 668 of file func_cdr.c.

669{
671 int res = 0;
672
673 if (router) {
674 stasis_message_router_remove(router, cdr_prop_write_message_type());
675 stasis_message_router_remove(router, cdr_write_message_type());
676 stasis_message_router_remove(router, cdr_read_message_type());
677 }
678 STASIS_MESSAGE_TYPE_CLEANUP(cdr_read_message_type);
679 STASIS_MESSAGE_TYPE_CLEANUP(cdr_write_message_type);
680 STASIS_MESSAGE_TYPE_CLEANUP(cdr_prop_write_message_type);
683
684 return res;
685}
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.
#define STASIS_MESSAGE_TYPE_CLEANUP(name)
Boiler-plate messaging macro for cleaning up message types.
Definition: stasis.h:1515
void stasis_message_router_remove(struct stasis_message_router *router, struct stasis_message_type *message_type)
Remove a route from a message router.

References ao2_cleanup, ast_cdr_message_router(), ast_custom_function_unregister(), cdr_function, cdr_prop_function, RAII_VAR, router, stasis_message_router_remove(), and STASIS_MESSAGE_TYPE_CLEANUP.

Referenced by load_module().

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Call Detail Record (CDR) dialplan functions" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .requires = "cdr", }
static

Definition at line 720 of file func_cdr.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 720 of file func_cdr.c.

◆ cdr_func_options

const struct ast_app_option cdr_func_options[128] = { [ 'f' ] = { .flag = OPT_FLOAT }, [ 'u' ] = { .flag = OPT_UNPARSED }, }
static

Definition at line 211 of file func_cdr.c.

Referenced by cdr_read_callback(), and cdr_write_callback().

◆ cdr_function

struct ast_custom_function cdr_function
static
Initial value:
= {
.name = "CDR",
.read = cdr_read,
.write = cdr_write,
}
static int cdr_read(struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t len)
Definition: func_cdr.c:456
static int cdr_write(struct ast_channel *chan, const char *cmd, char *arguments, const char *value)
Definition: func_cdr.c:514

Definition at line 656 of file func_cdr.c.

Referenced by load_module(), and unload_module().

◆ cdr_prop_function

struct ast_custom_function cdr_prop_function
static
Initial value:
= {
.name = "CDR_PROP",
.read = NULL,
.write = cdr_prop_write,
}
static int cdr_prop_write(struct ast_channel *chan, const char *cmd, char *parse, const char *value)
Definition: func_cdr.c:612

Definition at line 662 of file func_cdr.c.

Referenced by load_module(), and unload_module().