module Asterisk_Tests {

/* Asterisk test suite in TTCN-3
 * (C) 2024 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
 * All rights reserved.
 * Author: Pau Espin Pedrol <pespin@sysmocom.de>
 *
 * Released under the terms of GNU General Public License, Version 2 or
 * (at your option) any later version.
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 */

import from TCCOpenSecurity_Functions all;
import from General_Types all;
import from Osmocom_Types all;
import from Native_Functions all;
import from Misc_Helpers all;
import from TELNETasp_PortType all;
import from AMI_Functions all;

import from SDP_Types all;
import from SDP_Templates all;

import from SIP_Emulation all;
import from SIPmsg_Types all;
import from SIP_Templates all;

import from SIP_ConnectionHandler all;
import from IMS_ConnectionHandler all;

modulepar {
	charstring mp_local_sip_host := "127.0.0.2";
	integer mp_local_sip_port := 5060;
	charstring mp_remote_sip_host := "127.0.0.1";
	integer mp_remote_sip_port := 5060;

	charstring mp_local_ims_host := "127.0.0.3";
	integer mp_local_ims_port := 5060;
	charstring mp_ims_domain := "ims.mnc001.mcc238.3gppnetwork.org"
	charstring mp_ims_imsi := "238010000090828";

	/* Asterisk AMI: */
	charstring mp_ami_remote_host := "127.0.0.1";
	integer mp_ami_remote_port := 5038;
	charstring mp_ami_local_host := "0.0.0.0";
	integer mp_ami_local_port := 0;
	charstring mp_ami_user := "test_user";
	charstring mp_ami_secret := "1234";
	charstring mp_volte_ims_outbound_registration := "volte_ims";
}

type component test_CT {
	/* Manages all local VoIP users Asterisk is serving: */
	var SIP_Emulation_CT vc_SIP;
	/* Manages the IMS server Asterisk connects to: */
	var SIP_Emulation_CT vc_IMS;

	/* Connection towards Asterisk AMI iface: */
	var AMI_Adapter_CT vc_AMI;
	port AMI_Msg_PT AMI_CLIENT;

	port Coord_PT COORD;
	port IMSCoord_PT IMS_COORD;
}

const charstring broadcast_sip_extension := "0500";


function f_init_ConnHdlrPars(integer idx := 1) runs on test_CT return SIPConnHdlrPars {
	var template (value) CallPars cp := t_CallPars(mp_local_sip_host, 1234 + 2*idx);
	var template (value) SIPConnHdlrPars pars := t_Pars(mp_local_sip_host,
							    mp_local_sip_port,
							    mp_remote_sip_host,
							    mp_remote_sip_port,
							    "0" & int2str(str2int(broadcast_sip_extension) + idx),
							    cp := cp);
	return valueof(pars);
}

function f_init_IMS_ConnHdlrPars(integer idx := 1) runs on test_CT return IMS_ConnHdlrPars {
	var template (value) IMS_CallPars cp := t_IMS_CallPars(mp_local_ims_host, 1234 + 2*idx);
	var template (value) IMS_ConnHdlrPars pars := t_IMS_Pars(mp_local_ims_host,
								 mp_local_ims_port,
								 mp_ims_domain,
								 mp_ims_imsi,
								 cp := cp);
	return valueof(pars);
}

/* Initialize connection towards Asterisk AMI */
private function f_init_ami() runs on test_CT {
	var charstring id := "Asterisk_Tests_AMI_EMU";
	vc_AMI := AMI_Adapter_CT.create(id) alive;
	connect(self:AMI_CLIENT, vc_AMI:CLIENT);

	var AMI_Adapter_Parameters ami_pars := {
		remote_host := mp_ami_remote_host,
		remote_port := mp_ami_remote_port,
		local_host := mp_ami_local_host,
		local_port := mp_ami_local_port,
		welcome_str := c_default_AMI_Adapter_pars.welcome_str
	};
	vc_AMI.start(f_AMI_Adapter_main(ami_pars));

	f_ami_action_login(AMI_CLIENT, mp_ami_user, mp_ami_secret);

	timer tReady;
	tReady.start(10.0);
	alt {
	[] AMI_CLIENT.receive(tr_AMI_Event_FullyBooted);
	[] as_ami_rx_ignore(AMI_CLIENT);
	[] tReady.timeout {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
					log2str("AMI FullyBooted timeout: "));
		}
	}
}

