Asterisk.org: Developer Documentation (28 Oct 2009)

Wed Oct 28 15:48:24 2009

## Asterisk developer's documentation

# cdr_custom.c File Reference

Custom Comma Separated Value CDR records. More...

`#include <sys/types.h>`
`#include <stdio.h>`
`#include <string.h>`
`#include <errno.h>`
`#include <stdlib.h>`
`#include <unistd.h>`
`#include <time.h>`
`#include "asterisk.h"`
`#include "asterisk/channel.h"`
`#include "asterisk/cdr.h"`
`#include "asterisk/module.h"`
`#include "asterisk/config.h"`
`#include "asterisk/pbx.h"`
`#include "asterisk/logger.h"`
`#include "asterisk/utils.h"`

Include dependency graph for cdr_custom.c:

Go to the source code of this file.

## Defines

#define | CUSTOM_LOG_DIR "/cdr_custom"
#define | DATE_FORMAT "%Y-%m-%d %T"

## Functions

| AST_MUTEX_DEFINE_STATIC (lock)
static int | custom_log (struct ast_cdr *cdr)
char * | description (void)
| Provides a description of the module.
char * | key ()
| Returns the ASTERISK_GPL_KEY.
static int | load_config (int reload)
int | load_module (void)
| Initialize the module.
int | reload (void)
| Reload stuff.
int | unload_module (void)
| Cleanup all module structures, sockets, etc.
int | usecount (void)
| Provides a usecount.

## Variables

static char * | desc = "Customizable Comma Separated Values CDR Backend"
static char | format [1024] = ""
static char | master [AST_CONFIG_MAX_PATH]
static FILE * | mf = NULL
static char * | name = "cdr-custom"

## Detailed Description

Custom Comma Separated Value CDR records.

- See also CDR - Call Data Records and billing

Logs in LOG_DIR/cdr_custom

Definition in file cdr_custom.c.

## Define Documentation

#define CUSTOM_LOG_DIR "/cdr_custom"

Definition at line 52 of file cdr_custom.c.

#define DATE_FORMAT "%Y-%m-%d %T"

Definition at line 54 of file cdr_custom.c.

## Function Documentation

AST_MUTEX_DEFINE_STATIC | ( | lock |  | ) |

static int custom_log | ( | struct ast_cdr * | cdr | ) | `[static]`

Definition at line 108 of file cdr_custom.c.

References ast_log(), ast_strlen_zero(), ast_channel::cdr, LOG_ERROR, and pbx_substitute_variables_helper().

Referenced by load_module().

    00109 {
    00110    /* Make sure we have a big enough buf */
    00111    char buf[2048];
    00112    struct ast_channel dummy;
    00113
    00114    /* Abort if no master file is specified */
    00115    if (ast_strlen_zero(master))
    00116       return 0;
    00117
    00118    memset(buf, 0 , sizeof(buf));
    00119    /* Quite possibly the first use of a static struct ast_channel, we need it so the var funcs will work */
    00120    memset(&dummy, 0, sizeof(dummy));
    00121    dummy.cdr = cdr;
    00122    pbx_substitute_variables_helper(&dummy, format, buf, sizeof(buf) - 1);
    00123
    00124    /* because of the absolutely unconditional need for the
    00125       highest reliability possible in writing billing records,
    00126       we open write and close the log file each time */
    00127    mf = fopen(master, "a");
    00128    if (!mf) {
    00129       ast_log(LOG_ERROR, "Unable to re-open master file %s : %s\n", master, strerror(errno));
    00130    }
    00131    if (mf) {
    00132       fputs(buf, mf);
    00133       fflush(mf); /* be particularly anal here */
    00134       fclose(mf);
    00135       mf = NULL;
    00136    }
    00137    return 0;
    00138 }

char* description | ( | void |  | ) |

Provides a description of the module.

Returns:
  a short description of your module

Definition at line 140 of file cdr_custom.c.

    00141 {
    00142    return desc;
    00143 }

char* key | ( | void |  | ) |

Returns the ASTERISK_GPL_KEY.

This returns the ASTERISK_GPL_KEY, signifiying that you agree to the terms of the GPL stated in the ASTERISK_GPL_KEY. Your module will not load if it does not return the EXACT message:

     char *key(void) {
             return ASTERISK_GPL_KEY;
     }

Returns:
  ASTERISK_GPL_KEY

Definition at line 177 of file cdr_custom.c.

References ASTERISK_GPL_KEY.

    00178 {
    00179    return ASTERISK_GPL_KEY;
    00180 }

static int load_config | ( | int | reload | ) | `[static]`

Definition at line 67 of file cdr_custom.c.

