Skip to content

Commit

Permalink
acc_json: adding CDR as JSON functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
lbalaceanu committed Nov 13, 2019
1 parent e3fe8e7 commit 09f1c59
Show file tree
Hide file tree
Showing 3 changed files with 374 additions and 37 deletions.
226 changes: 202 additions & 24 deletions src/modules/acc_json/acc_json_mod.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,22 +43,36 @@ static int child_init(int rank);

int acc_json_init(acc_init_info_t *inf);
int acc_json_send_request(struct sip_msg *req, acc_info_t *inf);
int cdr_json_init(void);
int cdr_json_write(struct dlg_cell *dlg, struct sip_msg *req, cdr_info_t *inf);

// acc API
acc_api_t accb;
acc_engine_t _acc_json_engine;
cdr_engine_t _cdr_json_engine;
// mqueue API
mq_api_t mq_api;
// dlg API
struct dlg_binds dlgb;

int acc_flag = -1;
int acc_missed_flag = -1;
int acc_time_mode = 0;
static char *acc_extra_str = 0;
acc_extra_t *acc_extra = 0;
int output_syslog = -1;
char *output_mqueue_str = 0; /* see mqueue module queue name */
str q_name = {0, 0};
static char *log_facility_str = 0;
int acc_output_syslog = -1;
char *acc_output_mqueue_str = 0; /* see mqueue module queue name */
str acc_q_name = {0, 0};
static char *acc_log_facility_str = 0;

int cdr_enable = 0;
static char *cdr_extra_str = 0;
acc_extra_t *cdr_extra = 0;
int cdr_expired_dlg_enable = 0;
int cdr_output_syslog = -1;
char *cdr_output_mqueue_str = 0; /* see mqueue module queue name */
str cdr_q_name = {0, 0};
static char *cdr_log_facility_str = 0;

static cmd_export_t cmds[] = {{0, 0, 0, 0, 0, 0}};

Expand All @@ -68,10 +82,17 @@ static param_export_t params[] = {{"acc_flag", INT_PARAM, &acc_flag},
{"acc_extra", PARAM_STRING, &acc_extra_str},
{"acc_time_mode", INT_PARAM, &acc_time_mode},
{"acc_time_format", PARAM_STRING, &acc_time_format},
{"log_level", INT_PARAM, &log_level},
{"log_facility", PARAM_STRING, &log_facility_str},
{"output_mqueue", PARAM_STRING, &output_mqueue_str},
{"output_syslog", INT_PARAM, &output_syslog}, {0, 0, 0}};
{"acc_log_level", INT_PARAM, &acc_log_level},
{"acc_log_facility", PARAM_STRING, &acc_log_facility_str},
{"acc_output_mqueue", PARAM_STRING, &acc_output_mqueue_str},
{"acc_output_syslog", INT_PARAM, &acc_output_syslog},
{"cdr_extra", PARAM_STRING, &cdr_extra_str},
{"cdr_enable", INT_PARAM, &cdr_enable},
{"cdr_expired_dlg_enable", INT_PARAM, &cdr_expired_dlg_enable},
{"cdr_log_level", INT_PARAM, &cdr_log_level},
{"cdr_log_facility", PARAM_STRING, &cdr_log_facility_str},
{"cdr_output_mqueue", PARAM_STRING, &cdr_output_mqueue_str},
{"cdr_output_syslog", INT_PARAM, &cdr_output_syslog}, {0, 0, 0}};


struct module_exports exports = {
Expand All @@ -96,31 +117,53 @@ static int mod_init(void)
return -1;
}

if( cdr_enable < 0 || cdr_enable > 1) {
LM_ERR("cdr_enable is out of range\n");
return -1;
}
if( cdr_expired_dlg_enable < 0 || cdr_expired_dlg_enable > 1) {
LM_ERR("cdr_expired_dlg_enable is out of range\n");
return -1;
}

LM_INFO("janson version : %s\n", JANSSON_VERSION);
#if JANSSON_VERSION_HEX >= 0x010300
/* Code specific to version 1.3 and above */
#endif

