2
0
Эх сурвалжийг харах

added homer5 functionality to sipcapture module

Alexandr Dubovikov 10 жил өмнө
parent
commit
c1863d7dc5

+ 46 - 7
modules/sipcapture/examples/kamailio.cfg

@@ -81,7 +81,7 @@ route {
         $sht(a=>method::all) = $sht(a=>method::all) + 1;
 
         if($sht(b=>$rm::$cs::$ci) != $null) {
-                $var(a) = "sip_capture";
+		$var(a) = "sip_capture_call" + "_%Y%m%d";
                 sip_capture("$var(a)");
                 drop;
         }
@@ -191,11 +191,28 @@ route {
         }
 
 
-        $var(a) = "sip_capture";
-        # Kamailio 4.1 only
-        #sip_capture("$var(a)"); 
-        
-        sip_capture();
+	#Sharding
+	if(is_method("REGISTER")) {
+                $var(table) = "sip_capture_registration";
+        }
+        else if(is_method("INVITE|BYE|CANCEL|UPDATE|ACK|PRACK|REFER"))
+        {
+                $var(table) = "sip_capture_call";
+        }
+        else if(is_method("INFO"))
+        {
+                $var(table) = "sip_capture_call";
+        }
+        else if(is_method("OPTIONS|PUBLISH")) 
+        {
+                $var(table) = "sip_capture_rest";
+        }
+        else {
+                $var(table) = "sip_capture_rest";
+        }
+
+        $var(a) = $var(table) + "_%Y%m%d";
+        sip_capture("$var(a)");
 
         drop;
 }
@@ -306,7 +323,29 @@ onreply_route {
                 }
         }
 
-        sip_capture();
+	#sharding
+	if($rm == "REGISTER") {
+                $var(table) = "sip_capture_registration";
+        }
+        else if($rm =~ "(INVITE|UPDATE|BYE|ACK|PRACK|REFER)$")
+        {
+                $var(table) = "sip_capture_call";
+        } 
+        else if($rm =~ "(INFO)$")
+        {
+                $var(table) = "sip_capture_call";
+        }
+        else if($rm =~ "(OPTIONS|PUBLISH)$" )
+        {
+            $var(table) = "sip_capture_rest";
+        }
+        else {
+            $var(table) = "sip_capture_rest";
+        }
+
+        $var(a) = $var(table) + "_%Y%m%d";
+
+        sip_capture("$var(a)");
 
         drop;
 }

+ 0 - 161
modules/sipcapture/examples/partrotate_unixtimestamp.pl

