Пример #1
0
static int mod_init( void )
{
	pv_spec_t avp_spec;

	LM_INFO("initializing...\n");

	if (db_url.s)
		db_url.len = strlen(db_url.s);
	db_table_acc.len = strlen(db_table_acc.s);
	db_table_mc.len = strlen(db_table_mc.s);
	acc_method_col.len = strlen(acc_method_col.s);
	acc_fromtag_col.len = strlen(acc_fromtag_col.s);
	acc_totag_col.len = strlen(acc_totag_col.s);
	acc_callid_col.len = strlen(acc_callid_col.s);
	acc_sipcode_col.len = strlen(acc_sipcode_col.s);
	acc_sipreason_col.len = strlen(acc_sipreason_col.s);
	acc_time_col.len = strlen(acc_time_col.s);

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

	/* ----------- GENERIC INIT SECTION  ----------- */

	fix_flag_name(failed_transaction_string, failed_transaction_flag);

	failed_transaction_flag =
	    get_flag_id_by_name(FLAG_TYPE_MSG, failed_transaction_string);

	if (flag_idx2mask(&failed_transaction_flag)<0)
		return -1;
	fix_flag_name(cdr_string, cdr_flag);

	cdr_flag = get_flag_id_by_name(FLAG_TYPE_MSG, cdr_string);

	if (flag_idx2mask(&cdr_flag)<0)
		return -1;

	/* load the TM API */
	if (load_tm_api(&tmb)!=0) {
		LM_ERR("can't load TM API\n");
		return -1;
	}

	if (load_dlg_api(&dlg_api)!=0)
		LM_DBG("failed to find dialog API - is dialog module loaded?\n");

	if (cdr_flag && !dlg_api.get_dlg) {
		LM_WARN("error loading dialog module - cdrs cannot be generated\n");
		cdr_flag = 0;
	}
	/* if detect_direction is enabled, load rr also */
	if (detect_direction) {
		if (load_rr_api(&rrb)!=0) {
			LM_ERR("can't load RR API\n");
			return -1;
		}
		/* we need the append_fromtag on in RR */
		if (!rrb.append_fromtag) {
			LM_ERR("'append_fromtag' RR param is not enabled!"
				" - required by 'detect_direction'\n");
			return -1;
		}
	}

	/* listen for all incoming requests  */
	if ( tmb.register_tmcb( 0, 0, TMCB_REQUEST_IN, acc_onreq, 0, 0 ) <=0 ) {
		LM_ERR("cannot register TMCB_REQUEST_IN callback\n");
		return -1;
	}

	/* init the extra engine */
	init_acc_extra();

	/* configure multi-leg accounting */
	if (leg_info_str && (leg_info=parse_acc_leg(leg_info_str))==0 ) {
		LM_ERR("failed to parse multi_leg_info param\n");
		return -1;
	}
	if (leg_bye_info_str && (leg_bye_info=parse_acc_leg(leg_bye_info_str))==0 ) {
		LM_ERR("failed to parse multi_leg_bye_info param\n");
		return -1;
	}

	/* ----------- SYSLOG INIT SECTION ----------- */

	/* parse the extra string, if any */
	if (log_extra_str && (log_extra=parse_acc_extra(log_extra_str, 1))==0 ) {
		LM_ERR("failed to parse log_extra param\n");
		return -1;
	}
	if (log_extra_bye_str &&
			(log_extra_bye=parse_acc_extra(log_extra_bye_str, 0))==0 ) {
		LM_ERR("failed to parse log_extra_bye param\n");
		return -1;
	}

	fix_flag_name(log_string, log_flag);

	log_flag = get_flag_id_by_name(FLAG_TYPE_MSG, log_string);

	if (flag_idx2mask(&log_flag)<0)
		return -1;

	fix_flag_name(log_missed_string, log_missed_flag);

	log_missed_flag = get_flag_id_by_name(FLAG_TYPE_MSG, log_missed_string);

	if (flag_idx2mask(&log_missed_flag)<0)
		return -1;

	acc_log_init();

	/* ------------ SQL INIT SECTION ----------- */

	if (db_url.s && db_url.len > 0) {
		/* parse the extra string, if any */
		if (db_extra_str && (db_extra=parse_acc_extra(db_extra_str, 1))==0 ) {
			LM_ERR("failed to parse db_extra param\n");
			return -1;
		}
		if (db_extra_bye_str &&
				(db_extra_bye=parse_acc_extra(db_extra_bye_str, 0))==0 ) {
			LM_ERR("failed to parse db_extra_bye param\n");
			return -1;
		}
		if (acc_db_init(&db_url)<0){
			LM_ERR("failed...did you load a database module?\n");
			return -1;
		}
		/* fix the flags */
		fix_flag_name(db_string, db_flag);

		db_flag = get_flag_id_by_name(FLAG_TYPE_MSG, db_string);

		if (flag_idx2mask(&db_flag)<0)
			return -1;

		fix_flag_name(db_missed_string, db_missed_flag);

		db_missed_flag = get_flag_id_by_name(FLAG_TYPE_MSG, db_missed_string);

		if (flag_idx2mask(&db_missed_flag)<0)
			return -1;
		if (db_table_avp.s) {
			db_table_avp.len = strlen(db_table_avp.s);
			if (pv_parse_spec(&db_table_avp, &avp_spec) == 0 ||
					avp_spec.type != PVT_AVP) {
				LM_ERR("malformed or non AVP %s\n", db_table_avp.s);
				return -1;
			}
			if (pv_get_avp_name(0, &avp_spec.pvp, &db_table_name,
						&db_table_name_type)) {
				LM_ERR("invalid definition of AVP %s\n", db_table_avp.s);
				return -1;
			}
		}
	} else {
		db_flag = 0;
		db_missed_flag = 0;
	}

	/* ------------ AAA PROTOCOL INIT SECTION ----------- */

	if (aaa_proto_url && aaa_proto_url[0]) {
		/* parse the extra string, if any */
		if (aaa_extra_str && (aaa_extra = parse_acc_extra(aaa_extra_str, 1))==0) {
			LM_ERR("failed to parse aaa_extra param\n");
			return -1;
		}
		if (aaa_extra_bye_str &&
				(aaa_extra_bye = parse_acc_extra(aaa_extra_bye_str, 0))==0) {
			LM_ERR("failed to parse aaa_extra_bye param\n");
			return -1;
		}

		/* fix the flags */
		fix_flag_name(aaa_string, aaa_flag);

		aaa_flag = get_flag_id_by_name(FLAG_TYPE_MSG, aaa_string);

		if (flag_idx2mask(&aaa_flag)<0)
			return -1;

		fix_flag_name(aaa_missed_string, aaa_missed_flag);

		aaa_missed_flag = get_flag_id_by_name(FLAG_TYPE_MSG, aaa_missed_string);

		if (flag_idx2mask(&aaa_missed_flag)<0)
			return -1;

		if (init_acc_aaa(aaa_proto_url, service_type)!=0 ) {
			LM_ERR("failed to init radius\n");
			return -1;
		}
	} else {
		aaa_proto_url = NULL;
		aaa_flag = 0;
		aaa_missed_flag = 0;
	}

	/* ------------ DIAMETER INIT SECTION ----------- */

#ifdef DIAM_ACC
	/* fix the flags */
	fix_flag_name(diameter_string, diameter_flag);

	diameter_flag = get_flag_id_by_name(FLAG_TYPE_MSG, diameter_string);

	if (flag_idx2mask(&diameter_flag)<0)
		return -1;

	fix_flag_name(diameter_missed_string, diameter_missed_flag);

	diameter_missed_flag=get_flag_id_by_name(FLAG_TYPE_MSG, diameter_missed_string);

	if (flag_idx2mask(&diameter_missed_flag)<0)
		return -1;

	/* parse the extra string, if any */
	if (dia_extra_str && (dia_extra=parse_acc_extra(dia_extra_str))==0 ) {
		LM_ERR("failed to parse dia_extra param\n");
		return -1;
	}

	if (acc_diam_init()!=0) {
		LM_ERR("failed to init diameter engine\n");
		return -1;
	}

#endif

	/* ------------ EVENTS INIT SECTION ----------- */

	if (evi_extra_str && (evi_extra = parse_acc_extra(evi_extra_str, 1))==0) {
		LM_ERR("failed to parse evi_extra param\n");
		return -1;
	}
	if (evi_extra_bye_str &&
			(evi_extra_bye = parse_acc_extra(evi_extra_bye_str, 0))==0) {
		LM_ERR("failed to parse evi_extra_bye param\n");
		return -1;
	}

	/* fix the flags */
	fix_flag_name(evi_string, evi_flag);

	evi_flag = get_flag_id_by_name(FLAG_TYPE_MSG, evi_string);

	if (flag_idx2mask(&evi_flag)<0)
		return -1;

	fix_flag_name(evi_missed_string, evi_missed_flag);

	evi_missed_flag = get_flag_id_by_name(FLAG_TYPE_MSG, evi_missed_string);

	if (flag_idx2mask(&evi_missed_flag)<0)
		return -1;

	if (init_acc_evi() < 0) {
		LM_ERR("cannot init acc events\n");
		return -1;
	}

	/* load callbacks */
	if (cdr_flag && dlg_api.get_dlg && dlg_api.register_dlgcb(NULL,
				DLGCB_LOADED,acc_loaded_callback, NULL, NULL) < 0)
			LM_ERR("cannot register callback for dialog loaded - accounting "
					"for ongoing calls will be lost after restart\n");


	return 0;
}
Пример #2
0
static int mod_init( void )
{
#ifdef SQL_ACC
	if (db_url.s) {
		if(db_url.len<=0) {
			db_url.s = NULL;
			db_url.len = 0;
		}
	}
	if(db_table_acc.len!=3 || strncmp(db_table_acc.s, "acc", 3)!=0)
	{
		db_table_acc_data = db_table_acc.s;
		if(fixup_var_pve_str_12(&db_table_acc_data, 1)<0)
		{
			LM_ERR("unable to parse acc table name [%.*s]\n",
					db_table_acc.len, db_table_acc.s);
			return -1;
		}
	}
	if(db_table_mc.len!=12 || strncmp(db_table_mc.s, "missed_calls", 12)!=0)
	{
		db_table_mc_data = db_table_mc.s;
		if(fixup_var_pve_str_12(&db_table_mc_data, 1)<0)
		{
			LM_ERR("unable to parse mc table name [%.*s]\n",
					db_table_mc.len, db_table_mc.s);
			return -1;
		}
	}
#endif

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

	/* ----------- GENERIC INIT SECTION  ----------- */

	/* failed transaction handling */
	if ((failed_transaction_flag != -1) && 
		!flag_in_range(failed_transaction_flag)) {
		LM_ERR("failed_transaction_flag set to invalid value\n");
		return -1;
	}
	if (failed_filter_str) {
	    if (parse_failed_filter(failed_filter_str, failed_filter) == 0) {
		LM_ERR("failed to parse failed_filter param\n");
		return -1;
	    }
	} else {
	    failed_filter[0] = 0;
	}

	/* load the TM API */
	if (load_tm_api(&tmb)!=0) {
		LM_ERR("can't load TM API\n");
		return -1;
	}

	/* if detect_direction is enabled, load rr also */
	if (detect_direction) {
		if (load_rr_api(&rrb)!=0) {
			LM_ERR("can't load RR API\n");
			return -1;
		}
		/* we need the append_fromtag on in RR */
		if (!rrb.append_fromtag) {
			LM_ERR("'append_fromtag' RR param is not enabled!"
				" - required by 'detect_direction'\n");
			return -1;
		}
	}

	/* listen for all incoming requests  */
	if ( tmb.register_tmcb( 0, 0, TMCB_REQUEST_IN, acc_onreq, 0, 0 ) <=0 ) {
		LM_ERR("cannot register TMCB_REQUEST_IN callback\n");
		return -1;
	}

	/* configure multi-leg accounting */
	if (leg_info_str && (leg_info=parse_acc_leg(leg_info_str))==0 ) {
		LM_ERR("failed to parse multileg_info param\n");
		return -1;
	}

	/* ----------- SYSLOG INIT SECTION ----------- */

	/* parse the extra string, if any */
	if (log_extra_str && (log_extra=parse_acc_extra(log_extra_str))==0 ) {
		LM_ERR("failed to parse log_extra param\n");
		return -1;
	}

	if ((log_flag != -1) && !flag_in_range(log_flag)) {
		LM_ERR("log_flag set to invalid value\n");
		return -1;
	}

	if ((log_missed_flag != -1) && !flag_in_range(log_missed_flag)) {
		LM_ERR("log_missed_flag set to invalid value\n");
		return -1;
	}

	acc_log_init();

	/* ----------- INIT CDR GENERATION ----------- */

	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;
	}

	if( cdr_enable)
	{
		if( !cdr_start_str.s || !cdr_end_str.s || !cdr_duration_str.s) 
		{
		      LM_ERR( "necessary cdr_parameters are not set\n");
		      return -1;
		}			
		
		if( !cdr_start_str.len || !cdr_end_str.len || !cdr_duration_str.len) 
		{
		      LM_ERR( "necessary cdr_parameters are empty\n");
		      return -1;
		}
		
		
		if( set_cdr_extra( cdr_log_extra_str) != 0)
		{
			LM_ERR( "failed to set cdr extra '%s'\n", cdr_log_extra_str);
			return -1;
		}

		if( cdr_facility_str && set_cdr_facility( cdr_facility_str) != 0)
		{
			LM_ERR( "failed to set cdr facility '%s'\n", cdr_facility_str);
			return -1;
		}
	
		if( init_cdr_generation() != 0)
		{
			LM_ERR("failed to init cdr generation\n");
			return -1;
		}
	}

	/* ------------ SQL INIT SECTION ----------- */

