cdr_radius.c File Reference

RADIUS CDR Support. More...

#include "asterisk.h"
#include <radiusclient-ng.h>
#include "asterisk/channel.h"
#include "asterisk/cdr.h"
#include "asterisk/module.h"
#include "asterisk/utils.h"

Include dependency graph for cdr_radius.c:

Go to the source code of this file.

Defines

#define DATE_FORMAT   "%Y-%m-%d %T %z"
#define VENDOR_CODE   22736

Enumerations

enum  {
  PW_AST_ACCT_CODE = 101, PW_AST_SRC = 102, PW_AST_DST = 103, PW_AST_DST_CTX = 104,
  PW_AST_CLID = 105, PW_AST_CHAN = 106, PW_AST_DST_CHAN = 107, PW_AST_LAST_APP = 108,
  PW_AST_LAST_DATA = 109, PW_AST_START_TIME = 110, PW_AST_ANSWER_TIME = 111, PW_AST_END_TIME = 112,
  PW_AST_DURATION = 113, PW_AST_BILL_SEC = 114, PW_AST_DISPOSITION = 115, PW_AST_AMA_FLAGS = 116,
  PW_AST_UNIQUE_ID = 117, PW_AST_USER_FIELD = 118
}
enum  { RADIUS_FLAG_USEGMTIME = (1 << 0), RADIUS_FLAG_LOGUNIQUEID = (1 << 1), RADIUS_FLAG_LOGUSERFIELD = (1 << 2) }

Functions

static void __reg_module (void)
static void __unreg_module (void)
static int build_radius_record (VALUE_PAIR **tosend, struct ast_cdr *cdr)
static int load_module (void)
static int radius_log (struct ast_cdr *cdr)
static int unload_module (void)

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "RADIUS CDR Backend" , .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_EXTENDED, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_CDR_DRIVER, }
static struct ast_module_infoast_module_info = &__mod_info
static const char cdr_config [] = "cdr.conf"
static const char desc [] = "RADIUS CDR Backend"
static struct ast_flags global_flags = { RADIUS_FLAG_USEGMTIME | RADIUS_FLAG_LOGUNIQUEID | RADIUS_FLAG_LOGUSERFIELD }
static const char name [] = "radius"
static char radiuscfg [PATH_MAX] = "/etc/radiusclient-ng/radiusclient.conf"
static rc_handle * rh = NULL


Detailed Description

RADIUS CDR Support.

Author:
Philippe Sultan The Radius Client Library http://developer.berlios.de/projects/radiusclient-ng/

Definition in file cdr_radius.c.


Define Documentation

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

ISO 8601 standard format

Definition at line 56 of file cdr_radius.c.

#define VENDOR_CODE   22736

Definition at line 58 of file cdr_radius.c.

Referenced by build_radius_record().


Enumeration Type Documentation

anonymous enum

Enumerator:
PW_AST_ACCT_CODE 
PW_AST_SRC 
PW_AST_DST 
PW_AST_DST_CTX 
PW_AST_CLID 
PW_AST_CHAN 
PW_AST_DST_CHAN 
PW_AST_LAST_APP 
PW_AST_LAST_DATA 
PW_AST_START_TIME 
PW_AST_ANSWER_TIME 
PW_AST_END_TIME 
PW_AST_DURATION 
PW_AST_BILL_SEC 
PW_AST_DISPOSITION 
PW_AST_AMA_FLAGS 
PW_AST_UNIQUE_ID 
PW_AST_USER_FIELD 

Definition at line 60 of file cdr_radius.c.

00060      {
00061    PW_AST_ACCT_CODE =    101,
00062    PW_AST_SRC =          102,
00063    PW_AST_DST =          103,
00064    PW_AST_DST_CTX =      104,
00065    PW_AST_CLID =         105,
00066    PW_AST_CHAN =         106,
00067    PW_AST_DST_CHAN =     107,
00068    PW_AST_LAST_APP =     108,
00069    PW_AST_LAST_DATA =    109,
00070    PW_AST_START_TIME =   110,
00071    PW_AST_ANSWER_TIME =  111,
00072    PW_AST_END_TIME =     112,
00073    PW_AST_DURATION =     113,
00074    PW_AST_BILL_SEC =     114,
00075    PW_AST_DISPOSITION =  115,
00076    PW_AST_AMA_FLAGS =    116,
00077    PW_AST_UNIQUE_ID =    117,
00078    PW_AST_USER_FIELD =   118
00079 };

anonymous enum

Enumerator:
RADIUS_FLAG_USEGMTIME  Log dates and times in UTC
RADIUS_FLAG_LOGUNIQUEID  Log Unique ID
RADIUS_FLAG_LOGUSERFIELD  Log User Field

