Asterisk - The Open Source Telephony Project GIT-master-a63eec2
Loading...
Searching...
No Matches
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 = ASTERISK_GPL_KEY , .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:4443
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:978

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:3723
ast_cdr_options
CDR manipulation options. Certain function calls will manipulate the state of a CDR object based on t...
Definition cdr.h:243
@ AST_CDR_FLAG_DISABLE_ALL
Definition cdr.h:246
@ AST_CDR_FLAG_PARTY_A
Definition cdr.h:247
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:3696
#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.
static struct @519 args
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:2235
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
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(), 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

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:3183
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:3470
const char * ast_cdr_disp2str(int disposition)
Disposition to a string.
Definition cdr.c:3576
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:4340
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
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:217
unsigned int flags
Definition utils.h:218
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:776
#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, cdr_func_data::len, NULL, OPT_FLOAT, OPT_UNPARSED, options, stasis_message_data(), 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:2972
@ 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:4327
#define ast_channel_unlock(chan)
Definition channel.h:2973

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:3625
int ast_cdr_setvar(const char *channel_name, const char *name, const char *value)
Set a variable on a CDR.
Definition cdr.c:3316

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(), 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:1562
#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 = ASTERISK_GPL_KEY , .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.

656 {
657 .name = "CDR",
658 .read = cdr_read,
659 .write = cdr_write,
660};

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.

662 {
663 .name = "CDR_PROP",
664 .read = NULL,
665 .write = cdr_prop_write,
666};

Referenced by load_module(), and unload_module().