Fri Jul 15 2011 11:59:45

Asterisk developer's documentation


cdr_radius.c File Reference

RADIUS CDR Support. More...

#include "asterisk.h"
#include <time.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_DEFAULT , .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, .load = load_module, .unload = unload_module, }
static struct ast_module_infoast_module_info = &__mod_info
static char * cdr_config = "cdr.conf"
static char * desc = "RADIUS CDR Backend"
static struct ast_flags global_flags = { RADIUS_FLAG_USEGMTIME | RADIUS_FLAG_LOGUNIQUEID | RADIUS_FLAG_LOGUSERFIELD }
static 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
ExtRef:
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 46 of file cdr_radius.c.

Referenced by build_radius_record().

#define VENDOR_CODE   22736

Definition at line 48 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 50 of file cdr_radius.c.

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 71 of file cdr_radius.c.

     {
   /*! Log dates and times in UTC */
   RADIUS_FLAG_USEGMTIME = (1 << 0),
   /*! Log Unique ID */
   RADIUS_FLAG_LOGUNIQUEID = (1 << 1),
   /*! Log User Field */
   RADIUS_FLAG_LOGUSERFIELD = (1 << 2)
};

Function Documentation

static void __reg_module ( void  ) [static]

Definition at line 266 of file cdr_radius.c.

static void __unreg_module ( void  ) [static]

Definition at line 266 of file cdr_radius.c.

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

Definition at line 90 of file cdr_radius.c.

References ast_cdr::accountcode, ast_cdr::amaflags, ast_cdr::answer, ast_cdr_disp2str(), ast_cdr_flags2str(), ast_localtime(), 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, 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, ast_cdr::uniqueid, ast_cdr::userfield, and VENDOR_CODE.

Referenced by radius_log().

{
   int recordtype = PW_STATUS_STOP;
   struct ast_tm tm;
   char timestr[128];
   char *tmp;

   if (!rc_avpair_add(rh, tosend, PW_ACCT_STATUS_TYPE, &recordtype, 0, 0))
      return -1;

   /* Account code */
   if (!rc_avpair_add(rh, tosend, PW_AST_ACCT_CODE, &cdr->accountcode, strlen(cdr->accountcode), VENDOR_CODE))
      return -1;

   /* Source */
   if (!rc_avpair_add(rh, tosend, PW_AST_SRC, &cdr->src, strlen(cdr->src), VENDOR_CODE))
      return -1;

   /* Destination */
   if (!rc_avpair_add(rh, tosend, PW_AST_DST, &cdr->dst, strlen(cdr->dst), VENDOR_CODE))
      return -1;

   /* Destination context */
   if (!rc_avpair_add(rh, tosend, PW_AST_DST_CTX, &cdr->dcontext, strlen(cdr->dcontext), VENDOR_CODE))
      return -1;

   /* Caller ID */
   if (!rc_avpair_add(rh, tosend, PW_AST_CLID, &cdr->clid, strlen(cdr->clid), VENDOR_CODE))
      return -1;

   /* Channel */
   if (!rc_avpair_add(rh, tosend, PW_AST_CHAN, &cdr->channel, strlen(cdr->channel), VENDOR_CODE))
      return -1;

   /* Destination Channel */
   if (!rc_avpair_add(rh, tosend, PW_AST_DST_CHAN, &cdr->dstchannel, strlen(cdr->dstchannel), VENDOR_CODE))
      return -1;

   /* Last Application */
   if (!rc_avpair_add(rh, tosend, PW_AST_LAST_APP, &cdr->lastapp, strlen(cdr->lastapp), VENDOR_CODE))
      return -1;

   /* Last Data */
   if (!rc_avpair_add(rh, tosend, PW_AST_LAST_DATA, &cdr->lastdata, strlen(cdr->lastdata), VENDOR_CODE))
      return -1;


   /* Start Time */
   ast_strftime(timestr, sizeof(timestr), DATE_FORMAT,
      ast_localtime(&cdr->start, &tm,
         ast_test_flag(&global_flags, RADIUS_FLAG_USEGMTIME) ? "GMT" : NULL));
   if (!rc_avpair_add(rh, tosend, PW_AST_START_TIME, timestr, strlen(timestr), VENDOR_CODE))
      return -1;

   /* Answer Time */
   ast_strftime(timestr, sizeof(timestr), DATE_FORMAT,
      ast_localtime(&cdr->answer, &tm,
         ast_test_flag(&global_flags, RADIUS_FLAG_USEGMTIME) ? "GMT" : NULL));
   if (!rc_avpair_add(rh, tosend, PW_AST_ANSWER_TIME, timestr, strlen(timestr), VENDOR_CODE))
      return -1;

   /* End Time */
   ast_strftime(timestr, sizeof(timestr), DATE_FORMAT,
      ast_localtime(&cdr->end, &tm,
         ast_test_flag(&global_flags, RADIUS_FLAG_USEGMTIME) ? "GMT" : NULL));
   if (!rc_avpair_add(rh, tosend, PW_AST_END_TIME, timestr, strlen(timestr), VENDOR_CODE))
      return -1;

   /* Duration */
   if (!rc_avpair_add(rh, tosend, PW_AST_DURATION, &cdr->duration, 0, VENDOR_CODE))
      return -1;

   /* Billable seconds */
   if (!rc_avpair_add(rh, tosend, PW_AST_BILL_SEC, &cdr->billsec, 0, VENDOR_CODE))
      return -1;

   /* Disposition */
   tmp = ast_cdr_disp2str(cdr->disposition);
   if (!rc_avpair_add(rh, tosend, PW_AST_DISPOSITION, tmp, strlen(tmp), VENDOR_CODE))
      return -1;

   /* AMA Flags */
   tmp = ast_cdr_flags2str(cdr->amaflags);
   if (!rc_avpair_add(rh, tosend, PW_AST_AMA_FLAGS, tmp, strlen(tmp), VENDOR_CODE))
      return -1;

   if (ast_test_flag(&global_flags, RADIUS_FLAG_LOGUNIQUEID)) {
      /* Unique ID */
      if (!rc_avpair_add(rh, tosend, PW_AST_UNIQUE_ID, &cdr->uniqueid, strlen(cdr->uniqueid), VENDOR_CODE))
         return -1;
   }

   if (ast_test_flag(&global_flags, RADIUS_FLAG_LOGUSERFIELD)) {
      /* append the user field */
      if (!rc_avpair_add(rh, tosend, PW_AST_USER_FIELD, &cdr->userfield, strlen(cdr->userfield), VENDOR_CODE))
         return -1;
   }

   /* Setting Acct-Session-Id & User-Name attributes for proper generation
      of Acct-Unique-Session-Id on server side */
   /* Channel */
   if (!rc_avpair_add(rh, tosend, PW_USER_NAME, &cdr->channel, strlen(cdr->channel), 0))
      return -1;

   /* Unique ID */
   if (!rc_avpair_add(rh, tosend, PW_ACCT_SESSION_ID, &cdr->uniqueid, strlen(cdr->uniqueid), 0))
      return -1;

   return 0;
}
static int load_module ( void  ) [static]

