module SGSN_Tests {

/* Osmocom SGSN test suite in TTCN-3
 * (C) 2018-2019 Harald Welte <laforge@gnumonks.org>
 * (C) 2018-2019 sysmocom - s.f.m.c. GmbH
 * All rights reserved.
 *
 * 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
 */

friend module SGSN_Tests_Iu;

import from General_Types all;
import from Osmocom_Types all;
import from GSM_Types all;
import from Native_Functions all;
import from NS_Types all;
import from NS_Emulation all;
import from BSSGP_Types all;
import from BSSGP_Emulation all;
import from Osmocom_Gb_Types all;
import from SCCPasp_Types all;

import from MobileL3_CommonIE_Types all;
import from MobileL3_GMM_SM_Types all;
import from MobileL3_Types all;
import from L3_Templates all;
import from L3_Common all;

import from GSUP_Emulation all;
import from GSUP_Types all;
import from IPA_Emulation all;

import from RAN_Adapter all;
import from RAN_Emulation all;
import from RANAP_Templates all;
import from RANAP_PDU_Descriptions all;
import from RANAP_IEs all;

import from GTP_Emulation all;
import from GTP_Templates all;
import from GTP_CodecPort all;
import from GTPC_Types all;
import from GTPU_Types all;

import from LLC_Types all;
import from LLC_Templates all;

import from SNDCP_Types all;

import from TELNETasp_PortType all;
import from Osmocom_VTY_Functions all;

import from GSM_RR_Types all;

import from MobileL3_MM_Types all;


modulepar {
	/* IP/port on which we run our internal GSUP/HLR emulation */
	charstring mp_hlr_ip := "127.0.0.1";
	integer mp_hlr_port := 4222;
	charstring mp_ggsn_ip := "127.0.0.2";
	integer mp_echo_interval := 5; /* in seconds. Only used in test enabling g_use_echo  */

	NSConfigurations mp_nsconfig := {
		{
			local_udp_port := 21010,
			local_ip := "127.0.0.1",
			remote_udp_port := 23000,
			remote_ip := "127.0.0.1",
			nsvci := 97,
			nsei := 96,
			role_sgsn := false,
			handle_sns := false
		},
		{
			local_udp_port := 21011,
			local_ip := "127.0.0.1",
			remote_udp_port := 23000,
			remote_ip := "127.0.0.1",
			nsvci := 98,
			nsei := 97,
			role_sgsn := false,
			handle_sns := false
		},
		{
			local_udp_port := 21012,
			local_ip := "127.0.0.1",
			remote_udp_port := 23000,
			remote_ip := "127.0.0.1",
			nsvci := 99,
			nsei := 98,
			role_sgsn := false,
			handle_sns := false
		}
	};

	RAN_Configurations mp_ranap_cfg := {
		{
			transport := RANAP_TRANSPORT_IuCS,
			sccp_service_type := "mtp3_itu",
			sctp_addr := { 23908, "127.0.0.1", 2905, "127.0.0.1" },
			own_pc := 195,
			own_ssn := 142,
			peer_pc := 188, /* 0.23.4 */
			peer_ssn := 142,
			sio := '83'O,
			rctx := 2
		}
	}
};

type record GbInstance {
	NS_CT vc_NS,
	BSSGP_CT vc_BSSGP,
	BssgpConfig cfg
};

const integer NUM_GB := 3;
type record length(NUM_GB) of GbInstance GbInstances;
type record length(NUM_GB) of NSConfiguration NSConfigurations;
type record length(NUM_GB) of BssgpCellId BssgpCellIds;

const integer NUM_RNC := 1;
type record of RAN_Configuration RAN_Configurations;

type component test_CT {
	var GbInstances g_gb;
	var RAN_Adapter g_ranap[NUM_RNC];
	var boolean g_ranap_enable := false;

	var GSUP_Emulation_CT vc_GSUP;
	var IPA_Emulation_CT vc_GSUP_IPA;
	/* only to get events from IPA underneath GSUP */
	port IPA_CTRL_PT GSUP_IPA_EVENT;

	var GTP_Emulation_CT vc_GTP;

	port TELNETasp_PT SGSNVTY;

	var boolean g_initialized := false;
	var boolean g_use_echo := false;
};

type component BSSGP_ConnHdlr extends BSSGP_Client_CT, GSUP_ConnHdlr, GTP_ConnHdlr, RAN_ConnHdlr {
	var BSSGP_ConnHdlrPars g_pars;
	timer g_Tguard;
	var LLC_Entities llc;
}

type record SGSN_ConnHdlrNetworkPars {
	boolean expect_ptmsi,
	boolean expect_auth,
	boolean expect_ciph
};

type record BSSGP_ConnHdlrPars {
	/* IMEI of the simulated ME */
	hexstring imei,
	/* IMSI of the simulated MS */
	hexstring imsi,
	/* MSISDN of the simulated MS (probably unused) */
	hexstring msisdn,
	/* P-TMSI allocated to the simulated MS */
	OCT4 p_tmsi optional,
	OCT3 p_tmsi_sig optional,
	/* TLLI of the simulated MS */
	OCT4 tlli,
	OCT4 tlli_old optional,
	RoutingAreaIdentificationV ra optional,
	BssgpCellIds bssgp_cell_id,
	/* Tracks the RNC state. If true next L3 message will be sent with InitiualUe */
	boolean rnc_send_initial_ue,
	AuthVector vec optional,
	SGSN_ConnHdlrNetworkPars net,
	float t_guard,
	/* only in IuPS / RANAP case */
	SCCP_PAR_Address sccp_addr_local optional,
	SCCP_PAR_Address sccp_addr_peer optional
};

private function f_cellid_to_RAI(in BssgpCellId cell_id) return RoutingAreaIdentificationV {
	/* mcc_mnc is encoded as of 24.008 10.5.5.15 */
	var BcdMccMnc mcc_mnc := cell_id.ra_id.lai.mcc_mnc;

        var RoutingAreaIdentificationV ret := {
                mccDigit1 := mcc_mnc[0],
                mccDigit2 := mcc_mnc[1],
                mccDigit3 := mcc_mnc[2],
                mncDigit3 := mcc_mnc[3],
                mncDigit1 := mcc_mnc[4],
                mncDigit2 := mcc_mnc[5],
                lac := int2oct(cell_id.ra_id.lai.lac, 16),
                rac := int2oct(cell_id.ra_id.rac, 8)
        }
        return ret;
};

private function f_init_gb(inout GbInstance gb, charstring id, integer offset) runs on test_CT {
	gb.vc_NS := NS_CT.create(id & "-NS" & int2str(offset));
	gb.vc_BSSGP := BSSGP_CT.create(id & "-BSSGP" & int2str(offset));
	/* connect lower end of BSSGP emulation with NS upper port */
	connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP);

	gb.vc_NS.start(NSStart(mp_nsconfig[offset]));
	gb.vc_BSSGP.start(BssgpStart(gb.cfg));
}

private function f_init_gsup(charstring id) runs on test_CT {
	id := id & "-GSUP";
	var GsupOps ops := {
		create_cb := refers(GSUP_Emulation.ExpectedCreateCallback)
	};

	vc_GSUP_IPA := IPA_Emulation_CT.create(id & "-IPA");
	vc_GSUP := GSUP_Emulation_CT.create(id);

	map(vc_GSUP_IPA:IPA_PORT, system:IPA_CODEC_PT);
	connect(vc_GSUP:GSUP, vc_GSUP_IPA:IPA_GSUP_PORT);
	/* we use this hack to get events like ASP_IPA_EVENT_UP */
	connect(vc_GSUP_IPA:IPA_CTRL_PORT, self:GSUP_IPA_EVENT);

	vc_GSUP.start(GSUP_Emulation.main(ops, id));
	vc_GSUP_IPA.start(IPA_Emulation.main_server(mp_hlr_ip, mp_hlr_port));

	/* wait for incoming connection to GSUP port before proceeding */
	timer T := 10.0;
	T.start;
	alt {
		[] GSUP_IPA_EVENT.receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_UP)) { }
		[] T.timeout {
			setverdict(fail, "No connection to GSUP Port");
			mtc.stop;
		}
	}
}

private function f_init_gtp(charstring id) runs on test_CT {
	id := id & "-GTP";

	var GtpEmulationCfg gtp_cfg := {
		gtpc_bind_ip := mp_ggsn_ip,
		gtpc_bind_port := GTP1C_PORT,
		gtpu_bind_ip := mp_ggsn_ip,
		gtpu_bind_port := GTP1U_PORT,
		sgsn_role := false
	};

	vc_GTP := GTP_Emulation_CT.create(id);
	vc_GTP.start(GTP_Emulation.main(gtp_cfg));
}

private function f_init_vty() runs on test_CT {
	map(self:SGSNVTY, system:SGSNVTY);
	f_vty_set_prompts(SGSNVTY);
	f_vty_transceive(SGSNVTY, "enable");
	f_vty_transceive(SGSNVTY, "reset sgsn state");
	f_vty_config(SGSNVTY, "sgsn", "auth-policy remote");
}

private function f_vty_enable_echo_interval(boolean enable) runs on test_CT {
	if (enable) {
		f_vty_config(SGSNVTY, "sgsn", "ggsn 0 echo-interval " & int2str(mp_echo_interval));
	} else {
		f_vty_config(SGSNVTY, "sgsn", "ggsn 0 no echo-interval");
	}
}


/* mcc_mnc is 24.008 10.5.5.15 encoded. 262 42 */
function f_init(BcdMccMnc mcc_mnc := '262F42'H) runs on test_CT {
	var integer i;

	if (g_initialized == true) {
		return;
	}
	g_initialized := true;
	g_gb[0].cfg := {
		nsei := 96,
		bvci := 196,
		cell_id := {
			ra_id := {
				lai := {
					mcc_mnc := mcc_mnc, lac := 13135},
					rac := 0
				},
			cell_id := 20960
		},
		sgsn_role := false,
		depth := BSSGP_DECODE_DEPTH_L3
	};
	g_gb[1].cfg := {
		nsei := 97,
		bvci := 210,
		cell_id := {
			ra_id := {
				lai := {
					mcc_mnc := mcc_mnc, lac := 13200},
					rac := 0
				},
			cell_id := 20961
		},
		sgsn_role := false,
		depth := BSSGP_DECODE_DEPTH_L3
	};
	g_gb[2].cfg := {
		nsei := 98,
		bvci := 220,
		cell_id := {
			ra_id := {
				lai := {
					mcc_mnc := mcc_mnc, lac := 13300},
					rac := 0
				},
			cell_id := 20962
		},
		sgsn_role := false,
		depth := BSSGP_DECODE_DEPTH_L3
	};

	f_init_vty();
	f_init_gb(g_gb[0], "SGSN_Test-Gb0", 0);
	f_init_gb(g_gb[1], "SGSN_Test-Gb1", 1);
	f_init_gb(g_gb[2], "SGSN_Test-Gb2", 2);

	if (g_ranap_enable) {
		for (i := 0; i < NUM_RNC; i := i+1) {
			f_ran_adapter_init(g_ranap[i], mp_ranap_cfg[i], "SGSN_Test_" & int2str(i), RNC_RanOps);
			f_ran_adapter_start(g_ranap[i]);
		}
	}
	f_init_gsup("SGSN_Test");
	f_init_gtp("SGSN_Test");
	f_vty_enable_echo_interval(g_use_echo);
}

function f_cleanup() runs on test_CT {
	var integer i;
	if (g_ranap_enable) {
		for (i := 0; i < NUM_RNC; i := i+1) {
			f_ran_adapter_cleanup(g_ranap[i]);
		}
	}
	self.stop;
}

private function RncUnitdataCallback(RANAP_PDU ranap)
runs on RAN_Emulation_CT return template RANAP_PDU {
	var template RANAP_PDU resp := omit;

	log ("RANAP_RncUnitDataCallback");
	/* answer all RESET with RESET ACK */
	if (match(ranap, tr_RANAP_Reset)) {
		log("RANAP_RncUnitdataCallback: Responding to RESET with RESET-ACK");
		var CN_DomainIndicator dom;
		dom := ranap.initiatingMessage.value_.Reset.protocolIEs[1].value_.cN_DomainIndicator;
		resp := ts_RANAP_ResetAck(dom);
	}
	return resp;
}

const RanOps RNC_RanOps := {
	ranap_create_cb := refers(RAN_Emulation.RanapExpectedCreateCallback),
	ranap_unitdata_cb := refers(RncUnitdataCallback),
	ps_domain := true,
	decode_dtap := true,
	role_ms := true,
	protocol := RAN_PROTOCOL_RANAP,
	transport := RANAP_TRANSPORT_IuCS,
	use_osmux := false,
	sccp_addr_local := omit,
	sccp_addr_peer := omit
};

type function void_fn(charstring id) runs on BSSGP_ConnHdlr;

/* helper function to create, connect and start a BSSGP_ConnHdlr component */
function f_start_handler(void_fn fn, charstring id, GbInstances gb, integer imsi_suffix,
			 float t_guard := 30.0)