#ifdef SQL_ACC
	if (db_url.s && db_url.len > 0) {
		/* parse the extra string, if any */
		if (db_extra_str && (db_extra=parse_acc_extra(db_extra_str))==0 ) {
			LM_ERR("failed to parse db_extra param\n");
			return -1;
		}
		if (acc_db_init(&db_url)<0){
			LM_ERR("failed...did you load a database module?\n");
			return -1;
		}
		/* fix the flags */

		if ((db_flag != -1) && !flag_in_range(db_flag)) {
			LM_ERR("db_flag set to invalid value\n");
			return -1;
		}

		if ((db_missed_flag != -1) && !flag_in_range(db_missed_flag)) {
			LM_ERR("db_missed_flag set to invalid value\n");
			return -1;
		}
	} else {
		db_url.s = NULL;
		db_url.len = 0;
		db_flag = -1;
		db_missed_flag = -1;
	}
#endif

	/* ------------ RADIUS INIT SECTION ----------- */

#ifdef RAD_ACC
	if (radius_config && radius_config[0]) {
		/* parse the extra string, if any */
		if (rad_extra_str && (rad_extra=parse_acc_extra(rad_extra_str))==0 ) {
			LM_ERR("failed to parse rad_extra param\n");
			return -1;
		}

		/* fix the flags */
		if ((radius_flag != -1) && !flag_in_range(radius_flag)) {
			LM_ERR("radius_flag set to invalid value\n");
			return -1;
		}

		if ((radius_missed_flag != -1) && !flag_in_range(radius_missed_flag)) {
			LM_ERR("radius_missed_flag set to invalid value\n");
			return -1;
		}

		if (init_acc_rad( radius_config, service_type)!=0 ) {
			LM_ERR("failed to init radius\n");
			return -1;
		}
	} else {
		radius_config = 0;
		radius_flag = -1;
		radius_missed_flag = -1;
	}