/* Local SIP UAs */
private function f_init_sip_local() runs on test_CT {
	var charstring id := "Asterisk_Tests_LOCAL_SIP_EMU";
	f_init_sip(vc_SIP, id);
}

/* IMS Server connection */
private function f_init_sip_ims() runs on test_CT {
	var charstring id := "Asterisk_Tests_IMS_SIP_EMU";
	f_init_sip(vc_IMS, id);
}

function f_init() runs on test_CT {
	var charstring id;

	f_init_ami();
	f_init_sip_local();
	f_init_sip_ims();
	log("end of f_init");
}

function f_shutdown() runs on test_CT {
	/* Tear down AMI Adapter to avoid it keep receiving data from Asterisk
	 * and sending it to us after we stopped, causing error (Broken Pipe): */
	vc_AMI.stop;
	vc_AMI.done;
	log("end of ", testcasename());
	setverdict(pass);
}

function f_start_handler(void_fn fn, SIPConnHdlrPars pars)
runs on test_CT return SIPConnHdlr {
	var SIPConnHdlr vc_conn;
	var charstring id := testcasename() & "-ConnHdlr-" & pars.user;

	vc_conn := SIPConnHdlr.create(id) alive;

	connect(vc_conn:SIP, vc_SIP:CLIENT);
	connect(vc_conn:SIP_PROC, vc_SIP:CLIENT_PROC);

	connect(vc_conn:COORD, self:COORD);

	vc_conn.start(f_handler_init(fn, id, pars));
	return vc_conn;
}

function f_start_handler_IMS(ims_void_fn fn, IMS_ConnHdlrPars pars)
runs on test_CT return IMS_ConnHdlr {
	var IMS_ConnHdlr vc_conn;
	var charstring id := testcasename() & "-IMS_ConnHdlr-" & pars.subscr.imsi;

	vc_conn := IMS_ConnHdlr.create(id) alive;

	connect(vc_conn:SIP, vc_IMS:CLIENT);
	connect(vc_conn:SIP_PROC, vc_IMS:CLIENT_PROC);

	connect(vc_conn:COORD, self:IMS_COORD);

	vc_conn.start(f_ims_handler_init(fn, id, pars));
	return vc_conn;
}

/* Test SIP registration of local clients */
private function f_TC_internal_registration(charstring id) runs on SIPConnHdlr {

	f_SIP_register();
	// f_SIP_deregister();
	setverdict(pass);
}
testcase TC_internal_registration() runs on test_CT {
	var SIPConnHdlrPars pars;
	var SIPConnHdlr vc_conn;
	f_init();
	pars := f_init_ConnHdlrPars();
	vc_conn := f_start_handler(refers(f_TC_internal_registration), pars);
	vc_conn.done;
	f_shutdown();
}