References ast_config_AST_LOG_DIR, ast_config_destroy(), ast_config_load(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), ast_variable_browse(), cfg, ast_variable::lineno, lock, LOG_NOTICE, LOG_WARNING, ast_variable::name, ast_variable::next, ast_variable::value, and var.

    00068 {
    00069    struct ast_config *cfg;
    00070    struct ast_variable *var;
    00071    int res = -1;
    00072
    00073    strcpy(format, "");
    00074    strcpy(master, "");
    00075    ast_mutex_lock(&lock);
    00076    if((cfg = ast_config_load("cdr_custom.conf"))) {
    00077       var = ast_variable_browse(cfg, "mappings");
    00078       while(var) {
    00079          if (!ast_strlen_zero(var->name) && !ast_strlen_zero(var->value)) {
    00080             if (strlen(var->value) > (sizeof(format) - 2))
    00081                ast_log(LOG_WARNING, "Format string too long, will be truncated, at line %d\n", var->lineno);
    00082             strncpy(format, var->value, sizeof(format) - 2);
    00083             strcat(format,"\n");
    00084             snprintf(master, sizeof(master),"%s/%s/%s", ast_config_AST_LOG_DIR, name, var->name);
    00085             if (var->next) {
    00086                ast_log(LOG_NOTICE, "Sorry, only one mapping is supported at this time, mapping '%s' will be ignored at line %d.\n", var->next->name, var->next->lineno);
    00087                break;
    00088             }
    00089          } else
    00090             ast_log(LOG_NOTICE, "Mapping must have both filename and format at line %d\n", var->lineno);
    00091          var = var->next;
    00092       }
    00093       ast_config_destroy(cfg);
    00094       res = 0;
    00095    } else {
    00096       if (reload)
    00097          ast_log(LOG_WARNING, "Failed to reload configuration file.\n");
    00098       else
    00099          ast_log(LOG_WARNING, "Failed to load configuration file. Module not activated.\n");
    00100    }
    00101    ast_mutex_unlock(&lock);
    00102
    00103    return res;
    00104 }

int load_module | ( | void |  | ) |

Initialize the module.

This function is called at module load time. Put all code in here that needs to set up your module's hardware, software, registrations, etc.

Returns:
  This function should return 0 on success and non-zero on failure. If the module is not loaded successfully, Asterisk will call its unload_module() function.

Initialize the Agents module. This function is being called by Asterisk when loading the module. Among other thing it registers applications, cli commands and reads the cofiguration file.

Returns:
  int Always 0.

TE STUFF END

Definition at line 153 of file cdr_custom.c.

References ast_cdr_register(), ast_log(), custom_log(), load_config(), and LOG_ERROR.

    00154 {
    00155    int res = 0;
    00156
    00157    if (!load_config(0)) {
    00158       res = ast_cdr_register(name, desc, custom_log);
    00159       if (res)
    00160          ast_log(LOG_ERROR, "Unable to register custom CDR handling\n");
    00161       if (mf)
    00162          fclose(mf);
    00163    }
    00164    return res;
    00165 }

int reload | ( | void |  | ) |

Reload stuff.

This function is where any reload routines take place. Re-read config files, change signalling, whatever is appropriate on a reload.

Returns:
  The return value is not used.

Definition at line 167 of file cdr_custom.c.

References load_config().

    00168 {
    00169    return load_config(1);
    00170 }

int unload_module | ( | void |  | ) |

Cleanup all module structures, sockets, etc.

This is called at exit. Any registrations and memory allocations need to be unregistered and free'd here. Nothing else will do these for you (until exit).

Returns:
  Zero on success, or non-zero on error.

Definition at line 145 of file cdr_custom.c.

References ast_cdr_unregister().

    00146 {
    00147    if (mf)
    00148       fclose(mf);
    00149    ast_cdr_unregister(name);
    00150    return 0;
    00151 }

int usecount | ( | void |  | ) |

Provides a usecount.

This function will be called by various parts of asterisk. Basically, all it has to do is to return a usecount when called. You will need to maintain your usecount within the module somewhere. The usecount should be how many channels provided by this module are in use.

Returns:
  The module's usecount.

Definition at line 172 of file cdr_custom.c.

    00173 {
    00174    return 0;
    00175 }

## Variable Documentation

char* desc = "Customizable Comma Separated Values CDR Backend"`[static]`

Definition at line 58 of file cdr_custom.c.

char format[1024] = ""`[static]`

Definition at line 65 of file cdr_custom.c.

char master[AST_CONFIG_MAX_PATH]`[static]`

Definition at line 64 of file cdr_custom.c.

Referenced by __unload_module(), mutedlevel(), and zt_bridge().

FILE* mf = NULL`[static]`

Definition at line 62 of file cdr_custom.c.

char* name = "cdr-custom"`[static]`

Definition at line 60 of file cdr_custom.c.