From 797d633139a52a87736c04b71e31b1cb66e21e08 Mon Sep 17 00:00:00 2001 From: Richard Mudgett Date: Wed, 1 Feb 2012 17:42:15 +0000 Subject: Remove inconsistency in CEL eventtype for user defined events. The CEL eventtype field for ODBC and PGSQL backends should be USER_DEFINED instead of the user defined event name supplied by the CELGenUserEvent application. If the field is output as a number, the user defined name does not have a value and is always output as 21 for USER_DEFINED and the userdeftype field would be required to supply the user defined name. The following CEL backends (cel_odbc, cel_pgsql, cel_custom, cel_manager, and cel_sqlite3_custom) can be independently configured to remove this inconsistency. * Allows cel_manager, cel_custom, and cel_sqlite3_custom to behave the same way. (closes issue ASTERISK-17189) Reported by: Bryant Zimmerman Review: https://reviewboard.asterisk.org/r/1669/ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@353648 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- cel/cel_manager.c | 34 +++++++++++++++++++++++++++++++--- cel/cel_odbc.c | 26 +++++++++++++++++++++++++- cel/cel_pgsql.c | 33 +++++++++++++++++++++++++-------- cel/cel_tds.c | 12 +++++++----- configs/cel.conf.sample | 7 +++++++ configs/cel_custom.conf.sample | 1 + configs/cel_odbc.conf.sample | 9 ++++++++- configs/cel_pgsql.conf.sample | 5 +++++ configs/cel_sqlite3_custom.conf.sample | 1 + main/cel.c | 14 +++++++++----- 10 files changed, 119 insertions(+), 23 deletions(-) diff --git a/cel/cel_manager.c b/cel/cel_manager.c index 76ca48bbb..e1d0dc148 100644 --- a/cel/cel_manager.c +++ b/cel/cel_manager.c @@ -49,14 +49,25 @@ static const char DATE_FORMAT[] = "%Y-%m-%d %T"; static const char CONF_FILE[] = "cel.conf"; +/*! \brief AMI CEL is off by default */ +#define CEL_AMI_ENABLED_DEFAULT 0 + static int enablecel; +/*! \brief show_user_def is off by default */ +#define CEL_SHOW_USERDEF_DEFAULT 0 + +/*! TRUE if we should set the EventName header to USER_DEFINED on user events. */ +static unsigned char cel_show_user_def; + static struct ast_event_sub *event_sub; static void manager_log(const struct ast_event *event, void *userdata) { struct ast_tm timeresult; char start_time[80] = ""; + char user_defined_header[160]; + const char *event_name; struct ast_cel_event_record record = { .version = AST_CEL_EVENT_RECORD_VERSION, }; @@ -72,6 +83,17 @@ static void manager_log(const struct ast_event *event, void *userdata) ast_localtime(&record.event_time, &timeresult, NULL); ast_strftime(start_time, sizeof(start_time), DATE_FORMAT, &timeresult); + event_name = record.event_name; + user_defined_header[0] = '\0'; + if (record.event_type == AST_CEL_USER_DEFINED) { + if (cel_show_user_def) { + snprintf(user_defined_header, sizeof(user_defined_header), + "UserDefType: %s\r\n", record.user_defined_name); + } else { + event_name = record.user_defined_name; + } + } + manager_event(EVENT_FLAG_CALL, "CEL", "EventName: %s\r\n" "AccountCode: %s\r\n" @@ -92,8 +114,9 @@ static void manager_log(const struct ast_event *event, void *userdata) "Userfield: %s\r\n" "Peer: %s\r\n" "PeerAccount: %s\r\n" + "%s" "Extra: %s\r\n", - record.event_name, + event_name, record.account_code, record.caller_id_num, record.caller_id_name, @@ -112,6 +135,7 @@ static void manager_log(const struct ast_event *event, void *userdata) record.user_field, record.peer, record.peer_account, + user_defined_header, record.extra); } @@ -121,7 +145,8 @@ static int load_config(int reload) struct ast_config *cfg; struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 }; struct ast_variable *v; - int newenablecel = 0; + int newenablecel = CEL_AMI_ENABLED_DEFAULT; + int new_cel_show_user_def = CEL_SHOW_USERDEF_DEFAULT; cfg = ast_config_load(CONF_FILE, config_flags); if (cfg == CONFIG_STATUS_FILEUNCHANGED) { @@ -141,7 +166,9 @@ static int load_config(int reload) for (v = ast_variable_browse(cfg, cat); v; v = v->next) { if (!strcasecmp(v->name, "enabled")) { - newenablecel = ast_true(v->value); + newenablecel = ast_true(v->value) ? 1 : 0; + } else if (!strcasecmp(v->name, "show_user_defined")) { + new_cel_show_user_def = ast_true(v->value) ? 1 : 0; } else { ast_log(LOG_NOTICE, "Unknown option '%s' specified " "for cel_manager.\n", v->name); @@ -151,6 +178,7 @@ static int load_config(int reload) ast_config_destroy(cfg); + cel_show_user_def = new_cel_show_user_def; if (enablecel && !newenablecel) { if (event_sub) { event_sub = ast_event_unsubscribe(event_sub); diff --git a/cel/cel_odbc.c b/cel/cel_odbc.c index 223cb18c9..1a5427169 100644 --- a/cel/cel_odbc.c +++ b/cel/cel_odbc.c @@ -53,6 +53,12 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #define CONFIG "cel_odbc.conf" static struct ast_event_sub *event_sub = NULL; +/*! \brief show_user_def is off by default */ +#define CEL_SHOW_USERDEF_DEFAULT 0 + +/*! TRUE if we should set the eventtype field to USER_DEFINED on user events. */ +static unsigned char cel_show_user_def; + /* Optimization to reduce number of memory allocations */ static int maxsize = 512, maxsize2 = 512; @@ -103,7 +109,20 @@ static int load_config(void) return -1; } + /* Process the general category */ + cel_show_user_def = CEL_SHOW_USERDEF_DEFAULT; + for (var = ast_variable_browse(cfg, "general"); var; var = var->next) { + if (!strcasecmp(var->name, "show_user_defined")) { + cel_show_user_def = ast_true(var->value) ? 1 : 0; + } else { + /* Unknown option name. */ + } + } + for (catg = ast_category_browse(cfg, NULL); catg; catg = ast_category_browse(cfg, catg)) { + if (!strcasecmp(catg, "general")) { + continue; + } var = ast_variable_browse(cfg, catg); if (!var) continue; @@ -476,7 +495,12 @@ static void odbc_log(const struct ast_event *event, void *userdata) * form (but only when we're dealing with a character-based field). */ if (strcasecmp(entry->name, "eventtype") == 0) { - snprintf(colbuf, sizeof(colbuf), "%s", record.event_name); + const char *event_name; + + event_name = (!cel_show_user_def + && record.event_type == AST_CEL_USER_DEFINED) + ? record.user_defined_name : record.event_name; + snprintf(colbuf, sizeof(colbuf), "%s", event_name); } /* Truncate too-long fields */ diff --git a/cel/cel_pgsql.c b/cel/cel_pgsql.c index 99374a824..f7676f88e 100644 --- a/cel/cel_pgsql.c +++ b/cel/cel_pgsql.c @@ -63,6 +63,12 @@ static char *pghostname = NULL, *pgdbname = NULL, *pgdbuser = NULL, *pgpassword static int connected = 0; static int maxsize = 512, maxsize2 = 512; +/*! \brief show_user_def is off by default */ +#define CEL_SHOW_USERDEF_DEFAULT 0 + +/*! TRUE if we should set the eventtype field to USER_DEFINED on user events. */ +static unsigned char cel_show_user_def; + AST_MUTEX_DEFINE_STATIC(pgsql_lock); static PGconn *conn = NULL; @@ -70,12 +76,12 @@ static PGresult *result = NULL; static struct ast_event_sub *event_sub = NULL; struct columns { - char *name; - char *type; - int len; - unsigned int notnull:1; - unsigned int hasdefault:1; - AST_RWLIST_ENTRY(columns) list; + char *name; + char *type; + int len; + unsigned int notnull:1; + unsigned int hasdefault:1; + AST_RWLIST_ENTRY(columns) list; }; static AST_RWLIST_HEAD_STATIC(psql_columns, columns); @@ -185,8 +191,13 @@ static void pgsql_log(const struct ast_event *event, void *userdata) ast_str_append(&sql2, 0, "%s%f", SEP, (double) record.event_type); } else { /* Char field, probably */ - LENGTHEN_BUF2(strlen(record.event_name) + 1); - ast_str_append(&sql2, 0, "%s'%s'", SEP, record.event_name); + const char *event_name; + + event_name = (!cel_show_user_def + && record.event_type == AST_CEL_USER_DEFINED) + ? record.user_defined_name : record.event_name; + LENGTHEN_BUF2(strlen(event_name) + 1); + ast_str_append(&sql2, 0, "%s'%s'", SEP, event_name); } } else if (strcmp(cur->name, "amaflags") == 0) { if (strncmp(cur->type, "int", 3) == 0) { @@ -449,6 +460,10 @@ static int process_my_load_module(struct ast_config *cfg) if (!(table = ast_strdup(tmp))) { return AST_MODULE_LOAD_DECLINE; } + cel_show_user_def = CEL_SHOW_USERDEF_DEFAULT; + if ((tmp = ast_variable_retrieve(cfg, "global", "show_user_defined"))) { + cel_show_user_def = ast_true(tmp) ? 1 : 0; + } if (option_debug) { if (ast_strlen_zero(pghostname)) { ast_debug(3, "cel_pgsql: using default unix socket\n"); @@ -460,6 +475,8 @@ static int process_my_load_module(struct ast_config *cfg) ast_debug(3, "cel_pgsql: got dbname of %s\n", pgdbname); ast_debug(3, "cel_pgsql: got password of %s\n", pgpassword); ast_debug(3, "cel_pgsql: got sql table name of %s\n", table); + ast_debug(3, "cel_pgsql: got show_user_defined of %s\n", + cel_show_user_def ? "Yes" : "No"); } conn = PQsetdbLogin(pghostname, pgdbport, NULL, NULL, pgdbname, pgdbuser, pgpassword); diff --git a/cel/cel_tds.c b/cel/cel_tds.c index f5686c9b0..df2b573bf 100644 --- a/cel/cel_tds.c +++ b/cel/cel_tds.c @@ -19,17 +19,17 @@ * \brief FreeTDS CEL logger * * See also - * \arg \ref Config_cdr + * \arg \ref Config_cel * \arg http://www.freetds.org/ - * \ingroup cdr_drivers + * \ingroup cel_drivers */ /*! \verbatim * - * Table Structure for `cdr` + * Table Structure for `cel` * -CREATE TABLE [dbo].[cdr] ( +CREATE TABLE [dbo].[cel] ( [accountcode] [varchar] (20) NULL , [cidname] [varchar] (80) NULL , [cidnum] [varchar] (80) NULL , @@ -204,7 +204,9 @@ retry: ")", settings->table, accountcode_ai, clidnum_ai, clid_ai, cidani_ai, cidrdnis_ai, ciddnid_ai, exten_ai, context_ai, channel_ai, app_ai, appdata_ai, start, - record.event_name, ast_cel_get_ama_flag_name(record.amaflag), uniqueid_ai, linkedid_ai, + (record.event_type == AST_CEL_USER_DEFINED) + ? record.user_defined_name : record.event_name, + ast_cel_get_ama_flag_name(record.amaflag), uniqueid_ai, linkedid_ai, userfield_ai, peer_ai); if (erc == FAIL) { diff --git a/configs/cel.conf.sample b/configs/cel.conf.sample index a17cf6881..7bd7f89f0 100644 --- a/configs/cel.conf.sample +++ b/configs/cel.conf.sample @@ -105,6 +105,13 @@ events=APP_START,CHAN_START,CHAN_END,ANSWER,HANGUP,BRIDGE_START,BRIDGE_END ; Default value: no ;enabled=yes +; Use 'show_user_defined' to put "USER_DEFINED" in the EventName header, +; instead of (by default) just putting the user defined event name there. +; When enabled the UserDefType header is added for user defined events to +; provide the user defined event name. +; +;show_user_defined=yes + ; ; RADIUS CEL Backend ; diff --git a/configs/cel_custom.conf.sample b/configs/cel_custom.conf.sample index 59c33dc54..126248aca 100644 --- a/configs/cel_custom.conf.sample +++ b/configs/cel_custom.conf.sample @@ -24,6 +24,7 @@ ; ; eventtype - The name of the CEL event. ; eventtime - The timestamp of the CEL event. +; eventenum - Like eventtype but is "USER_DEFINED" for a user defined event. ; userdeftype - User defined event type name from CELGenUserEvent(). ; eventextra - Extra data included with this CEL event, typically along with ; an event of type USER_DEFINED from CELGenUserEvent(). diff --git a/configs/cel_odbc.conf.sample b/configs/cel_odbc.conf.sample index 640de4fb6..1c7ff5095 100644 --- a/configs/cel_odbc.conf.sample +++ b/configs/cel_odbc.conf.sample @@ -2,6 +2,13 @@ ; Asterisk Channel Event Logging (CEL) - Adaptive ODBC Backend ; +; General module options category. +[general] +; Use 'show_user_defined' to put "USER_DEFINED" in the eventtype field, +; instead of (by default) just putting the user defined event name there. +; +;show_user_defined=yes + ; This configuration defines the connections and tables for which CEL records ; may be populated. Each context specifies a different CEL table to be used. ; @@ -90,7 +97,7 @@ ;alias dst => dest ;alias dstchannel => dest_channel -; Any filter specified MUST match exactly or the CE will be discarded +; Any filter specified MUST match exactly or the event will be discarded ;filter accountcode => somename ;filter src => 123 diff --git a/configs/cel_pgsql.conf.sample b/configs/cel_pgsql.conf.sample index d71fcc6be..cc9b9ff91 100644 --- a/configs/cel_pgsql.conf.sample +++ b/configs/cel_pgsql.conf.sample @@ -54,6 +54,11 @@ ; extra [global] +; Use 'show_user_defined' to put "USER_DEFINED" in the eventtype field, +; instead of (by default) just putting the user defined event name there. +; +;show_user_defined=yes + ;hostname=localhost ;port=5432 ;dbname=asterisk diff --git a/configs/cel_sqlite3_custom.conf.sample b/configs/cel_sqlite3_custom.conf.sample index 14f2dd228..2d9a24fc7 100644 --- a/configs/cel_sqlite3_custom.conf.sample +++ b/configs/cel_sqlite3_custom.conf.sample @@ -11,6 +11,7 @@ ; ; eventtype - The name of the CEL event. ; eventtime - The timestamp of the CEL event. +; eventenum - Like eventtype but is "USER_DEFINED" for a user defined event. ; userdeftype - User defined event type name from CELGenUserEvent(). ; eventextra - Extra data included with this CEL event, typically along with ; an event of type USER_DEFINED from CELGenUserEvent(). diff --git a/main/cel.c b/main/cel.c index 6e8215f20..f7e28f0ef 100644 --- a/main/cel.c +++ b/main/cel.c @@ -402,6 +402,7 @@ struct ast_channel *ast_cel_fabricate_channel_from_event(const struct ast_event { struct varshead *headp; struct ast_var_t *newvariable; + const char *mixed_name; char timebuf[30]; struct ast_channel *tchan; struct ast_cel_event_record record = { @@ -422,7 +423,9 @@ struct ast_channel *ast_cel_fabricate_channel_from_event(const struct ast_event } /* next, fill the channel with their data */ - if ((newvariable = ast_var_assign("eventtype", record.event_name))) { + mixed_name = (record.event_type == AST_CEL_USER_DEFINED) + ? record.user_defined_name : record.event_name; + if ((newvariable = ast_var_assign("eventtype", mixed_name))) { AST_LIST_INSERT_HEAD(headp, newvariable, entries); } @@ -439,6 +442,9 @@ struct ast_channel *ast_cel_fabricate_channel_from_event(const struct ast_event AST_LIST_INSERT_HEAD(headp, newvariable, entries); } + if ((newvariable = ast_var_assign("eventenum", record.event_name))) { + AST_LIST_INSERT_HEAD(headp, newvariable, entries); + } if ((newvariable = ast_var_assign("userdeftype", record.user_defined_name))) { AST_LIST_INSERT_HEAD(headp, newvariable, entries); } @@ -598,13 +604,11 @@ int ast_cel_fill_record(const struct ast_event *e, struct ast_cel_event_record * r->event_time.tv_sec = ast_event_get_ie_uint(e, AST_EVENT_IE_CEL_EVENT_TIME); r->event_time.tv_usec = ast_event_get_ie_uint(e, AST_EVENT_IE_CEL_EVENT_TIME_USEC); - r->user_defined_name = ""; - + r->event_name = ast_cel_get_type_name(r->event_type); if (r->event_type == AST_CEL_USER_DEFINED) { r->user_defined_name = ast_event_get_ie_str(e, AST_EVENT_IE_CEL_USEREVENT_NAME); - r->event_name = r->user_defined_name; } else { - r->event_name = ast_cel_get_type_name(r->event_type); + r->user_defined_name = ""; } r->caller_id_name = S_OR(ast_event_get_ie_str(e, AST_EVENT_IE_CEL_CIDNAME), ""); -- cgit v1.2.3