runs on test_CT return BSSGP_ConnHdlr {
	var BSSGP_ConnHdlr vc_conn;
	var SGSN_ConnHdlrNetworkPars net_pars := {
		expect_ptmsi := true,
		expect_auth := true,
		expect_ciph := false
	};
	var BSSGP_ConnHdlrPars pars := {
		imei := f_gen_imei(imsi_suffix),
		imsi := f_gen_imsi(imsi_suffix),
		msisdn := f_gen_msisdn(imsi_suffix),
		p_tmsi := omit,
		p_tmsi_sig := omit,
		tlli := f_gprs_tlli_random(),
		tlli_old := omit,
		ra := omit,
		bssgp_cell_id := { gb[0].cfg.cell_id, gb[1].cfg.cell_id, gb[2].cfg.cell_id },
		rnc_send_initial_ue := true,
		vec := omit,
		net := net_pars,
		t_guard := t_guard,
		sccp_addr_local := omit,
		sccp_addr_peer := omit
	};

	if (g_ranap_enable) {
		pars.sccp_addr_local := g_ranap[0].sccp_addr_own;
		pars.sccp_addr_peer := g_ranap[0].sccp_addr_peer;
	}

	vc_conn := BSSGP_ConnHdlr.create(id);
	connect(vc_conn:BSSGP[0], gb[0].vc_BSSGP:BSSGP_SP);
	connect(vc_conn:BSSGP_SIG[0], gb[0].vc_BSSGP:BSSGP_SP_SIG);
	connect(vc_conn:BSSGP_PROC[0], gb[0].vc_BSSGP:BSSGP_PROC);
	connect(vc_conn:BSSGP[1], gb[1].vc_BSSGP:BSSGP_SP);
	connect(vc_conn:BSSGP_SIG[1], gb[1].vc_BSSGP:BSSGP_SP_SIG);
	connect(vc_conn:BSSGP_PROC[1], gb[1].vc_BSSGP:BSSGP_PROC);
	connect(vc_conn:BSSGP[2], gb[2].vc_BSSGP:BSSGP_SP);
	connect(vc_conn:BSSGP_SIG[2], gb[2].vc_BSSGP:BSSGP_SP_SIG);
	connect(vc_conn:BSSGP_PROC[2], gb[2].vc_BSSGP:BSSGP_PROC);

	/* FIXME: support multiple RNCs */
	if (g_ranap_enable) {
		connect(vc_conn:BSSAP, g_ranap[0].vc_RAN:CLIENT);
		connect(vc_conn:BSSAP_PROC, g_ranap[0].vc_RAN:PROC);
	}

	connect(vc_conn:GSUP, vc_GSUP:GSUP_CLIENT);
	connect(vc_conn:GSUP_PROC, vc_GSUP:GSUP_PROC);

	connect(vc_conn:GTP, vc_GTP:CLIENT);
	connect(vc_conn:GTP_PROC, vc_GTP:CLIENT_PROC);

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

private altstep as_Tguard() runs on BSSGP_ConnHdlr {
	[] g_Tguard.timeout {
		setverdict(fail, "Tguard timeout");
		mtc.stop;
	}
}

/* first function called in every ConnHdlr */
private function f_handler_init(void_fn fn, charstring id, BSSGP_ConnHdlrPars pars)
runs on BSSGP_ConnHdlr {
	/* do some common stuff like setting up g_pars */
	g_pars := pars;

	llc := f_llc_create(false);

	/* register with BSSGP core */
	f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[0]);
	/* tell GSUP dispatcher to send this IMSI to us */
	f_create_gsup_expect(hex2str(g_pars.imsi));
	/* tell GTP dispatcher to send this IMSI to us */
	f_gtp_register_imsi(g_pars.imsi);

	g_Tguard.start(pars.t_guard);
	activate(as_Tguard());

	/* call the user-supplied test case function */
	fn.apply(id);
	f_bssgp_client_unregister(g_pars.imsi);
}

/* TODO:
   * Detach without Attach
   * SM procedures without attach / RAU
   * ATTACH / RAU
   ** with / without authentication
   ** with / without P-TMSI allocation
   * re-transmissions of LLC frames
   * PDP Context activation
   ** with different GGSN config in SGSN VTY
   ** with different PDP context type (v4/v6/v46)
   ** timeout from GGSN
   ** multiple / secondary PDP context
 */

testcase TC_wait_ns_up() runs on test_CT {
	f_init();
	f_sleep(20.0);
	f_cleanup();
}

friend function is_gb(integer ran_index) return boolean {
	return ran_index < NUM_GB;
}
friend function is_iu(integer ran_index) return boolean {
	return ran_index >= NUM_GB;
}

function f_send_llc(template (value) PDU_LLC llc_pdu, integer ran_index := 0) runs on BSSGP_ConnHdlr {
	var octetstring llc_enc := enc_PDU_LLC(valueof(llc_pdu));
	BSSGP[ran_index].send(ts_BSSGP_UL_UD(g_pars.tlli, g_pars.bssgp_cell_id[ran_index], llc_enc));
}

private function f_send_l3_gmm_llc(template (value) PDU_L3_MS_SGSN l3_mo, integer ran_index := 0) runs on BSSGP_ConnHdlr {
	var octetstring l3_enc := enc_PDU_L3_MS_SGSN(valueof(l3_mo));
	var BIT4 sapi := f_llc_sapi_by_l3_mo(valueof(l3_mo));
	var integer n_u := f_llc_get_n_u_tx(llc[bit2int(sapi)]);
	f_send_llc(ts_LLC_UI(l3_enc, sapi, '0'B, n_u), ran_index);
}

/* trigger sending of a RANAP InitialUE and wait for SCCP connection confirmation */
function f_send_l3_initial_ue(template (value) PDU_L3_MS_SGSN l3_mo) runs on BSSGP_ConnHdlr {
	log("Sending InitialUE: ", l3_mo);
	var octetstring l3_enc := enc_PDU_L3_MS_SGSN(valueof(l3_mo));
	var RANAP_PDU ranap;
	var LAI lai := {
		pLMNidentity := '62F224'O,
		lAC := '1234'O,
		iE_Extensions := omit
	};
	var SAI sai := {
		pLMNidentity := lai.pLMNidentity,
		lAC := lai.lAC,
		sAC := '0000'O, /* FIXME */
		iE_Extensions := omit
	};
	var IuSignallingConnectionIdentifier sigc_id := int2bit(23, 24); /* FIXME */
	var GlobalRNC_ID grnc_id := {
		pLMNidentity := lai.pLMNidentity,
		rNC_ID := 2342 /* FIXME */
	};

	ranap := valueof(ts_RANAP_initialUE_CS(lai, sai, l3_enc, sigc_id, grnc_id));
	BSSAP.send(ts_RANAP_Conn_Req(g_pars.sccp_addr_peer, g_pars.sccp_addr_local, ranap));
	alt {
	[] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND) {}
	[] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {
		setverdict(fail, "DISC.ind from SCCP");
		mtc.stop;
		}
	}
}

/* send a L3 (GMM/SM) message over whatever is the appropriate lower-layer bearer */
function f_send_l3(template (value) PDU_L3_MS_SGSN l3_mo, integer ran_index := 0) runs on BSSGP_ConnHdlr {
	if (is_iu(ran_index)) {
		if (g_pars.rnc_send_initial_ue) {
			g_pars.rnc_send_initial_ue := false;
			f_send_l3_initial_ue(l3_mo);
		} else {
			BSSAP.send(ts_PDU_DTAP_PS_MO(l3_mo));
		}
	} else {
		f_send_l3_gmm_llc(l3_mo, ran_index);
	}
}

altstep as_mm_identity(integer ran_index := 0) runs on BSSGP_ConnHdlr {
	var MobileIdentityLV mi;
	[is_gb(ran_index)] BSSGP[ran_index].receive(tr_GMM_ID_REQ('001'B)) {
		mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
		f_send_l3(ts_GMM_ID_RESP(mi), ran_index);
		repeat;
	}
	[is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_ID_REQ('001'B))) {
		mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
		f_send_l3(ts_GMM_ID_RESP(mi), ran_index);
		repeat;
	}
	[is_gb(ran_index)] BSSGP[ran_index].receive(tr_GMM_ID_REQ('010'B)) {
		mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
		f_send_l3(ts_GMM_ID_RESP(mi), ran_index);
		repeat;
	}
	[is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_ID_REQ('010'B))) {
		mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
		f_send_l3(ts_GMM_ID_RESP(mi), ran_index);
		repeat;
	}
}

/* receive a L3 (GMM/SM) message over whatever is the appropriate lower-layer bearer */
function f_receive_l3(template PDU_L3_SGSN_MS rx_tpl := ?, integer ran_index := 0)
runs on BSSGP_ConnHdlr return PDU_L3_SGSN_MS {
	var PDU_DTAP_PS_MT mt;
	var PDU_L3_SGSN_MS l3_mt;
	alt {
	[is_gb(ran_index)] BSSGP[ran_index].receive(rx_tpl) -> value l3_mt { }
	[is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(rx_tpl)) -> value mt {
		l3_mt := mt.dtap;
		}
	}
	return l3_mt;
}

/* perform GMM authentication (if expected).
 * Note, for umts_aka_challenge to work, the revisionLevelIndicatior needs to
 * be 1 to mark R99 capability, in the GMM Attach Request, see f_gmm_attach(). */
function f_gmm_auth (boolean umts_aka_challenge := false, boolean force_gsm_sres := false, integer ran_index := 0) runs on BSSGP_ConnHdlr {
	var PDU_L3_MS_SGSN l3_mo;
	var PDU_L3_SGSN_MS l3_mt;
	var default di := activate(as_mm_identity(ran_index));
	if (g_pars.net.expect_auth) {
		var GSUP_IE auth_tuple;
		var template AuthenticationParameterAUTNTLV autn;

		if (umts_aka_challenge) {
			g_pars.vec := f_gen_auth_vec_3g();
			autn := {
				elementIdentifier := '28'O,
				lengthIndicator := lengthof(g_pars.vec.autn),
				autnValue := g_pars.vec.autn
				};

			auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
								       g_pars.vec.sres,
								       g_pars.vec.kc,
								       g_pars.vec.ik,
								       g_pars.vec.ck,
								       g_pars.vec.autn,
								       g_pars.vec.res));
			log("GSUP sends 2G and 3G auth tuples", auth_tuple);
		} else {
			g_pars.vec := f_gen_auth_vec_2g();
			autn := omit;
			auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G(g_pars.vec.rand,
								     g_pars.vec.sres,
								     g_pars.vec.kc));
			log("GSUP sends only 2G auth tuple", auth_tuple);
		}

		GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
		GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));

		var template PDU_L3_SGSN_MS auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
		auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
		l3_mt := f_receive_l3(auth_ciph_req, ran_index);
		var BIT4 ac_ref := l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.acReferenceNumber.valueField;
		var template PDU_L3_MS_SGSN auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);

		if (umts_aka_challenge and not force_gsm_sres) {
			/* set UMTS response instead */
			auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationParResp := {
				valueField := substr(g_pars.vec.res, 0, 4)
			};
			auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationRespParExt := {
				elementIdentifier := '21'O,
				lengthIndicator := lengthof(g_pars.vec.res) - 4,
				valueField := substr(g_pars.vec.res, 4, lengthof(g_pars.vec.res) - 4)
			};
		}

		l3_mo := valueof(auth_ciph_resp);
		if (ispresent(l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest) and
		    l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest.valueField == '001'B) {
			l3_mo.msgs.gprs_mm.authenticationAndCipheringResponse.imeisv :=
						valueof(ts_MI_IMEISV_TLV(g_pars.imei & '0'H));
		}
		f_send_l3(l3_mo, ran_index);

		/* Security Mode Command + Complete on Iu case */
		if (is_iu(ran_index)) {
			BSSAP.receive(tr_RANAP_SecurityModeCmd(uia_algs := ?, uia_key := oct2bit(g_pars.vec.ik),
								key_sts := ?)) {
				var IntegrityProtectionAlgorithm uia_chosen := 0; /* 0 = standard_UMTS_integrity_algorithm_UIA1 */
				BSSAP.send(ts_RANAP_SecurityModeComplete(uia_chosen));
				BSSAP.receive(tr_RANAP_CommonId(imsi_hex2oct(g_pars.imsi)))
			}
		}
	} else {
		/* wait for identity procedure */
		f_sleep(1.0);
	}

	deactivate(di);
}

function f_upd_ptmsi_and_tlli(OCT4 p_tmsi, integer ran_index := 0) runs on BSSGP_ConnHdlr {
	g_pars.p_tmsi := p_tmsi;
	/* update TLLI */
	g_pars.tlli_old := g_pars.tlli;
	g_pars.tlli := g_pars.p_tmsi or4b 'c0000000'O;
	if (is_gb(ran_index)) {
		f_bssgp_client_llgmm_assign(g_pars.tlli_old, g_pars.tlli, BSSGP_PROC[ran_index]);
	}
}

function f_process_attach_accept(PDU_GMM_AttachAccept aa) runs on BSSGP_ConnHdlr {
	/* mandatory IE */
	var hexstring aa_plmn := f_RAI_to_plmn_hexstr(aa.routingAreaIdentification);
	if (not (g_pars.bssgp_cell_id[0].ra_id.lai.mcc_mnc == aa_plmn)) {
		  setverdict(fail, "mismatching PLMN in Attach Accept: " & hex2str(aa_plmn)
				   & "; expected " & hex2str(g_pars.bssgp_cell_id[0].ra_id.lai.mcc_mnc));
		  mtc.stop;
	}
	g_pars.ra := aa.routingAreaIdentification;
	if (ispresent(aa.allocatedPTMSI)) {
		if (not g_pars.net.expect_ptmsi) {
			setverdict(fail, "unexpected P-TMSI allocation");
			mtc.stop;
		}
		f_upd_ptmsi_and_tlli(aa.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets);
	}
	if (ispresent(aa.msIdentity)) {
		setverdict(fail, "unexpected TMSI allocation in non-combined attach");
		mtc.stop;
	}
	/* P-TMSI.sig */
	if (ispresent(aa.ptmsiSignature)) {
		g_pars.p_tmsi_sig := aa.ptmsiSignature.valueField;
	}
	/* updateTimer */
	// aa.readyTimer
	/* T3302, T3319, T3323, T3312_ext, T3324 */
}

function f_process_rau_accept(PDU_GMM_RoutingAreaUpdateAccept ra, integer ran_index := 0) runs on BSSGP_ConnHdlr {
	/* mandatory IE */
	g_pars.ra := ra.routingAreaId;
	if (ispresent(ra.allocatedPTMSI)) {
		if (not g_pars.net.expect_ptmsi) {
			setverdict(fail, "unexpected P-TMSI allocation");
			mtc.stop;
		}
		f_upd_ptmsi_and_tlli(ra.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets, ran_index);
	}
	if (ispresent(ra.msIdentity)) {
		setverdict(fail, "unexpected TMSI allocation in non-combined attach");
		mtc.stop;
	}
	/* P-TMSI.sig */
	if (ispresent(ra.ptmsiSignature)) {
		g_pars.p_tmsi_sig := ra.ptmsiSignature.valueField;
	}
	/* updateTimer */
	// aa.readyTimer
	/* T3302, T3319, T3323, T3312_ext, T3324 */
}


function f_random_RAI(HEX0_3n mcc := '262'H, HEX0_3n mnc := '42'H) return RoutingAreaIdentificationV {
	return f_RAI(mcc, mnc, f_rnd_octstring(2), f_rnd_octstring(1));
}

/* return a MobileIdentityLV: P-TMSI if we have one, IMSI otherwise */
private function f_mi_get_lv() runs on BSSGP_ConnHdlr return MobileIdentityLV {
	if (ispresent(g_pars.p_tmsi)) {
		return valueof(ts_MI_TMSI_LV(g_pars.p_tmsi));
	} else {
		return valueof(ts_MI_IMSI_LV(g_pars.imsi));
	}
}

private function f_gmm_gsup_lu_isd() runs on BSSGP_ConnHdlr {
	var GSUP_PDU gsup;
	/* Expect MSC to perform LU with HLR */
	GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
	gsup := valueof(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
	gsup.ies := gsup.ies & { valueof(ts_GSUP_IE_PdpInfo(char2oct("*"), '0121'O, ''O)) };
	GSUP.send(gsup);
	GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi));
	GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
}