/* Successful SIP MO-MT Call between local clients: */
private function f_TC_internal_call_mo(charstring id) runs on SIPConnHdlr {

	f_SIP_register();
	COORD.send(COORD_CMD_REGISTERED);

	COORD.receive(COORD_CMD_START);
	f_SIP_mo_call_setup();
	COORD.send(COORD_CMD_CALL_ESTABLISHED);

	COORD.receive(COORD_CMD_HANGUP);
	f_SIP_do_call_hangup();

	setverdict(pass);
}
private function f_TC_internal_call_mt(charstring id) runs on SIPConnHdlr {

	f_create_sip_expect(valueof(ts_SipUrl_from_Addr_Union(g_pars.cp.called.addr)));

	f_SIP_register();
	COORD.send(COORD_CMD_REGISTERED);

	if (g_pars.cp.mt.exp_cancel) {
		as_SIP_mt_call_cancelled();
		COORD.send(COORD_CMD_CALL_CANCELLED);
		setverdict(pass);
		return;
	}

	as_SIP_mt_call_accept(exp_update_to_direct_rtp := g_pars.cp.exp_update_to_direct_rtp);
	COORD.send(COORD_CMD_CALL_ESTABLISHED);

	if (g_pars.cp.exp_update_to_direct_rtp) {
		/* Once MO hangs up, Asterisk updates us to point RTP to it: */
		as_SIP_exp_call_update(g_pars.cp.sip_seq_nr + 1);
	}
	as_SIP_exp_call_hangup(g_pars.cp.sip_seq_nr + 1);

	setverdict(pass);
}
testcase TC_internal_call_momt() runs on test_CT {
	var SIPConnHdlrPars pars[2];
	var SIPConnHdlr vc_conn[2];

	f_init();

	pars[0] := f_init_ConnHdlrPars(idx := 1);
	pars[1] := f_init_ConnHdlrPars(idx := 2);

	pars[0].cp.calling := pars[0].registrar_sip_record;
	pars[0].cp.called := pars[1].registrar_sip_record;

	pars[1].cp.calling := pars[0].registrar_sip_record;
	pars[1].cp.called := pars[1].local_sip_record;

	vc_conn[0] := f_start_handler(refers(f_TC_internal_call_mo), pars[0]);
	vc_conn[1] := f_start_handler(refers(f_TC_internal_call_mt), pars[1]);

	interleave {
	[] COORD.receive(COORD_CMD_REGISTERED) from vc_conn[0];
	[] COORD.receive(COORD_CMD_REGISTERED) from vc_conn[1];
	}

	COORD.send(COORD_CMD_START) to vc_conn[0];

	interleave {
	[] COORD.receive(COORD_CMD_CALL_ESTABLISHED) from vc_conn[0];
	[] COORD.receive(COORD_CMD_CALL_ESTABLISHED) from vc_conn[1];
	}

	/* Call on-going */
	f_sleep(1.0);

	COORD.send(COORD_CMD_HANGUP) to vc_conn[0];


	vc_conn[0].done;
	vc_conn[1].done;
	f_shutdown();
}

/* One of the users calls (INVITE) shared extension, which makes all other user
 * equipments ring (INVITE). The first one to pick up the call (OK 200) gets the
 * call established (ACK), others get a CANCEL event. */
private function TC_internal_call_all_Nregistered(integer num_conns := 2) runs on test_CT {
	var SIPConnHdlrList vc_conn_list := {};
	const integer vc_conn_mo_idx := 0; /* Index of MO leg in vc_conn_list */
	const integer vc_conn_mt_idx := 1; /* Index of MT leg in vc_conn_list, peer picking up first the call */
	var SipAddr broadcast_sip_record;
	var SIPConnHdlrPars pars_mo;

	f_init();

	broadcast_sip_record := valueof(ts_SipAddr(ts_HostPort(mp_local_sip_host),
					ts_UserInfo(broadcast_sip_extension)));

	for (var integer i := 0; i < num_conns; i := i + 1) {
		var SIPConnHdlrPars pars;
		var SIPConnHdlr vc_conn;
		pars := f_init_ConnHdlrPars(idx := i + 1);
		if (i == vc_conn_mo_idx) { /* MO */
			pars.cp.calling := pars.registrar_sip_record;
			pars.cp.called := broadcast_sip_record;
			vc_conn := f_start_handler(refers(f_TC_internal_call_mo), pars);
			pars_mo := pars;
		} else { /* MT */
			pars.cp.calling := pars_mo.registrar_sip_record;
			pars.cp.called := pars.local_sip_record;
			pars.cp.mt.wait_coord_cmd_pickup := true;
			if (i != vc_conn_mt_idx) {
				/* Only first MT picking up (OK 200 INVITE) will be ACKed, others CANCELed: */
				pars.cp.mt.exp_cancel := true;
			}
			vc_conn := f_start_handler(refers(f_TC_internal_call_mt), pars);
		}
		vc_conn_list := vc_conn_list & { vc_conn };
	}

	/* Wait all users are registered: */
	for (var integer i := 0; i < num_conns; i := i + 1) {
		/* Note: "from vc_conn_list[i]" can't be used since they may arrive from components in any order: */
		COORD.receive(COORD_CMD_REGISTERED);
	}

	/* Ask MO user to start the call: */
	COORD.send(COORD_CMD_START) to vc_conn_list[vc_conn_mo_idx];

	/* Make sure the desired MT is the one picking up first the call: */
	COORD.send(COORD_CMD_PICKUP) to vc_conn_list[vc_conn_mt_idx];
	interleave {
	[] COORD.receive(COORD_CMD_CALL_ESTABLISHED) from vc_conn_list[vc_conn_mo_idx];
	[] COORD.receive(COORD_CMD_CALL_ESTABLISHED) from vc_conn_list[vc_conn_mt_idx];
	}

	/* Pick up from other phone calls and expect CANCEL: */
	for (var integer i := 0; i < num_conns; i := i + 1) {
		if (i != vc_conn_mo_idx and i != vc_conn_mt_idx) {
			COORD.send(COORD_CMD_PICKUP) to vc_conn_list[i];
			COORD.receive(COORD_CMD_CALL_CANCELLED) from vc_conn_list[i];
		}
	}

	/* Call on-going */
	f_sleep(1.0);

	COORD.send(COORD_CMD_HANGUP) to vc_conn_list[vc_conn_mo_idx];

	for (var integer i := 0; i < num_conns; i := i + 1) {
		vc_conn_list[i].done;
	}
	f_shutdown();
}
testcase TC_internal_call_all_2registered() runs on test_CT {
	TC_internal_call_all_Nregistered(2);
}
testcase TC_internal_call_all_3registered() runs on test_CT {
	TC_internal_call_all_Nregistered(3);
}
testcase TC_internal_call_all_4registered() runs on test_CT {
	TC_internal_call_all_Nregistered(4);
}