if(log_facility_str) {
int tmp = str2facility(log_facility_str);
if(acc_log_facility_str) {
int tmp = str2facility(acc_log_facility_str);
if(tmp != -1)
log_facility = tmp;
acc_log_facility = tmp;
else {
LM_ERR("invalid log facility configured");
return -1;
}
}

if (cdr_log_facility_str) {
int tmp = str2facility(cdr_log_facility_str);
if (tmp != -1)
cdr_log_facility = tmp;
else {
LM_ERR("invalid log facility configured");
return -1;
}
}

/* load the MQUEUE API */
if(output_mqueue_str && (load_mq_api(&mq_api) != 0)) {
if((acc_output_mqueue_str || cdr_output_mqueue_str) && (load_mq_api(&mq_api) != 0)) {
LM_ERR("can't load mqueue module API, disabling json acc to mqueue\n");
output_mqueue_str = NULL;
acc_output_mqueue_str = NULL;
}
if(output_mqueue_str) {
q_name.s = output_mqueue_str;
q_name.len = strlen(output_mqueue_str);
if(acc_output_mqueue_str) {
acc_q_name.s = acc_output_mqueue_str;
acc_q_name.len = strlen(acc_output_mqueue_str);
}
if(cdr_output_mqueue_str) {
cdr_q_name.s = cdr_output_mqueue_str;
cdr_q_name.len = strlen(cdr_output_mqueue_str);
}

/* parse the extra string, if any */
if(acc_extra_str && (acc_extra = accb.parse_extra(acc_extra_str)) == 0) {
LM_ERR("failed to parse acc_extra param\n");
Expand All @@ -141,6 +184,29 @@ static int mod_init(void)
return -1;
}

if (cdr_enable) {
if(load_dlg_api( &dlgb) != 0) {
LM_ERR("can't load dialog API\n");
return -1;
}
/* parse the extra string, if any */
if(cdr_extra_str && (cdr_extra = accb.parse_extra(cdr_extra_str)) == 0) {
LM_ERR("failed to parse cdr_extra param\n");
return -1;
}
memset(&_cdr_json_engine, 0, sizeof(cdr_engine_t));

_cdr_json_engine.cdr_write = cdr_json_write;
_cdr_json_engine.cdr_init = cdr_json_init;
memcpy(_cdr_json_engine.name, "json", 4);

if (!accb.register_cdr_engine
|| (accb.register_cdr_engine
&& (accb.register_cdr_engine(&_cdr_json_engine) < 0))) {
LM_ERR("cannot register ACC CDR JSON engine\n");
return -1;
}
}
return 0;
}

Expand All @@ -166,11 +232,20 @@ int acc_json_init(acc_init_info_t *inf)
}


void syslog_write(const char *acc)
void acc_syslog_write(const char *acc)
{
//setlogmask(LOG_UPTO (LOG_NOTICE));
openlog("json_acc", LOG_CONS | LOG_PID | LOG_NDELAY, log_facility);
syslog(log_level, "%s", acc);
openlog("json_acc", LOG_CONS | LOG_PID | LOG_NDELAY, acc_log_facility);
syslog(acc_log_level, "%s", acc);
closelog();
}


void cdr_syslog_write(const char *cdr)
{
//setlogmask(LOG_UPTO (LOG_NOTICE));
openlog("json_acc", LOG_CONS | LOG_PID | LOG_NDELAY, cdr_log_facility);
syslog(cdr_log_level, "%s", cdr);
closelog();
}

Expand Down Expand Up @@ -279,18 +354,18 @@ int acc_json_send_request(struct sip_msg *req, acc_info_t *inf)
str acc_str = {json_string, strlen(json_string)};

// json acc output to mqueue
if(output_mqueue_str) {
if(acc_output_mqueue_str) {
str key = str_init("acc");
if(mq_api.add(&q_name, &key, &acc_str)) {
if(mq_api.add(&acc_q_name, &key, &acc_str)) {
LM_DBG("ACC queued [%d][%s]\n", acc_str.len, acc_str.s);
} else {
LM_DBG("ACC mqueue add error [%d][%s]\n", acc_str.len,
acc_str.s);
}
}
// json acc output to syslog
if(output_syslog)
syslog_write(json_string);
if(acc_output_syslog)
acc_syslog_write(json_string);
free(json_string);
json_object_clear(object);
json_decref(object);
Expand All @@ -299,3 +374,106 @@ int acc_json_send_request(struct sip_msg *req, acc_info_t *inf)
free_strar_mem(&(inf->tarr[m - o]), &(inf->varr[m - o]), o, m);
return 1;
}


int cdr_json_init(void)
{
LM_DBG(" init ...\n");
return 0;
}


int cdr_json_write(struct dlg_cell *dlg, struct sip_msg *req, cdr_info_t *inf)
{
int attr_cnt = 0;
int i;
int extra_cnt = 0;
int core_cnt = 0;

json_t *object = json_object();

/* get default values */
core_cnt = accb.get_core_cdr_attrs( dlg, inf->varr, inf->iarr, inf->tarr);
attr_cnt += core_cnt;

for(i = 0; i < attr_cnt; i++) {
LM_DBG("[%d][%.*s]\n", i, inf->varr[i].len, inf->varr[i].s);
char *tmp = strndup(inf->varr[i].s, inf->varr[i].len);
json_t *value = json_string(tmp);
if(!value)
value = json_string("NON-UTF8");
if(i == 0) {
json_object_set_new(object, cdr_start_str.s, value);
} else if(i == 1) {
json_object_set_new(object, cdr_end_str.s, value);
} else if(i == 2) {
json_object_set_new(object, cdr_duration_str.s, value);
}
free(tmp);
}

/* get extra values */
if (req)
{
/* free memory allocated by get_extra_attrs */
extra_cnt += accb.get_extra_attrs( cdr_extra,
req,
inf->varr + attr_cnt,
inf->iarr + attr_cnt,
inf->tarr + attr_cnt);
attr_cnt += extra_cnt;
} else if (cdr_expired_dlg_enable){
int dlg_index = 0;
dlg_index += accb.get_extra_dlg_attrs( cdr_extra,
dlg,
inf->varr + attr_cnt,
inf->iarr + attr_cnt,
inf->tarr + attr_cnt,
&dlgb);
attr_cnt += dlg_index;
}

struct acc_extra *extra = cdr_extra;
for( ; i < attr_cnt; i++)
{
LM_DBG("[%d][%s][%.*s]\n", i, extra->name.s, inf->varr[i].len,
inf->varr[i].s);
char *tmp = strndup(inf->varr[i].s, inf->varr[i].len);
json_t *value = json_string(tmp);
if(!value)
value = json_string("NON-UTF8");
json_object_set_new(object, extra->name.s, value);
free(tmp);
extra = extra->next;
}

if(object) {
if(json_object_size(object) == 0) {
LM_ERR("json object empty\n");
json_decref(object);
return 0;
}
char *json_string = json_dumps(object, JSON_ENSURE_ASCII);
str cdr_str = {json_string, strlen(json_string)};

// json acc output to mqueue
if (cdr_output_mqueue_str) {
str key = str_init("cdr");
if (mq_api.add(&cdr_q_name, &key, &cdr_str)) {
LM_DBG("CDR queued [%d][%s]\n", cdr_str.len, cdr_str.s);
} else {
LM_DBG("CDR mqueue add error [%d][%s]\n", cdr_str.len,
cdr_str.s);
}
}
// json acc output to syslog
if(cdr_output_syslog)
cdr_syslog_write(json_string);
free(json_string);
json_object_clear(object);
json_decref(object);
}
/* free memory allocated by get_extra_attrs */
free_strar_mem(&(inf->tarr[core_cnt]), &(inf->varr[core_cnt]), extra_cnt, attr_cnt);
return 1;
}
10 changes: 8 additions & 2 deletions src/modules/acc_json/acc_json_mod.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,17 @@ str acc_sipcode_key = str_init("sip_code");
str acc_sipreason_key = str_init("sip_reason");
str acc_time_key = str_init("time");

str cdr_start_str = str_init("start_time");
str cdr_end_str = str_init("end_time");
str cdr_duration_str = str_init("duration");

#define ACC_TIME_FORMAT_SIZE 128
static char acc_time_format_buf[ACC_TIME_FORMAT_SIZE];
char *acc_time_format = "%Y-%m-%d %H:%M:%S";

int log_level = L_NOTICE;
int log_facility = LOG_DAEMON;
int acc_log_level = L_NOTICE;
int acc_log_facility = LOG_DAEMON;
int cdr_log_level = L_NOTICE;
int cdr_log_facility = LOG_DAEMON;

#endif

0 comments on commit 09f1c59

Please sign in to comment.