friend function f_gmm_attach(boolean umts_aka_challenge, boolean force_gsm_sres, integer ran_index := 0) runs on BSSGP_ConnHdlr {
	var RoutingAreaIdentificationV old_ra := f_random_RAI();
	var template PDU_L3_MS_SGSN attach_req := ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit);
	var PDU_L3_SGSN_MS l3_mt;

	/* indicate R99 capability of the MS to enable UMTS AKA in presence of
	 * 3G auth vectors */
	attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.revisionLevelIndicatior := '1'B;
	/* The thing is, if the solSACapability is 'omit', then the
	 * revisionLevelIndicatior is at the wrong place! */
	attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.solSACapability := '0'B;

	f_send_l3(attach_req, ran_index);
	f_gmm_auth(umts_aka_challenge, force_gsm_sres, ran_index);
	/* Expect SGSN to perform LU with HLR */
	f_gmm_gsup_lu_isd();

	l3_mt := f_receive_l3(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?), ran_index);
	f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);

	/* FIXME: Extract P-TMSI, if any. Only send Complete if necessary */
	f_send_l3(ts_GMM_ATTACH_COMPL, ran_index);

	/* IuPS case: Expect Iu Release */
	if (is_iu(ran_index)) {
		as_iu_release_compl_disc();
	}

	/* Race condition
	 * It has shown, that GMM_ATTACH_COMPL might take some time to arrive at the SGSN through the layers.
	 * In TC hlr_location_cancel_request_update, the GMM_ATTACH_COMPL came 2ms too late, so that the Location Cancel Request
	 * arrived before it. This results in a test case failure.
	 * Delay execution by 50 ms
	 */
	f_sleep(0.05);
}

friend function f_bssgp_suspend(integer ran_idx := 0) runs on BSSGP_ConnHdlr return OCT1 {
	timer T := 5.0;
	var PDU_BSSGP rx_pdu;
	BSSGP_SIG[ran_idx].send(ts_BSSGP_SUSPEND(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id));
	T.start;
	alt {
	[] BSSGP_SIG[ran_idx].receive(tr_BSSGP_SUSPEND_ACK(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id, ?)) -> value rx_pdu {
		return rx_pdu.pDU_BSSGP_SUSPEND_ACK.suspend_Reference_Number.suspend_Reference_Number_value;
		}
	[] BSSGP_SIG[ran_idx].receive(tr_BSSGP_SUSPEND_NACK(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id, ?)) -> value rx_pdu {
		setverdict(fail, "SUSPEND-NACK in response to SUSPEND for TLLI ", g_pars.tlli);
		mtc.stop;
		}
	[] T.timeout {
		setverdict(fail, "No SUSPEND-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
		mtc.stop;
		}
	}
	return '00'O;
}

friend function f_bssgp_resume(OCT1 susp_ref, integer ran_idx := 0) runs on BSSGP_ConnHdlr {
	timer T := 5.0;
	BSSGP_SIG[ran_idx].send(ts_BSSGP_RESUME(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id, susp_ref));
	T.start;
	alt {
	[] BSSGP_SIG[ran_idx].receive(tr_BSSGP_RESUME_ACK(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id));
	[] BSSGP_SIG[ran_idx].receive(tr_BSSGP_RESUME_NACK(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id,
?)) {
		setverdict(fail, "RESUME-NACK in response to RESUME for TLLI ", g_pars.tlli);
		mtc.stop;
		}
	[] T.timeout {
		setverdict(fail, "No RESUME-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
		mtc.stop;
		}
	}
}


private function f_TC_attach(charstring id) runs on BSSGP_ConnHdlr {
	f_gmm_attach(false, false);
	setverdict(pass);
}

testcase TC_attach() runs on test_CT {
	var BSSGP_ConnHdlr vc_conn;
	f_init();
	f_sleep(1.0);
	vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, 1);
	vc_conn.done;
	f_cleanup();
}

testcase TC_attach_mnc3() runs on test_CT {
	var BSSGP_ConnHdlr vc_conn;
	f_init('023042'H);
	f_sleep(1.0);
	vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, 1001);
	vc_conn.done;
	f_cleanup();
}

private function f_TC_attach_umts_aka_umts_res(charstring id) runs on BSSGP_ConnHdlr {
	f_gmm_attach(true, false);
	setverdict(pass);
}
testcase TC_attach_umts_aka_umts_res() runs on test_CT {
	var BSSGP_ConnHdlr vc_conn;
	f_init();
	f_sleep(1.0);
	vc_conn := f_start_handler(refers(f_TC_attach_umts_aka_umts_res), testcasename(), g_gb, 1002);
	vc_conn.done;
	f_cleanup();
}

private function f_TC_attach_umts_aka_gsm_sres(charstring id) runs on BSSGP_ConnHdlr {
	f_gmm_attach(true, true);
	setverdict(pass);
}
testcase TC_attach_umts_aka_gsm_sres() runs on test_CT {
	var BSSGP_ConnHdlr vc_conn;
	f_init();
	f_sleep(1.0);
	vc_conn := f_start_handler(refers(f_TC_attach_umts_aka_gsm_sres), testcasename(), g_gb, 1003);
	vc_conn.done;
	f_cleanup();
}

/* MS never responds to ID REQ, expect ATTACH REJECT */
private function f_TC_attach_auth_id_timeout(charstring id) runs on BSSGP_ConnHdlr {
	var RoutingAreaIdentificationV old_ra := f_random_RAI();

	f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
	alt {
	[] BSSGP[0].receive(tr_GMM_ID_REQ(?)) {
		/* don't send ID Response */
		repeat;
		}
	[] BSSGP[0].receive(tr_GMM_ATTACH_REJECT('09'O)) {
		setverdict(pass);
		}
	[] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
		setverdict(fail, "Wrong Attach Reject Cause");
		mtc.stop;
		}
	}
}
testcase TC_attach_auth_id_timeout() runs on test_CT {
	var BSSGP_ConnHdlr vc_conn;
	f_init();
	vc_conn := f_start_handler(refers(f_TC_attach_auth_id_timeout), testcasename(), g_gb, 2, 40.0);
	vc_conn.done;
	f_cleanup();
}

/* HLR never responds to SAI REQ, expect ATTACH REJECT */
private function f_TC_attach_auth_sai_timeout(charstring id) runs on BSSGP_ConnHdlr {
	var RoutingAreaIdentificationV old_ra := f_random_RAI();

	f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
	alt {
	[] as_mm_identity();
	[] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)); { }
	}
	/* don't send SAI-response from HLR */
	BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?));
	setverdict(pass);
}
testcase TC_attach_auth_sai_timeout() runs on test_CT {
	var BSSGP_ConnHdlr vc_conn;
	f_init();
	vc_conn := f_start_handler(refers(f_TC_attach_auth_sai_timeout), testcasename(), g_gb, 3);
	vc_conn.done;
	f_cleanup();
}

/* HLR rejects SAI, expect ATTACH REJECT */
private function f_TC_attach_auth_sai_reject(charstring id) runs on BSSGP_ConnHdlr {
	var RoutingAreaIdentificationV old_ra := f_random_RAI();

	f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
	alt {
	[] as_mm_identity();
	[] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)); {
		GSUP.send(ts_GSUP_SAI_ERR(g_pars.imsi, 23));
		}
	}
	BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?));
	setverdict(pass);
}
testcase TC_attach_auth_sai_reject() runs on test_CT {
	var BSSGP_ConnHdlr vc_conn;
	f_init();
	vc_conn := f_start_handler(refers(f_TC_attach_auth_sai_reject), testcasename(), g_gb, 4);
	vc_conn.done;
	f_cleanup();
}

/* HLR never responds to UL REQ, expect ATTACH REJECT */
private function f_TC_attach_gsup_lu_timeout(charstring id) runs on BSSGP_ConnHdlr {
	var PDU_L3_SGSN_MS l3_mt;
	var RoutingAreaIdentificationV old_ra := f_random_RAI();

	f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
	f_gmm_auth();
	/* Expect MSC to perform LU with HLR */
	GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
	/* Never follow-up with ISD_REQ or UL_RES */
	alt {
	[] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
		setverdict(pass);
		}
	[] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
		f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
		setverdict(fail);
		mtc.stop;
		}
	}
}
testcase TC_attach_gsup_lu_timeout() runs on test_CT {
	var BSSGP_ConnHdlr vc_conn;
	f_init();
	f_sleep(1.0);
	vc_conn := f_start_handler(refers(f_TC_attach_gsup_lu_timeout), testcasename(), g_gb, 5);
	vc_conn.done;
	f_cleanup();
}

/* HLR rejects UL REQ, expect ATTACH REJECT */
private function f_TC_attach_gsup_lu_reject(charstring id) runs on BSSGP_ConnHdlr {
	var PDU_L3_SGSN_MS l3_mt;
	var RoutingAreaIdentificationV old_ra := f_random_RAI();

	f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
	f_gmm_auth();
	/* Expect MSC to perform LU with HLR */
	GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi)) {
		GSUP.send(ts_GSUP_UL_ERR(g_pars.imsi, 0));
	}
	alt {
	[] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
		setverdict(pass);
		}
	[] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
		f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
		setverdict(fail);
		mtc.stop;
		}
	}
}
testcase TC_attach_gsup_lu_reject() runs on test_CT {
	var BSSGP_ConnHdlr vc_conn;
	f_init();
	f_sleep(1.0);
	vc_conn := f_start_handler(refers(f_TC_attach_gsup_lu_reject), testcasename(), g_gb, 6);
	vc_conn.done;
	f_cleanup();
}


/* Attempt of combined GPRS + IMSI attach: network should ACK only GPRS attach  */
private function f_TC_attach_combined(charstring id) runs on BSSGP_ConnHdlr {
	var PDU_L3_SGSN_MS l3_mt;
	var RoutingAreaIdentificationV old_ra := f_random_RAI();

	f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, true, false, omit, omit));
	f_gmm_auth();
	/* Expect MSC to perform LU with HLR */
	f_gmm_gsup_lu_isd();

	BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
		f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
	}
	f_send_l3(ts_GMM_ATTACH_COMPL);
	setverdict(pass);
}
testcase TC_attach_combined() runs on test_CT {
	var BSSGP_ConnHdlr vc_conn;
	f_init();
	f_sleep(1.0);
	vc_conn := f_start_handler(refers(f_TC_attach_combined), testcasename(), g_gb, 7);
	vc_conn.done;
	f_cleanup();
}

/* Attempt of GPRS ATTACH in 'accept all' mode */
private function f_TC_attach_accept_all(charstring id) runs on BSSGP_ConnHdlr {
	var PDU_L3_SGSN_MS l3_mt;
	var RoutingAreaIdentificationV old_ra := f_random_RAI();

	g_pars.net.expect_auth := false;

	f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
	f_gmm_auth();
	BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
		f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
	}
	f_send_l3(ts_GMM_ATTACH_COMPL);
	setverdict(pass);
}
testcase TC_attach_accept_all() runs on test_CT {
	var BSSGP_ConnHdlr vc_conn;
	f_init();
	f_sleep(1.0);
	f_vty_config(SGSNVTY, "sgsn", "auth-policy accept-all");
	vc_conn := f_start_handler(refers(f_TC_attach_accept_all), testcasename(), g_gb, 8);
	vc_conn.done;
	f_cleanup();
}

/* Attempt of GPRS ATTACH in 'accept all' mode */
private function f_TC_attach_closed_foreign(charstring id) runs on BSSGP_ConnHdlr {
	var RoutingAreaIdentificationV old_ra := f_random_RAI();

	/* Simulate a foreign IMSI */
	g_pars.imsi := '001010123456789'H;
	f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[0]);

	g_pars.net.expect_auth := false;

	f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
	alt {
	[] as_mm_identity();
	[] BSSGP[0].receive(tr_GMM_ATTACH_REJECT('07'O)) {
		setverdict(pass);
		}
	[] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
		setverdict(pass);
		}
	[] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) {
		setverdict(fail);
		mtc.stop;
		}
	}
}
testcase TC_attach_closed() runs on test_CT {
	var BSSGP_ConnHdlr vc_conn;
	f_init();
	f_sleep(1.0);
	f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
	/* test with foreign IMSI: Must Reject */
	vc_conn := f_start_handler(refers(f_TC_attach_closed_foreign), testcasename(), g_gb, 9);
	vc_conn.done;
	/* test with home IMSI: Must Accept */
	vc_conn := f_start_handler(refers(f_TC_attach_accept_all), testcasename(), g_gb, 10);
	vc_conn.done;
	f_cleanup();
}

/* Routing Area Update from Unknown TLLI -> REJECT */
private function f_TC_rau_unknown(charstring id) runs on BSSGP_ConnHdlr {
	var RoutingAreaIdentificationV old_ra := f_random_RAI();

	f_send_l3(ts_GMM_RAU_REQ(f_mi_get_lv(), GPRS_UPD_T_RA, old_ra, false, omit, omit));
	alt {
	[] BSSGP[0].receive(tr_GMM_RAU_REJECT('0a'O)) { /* gmm cause: implicitly detached */
		setverdict(pass);
		}
	/* FIXME: Expect XID RESET? */
	[] BSSGP[0].receive { repeat; }
	}
}
testcase TC_rau_unknown() runs on test_CT {
	var BSSGP_ConnHdlr vc_conn;
	f_init();
	f_sleep(1.0);
	vc_conn := f_start_handler(refers(f_TC_rau_unknown), testcasename(), g_gb, 11);
	vc_conn.done;
	f_cleanup();
}

private function f_TC_attach_rau(charstring id) runs on BSSGP_ConnHdlr {
	/* first perform regular attach */
	f_TC_attach(id);

	f_routing_area_update(g_pars.ra);

}
testcase TC_attach_rau() runs on test_CT {
	var BSSGP_ConnHdlr vc_conn;
	f_init();
	f_sleep(1.0);
	vc_conn := f_start_handler(refers(f_TC_attach_rau), testcasename(), g_gb, 12);
	vc_conn.done;
	f_cleanup();
}