testcase TC_selftest() runs on test_CT {
	f_ami_selftest();
	f_sip_digest_selftest();
	setverdict(pass);
}

private function f_AMI_IMS_start_register(IMS_ConnHdlrPars pars) runs on test_CT
{
	/* Give some time for IMS_ConnHdlr to register SIP expect. This could be done through IMS_COORD. */
	f_sleep(1.0);
	/* Clear events: */
	AMI_CLIENT.clear;

	/* Announce network information, this should usually happen when UE
	 * becomes attached to network and before IMS APN is set up: */
	f_ami_action_PJSIPAccessNetworkInfo(AMI_CLIENT, mp_volte_ims_outbound_registration,
					    f_ami_gen_PJSIPAccessNetworkInfo_Info_EUTRAN(pars.subscr.uli_str));

	/* Trigger registration: */
	f_ami_action_PJSIPRegister(AMI_CLIENT, mp_volte_ims_outbound_registration);
}

private altstep as_AMI_IMS_register_Auth(IMS_ConnHdlrPars pars, boolean resync := false) runs on test_CT
{
	var charstring rand_str := oct2str(pars.subscr.auth.rand);
	var charstring autn_str := oct2str(pars.subscr.auth.autn);
	[not resync] AMI_CLIENT.receive(tr_AMI_Event_AuthRequest(mp_volte_ims_outbound_registration,
						    rand := pattern @nocase rand_str,
						    autn := pattern @nocase autn_str)) {
		f_ami_action_AuthResponse_RES(AMI_CLIENT,
					mp_volte_ims_outbound_registration,
					f_str_tolower(oct2str(pars.subscr.auth.res)),
					f_str_tolower(oct2str(pars.subscr.auth.ck)),
					f_str_tolower(oct2str(pars.subscr.auth.ik)));

		AMI_CLIENT.receive(tr_AMI_Event_Registry(f_sip_SipAddr_to_str(pars.subscr.local_sip_record),
							"sip:" & mp_ims_domain,
							"Registered"));
	}
	[resync] AMI_CLIENT.receive(tr_AMI_Event_AuthRequest(mp_volte_ims_outbound_registration,
						    rand := pattern @nocase rand_str,
						    autn := pattern @nocase autn_str)) {
		f_ami_action_AuthResponse_AUTS(AMI_CLIENT,
				mp_volte_ims_outbound_registration,
				f_str_tolower(oct2str(pars.subscr.auth.auts)));
	}
}

private function f_AMI_IMS_register(IMS_ConnHdlrPars pars, boolean resync := false) runs on test_CT
{
	f_AMI_IMS_start_register(pars);
	as_AMI_IMS_register_Auth(pars, resync := resync);
}

private function f_AMI_IMS_unregister(IMS_ConnHdlrPars pars) runs on test_CT
{
	f_ami_action_PJSIPUnregister(AMI_CLIENT, mp_volte_ims_outbound_registration);
	AMI_CLIENT.receive(tr_AMI_Event_Registry(f_sip_SipAddr_to_str(pars.subscr.local_sip_record),
						"sip:" & mp_ims_domain,
						"Unregistered"));
}