Definition at line 230 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_true(), ast_variable_retrieve(), CONFIG_STATUS_FILEINVALID, LOG_NOTICE, RADIUS_FLAG_LOGUNIQUEID, RADIUS_FLAG_LOGUSERFIELD, RADIUS_FLAG_USEGMTIME, and radius_log().

{
   struct ast_config *cfg;
   struct ast_flags config_flags = { 0 };
   int res;
   const char *tmp;

   if ((cfg = ast_config_load(cdr_config, config_flags)) && cfg != CONFIG_STATUS_FILEINVALID) {
      ast_set2_flag(&global_flags, ast_true(ast_variable_retrieve(cfg, "radius", "usegmtime")), RADIUS_FLAG_USEGMTIME);
      ast_set2_flag(&global_flags, ast_true(ast_variable_retrieve(cfg, "radius", "loguniqueid")), RADIUS_FLAG_LOGUNIQUEID);
      ast_set2_flag(&global_flags, ast_true(ast_variable_retrieve(cfg, "radius", "loguserfield")), RADIUS_FLAG_LOGUSERFIELD);
      if ((tmp = ast_variable_retrieve(cfg, "radius", "radiuscfg")))
         ast_copy_string(radiuscfg, tmp, sizeof(radiuscfg));
      ast_config_destroy(cfg);
   } else
      return AST_MODULE_LOAD_DECLINE;

   /* start logging */
   rc_openlog("asterisk");

   /* read radiusclient-ng config file */
   if (!(rh = rc_read_config(radiuscfg))) {
      ast_log(LOG_NOTICE, "Cannot load radiusclient-ng configuration file %s.\n", radiuscfg);
      return AST_MODULE_LOAD_DECLINE;
   }

   /* read radiusclient-ng dictionaries */
   if (rc_read_dictionary(rh, rc_conf_str(rh, "dictionary"))) {
      ast_log(LOG_NOTICE, "Cannot load radiusclient-ng dictionary file.\n");
      return AST_MODULE_LOAD_DECLINE;
   }

   res = ast_cdr_register(name, desc, radius_log);
   return AST_MODULE_LOAD_SUCCESS;
}
static int radius_log ( struct ast_cdr cdr) [static]

Definition at line 201 of file cdr_radius.c.

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

Referenced by load_module().

{
   int result = ERROR_RC;
   VALUE_PAIR *tosend = NULL;

   if (build_radius_record(&tosend, cdr)) {
      ast_debug(1, "Unable to create RADIUS record. CDR not recorded!\n");
      goto return_cleanup;
   }

   result = rc_acct(rh, 0, tosend);
   if (result != OK_RC) {
      ast_log(LOG_ERROR, "Failed to record Radius CDR record!\n");
   }

return_cleanup:
   if (tosend) {
      rc_avpair_free(tosend);
   }

   return result;
}
static int unload_module ( void  ) [static]

Definition at line 224 of file cdr_radius.c.

References ast_cdr_unregister().

{
   ast_cdr_unregister(name);
   return 0;
}

Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .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, .load = load_module, .unload = unload_module, } [static]

Definition at line 266 of file cdr_radius.c.

Definition at line 266 of file cdr_radius.c.

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

Definition at line 82 of file cdr_radius.c.

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

Definition at line 80 of file cdr_radius.c.

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

Definition at line 86 of file cdr_radius.c.

char* name = "radius" [static]

Definition at line 81 of file cdr_radius.c.

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

Definition at line 84 of file cdr_radius.c.

rc_handle* rh = NULL [static]

Definition at line 88 of file cdr_radius.c.