/* general GPRS DETACH helper */
function f_detach_mo(BIT3 detach_type, boolean power_off, boolean expect_purge, integer ran_index := 0) runs on BSSGP_ConnHdlr {
	var PDU_L3_SGSN_MS l3_mt;
	timer T := 5.0;
	f_send_l3(ts_GMM_DET_REQ_MO(detach_type, power_off), ran_index);
	if (expect_purge) {
		GSUP.receive(tr_GSUP_PURGE_MS_REQ(g_pars.imsi, OSMO_GSUP_CN_DOMAIN_PS));
		GSUP.send(ts_GSUP_PURGE_MS_RES(g_pars.imsi));
	}
	T.start;
	alt {
	[not expect_purge] GSUP.receive(tr_GSUP_PURGE_MS_REQ(?)) {
		setverdict(fail, "Unexpected GSUP PURGE MS for unregistered TLLI");
		mtc.stop;
		}
	[power_off] BSSGP[ran_index].receive(tr_GMM_DET_ACCEPT_MT) -> value l3_mt {
		g_pars.ra := omit;
		setverdict(fail, "Unexpected DETACH ACCEPT in power-off DETACH");
		mtc.stop;
		/* TODO: check if any PDP contexts are deactivated on network side? */
		}
	[power_off] T.timeout {
		setverdict(pass);
		}
	[not power_off] BSSGP[ran_index].receive(tr_GMM_DET_ACCEPT_MT) -> value l3_mt {
		g_pars.ra := omit;
		setverdict(pass);
		/* TODO: check if any PDP contexts are deactivated on network side? */
		}
	[] BSSGP[ran_index].receive(PDU_L3_SGSN_MS:?) -> value l3_mt {
		if (power_off) {
			setverdict(fail, "Unexpected Layer 3 package received in power-off DETACH");
		} else {
			setverdict(fail, "Unexpected Layer 3 package received in normal DETACH");
		}
		mtc.stop;
		}
	[] BSSGP[ran_index].receive { repeat; }
	}
}

/* IMSI DETACH (non-power-off) for unknown TLLI */
private function f_TC_detach_unknown_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
	f_detach_mo(c_GMM_DTT_MO_GPRS, false, false);
}
testcase TC_detach_unknown_nopoweroff() runs on test_CT {
	var BSSGP_ConnHdlr vc_conn;
	f_init();
	f_sleep(1.0);
	vc_conn := f_start_handler(refers(f_TC_detach_unknown_nopoweroff), testcasename(), g_gb, 13);
	vc_conn.done;
	f_cleanup();
}

/* IMSI DETACH (power-off) for unknown TLLI */
private function f_TC_detach_unknown_poweroff(charstring id) runs on BSSGP_ConnHdlr {
	f_detach_mo(c_GMM_DTT_MO_GPRS,  true, false);
}
testcase TC_detach_unknown_poweroff() runs on test_CT {
	var BSSGP_ConnHdlr vc_conn;
	f_init();
	f_sleep(1.0);
	vc_conn := f_start_handler(refers(f_TC_detach_unknown_poweroff), testcasename(), g_gb, 14);
	vc_conn.done;
	f_cleanup();
}

/* IMSI DETACH (non-power-off) for known TLLI */
private function f_TC_detach_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
	/* first perform regular attach */
	f_TC_attach(id);

	f_detach_mo(c_GMM_DTT_MO_GPRS, false, true);
}
testcase TC_detach_nopoweroff() runs on test_CT {
	var BSSGP_ConnHdlr vc_conn;
	f_init();
	f_sleep(1.0);
	vc_conn := f_start_handler(refers(f_TC_detach_nopoweroff), testcasename(), g_gb, 15);
	vc_conn.done;
	f_cleanup();
}

/* IMSI DETACH (power-off) for known TLLI */
private function f_TC_detach_poweroff(charstring id) runs on BSSGP_ConnHdlr {
	/* first perform regular attach */
	f_TC_attach(id);

	f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
}
testcase TC_detach_poweroff() runs on test_CT {
	var BSSGP_ConnHdlr vc_conn;
	f_init();
	f_sleep(1.0);
	vc_conn := f_start_handler(refers(f_TC_detach_poweroff), testcasename(), g_gb, 16);
	vc_conn.done;
	f_cleanup();
}

type record PdpActPars {
	BIT3			tid,				/* L3 Transaction ID */
	BIT4			nsapi,				/* SNDCP NSAPI */
	BIT4			sapi,				/* LLC SAPI */
	QoSV			qos,				/* QoS parameters */
	PDPAddressV		addr,				/* IP address */
	octetstring		apn optional,			/* APN name */
	ProtocolConfigOptionsV	pco optional,			/* protoco config opts */
	OCT1			exp_rej_cause optional,		/* expected SM reject cause */
	OCT1			gtp_resp_cause,			/* GTP response cause */
	OCT4			chg_id,				/* GTP Charging Identifier */

	OCT4			ggsn_tei_c,			/* GGSN TEI Control*/
	OCT4			ggsn_tei_u,			/* GGSN TEI User */
	octetstring		ggsn_ip_c,			/* GGSN IP Control */
	octetstring		ggsn_ip_u,			/* GGSN IP User */
	OCT1			ggsn_restart_ctr,		/* GGSN Restart Counter */

	OCT4			sgsn_tei_c optional,		/* SGSN TEI Control */
	OCT4			sgsn_tei_u optional,		/* SGSN TEI User */
	octetstring		sgsn_ip_c optional,		/* SGSN IP Control */
	octetstring		sgsn_ip_u optional		/* SGSN IP USer */
};


private function f_process_gtp_ctx_act_req(inout PdpActPars apars, PDU_GTPC gtpc) runs on BSSGP_ConnHdlr {
	var GTPC_PDUs gtpc_rx := gtpc.gtpc_pdu;
	apars.sgsn_tei_c := gtpc_rx.createPDPContextRequest.teidControlPlane.teidControlPlane;
	apars.sgsn_tei_u := gtpc_rx.createPDPContextRequest.teidDataI.teidDataI;
	apars.sgsn_ip_c := gtpc_rx.createPDPContextRequest.sgsn_addr_signalling.addressf;
	apars.sgsn_ip_u := gtpc_rx.createPDPContextRequest.sgsn_addr_traffic.addressf;
	f_gtp_register_teid(apars.ggsn_tei_c);
	f_gtp_register_teid(apars.ggsn_tei_u);
}

function f_pdp_ctx_act(inout PdpActPars apars, boolean send_recovery := false, integer ran_index := 0)
runs on BSSGP_ConnHdlr {
	var boolean exp_rej := ispresent(apars.exp_rej_cause);
	var Gtp1cUnitdata g_ud;
	var template Recovery_gtpc recovery := omit;

	if (send_recovery) {
		recovery := ts_Recovery(apars.ggsn_restart_ctr);
	}

	f_send_l3(ts_SM_ACT_PDP_REQ(apars.tid, apars.nsapi, apars.sapi, apars.qos, apars.addr,
				     apars.apn, apars.pco), ran_index);
	GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud {
		f_process_gtp_ctx_act_req(apars, g_ud.gtpc);
		var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
		GTP.send(ts_GTPC_CreatePdpResp(g_ud.peer, seq_nr,
						apars.sgsn_tei_c, apars.gtp_resp_cause,
						apars.ggsn_tei_c, apars.ggsn_tei_u,
						apars.nsapi,
						apars.ggsn_ip_c, apars.ggsn_ip_u, apars.chg_id,
						omit, recovery));
	}
	alt {
	[exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_REJ(apars.tid, apars.exp_rej_cause)) {
		setverdict(pass);
		}
	[exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_ACCEPT) {
		setverdict(fail, "Unexpected PDP CTX ACT ACC");
		mtc.stop;
		}
	[not exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_REJ(apars.tid, ?)) {
		setverdict(fail, "Unexpected PDP CTX ACT FAIL");
		mtc.stop;
		}
	[not exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_REJ(apars.tid, ?)) {
		setverdict(fail, "Unexpected PDP CTX ACT FAIL");
		mtc.stop;
		}
	[not exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_ACCEPT(apars.tid, apars.sapi)) {
		setverdict(pass);
		}
	[] as_xid(apars, ran_index);
	}
}

function f_pdp_ctx_deact_mo(inout PdpActPars apars, OCT1 cause, integer ran_index := 0)
runs on BSSGP_ConnHdlr {
	var boolean exp_rej := ispresent(apars.exp_rej_cause);
	var Gtp1cUnitdata g_ud;

	f_send_l3(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause, false, omit), ran_index);
	GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
		var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
		BSSGP[ran_index].clear;
		GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
	}
	alt {
	[] BSSGP[ran_index].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
		setverdict(pass);
		}
	[] as_xid(apars, ran_index);
	}
}

function f_pdp_ctx_deact_mt(inout PdpActPars apars, boolean error_ind := false, integer ran_index := 0)
runs on BSSGP_ConnHdlr {
	var Gtp1cUnitdata g_ud;
	var integer seq_nr := 23;
	var GtpPeer peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));

	BSSGP[ran_index].clear;
	if (error_ind) {
		GTP.send(ts_GTPU_ErrorIndication(peer, 0 /* seq */, apars.ggsn_tei_u, apars.ggsn_ip_u));
	} else {
		GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));
	}

	timer T := 5.0;
	T.start;

	alt {
	[] BSSGP[ran_index].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {
		f_send_l3(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid), ran_index);
		}
	[not error_ind] GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) {
		repeat;
		}
	[] T.timeout {
		setverdict(fail, "Waiting for SM_DEACT_PDP_REQ_MT");
		}
	}
}


/* Table 10.5.156/3GPP TS 24.008 */
template (value) QoSV t_QosDefault := {
	reliabilityClass := '011'B, /* unacknowledged GTP+LLC, acknowledged RLC */
	delayClass := '100'B,	/* best effort */
	spare1 := '00'B,
	precedenceClass := '010'B, /* normal */
	spare2 := '0'B,
	peakThroughput := '0000'B, /* subscribed */
	meanThroughput := '00000'B, /* subscribed */
	spare3 := '000'B,
	deliverErroneusSDU := omit,
	deliveryOrder := omit,
	trafficClass := omit,
	maxSDUSize := omit,
	maxBitrateUplink := omit,
	maxBitrateDownlink := omit,
	sduErrorRatio := omit,
	residualBER := omit,
	trafficHandlingPriority := omit,
	transferDelay := omit,
	guaranteedBitRateUplink := omit,
	guaranteedBitRateDownlink := omit,
	sourceStatisticsDescriptor := omit,
	signallingIndication := omit,
	spare4 := omit,
	maxBitrateDownlinkExt := omit,
	guaranteedBitRateDownlinkExt := omit,
	maxBitrateUplinkExt := omit,
	guaranteedBitRateUplinkExt := omit,
	maxBitrateDownlinkExt2 := omit,
	guaranteedBitRateDownlinkExt2 := omit,
	maxBitrateUplinkExt2 := omit,
	guaranteedBitRateUplinkExt2 := omit
}

/* 10.5.6.4 / 3GPP TS 24.008 */
template (value) PDPAddressV t_AddrIPv4dyn := {
	pdpTypeOrg := '0001'B, /* IETF */
	spare := '0000'B,
	pdpTypeNum := '21'O, /* IPv4 */
	addressInfo := omit
}
template (value) PDPAddressV t_AddrIPv6dyn := {
	pdpTypeOrg := '0001'B, /* IETF */
	spare := '0000'B,
	pdpTypeNum := '53'O, /* IPv6 */
	addressInfo := omit
}

template (value) PdpActPars t_PdpActPars(charstring ggsn_ip) := {
	tid := '000'B,
	nsapi := '0101'B, /* < 5 are reserved */
	sapi := '0011'B, /* 3/5/9/11 */
	qos := t_QosDefault,
	addr := t_AddrIPv4dyn,
	apn := omit,
	pco := omit,
	exp_rej_cause := omit,
	gtp_resp_cause := int2oct(128, 1),
	chg_id := f_rnd_octstring(4),

	/* FIXME: make below dynamic !! */
	ggsn_tei_c := f_rnd_octstring(4),
	ggsn_tei_u := f_rnd_octstring(4),
	ggsn_ip_c := f_inet_addr(ggsn_ip),
	ggsn_ip_u := f_inet_addr(ggsn_ip),
	ggsn_restart_ctr := int2oct(2, 1),

	sgsn_tei_c := omit,
	sgsn_tei_u := omit,
	sgsn_ip_c := omit,
	sgsn_ip_u := omit
}

template (value) GtpPeer ts_GtpPeerU(octetstring ip) := {
	connId := 1,
	remName := f_inet_ntoa(ip),
	remPort := GTP1U_PORT
}

template (value) GtpPeer ts_GtpPeerC(octetstring ip) := {
	connId := 1,
	remName := f_inet_ntoa(ip),
	remPort := GTP1C_PORT
}

private function f_gtpu_send(inout PdpActPars apars, octetstring payload) runs on BSSGP_ConnHdlr {
	var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
	GTP.send(ts_GTP1U_GPDU(peer, 0 /*seq*/, apars.sgsn_tei_u, payload));
}

private altstep as_xid(PdpActPars apars, integer ran_index := 0) runs on BSSGP_ConnHdlr {
	[] BSSGP[ran_index].receive(tr_LLC_XID_MT_CMD(?, apars.sapi)) {
		repeat;
	}
}

template PDU_SN tr_SN_UD(template BIT4 nsapi, template octetstring payload) := {
	pDU_SN_UNITDATA := {
		nsapi := nsapi,
		moreBit := ?,
		snPduType := '1'B,
		firstSegmentIndicator := ?,
		spareBit := ?,
		pcomp := ?,
		dcomp := ?,
		npduNumber := ?,
		segmentNumber := ?,
		npduNumberContinued := ?,
		dataSegmentSnUnitdataPdu := payload
	}
}

/* simple case: single segment, no compression */
template (value) PDU_SN ts_SN_UD(BIT4 nsapi, octetstring payload) := {
	pDU_SN_UNITDATA := {
		nsapi := nsapi,
		moreBit := '0'B,
		snPduType := '1'B,
		firstSegmentIndicator := '1'B,
		spareBit := '0'B,
		pcomp := '0000'B,
		dcomp := '0000'B,
		npduNumber := '0000'B,
		segmentNumber := '0000'B,
		npduNumberContinued := '00'O,
		dataSegmentSnUnitdataPdu := payload
	}
}

/* Transceive given 'payload' as MT message from GTP -> OsmoSGSN -> Gb */
private function f_gtpu_xceive_mt(inout PdpActPars apars, octetstring payload, integer ran_index := 0, boolean expect_fwd := true)
runs on BSSGP_ConnHdlr {
	timer T := 5.0;
	/* Send PDU via GTP from our simulated GGSN to the SGSN */
	f_gtpu_send(apars, payload);
	T.start;
	/* Expect PDU via BSSGP/LLC on simulated PCU from SGSN */
	alt {
	[] as_xid(apars, ran_index);
	//[] BSSGP[ran_index].receive(tr_BD_SNDCP(apars.sapi, tr_SN_UD(apars.nsapi, payload)));
	[expect_fwd] BSSGP[ran_index].receive(tr_SN_UD(apars.nsapi, payload));
	[expect_fwd] T.timeout {
		setverdict(fail, "Timeout waiting for GTP-U to appear on BSSGP");
		mtc.stop;
		}
	[not expect_fwd] BSSGP[ran_index].receive(tr_SN_UD(apars.nsapi, payload)) {
		setverdict(fail, "GTP-U forwarded to BSSGP but not expected")
		mtc.stop;
		}
	[not expect_fwd] T.timeout {}
	}
}

