Asterisk - The Open Source Telephony Project GIT-master-7921072
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 197 of file func_cdr.c.

197 {
198 OPT_UNPARSED = (1 << 1),
199 OPT_FLOAT = (1 << 2),
200};
@ OPT_FLOAT
Definition: func_cdr.c:199
@ OPT_UNPARSED
Definition: func_cdr.c:198

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 714 of file func_cdr.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 714 of file func_cdr.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

Definition at line 714 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 606 of file func_cdr.c.

608{
610 RAII_VAR(struct cdr_func_payload *, payload, NULL, ao2_cleanup);
612
613 if (!chan) {
614 ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
615 return -1;
616 }
617
618 if (!router) {
619 ast_log(AST_LOG_WARNING, "Failed to manipulate CDR for channel %s: no message router\n",
620 ast_channel_name(chan));
621 return -1;
622 }
623
624 if (!cdr_prop_write_message_type()) {
625 ast_log(AST_LOG_WARNING, "Failed to manipulate CDR for channel %s: message type not available\n",
626 ast_channel_name(chan));
627 return -1;
628 }
629
630 payload = ao2_alloc(sizeof(*payload), NULL);
631 if (!payload) {
632 return -1;
633 }
634 payload->chan = chan;
635 payload->cmd = cmd;
636 payload->arguments = parse;
637 payload->value = value;
638
639 message = stasis_message_create(cdr_prop_write_message_type(), payload);
640 if (!message) {
641 ast_log(AST_LOG_WARNING, "Failed to manipulate CDR for channel %s: unable to create message\n",
642 ast_channel_name(chan));
643 return -1;
644 }
646
647 return 0;
648}
#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:4356
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 402 of file func_cdr.c.

403{
405 enum ast_cdr_options option;
406 char *parse;
408 AST_APP_ARG(variable);
410 );
411
412 if (cdr_prop_write_message_type() != stasis_message_type(message)) {
413 return;
414 }
415
416 if (!payload) {
417 return;
418 }
419
420 if (ast_strlen_zero(payload->arguments)) {
421 ast_log(AST_LOG_WARNING, "%s requires a variable (%s(variable)=value)\n)",
422 payload->cmd, payload->cmd);
423 return;
424 }
425 if (ast_strlen_zero(payload->value)) {
426 ast_log(AST_LOG_WARNING, "%s requires a value (%s(variable)=value)\n)",
427 payload->cmd, payload->cmd);
428 return;
429 }
430 parse = ast_strdupa(payload->arguments);
432
433 if (!strcasecmp("party_a", args.variable)) {
434 option = AST_CDR_FLAG_PARTY_A;
435 } else if (!strcasecmp("disable", args.variable)) {
437 } else {
438 ast_log(AST_LOG_WARNING, "Unknown option %s used with %s\n", args.variable, payload->cmd);
439 return;
440 }
441
442 if (ast_true(payload->value)) {
443 ast_cdr_set_property(ast_channel_name(payload->chan), option);
444 } else {
446 }
447}
#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:3637
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:3610
#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:209
struct ast_channel * chan
Definition: func_cdr.c:208
const char * value
Definition: func_cdr.c:211
const char * arguments
Definition: func_cdr.c:210
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 450 of file func_cdr.c.

452{
454 RAII_VAR(struct cdr_func_payload *, payload, NULL, ao2_cleanup);
455 struct cdr_func_data output = { 0, };
456
457 if (!chan) {
458 ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
459 return -1;
460 }
461
462 if (!cdr_read_message_type()) {
463 ast_log(AST_LOG_WARNING, "Failed to manipulate CDR for channel %s: message type not available\n",
464 ast_channel_name(chan));
465 return -1;
466 }
467
468 payload = ao2_alloc(sizeof(*payload), NULL);
469 if (!payload) {
470 return -1;
471 }
472 payload->chan = chan;
473 payload->cmd = cmd;
474 payload->arguments = parse;
475 payload->data = &output;
476
477 buf[0] = '\0';/* Ensure the buffer is initialized. */
478 output.buf = buf;
479 output.len = len;
480
481 message = stasis_message_create(cdr_read_message_type(), payload);
482 if (!message) {
483 ast_log(AST_LOG_WARNING, "Failed to manipulate CDR for channel %s: unable to create message\n",
484 ast_channel_name(chan));
485 return -1;
486 }
487
488 /* If this is a request on a dummy channel, we're doing post-processing on an
489 * already dispatched CDR. Simply call the callback to calculate the value and
490 * return, instead of posting to Stasis as we would for a running channel.
491 */
494 } else {
496
497 if (!router) {
498 ast_log(AST_LOG_WARNING, "Failed to manipulate CDR for channel %s: no message router\n",
499 ast_channel_name(chan));
500 return -1;
501 }
503 }
504
505 return 0;
506}
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:250
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:216
size_t len
Definition: func_cdr.c:217

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 250 of file func_cdr.c.

