Sat Apr 26 2014 22:02:00

Asterisk developer's documentation


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

Referenced by build_radius_record().

#define VENDOR_CODE   22736

Definition at line 53 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 55 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 76 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 298 of file cdr_radius.c.

static void __unreg_module ( void  ) [static]

Definition at line 298 of file cdr_radius.c.

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

Definition at line 99 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 243 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, RADIUS_FLAG_LOGUNIQUEID, RADIUS_FLAG_LOGUSERFIELD, RADIUS_FLAG_USEGMTIME, and radius_log().

{
   struct ast_config *cfg;
   struct ast_flags config_flags = { 0 };
   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
    *
    * NOTE: Yes this causes a slight memory leak if the module is
    * unloaded.  However, it is better than a crash if cdr_radius
    * and cel_radius are both loaded.
    */
   tmp = ast_strdup("asterisk");
   if (tmp) {
      rc_openlog((char *) tmp);
   }

   /* 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");
      rc_destroy(rh);
      rh = NULL;
      return AST_MODULE_LOAD_DECLINE;
   }

   if (ast_cdr_register(name, desc, radius_log)) {
      rc_destroy(rh);
      rh = NULL;
      return AST_MODULE_LOAD_DECLINE;
   } else {
      return AST_MODULE_LOAD_SUCCESS;
   }
}
static int radius_log ( struct ast_cdr cdr) [static]

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

References ast_cdr_unregister().

{
   ast_cdr_unregister(name);
   if (rh) {
      rc_destroy(rh);
      rh = NULL;
   }
   return 0;
}

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, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_CDR_DRIVER, } [static]

Definition at line 298 of file cdr_radius.c.

Definition at line 298 of file cdr_radius.c.

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

Definition at line 87 of file cdr_radius.c.

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

Definition at line 86 of file cdr_radius.c.

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

Definition at line 92 of file cdr_radius.c.

rc_handle* rh = NULL [static]

Definition at line 97 of file cdr_radius.c.

Referenced by handle_response().