/* Transceive given 'payload' as MO message from Gb -> OsmoSGSN -> GTP */
private function f_gtpu_xceive_mo(inout PdpActPars apars, octetstring payload, integer ran_index := 0)
runs on BSSGP_ConnHdlr {
	/* Send PDU via SNDCP/LLC/BSSGP/NS via simulated MS/PCU to the SGSN */
	var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
	var PDU_SN sndcp := valueof(ts_SN_UD(apars.nsapi, payload));
	BSSGP[ran_index].send(ts_LLC_UI(enc_PDU_SN(sndcp), apars.sapi, '0'B, 0));
	/* Expect PDU via GTP from SGSN on simulated GGSN */
	alt {
	[] GTP.receive(tr_GTPU_GPDU(peer, apars.ggsn_tei_u, payload));
	}
}

private function f_TC_attach_pdp_act(charstring id) runs on BSSGP_ConnHdlr {
	var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));

	/* first perform regular attach */
	f_TC_attach(id);

	f_pdp_ctx_act(apars);
}
testcase TC_attach_pdp_act() runs on test_CT {
	var BSSGP_ConnHdlr vc_conn;
	f_init();
	vc_conn := f_start_handler(refers(f_TC_attach_pdp_act), testcasename(), g_gb, 17);
	vc_conn.done;
	f_cleanup();
}

/* PDP Context activation for not-attached subscriber; expect fail */
private function f_TC_pdp_act_unattached(charstring id) runs on BSSGP_ConnHdlr {
	var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
	f_send_l3(ts_SM_ACT_PDP_REQ(apars.tid, apars.nsapi, apars.sapi, apars.qos, apars.addr,
				     apars.apn, apars.pco));
	alt {
	/* We might want toalso actually expect a PDPC CTX ACT REJ? */
	[] BSSGP[0].receive(tr_GMM_DET_REQ_MT(?, ?)) {
		setverdict(pass);
		}
	[] GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) {
		setverdict(fail, "Unexpected GTP PDP CTX ACT");
		mtc.stop;
		}
	[] BSSGP[0].receive(tr_SM_ACT_PDP_ACCEPT(?, ?)) {
		setverdict(fail, "Unexpected SM PDP CTX ACT ACK");
		mtc.stop;
		}
	[] BSSGP[0].receive { repeat; }
	}
}
testcase TC_pdp_act_unattached() runs on test_CT {
	var BSSGP_ConnHdlr vc_conn;
	f_init();
	vc_conn := f_start_handler(refers(f_TC_pdp_act_unattached), testcasename(), g_gb, 18);
	vc_conn.done;
	f_cleanup();
}

/* ATTACH + PDP CTX ACT + user plane traffic */
private function f_TC_attach_pdp_act_user(charstring id) runs on BSSGP_ConnHdlr {
	var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));

	/* first perform regular attach */
	f_TC_attach(id);
	/* then activate PDP context */
	f_pdp_ctx_act(apars);
	/* then transceive a downlink PDU */
	f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
	f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
}
testcase TC_attach_pdp_act_user() runs on test_CT {
	var BSSGP_ConnHdlr vc_conn;
	f_init();
	vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_user), testcasename(), g_gb, 19);
	vc_conn.done;
	f_cleanup();
}

/* ATTACH + PDP CTX ACT; reject from GGSN */
private function f_TC_attach_pdp_act_ggsn_reject(charstring id) runs on BSSGP_ConnHdlr {
	var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));

	apars.gtp_resp_cause := int2oct(199, 1);	/* no resources available */
	apars.exp_rej_cause := '1a'O;			/* insufficient resources */

	/* first perform regular attach */
	f_TC_attach(id);
	/* then activate PDP context */
	f_pdp_ctx_act(apars);
}
testcase TC_attach_pdp_act_ggsn_reject() runs on test_CT {
	var BSSGP_ConnHdlr vc_conn;
	f_init();
	vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_ggsn_reject), testcasename(), g_gb, 20);
	vc_conn.done;
	f_cleanup();
}

/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MO direction */
private function f_TC_attach_pdp_act_user_deact_mo(charstring id) runs on BSSGP_ConnHdlr {
	var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));

	/* first perform regular attach */
	f_TC_attach(id);
	/* then activate PDP context */
	f_pdp_ctx_act(apars);
	/* then transceive a downlink PDU */
	f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
	f_gtpu_xceive_mo(apars, f_rnd_octstring(200));

	f_pdp_ctx_deact_mo(apars, '00'O);
}
testcase TC_attach_pdp_act_user_deact_mo() runs on test_CT {
	var BSSGP_ConnHdlr vc_conn;
	f_init();
	vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_user_deact_mo), testcasename(), g_gb, 21);
	vc_conn.done;
	f_cleanup();
}

/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction */
private function f_TC_attach_pdp_act_user_deact_mt(charstring id) runs on BSSGP_ConnHdlr {
	var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));

	/* first perform regular attach */
	f_TC_attach(id);
	/* then activate PDP context */
	f_pdp_ctx_act(apars);
	/* then transceive a downlink PDU */
	f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
	f_gtpu_xceive_mo(apars, f_rnd_octstring(200));

	f_pdp_ctx_deact_mt(apars, false);
}
testcase TC_attach_pdp_act_user_deact_mt() runs on test_CT {
	var BSSGP_ConnHdlr vc_conn;
	f_init();
	vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_user_deact_mt), testcasename(), g_gb, 22);
	vc_conn.done;
	f_cleanup();
}

/* Test MS sending a duplicate Deact PDP Ctx (OS#3956). */
private function f_TC_attach_pdp_act_deact_dup(charstring id) runs on BSSGP_ConnHdlr {
	var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
	var Gtp1cUnitdata g_ud;
	var integer i;
	var OCT1 cause_regular_deact := '24'O;

	/* first perform regular attach + PDP context act */
	f_TC_attach(id);
	f_pdp_ctx_act(apars);

	f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause_regular_deact, false, omit), 0);
	f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause_regular_deact, false, omit), 0);

	for (i := 0; i < 2; i := i+1) {
		GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
			var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
			log("Received deletePDPContextResponse " & int2str(i) & ", seq_nr=" & int2str(seq_nr));
			GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
		}
	}

	alt {
	[] BSSGP[0].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
		setverdict(pass);
		}
	[] as_xid(apars, 0);
	}

	/* Make sure second DeactPdpAccept is sent: */
	timer T := 2.0;
	T.start;
	alt {
	[] BSSGP[0].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
		setverdict(fail, "Second SM_DEACT_PDP_ACCEPT_MT received");
		}
	[] T.timeout {
		setverdict(pass);
		}
	}

	setverdict(pass);
}
testcase TC_attach_pdp_act_deact_dup() runs on test_CT {
	var BSSGP_ConnHdlr vc_conn;
	f_init();
	vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_dup), testcasename(), g_gb, 46);
	vc_conn.done;
	f_cleanup();
}

/* ATTACH + ATTACH (2nd) */
private function f_TC_attach_forget_tlli_attach(charstring id) runs on BSSGP_ConnHdlr {
	g_pars.t_guard  := 5.0;

	/* first perform regular attach */
	f_TC_attach(id);

	/* second to perform regular attach */
	f_TC_attach(id);
}


testcase TC_attach_second_attempt() runs on test_CT {
	var BSSGP_ConnHdlr vc_conn;
	f_init();
	vc_conn := f_start_handler(refers(f_TC_attach_forget_tlli_attach), testcasename(), g_gb, 22);
	vc_conn.done;
	f_cleanup();
}

private function f_TC_attach_echo_timeout(charstring id) runs on BSSGP_ConnHdlr {
	var Gtp1cUnitdata g_ud;
	var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
	var integer seq_nr;

	/* first perform regular attach */
	f_TC_attach(id);
	/* then activate PDP context */
	f_pdp_ctx_act(apars);

	/* Wait to receive first echo request and send initial Restart counter */
	GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
		BSSGP[0].clear;
		seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
		GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
		f_sleep(int2float(mp_echo_interval)); /* wait until around next echo is expected */
	}

	/* At some point next echo request not answered will timeout and SGSN
	   should drop the pdp ctx. Around T3 (3secs) * 6 (+ extra, a lot due to OS#4178): */
	timer T := 3.0 * 6.0 + 16.0;
	T.start;
	alt {
		[] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {
			f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
			setverdict(pass);
		}
		[] GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
			/* SGSN currently doesn't send this message because it expects GGSN to be non-reachable anyway */
			seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
			log("Received deletePDPContextRequest seq_nr=" & int2str(seq_nr));
			GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
			repeat;
		}
		[] GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
			seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
			log("Received EchoRequest seq_nr=" & int2str(seq_nr));
			repeat;
		}
		[] T.timeout {
			setverdict(fail, "BSSGP DeactPdpReq not received");
			mtc.stop;
		}
		[] as_xid(apars);
	}
	T.stop

	setverdict(pass);
}
/* ATTACH + trigger Recovery procedure through CreatePdpResp */
testcase TC_attach_echo_timeout() runs on test_CT {
	var BSSGP_ConnHdlr vc_conn;
	g_use_echo := true;
	f_init();
	vc_conn := f_start_handler(refers(f_TC_attach_echo_timeout), testcasename(), g_gb, 67, 50.0);
	vc_conn.done;
	g_use_echo := false;
	f_cleanup();
}

private function f_TC_attach_restart_ctr_echo(charstring id) runs on BSSGP_ConnHdlr {
	var Gtp1cUnitdata g_ud;
	var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));

	/* first perform regular attach */
	f_TC_attach(id);
	/* Activate a pdp context against the  GGSN */
	f_pdp_ctx_act(apars);
	/* Wait to receive first echo request and send initial Restart counter */
	GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
		var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
		GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
	}
	/* Wait to receive second echo request and send incremented Restart
	   counter. This will fake a restarted GGSN, and pdp ctx allocated
	   should be released by SGSN */
	apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);
	GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
		var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
		GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
	}
	var OCT1 cause_network_failure := int2oct(38, 1)
	alt {
	[] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, cause_network_failure, true)) {
		f_send_l3(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
		setverdict(pass);
		}
	[] as_xid(apars);
	}
	setverdict(pass);
}
/* ATTACH + trigger Recovery procedure through EchoResp */
testcase TC_attach_restart_ctr_echo() runs on test_CT {
	var BSSGP_ConnHdlr vc_conn;
	g_use_echo := true
	f_init();
	vc_conn := f_start_handler(refers(f_TC_attach_restart_ctr_echo), testcasename(), g_gb, 23, 30.0);
	vc_conn.done;
	g_use_echo := false
	f_cleanup();
}

private function f_TC_attach_restart_ctr_create(charstring id) runs on BSSGP_ConnHdlr {
	var Gtp1cUnitdata g_ud;
	var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
	var integer seq_nr := 23;
	var GtpPeer peer;
	/* first perform regular attach */
	f_TC_attach(id);

	/* Use this CTX ACT to send initial Restart counter to SGSN. */
	apars.gtp_resp_cause := int2oct(199, 1);	/* no resources available */
	apars.exp_rej_cause := '1a'O;			/* insufficient resources */
	f_pdp_ctx_act(apars, true);

	/* Increment restart_ctr. This will fake a restarted GGSN when CreatePdpResp is
/* received. */
	apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);

	/* FIXME: Once we can easily handle different pdp ctx simultaneously, it
	   would be great to have an active pdp context here before triggering
	   Recovery, and making sure the the DEACT request is sent by the SGSN.
	*/

	/* Activate a pdp context against the GGSN, send incremented Recovery
	   IE. This should trigger the recovery path, but still this specific
	   CTX activation should work. */
	apars.exp_rej_cause := omit; /* default value for tests */
	apars.gtp_resp_cause := int2oct(128, 1);  /* default value for tests */
	f_pdp_ctx_act(apars, true);

	setverdict(pass);
}
/* ATTACH + trigger Recovery procedure through CreatePdpResp */
testcase TC_attach_restart_ctr_create() runs on test_CT {
	var BSSGP_ConnHdlr vc_conn;
	f_init();
	vc_conn := f_start_handler(refers(f_TC_attach_restart_ctr_create), testcasename(), g_gb, 24, 30.0);
	vc_conn.done;
	f_cleanup();
}

/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction + trigger T3395 */
private function f_TC_attach_pdp_act_deact_mt_t3395_expire(charstring id) runs on BSSGP_ConnHdlr {
	var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
	var integer seq_nr := 23;
	var GtpPeer peer;
	var integer i;

	/* first perform regular attach */
	f_TC_attach(id);
	/* then activate PDP context */
	f_pdp_ctx_act(apars);

	BSSGP[0].clear;
	peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
	GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));

	for (i := 0; i < 5; i := i+1) {
		alt {
			[] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {}
			[] as_xid(apars);
		}
	}

	GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) {}

	f_send_l3(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
	setverdict(pass);
}
testcase TC_attach_pdp_act_deact_mt_t3395_expire() runs on test_CT {
	var BSSGP_ConnHdlr vc_conn;
	f_init();
	f_sleep(1.0);
	vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_mt_t3395_expire), testcasename(), g_gb, 25, 60.0);
	vc_conn.done;
	f_cleanup();
}

/* ATTACH + PDP CTX ACT dropped + retrans */
private function f_TC_attach_pdp_act_deact_gtp_retrans(charstring id) runs on BSSGP_ConnHdlr {
	var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
	var Gtp1cUnitdata g_ud_first, g_ud_second;
	/* first perform regular attach */
	f_TC_attach(id);

	/* then activate PDP context on the Gb side */
	f_send_l3_gmm_llc(ts_SM_ACT_PDP_REQ(apars.tid, apars.nsapi, apars.sapi, apars.qos, apars.addr,
				     apars.apn, apars.pco), 0);

	GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud_first {}
	log("First createPDPContextRequest received, dropping & waiting for retransmission");
	GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud_second {
		if (g_ud_first != g_ud_second) {
			setverdict(fail, "Retransmitted GTP message createPDPContextRequest is different from original one!");
			mtc.stop;
		}
		f_process_gtp_ctx_act_req(apars, g_ud_second.gtpc);
		var integer seq_nr := oct2int(g_ud_second.gtpc.opt_part.sequenceNumber);
		GTP.send(ts_GTPC_CreatePdpResp(g_ud_second.peer, seq_nr,
						apars.sgsn_tei_c, apars.gtp_resp_cause,
						apars.ggsn_tei_c, apars.ggsn_tei_u,
						apars.nsapi,
						apars.ggsn_ip_c, apars.ggsn_ip_u, apars.chg_id,
						omit, omit));
	}
	BSSGP[0].receive(tr_SM_ACT_PDP_ACCEPT) {}

	/* Now the same with Deact */
	f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, '00'O, false, omit), 0);
	GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud_first {}
	log("First deletePDPContextRequest received, dropping & waiting for retransmission");
	GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud_second {
		if (g_ud_first != g_ud_second) {
			setverdict(fail, "Retransmitted GTP message deletePDPContextRequest is different from original one!");
			mtc.stop;
		}
		var integer seq_nr := oct2int(g_ud_second.gtpc.opt_part.sequenceNumber);
		BSSGP[0].clear;
		GTP.send(ts_GTPC_DeletePdpResp(g_ud_second.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
	}
	alt {
	[] BSSGP[0].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
		setverdict(pass);
		}
	[] as_xid(apars, 0);
	}

	setverdict(pass);
}
testcase TC_attach_pdp_act_deact_gtp_retrans() runs on test_CT {
	var BSSGP_ConnHdlr vc_conn;
	f_init();
	vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_gtp_retrans), testcasename(), g_gb, 27);
	vc_conn.done;
	f_cleanup();
}