251{
253 struct cdr_func_data *output;
254 char *info;
255 char *value = NULL;
256 struct ast_flags flags = { 0 };
257 char tempbuf[512];
259 AST_APP_ARG(variable);
261 );
262
263 if (cdr_read_message_type() != stasis_message_type(message)) {
264 return;
265 }
266
267 ast_assert(payload != NULL);
268 output = payload->data;
269 ast_assert(output != NULL);
270
271 if (ast_strlen_zero(payload->arguments)) {
272 ast_log(AST_LOG_WARNING, "%s requires a variable (%s(variable[,option]))\n)",
273 payload->cmd, payload->cmd);
274 return;
275 }
276 info = ast_strdupa(payload->arguments);
278
279 if (!ast_strlen_zero(args.options)) {
281 }
282
283 if (ast_strlen_zero(ast_channel_name(payload->chan))) {
284 /* Format request on a dummy channel */
285 ast_cdr_format_var(ast_channel_cdr(payload->chan), args.variable, &value, tempbuf, sizeof(tempbuf), ast_test_flag(&flags, OPT_UNPARSED));
286 if (ast_strlen_zero(value)) {
287 return;
288 }
289 ast_copy_string(tempbuf, value, sizeof(tempbuf));
291 } else if (ast_cdr_getvar(ast_channel_name(payload->chan), args.variable, tempbuf, sizeof(tempbuf))) {
292 return;
293 }
294
296 && (!strcasecmp("billsec", args.variable) || !strcasecmp("duration", args.variable))) {
297 struct timeval start = cdr_retrieve_time(payload->chan, !strcasecmp("billsec", args.variable) ? "answer" : "start");
298 struct timeval finish = cdr_retrieve_time(payload->chan, "end");
299 double delta;
300
301 if (ast_tvzero(finish)) {
302 finish = ast_tvnow();
303 }
304
305 if (ast_tvzero(start)) {
306 delta = 0.0;
307 } else {
308 delta = (double)(ast_tvdiff_us(finish, start) / 1000000.0);
309 }
310 snprintf(tempbuf, sizeof(tempbuf), "%lf", delta);
311
312 } else if (!ast_test_flag(&flags, OPT_UNPARSED)) {
313 if (!strcasecmp("start", args.variable)
314 || !strcasecmp("end", args.variable)
315 || !strcasecmp("answer", args.variable)) {
316 struct timeval fmt_time;
317 struct ast_tm tm;
318 /* tv_usec is suseconds_t, which could be int or long */
319 long int tv_sec;
320 long int tv_usec;
321
322 if (sscanf(tempbuf, "%ld.%ld", &tv_sec, &tv_usec) != 2) {
323 ast_log(AST_LOG_WARNING, "Unable to parse %s (%s) from the CDR for channel %s\n",
324 args.variable, tempbuf, ast_channel_name(payload->chan));
325 return;
326 }
327 if (tv_sec) {
328 fmt_time.tv_sec = tv_sec;
329 fmt_time.tv_usec = tv_usec;
330 ast_localtime(&fmt_time, &tm, NULL);
331 ast_strftime(tempbuf, sizeof(tempbuf), "%Y-%m-%d %T", &tm);
332 } else {
333 tempbuf[0] = '\0';
334 }
335 } else if (!strcasecmp("disposition", args.variable)) {
336 int disposition;
337
338 if (sscanf(tempbuf, "%8d", &disposition) != 1) {
339 ast_log(AST_LOG_WARNING, "Unable to parse %s (%s) from the CDR for channel %s\n",
340 args.variable, tempbuf, ast_channel_name(payload->chan));
341 return;
342 }
343 snprintf(tempbuf, sizeof(tempbuf), "%s", ast_cdr_disp2str(disposition));
344 } else if (!strcasecmp("amaflags", args.variable)) {
345 int amaflags;
346
347 if (sscanf(tempbuf, "%8d", &amaflags) != 1) {
348 ast_log(AST_LOG_WARNING, "Unable to parse %s (%s) from the CDR for channel %s\n",
349 args.variable, tempbuf, ast_channel_name(payload->chan));
350 return;
351 }
352 snprintf(tempbuf, sizeof(tempbuf), "%s", ast_channel_amaflags2string(amaflags));
353 }
354 }
355
356 ast_copy_string(output->buf, tempbuf, output->len);
357}
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:3112
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:3386
const char * ast_cdr_disp2str(int disposition)
Disposition to a string.
Definition: cdr.c:3492
static int amaflags
Definition: chan_iax2.c:476
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:4372
static const struct ast_app_option cdr_func_options[128]
Definition: func_cdr.c:205
static struct timeval cdr_retrieve_time(struct ast_channel *chan, const char *time_name)
Definition: func_cdr.c:224
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:3056
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 224 of file func_cdr.c.

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

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 508 of file func_cdr.c.