Definition at line 81 of file cdr_radius.c.

00081      {
00082    /*! Log dates and times in UTC */
00083    RADIUS_FLAG_USEGMTIME = (1 << 0),
00084    /*! Log Unique ID */
00085    RADIUS_FLAG_LOGUNIQUEID = (1 << 1),
00086    /*! Log User Field */
00087    RADIUS_FLAG_LOGUSERFIELD = (1 << 2)
00088 };


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 308 of file cdr_radius.c.

static void __unreg_module ( void   )  [static]

Definition at line 308 of file cdr_radius.c.

static int build_radius_record ( VALUE_PAIR **  tosend,
struct ast_cdr cdr 
) [static]

Definition at line 104 of file cdr_radius.c.

References ast_cdr::accountcode, ast_cdr::amaflags, ast_cdr::answer, ast_cdr_disp2str(), ast_channel_amaflags2string(), ast_localtime(), ast_strdupa, ast_strftime(), ast_test_flag, ast_cdr::billsec, ast_cdr::channel, ast_cdr::clid, DATE_FORMAT, ast_cdr::dcontext, ast_cdr::disposition, ast_cdr::dst, ast_cdr::dstchannel, ast_cdr::duration, ast_cdr::end, ast_cdr::lastapp, ast_cdr::lastdata, NULL, PW_AST_ACCT_CODE, PW_AST_AMA_FLAGS, PW_AST_ANSWER_TIME, PW_AST_BILL_SEC, PW_AST_CHAN, PW_AST_CLID, PW_AST_DISPOSITION, PW_AST_DST, PW_AST_DST_CHAN, PW_AST_DST_CTX, PW_AST_DURATION, PW_AST_END_TIME, PW_AST_LAST_APP, PW_AST_LAST_DATA, PW_AST_SRC, PW_AST_START_TIME, PW_AST_UNIQUE_ID, PW_AST_USER_FIELD, RADIUS_FLAG_LOGUNIQUEID, RADIUS_FLAG_LOGUSERFIELD, RADIUS_FLAG_USEGMTIME, ast_cdr::src, ast_cdr::start, tmp(), ast_cdr::uniqueid, ast_cdr::userfield, and VENDOR_CODE.

Referenced by radius_log().