/* Test that SGSN GTP response retransmit queue works fine */
private function f_TC_attach_pdp_act_deact_gtp_retrans_resp(charstring id) runs on BSSGP_ConnHdlr {
	var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
	var integer seq_nr := 23;
	var Gtp1cUnitdata g_ud_first, g_ud_second;
	var template Gtp1cUnitdata g_delete_req;
	/* first perform regular attach + PDP context act */
	f_TC_attach(id);
	f_pdp_ctx_act(apars);

	/* Now perform an MT DeleteCtxReq and emulate GGSN didn't receive response and sends a duplicated DeleteCtxReq */
	BSSGP[0].clear;
	var GtpPeer peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
	g_delete_req := ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B);
	GTP.send(g_delete_req);
	alt {
	[] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {
			f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid), 0);
		}
	[] as_xid(apars, 0);
	}
	GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) -> value g_ud_first {
		if (g_ud_first.gtpc.gtpc_pdu.deletePDPContextResponse.cause.causevalue != '80'O) {
			setverdict(fail, "Received deletePDPContextResponse cause is not 'Request accepted'");
			mtc.stop;
		}
	};

	/* Send duplicate DeleteCtxReq */
	log("First deletePDPContextResponse received, dropping & retransmitting retransmission of deletePDPContextRequest");
	GTP.send(g_delete_req);
	GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) -> value g_ud_second {
		if (g_ud_first != g_ud_second) {
			setverdict(fail, "Retransmitted GTP message deletePDPContextResponse is different from original one!");
			mtc.stop;
		}
	}

	/* Let's send now a new DeleteCtxReq (increased seq_nr) to make sure it
	 * is handled differently by SGSN (expect "non-existent" cause) */
	g_delete_req := ts_GTPC_DeletePDP(peer, seq_nr + 1, apars.sgsn_tei_c, apars.nsapi, '1'B);
	GTP.send(g_delete_req);
	/* Response with cause "non-existent" must be sent with TEID 0 according to specs */
	GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, '00000000'O)) -> value g_ud_second {
		if (g_ud_second.gtpc.gtpc_pdu.deletePDPContextResponse.cause.causevalue != 'C0'O) {
			setverdict(fail, "Received deletePDPContextResponse cause is not 'Non-existent'");
			mtc.stop;
		}
	}

	setverdict(pass);
}
testcase TC_attach_pdp_act_deact_gtp_retrans_resp() runs on test_CT {
	var BSSGP_ConnHdlr vc_conn;
	f_init();
	vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_gtp_retrans_resp), testcasename(), g_gb, 28);
	vc_conn.done;
	f_cleanup();
}

private function f_TC_hlr_location_cancel_request_update(charstring id) runs on BSSGP_ConnHdlr {
	/* MS: perform regular attach */
	f_TC_attach(id);

	/* HLR: cancel the location request */
	GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_UPDATE));
	GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));

	/* ensure no Detach Request got received */
	timer T := 5.0;
	T.start;
	alt {
		[] BSSGP[0].receive(tr_GMM_DET_REQ_MT(*, *, *)) {
			T.stop;
			setverdict(fail, "Unexpected GMM Detach Request");
			mtc.stop;
		}
		[] T.timeout {
			setverdict(pass);
			mtc.stop;
		}
		[] BSSGP[0].receive {
			repeat;
		}
	}
}

/* ATTACH + PDP CTX ACT + user plane traffic + ERROR IND in MT direction */
private function f_TC_attach_pdp_act_user_error_ind_ggsn(charstring id) runs on BSSGP_ConnHdlr {
	var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));

	/* first perform regular attach */
	f_TC_attach(id);
	/* then activate PDP context */
	f_pdp_ctx_act(apars);
	/* then transceive a downlink PDU */
	f_gtpu_xceive_mo(apars, f_rnd_octstring(200));

	/* Send Error indication as response from upload PDU and expect deact towards MS */
	f_pdp_ctx_deact_mt(apars, true);
}
testcase TC_attach_pdp_act_user_error_ind_ggsn() runs on test_CT {
	var BSSGP_ConnHdlr vc_conn;
	f_init();
	vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_user_error_ind_ggsn), testcasename(), g_gb, 26);
	vc_conn.done;
	f_cleanup();
}

testcase TC_hlr_location_cancel_request_update() runs on test_CT {
	/* MS <-> SGSN: GMM Attach
	 * HLR -> SGSN: Cancel Location Request
	 * HLR <- SGSN: Cancel Location Ack
	 */
	var BSSGP_ConnHdlr vc_conn;
	f_init();
	f_sleep(1.0);
	vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_update), testcasename(), g_gb, 31);
	vc_conn.done;
	f_cleanup();
}


private function f_TC_hlr_location_cancel_request_withdraw(charstring id) runs on BSSGP_ConnHdlr {
	/* MS: perform regular attach */
	f_TC_attach(id);

	/* HLR: cancel the location request */
	GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_WITHDRAW));
	GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
	GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));

	/* MS: receive a Detach Request */
	BSSGP[0].receive(tr_GMM_DET_REQ_MT(c_GMM_DTT_MT_IMSI_DETACH, ?, ?));
	f_send_l3(ts_GMM_DET_ACCEPT_MO);

	setverdict(pass);
}

testcase TC_hlr_location_cancel_request_withdraw() runs on test_CT {
	/* MS <-> SGSN: GMM Attach
	 * HLR -> SGSN: Cancel Location Request
	 * HLR <- SGSN: Cancel Location Ack
	 * MS  <- SGSN: Detach Request
	 * SGSN->   MS: Detach Complete
	 */
	var BSSGP_ConnHdlr vc_conn;
	f_init();
	f_sleep(1.0);
	vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_withdraw), testcasename(), g_gb, 29);
	vc_conn.done;
	f_cleanup();
}


private function f_hlr_location_cancel_request_unknown_subscriber(
		charstring id,
		GSUP_CancelType canceltype) runs on BSSGP_ConnHdlr {

	/* HLR: cancel the location request */
	GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, canceltype));

	/* cause 2 = IMSI_UNKNOWN */
	GSUP.receive(tr_GSUP_CL_ERR(g_pars.imsi, 2));

	setverdict(pass);
}

private function f_TC_hlr_location_cancel_request_unknown_subscriber_withdraw(charstring id) runs on BSSGP_ConnHdlr {
	f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
}

testcase TC_hlr_location_cancel_request_unknown_subscriber_withdraw() runs on test_CT {
	/* HLR -> SGSN: Cancel Location Request
	 * HLR <- SGSN: Cancel Location Error
	 */

	var BSSGP_ConnHdlr vc_conn;
	f_init();
	f_sleep(1.0);
	vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_unknown_subscriber_withdraw), testcasename(), g_gb, 30);
	vc_conn.done;
	f_cleanup();
}

private function f_TC_hlr_location_cancel_request_unknown_subscriber_update(charstring id) runs on BSSGP_ConnHdlr {
	f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
}

testcase TC_hlr_location_cancel_request_unknown_subscriber_update() runs on test_CT {
	/* HLR -> SGSN: Cancel Location Request
	 * HLR <- SGSN: Cancel Location Error
	 */

	var BSSGP_ConnHdlr vc_conn;
	f_init();
	f_sleep(1.0);
	vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_unknown_subscriber_update), testcasename(), g_gb, 30);
	vc_conn.done;
	f_cleanup();
}

private function f_TC_attach_detach_check_subscriber_list(charstring id) runs on BSSGP_ConnHdlr {
	f_TC_attach(id);
	f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
}

testcase TC_attach_detach_check_subscriber_list() runs on test_CT {
	/* MS <-> SGSN: Attach
	 * MS ->  SGSN: Detach Req (Power off)
	 * VTY -> SGSN: Check if MS is NOT in subscriber cache
	 */
	var BSSGP_ConnHdlr vc_conn;
	var integer id := 33;
	var charstring imsi := hex2str(f_gen_imsi(id));

	f_init();
	vc_conn := f_start_handler(refers(f_TC_attach_detach_check_subscriber_list), testcasename(), g_gb, id);
	vc_conn.done;

	f_vty_transceive_not_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
	f_cleanup();
}

/* Attempt an attach, but loose the Identification Request (IMEI) */
private function f_TC_attach_no_imei_response(charstring id) runs on BSSGP_ConnHdlr {
	var integer count_req := 0;
	var MobileIdentityLV mi;

	f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), f_random_RAI(), true, false, omit, omit));

	alt {
		[] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
			/* break */
		}
		[] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
			mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
			f_send_l3(ts_GMM_ID_RESP(mi));
			repeat;
		}
		[] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
			/* ignore ID REQ IMEI */
			count_req := count_req + 1;
			repeat;
		}
	}
	if (count_req != 5) {
		setverdict(fail, "Did not received GMM ID Request Type IMEI 5 times!");
		mtc.stop;
	}
	setverdict(pass);
}

testcase TC_attach_no_imei_response() runs on test_CT {
	/* MS -> SGSN: Attach Request IMSI
	 * MS <- SGSN: Identity Request IMSI (optional)
	 * MS -> SGSN: Identity Response IMSI (optional)
	 * MS <- SGSN: Identity Request IMEI
	 * MS -x SGSN: no response
	 * MS <- SGSN: re-send: Identity Request IMEI 4x
	 * MS <- SGSN: Attach Reject
	 */
	var BSSGP_ConnHdlr vc_conn;
	f_init();
	f_sleep(1.0);
	vc_conn := f_start_handler(refers(f_TC_attach_no_imei_response), testcasename(), g_gb, 32, 60.0);
	vc_conn.done;
	f_cleanup();
}

/* Attempt an attach, but loose the Identification Request (IMSI) */
private function f_TC_attach_no_imsi_response(charstring id) runs on BSSGP_ConnHdlr {
	var integer count_req := 0;
	var MobileIdentityLV mi;

	/* set p_tmsi to use it in Attach Req via f_mi_get_lv() */
	g_pars.p_tmsi := 'c0000035'O;

	f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), f_random_RAI(), true, false, omit, omit));

	alt {
		[] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
			/* break */
		}
		[] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
			/* ignore ID REQ IMSI */
			count_req := count_req + 1;
			repeat;
		}
		[] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
			mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
			f_send_l3(ts_GMM_ID_RESP(mi));
			repeat;
		}
	}
	if (count_req != 5) {
		setverdict(fail, "Did not received GMM ID Request Type IMSI 5 times!");
		mtc.stop;
	}
	setverdict(pass);
}

testcase TC_attach_no_imsi_response() runs on test_CT {
	/* MS -> SGSN: Attach Request TMSI (unknown)
	 * MS <- SGSN: Identity Request IMEI (optional)
	 * MS -> SGSN: Identity Response IMEI (optional)
	 * MS <- SGSN: Identity Request IMSI
	 * MS -x SGSN: no response
	 * MS <- SGSN: re-send: Identity Request IMSI 4x
	 * MS <- SGSN: Attach Reject
	 */
	var BSSGP_ConnHdlr vc_conn;
	f_init();
	f_sleep(1.0);
	vc_conn := f_start_handler(refers(f_TC_attach_no_imsi_response), testcasename(), g_gb, 35, 60.0);
	vc_conn.done;
	f_cleanup();
}

private function f_sgsn_vty_destroy_subscriber_imsi(TELNETasp_PT pt, charstring imsi) {
	f_vty_transceive(pt, "update-subscriber imsi " & imsi & " destroy");
}

testcase TC_attach_check_subscriber_list() runs on test_CT {
	/* MS <-> SGSN: Attach
	 * VTY -> SGSN: Check if MS is in subscriber cache
	 */
	var BSSGP_ConnHdlr vc_conn;
	var integer id := 34;
	var charstring imsi := hex2str(f_gen_imsi(id));

	f_init();
	f_sleep(1.0);
	vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, id);
	vc_conn.done;

	f_vty_transceive_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
	f_sgsn_vty_destroy_subscriber_imsi(SGSNVTY, imsi);
	f_cleanup();
}

private function f_TC_attach_closed_imsi_added(charstring id) runs on BSSGP_ConnHdlr {
	var RoutingAreaIdentificationV old_ra := f_random_RAI();
	var PDU_L3_SGSN_MS l3_mt;

	/* unregister the old IMSI */
	f_bssgp_client_unregister(g_pars.imsi);
	/* Simulate a foreign IMSI */
	g_pars.imsi := '001010123456700'H;
	f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[0]);

	/* there is no auth */
	g_pars.net.expect_auth := false;

	f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
	f_gmm_auth();
	alt {
		[] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
			setverdict(fail, "Received unexpected GMM Attach REJECT");
			mtc.stop;
		}
		[] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) -> value l3_mt {
			f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
			f_send_l3(ts_GMM_ATTACH_COMPL);
			setverdict(pass);
		}
	}
}

private function f_TC_attach_closed_add_vty(charstring id) runs on BSSGP_ConnHdlr {

	f_TC_attach_closed_foreign(id);
	f_TC_attach_closed_imsi_added(id);

}


testcase TC_attach_closed_add_vty() runs on test_CT {
	/* VTY-> SGSN: policy close
	 * MS -> SGSN: Attach Request
	 * MS <- SGSN: Identity Request IMSI
	 * MS -> SGSN: Identity Response IMSI
	 * MS <- SGSN: Attach Reject
	 * VTY-> SGSN: policy imsi-acl add IMSI
	 * MS -> SGSN: Attach Request
	 * MS <- SGSN: Identity Request IMSI
	 * MS -> SGSN: Identity Response IMSI
	 * MS <- SGSN: Identity Request IMEI
	 * MS -> SGSN: Identity Response IMEI
	 * MS <- SGSN: Attach Accept
	 */
	var BSSGP_ConnHdlr vc_conn;
	f_init();
	f_sleep(1.0);
	f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
	f_vty_config(SGSNVTY, "sgsn", "imsi-acl del 001010123456789");
	f_vty_config(SGSNVTY, "sgsn", "imsi-acl del 001010123456700");
	f_vty_config(SGSNVTY, "sgsn", "imsi-acl add 001010123456700");
	/* test with foreign IMSI: Must Reject */
	vc_conn := f_start_handler(refers(f_TC_attach_closed_add_vty), testcasename(), g_gb, 9);
	vc_conn.done;
	f_cleanup();
}