/* Test IMS registration of VoLTE UE */
private function f_TC_ims_registration(charstring id) runs on IMS_ConnHdlr {
	f_create_sip_expect(valueof(ts_SipUrl_from_Addr_Union(g_pars.subscr.registrar_sip_record.addr)));
	as_IMS_register();
	as_IMS_unregister();
	setverdict(pass);
}
testcase TC_ims_registration() runs on test_CT {
	var IMS_ConnHdlrPars pars;
	var IMS_ConnHdlr vc_conn;
	f_init();
	pars := f_init_IMS_ConnHdlrPars();
	vc_conn := f_start_handler_IMS(refers(f_TC_ims_registration), pars);

	f_AMI_IMS_register(pars);

	/* Stay registered for one second */
	f_sleep(1.0);

	/* Trigger unregistration: */
	f_AMI_IMS_unregister(pars);

	vc_conn.done;
	f_shutdown();
}

/* Test IMS registration of VoLTE UE. ISIM Resync case. */
private function f_TC_ims_registration_resync(charstring id) runs on IMS_ConnHdlr {
	f_create_sip_expect(valueof(ts_SipUrl_from_Addr_Union(g_pars.subscr.registrar_sip_record.addr)));
	as_IMS_register(exp_auth_resync := true);
	as_IMS_unregister();
	setverdict(pass);
}
testcase TC_ims_registration_resync() runs on test_CT {
	var IMS_ConnHdlrPars pars;
	var IMS_ConnHdlr vc_conn;
	f_init();
	pars := f_init_IMS_ConnHdlrPars();
	vc_conn := f_start_handler_IMS(refers(f_TC_ims_registration_resync), pars);

	/* Emulate first Auth sync failure: */
	f_AMI_IMS_register(pars, resync := true);
	/* Second auth goes well: */
	as_AMI_IMS_register_Auth(pars, resync := false);
	/* Stay registered for one second */
	f_sleep(1.0);

	/* Trigger unregistration: */
	f_AMI_IMS_unregister(pars);

	vc_conn.done;
	f_shutdown();
}

/* Test SIP registration of local clients */
private function f_TC_ims_call_mo(charstring id) runs on IMS_ConnHdlr {
	f_create_sip_expect(valueof(ts_SipUrl_from_Addr_Union(g_pars.subscr.registrar_sip_record.addr)));
	if (ispresent(g_pars.subscr.cp.called)) {
		f_create_sip_expect(valueof(ts_SipUrl_from_Addr_Union(g_pars.subscr.cp.called.addr)));
	}
	as_IMS_register();
	setverdict(pass);
	as_IMS_mo_call_accept();
	setverdict(pass);
	COORD.send(COORD_CMD_CALL_ESTABLISHED);
	as_IMS_exp_call_hangup(g_pars.subscr.cp.sip_seq_nr + 1);
	setverdict(pass);
	as_IMS_unregister();
}
testcase TC_ims_call_mo() runs on test_CT {
	var SIPConnHdlrPars sip_pars;
	var IMS_ConnHdlrPars ims_pars;
	var SIPConnHdlr vc_conn_sip;
	var IMS_ConnHdlr vc_conn_ims;
	const charstring c_ext_msisdn := "90829";

	f_init();

	sip_pars := f_init_ConnHdlrPars(idx := 1);
	ims_pars := f_init_IMS_ConnHdlrPars();

	sip_pars.cp.calling := sip_pars.registrar_sip_record;
	sip_pars.cp.called := valueof(ts_SipAddr(ts_HostPort(sip_pars.remote_sip_host),
						 ts_UserInfo(c_ext_msisdn)));
	ims_pars.subscr.cp.calling := valueof(ts_SipAddr(ts_HostPort(ims_pars.realm),
							 ts_UserInfo(ims_pars.subscr.msisdn)));
	ims_pars.subscr.cp.called := valueof(ts_SipAddr(ts_HostPort(ims_pars.realm),
							ts_UserInfo(c_ext_msisdn)));

	vc_conn_ims := f_start_handler_IMS(refers(f_TC_ims_call_mo), ims_pars);
	vc_conn_sip := f_start_handler(refers(f_TC_internal_call_mo), sip_pars);

	COORD.receive(COORD_CMD_REGISTERED) from vc_conn_sip;

	f_AMI_IMS_register(ims_pars);

	COORD.send(COORD_CMD_START) to vc_conn_sip;
	COORD.receive(COORD_CMD_CALL_ESTABLISHED) from vc_conn_sip;
	IMS_COORD.receive(COORD_CMD_CALL_ESTABLISHED) from vc_conn_ims;

	/* TODO: "Action: DedicatedBearerStatus" */

	/* Call on-going */
	f_sleep(1.0);

	COORD.send(COORD_CMD_HANGUP) to vc_conn_sip;

	/* Trigger unregistration: */
	f_sleep(1.0);
	AMI_CLIENT.clear;
	f_AMI_IMS_unregister(ims_pars);

	vc_conn_sip.done;
	vc_conn_ims.done;
	f_shutdown();
}

