diff --git a/CHANGES b/CHANGES index 0a4f80922..a99de3aed 100644 --- a/CHANGES +++ b/CHANGES @@ -27,6 +27,11 @@ CLI Changes * The 'logger reload' command now supports an optional argument, specifying an alternate configuration file to use. +CDR +--- + * The filter option in cdr_adaptive_odbc now supports negating the argument, + thus allowing records which do NOT match the specified filter. + ------------------------------------------------------------------------------ --- Functionality changes from Asterisk 1.6.2 to Asterisk 1.8 ---------------- ------------------------------------------------------------------------------ diff --git a/cdr/cdr_adaptive_odbc.c b/cdr/cdr_adaptive_odbc.c index f0b0e99bf..db19896f2 100644 --- a/cdr/cdr_adaptive_odbc.c +++ b/cdr/cdr_adaptive_odbc.c @@ -65,6 +65,7 @@ struct columns { SQLSMALLINT nullable; SQLINTEGER octetlen; AST_LIST_ENTRY(columns) list; + unsigned int negatefiltervalue:1; }; struct tables { @@ -163,9 +164,16 @@ static int load_config(void) /* Check for filters first */ for (var = ast_variable_browse(cfg, catg); var; var = var->next) { if (strncmp(var->name, "filter", 6) == 0) { + int negate = 0; char *cdrvar = ast_strdupa(var->name + 6); cdrvar = ast_strip(cdrvar); - ast_verb(3, "Found filter %s for cdr variable %s in %s@%s\n", var->value, cdrvar, tableptr->table, tableptr->connection); + if (cdrvar[strlen(cdrvar) - 1] == '!') { + negate = 1; + cdrvar[strlen(cdrvar) - 1] = '\0'; + ast_trim_blanks(cdrvar); + } + + ast_verb(3, "Found filter %s'%s' for cdr variable %s in %s@%s\n", negate ? "!" : "", var->value, cdrvar, tableptr->table, tableptr->connection); entry = ast_calloc(sizeof(char), sizeof(*entry) + strlen(cdrvar) + 1 + strlen(var->value) + 1); if (!entry) { @@ -180,6 +188,7 @@ static int load_config(void) entry->filtervalue = (char *)entry + sizeof(*entry) + strlen(cdrvar) + 1; strcpy(entry->cdrname, cdrvar); strcpy(entry->filtervalue, var->value); + entry->negatefiltervalue = negate; AST_LIST_INSERT_TAIL(&(tableptr->columns), entry, list); } @@ -403,10 +412,11 @@ static int odbc_log(struct ast_cdr *cdr) * is very specifically NOT ast_strlen_zero(), because the filter * could legitimately specify that the field is blank, which is * different from the field being unspecified (NULL). */ - if (entry->filtervalue && strcasecmp(colptr, entry->filtervalue) != 0) { + if ((entry->filtervalue && !entry->negatefiltervalue && strcasecmp(colptr, entry->filtervalue) != 0) || + (entry->filtervalue && entry->negatefiltervalue && strcasecmp(colptr, entry->filtervalue) == 0)) { ast_verb(4, "CDR column '%s' with value '%s' does not match filter of" - " '%s'. Cancelling this CDR.\n", - entry->cdrname, colptr, entry->filtervalue); + " %s'%s'. Cancelling this CDR.\n", + entry->cdrname, colptr, entry->negatefiltervalue ? "!" : "", entry->filtervalue); goto early_release; } diff --git a/configs/cdr_adaptive_odbc.conf.sample b/configs/cdr_adaptive_odbc.conf.sample index c43b9a17e..9b2725b93 100644 --- a/configs/cdr_adaptive_odbc.conf.sample +++ b/configs/cdr_adaptive_odbc.conf.sample @@ -37,6 +37,8 @@ ; Any filter specified MUST match exactly or the CDR will be discarded ;filter accountcode => somename ;filter src => 123 +; Negative filters are also now available +;filter src != 456 ; ; Additionally, we now support setting static values per column. Reason ; for this is to allow different sections to specify different values for