/* Attempt an attach, but never answer a Attach Complete */
private function f_TC_attach_check_complete_resend(charstring id) runs on BSSGP_ConnHdlr {
	var integer count_req := 0;

	f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), f_random_RAI(), true, false, omit, omit));
	f_gmm_auth();
	/* Expect SGSN to perform LU with HLR */
	f_gmm_gsup_lu_isd();

	timer T := 10.0;
	T.start;
	alt {
		[] T.timeout {
			/* break */
		}
		[] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) {
			/* ignore */
			count_req := count_req + 1;
			T.start;
			repeat;
		}
	}
	if (count_req != 5) {
		setverdict(fail, "Did not received GMM Attach Complete.");
		mtc.stop;
	}
	setverdict(pass);
}

testcase TC_attach_check_complete_resend() runs on test_CT {
	/* MS -> SGSN: Attach Request IMSI
	 * MS <- SGSN: Identity Request *
	 * MS -> SGSN: Identity Response *
	 * MS <- SGSN: Attach Complete 5x
	 */
	var BSSGP_ConnHdlr vc_conn;
	f_init();
	f_sleep(1.0);
	vc_conn := f_start_handler(refers(f_TC_attach_check_complete_resend), testcasename(), g_gb, 36, 60.0);
	vc_conn.done;
	f_cleanup();
}

friend function f_routing_area_update(RoutingAreaIdentificationV ra, integer ran_index := 0) runs on BSSGP_ConnHdlr {
	var PDU_L3_SGSN_MS l3_mt;
	var PDU_DTAP_PS_MT mt;
	var template OCT4 p_tmsi := omit;

	if (is_iu(ran_index)) {
		p_tmsi := g_pars.p_tmsi;
	}
	/* then send RAU */
	f_send_l3(ts_GMM_RAU_REQ(f_mi_get_lv(), GPRS_UPD_T_RA, g_pars.ra, false, omit, omit, p_tmsi), ran_index);
	alt {
	[is_gb(ran_index)] BSSGP[ran_index].receive(tr_GMM_RAU_ACCEPT) -> value l3_mt {
		f_process_rau_accept(l3_mt.msgs.gprs_mm.routingAreaUpdateAccept, ran_index);
		f_send_l3(ts_GMM_RAU_COMPL, ran_index);
		setverdict(pass);
		}
	[is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_RAU_ACCEPT)) -> value mt {
		f_process_rau_accept(mt.dtap.msgs.gprs_mm.routingAreaUpdateAccept, ran_index);
		f_send_l3(ts_GMM_RAU_COMPL, ran_index);
		setverdict(pass);
		}

	[is_gb(ran_index)] BSSGP[ran_index].receive(tr_GMM_RAU_REJECT) {
		setverdict(fail, "Unexpected RAU Reject");
		mtc.stop;
		}
	[is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_RAU_REJECT)) {
		setverdict(fail, "Unexpected RAU Reject");
		mtc.stop;
		}

	[is_iu(ran_index)] BSSAP.receive(tr_RANAP_SecurityModeCmd(uia_algs := ?, uia_key := oct2bit(g_pars.vec.ik),
								key_sts := ?)) {
			var IntegrityProtectionAlgorithm uia_chosen := 0; /* 0 = standard_UMTS_integrity_algorithm_UIA1 */
			BSSAP.send(ts_RANAP_SecurityModeComplete(uia_chosen));
			BSSAP.receive(tr_RANAP_CommonId(imsi_hex2oct(g_pars.imsi)))
			repeat;
		}
	[is_gb(ran_index)] BSSGP[ran_index].receive { repeat; }
	[is_iu(ran_index)] BSSAP.receive { repeat; }
	}
}

private function f_TC_attach_rau_a_a(charstring id) runs on BSSGP_ConnHdlr {
	/* first perform regular attach */
	f_TC_attach(id);

	/* then send RAU */
	f_routing_area_update(g_pars.ra);

	/* do another RAU */
	f_routing_area_update(g_pars.ra);

	f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
}

testcase TC_attach_rau_a_a() runs on test_CT {
	/* MS <-> SGSN: Successful Attach
	 * MS  -> SGSN: Routing Area Update Request
	 * MS <-  SGSN: Routing Area Update Accept
	 * MS  -> SGSN: Routing Area Update Request
	 * MS <-  SGSN: Routing Area Update Accept
	 * MS  -> SGSN: Detach (PowerOff)
	 */
	var BSSGP_ConnHdlr vc_conn;
	f_init();
	f_sleep(1.0);
	vc_conn := f_start_handler(refers(f_TC_attach_rau_a_a), testcasename(), g_gb, 37);
	vc_conn.done;
	f_cleanup();
}

private function f_TC_attach_rau_a_b(charstring id) runs on BSSGP_ConnHdlr {
	f_TC_attach(id);

	log("attach complete sending rau");
	f_routing_area_update(g_pars.ra, 0);

	log("rau complete unregistering");
	f_bssgp_client_unregister(g_pars.imsi);
	f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[1], BSSGP_PROC[1]);

	log("sending second RAU via different RA");
	f_routing_area_update(f_cellid_to_RAI(g_pars.bssgp_cell_id[1]), 1);

	f_detach_mo(c_GMM_DTT_MO_GPRS, true, true, 1);
}

testcase TC_attach_rau_a_b() runs on test_CT {
	/* MS <-> SGSN: Successful Attach
	 * MS  -> SGSN: Routing Area _a_ Update Request
	 * MS <-  SGSN: Routing Area _a_ Update Accept
	 * MS  -> SGSN: Routing Area _b_ Update Request
	 * MS <-  SGSN: Routing Area _b_ Update Accept
	 * MS  -> SGSN: Detach (PowerOff)
	 */
	var BSSGP_ConnHdlr vc_conn;
	f_init();
	f_sleep(1.0);
	vc_conn := f_start_handler(refers(f_TC_attach_rau_a_b), testcasename(), g_gb, 38);
	vc_conn.done;
	f_cleanup();
}

private function f_TC_attach_gmm_attach_req_while_gmm_attach(charstring id) runs on BSSGP_ConnHdlr {
	var integer count_req := 0;
	var MobileIdentityLV mi;
	var RoutingAreaIdentificationV rand_rai := f_random_RAI();
	var PDU_L3_SGSN_MS l3_mt;

	f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), rand_rai, true, false, omit, omit));

	alt {
		[] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
			setverdict(fail, "Unexpected GMM ATTACH REJECT");
			mtc.stop;
		}
		[] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
			mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
			f_send_l3(ts_GMM_ID_RESP(mi));
			repeat;
		}
		[] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
			/* send out a second GMM_Attach Request.
			 * If the SGSN follows the rules, this 2nd ATTACH REQ should be ignored, because
			 * of the same content */
			f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), rand_rai, true, false, omit, omit));
			mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
			f_send_l3(ts_GMM_ID_RESP(mi));
		}
	}
	f_sleep(1.0);

	/* we've sent already a IMEI answer, we should NOT asked again for IMEI */
	alt {
		[] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
			mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
			f_send_l3(ts_GMM_ID_RESP(mi));
			repeat;
		}
		[] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
			setverdict(fail, "Unexpected GMM ID REQ (IMEI).");
			mtc.stop;
		}
		[] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
			setverdict(fail, "Unexpected GMM ATTACH REJECT");
			mtc.stop;
		}
		[] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
			f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
			f_send_l3(ts_GMM_ATTACH_COMPL);
			setverdict(pass);
			/* FIXME: Extract P-TMSI, if any. Only send Complete if necessary */
		}
	}
}

testcase TC_attach_gmm_attach_req_while_gmm_attach() runs on test_CT {
	/* Testing if the SGSN ignore Attach Request with the exact same content */
	/* MS -> SGSN: Attach Request IMSI
	 * MS <- SGSN: Identity Request IMSI (optional)
	 * MS -> SGSN: Identity Response IMSI (optional)
	 * MS <- SGSN: Identity Request IMEI
	 * MS -> SGSN: Attach Request (2nd)
	 * MS <- SGSN: Identity Response IMEI
	 * MS <- SGSN: Attach Accept
	 * MS -> SGSN: Attach Complete
	 */
	var BSSGP_ConnHdlr vc_conn;
	f_init();
	f_sleep(1.0);
	f_vty_config(SGSNVTY, "sgsn", "auth-policy accept-all");
	vc_conn := f_start_handler(refers(f_TC_attach_gmm_attach_req_while_gmm_attach), testcasename(), g_gb, 39);
	vc_conn.done;
	f_cleanup();
}

private function f_TC_attach_usim_resync(charstring id) runs on BSSGP_ConnHdlr {
	var RoutingAreaIdentificationV old_ra := f_random_RAI();

	var template PDU_L3_MS_SGSN attach_req := ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit);

	/* send Attach Request */
	/* indicate R99 capability of the MS to enable UMTS AKA in presence of
	 * 3G auth vectors */
	attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.revisionLevelIndicatior := '1'B;
	/* The thing is, if the solSACapability is 'omit', then the
	 * revisionLevelIndicatior is at the wrong place! */
	attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.solSACapability := '0'B;
	f_send_l3(attach_req);

	/* do the auth */
	var PDU_L3_MS_SGSN l3_mo;
	var PDU_L3_SGSN_MS l3_mt;
	var default di := activate(as_mm_identity());

	var GSUP_IE auth_tuple;
	var template AuthenticationParameterAUTNTLV autn;

	g_pars.vec := f_gen_auth_vec_3g();
	autn := {
		elementIdentifier := '28'O,
		lengthIndicator := lengthof(g_pars.vec.autn),
		autnValue := g_pars.vec.autn
		};
	auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
							g_pars.vec.sres,
							g_pars.vec.kc,
							g_pars.vec.ik,
							g_pars.vec.ck,
							g_pars.vec.autn,
							g_pars.vec.res));
	log("GSUP sends 2G and 3G auth tuples", auth_tuple);
	GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
	GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));

	var template PDU_L3_SGSN_MS auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
	auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
	BSSGP[0].receive(auth_ciph_req) -> value l3_mt;

	/* send the gmm auth failure with resync IE */
	f_send_l3(ts_GMM_AUTH_FAIL_UMTS_AKA_RESYNC(g_pars.vec.auts));

	/* wait for the GSUP resync request */
	GSUP.receive(tr_GSUP_SAI_REQ_UMTS_AKA_RESYNC(
		g_pars.imsi,
		g_pars.vec.auts,
		g_pars.vec.rand));

	/* generate new key material */
	g_pars.vec := f_gen_auth_vec_3g();
	autn := {
		elementIdentifier := '28'O,
		lengthIndicator := lengthof(g_pars.vec.autn),
		autnValue := g_pars.vec.autn
		};

	auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
							g_pars.vec.sres,
							g_pars.vec.kc,
							g_pars.vec.ik,
							g_pars.vec.ck,
							g_pars.vec.autn,
							g_pars.vec.res));
	/* send new key material */
	GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));

	/* wait for the new Auth Request */
	auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
	auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
	BSSGP[0].receive(auth_ciph_req) -> value l3_mt;
	var BIT4 ac_ref := l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.acReferenceNumber.valueField;
	var template PDU_L3_MS_SGSN auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
	auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
	auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationParResp := {
		valueField := substr(g_pars.vec.res, 0, 4)
	};
	auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationRespParExt := {
		elementIdentifier := '21'O,
		lengthIndicator := lengthof(g_pars.vec.res) - 4,
		valueField := substr(g_pars.vec.res, 4, lengthof(g_pars.vec.res) - 4)
	};
	l3_mo := valueof(auth_ciph_resp);
	if (ispresent(l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest) and
		l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest.valueField == '001'B) {
		l3_mo.msgs.gprs_mm.authenticationAndCipheringResponse.imeisv :=
					valueof(ts_MI_IMEISV_TLV(g_pars.imei & '0'H));
	}
	f_send_l3(l3_mo);
	deactivate(di);

	/* Expect SGSN to perform LU with HLR */
	f_gmm_gsup_lu_isd();

	BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
		f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
	}
	f_send_l3(ts_GMM_ATTACH_COMPL);
	setverdict(pass);
}

testcase TC_attach_usim_resync() runs on test_CT {
	/* MS -> SGSN: Attach Request
	 * MS <- SGSN: Identity Request IMSI
	 * MS -> SGSN: Identity Response IMSI
	 * MS <- SGSN: Identity Request IMEI
	 * MS -> SGSN: Identity Response IMEI
	 * HLR<- SGSN: SAI Request
	 * HLR-> SGSN: SAI Response
	 * MS <- SGSN: Auth Request
	 * MS -> SGSN: Auth Failure (with AUTS)
	 * HLR<- SGSN: SAI Request (with AUTS & RAND)
	 * HLR-> SGSN: SAI Response (new key material)
	 * MS <- SGSN: Auth Request (new key material)
	 * MS -> SGSN: Auth Response
	 * MS <- SGSN: Attach Accept
	 * MS -> SGSN: Attach Complete
	 */
	var BSSGP_ConnHdlr vc_conn;
	f_init();
	f_sleep(1.0);
	vc_conn := f_start_handler(refers(f_TC_attach_usim_resync), testcasename(), g_gb, 40);
	vc_conn.done;
	f_cleanup();
}


/* Send LLC NULL to see if the SGSN survives it (OS#3952) */
private function f_TC_llc_null(charstring id) runs on BSSGP_ConnHdlr {
	f_gmm_attach(false, false);
	f_sleep(1.0);
	f_send_llc(ts_LLC_NULL('0'B, c_LLC_SAPI_LLGMM, LLC_CR_UL_CMD));
	/* try to detach to check if SGSN is still alive */
	f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
}
testcase TC_llc_null() runs on test_CT {
	var BSSGP_ConnHdlr vc_conn;
	f_init();
	f_sleep(1.0);
	vc_conn := f_start_handler(refers(f_TC_llc_null), testcasename(), g_gb, 41);
	vc_conn.done;
	f_cleanup();
}