@@ -1,161 +0,0 @@
-#!/usr/bin/perl
-#
-# partrotate_unixtimestamp - perl script for mySQL partition rotation
-#
-# Copyright (C) 2011-2014 Alexandr Dubovikov ([email protected])
-#
-# This file is part of webhomer, a free capture server.
-#
-# partrotate_unixtimestamp is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
-# (at your option) any later version
-#
-# partrotate_unixtimestamp is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
-use DBI;
-
-$version = "0.3.1k";
-$mysql_table = "sip_capture";
-$mysql_dbname = "homer_db";
-$mysql_user = "mysql_login";
-$mysql_password = "mysql_password";
-$mysql_host = "localhost";
-$maxparts = 6; #6 days How long keep the data in the DB
-$newparts = 2; #new partitions for 2 days. Anyway, start this script daily!
-@stepsvalues = (86400, 3600, 1800, 900); 
-$partstep = 0; # 0 - Day, 1 - Hour, 2 - 30 Minutes, 3 - 15 Minutes 
-$engine = "InnoDB"; #MyISAM or InnoDB
-$compress = "ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8"; #Enable this if you want use barracuda format or set var to empty.
-$sql_schema_version = 2;
-$auth_column = "auth";
-$check_table = 1; #Check if table exists. For PostgreSQL change creation schema!
-
-#Check it
-$partstep=0 if(!defined $stepsvalues[$partstep]);
-#Mystep
-$mystep = $stepsvalues[$partstep];
-#Coof
-
-# Optionally load override configuration. perl format
-$rc = "/etc/sysconfig/partrotaterc";
-if (-e $rc) {
-  do $rc;
-}
-
-$coof=int(86400/$mystep);
-
-#How much partitions
-$maxparts*=$coof;
-$newparts*=$coof;
-$totalparts = ($maxparts+$newparts);
-
-my $db = DBI->connect("DBI:mysql:$mysql_dbname:$mysql_host:3306", $mysql_user, $mysql_password);
-
-$auth_column = "authorization" if($sql_schema_version == 1);
-
-#$db->{PrintError} = 0;
-
-#check if the table has partitions. If not, create one
-my $query = "SHOW TABLE STATUS FROM ".$mysql_dbname. " WHERE Name='".$mysql_table."'";
-$sth = $db->prepare($query);
-$sth->execute();
-my $tstatus = $sth->fetchrow_hashref()->{Create_options};
-if ($tstatus !~ /partitioned/) {
-   my $query = "ALTER TABLE ".$mysql_table. " PARTITION BY RANGE ( UNIX_TIMESTAMP(`date`)) (PARTITION pmax VALUES LESS THAN MAXVALUE)";
-   $sth = $db->prepare($query);
-   $sth->execute();
-}
-
-my $query = "SELECT UNIX_TIMESTAMP(CURDATE() - INTERVAL 1 DAY)";
-$sth = $db->prepare($query);
-$sth->execute();
-my ($curtstamp) = $sth->fetchrow_array();
-$curtstamp+=0; 
-$todaytstamp+=0;
-
-
-
-my %PARTS;
-#Geting all partitions
-$query = "SELECT PARTITION_NAME, PARTITION_DESCRIPTION"
-             ."\n FROM INFORMATION_SCHEMA.PARTITIONS WHERE TABLE_NAME='".$mysql_table."'"
-             ."\n AND TABLE_SCHEMA='".$mysql_dbname."' ORDER BY PARTITION_DESCRIPTION ASC;";
-$sth = $db->prepare($query);
-$sth->execute();
-my @oldparts;
-my @partsremove;
-while(my @ref = $sth->fetchrow_array())
-{
-  
-   my $minpart = $ref[0];
-   my $todaytstamp = $ref[1];
-       
-   next if($minpart eq "pmax");
-      
-   if($curtstamp <= $todaytstamp) { 
-          $PARTS{$minpart."_".$todaytstamp} = 1;
-   }
-   else { push(@oldparts, \@ref); }
-   
-}
-
-my $partcount = $#oldparts;
-if($partcount > $maxparts)
-{
-    foreach my $ref (@oldparts) {
-
-       $minpart = $ref->[0];
-       $todaytstamp = $ref->[1];
-
-       push(@partsremove,$minpart);
-
-       $partcount--;
-       last if($partcount <= $maxparts);
-    }
-}
-
-
-if($#partsremove > 0)   
-{
-
-    $query = "ALTER TABLE ".$mysql_table." DROP PARTITION ".join(',', @partsremove);
-    $db->do($query);
-    if (!$db->{Executed}) {
-           print "Couldn't drop partition: $minpart\n";
-           break;
-    }
-}
-
-# < condition
-$curtstamp+=(86400);
-
-#Create new partitions
-for(my $i=0; $i<$newparts; $i++) {
-
-    $oldstamp = $curtstamp;
-    $curtstamp+=$mystep;   
-
-    ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($oldstamp);
-
-    my $newpartname = sprintf("p%04d%02d%02d%02d",($year+=1900),(++$mon),$mday,$hour);
-    $newpartname.= sprintf("%02d", $min) if($partstep > 1);
-
-    if(!defined $PARTS{$newpartname."_".$curtstamp}) {
-
-        # Fix MAXVALUE. Thanks Dorn B. <[email protected]> for report and fix.
-        $query = "ALTER TABLE ".$mysql_table." REORGANIZE PARTITION pmax INTO (PARTITION ".$newpartname
-                                ."\n VALUES LESS THAN (".$curtstamp.") ENGINE = ".$engine.", PARTITION pmax VALUES LESS THAN MAXVALUE ENGINE = ".$engine.")";
-        $db->do($query);
-        if (!$db->{Executed}) {
-             print "Couldn't add partition: $newpartname\n";
-        }
-    }    
-}

+ 6 - 7
modules/sipcapture/hep.c

@@ -37,7 +37,7 @@
 #include "sipcapture.h"
 
 
-static int show_error = 0;
+
 static int count = 0;
 
 struct hep_timehdr* heptime;
@@ -58,10 +58,7 @@ int hep_msg_received(void *data)
         struct receive_info *ri;
 
         if(!hep_capture_on) {
-        	if(show_error == 0) {
-                	LOG(L_ERR, "sipcapture:hep_msg_received HEP is not enabled\n");
-                	show_error = 1;
-        	}
+                LOG(L_ERR, "sipcapture:hep_msg_received HEP is not enabled\n");
                 return -1;
         }
 
@@ -487,9 +484,11 @@ int parsing_hepv3_message(char *buf, unsigned int len) {
           
 
         if(payload != NULL ) {
-                /* and now recieve message */                
+                /* and now recieve message */
                 if (hg->proto_t->data == 5) receive_logging_json_msg(payload, payload_len, hg, "rtcp_capture");
-                else if (hg->proto_t->data == 100) receive_logging_json_msg(payload, payload_len, hg, "logs_capture");                
+                else if (hg->proto_t->data == 32) receive_logging_json_msg(payload, payload_len, hg, "report_capture");
+                else if (hg->proto_t->data == 99) receive_logging_json_msg(payload, payload_len, hg, "report_capture");
+                else if (hg->proto_t->data == 100) receive_logging_json_msg(payload, payload_len, hg, "logs_capture");
                 else receive_msg(payload, payload_len, &ri);
         }
 

+ 306 - 18
modules/sipcapture/sipcapture.c

@@ -3,7 +3,7 @@
  *
  * sipcapture module - helper module to capture sip messages
  *
- * Copyright (C) 2011-2014 Alexandr Dubovikov (QSC AG) ([email protected])
+ * Copyright (C) 2011-2015 Alexandr Dubovikov ([email protected])
  *
  * This file is part of Kamailio, a free SIP server.
  *
@@ -131,9 +131,15 @@ static int sipcapture_init_rpc(void);
 static int child_init(int rank);
 static void destroy(void);
 static int sipcapture_fixup(void** param, int param_no);
-static int sip_capture(struct sip_msg *msg, str *dtable,  _capture_mode_data_t *cm_data);
+static int reportcapture_fixup(void** param, int param_no);
+static int float2int_fixup(void** param, int param_no);
 
+static int sip_capture(struct sip_msg *msg, str *dtable,  _capture_mode_data_t *cm_data);
+static int report_capture(struct sip_msg *msg, str *_table, str* _corr, str *_data);
 static int w_sip_capture(struct sip_msg* _m, char* _table, _capture_mode_data_t * _cm_data, char* s2);
+static int w_report_capture(struct sip_msg* _m, char* _table, char* _corr, char* _data);
+static int w_float2int(struct sip_msg* _m, char* _val, char* _coof, char* s2);
+
 int init_rawsock_children(void);
 int extract_host_port(void);
 int raw_capture_socket(struct ip_addr* ip, str* iface, int port_start, int port_end, int proto);
@@ -146,6 +152,7 @@ static struct mi_root* sip_capture_mi(struct mi_root* cmd, void* param );
 static str db_url		= str_init(DEFAULT_DB_URL);
 static str table_name		= str_init("sip_capture");
 static str hash_source		= str_init("call_id");
+static str table_time_sufix	= str_init("%Y%m%D");
 static str mt_mode		= str_init("rand");
 static str date_column		= str_init("date");
 static str micro_ts_column 	= str_init("micro_ts");
@@ -243,8 +250,12 @@ struct hep_timehdr* heptime;
  */
 static cmd_export_t cmds[] = {
 	{"sip_capture", (cmd_function)w_sip_capture, 0, 0, 0, ANY_ROUTE},
-	{"sip_capture", (cmd_function)w_sip_capture, 1, sipcapture_fixup, 0, ANY_ROUTE },	                         
+	{"sip_capture", (cmd_function)w_sip_capture, 1, sipcapture_fixup, 0, ANY_ROUTE },	                         	
 	{"sip_capture", (cmd_function)w_sip_capture, 2, sipcapture_fixup, 0, ANY_ROUTE },
+	{"report_capture", (cmd_function)w_report_capture, 1, reportcapture_fixup, 0, ANY_ROUTE },	                         
+	{"report_capture", (cmd_function)w_report_capture, 2, reportcapture_fixup, 0, ANY_ROUTE },	                         
+	{"report_capture", (cmd_function)w_report_capture, 3, reportcapture_fixup, 0, ANY_ROUTE },	                         
+	{"float2int", (cmd_function)w_float2int, 2, float2int_fixup, 0, ANY_ROUTE },	                         
 	{0, 0, 0, 0, 0, 0}
 };
 
@@ -310,9 +321,10 @@ static param_export_t params[] = {
         {"raw_moni_bpf_on",  		INT_PARAM, &bpf_on   },		
         {"callid_aleg_header",          PARAM_STR, &callid_aleg_header},
         {"capture_mode",		PARAM_STRING|USE_FUNC_PARAM, (void *)capture_mode_param},
-    {"insert_retries",   	INT_PARAM, &insert_retries },
-    {"insert_retry_timeout",INT_PARAM, &insert_retry_timeout },
-		{0, 0, 0}
+        {"insert_retries",   		INT_PARAM, &insert_retries },
+        {"insert_retry_timeout",	INT_PARAM, &insert_retry_timeout },
+        {"table_time_sufix",		PARAM_STR, &table_time_sufix },
+	{0, 0, 0}
 };
 
 
@@ -908,6 +920,62 @@ static int sipcapture_fixup(void** param, int param_no)
         
         return 0;
 } 
+
+static int reportcapture_fixup(void** param, int param_no)
+{
+
+        if (param_no == 1 ) {
+                return fixup_var_pve_str_12(param, 1);
+        }
+        if (param_no == 2 ){
+                return fixup_var_pve_str_12(param, 1);
+        }
+        if (param_no == 3 ){
+                return fixup_var_pve_str_12(param, 1);
+        }
+        
+        return 0;
+} 
+
+static int float2int_fixup(void** param, int param_no)
+{
+
+        if (param_no == 1 ) {
+                return fixup_var_pve_str_12(param, 1);
+        }
+        if (param_no == 2 ){
+                return fixup_var_pve_str_12(param, 1);
+        }
+        
+        return 0;
+} 
+
+
+
+static int w_float2int(struct sip_msg* _m, char* _val, char* _coof, char* s2)
+{
+        str value = {0};
+        str coof = {0};
+        int ret = 0;
+  
+        if(_val!=NULL && (get_str_fparam(&value, _m, (fparam_t*)_val) < 0))
+        {
+                LM_ERR("invalid table parameter [%s] [%s]\n", _val, value.s);
+                return -1;
+        }
+        
+        if(_coof!=NULL && (get_str_fparam(&coof, _m, (fparam_t*)_coof) < 0))
+        {
+                LM_ERR("invalid data parameter [%s] [%s]\n", _coof, coof.s);
+                return -1;
+        }
+
+        ret = (int) (atof (value.s) * atoi(coof.s));
+
+        return  ret ? ret : -1;
+}
+
+
    
 static int w_sip_capture(struct sip_msg* _m, char* _table, _capture_mode_data_t * cm_data, char* s2)
 {
@@ -922,6 +990,40 @@ static int w_sip_capture(struct sip_msg* _m, char* _table, _capture_mode_data_t
         return sip_capture(_m, (table.len>0)?&table:NULL, cm_data );
 }
 
+static int w_report_capture(struct sip_msg* _m, char* _table, char* _corr, char* _data)
+{
+        str table = {0};
+        str corr = {0};
+        str data = {0};
+        
+        if(_table!=NULL && (get_str_fparam(&table, _m, (fparam_t*)_table) < 0))
+        {
+                LM_ERR("invalid table parameter [%s] [%s]\n", _table, table.s);
+                return -1;
+        }
+        
+        if(_corr!=NULL && (get_str_fparam(&corr, _m, (fparam_t*)_corr) < 0))
+        {
+                LM_ERR("invalid corr parameter [%s] [%s]\n", _corr, corr.s);
+                return -1;
+        }
+        
+        if(_data!=NULL && (get_str_fparam(&data, _m, (fparam_t*)_data) < 0))
+        {
+
+        
+                LM_ERR("invalid data parameter [%s] [%s]\n", _data, data.s);
+                return -1;
+        }
+        
+        /* workaround for data function */
+        if(data.len > 0 && !strncmp(data.s, "report_capture", data.len)) data.len = 0;
+        
+        return report_capture(_m, (table.len>0)?&table:NULL, (corr.len>0)?&corr:NULL ,(data.len>0)?&data:NULL );        
+        
+}
+
+
 
 int extract_host_port(void)
 {
@@ -1093,13 +1195,13 @@ static int sip_capture_store(struct _sipcapture_object *sco, str *dtable, _captu
 	int counter = 0;
 	db_insert_f insert;
 	time_t retry_failed_time = 0;
-
+	struct tm capt_ts;
+	
+	/* new */
 	str *table = NULL;
 	_capture_mode_data_t *c = NULL;
-        char strftime_buf[128];
-        time_t tvsec_;
-         struct tm capt_ts;
-
+	char strftime_buf[128];	        
+	time_t tvsec_;
 
 	c = (cm_data)? cm_data:capture_def;
 	if (!c){
@@ -1310,8 +1412,7 @@ static int sip_capture_store(struct _sipcapture_object *sco, str *dtable, _captu
 
 	if (dtable){
 		table = dtable;
-	}
-
+        }
 	else if (c->no_tables > 0 ){
 
 		if ( c->mtmode == mode_hash ){
@@ -1335,19 +1436,24 @@ static int sip_capture_store(struct _sipcapture_object *sco, str *dtable, _captu
 		}
 		table = &c->table_names[ii];
 	}
+	else {
+	        table->s = table_name.s;
+	        table->len = table_name.len;
+	}
 
-	tvsec_ = (time_t) (sco->tmstamp/1000000);
-        if(gmtime_r( &tvsec_, &capt_ts) == NULL)
+        
+	tvsec_ = (time_t) (sco->tmstamp/1000000);        		
+	if(gmtime_r( &tvsec_, &capt_ts) == NULL)
         {
-                LM_ERR("unable to set gmtime for sipcapture\n");
+                LM_ERR("unable to set time to attributes\n");
                 return -1;
         }
 
         table->len = strftime(strftime_buf, sizeof(strftime_buf), table->s,  &capt_ts);
         table->s = strftime_buf;
-
+	
 	/* check dynamic table */
-	LM_DBG("insert into homer table: [%.*s]\n", table->len, table->s);
+	LM_DBG("insert into homer table [1]: [%.*s]\n", table->len, table->s);
 	c->db_funcs.use_table(c->db_con, table);
 
 	LM_DBG("storing info...\n");
@@ -2079,6 +2185,11 @@ int receive_logging_json_msg(char * buf, unsigned int len, struct hep_generic_re
 		LM_ERR("no connection mode available to store data\n");
 		return -1;
 	}
+	
+	if(!correlation_id || strlen(correlation_id) == 0) {
+	        LM_ERR("no correlation id defined\n");
+		return -1;
+        }	
 
 	memset(&sco, 0, sizeof(struct _sipcapture_object));
 	gettimeofday( &tvb, &tz );
@@ -2101,6 +2212,13 @@ int receive_logging_json_msg(char * buf, unsigned int len, struct hep_generic_re
 	}
 
 
+	 /* type of proto */
+        if (hg->proto_t->data == 5) sco.type = 1;
+        else if (hg->proto_t->data == 32) sco.type = 2;
+        else if (hg->proto_t->data == 99) sco.type = 1;
+        else if (hg->proto_t->data == 100) sco.type = 1;
+
+
         /*source ip*/
         sco.source_ip.s = ipstr_src;
         sco.source_ip.len = strlen(ipstr_src);
@@ -2214,4 +2332,174 @@ error:
 	return -1;
 }
 
+static int report_capture(struct sip_msg *msg, str *_table, str* _corr,  str *_data)
+{
+	struct _sipcapture_object sco;
+	db_key_t db_keys[RTCP_NR_KEYS];
+	db_val_t db_vals[RTCP_NR_KEYS];	                        	        
+	char buf_ip[IP_ADDR_MAX_STR_SIZE+12];
+	struct timeval tvb;
+        struct timezone tz;
+        char tmp_node[100];
+        time_t epoch_time_as_time_t;
+        str corrtmp, tmp;
+                        
+	
+	_capture_mode_data_t *c = NULL;
+	c = capture_def;
+	if (!c){
+	        LM_ERR("no connection mode available to store data\n");
+	        return -1;
+        }
+	                                                          
+	                                          
+	LM_DBG("CAPTURE DEBUG...\n");
+
+	gettimeofday( &tvb, &tz );	        
+
+	if(msg==NULL) {
+		LM_DBG("nothing to capture\n");
+		return -1;
+	}
+	memset(&sco, 0, sizeof(struct _sipcapture_object));
+
+	if(capture_on_flag==NULL || *capture_on_flag==0) {
+		LM_DBG("capture off...\n");
+		return -1;
+	}
+
+	sco.proto = msg->rcv.proto;
+		
+	/* FAMILY TYPE */
+	sco.family = msg->rcv.src_ip.af;
+	
+	/* MESSAGE TYPE */
+	sco.type = msg->first_line.type;
+	
+	/* MSG */	
+	sco.msg.s = msg->buf;
+	sco.msg.len = msg->len;	        
+	//EMPTY_STR(sco.msg);
+                 
+	/* IP source and destination */
+	
+	strcpy(buf_ip, ip_addr2a(&msg->rcv.src_ip));
+	sco.source_ip.s = buf_ip;
+	sco.source_ip.len = strlen(buf_ip);
+        sco.source_port = msg->rcv.src_port;	
+
+        /*source ip*/
+	sco.destination_ip.s = ip_addr2a(&msg->rcv.dst_ip);
+	sco.destination_ip.len = strlen(sco.destination_ip.s);
+	sco.destination_port = msg->rcv.dst_port;
+
+			
+	if(heptime && heptime->tv_sec != 0) {
+               sco.tmstamp = (unsigned long long)heptime->tv_sec*1000000+heptime->tv_usec; /* micro ts */
+               snprintf(tmp_node, 100, "%.*s:%i", capture_node.len, capture_node.s, heptime->captid);
+               sco.node.s = tmp_node;
+               sco.node.len = strlen(tmp_node);
+               epoch_time_as_time_t = heptime->tv_sec;;
+        }
+        else {
+               sco.tmstamp = (unsigned long long)tvb.tv_sec*1000000+tvb.tv_usec; /* micro ts */
+               sco.node = capture_node;
+               epoch_time_as_time_t = tvb.tv_sec;
+        }
+
+        if(_corr && _corr->len > 0) {
+                 corrtmp.s = _corr->s;
+                 corrtmp.len = _corr->len;
+        }
+        else if(correlation_id) {
+                corrtmp.s = correlation_id;
+                corrtmp.len = strlen(correlation_id);
+                if(!strncmp(_table->s, "rtcp_capture",12)) corrtmp.len--;
+        }
+
+	db_keys[0] = &date_column;
+	db_vals[0].type = DB1_DATETIME;
+	db_vals[0].nul = 0;
+	db_vals[0].val.time_val = epoch_time_as_time_t;
+	
+	db_keys[1] = &micro_ts_column;
+        db_vals[1].type = DB1_BIGINT;
+        db_vals[1].nul = 0;
+        db_vals[1].val.ll_val = sco.tmstamp;
+	
+	db_keys[2] = &correlation_column;
+	db_vals[2].type = DB1_STR;
+	db_vals[2].nul = 0;
+	db_vals[2].val.str_val = corrtmp;
+	
+	db_keys[3] = &source_ip_column;
+	db_vals[3].type = DB1_STR;
+	db_vals[3].nul = 0;
+	db_vals[3].val.str_val = sco.source_ip;
+	
+	db_keys[4] = &source_port_column;
+        db_vals[4].type = DB1_INT;
+        db_vals[4].nul = 0;
+        db_vals[4].val.int_val = sco.source_port;
+        
+	db_keys[5] = &dest_ip_column;
+	db_vals[5].type = DB1_STR;
+	db_vals[5].nul = 0;
+	db_vals[5].val.str_val = sco.destination_ip;
+	
+	db_keys[6] = &dest_port_column;
+        db_vals[6].type = DB1_INT;
+        db_vals[6].nul = 0;
+        db_vals[6].val.int_val = sco.destination_port;        
+        
+        db_keys[7] = &proto_column;			
+        db_vals[7].type = DB1_INT;
+        db_vals[7].nul = 0;
+        db_vals[7].val.int_val = sco.proto;        
+
+        db_keys[8] = &family_column;			
+        db_vals[8].type = DB1_INT;
+        db_vals[8].nul = 0;
+        db_vals[8].val.int_val = sco.family;        
+        
+        db_keys[9] = &type_column;			
+        db_vals[9].type = DB1_INT;
+        db_vals[9].nul = 0;
+        db_vals[9].val.int_val = sco.type;                
+
+	db_keys[10] = &node_column;
+	db_vals[10].type = DB1_STR;
+	db_vals[10].nul = 0;
+	db_vals[10].val.str_val = sco.node;
+	
+	db_keys[11] = &msg_column;
+	db_vals[11].type = DB1_BLOB;
+	db_vals[11].nul = 0;
+
+	if(_data && _data->len > 0) 
+	{
+	        tmp.s = _data->s;
+        	tmp.len = _data->len;	
+	}	
+	else {
+	        /* MSG */
+	        tmp.s = msg->buf;
+	        tmp.len = msg->len;
+        }
+	
+	db_vals[11].val.blob_val = tmp;
+
+	c->db_funcs.use_table(c->db_con, _table);
+
+	if (c->db_funcs.insert(c->db_con, db_keys, db_vals, RTCP_NR_KEYS) < 0) {
+		LM_ERR("failed to insert into database\n");
+                goto error;               
+	}
+
+	return 1;
+
+error:
+        return -1;
+                        
+}
 

+ 1 - 0
modules/sipcapture/sipcapture.h

@@ -61,6 +61,7 @@ struct _sipcapture_object {
 	str rtp_stat;
 	int type;
         long long tmstamp;
+        long timestamp;
 	str node;
 	str msg;
 #ifdef STATISTICS