00105 {
00106    int recordtype = PW_STATUS_STOP;
00107    struct ast_tm tm;
00108    char timestr[128];
00109    char *tmp;
00110 
00111    if (!rc_avpair_add(rh, tosend, PW_ACCT_STATUS_TYPE, &recordtype, 0, 0))
00112       return -1;
00113 
00114    /* Account code */
00115    if (!rc_avpair_add(rh, tosend, PW_AST_ACCT_CODE, &cdr->accountcode, strlen(cdr->accountcode), VENDOR_CODE))
00116       return -1;
00117 
00118    /* Source */
00119    if (!rc_avpair_add(rh, tosend, PW_AST_SRC, &cdr->src, strlen(cdr->src), VENDOR_CODE))
00120       return -1;
00121 
00122    /* Destination */
00123    if (!rc_avpair_add(rh, tosend, PW_AST_DST, &cdr->dst, strlen(cdr->dst), VENDOR_CODE))
00124       return -1;
00125 
00126    /* Destination context */
00127    if (!rc_avpair_add(rh, tosend, PW_AST_DST_CTX, &cdr->dcontext, strlen(cdr->dcontext), VENDOR_CODE))
00128       return -1;
00129 
00130    /* Caller ID */
00131    if (!rc_avpair_add(rh, tosend, PW_AST_CLID, &cdr->clid, strlen(cdr->clid), VENDOR_CODE))
00132       return -1;
00133 
00134    /* Channel */
00135    if (!rc_avpair_add(rh, tosend, PW_AST_CHAN, &cdr->channel, strlen(cdr->channel), VENDOR_CODE))
00136       return -1;
00137 
00138    /* Destination Channel */
00139    if (!rc_avpair_add(rh, tosend, PW_AST_DST_CHAN, &cdr->dstchannel, strlen(cdr->dstchannel), VENDOR_CODE))
00140       return -1;
00141 
00142    /* Last Application */
00143    if (!rc_avpair_add(rh, tosend, PW_AST_LAST_APP, &cdr->lastapp, strlen(cdr->lastapp), VENDOR_CODE))
00144       return -1;
00145 
00146    /* Last Data */
00147    if (!rc_avpair_add(rh, tosend, PW_AST_LAST_DATA, &cdr->lastdata, strlen(cdr->lastdata), VENDOR_CODE))
00148       return -1;
00149 
00150 
00151    /* Start Time */
00152    ast_strftime(timestr, sizeof(timestr), DATE_FORMAT,
00153       ast_localtime(&cdr->start, &tm,
00154          ast_test_flag(&global_flags, RADIUS_FLAG_USEGMTIME) ? "GMT" : NULL));
00155    if (!rc_avpair_add(rh, tosend, PW_AST_START_TIME, timestr, strlen(timestr), VENDOR_CODE))
00156       return -1;
00157 
00158    /* Answer Time */
00159    ast_strftime(timestr, sizeof(timestr), DATE_FORMAT,
00160       ast_localtime(&cdr->answer, &tm,
00161          ast_test_flag(&global_flags, RADIUS_FLAG_USEGMTIME) ? "GMT" : NULL));
00162    if (!rc_avpair_add(rh, tosend, PW_AST_ANSWER_TIME, timestr, strlen(timestr), VENDOR_CODE))
00163       return -1;
00164 
00165    /* End Time */
00166    ast_strftime(timestr, sizeof(timestr), DATE_FORMAT,
00167       ast_localtime(&cdr->end, &tm,
00168          ast_test_flag(&global_flags, RADIUS_FLAG_USEGMTIME) ? "GMT" : NULL));
00169    if (!rc_avpair_add(rh, tosend, PW_AST_END_TIME, timestr, strlen(timestr), VENDOR_CODE))
00170       return -1;
00171 
00172    /* Duration */
00173    if (!rc_avpair_add(rh, tosend, PW_AST_DURATION, &cdr->duration, 0, VENDOR_CODE))
00174       return -1;
00175 
00176    /* Billable seconds */
00177    if (!rc_avpair_add(rh, tosend, PW_AST_BILL_SEC, &cdr->billsec, 0, VENDOR_CODE))
00178       return -1;
00179 
00180    /* Disposition */
00181    tmp = ast_strdupa(ast_cdr_disp2str(cdr->disposition));
00182    if (!rc_avpair_add(rh, tosend, PW_AST_DISPOSITION, tmp, strlen(tmp), VENDOR_CODE))
00183       return -1;
00184 
00185    /* AMA Flags */
00186    tmp = ast_strdupa(ast_channel_amaflags2string(cdr->amaflags));
00187    if (!rc_avpair_add(rh, tosend, PW_AST_AMA_FLAGS, tmp, strlen(tmp), VENDOR_CODE))
00188       return -1;
00189 
00190    if (ast_test_flag(&global_flags, RADIUS_FLAG_LOGUNIQUEID)) {
00191       /* Unique ID */
00192       if (!rc_avpair_add(rh, tosend, PW_AST_UNIQUE_ID, &cdr->uniqueid, strlen(cdr->uniqueid), VENDOR_CODE))
00193          return -1;
00194    }
00195 
00196    if (ast_test_flag(&global_flags, RADIUS_FLAG_LOGUSERFIELD)) {
00197       /* append the user field */
00198       if (!rc_avpair_add(rh, tosend, PW_AST_USER_FIELD, &cdr->userfield, strlen(cdr->userfield), VENDOR_CODE))
00199          return -1;
00200    }
00201 
00202    /* Setting Acct-Session-Id & User-Name attributes for proper generation
00203     * of Acct-Unique-Session-Id on server side 
00204     */
00205    /* Channel */
00206    if (!rc_avpair_add(rh, tosend, PW_USER_NAME, &cdr->channel, strlen(cdr->channel), 0))
00207       return -1;
00208 
00209    /* Unique ID */
00210    if (!rc_avpair_add(rh, tosend, PW_ACCT_SESSION_ID, &cdr->uniqueid, strlen(cdr->uniqueid), 0))
00211       return -1;
00212 
00213    return 0;
00214 }

static int load_module ( void   )  [static]

Definition at line 252 of file cdr_radius.c.

References ast_cdr_register(), ast_config_destroy(), ast_config_load, ast_copy_string(), ast_log, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, ast_set2_flag, ast_strdup, ast_true(), ast_variable_retrieve(), CONFIG_STATUS_FILEINVALID, LOG_NOTICE, NULL, RADIUS_FLAG_LOGUNIQUEID, RADIUS_FLAG_LOGUSERFIELD, RADIUS_FLAG_USEGMTIME, radius_log(), and tmp().