/* Send LLC SABM to see if the SGSN rejects it properly with DM */
private function f_TC_llc_sabm_dm_llgmm(charstring id) runs on BSSGP_ConnHdlr {
	f_gmm_attach(false, false);
	f_sleep(1.0);
	f_send_llc(ts_LLC_SABM({}, '1'B, c_LLC_SAPI_LLGMM, LLC_CR_UL_CMD));
	BSSGP[0].receive(tr_LLC_DM(?, c_LLC_SAPI_LLGMM, LLC_CR_DL_RSP));
	setverdict(pass);
}
testcase TC_llc_sabm_dm_llgmm() runs on test_CT {
	var BSSGP_ConnHdlr vc_conn;
	f_init();
	f_sleep(1.0);
	vc_conn := f_start_handler(refers(f_TC_llc_sabm_dm_llgmm), testcasename(), g_gb, 42);
	vc_conn.done;
	f_cleanup();
}

/* Send LLC SABM to see if the SGSN rejects it properly with DM */
private function f_TC_llc_sabm_dm_ll5(charstring id) runs on BSSGP_ConnHdlr {
	f_gmm_attach(false, false);
	f_sleep(1.0);
	f_send_llc(ts_LLC_SABM({}, '1'B, c_LLC_SAPI_LL5, LLC_CR_UL_CMD));
	BSSGP[0].receive(tr_LLC_DM(?, c_LLC_SAPI_LL5, LLC_CR_DL_RSP));
	setverdict(pass);
}
testcase TC_llc_sabm_dm_ll5() runs on test_CT {
	var BSSGP_ConnHdlr vc_conn;
	f_init();
	f_sleep(1.0);
	vc_conn := f_start_handler(refers(f_TC_llc_sabm_dm_ll5), testcasename(), g_gb, 43);
	vc_conn.done;
	f_cleanup();
}

/* test XID handshake with empty L3 info: expect empty return (some phones require that, OS#3426 */
private function f_TC_xid_empty_l3(charstring id) runs on BSSGP_ConnHdlr {
	var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
	var template (value) XID_Information xid;
	var template XID_Information xid_rx;

	/* first perform regular attach */
	f_TC_attach(id);
	/* then activate PDP context */
	f_pdp_ctx_act(apars);

	/* start MO XID */
	xid := { ts_XID_L3(''O) };
	xid_rx := { tr_XID_L3(''O) };
	f_send_llc(ts_LLC_XID_MO_CMD(xid, apars.sapi));
	alt {
	[] BSSGP[0].receive(tr_LLC_XID(xid_rx, apars.sapi));
	[] as_xid(apars);
	}
	setverdict(pass);
}
testcase TC_xid_empty_l3() runs on test_CT {
	var BSSGP_ConnHdlr vc_conn;
	f_init();
	f_sleep(1.0);
	vc_conn := f_start_handler(refers(f_TC_xid_empty_l3), testcasename(), g_gb, 44);
	vc_conn.done;
	f_cleanup();
}

private function f_TC_xid_n201u(charstring id) runs on BSSGP_ConnHdlr {
	var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
	var template (value) XID_Information xid;
	var template XID_Information xid_rx;

	/* first perform regular attach */
	f_TC_attach(id);
	/* then activate PDP context */
	f_pdp_ctx_act(apars);

	/* start MO XID */
	xid := { ts_XID_N201U(1234) };
	xid_rx := { tr_XID_N201U(1234) };
	f_send_llc(ts_LLC_XID_MO_CMD(xid, apars.sapi));
	alt {
	[] BSSGP[0].receive(tr_LLC_XID_MT_RSP(xid_rx, apars.sapi));
	[] as_xid(apars);
	}
	setverdict(pass);
}
testcase TC_xid_n201u() runs on test_CT {
	var BSSGP_ConnHdlr vc_conn;
	f_init();
	f_sleep(1.0);
	vc_conn := f_start_handler(refers(f_TC_xid_n201u), testcasename(), g_gb, 45);
	vc_conn.done;
	f_cleanup();
}

private function f_TC_attach_pdp_act_gmm_detach(charstring id) runs on BSSGP_ConnHdlr {
	var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));

	/* first perform regular attach */
	f_TC_attach(id);
	/* then activate PDP context */
	f_pdp_ctx_act(apars);
	/* do a normal detach */
	f_detach_mo(c_GMM_DTT_MO_GPRS, false, true);
}

testcase TC_attach_pdp_act_gmm_detach() runs on test_CT {
	/* MS  -> SGSN: Attach Request
	 * MS <-> SGSN: [..]
	 * MS  -> SGSN: Attach Complete
	 * MS  -> SGSN: PDP Activate Request
	 * MS <-  SGSN: PDP Activate Accept
	 * MS  -> SGSN: GMM Detach Request
	 * MS <-  SGSN: GMM Detach Accept
	 */
	var BSSGP_ConnHdlr vc_conn;
	f_init();
	vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_gmm_detach), testcasename(), g_gb, 26);
	vc_conn.done;
	f_cleanup();
}

private function f_TC_attach_req_id_req_ra_update(charstring id) runs on BSSGP_ConnHdlr {
	var RoutingAreaIdentificationV old_ra := f_random_RAI();
	var RoutingAreaIdentificationV new_ra := f_random_RAI();
	while (old_ra == new_ra) { new_ra := f_random_RAI(); };
	var template PDU_L3_MS_SGSN attach_req := ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit);
	var PDU_L3_SGSN_MS l3_mt;

	f_send_l3(attach_req, 0);

	BSSGP[0].receive(tr_GMM_ID_REQ(?));

	f_send_l3(ts_GMM_RAU_REQ(f_mi_get_lv(), GPRS_UPD_T_RA, new_ra, false, omit, omit));
	alt {
	[] BSSGP[0].receive(tr_GMM_RAU_REJECT('0a'O)) {
		setverdict(pass);
		}
	[] BSSGP[0].receive { repeat; }
	}
}

/* This test triggers crash in osmo-sgsn before osmo-sgsn.git I64fa5cf1b427d3abb99e553e584897261a827ce6.
 * See OS#3957 and OS#4245 for more information.
 */
testcase TC_attach_req_id_req_ra_update() runs on test_CT {
	/*
	 * MS --> SGSN: Attach Req (TMSI, RAI=901-70-356-101)
	 * MS <-- SGSN: Identity Request (IMEI)
	 * MS --> SGSN: RA Updating (RAI=901-70-2758-208)
	 */
	var BSSGP_ConnHdlr vc_conn;
	f_init();
	vc_conn := f_start_handler(refers(f_TC_attach_req_id_req_ra_update), testcasename(), g_gb, 47);
	vc_conn.done;
	f_cleanup();
}

private altstep as_nopaging_ps(integer ran_idx := 0) runs on BSSGP_ConnHdlr {
var PDU_BSSGP rx;
[] BSSGP_SIG[ran_idx].receive(tr_BSSGP_PS_PAGING(?)) -> value rx {
	setverdict(fail, "Received unexpected PS PAGING: ", rx);
	mtc.stop;
	}
}

/* SUSPEND, then DL traffic: should not pass + no paging expected */
private function f_TC_suspend_nopaging(charstring id) runs on BSSGP_ConnHdlr {
	var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
	var default d;

	/* first perform regular attach */
	f_TC_attach(id);
	/* then activate PDP context */
	f_pdp_ctx_act(apars);
	/* then transceive a downlink PDU */
	f_gtpu_xceive_mt(apars, f_rnd_octstring(100));

	/* now suspend GPRS */
	f_bssgp_suspend();

	d := activate(as_nopaging_ps());

	/* at this point we don't expect any downlink traffic at all, neither actual LLC/SNDCP data,
	 * nor any related paging requests */
	f_gtpu_xceive_mt(apars, f_rnd_octstring(100), expect_fwd := false);

	deactivate(d);
}
testcase TC_suspend_nopaging() runs on test_CT {
	var BSSGP_ConnHdlr vc_conn;
	f_init();
	f_sleep(1.0);
	vc_conn := f_start_handler(refers(f_TC_suspend_nopaging), testcasename(), g_gb, 48);
	vc_conn.done;
	f_cleanup();
}


/* SUSPEND, then RESUME: data expected to flow after explicit resume */
private function f_TC_suspend_resume(charstring id) runs on BSSGP_ConnHdlr {
	var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
	var OCT1 susp_ref;
	var default d;

	/* first perform regular attach */
	f_TC_attach(id);
	/* then activate PDP context */
	f_pdp_ctx_act(apars);
	/* then transceive a downlink PDU */
	f_gtpu_xceive_mt(apars, f_rnd_octstring(100));

	/* now suspend GPRS */
	susp_ref := f_bssgp_suspend();

	d := activate(as_nopaging_ps());

	/* at this point we don't expect any downlink traffic at all, neither actual LLC/SNDCP data,
	 * nor any related paging requests */
	f_gtpu_xceive_mt(apars, f_rnd_octstring(100), expect_fwd := false);

	deactivate(d);

	/* resume GPRS */
	f_bssgp_resume(susp_ref);

	/* now data should be flowing again */
	f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
}
testcase TC_suspend_resume() runs on test_CT {
	var BSSGP_ConnHdlr vc_conn;
	f_init();
	f_sleep(1.0);
	vc_conn := f_start_handler(refers(f_TC_suspend_resume), testcasename(), g_gb, 49);
	vc_conn.done;
	f_cleanup();
}

/* SUSPEND, then RAU: data expected to flow after implicit resume */
private function f_TC_suspend_rau(charstring id) runs on BSSGP_ConnHdlr {
	var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
	var default d;

	/* first perform regular attach */
	f_TC_attach(id);
	/* then activate PDP context */
	f_pdp_ctx_act(apars);
	/* then transceive a downlink PDU */
	f_gtpu_xceive_mt(apars, f_rnd_octstring(100));

	/* now suspend GPRS */
	f_bssgp_suspend();

	d := activate(as_nopaging_ps());

	/* at this point we don't expect any downlink traffic at all, neither actual LLC/SNDCP data,
	 * nor any related paging requests */
	f_gtpu_xceive_mt(apars, f_rnd_octstring(100), expect_fwd := false);

	deactivate(d);

	/* perform RAU (implicit RESUME) */
	f_routing_area_update(g_pars.ra);

	/* now data should be flowing again */
	f_gtpu_xceive_mt(apars, f_rnd_octstring(100));

}
testcase TC_suspend_rau() runs on test_CT {
	var BSSGP_ConnHdlr vc_conn;
	f_init();
	f_sleep(1.0);
	vc_conn := f_start_handler(refers(f_TC_suspend_rau), testcasename(), g_gb, 50);
	vc_conn.done;
	f_cleanup();
}


/* wait for T3314 expiration and check that PS PAGING is created on DL PDU */
private function f_TC_paging_ps(charstring id) runs on BSSGP_ConnHdlr {
	var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
	var default d;

	/* first perform regular attach */
	f_TC_attach(id);
	/* then activate PDP context */
	f_pdp_ctx_act(apars);
	/* then transceive a downlink PDU */
	f_gtpu_xceive_mt(apars, f_rnd_octstring(100));

	/* now wait for T3314 expiration (test_CT below has reduced it to 3s) */
	f_sleep(5.0);

	/* now data should be flowing again, but with PS PAGING */
	f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
	BSSGP_SIG[0].receive(tr_BSSGP_PS_PAGING(?));

	/* FIXME: simulate paging response */
	/* FIXME: verify PDU actually arrives only after paging response was successful */

}
testcase TC_paging_ps() runs on test_CT {
	var BSSGP_ConnHdlr vc_conn;
	f_init();
	f_vty_config(SGSNVTY, "sgsn", "timer 3314 3");
	f_sleep(1.0);
	vc_conn := f_start_handler(refers(f_TC_paging_ps), testcasename(), g_gb, 51);
	vc_conn.done;
	f_vty_config(SGSNVTY, "sgsn", "timer 3314 default");
	f_cleanup();
}





control {
	execute( TC_attach() );
	execute( TC_attach_mnc3() );
	execute( TC_attach_umts_aka_umts_res() );
	execute( TC_attach_umts_aka_gsm_sres() );
	execute( TC_attach_auth_id_timeout() );
	execute( TC_attach_auth_sai_timeout() );
	execute( TC_attach_auth_sai_reject() );
	execute( TC_attach_gsup_lu_timeout() );
	execute( TC_attach_gsup_lu_reject() );
	execute( TC_attach_combined() );
	execute( TC_attach_accept_all() );
	execute( TC_attach_closed() );
	execute( TC_attach_no_imei_response() );
	execute( TC_attach_no_imsi_response() );
	execute( TC_attach_closed_add_vty(), 20.0 );
	execute( TC_attach_check_subscriber_list(), 20.0 );
	execute( TC_attach_detach_check_subscriber_list(), 20.0 );
	execute( TC_attach_check_complete_resend() );
	execute( TC_hlr_location_cancel_request_update(), 20.0 );
	execute( TC_hlr_location_cancel_request_withdraw(), 20.0 );
	execute( TC_hlr_location_cancel_request_unknown_subscriber_withdraw(), 20.0 );
	execute( TC_hlr_location_cancel_request_unknown_subscriber_update(), 20.0 );
	execute( TC_rau_unknown() );
	execute( TC_attach_rau() );
	execute( TC_attach_rau_a_a() );
	execute( TC_attach_rau_a_b() );
	execute( TC_attach_usim_resync() );
	execute( TC_detach_unknown_nopoweroff() );
	execute( TC_detach_unknown_poweroff() );
	execute( TC_detach_nopoweroff() );
	execute( TC_detach_poweroff() );
	execute( TC_attach_pdp_act() );
	execute( TC_pdp_act_unattached() );
	execute( TC_attach_pdp_act_user() );
	execute( TC_attach_pdp_act_ggsn_reject() );
	execute( TC_attach_pdp_act_user_deact_mo() );
	execute( TC_attach_pdp_act_user_deact_mt() );
	execute( TC_attach_pdp_act_deact_dup() );
	execute( TC_attach_second_attempt() );
	execute( TC_attach_echo_timeout() );
	execute( TC_attach_restart_ctr_echo() );
	execute( TC_attach_restart_ctr_create() );
	execute( TC_attach_pdp_act_deact_mt_t3395_expire() );
	execute( TC_attach_pdp_act_deact_gtp_retrans() );
	execute( TC_attach_pdp_act_deact_gtp_retrans_resp() );
	execute( TC_attach_pdp_act_user_error_ind_ggsn() );
	execute( TC_attach_pdp_act_gmm_detach() );
	execute( TC_attach_gmm_attach_req_while_gmm_attach() );

	execute( TC_xid_empty_l3() );
	execute( TC_xid_n201u() );

	execute( TC_llc_null() );
	execute( TC_llc_sabm_dm_llgmm() );
	execute( TC_llc_sabm_dm_ll5() );

	execute( TC_suspend_nopaging() );
	execute( TC_suspend_resume() );
	execute( TC_suspend_rau() );
	execute( TC_paging_ps() );

	/* At the end, may crash osmo-sgsn, see OS#3957, OS#4245 */
	execute( TC_attach_req_id_req_ra_update() );
}



}
