TT#3990 Undo stop-rec processing but use pbx/xfer

Revert logic to pick peer id from stop record. This needs a better
approach somehow.
Instead, add logic to always take -pbx_1 and -xfer_1 stop records
into account when searching for stop records, to fix duration of
CDRs on transfer and park/unpark (which is just a special case
of transfer).

Change-Id: Ia80add6d5cb762800c563889c0d95ee25ed74168
changes/66/8766/2
Andreas Granig 10 years ago
parent cf6ce37a4a
commit e00771b4fa

61
cdr.c

@ -40,7 +40,7 @@ static const char* cdr_map_status(const char *sip_status)
int cdr_process_records(med_entry_t *records, u_int64_t count, u_int64_t *ext_count, struct medmysql_batches *batches)
{
int ret;
int ret = 0;
u_int8_t trash = 0;
u_int64_t i;
@ -50,7 +50,6 @@ int cdr_process_records(med_entry_t *records, u_int64_t count, u_int64_t *ext_co
u_int16_t invite_200 = 0;
char *callid = records[0].callid;
int cid_len;
cdr_entry_t *cdrs;
@ -61,37 +60,19 @@ int cdr_process_records(med_entry_t *records, u_int64_t count, u_int64_t *ext_co
for(i = 0; i < count; ++i)
{
med_entry_t *e = &(records[i]);
if (config_pbx_stop_records) {
cid_len = strlen(e->callid);
if (cid_len >= PBX_SUFFIX_LEN
&& strcmp(e->callid + cid_len - PBX_SUFFIX_LEN, PBX_SUFFIX) == 0)
{
e->is_pbx = 1;
e->callid[cid_len - PBX_SUFFIX_LEN] = '\0'; /* truncate in place */
e->valid = 0;
}
}
/* For pbx records, we ignore everything other than bye records. For regular records,
* we ignore only the stop record. */
if(strcmp(e->sip_method, MSG_INVITE) == 0)
{
++msg_invites;
e->method = MED_INVITE;
if (!e->is_pbx && e->valid) {
++msg_invites;
if(strncmp("200", e->sip_code, 3) == 0)
{
++invite_200;
}
if(strncmp("200", e->sip_code, 3) == 0)
{
++invite_200;
}
}
else if(strcmp(e->sip_method, MSG_BYE) == 0)
{
++msg_byes;
e->method = MED_BYE;
if (!e->is_pbx && e->valid)
++msg_byes;
}
else
{
@ -117,14 +98,7 @@ int cdr_process_records(med_entry_t *records, u_int64_t count, u_int64_t *ext_co
}
else
{
ret = cdr_create_cdrs(records, count, &cdrs, &cdr_count, &trash);
if (ret == 1) {
// insufficient data - don't trash and wait
return 0;
}
if(ret != 0)
if(cdr_create_cdrs(records, count, &cdrs, &cdr_count, &trash) != 0)
goto error;
else
{
@ -172,7 +146,7 @@ int cdr_process_records(med_entry_t *records, u_int64_t count, u_int64_t *ext_co
if(medmysql_trash_entries(callid, batches) != 0)
goto error;
}
return 0;
return ret;
error:
@ -377,7 +351,6 @@ static int cdr_parse_srcleg(char *srcleg, cdr_entry_t *cdr)
g_strlcpy(cdr->source_gpp[i], tmp2, sizeof(cdr->source_gpp[i]));
tmp2 = ++tmp1;
}
tmp1 = strchr(tmp2, MED_SEP);
if(tmp1 == NULL)
{
@ -547,7 +520,6 @@ static int cdr_create_cdrs(med_entry_t *records, u_int64_t count,
char *endtime = NULL;
double unix_endtime = 0, tmp_unix_endtime = 0;
const char *call_status;
med_entry_t *pbx_record = NULL;
*cdr_count = 0;
@ -560,8 +532,6 @@ static int cdr_create_cdrs(med_entry_t *records, u_int64_t count,
{
++invites;
}
else if (e->is_pbx)
pbx_record = e;
else if(e->method == MED_BYE && endtime == NULL)
{
endtime = e->timestamp;
@ -639,15 +609,6 @@ static int cdr_create_cdrs(med_entry_t *records, u_int64_t count,
*trash = 1;
return 0;
}
if (config_pbx_stop_records && !strcmp(cdr->destination_user_id, "0")) {
if (!pbx_record) {
// insufficient data - wait
free(*cdrs);
return 1;
}
cdr->destination_lcr_id = atoll(pbx_record->dst_leg);
}
if(cdr_fill_record(cdr) != 0)
{
@ -722,12 +683,6 @@ void cdr_set_provider(cdr_entry_t *cdr)
else if (cdr->destination_lcr_id) {
snprintf(cdr->destination_provider_id, sizeof(cdr->destination_provider_id),
"%llu", (unsigned long long) cdr->destination_lcr_id);
if (config_pbx_stop_records) {
// lcr_id determines the destination peer host name
val = g_hash_table_lookup(med_peer_id_hostname_table, cdr->destination_provider_id);
if (val)
g_strlcpy(cdr->destination_domain, val, sizeof(cdr->destination_domain));
}
val = g_hash_table_lookup(med_peer_id_table, cdr->destination_provider_id);
g_strlcpy(cdr->destination_provider_id, val ? : "0", sizeof(cdr->destination_provider_id));
}

@ -7,7 +7,6 @@ unsigned int config_interval = MEDIATOR_DEFAULT_INTERVAL;
u_int8_t config_dumpcdr = MEDIATOR_DEFAULT_DUMPCDR;
u_int8_t config_daemonize = MEDIATOR_DEFAULT_DAEMONIZE;
char *config_pid_path = MEDIATOR_DEFAULT_PIDPATH;
int config_pbx_stop_records;
char *config_med_host = MEDIATOR_DEFAULT_ACCHOST;
char *config_med_user = MEDIATOR_DEFAULT_ACCUSER;
@ -64,7 +63,6 @@ static void config_help(const char *self)
" -d\tEnables daemonization of the process (default = disabled).\n" \
" -l\tEnables dumping of CDRs to syslog (default = disabled).\n" \
" -i\tThe creation interval (default = %d).\n" \
" -s\tExpect additional stop records (default = disabled).\n" \
" -h\tThe ACC db host (default = '%s').\n" \
" -o\tThe ACC db port (default = '%d').\n" \
" -u\tThe ACC db user (default = '%s').\n" \
@ -99,7 +97,7 @@ int config_parse_cmdopts(int argc, char **argv)
{
int c;
while((c = getopt(argc, argv, "D:i:dl?sh:u:p:b:o:H:U:P:B:O:S:T:R:A:N:Z:z:W:w:X:x:")) != -1)
while((c = getopt(argc, argv, "D:i:dl?h:u:p:b:o:H:U:P:B:O:S:T:R:A:N:Z:z:W:w:X:x:")) != -1)
{
if(c == '?')
{
@ -114,9 +112,6 @@ int config_parse_cmdopts(int argc, char **argv)
{
config_dumpcdr = 1;
}
else if (c == 's')
config_pbx_stop_records = 1;
else if(c == 'D')
{
config_pid_path = (char*)strdup(optarg);

@ -7,7 +7,6 @@
extern u_int8_t config_daemonize;
extern char *config_pid_path;
extern char *config_hostname;
extern int config_pbx_stop_records;
extern char *config_med_host;
extern unsigned int config_med_port;

@ -23,4 +23,3 @@ STATS_USER="mediator"
STATS_PASS='GimmeAllUr$$$'
STATS_DB="stats"
STATS_PERIOD=1
PEER_PBX_STOP_RECORDS=0

@ -65,7 +65,6 @@ OPTIONS=""
[ -z "$STATS_PASS" ] || OPTIONS="$OPTIONS -w $STATS_PASS"
[ -z "$STATS_DB" ] || OPTIONS="$OPTIONS -X $STATS_DB"
[ -z "$STATS_PERIOD" ] || OPTIONS="$OPTIONS -x $STATS_PERIOD"
[ "$PEER_PBX_STOP_RECORDS" = "0" ] || OPTIONS="$OPTIONS -s"
if test "$FORK" = "yes" ; then
OPTIONS="$OPTIONS -d"
fi

@ -26,8 +26,6 @@ GHashTable *med_peer_host_table = NULL;
GHashTable *med_peer_id_table = NULL;
GHashTable *med_uuid_table = NULL;
GHashTable *med_call_stat_info_table = NULL;
GHashTable *med_peer_id_host_table = NULL;
GHashTable *med_peer_id_hostname_table = NULL;
/**********************************************************************/
static int mediator_load_maps()
@ -36,10 +34,8 @@ static int mediator_load_maps()
med_peer_host_table = g_hash_table_new_full(g_str_hash, g_str_equal, free, free);
med_peer_id_table = g_hash_table_new_full(g_str_hash, g_str_equal, free, free);
med_uuid_table = g_hash_table_new_full(g_str_hash, g_str_equal, free, free);
med_peer_id_host_table = g_hash_table_new_full(g_str_hash, g_str_equal, free, free);
med_peer_id_hostname_table = g_hash_table_new_full(g_str_hash, g_str_equal, free, free);
if(medmysql_load_maps())
if(medmysql_load_maps(med_peer_ip_table, med_peer_host_table, med_peer_id_table))
return -1;
if(medmysql_load_uuids(med_uuid_table))
return -1;

@ -53,16 +53,13 @@
#define MED_SEP '|'
#define PBX_SUFFIX "_pbx-1"
#define PBX_SUFFIX_LEN strlen(PBX_SUFFIX)
extern int mediator_lockfd;
extern sig_atomic_t mediator_shutdown;
typedef enum {
MED_INVITE = 1,
MED_BYE = 2,
MED_UNRECOGNIZED = 3,
MED_UNRECOGNIZED = 3
} med_method_t;
@ -77,7 +74,6 @@ typedef struct {
u_int8_t valid;
med_method_t method;
char sip_method[32];
int is_pbx;
} med_entry_t;
typedef struct {
@ -89,8 +85,6 @@ extern GHashTable *med_peer_ip_table;
extern GHashTable *med_peer_id_table;
extern GHashTable *med_uuid_table;
extern GHashTable *med_call_stat_info_table;
extern GHashTable *med_peer_id_host_table;
extern GHashTable *med_peer_id_hostname_table;
void critical(const char *);

@ -6,17 +6,45 @@
#include "medmysql.h"
#include "config.h"
/*#define MED_CALLID_QUERY "(select a.callid, a.time from acc a, acc b where a.callid = b.callid and a.method = 'INVITE' and b.method = 'BYE' group by callid) union (select callid, time from acc where method = 'INVITE' and sip_code != '200') order by time asc limit 0,200000"*/
#define MED_CALLID_QUERY "select a.callid from acc a left join acc b on a.callid = b.callid and b.method = 'BYE' where a.method = 'INVITE' and (a.sip_code != '200' or b.id is not null) group by a.callid limit 0,200000"
#define MED_FETCH_QUERY "select distinct sip_code, sip_reason, method, callid, time, time_hires, " \
#define PBXSUFFIX "_pbx-1"
#define XFERSUFFIX "_xfer-1"
#define MED_CALLID_QUERY "select a.callid from acc a" \
" where a.method = 'INVITE' " \
" and (a.sip_code != '200' " \
" OR EXISTS " \
" (select b.id from acc b " \
" where b.callid = a.callid " \
" and b.method = 'BYE' " \
" limit 1) " \
" OR EXISTS " \
" (select b.id from acc b " \
" where b.callid = concat(a.callid, '"PBXSUFFIX"') " \
" and b.method = 'BYE' " \
" limit 1) " \
" OR EXISTS " \
" (select b.id from acc b " \
" where b.callid = concat(a.callid, '"XFERSUFFIX"') " \
" and b.method = 'BYE' " \
" limit 1) " \
" ) " \
" group by a.callid limit 0,200000"
#define MED_FETCH_QUERY "(select distinct sip_code, sip_reason, method, callid, time, time_hires, " \
"src_leg, dst_leg " \
"from acc where method = 'INVITE' and callid = '%s' order by time_hires asc) " \
"union all " \
"(select distinct sip_code, sip_reason, method, callid, time, time_hires, " \
"src_leg, dst_leg " \
"from acc where callid = '%s' order by time_hires asc"
#define MED_FETCH_QUERY_PBX "select distinct sip_code, sip_reason, method, callid, time, time_hires, " \
"from acc where method = 'BYE' and callid in ('%s', '%s"PBXSUFFIX"') " \
"order by length(callid) asc, time_hires asc) " \
"union all " \
"(select distinct sip_code, sip_reason, method, callid, time, time_hires, " \
"src_leg, dst_leg " \
"from acc where callid = '%s' or callid = '%s"PBX_SUFFIX"' order by time_hires asc"
"from acc where method = 'BYE' and callid in ('%s', '%s"XFERSUFFIX"') " \
"order by length(callid) asc, time_hires asc)"
#define MED_LOAD_PEER_QUERY "select h.ip, h.host, g.peering_contract_id, h.id, h.name " \
#define MED_LOAD_PEER_QUERY "select h.ip, h.host, g.peering_contract_id, h.id " \
"from provisioning.voip_peer_hosts h, provisioning.voip_peer_groups g " \
"where g.id = h.group_id"
#define MED_LOAD_UUID_QUERY "select vs.uuid, r.contract_id from billing.voip_subscribers vs, " \
@ -226,10 +254,10 @@ int medmysql_fetch_records(med_callid_t *callid,
*count = 0;
if (!config_pbx_stop_records)
snprintf(query, sizeof(query), MED_FETCH_QUERY, callid->value);
else
snprintf(query, sizeof(query), MED_FETCH_QUERY_PBX, callid->value, callid->value);
snprintf(query, sizeof(query), MED_FETCH_QUERY,
callid->value,
callid->value, callid->value,
callid->value, callid->value);
/*syslog(LOG_DEBUG, "q='%s'", query);*/
@ -298,10 +326,6 @@ int medmysql_trash_entries(const char *callid, struct medmysql_batches *batches)
batches->acc_trash.len += sprintf(batches->acc_trash.str + batches->acc_trash.len, "'%s',", callid);
if (config_pbx_stop_records)
batches->acc_trash.len += sprintf(batches->acc_trash.str + batches->acc_trash.len,
"'%s"PBX_SUFFIX"',", callid);
return medmysql_delete_entries(callid, batches);
}
@ -318,10 +342,6 @@ int medmysql_backup_entries(const char *callid, struct medmysql_batches *batches
batches->acc_backup.len += sprintf(batches->acc_backup.str + batches->acc_backup.len, "'%s',", callid);
if (config_pbx_stop_records)
batches->acc_backup.len += sprintf(batches->acc_backup.str + batches->acc_backup.len,
"'%s"PBX_SUFFIX"',", callid);
return medmysql_delete_entries(callid, batches);
}
@ -343,10 +363,6 @@ int medmysql_delete_entries(const char *callid, struct medmysql_batches *batches
batches->to_delete.len += sprintf(batches->to_delete.str + batches->to_delete.len, "'%s',", callid);
if (config_pbx_stop_records)
batches->to_delete.len += sprintf(batches->to_delete.str + batches->to_delete.len,
"'%s"PBX_SUFFIX"',", callid);
return 0;
}
@ -383,7 +399,7 @@ int medmysql_insert_cdrs(cdr_entry_t *entries, u_int64_t count, struct medmysql_
"source_gpp5, source_gpp6, source_gpp7, source_gpp8, source_gpp9, " \
"destination_gpp0, destination_gpp1, destination_gpp2, destination_gpp3, destination_gpp4, " \
"destination_gpp5, destination_gpp6, destination_gpp7, destination_gpp8, destination_gpp9, " \
"source_lnp_prefix, destination_lnp_prefix" \
"source_lnp_prefix, destination_lnp_prefix" \
") values ");
}
@ -579,7 +595,7 @@ int medmysql_update_call_stat_info(const char *call_code, const double start_tim
}
/**********************************************************************/
int medmysql_load_maps()
int medmysql_load_maps(GHashTable *ip_table, GHashTable *host_table, GHashTable *id_table)
{
MYSQL_RES *res;
MYSQL_ROW row;
@ -607,30 +623,22 @@ int medmysql_load_maps()
goto out;
}
if(med_peer_ip_table != NULL)
if(ip_table != NULL)
{
if(g_hash_table_lookup(med_peer_ip_table, row[0]) != NULL)
if(g_hash_table_lookup(ip_table, row[0]) != NULL)
syslog(LOG_WARNING, "Skipping duplicate IP '%s'", row[0]);
else
g_hash_table_insert(med_peer_ip_table, strdup(row[0]), strdup(row[2]));
g_hash_table_insert(ip_table, strdup(row[0]), strdup(row[2]));
}
if(med_peer_host_table != NULL && row[1] != NULL) // host column is optional
if(host_table != NULL && row[1] != NULL) // host column is optional
{
if(g_hash_table_lookup(med_peer_host_table, row[1]) != NULL)
if(g_hash_table_lookup(host_table, row[1]) != NULL)
syslog(LOG_WARNING, "Skipping duplicate host '%s'", row[1]);
else
g_hash_table_insert(med_peer_host_table, strdup(row[1]), strdup(row[2]));
}
if (med_peer_id_table)
g_hash_table_insert(med_peer_id_table, strdup(row[3]), strdup(row[2]));
if (med_peer_id_host_table) {
if (row[1] && *row[1])
g_hash_table_insert(med_peer_id_host_table, strdup(row[3]), strdup(row[1]));
else
g_hash_table_insert(med_peer_id_host_table, strdup(row[3]), strdup(row[0]));
g_hash_table_insert(host_table, strdup(row[1]), strdup(row[2]));
}
if (med_peer_id_hostname_table)
g_hash_table_insert(med_peer_id_hostname_table, strdup(row[3]), strdup(row[4]));
if (id_table)
g_hash_table_insert(id_table, strdup(row[3]), strdup(row[2]));
}
out:

@ -36,7 +36,7 @@ int medmysql_trash_entries(const char *callid, struct medmysql_batches *);
int medmysql_backup_entries(const char *callid, struct medmysql_batches *);
int medmysql_delete_entries(const char *callid, struct medmysql_batches *);
int medmysql_insert_cdrs(cdr_entry_t *records, u_int64_t count, struct medmysql_batches *);
int medmysql_load_maps();
int medmysql_load_maps(GHashTable *ip_table, GHashTable *host_table, GHashTable *id_table);
int medmysql_load_uuids(GHashTable *uuid_table);
int medmysql_batch_start(struct medmysql_batches *);
int medmysql_batch_end(struct medmysql_batches *);

Loading…
Cancel
Save