510{
511 struct stasis_message *message;
512 struct cdr_func_payload *payload;
515 AST_APP_ARG(variable);
517 );
518 char *parse;
519
520 if (!chan) {
521 ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
522 return -1;
523 }
524 if (ast_strlen_zero(arguments)) {
525 ast_log(LOG_WARNING, "%s requires a variable (%s(variable)=value)\n)",
526 cmd, cmd);
527 return -1;
528 }
529 if (!value) {
530 ast_log(LOG_WARNING, "%s requires a value (%s(variable)=value)\n)",
531 cmd, cmd);
532 return -1;
533 }
534
535 parse = ast_strdupa(arguments);
537
538 /* These CDR variables are no longer supported or set directly on the channel */
539 if (!strcasecmp(args.variable, "accountcode")) {
540 ast_log(LOG_WARNING, "Using the %s function to set 'accountcode' is deprecated. Please use the CHANNEL function instead.\n",
541 cmd);
542 ast_channel_lock(chan);
543 ast_channel_accountcode_set(chan, value);
544 ast_channel_unlock(chan);
545 return 0;
546 }
547 if (!strcasecmp(args.variable, "amaflags")) {
548 int amaflags;
549
550 ast_log(LOG_WARNING, "Using the %s function to set 'amaflags' is deprecated. Please use the CHANNEL function instead.\n",
551 cmd);
552 if (isdigit(*value)) {
553 if (sscanf(value, "%30d", &amaflags) != 1) {
555 }
556 } else {
558 }
559 ast_channel_lock(chan);
561 ast_channel_unlock(chan);
562 return 0;
563 }
564 if (!strcasecmp(args.variable, "peeraccount")) {
565 ast_log(LOG_WARNING, "The 'peeraccount' setting is not supported. Please set the 'accountcode' on the appropriate channel using the CHANNEL function.\n");
566 return 0;
567 }
568
569 /* The remaining CDR variables are handled by CDR processing code */
570 if (!cdr_write_message_type()) {
571 ast_log(LOG_WARNING, "Failed to manipulate CDR for channel %s: message type not available\n",
572 ast_channel_name(chan));
573 return -1;
574 }
575
576 payload = ao2_alloc(sizeof(*payload), NULL);
577 if (!payload) {
578 return -1;
579 }
580 payload->chan = chan;
581 payload->cmd = cmd;
582 payload->arguments = arguments;
583 payload->value = value;
584
585 message = stasis_message_create(cdr_write_message_type(), payload);
586 ao2_ref(payload, -1);
587 if (!message) {
588 ast_log(LOG_WARNING, "Failed to manipulate CDR for channel %s: unable to create message\n",
589 ast_channel_name(chan));
590 return -1;
591 }
593 if (!router) {
594 ast_log(LOG_WARNING, "Failed to manipulate CDR for channel %s: no message router\n",
595 ast_channel_name(chan));
596 ao2_ref(message, -1);
597 return -1;
598 }
600 ao2_ref(router, -1);
601 ao2_ref(message, -1);
602
603 return 0;
604}
#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:2922
@ AST_AMA_NONE
Definition: channel.h:1178
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:4359
#define ast_channel_unlock(chan)
Definition: channel.h:2923

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 359 of file func_cdr.c.

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

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 681 of file func_cdr.c.

682{
684 int res = 0;
685
686 if (!router) {
688 }
689
690 res |= STASIS_MESSAGE_TYPE_INIT(cdr_read_message_type);
691 res |= STASIS_MESSAGE_TYPE_INIT(cdr_write_message_type);
692 res |= STASIS_MESSAGE_TYPE_INIT(cdr_prop_write_message_type);
695 res |= stasis_message_router_add(router, cdr_prop_write_message_type(),
697 res |= stasis_message_router_add(router, cdr_write_message_type(),
699 res |= stasis_message_router_add(router, cdr_read_message_type(),
701
702 if (res) {
705 }
707}
static void cdr_prop_write_callback(void *data, struct stasis_subscription *sub, struct stasis_message *message)
Definition: func_cdr.c:402
static struct ast_custom_function cdr_prop_function
Definition: func_cdr.c:656
static void cdr_write_callback(void *data, struct stasis_subscription *sub, struct stasis_message *message)
Definition: func_cdr.c:359
static int unload_module(void)
Definition: func_cdr.c:662
static struct ast_custom_function cdr_function
Definition: func_cdr.c:650
@ 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:1558
#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 662 of file func_cdr.c.

663{
665 int res = 0;
666
667 if (router) {
668 stasis_message_router_remove(router, cdr_prop_write_message_type());
669 stasis_message_router_remove(router, cdr_write_message_type());
670 stasis_message_router_remove(router, cdr_read_message_type());
671 }
672 STASIS_MESSAGE_TYPE_CLEANUP(cdr_read_message_type);
673 STASIS_MESSAGE_TYPE_CLEANUP(cdr_write_message_type);
674 STASIS_MESSAGE_TYPE_CLEANUP(cdr_prop_write_message_type);
677
678 return res;
679}
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 714 of file func_cdr.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 714 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 205 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:450
static int cdr_write(struct ast_channel *chan, const char *cmd, char *arguments, const char *value)
Definition: func_cdr.c:508

Definition at line 650 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:606

Definition at line 656 of file func_cdr.c.

Referenced by load_module(), and unload_module().