/* Test SIP registration of local clients */
private function f_TC_ims_call_mt(charstring id) runs on IMS_ConnHdlr {
	f_create_sip_expect(valueof(ts_SipUrl_from_Addr_Union(g_pars.subscr.registrar_sip_record.addr)));
	as_IMS_register();
	COORD.send(IMS_COORD_CMD_REGISTERED);
	setverdict(pass);

	COORD.receive(IMS_COORD_CMD_START);
	f_IMS_mt_call_setup();
	setverdict(pass);
	COORD.send(IMS_COORD_CMD_CALL_ESTABLISHED);

	COORD.receive(IMS_COORD_CMD_HANGUP);
	f_IMS_do_call_hangup();
	setverdict(pass);

	as_IMS_unregister();
}
testcase TC_ims_call_mt() runs on test_CT {
	var SIPConnHdlrPars sip_pars;
	var IMS_ConnHdlrPars ims_pars;
	var SIPConnHdlr vc_conn_sip;
	var IMS_ConnHdlr vc_conn_ims;
	const charstring c_ext_msisdn := "90829";

	f_init();

	sip_pars := f_init_ConnHdlrPars(idx := 1);
	ims_pars := f_init_IMS_ConnHdlrPars();

	sip_pars.cp.exp_update_to_direct_rtp := false;
	sip_pars.cp.calling := valueof(ts_SipAddr(ts_HostPort(sip_pars.remote_sip_host),
						 ts_UserInfo(c_ext_msisdn)));
	sip_pars.cp.called := sip_pars.local_sip_record;
	ims_pars.subscr.cp.calling := valueof(ts_SipAddr(ts_HostPort(ims_pars.realm),
							ts_UserInfo(c_ext_msisdn)));
	ims_pars.subscr.cp.called := valueof(ts_SipAddr(ts_HostPort(ims_pars.realm),
							 ts_UserInfo(ims_pars.subscr.msisdn)));

	vc_conn_ims := f_start_handler_IMS(refers(f_TC_ims_call_mt), ims_pars);
	vc_conn_sip := f_start_handler(refers(f_TC_internal_call_mt), sip_pars);

	COORD.receive(COORD_CMD_REGISTERED) from vc_conn_sip;

	f_AMI_IMS_register(ims_pars);
	IMS_COORD.receive(IMS_COORD_CMD_REGISTERED) from vc_conn_ims;

	IMS_COORD.send(IMS_COORD_CMD_START) to vc_conn_ims;
	IMS_COORD.receive(IMS_COORD_CMD_CALL_ESTABLISHED) from vc_conn_ims;
	COORD.receive(COORD_CMD_CALL_ESTABLISHED) from vc_conn_sip;

	/* TODO: "Action: DedicatedBearerStatus" */

	/* Call on-going */
	f_sleep(1.0);

	IMS_COORD.send(IMS_COORD_CMD_HANGUP) to vc_conn_ims;

	/* Trigger unregistration: */
	f_sleep(1.0);
	AMI_CLIENT.clear;
	f_AMI_IMS_unregister(ims_pars);

	vc_conn_sip.done;
	vc_conn_ims.done;
	f_shutdown();
}

control {
	execute( TC_internal_registration() );
	execute( TC_internal_call_momt() );
	execute( TC_internal_call_all_2registered() );
	execute( TC_internal_call_all_3registered() );
	execute( TC_internal_call_all_4registered() );
	execute( TC_ims_registration() );
	execute( TC_ims_registration_resync() );
	execute( TC_ims_call_mo() );
	execute( TC_ims_call_mt() );
}

}
