/* * Asterisk -- A telephony toolkit for Linux. * * RADIUS CDR logger * * Copyright (C) 2004 Minitelecom * * by Michael Pounov * * $Author: misho $ * $Id: cdr_radius.c,v 1.2 2004/04/19 12:59:18 misho Exp $ * * This program is free software, distributed under the terms of * the GNU General Public License. * */ #include #include #include #include #include #include #include #include #include "global.h" #include "cdr_radius.h" static char *desc = "RADIUS CDR Backend"; static char *name = "radius"; const char *csMaskRad = "Cpp"; const char *csMaskErr = "pp_error"; const char *csPickup = "pickup"; const char *csMaskCall = "callerror"; static int radius_stop(char* user, char* app, char* appdata, int billtime, int alltime, char* channel) { struct rad_handle *rh; int res, nProto = 0; char szProto[MAX_STR + 1]; char szFN[MAX_STR + 1]; char szSID[MAX_SID + 1]; FILE *f; rh = rad_acct_open(); // ast_log(LOG_NOTICE,"user=%s,app=%s,appdata=%s,channel=%s\n ",user,app,appdata,channel); if (!rh) return 0; else rad_config(rh, RADCONFIG); memset(szProto, 0, MAX_STR + 1); memset(szFN, 0, MAX_STR + 1); memset(szSID, 0, MAX_SID + 1); rad_create_request(rh, RAD_ACCOUNTING_REQUEST); rad_put_int(rh, RAD_ACCT_STATUS_TYPE, RAD_STOP); rad_put_string(rh, RAD_USER_NAME, user); rad_put_int(rh, RAD_SERVICE_TYPE, SERV_TYPE); rad_put_int(rh, RAD_ACCT_TERMINATE_CAUSE, RAD_TERM_USER_REQUEST); sscanf(appdata, "%[^/]", szProto); if (!strncmp(szProto, PROTO_SIP, strlen(PROTO_SIP))) nProto = RAD_SIP; if (!strncmp(szProto, PROTO_H323, strlen(PROTO_H323))) nProto = RAD_H323; if (!strncmp(szProto, PROTO_IAX2, strlen(PROTO_IAX2))) nProto = RAD_IAX2; rad_put_int(rh, RAD_FRAMED_PROTOCOL, nProto); rad_put_int(rh, RAD_NAS_PORT_TYPE, RAD_VOIP); rad_put_string(rh, RAD_NAS_IDENTIFIER, NAS_IDENT); rad_put_string(rh, RAD_CALLING_STATION_ID, szProto); rad_put_string(rh, RAD_CALLED_STATION_ID, app); sprintf(szFN, "%s/%s.sid", TMP, user); if (!access(szFN, R_OK | W_OK)) { f = fopen(szFN, "r"); fgets(szSID, MAX_SID, f); fclose(f); } remove(szFN); rad_put_string(rh, RAD_ACCT_SESSION_ID, szSID); rad_put_int(rh, RAD_ACCT_SESSION_TIME, billtime); rad_put_int(rh, RAD_ACCT_DELAY_TIME, alltime); rad_put_int(rh, RAD_NAS_PORT, 0); ast_log(LOG_DEBUG,"cdr_radius: sending a CDR record.\n"); res = rad_send_request(rh); rad_close(rh); return res == RAD_ACCOUNTING_RESPONSE; } static int radius_log(struct ast_cdr* cdr) { char szCmd[MAX_STR + 1]; memset(szCmd, 0, MAX_STR + 1); // Stoped error and other non-billing records ... if (!strlen(cdr->accountcode)) { // If you want to catch any of this errors - insert your code down ;) if (!strncmp(cdr->lastdata, csPickup, strlen(csPickup))) return 0; if (!strncmp(cdr->lastdata, csMaskRad, strlen(csMaskRad))) return 0; if (!strncmp(cdr->lastdata, csMaskCall, strlen(csMaskCall))) return 0; if (!strncmp(cdr->lastdata, csMaskErr, strlen(csMaskErr))) return 0; return 0; } radius_stop(cdr->accountcode, cdr->lastapp, cdr->lastdata, cdr->billsec, cdr->duration, cdr->channel); // Clear sessionID file :-P sprintf(szCmd, "%s/%s.sid", TMP, cdr->accountcode); remove(szCmd); return 0; } // ----------------------- char *description(void) { return desc; } int unload_module(void) { ast_cdr_unregister(name); return 0; } int load_module(void) { int res; res = ast_cdr_register(name, desc, radius_log); if (res) ast_log(LOG_ERROR, "Unable to register RADIUS CDR handling\n"); return res; } int reload(void) { return 0; } int usecount(void) { return 0; } char *key() { return ASTERISK_GPL_KEY; }