#endif

	/* ------------ DIAMETER INIT SECTION ----------- */

#ifdef DIAM_ACC
	/* fix the flags */
	if (flag_idx2mask(&diameter_flag)<0)
		return -1;
	if (flag_idx2mask(&diameter_missed_flag)<0)
		return -1;

	/* parse the extra string, if any */
	if (dia_extra_str && (dia_extra=parse_acc_extra(dia_extra_str))==0 ) {
		LM_ERR("failed to parse dia_extra param\n");
		return -1;
	}

	if (acc_diam_init()!=0) {
		LM_ERR("failed to init diameter engine\n");
		return -1;
	}

#endif

	_acc_module_initialized = 1;
	if(acc_init_engines()<0) {
		LM_ERR("failed to init extra engines\n");
		return -1;
	}

	return 0;
}
Пример #3
0
static int mod_init(void)
{
	pv_spec_t avp_spec;
	int i;

	init_db_url( db_url , 0 /*cannot be null*/);
	siptrace_table.len = strlen(siptrace_table.s);
	date_column.len = strlen(date_column.s);
	callid_column.len = strlen(callid_column.s);
	traced_user_column.len = strlen(traced_user_column.s);
	msg_column.len = strlen(msg_column.s);
	method_column.len = strlen(method_column.s);
	status_column.len = strlen(status_column.s);
	fromproto_column.len = strlen(fromproto_column.s);
	fromip_column.len = strlen(fromip_column.s);
	fromport_column.len = strlen(fromport_column.s);
	toproto_column.len = strlen(toproto_column.s);
	toip_column.len = strlen(toip_column.s);
	toport_column.len = strlen(toport_column.s);
	fromtag_column.len = strlen(fromtag_column.s);
	direction_column.len = strlen(direction_column.s);
	if (traced_user_avp_str.s)
		traced_user_avp_str.len = strlen(traced_user_avp_str.s);
	if (trace_table_avp_str.s)
		trace_table_avp_str.len = strlen(trace_table_avp_str.s);
	if (dup_uri_str.s)
		dup_uri_str.len = strlen(dup_uri_str.s);

	if (trace_local_ip.s)
		parse_trace_local_ip();

	LM_INFO("initializing...\n");

	fix_flag_name(trace_flag_str, trace_flag);

	trace_flag = get_flag_id_by_name(FLAG_TYPE_MSG, trace_flag_str);

	if (flag_idx2mask(&trace_flag)<0)
		return -1;

	trace_to_database_flag = (int*)shm_malloc(sizeof(int));
        if(trace_to_database_flag==NULL) {
                LM_ERR("no more shm memory left\n");
                return -1;
        }

	*trace_to_database_flag = trace_to_database;

	if(trace_to_database_flag!=NULL && *trace_to_database_flag!=0) {
		/* Find a database module */
		if (db_bind_mod(&db_url, &db_funcs))
		{
			LM_ERR("unable to bind database module\n");
			return -1;
		}
		if (trace_to_database_flag && !DB_CAPABILITY(db_funcs, DB_CAP_INSERT))
		{
			LM_ERR("database modules does not provide all functions needed by module\n");
			return -1;
		}

		if ((db_con = db_funcs.init(&db_url)) == 0) {
			LM_CRIT("Cannot connect to DB\n");
			return -1;
		}

		if(db_check_table_version(&db_funcs, db_con,
				&siptrace_table, SIPTRACE_TABLE_VERSION) < 0) {
			LM_ERR("error during table version check.\n");
			return -1;
		}

		db_funcs.close(db_con);
		db_con = 0;
	}

	trace_on_flag = (int*)shm_malloc(sizeof(int));
	if(trace_on_flag==NULL)
	{
		LM_ERR("no more shm memory left\n");
		return -1;
	}

	*trace_on_flag = trace_on;



	/* register callbacks to TM */
	if (load_tm_api(&tmb)!=0)
	{
		LM_ERR("can't load tm api\n");
		return -1;
	}

	if(tmb.register_tmcb( 0, 0, TMCB_REQUEST_IN, trace_onreq_in, 0, 0) <=0)
	{
		LM_ERR("can't register trace_onreq_in\n");
		return -1;
	}

	/* register sl callback */
	register_slcb_f = (register_slcb_t)find_export("register_slcb", 0, 0);
	if(register_slcb_f==NULL)
	{
		LM_ERR("can't load sl api\n");
		return -1;
	}
	if(register_slcb_f(SLCB_REPLY_OUT,trace_sl_onreply_out, NULL)!=0)
	{
		LM_ERR("can't register trace_sl_onreply_out\n");
		return -1;
	}
	if(register_fwdcb(trace_msg_out_w)!=0)
	{
		LM_ERR("can't register trace_sl_ack_out\n");
		return -1;
	}
	if(enable_ack_trace&&register_slcb_f(SLCB_ACK_IN,trace_sl_ack_in,NULL)!=0)
	{
		LM_ERR("can't register trace_sl_ack_in\n");
		return -1;
	}

	if(dup_uri_str.s!=0) {
		dup_uri_str.len = strlen(dup_uri_str.s);
		dup_uri = (struct sip_uri *)pkg_malloc(sizeof(struct sip_uri));
		if(dup_uri==0) {
			LM_ERR("no more pkg memory left\n");
			return -1;
		}
		memset(dup_uri, 0, sizeof(struct sip_uri));
		if(parse_uri(dup_uri_str.s, dup_uri_str.len, dup_uri)<0) {
			LM_ERR("bad dup uri\n");
			return -1;
		}
	}

	if(traced_user_avp_str.s && traced_user_avp_str.len > 0)
	{
		if (pv_parse_spec(&traced_user_avp_str, &avp_spec)==0
				|| avp_spec.type!=PVT_AVP) {
			LM_ERR("malformed or non AVP %.*s AVP definition\n",
				traced_user_avp_str.len, traced_user_avp_str.s);
			return -1;
		}

		if(pv_get_avp_name(0, &avp_spec.pvp, &traced_user_avp,
					&traced_user_avp_type)!=0)
		{
			LM_ERR("[%.*s] - invalid AVP definition\n",
				traced_user_avp_str.len, traced_user_avp_str.s);
			return -1;
		}
	} else {
		traced_user_avp = -1;
		traced_user_avp_type = 0;
	}
	if(trace_table_avp_str.s && trace_table_avp_str.len > 0)
	{
		if (pv_parse_spec(&trace_table_avp_str, &avp_spec)==0
				|| avp_spec.type!=PVT_AVP) {
			LM_ERR("malformed or non AVP %.*s AVP definition\n",
				trace_table_avp_str.len, trace_table_avp_str.s);
			return -1;
		}

		if(pv_get_avp_name(0, &avp_spec.pvp, &trace_table_avp,
					&trace_table_avp_type)!=0)
		{
			LM_ERR("[%.*s] - invalid AVP definition\n"
				, trace_table_avp_str.len, trace_table_avp_str.s);
			return -1;
		}
	} else {
		trace_table_avp = -1;
		trace_table_avp_type = 0;
	}

	if (duplicate_with_hep) {
		load_hep = (load_hep_f)find_export("load_hep", 1, 0);
		if (!load_hep) {
			LM_ERR("Can't bind proto hep!\n");
			return -1;
		}

		if (load_hep(&hep_api)) {
			LM_ERR("can't bind proto hep\n");
			return -1;
		}
	}



	/* init the DB keys for future queries */
	db_keys[0] = &msg_column;
	db_keys[1] = &callid_column;
	db_keys[2] = &method_column;
	db_keys[3] = &status_column;
	db_keys[4] = &fromproto_column;
	db_keys[5] = &fromip_column;
	db_keys[6] = &fromport_column;
	db_keys[7] = &toproto_column;
	db_keys[8] = &toip_column;
	db_keys[9] = &toport_column;
	db_keys[10] = &date_column;
	db_keys[11] = &direction_column;
	db_keys[12] = &fromtag_column;
	db_keys[13] = &traced_user_column;

	/* init DB values info which is constant ( type, null ) */
	db_vals[0].type = DB_BLOB;
	db_vals[1].type = DB_STR;
	db_vals[2].type = DB_STR;
	db_vals[3].type = DB_STR;
	db_vals[4].type = DB_STR;
	db_vals[5].type = DB_STR;
	db_vals[6].type = DB_INT;
	db_vals[7].type = DB_STR;
	db_vals[8].type = DB_STR;
	db_vals[9].type = DB_INT;
	db_vals[10].type = DB_DATETIME;
	db_vals[11].type = DB_STRING;
	db_vals[12].type = DB_STR;
	db_vals[13].type = DB_STR;
	/* no field can be null */
	for (i=0;i<NR_KEYS;i++)
		db_vals[i].nul = 0;

	return 0;
}
Пример #4
0
static int mod_init(void)
{
	pv_spec_t avp_spec;
	str s;

	LM_INFO("initializing...\n");
	
	if(siptrace_table==0 || strlen(siptrace_table)<=0)
	{
		LM_ERR("invalid table name\n");
		return -1;
	}

	if (flag_idx2mask(&trace_flag)<0)
		return -1;

	/* Find a database module */
	if (bind_dbmod(db_url, &db_funcs))
	{
		LM_ERR("unable to bind database module\n");
		return -1;
	}
	if (!DB_CAPABILITY(db_funcs, DB_CAP_INSERT))
	{
		LM_ERR("database modules does not provide all functions needed by module\n");
		return -1;
	}

	trace_on_flag = (int*)shm_malloc(sizeof(int));
	if(trace_on_flag==NULL)
	{
		LM_ERR("no more shm memory left\n");
		return -1;
	}
	
	*trace_on_flag = trace_on;
	
	/* register callbacks to TM */
	if (load_tm_api(&tmb)!=0)
	{
		LM_ERR("can't load tm api\n");
		return -1;
	}

	if(tmb.register_tmcb( 0, 0, TMCB_REQUEST_IN, trace_onreq_in, 0) <=0)
	{
		LM_ERR("can't register trace_onreq_in\n");
		return -1;
	}

	/* register sl callback */
	register_slcb_f = (register_slcb_t)find_export("register_slcb", 0, 0);
	if(register_slcb_f==NULL)
	{
		LM_ERR("can't load sl api\n");
		return -1;
	}
	if(register_slcb_f(SLCB_REPLY_OUT,trace_sl_onreply_out, NULL)!=0)
	{
		LM_ERR("can't register trace_sl_onreply_out\n");
		return -1;
	}
	if(register_slcb_f(SLCB_ACK_IN,trace_sl_ack_in, NULL)!=0)
	{
		LM_ERR("can't register trace_sl_ack_in\n");
		return -1;
	}

	if(dup_uri_str.s!=0) {
		dup_uri_str.len = strlen(dup_uri_str.s);
		dup_uri = (struct sip_uri *)pkg_malloc(sizeof(struct sip_uri));
		if(dup_uri==0) {
			LM_ERR("no more pkg memory left\n");
			return -1;
		}
		memset(dup_uri, 0, sizeof(struct sip_uri));
		if(parse_uri(dup_uri_str.s, dup_uri_str.len, dup_uri)<0) {
			LM_ERR("bad dup uri\n");
			return -1;
		}
	}

	if(traced_user_avp_str && *traced_user_avp_str)
	{
		s.s = traced_user_avp_str; s.len = strlen(s.s);
		if (pv_parse_spec(&s, &avp_spec)==0
				|| avp_spec.type!=PVT_AVP) {
			LM_ERR("malformed or non AVP %s AVP definition\n", traced_user_avp_str);
			return -1;
		}

		if(pv_get_avp_name(0, &avp_spec.pvp, &traced_user_avp,
					&traced_user_avp_type)!=0)
		{
			LM_ERR("[%s] - invalid AVP definition\n", traced_user_avp_str);
			return -1;
		}
	} else {
		traced_user_avp.n = 0;
		traced_user_avp_type = 0;
	}
	if(trace_table_avp_str && *trace_table_avp_str)
	{
		s.s = trace_table_avp_str; s.len = strlen(s.s);
		if (pv_parse_spec(&s, &avp_spec)==0
				|| avp_spec.type!=PVT_AVP) {
			LM_ERR("malformed or non AVP %s AVP definition\n", trace_table_avp_str);
			return -1;
		}

		if(pv_get_avp_name(0, &avp_spec.pvp, &trace_table_avp,
					&trace_table_avp_type)!=0)
		{
			LM_ERR("[%s] - invalid AVP definition\n", trace_table_avp_str);
			return -1;
		}
	} else {
		trace_table_avp.n = 0;
		trace_table_avp_type = 0;
	}

	return 0;
}