00253 {
00254    struct ast_config *cfg;
00255    struct ast_flags config_flags = { 0 };
00256    const char *tmp;
00257 
00258    if ((cfg = ast_config_load(cdr_config, config_flags)) && cfg != CONFIG_STATUS_FILEINVALID) {
00259       ast_set2_flag(&global_flags, ast_true(ast_variable_retrieve(cfg, "radius", "usegmtime")), RADIUS_FLAG_USEGMTIME);
00260       ast_set2_flag(&global_flags, ast_true(ast_variable_retrieve(cfg, "radius", "loguniqueid")), RADIUS_FLAG_LOGUNIQUEID);
00261       ast_set2_flag(&global_flags, ast_true(ast_variable_retrieve(cfg, "radius", "loguserfield")), RADIUS_FLAG_LOGUSERFIELD);
00262       if ((tmp = ast_variable_retrieve(cfg, "radius", "radiuscfg")))
00263          ast_copy_string(radiuscfg, tmp, sizeof(radiuscfg));
00264       ast_config_destroy(cfg);
00265    } else
00266       return AST_MODULE_LOAD_DECLINE;
00267 
00268    /*
00269     * start logging
00270     *
00271     * NOTE: Yes this causes a slight memory leak if the module is
00272     * unloaded.  However, it is better than a crash if cdr_radius
00273     * and cel_radius are both loaded.
00274     */
00275    tmp = ast_strdup("asterisk");
00276    if (tmp) {
00277       rc_openlog((char *) tmp);
00278    }
00279 
00280    /* read radiusclient-ng config file */
00281    if (!(rh = rc_read_config(radiuscfg))) {
00282       ast_log(LOG_NOTICE, "Cannot load radiusclient-ng configuration file %s.\n", radiuscfg);
00283       return AST_MODULE_LOAD_DECLINE;
00284    }
00285 
00286    /* read radiusclient-ng dictionaries */
00287    if (rc_read_dictionary(rh, rc_conf_str(rh, "dictionary"))) {
00288       ast_log(LOG_NOTICE, "Cannot load radiusclient-ng dictionary file.\n");
00289       rc_destroy(rh);
00290       rh = NULL;
00291       return AST_MODULE_LOAD_DECLINE;
00292    }
00293 
00294    if (ast_cdr_register(name, desc, radius_log)) {
00295       rc_destroy(rh);
00296       rh = NULL;
00297       return AST_MODULE_LOAD_DECLINE;
00298    } else {
00299       return AST_MODULE_LOAD_SUCCESS;
00300    }
00301 }

static int radius_log ( struct ast_cdr cdr  )  [static]

Definition at line 216 of file cdr_radius.c.

References ast_debug, ast_log, build_radius_record(), LOG_ERROR, NULL, and result.

Referenced by load_module().

00217 {
00218    int result = ERROR_RC;
00219    VALUE_PAIR *tosend = NULL;
00220 
00221    if (build_radius_record(&tosend, cdr)) {
00222       ast_debug(1, "Unable to create RADIUS record. CDR not recorded!\n");
00223       goto return_cleanup;
00224    }
00225 
00226    result = rc_acct(rh, 0, tosend);
00227    if (result != OK_RC) {
00228       ast_log(LOG_ERROR, "Failed to record Radius CDR record!\n");
00229    }
00230 
00231 return_cleanup:
00232    if (tosend) {
00233       rc_avpair_free(tosend);
00234    }
00235 
00236    return result;
00237 }

static int unload_module ( void   )  [static]

Definition at line 239 of file cdr_radius.c.

References ast_cdr_unregister(), and NULL.

00240 {
00241    if (ast_cdr_unregister(name)) {
00242       return -1;
00243    }
00244 
00245    if (rh) {
00246       rc_destroy(rh);
00247       rh = NULL;
00248    }
00249    return 0;
00250 }


Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "RADIUS CDR Backend" , .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_EXTENDED, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_CDR_DRIVER, } [static]

Definition at line 308 of file cdr_radius.c.

Definition at line 308 of file cdr_radius.c.

const char cdr_config[] = "cdr.conf" [static]

Definition at line 92 of file cdr_radius.c.

Referenced by module_config_alloc().

const char desc[] = "RADIUS CDR Backend" [static]

Definition at line 90 of file cdr_radius.c.

struct ast_flags global_flags = { RADIUS_FLAG_USEGMTIME | RADIUS_FLAG_LOGUNIQUEID | RADIUS_FLAG_LOGUSERFIELD } [static]

Definition at line 100 of file cdr_radius.c.

const char name[] = "radius" [static]

Definition at line 91 of file cdr_radius.c.

char radiuscfg[PATH_MAX] = "/etc/radiusclient-ng/radiusclient.conf" [static]

Definition at line 97 of file cdr_radius.c.

rc_handle* rh = NULL [static]

Definition at line 102 of file cdr_radius.c.

Referenced by handle_registrations(), and handle_response().


Generated on Thu Apr 16 06:29:25 2015 for Asterisk - The Open Source Telephony Project by  doxygen 1.5.6