Change in osmo-ttcn3-hacks[master]: msc: add inter-BSC and inter-MSC Handover tests

Neels Hofmeyr gerrit-no-reply at lists.osmocom.org
Fri Apr 12 03:58:20 UTC 2019


Neels Hofmeyr has uploaded this change for review. ( https://gerrit.osmocom.org/13617


Change subject: msc: add inter-BSC and inter-MSC Handover tests
......................................................................

msc: add inter-BSC and inter-MSC Handover tests

Change-Id: I7d76c982ad4e198534fa488609c41e8892b268ab
---
M library/BSSMAP_Emulation.ttcn
M library/BSSMAP_Templates.ttcn
M library/GSUP_Types.ttcn
M library/L3_Templates.ttcn
M msc/BSC_ConnectionHandler.ttcn
M msc/MSC_Tests.ttcn
6 files changed, 1,024 insertions(+), 112 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/osmo-ttcn3-hacks refs/changes/17/13617/1

diff --git a/library/BSSMAP_Emulation.ttcn b/library/BSSMAP_Emulation.ttcn
index 55ce2fb..2be3b70 100644
--- a/library/BSSMAP_Emulation.ttcn
+++ b/library/BSSMAP_Emulation.ttcn
@@ -121,6 +121,7 @@
 		MgcpCommand, MgcpResponse;
 } with { extension "internal" };
 
+type uint2_t N_Sd_Array[4];
 
 /* represents a single BSSAP connection over SCCP */
 type record ConnectionData {
@@ -132,7 +133,7 @@
 	/* CIC that has been used for voice of this channel (BSC side) */
 	integer		cic optional,
 	/* array of N(SD) values for MO DTAP messages, indexed by discriminator */
-	uint2_t		n_sd[4]
+	N_Sd_Array	n_sd
 }
 
 type record ImsiMapping {
@@ -432,30 +433,53 @@
 
 template BIT4 t_ML3_DISC_CC_MM_SS := ('0011'B, '0101'B, '1011'B);
 
-/* patch N(SD) into enc_l3, according to 24.007 11.2.3.2 */
-function f_ML3_patch_seq(inout ConnectionData cd, in PDU_ML3_MS_NW dtap, inout octetstring enc_l3) {
+function f_next_n_sd(inout N_Sd_Array n_sd, in integer n_sd_idx) return uint2_t {
 	var uint2_t seq_nr;
-	if (ischosen(dtap.msgs.cc) or ischosen(dtap.msgs.mm) or ischosen(dtap.msgs.ss)) {
-		seq_nr := cd.n_sd[0];
-		cd.n_sd[0] := (cd.n_sd[0] + 1) mod 4;
-	} else if (ischosen(dtap.msgs.gcc)) {
-		seq_nr := cd.n_sd[1];
-		cd.n_sd[1] := (cd.n_sd[1] + 1) mod 2;
-	} else if (ischosen(dtap.msgs.bcc)) {
-		seq_nr := cd.n_sd[2];
-		cd.n_sd[2] := (cd.n_sd[2] + 1) mod 2;
-	} else if (ischosen(dtap.msgs.loc)) {
-		seq_nr := cd.n_sd[3];
-		cd.n_sd[3] := (cd.n_sd[3] + 1) mod 2;
+	if (n_sd_idx == 0) {
+		seq_nr := n_sd[0];
+		n_sd[0] := (n_sd[0] + 1) mod 4;
+	} else if (n_sd_idx >= 1 and n_sd_idx <= 3) {
+		seq_nr := n_sd[n_sd_idx];
+		n_sd[n_sd_idx] := (n_sd[n_sd_idx] + 1) mod 2;
 	} else {
 		/* no sequence number to patch */
-		return;
+		seq_nr := 0;
 	}
+	return seq_nr;
+}
+
+/* patch N(SD) into enc_l3, according to 24.007 11.2.3.2 */
+function f_ML3_patch_seq_nr(in uint2_t seq_nr, inout octetstring enc_l3) {
 	log("patching N(SD)=", seq_nr, " into dtap ", enc_l3);
 	enc_l3[1] := (enc_l3[1] and4b '3f'O) or4b bit2oct(int2bit(seq_nr, 8) << 6);
 	log("patched enc_l3: ", enc_l3);
 }
 
+function f_ML3_n_sd_idx(in PDU_ML3_MS_NW dtap) return integer {
+	var uint2_t seq_nr;
+	if (ischosen(dtap.msgs.cc) or ischosen(dtap.msgs.mm) or ischosen(dtap.msgs.ss)) {
+		return 0;
+	} else if (ischosen(dtap.msgs.gcc)) {
+		return 1;
+	} else if (ischosen(dtap.msgs.bcc)) {
+		return 2;
+	} else if (ischosen(dtap.msgs.loc)) {
+		return 3;
+	}
+	/* no sequence number to patch */
+	return -1;
+}
+
+/* patch N(SD) into enc_l3, according to 24.007 11.2.3.2 */
+function f_ML3_patch_seq(inout ConnectionData cd, in PDU_ML3_MS_NW dtap, inout octetstring enc_l3) {
+	var integer n_sd_idx := f_ML3_n_sd_idx(dtap);
+	if (n_sd_idx < 0) {
+		return;
+	}
+	var uint2_t seq_nr := f_next_n_sd(cd.n_sd, n_sd_idx);
+	f_ML3_patch_seq_nr(seq_nr, enc_l3);
+}
+
 private function f_bssap_l3_is_rr(PDU_BSSAP bssap) return boolean {
 	var template octetstring l3 := f_bssap_extract_l3(bssap);
 	if (not isvalue(l3)) {
@@ -551,6 +575,8 @@
 		var octetstring l3_info;
 		var hexstring imsi;
 		var OCT4 tmsi;
+		var integer targetPointCode;
+		var N_Sd_Array last_n_sd;
 
 		alt {
 		/* SCCP -> Client: UNIT-DATA (connectionless SCCP) from a BSC */
@@ -663,6 +689,18 @@
 			BSSAP.send(ts_BSSAP_DATA_req(ConnectionTable[idx].sccp_conn_id, bssap));
 			}
 
+		[] PROC.getcall(BSSMAPEM_last_n_sd:{?,-}) -> param(vc_hdlr) {
+			var integer idx := f_idx_by_comp(vc_hdlr);
+			last_n_sd := ConnectionTable[idx].n_sd;
+			PROC.reply(BSSMAPEM_last_n_sd:{vc_hdlr, last_n_sd}) to vc_hdlr;
+			}
+
+		[] PROC.getcall(BSSMAPEM_continue_after_n_sd:{?,?}) -> param(last_n_sd, vc_hdlr) {
+			var integer idx := f_idx_by_comp(vc_hdlr);
+			ConnectionTable[idx].n_sd := last_n_sd;
+			PROC.reply(BSSMAPEM_continue_after_n_sd:{last_n_sd, vc_hdlr}) to vc_hdlr;
+			}
+
 		[not g_bssmap_ops.role_ms] CLIENT.receive(PDU_DTAP_MT:?) -> value dtap_mt sender vc_conn {
 			var integer conn_id := f_conn_id_by_comp(vc_conn);
 			/* convert from decoded DTAP to encoded DTAP */
@@ -717,6 +755,11 @@
 			PROC.reply(BSSMAPEM_register:{l3_info, vc_hdlr}) to vc_hdlr;
 			}
 
+		[] PROC.getcall(BSSMAPEM_register_handoverRequest:{?,?}) -> param(targetPointCode, vc_hdlr) {
+			f_create_expect(omit, vc_hdlr, targetPointCode);
+			PROC.reply(BSSMAPEM_register_handoverRequest:{targetPointCode, vc_hdlr}) to vc_hdlr;
+			}
+
 		[] PROC.getcall(BSSMAPEM_register_imsi:{?,?,?}) -> param(imsi, tmsi, vc_hdlr) {
 			f_create_imsi(imsi, tmsi, vc_hdlr);
 			PROC.reply(BSSMAPEM_register_imsi:{imsi, tmsi, vc_hdlr}) to vc_hdlr;
@@ -741,18 +784,27 @@
 type record ExpectData {
 	/* L3 payload based on which we can match it */
 	octetstring l3_payload optional,
+	integer handoverRequestPointCode optional,
 	/* component reference for this connection */
 	BSSAP_ConnHdlr vc_conn
 }
 
 /* procedure based port to register for incoming connections */
 signature BSSMAPEM_register(in octetstring l3, in BSSAP_ConnHdlr hdlr);
+signature BSSMAPEM_register_handoverRequest(in integer targetPointCode, in BSSAP_ConnHdlr hdlr);
 
 /* procedure based port to register for incoming IMSI/TMSI */
 signature BSSMAPEM_register_imsi(in hexstring imsi, in OCT4 tmsi, in BSSAP_ConnHdlr hdlr);
 
+/* If DTAP happens across other channels (e.g. GSUP), provide manual advancing of the n_sd sequence number */
+signature BSSMAPEM_last_n_sd(in BSSAP_ConnHdlr hdlr, out N_Sd_Array last_n_sd);
+
+/* Update conn's n_sd sequence nr after the connection was taken over from elsewhere */
+signature BSSMAPEM_continue_after_n_sd(N_Sd_Array last_n_sd, in BSSAP_ConnHdlr hdlr);
+
 type port BSSMAPEM_PROC_PT procedure {
-	inout BSSMAPEM_register, BSSMAPEM_register_imsi;
+	inout BSSMAPEM_register, BSSMAPEM_register_handoverRequest, BSSMAPEM_register_imsi, BSSMAPEM_last_n_sd,
+	      BSSMAPEM_continue_after_n_sd;
 } with { extension "internal" };
 
 /* CreateCallback that can be used as create_cb and will use the expectation table */
@@ -760,16 +812,35 @@
 runs on BSSMAP_Emulation_CT return BSSAP_ConnHdlr {
 	var BSSAP_ConnHdlr ret := null;
 	var octetstring l3_info;
+	var boolean handoverRequest := false;
+	var integer handoverRequestPointCode;
 	var integer i;
 
-	if (not ischosen(conn_ind.userData.pdu.bssmap.completeLayer3Information)) {
-		setverdict(fail, "N-CONNECT.ind with L3 != COMPLETE L3");
+	if (ischosen(conn_ind.userData.pdu.bssmap.completeLayer3Information)) {
+		l3_info := conn_ind.userData.pdu.bssmap.completeLayer3Information.layer3Information.layer3info;
+		log("ExpectedCreateCallback completeLayer3Information");
+	} else if (ischosen(conn_ind.userData.pdu.bssmap.handoverRequest)) {
+		handoverRequest := true;
+		handoverRequestPointCode := bit2int(conn_ind.calledAddress.signPointCode);
+		log("ExpectedCreateCallback handoverRequest ", handoverRequestPointCode);
+	} else {
+		setverdict(fail, "N-CONNECT.ind with L3 != COMPLETE L3 nor a Handover Request");
 		mtc.stop;
 		return ret;
 	}
-	l3_info := conn_ind.userData.pdu.bssmap.completeLayer3Information.layer3Information.layer3info;
 
 	for (i := 0; i < sizeof(ExpectTable); i:= i+1) {
+		if (handoverRequest) {
+			log("ExpectTable[", i, "].handoverRequestPointCode = ", ExpectTable[i].handoverRequestPointCode,
+			    " ==? ", handoverRequestPointCode);
+			if (ExpectTable[i].handoverRequestPointCode == handoverRequestPointCode) {
+				ret := ExpectTable[i].vc_conn;
+				log("Found Expect[", i, "] for handoverRequest handled at ", ret);
+				return ret;
+			} else {
+				continue;
+			}
+		}
 		if (not ispresent(ExpectTable[i].l3_payload)) {
 			continue;
 		}
@@ -788,14 +859,26 @@
 	return ret;
 }
 
-private function f_create_expect(octetstring l3, BSSAP_ConnHdlr hdlr)
+private function f_create_expect(template octetstring l3, BSSAP_ConnHdlr hdlr,
+				 template integer handoverRequestPointCode := omit)
 runs on BSSMAP_Emulation_CT {
 	var integer i;
+	log("f_create_expect(l3 := ", l3, ", handoverRequest := ", handoverRequestPointCode);
 	for (i := 0; i < sizeof(ExpectTable); i := i+1) {
-		if (not ispresent(ExpectTable[i].l3_payload)) {
-			ExpectTable[i].l3_payload := l3;
+		if (not ispresent(ExpectTable[i].l3_payload)
+		    and not ispresent(ExpectTable[i].handoverRequestPointCode)) {
+			if (ispresent(l3)) {
+				ExpectTable[i].l3_payload := valueof(l3);
+			}
+			if (ispresent(handoverRequestPointCode)) {
+				ExpectTable[i].handoverRequestPointCode := valueof(handoverRequestPointCode);
+			}
 			ExpectTable[i].vc_conn := hdlr;
-			log("Created Expect[", i, "] for ", l3, " to be handled at ", hdlr);
+			if (ispresent(handoverRequestPointCode)) {
+				log("Created Expect[", i, "] for handoverRequest to be handled at ", hdlr);
+			} else {
+				log("Created Expect[", i, "] for ", l3, " to be handled at ", hdlr);
+			}
 			return;
 		}
 	}
@@ -821,6 +904,7 @@
 runs on BSSMAP_Emulation_CT {
 	for (var integer i := 0; i < sizeof(ExpectTable); i := i+1) {
 		ExpectTable[i].l3_payload := omit;
+		ExpectTable[i].handoverRequestPointCode := omit;
 	}
 }
 
diff --git a/library/BSSMAP_Templates.ttcn b/library/BSSMAP_Templates.ttcn
index 4df39d4..b7230cd 100644
--- a/library/BSSMAP_Templates.ttcn
+++ b/library/BSSMAP_Templates.ttcn
@@ -307,7 +307,7 @@
 	}
 }
 
-template BSSMAP_IE_CellIdentifierList ts_BSSMAP_IE_CidList(BSSMAP_FIELD_CellIdentificationList cid_list) := {
+template BSSMAP_IE_CellIdentifierList ts_BSSMAP_IE_CidList(template BSSMAP_FIELD_CellIdentificationList cid_list) := {
 	elementIdentifier := '1A'O,
 	lengthIndicator := 0, /* overwritten */
 	cellIdentifierDiscriminator := '0000'B, /* overwritten */
@@ -315,31 +315,6 @@
 	cellIdentificationList := cid_list
 }
 
-template PDU_BSSAP ts_BSSMAP_HandoReq(BssmapCause cause, BSSMAP_FIELD_CellIdentificationList cid_list)
-modifies ts_BSSAP_BSSMAP := {
-	pdu := {
-		bssmap := {
-			handoverRequired := {
-				messageType := '11'O,
-				cause := ts_BSSMAP_IE_Cause(cause),
-				responseRequest := omit,
-				cellIdentifierList := ts_BSSMAP_IE_CidList(cid_list),
-				circuitPoolList := omit,
-				currentChannelType1 := omit,
-				speechVersion := omit,
-				queueingIndicator := omit,
-				oldToNewBSSInfo := omit,
-				sourceToTargetRNCTransparentInfo := omit,
-				sourceToTargetRNCTransparentInfoCDMA := omit,
-				gERANClassmark := omit,
-				talkerPriority := omit,
-				speechCodec := omit,
-				cSG_Identifier := omit
-			}
-		}
-	}
-}
-
 const OCT1 ChRate_ANY := '00'O;
 const OCT1 ChRate_TCHF	:= '08'O;
 const OCT1 ChRate_TCHH	:= '09'O;
@@ -703,6 +678,33 @@
 	}
 }
 
+template PDU_BSSAP ts_BSSMAP_HandoverRequired(BssmapCause cause,
+					      template BSSMAP_FIELD_CellIdentificationList cid_list)
+modifies ts_BSSAP_BSSMAP := {
+	pdu := {
+		bssmap := {
+			handoverRequired := {
+				messageType := '11'O,
+				cause := ts_BSSMAP_IE_Cause(cause),
+				responseRequest := omit,
+				cellIdentifierList := ts_BSSMAP_IE_CidList(cid_list),
+				circuitPoolList := omit,
+				currentChannelType1 := omit,
+				speechVersion := omit,
+				queueingIndicator := omit,
+				oldToNewBSSInfo := omit,
+				sourceToTargetRNCTransparentInfo := omit,
+				sourceToTargetRNCTransparentInfoCDMA := omit,
+				gERANClassmark := omit,
+				talkerPriority := omit,
+				speechCodec := omit,
+				cSG_Identifier := omit
+			}
+		}
+	}
+}
+
+
 template PDU_BSSAP tr_BSSMAP_HandoverRequired modifies tr_BSSAP_BSSMAP := {
 	pdu := {
 		bssmap := {
@@ -713,6 +715,38 @@
 	}
 }
 
+template PDU_BSSAP tr_BSSMAP_HandoverRequiredReject modifies tr_BSSAP_BSSMAP := {
+	pdu := {
+		bssmap := {
+			handoverRequiredReject := {
+				messageType := '1A'O
+			}
+		}
+	}
+}
+
+template PDU_BSSAP tr_BSSMAP_HandoverCommand
+modifies tr_BSSAP_BSSMAP := {
+	pdu := {
+		bssmap := {
+			handoverCommand := {
+				messageType := '13'O
+			}
+		}
+	}
+}
+
+template PDU_BSSAP tr_BSSMAP_HandoverSucceeded
+modifies tr_BSSAP_BSSMAP := {
+	pdu := {
+		bssmap := {
+			handoverSucceeded := {
+				messageType := '15'O
+			}
+		}
+	}
+}
+
 template (value) PDU_BSSAP ts_BSSMAP_HandoverCommand(octetstring layer3info)
 modifies ts_BSSAP_BSSMAP := {
 	pdu := {
@@ -751,6 +785,16 @@
 	}
 }
 
+template PDU_BSSAP tr_BSSMAP_HandoverRequest modifies tr_BSSAP_BSSMAP := {
+	pdu := {
+		bssmap := {
+			handoverRequest := {
+				messageType := '10'O
+			}
+		}
+	}
+}
+
 template PDU_BSSAP ts_BSSMAP_HandoverRequest(
 		template BSSMAP_IE_CircuitIdentityCode cic := omit,
 		template BSSMAP_IE_AoIP_TransportLayerAddress aoip_tla := omit,
@@ -826,6 +870,41 @@
 	}
 }
 
+template PDU_BSSAP ts_BSSMAP_HandoverRequestAcknowledge(
+			template octetstring layer3info,
+			template LIN1 layer3infoLength,
+			template BSSMAP_IE_AoIP_TransportLayerAddress aoIPTransportLayer := omit,
+			template BSSMAP_IE_SpeechCodec speechCodec := omit,
+			template BSSMAP_IE_ChosenChannel chosenChannel := omit,
+			template BSSMAP_IE_ChosenEncryptionAlgorithm chosenEncryptionAlgorithm := omit)
+modifies ts_BSSAP_BSSMAP := {
+	pdu := {
+		bssmap := {
+			handoverRequestAck := {
+				messageType := '12'O,
+				layer3Information := {
+					elementIdentifier := '17'O,
+					lengthIndicator := layer3infoLength,
+					layer3info := layer3info
+				},
+				chosenChannel := chosenChannel,
+				chosenEncryptionAlgorithm := chosenEncryptionAlgorithm,
+				circuitPool := omit,
+				speechVersion := omit,
+				circuitIdentityCode := omit,
+				lSAIdentifier := omit,
+				newBSSToOldBSSInfo := omit,
+				interSystemInformation := omit,
+				talkerPriority := omit,
+				aoIPTransportLayer := aoIPTransportLayer,
+				codecList := omit,
+				speechCodec := speechCodec,
+				lCLS_bSS_Status := omit
+			}
+		}
+	}
+}
+
 template PDU_BSSAP tr_BSSMAP_HandoverDetect
 modifies tr_BSSAP_BSSMAP := {
 	pdu := {
@@ -838,6 +917,18 @@
 	}
 }
 
+template PDU_BSSAP ts_BSSMAP_HandoverDetect
+modifies ts_BSSAP_BSSMAP := {
+	pdu := {
+		bssmap := {
+			handoverDetect := {
+				messageType := '1B'O,
+				talkerPriority := omit
+			}
+		}
+	}
+}
+
 template PDU_BSSAP tr_BSSMAP_HandoverComplete
 modifies tr_BSSAP_BSSMAP := {
 	pdu := {
@@ -856,6 +947,24 @@
 	}
 }
 
+template PDU_BSSAP ts_BSSMAP_HandoverComplete
+modifies ts_BSSAP_BSSMAP := {
+	pdu := {
+		bssmap := {
+			handoverComplete := {
+				messageType := '14'O,
+				rR_Cause := omit,
+				talkerPriority := omit,
+				speechCodec := omit,
+				codecList := omit,
+				chosenEncryptionAlgorithm := omit,
+				chosenChannel := omit,
+				lCLS_BSS_Status := omit
+			}
+		}
+	}
+}
+
 template PDU_BSSAP tr_BSSMAP_HandoverPerformed
 modifies tr_BSSAP_BSSMAP := {
 	pdu := {
@@ -975,7 +1084,7 @@
 				messageType := '52'O,
 				iMSI := ts_BSSMAP_Imsi(imsi_digits),
 				tMSI := f_tmsi_or_omit(tmsi),
-				cellIdentifierList := ts_BSSMAP_IE_CidList(valueof(cid_list)),
+				cellIdentifierList := ts_BSSMAP_IE_CidList(cid_list),
 				channelNeeded := chneed,
 				eMLPP_Priority := omit,
 				pagingInformation := omit /* only VGCS/VBS flag */
diff --git a/library/GSUP_Types.ttcn b/library/GSUP_Types.ttcn
index c024d37..3a0d4e5 100644
--- a/library/GSUP_Types.ttcn
+++ b/library/GSUP_Types.ttcn
@@ -55,7 +55,16 @@
 	OSMO_GSUP_SM_ALERT_RSN_IE	('46'O),
 
 	OSMO_GSUP_IMEI_IE		('50'O),
-	OSMO_GSUP_IMEI_RESULT_IE	('51'O)
+	OSMO_GSUP_IMEI_RESULT_IE	('51'O),
+
+	OSMO_GSUP_KIND_IE		('0a'O),
+
+	OSMO_GSUP_SOURCE_NAME_IE	('60'O),
+	OSMO_GSUP_DESTINATION_NAME_IE	('61'O),
+	OSMO_GSUP_AN_APDU_IE		('62'O),
+	OSMO_GSUP_CAUSE_RR_IE		('63'O),
+	OSMO_GSUP_CAUSE_BSSAP_IE	('64'O),
+	OSMO_GSUP_CAUSE_SM_IE		('65'O)
 } with { variant "FIELDLENGTH(8)" };
 
 type enumerated GSUP_MessageType {
@@ -103,7 +112,27 @@
 
 	OSMO_GSUP_MSGT_CHECK_IMEI_REQUEST	('00110000'B),
 	OSMO_GSUP_MSGT_CHECK_IMEI_ERROR		('00110001'B),
-	OSMO_GSUP_MSGT_CHECK_IMEI_RESULT	('00110010'B)
+	OSMO_GSUP_MSGT_CHECK_IMEI_RESULT	('00110010'B),
+
+	OSMO_GSUP_MSGT_E_PREPARE_HANDOVER_REQUEST		('00110100'B),
+	OSMO_GSUP_MSGT_E_PREPARE_HANDOVER_ERROR			('00110101'B),
+	OSMO_GSUP_MSGT_E_PREPARE_HANDOVER_RESULT		('00110110'B),
+
+	OSMO_GSUP_MSGT_E_PREPARE_SUBSEQUENT_HANDOVER_REQUEST	('00111000'B),
+	OSMO_GSUP_MSGT_E_PREPARE_SUBSEQUENT_HANDOVER_ERROR	('00111001'B),
+	OSMO_GSUP_MSGT_E_PREPARE_SUBSEQUENT_HANDOVER_RESULT	('00111010'B),
+
+	OSMO_GSUP_MSGT_E_SEND_END_SIGNAL_REQUEST		('00111100'B),
+	OSMO_GSUP_MSGT_E_SEND_END_SIGNAL_ERROR			('00111101'B),
+	OSMO_GSUP_MSGT_E_SEND_END_SIGNAL_RESULT			('00111110'B),
+
+	OSMO_GSUP_MSGT_E_PROCESS_ACCESS_SIGNALLING_REQUEST	('01000000'B),
+	OSMO_GSUP_MSGT_E_FORWARD_ACCESS_SIGNALLING_REQUEST	('01000100'B),
+
+	OSMO_GSUP_MSGT_E_CLOSE					('01000111'B),
+	OSMO_GSUP_MSGT_E_ABORT					('01001011'B),
+
+	OSMO_GSUP_MSGT_E_ROUTING_ERROR				('01001110'B)
 } with { variant "FIELDLENGTH(8)" };
 
 type enumerated GSUP_CancelType {
@@ -128,6 +157,14 @@
 	OSMO_GSUP_SESSION_STATE_END		(3)
 } with { variant "FIELDLENGTH(8)" };
 
+type enumerated GSUP_Kind {
+	OSMO_GSUP_KIND_UNSET			(0),
+	OSMO_GSUP_KIND_SUBSCRIBER_MANAGEMENT	(1),
+	OSMO_GSUP_KIND_SMS			(2),
+	OSMO_GSUP_KIND_USSD			(3),
+	OSMO_GSUP_KIND_INTER_MSC		(4)
+} with { variant "FIELDLENGTH(8)" };
+
 type record GSUP_MSISDN {
 	uint8_t	len,
 	hexstring digits optional
@@ -138,6 +175,16 @@
 	hexstring digits optional
 } with { variant (len) "LENGTHTO(digits)" };
 
+type enumerated GSUP_AN_PROTO {
+	OSMO_GSUP_AN_PROTO_48006 (1),
+	OSMO_GSUP_AN_PROTO_25413 (2)
+} with { variant "FIELDLENGTH(8)" };
+
+type record GSUP_AN_APDU {
+	GSUP_AN_PROTO proto,
+	octetstring pdu
+};
+
 type record GSUP_IE {
 	GSUP_IEI	tag,
 	uint8_t		len,
@@ -175,6 +222,13 @@
 				 sm_alert_rsn, tag = OSMO_GSUP_SM_ALERT_RSN_IE;
 				 imei, tag = OSMO_GSUP_IMEI_IE;
 				 imei_result, tag = OSMO_GSUP_IMEI_RESULT_IE;
+				 kind, tag = OSMO_GSUP_KIND_IE;
+				 source_name, tag = OSMO_GSUP_SOURCE_NAME_IE;
+				 destination_name, tag = OSMO_GSUP_DESTINATION_NAME_IE;
+				 an_apdu, tag = OSMO_GSUP_AN_APDU_IE;
+				 cause_rr, tag = OSMO_GSUP_CAUSE_RR_IE;
+				 cause_bssap, tag = OSMO_GSUP_CAUSE_BSSAP_IE;
+				 cause_sm, tag = OSMO_GSUP_CAUSE_SM_IE;
 			)"
 };
 
@@ -219,7 +273,18 @@
 	GSUP_SM_ALERT_RSN_Type	sm_alert_rsn,
 
 	GSUP_IMEI		imei,
-	GSUP_IMEIResult		imei_result
+	GSUP_IMEIResult		imei_result,
+
+	GSUP_Kind		kind,
+
+	octetstring		source_name,
+	octetstring		destination_name,
+
+	GSUP_AN_APDU		an_apdu,
+
+	OCT1			cause_rr,
+	OCT1			cause_bssap,
+	OCT1			cause_sm
 };
 
 type record GSUP_PDU {
@@ -930,6 +995,70 @@
 	}
 }
 
+template GSUP_IE tr_GSUP_IE_Kind(template GSUP_Kind val) := {
+	tag := OSMO_GSUP_KIND_IE,
+	len := ?,
+	val := {
+		kind := val
+	}
+}
+
+template (value) GSUP_IE ts_GSUP_IE_Kind(GSUP_Kind val) := {
+	tag := OSMO_GSUP_KIND_IE,
+	len := 0, /* overwritten */
+	val := {
+		kind := val
+	}
+}
+
+template GSUP_IE tr_GSUP_IE_Source_Name(template octetstring name) := {
+	tag := OSMO_GSUP_SOURCE_NAME_IE,
+	len := ?,
+	val := {
+		source_name := name
+	}
+}
+
+template (value) GSUP_IE ts_GSUP_IE_Source_Name(octetstring name) := {
+	tag := OSMO_GSUP_SOURCE_NAME_IE,
+	len := 0, /* overwritten */
+	val := {
+		source_name := name
+	}
+}
+
+template GSUP_IE tr_GSUP_IE_Destination_Name(template octetstring name) := {
+	tag := OSMO_GSUP_DESTINATION_NAME_IE,
+	len := ?,
+	val := {
+		destination_name := name
+	}
+}
+
+template (value) GSUP_IE ts_GSUP_IE_Destination_Name(octetstring name) := {
+	tag := OSMO_GSUP_DESTINATION_NAME_IE,
+	len := 0, /* overwritten */
+	val := {
+		destination_name := name
+	}
+}
+
+template GSUP_IE tr_GSUP_IE_AN_APDU(template GSUP_AN_APDU an_apdu) := {
+	tag := OSMO_GSUP_AN_APDU_IE,
+	len := ?,
+	val := {
+		an_apdu := an_apdu
+	}
+}
+
+template (value) GSUP_IE ts_GSUP_IE_AN_APDU(GSUP_AN_APDU an_apdu) := {
+	tag := OSMO_GSUP_AN_APDU_IE,
+	len := 0, /* overwritten */
+	val := {
+		an_apdu := an_apdu
+	}
+}
+
 private function f_gen_ts_ss_ies(
 	hexstring imsi,
 	OCT4 sid,
@@ -962,14 +1091,20 @@
 		tr_GSUP_IE_SessionId(sid),
 		tr_GSUP_IE_SessionState(state)
 	};
+	var integer last_idx := 3;
 
 	/* Optional SS payload */
 	if (istemplatekind(ss, "*")) {
 		ies[3] := *;
+		last_idx := last_idx + 1;
 	} else if (not istemplatekind(ss, "omit")) {
 		ies[3] := tr_GSUP_IE_SSInfo(ss);
+		last_idx := last_idx + 1;
 	}
 
+	ies[last_idx] := tr_GSUP_IE_Kind(OSMO_GSUP_KIND_USSD);
+	last_idx := last_idx + 1;
+
 	return ies;
 }
 
@@ -1036,7 +1171,8 @@
 		tr_GSUP_IE_IMSI(imsi),
 		tr_GSUP_IE_Cause(cause),
 		tr_GSUP_IE_SessionId(sid),
-		tr_GSUP_IE_SessionState(state)
+		tr_GSUP_IE_SessionState(state),
+		tr_GSUP_IE_Kind(OSMO_GSUP_KIND_SMS)
 	}
 );
 
@@ -1069,7 +1205,8 @@
 		tr_GSUP_IE_SM_RP_MR(sm_rp_mr),
 		tr_GSUP_IE_SM_RP_DA(sm_rp_da),
 		tr_GSUP_IE_SM_RP_OA(sm_rp_oa),
-		tr_GSUP_IE_SM_RP_UI(sm_rp_ui)
+		tr_GSUP_IE_SM_RP_UI(sm_rp_ui),
+		tr_GSUP_IE_Kind(OSMO_GSUP_KIND_SMS)
 	}
 );
 
@@ -1090,7 +1227,8 @@
 	OSMO_GSUP_MSGT_MO_FORWARD_SM_RESULT,
 	{
 		tr_GSUP_IE_IMSI(imsi),
-		tr_GSUP_IE_SM_RP_MR(sm_rp_mr)
+		tr_GSUP_IE_SM_RP_MR(sm_rp_mr),
+		tr_GSUP_IE_Kind(OSMO_GSUP_KIND_SMS)
 	}
 );
 
@@ -1115,7 +1253,8 @@
 	{
 		tr_GSUP_IE_IMSI(imsi),
 		tr_GSUP_IE_SM_RP_MR(sm_rp_mr),
-		tr_GSUP_IE_SM_RP_CAUSE(sm_rp_cause)
+		tr_GSUP_IE_SM_RP_CAUSE(sm_rp_cause),
+		tr_GSUP_IE_Kind(OSMO_GSUP_KIND_SMS)
 	}
 );
 
@@ -1162,7 +1301,8 @@
 		tr_GSUP_IE_SM_RP_DA(sm_rp_da),
 		tr_GSUP_IE_SM_RP_OA(sm_rp_oa),
 		tr_GSUP_IE_SM_RP_UI(sm_rp_ui),
-		tr_GSUP_IE_SM_RP_MMS(sm_rp_mms)
+		tr_GSUP_IE_SM_RP_MMS(sm_rp_mms),
+		tr_GSUP_IE_Kind(OSMO_GSUP_KIND_SMS)
 	}
 );
 
@@ -1183,7 +1323,8 @@
 	OSMO_GSUP_MSGT_MT_FORWARD_SM_RESULT,
 	{
 		tr_GSUP_IE_IMSI(imsi),
-		tr_GSUP_IE_SM_RP_MR(sm_rp_mr)
+		tr_GSUP_IE_SM_RP_MR(sm_rp_mr),
+		tr_GSUP_IE_Kind(OSMO_GSUP_KIND_SMS)
 	}
 );
 
@@ -1208,7 +1349,8 @@
 	{
 		tr_GSUP_IE_IMSI(imsi),
 		tr_GSUP_IE_SM_RP_MR(sm_rp_mr),
-		tr_GSUP_IE_SM_RP_CAUSE(sm_rp_cause)
+		tr_GSUP_IE_SM_RP_CAUSE(sm_rp_cause),
+		tr_GSUP_IE_Kind(OSMO_GSUP_KIND_SMS)
 	}
 );
 
@@ -1233,7 +1375,8 @@
 	{
 		tr_GSUP_IE_IMSI(imsi),
 		tr_GSUP_IE_SM_RP_MR(sm_rp_mr),
-		tr_GSUP_IE_SM_ALERT_RSN(sm_alert_rsn)
+		tr_GSUP_IE_SM_ALERT_RSN(sm_alert_rsn),
+		tr_GSUP_IE_Kind(OSMO_GSUP_KIND_SMS)
 	}
 );
 
@@ -1254,7 +1397,8 @@
 	OSMO_GSUP_MSGT_READY_FOR_SM_RESULT,
 	{
 		tr_GSUP_IE_IMSI(imsi),
-		tr_GSUP_IE_SM_RP_MR(sm_rp_mr)
+		tr_GSUP_IE_SM_RP_MR(sm_rp_mr),
+		tr_GSUP_IE_Kind(OSMO_GSUP_KIND_SMS)
 	}
 );
 
@@ -1279,7 +1423,8 @@
 	{
 		tr_GSUP_IE_IMSI(imsi),
 		tr_GSUP_IE_SM_RP_MR(sm_rp_mr),
-		tr_GSUP_IE_SM_RP_CAUSE(sm_rp_cause)
+		tr_GSUP_IE_SM_RP_CAUSE(sm_rp_cause),
+		tr_GSUP_IE_Kind(OSMO_GSUP_KIND_SMS)
 	}
 );
 
@@ -1293,5 +1438,79 @@
 		return false;
 }
 
+template GSUP_AN_APDU t_GSUP_AN_APDU(
+	template GSUP_AN_PROTO an_proto := ?,
+	template octetstring pdu := ?
+) := {
+	proto := an_proto,
+	pdu := pdu
+};
+
+template GSUP_PDU tr_GSUP_E_AN_APDU(
+	template GSUP_MessageType msgt,
+	template hexstring imsi := ?,
+	template octetstring source_name := ?,
+	template octetstring destination_name := ?,
+	template GSUP_AN_APDU an_apdu := ?
+) := tr_GSUP(
+	msgt,
+	{
+		tr_GSUP_IE_IMSI(imsi),
+		tr_GSUP_IE_Kind(OSMO_GSUP_KIND_INTER_MSC),
+		tr_GSUP_IE_Source_Name(source_name),
+		tr_GSUP_IE_Destination_Name(destination_name),
+		tr_GSUP_IE_AN_APDU(an_apdu)
+	}
+);
+
+template GSUP_PDU tr_GSUP_E_NO_PDU(
+	template GSUP_MessageType msgt,
+	template hexstring imsi := ?,
+	template octetstring source_name := ?,
+	template octetstring destination_name := ?
+) := tr_GSUP(
+	msgt,
+	{
+		tr_GSUP_IE_IMSI(imsi),
+		tr_GSUP_IE_Kind(OSMO_GSUP_KIND_INTER_MSC),
+		tr_GSUP_IE_Source_Name(source_name),
+		tr_GSUP_IE_Destination_Name(destination_name)
+	}
+);
+
+template (value) GSUP_PDU ts_GSUP_E_AN_APDU(
+	GSUP_MessageType msgt,
+	hexstring imsi,
+	octetstring source_name,
+	octetstring destination_name,
+	GSUP_AN_APDU an_apdu
+) := ts_GSUP(
+	msgt,
+	{
+		valueof(ts_GSUP_IE_IMSI(imsi)),
+		valueof(ts_GSUP_IE_Kind(OSMO_GSUP_KIND_INTER_MSC)),
+		valueof(ts_GSUP_IE_Source_Name(source_name)),
+		valueof(ts_GSUP_IE_Destination_Name(destination_name)),
+		valueof(ts_GSUP_IE_AN_APDU(an_apdu))
+	}
+);
+
+template (value) GSUP_PDU ts_GSUP_E_PrepareHandoverResult(
+	hexstring imsi,
+	hexstring msisdn,
+	octetstring source_name,
+	octetstring destination_name,
+	GSUP_AN_APDU an_apdu
+) := ts_GSUP(
+	OSMO_GSUP_MSGT_E_PREPARE_HANDOVER_RESULT,
+	{
+		valueof(ts_GSUP_IE_IMSI(imsi)),
+		valueof(ts_GSUP_IE_MSISDN(msisdn)),
+		valueof(ts_GSUP_IE_Kind(OSMO_GSUP_KIND_INTER_MSC)),
+		valueof(ts_GSUP_IE_Source_Name(source_name)),
+		valueof(ts_GSUP_IE_Destination_Name(destination_name)),
+		valueof(ts_GSUP_IE_AN_APDU(an_apdu))
+	}
+);
 
 } with { encode "RAW"; variant "FIELDORDER(msb)" }
diff --git a/library/L3_Templates.ttcn b/library/L3_Templates.ttcn
index 6099303..cf6d64c 100644
--- a/library/L3_Templates.ttcn
+++ b/library/L3_Templates.ttcn
@@ -582,6 +582,59 @@
 	}
 }
 
+template PDU_ML3_NW_MS tr_RR_HandoverCommand := {
+	discriminator := '0110'B,
+	tiOrSkip := {
+		skipIndicator := '0000'B
+	},
+	msgs := {
+		rrm := {
+			handoverCommand := {
+				messageType := '00101011'B,
+				cellDescription := ?,
+				channelDescription2 := ?,
+				handoverReference := ?,
+				powerCommandAndAccesstype := ?,
+				synchronizationIndication := *,
+				frequencyShortListAfterTime := *,
+				frequencyListAfterTime := *,
+				cellChannelDescription := *,
+				multislotAllocation := *,
+				modeOfChannelSet1 := *,
+				modeOfChannelSet2 := *,
+				modeOfChannelSet3 := *,
+				modeOfChannelSet4 := *,
+				modeOfChannelSet5 := *,
+				modeOfChannelSet6 := *,
+				modeOfChannelSet7 := *,
+				modeOfChannelSet8 := *,
+				descrOf2ndCh_at := *,
+				modeOf2ndChannel := *,
+				frequencyChannelSequence_at := *,
+				mobileAllocation_at := *,
+				startingTime := *,
+				timeDifference := *,
+				timingAdvance := *,
+				frequencyShortListBeforeTime := *,
+				frequencyListBeforeTime := *,
+				descrOf1stCh_bt := *,
+				descrOf2ndCh_bt := *,
+				frequencyChannelSequence_bt := *,
+				mobileAllocation_bt := *,
+				cipherModeSetting := *,
+				vGCS_TargetModeIndication := *,
+				multiRateConfiguration := *,
+				dynamicARFCN_Mapping := *,
+				vGCS_Ciphering_Parameters := *,
+				dedicatedServiceInformation := *,
+				pLMNIndex := *,
+				extendedTSCSet_afterTime := *,
+				extendedTSCSet_beforeTime := *
+			}
+		}
+	}
+}
+
 function ts_CM3_TLV(template (omit) OCTN cm3) return template MobileStationClassmark3_TLV {
 	if (not isvalue(cm3)) {
 		return omit;
@@ -1271,12 +1324,12 @@
 }
 
 
-template (value) PDU_ML3_MS_NW ts_ML3_MO_CC_REL_COMPL(integer tid) := {
+template (value) PDU_ML3_MS_NW ts_ML3_MO_CC_REL_COMPL(integer tid, BIT1 tid_remote := '0'B) := {
 	discriminator := '0011'B,
 	tiOrSkip := {
 		transactionId := {
 			tio := int2bit(tid, 3),
-			tiFlag := '0'B,
+			tiFlag := tid_remote,
 			tIExtension := omit
 		}
 	},
diff --git a/msc/BSC_ConnectionHandler.ttcn b/msc/BSC_ConnectionHandler.ttcn
index 833c31f..25444b2 100644
--- a/msc/BSC_ConnectionHandler.ttcn
+++ b/msc/BSC_ConnectionHandler.ttcn
@@ -411,6 +411,8 @@
 	/* CC related parameters */
 	hexstring called_party,				/* whom are we calling */
 	integer transaction_id optional,		/* which TS 04.08 CC transaction ID to use */
+	boolean mo_call,				/* For a MO call, the transaction_id was allocated by the MS,
+							   important to set the TI flag properly */
 	BearerCapability_TLV bearer_cap,		/* which bearer capabilities to claim */
 	boolean emergency,				/* is this an emergency call? */
 
@@ -441,6 +443,7 @@
 template (value) CallParameters t_CallParams(hexstring called, integer tid) := {
 	called_party := called,
 	transaction_id := tid,
+	mo_call := false,
 	bearer_cap := valueof(ts_Bcap_voice),
 	emergency := false,
 	mncc_callref := omit,
@@ -455,6 +458,7 @@
 	mgw_rtp_port_mss := 11000,
 	rtp_payload_type := 98,
 	rtp_sdp_format := "AMR/8000",
+	mgw_drop_dlcx := false,
 	mgcp_call_id := omit,
 	mgcp_ep := omit,
 	mgcp_connection_id_bss := '0'H,//
@@ -774,17 +778,24 @@
 	MNCC.send(ts_MNCC_DISC_req(cpars.mncc_callref, valueof(ts_MNCC_cause(23))));
 	BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_DISC(cpars.transaction_id)));
 
+	log("f_call_hangup 1: rx DTAP CC DISC");
+
 	if (release_by_ms) {
-		log("f_call_hangup 1a");
+		var BIT1 tid_remote := '1'B;
+		if (cpars.mo_call) {
+			tid_remote := '0'B;
+		}
 		/* B-side (MS) Release of call */
-		BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_RELEASE(cpars.transaction_id, '1'B, '0000000'B)));
+		BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_RELEASE(cpars.transaction_id, tid_remote, '0000000'B)));
 		MNCC.receive(tr_MNCC_REL_ind(cpars.mncc_callref));
+		log("f_call_hangup 2: rx MNCC REL ind");
 		BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_REL_COMPL(cpars.transaction_id)));
+		log("f_call_hangup 3: rx DTAP CC REL COMPL");
 	} else {
-		log("f_call_hangup 1b");
 		/* A-side (PLMN) Release of call */
 		MNCC.send(ts_MNCC_REL_req(cpars.mncc_callref, valueof(ts_MNCC_cause(42))));
 		BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_RELEASE(cpars.transaction_id)));
+		log("f_call_hangup 4: rx DTAP CC RELEASE");
 		BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_REL_COMPL(cpars.transaction_id)));
 	}
 
@@ -795,13 +806,13 @@
 	/* clearing of radio channel */
 	interleave {
 	[] BSSAP.receive(t_clear) {
-		log("f_call_hangup 2");
+		log("f_call_hangup 5: rx BSSAP Clear Command");
 		BSSAP.send(ts_BSSMAP_ClearComplete);
 		BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
-		log("f_call_hangup 3");
+		log("f_call_hangup 6: rx SCCP DISC");
 		}
 	[] MGCP.receive(tr_DLCX(?)) -> value mgcp_cmd {
-			log("f_call_hangup 4");
+			log("f_call_hangup 7: rx MGCP DLCX");
 			if (respond_to_dlcx) {
 				MGCP.send(ts_DLCX_ACK2(mgcp_cmd.line.trans_id));
 			}
@@ -813,18 +824,17 @@
 	 * Unless the first DLCX did not contain a CI, in which case it was a wildcard DLCX for both. */
 	if (dlcx_contained_ci) {
 		MGCP.receive(tr_DLCX(?)) -> value mgcp_cmd {
-				log("f_call_hangup 5");
-				if (respond_to_dlcx) {
-					MGCP.send(ts_DLCX_ACK2(mgcp_cmd.line.trans_id));
-				}
+			log("f_call_hangup 8: rx MGCP DLCX");
+			if (respond_to_dlcx) {
+				MGCP.send(ts_DLCX_ACK2(mgcp_cmd.line.trans_id));
 			}
 		}
 	}
 
 	f_create_mgcp_delete_ep(cpars.mgcp_ep);
+	log("f_call_hangup 9: done");
 
 	deactivate(mdcx);
-	log("f_call_hangup DONE");
 
 	setverdict(pass);
 }
@@ -943,6 +953,27 @@
 	}
 }
 
+function f_create_bssmap_exp_handoverRequest(integer targetPointCode) runs on BSC_ConnHdlr {
+	BSSAP_PROC.call(BSSMAPEM_register_handoverRequest:{targetPointCode, self}) {
+		[] BSSAP_PROC.getreply(BSSMAPEM_register_handoverRequest:{?, ?}) {};
+	}
+}
+
+function f_bssmap_last_n_sd() runs on BSC_ConnHdlr return N_Sd_Array {
+	var N_Sd_Array last_n_sd;
+	BSSAP_PROC.call(BSSMAPEM_last_n_sd:{self, -}) {
+		[] BSSAP_PROC.getreply(BSSMAPEM_last_n_sd:{self, ?}) -> param(last_n_sd) {
+				return last_n_sd;
+			};
+	}
+}
+
+function f_bssmap_continue_after_n_sd(N_Sd_Array last_n_sd) runs on BSC_ConnHdlr {
+	BSSAP_PROC.call(BSSMAPEM_continue_after_n_sd:{last_n_sd, self}) {
+		[] BSSAP_PROC.getreply(BSSMAPEM_continue_after_n_sd:{last_n_sd, self});
+	}
+}
+
 type record SmsParametersTp {
 	OCT1		msg_ref,
 	TP_DA		da,
diff --git a/msc/MSC_Tests.ttcn b/msc/MSC_Tests.ttcn
index bf3c60e..957ea67 100644
--- a/msc/MSC_Tests.ttcn
+++ b/msc/MSC_Tests.ttcn
@@ -154,8 +154,16 @@
 	}
 }
 
-private altstep as_optional_cc_rel(CallParameters cpars) runs on BSC_ConnHdlr {
-	[] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_RELEASE(cpars.transaction_id))) { repeat; };
+private altstep as_optional_cc_rel(CallParameters cpars, boolean respond := false) runs on BSC_ConnHdlr {
+	[] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_RELEASE(cpars.transaction_id))) {
+			if (respond) {
+				var BIT1 tid_remote := '1'B;
+				if (cpars.mo_call) {
+					tid_remote := '0'B;
+				}
+				BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_REL_COMPL(cpars.transaction_id, tid_remote)));
+			}
+		}
 }
 
 function f_init_smpp(charstring id) runs on MTC_CT {
@@ -457,31 +465,6 @@
 	}
 }
 
-template PDU_BSSAP ts_BSSMAP_HandoReq(BssmapCause cause, BSSMAP_IE_CellIdentifierList cid_list)
-modifies ts_BSSAP_BSSMAP := {
-	pdu := {
-		bssmap := {
-			handoverRequired := {
-				messageType := '11'O,
-				cause := ts_BSSMAP_IE_Cause(cause),
-				responseRequest := omit,
-				cellIdentifierList := cid_list,
-				circuitPoolList := omit,
-				currentChannelType1 := omit,
-				speechVersion := omit,
-				queueingIndicator := omit,
-				oldToNewBSSInfo := omit,
-				sourceToTargetRNCTransparentInfo := omit,
-				sourceToTargetRNCTransparentInfoCDMA := omit,
-				gERANClassmark := omit,
-				talkerPriority := omit,
-				speechCodec := omit,
-				cSG_Identifier := omit
-			}
-		}
-	}
-}
-
 type function void_fn(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr;
 
 /* FIXME: move into BSC_ConnectionHandler? */
@@ -516,14 +499,14 @@
 	return pars;
 }
 
-function f_start_handler_with_pars(void_fn fn, BSC_ConnHdlrPars pars) runs on MTC_CT return BSC_ConnHdlr {
+function f_start_handler_with_pars(void_fn fn, BSC_ConnHdlrPars pars, integer bssap_idx := 0) runs on MTC_CT return BSC_ConnHdlr {
 	var BSC_ConnHdlr vc_conn;
-	var charstring id := testcasename();
+	var charstring id := testcasename() & int2str(bssap_idx);
 
 	vc_conn := BSC_ConnHdlr.create(id);
 	/* BSSMAP part / A interface */
-	connect(vc_conn:BSSAP, g_bssap[0].vc_BSSMAP:CLIENT);
-	connect(vc_conn:BSSAP_PROC, g_bssap[0].vc_BSSMAP:PROC);
+	connect(vc_conn:BSSAP, g_bssap[bssap_idx].vc_BSSMAP:CLIENT);
+	connect(vc_conn:BSSAP_PROC, g_bssap[bssap_idx].vc_BSSMAP:PROC);
 	/* MNCC part */
 	connect(vc_conn:MNCC, vc_MNCC:MNCC_CLIENT);
 	connect(vc_conn:MNCC_PROC, vc_MNCC:MNCC_PROC);
@@ -550,8 +533,9 @@
 	return vc_conn;
 }
 
-function f_start_handler(void_fn fn, integer imsi_suffix) runs on MTC_CT return BSC_ConnHdlr {
-	return f_start_handler_with_pars(fn, f_init_pars(imsi_suffix));
+
+function f_start_handler(void_fn fn, integer imsi_suffix, integer bssap_idx := 0) runs on MTC_CT return BSC_ConnHdlr {
+	return f_start_handler_with_pars(fn, f_init_pars(imsi_suffix), bssap_idx);
 }
 
 private function f_tc_lu_imsi_noauth_tmsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
@@ -4655,6 +4639,434 @@
    *
  */
 
+private function f_tc_ho_inter_bsc_unknown_cell(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
+	f_init_handler(pars);
+	var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
+	cpars.bss_rtp_port := 1110;
+	cpars.mgcp_connection_id_bss := '22222'H;
+	cpars.mgcp_connection_id_mss := '33333'H;
+	cpars.mgcp_ep := "rtpbridge/1 at mgw";
+	cpars.mo_call := true;
+
+	f_perform_lu();
+	f_mo_call_establish(cpars);
+
+	f_sleep(1.0);
+
+	var myBSSMAP_Cause cause_val := GSM0808_CAUSE_BETTER_CELL;
+	var BssmapCause cause := enum2int(cause_val);
+
+	var template BSSMAP_FIELD_CellIdentificationList cil;
+	cil := { cIl_LAI := { ts_BSSMAP_CI_LAI('023'H, '42'H, 999) } };
+
+	BSSAP.send(ts_BSSMAP_HandoverRequired(cause, cil));
+	BSSAP.receive(tr_BSSMAP_HandoverRequiredReject);
+
+	f_call_hangup(cpars, true);
+}
+testcase TC_ho_inter_bsc_unknown_cell() runs on MTC_CT {
+	var BSC_ConnHdlr vc_conn;
+	f_init();
+
+	vc_conn := f_start_handler(refers(f_tc_ho_inter_bsc_unknown_cell), 53);
+	vc_conn.done;
+}
+
+private altstep as_mgcp_ack_all_mdcx(CallParameters cpars) runs on BSC_ConnHdlr {
+	var MgcpCommand mgcp_cmd;
+	[] MGCP.receive(tr_MDCX) -> value mgcp_cmd {
+			var SDP_Message sdp := valueof(ts_SDP(cpars.mgw_rtp_ip_mss, cpars.mgw_rtp_ip_mss,
+								hex2str(cpars.mgcp_call_id), "42",
+								cpars.mgw_rtp_port_mss,
+								{ int2str(cpars.rtp_payload_type) },
+								{ valueof(ts_SDP_rtpmap(cpars.rtp_payload_type,
+											cpars.rtp_sdp_format)),
+								  valueof(ts_SDP_ptime(20)) }));
+			MGCP.send(ts_MDCX_ACK(mgcp_cmd.line.trans_id, cpars.mgcp_connection_id_mss, sdp));
+			repeat;
+		}
+}
+
+private function f_tc_ho_inter_bsc0(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
+	var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
+	cpars.bss_rtp_port := 1110;
+	cpars.mgcp_connection_id_bss := '22222'H;
+	cpars.mgcp_connection_id_mss := '33333'H;
+	cpars.mgcp_ep := "rtpbridge/1 at mgw";
+	cpars.mo_call := true;
+
+	f_init_handler(pars);
+
+	f_perform_lu();
+	f_mo_call_establish(cpars);
+
+	f_sleep(1.0);
+
+	var default ack_mdcx := activate(as_mgcp_ack_all_mdcx(cpars));
+
+	var myBSSMAP_Cause cause_val := GSM0808_CAUSE_BETTER_CELL;
+	var BssmapCause cause := enum2int(cause_val);
+
+	var template BSSMAP_FIELD_CellIdentificationList cil;
+	cil := { cIl_LAI := { ts_BSSMAP_CI_LAI('023'H, '42'H, 5) } };
+
+	/* old BSS sends Handover Required */
+	BSSAP.send(ts_BSSMAP_HandoverRequired(cause, cil));
+
+	/* Now the action goes on in f_tc_ho_inter_bsc1() */
+
+	/* MSC forwards the RR Handover Command to old BSS */
+	var PDU_BSSAP ho_command;
+	BSSAP.receive(tr_BSSMAP_HandoverCommand) -> value ho_command;
+
+	log("GOT HandoverCommand", ho_command);
+
+	BSSAP.receive(tr_BSSMAP_HandoverSucceeded);
+
+	/* f_tc_ho_inter_bsc1() completes Handover, then expecting a Clear here. */
+	f_expect_clear();
+
+	log("FIRST inter-BSC Handover done");
+
+
+	/* ------------------------ */
+
+	/* Ok, that went well, now the other BSC is handovering back here --
+	 * from now on this here is the new BSS. */
+	f_create_bssmap_exp_handoverRequest(193);
+
+	var PDU_BSSAP ho_request;
+	BSSAP.receive(tr_BSSMAP_HandoverRequest) -> value ho_request;
+
+	/* new BSS composes a RR Handover Command */
+	var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
+	var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
+	var BSSMAP_IE_AoIP_TransportLayerAddress tla := valueof(ts_BSSMAP_IE_AoIP_TLA4('01020304'O, 2342));
+	BSSAP.send(ts_BSSMAP_HandoverRequestAcknowledge(rr_ho_cmd_enc, lengthof(rr_ho_cmd_enc),
+							tla, ts_BSSMAP_IE_SpeechCodec({ts_CodecFR})));
+
+	/* Now f_tc_ho_inter_bsc1() expects HandoverCommand */
+
+	f_sleep(0.5);
+
+	/* Notify that the MS is now over here */
+
+	BSSAP.send(ts_BSSMAP_HandoverDetect);
+	f_sleep(0.1);
+	BSSAP.send(ts_BSSMAP_HandoverComplete);
+
+	f_sleep(3.0);
+
+	deactivate(ack_mdcx);
+
+	var default ccrel := activate(as_optional_cc_rel(cpars, true));
+	f_call_hangup(cpars, true);
+	f_sleep(1.0);
+	deactivate(ccrel);
+
+	setverdict(pass);
+}
+private function f_tc_ho_inter_bsc1(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
+	f_init_handler(pars);
+	f_create_bssmap_exp_handoverRequest(194);
+
+	var PDU_BSSAP ho_request;
+	BSSAP.receive(tr_BSSMAP_HandoverRequest) -> value ho_request;
+
+	/* new BSS composes a RR Handover Command */
+	var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
+	var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
+	var BSSMAP_IE_AoIP_TransportLayerAddress tla := valueof(ts_BSSMAP_IE_AoIP_TLA4('01020304'O, 2342));
+	BSSAP.send(ts_BSSMAP_HandoverRequestAcknowledge(rr_ho_cmd_enc, lengthof(rr_ho_cmd_enc),
+							tla, ts_BSSMAP_IE_SpeechCodec({ts_CodecFR})));
+
+	/* Now f_tc_ho_inter_bsc0() expects HandoverCommand */
+
+	f_sleep(0.5);
+
+	/* Notify that the MS is now over here */
+
+	BSSAP.send(ts_BSSMAP_HandoverDetect);
+	f_sleep(0.1);
+	BSSAP.send(ts_BSSMAP_HandoverComplete);
+
+	f_sleep(3.0);
+
+	/* Now I'd like to f_call_hangup() but we don't know any cpars here. So
+	 * ... handover back to the first BSC :P */
+
+	var myBSSMAP_Cause cause_val := GSM0808_CAUSE_BETTER_CELL;
+	var BssmapCause cause := enum2int(cause_val);
+
+	var template BSSMAP_FIELD_CellIdentificationList cil;
+	cil := { cIl_LAI := { ts_BSSMAP_CI_LAI('262'H, '42'H, 23) } };
+
+	/* old BSS sends Handover Required */
+	BSSAP.send(ts_BSSMAP_HandoverRequired(cause, cil));
+
+	/* Now the action goes on in f_tc_ho_inter_bsc0() */
+
+	/* MSC forwards the RR Handover Command to old BSS */
+	var PDU_BSSAP ho_command;
+	BSSAP.receive(tr_BSSMAP_HandoverCommand) -> value ho_command;
+
+	log("GOT HandoverCommand", ho_command);
+
+	BSSAP.receive(tr_BSSMAP_HandoverSucceeded);
+
+	/* f_tc_ho_inter_bsc1() completes Handover, then expecting a Clear here. */
+	f_expect_clear();
+	setverdict(pass);
+}
+testcase TC_ho_inter_bsc() runs on MTC_CT {
+	var BSC_ConnHdlr vc_conn0;
+	var BSC_ConnHdlr vc_conn1;
+	f_init(2);
+
+	var BSC_ConnHdlrPars pars0 := f_init_pars(53);
+	var BSC_ConnHdlrPars pars1 := f_init_pars(53);
+
+	vc_conn0 := f_start_handler_with_pars(refers(f_tc_ho_inter_bsc0), pars0, 0);
+	vc_conn1 := f_start_handler_with_pars(refers(f_tc_ho_inter_bsc1), pars1, 1);
+	vc_conn0.done;
+	vc_conn1.done;
+}
+
+function f_ML3_patch_seq_nr_MS_NW(in uint2_t seq_nr, inout octetstring enc_l3) {
+	log("MS_NW patching N(SD)=", seq_nr, " into dtap ", enc_l3);
+	enc_l3[2] := (enc_l3[2] and4b '3f'O) or4b bit2oct(int2bit(seq_nr, 8) << 6);
+	log("MS_NW patched enc_l3: ", enc_l3);
+}
+
+private function f_tc_ho_inter_msc_out(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
+	var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
+	cpars.bss_rtp_port := 1110;
+	cpars.mgcp_connection_id_bss := '22222'H;
+	cpars.mgcp_connection_id_mss := '33333'H;
+	cpars.mgcp_ep := "rtpbridge/1 at mgw";
+	cpars.mo_call := true;
+	var hexstring ho_number := f_gen_msisdn(99999);
+
+	f_init_handler(pars);
+
+	f_create_mncc_expect(hex2str(ho_number));
+
+	f_perform_lu();
+	f_mo_call_establish(cpars);
+
+	f_sleep(1.0);
+
+	var default ack_mdcx := activate(as_mgcp_ack_all_mdcx(cpars));
+
+	var myBSSMAP_Cause cause_val := GSM0808_CAUSE_BETTER_CELL;
+	var BssmapCause cause := enum2int(cause_val);
+
+	var template BSSMAP_FIELD_CellIdentificationList cil;
+	cil := { cIl_LAI := { ts_BSSMAP_CI_LAI('017'H, '017'H, 1) } };
+
+	/* old BSS sends Handover Required */
+	BSSAP.send(ts_BSSMAP_HandoverRequired(cause, cil));
+
+	/* The target cell 017-017 LAC 1 is configured to be a remote MSC of name "msc-017-017-1".
+	 * This MSC tries to reach the other MSC via GSUP. */
+
+	var octetstring remote_msc_name := '6D73632D3031372D3031372D31'O; /* "msc-017-017-1" as octetstring */
+	var GSUP_PDU prep_ho_req;
+	GSUP.receive(tr_GSUP_E_AN_APDU(OSMO_GSUP_MSGT_E_PREPARE_HANDOVER_REQUEST,
+				pars.imsi, destination_name := remote_msc_name)) -> value prep_ho_req;
+
+	var GSUP_IeValue source_name_ie;
+	f_gsup_find_ie(prep_ho_req, OSMO_GSUP_SOURCE_NAME_IE, source_name_ie);
+	var octetstring local_msc_name := source_name_ie.source_name;
+
+	/* Remote MSC has figured out its BSC and signals success */
+	var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
+	var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
+	var PDU_BSSAP ho_req_ack := valueof(ts_BSSMAP_HandoverRequestAcknowledge(rr_ho_cmd_enc, lengthof(rr_ho_cmd_enc),
+					aoIPTransportLayer := omit,
+					speechCodec := ts_BSSMAP_IE_SpeechCodec({ts_CodecFR})));
+	GSUP.send(ts_GSUP_E_PrepareHandoverResult(
+				pars.imsi,
+				ho_number,
+				remote_msc_name, local_msc_name,
+				valueof(t_GSUP_AN_APDU(OSMO_GSUP_AN_PROTO_48006, enc_PDU_BSSAP(ho_req_ack)))));
+
+	/* MSC forwards the RR Handover Command to old BSS */
+	BSSAP.receive(tr_BSSMAP_HandoverCommand);
+
+	/* The MS shows up at remote new BSS */
+
+	GSUP.send(ts_GSUP_E_AN_APDU(OSMO_GSUP_MSGT_E_PROCESS_ACCESS_SIGNALLING_REQUEST,
+				pars.imsi, remote_msc_name, local_msc_name,
+				valueof(t_GSUP_AN_APDU(OSMO_GSUP_AN_PROTO_48006,
+						enc_PDU_BSSAP(valueof(ts_BSSMAP_HandoverDetect))))));
+	BSSAP.receive(tr_BSSMAP_HandoverSucceeded);
+	f_sleep(0.1);
+
+	/* Save the MS sequence counters for use on the other connection */
+	var N_Sd_Array last_n_sd := f_bssmap_last_n_sd();
+
+	GSUP.send(ts_GSUP_E_AN_APDU(OSMO_GSUP_MSGT_E_SEND_END_SIGNAL_REQUEST,
+				pars.imsi, remote_msc_name, local_msc_name,
+				valueof(t_GSUP_AN_APDU(OSMO_GSUP_AN_PROTO_48006,
+						enc_PDU_BSSAP(valueof(ts_BSSMAP_HandoverComplete))))));
+
+	/* The local BSS conn clears, all communication goes via remote MSC now */
+	f_expect_clear();
+
+	/**********************************/
+	/* Play through some signalling across the inter-MSC link.
+	 * This is a copy of f_tc_lu_and_mo_ussd_single_request() translated into GSUP AN-APDUs. */
+
+	var template OCTN facility_req := f_USSD_FACILITY_IE_INVOKE(
+		invoke_id := 5, /* Phone may not start from 0 or 1 */
+		op_code := SS_OP_CODE_PROCESS_USS_REQ,
+		ussd_string := "*#100#"
+	);
+
+	var template OCTN facility_rsp := f_USSD_FACILITY_IE_RETURN_RESULT(
+		invoke_id := 5, /* InvokeID shall be the same for both REQ and RSP */
+		op_code := SS_OP_CODE_PROCESS_USS_REQ,
+		ussd_string := "Your extension is " & hex2str(g_pars.msisdn) & "\r"
+	)
+
+	/* Compose a new SS/REGISTER message with request */
+	var template (value) PDU_ML3_MS_NW ussd_req := ts_ML3_MO_SS_REGISTER(
+		tid := 1, /* We just need a single transaction */
+		ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
+		facility := valueof(facility_req)
+	);
+	var PDU_ML3_MS_NW ussd_req_v := valueof(ussd_req);
+
+	/* Compose SS/RELEASE_COMPLETE template with expected response */
+	var template PDU_ML3_NW_MS ussd_rsp := tr_ML3_MT_SS_RELEASE_COMPLETE(
+		tid := 1, /* Response should arrive within the same transaction */
+		ti_flag := c_TIF_REPL, /* Sent to the side that originates the TI */
+		facility := valueof(facility_rsp)
+	);
+
+	/* Compose expected MSC -> HLR message */
+	var template GSUP_PDU gsup_req := tr_GSUP_PROC_SS_REQ(
+		imsi := g_pars.imsi,
+		state := OSMO_GSUP_SESSION_STATE_BEGIN,
+		ss := valueof(facility_req)
+	);
+
+	/* To be used for sending response with correct session ID */
+	var GSUP_PDU gsup_req_complete;
+
+	/* Request own number */
+	/* From remote MSC instead of BSSAP directly */
+	/* Patch the correct N_SD value into the message. */
+	var octetstring l3_enc := enc_PDU_ML3_MS_NW(ussd_req_v);
+	var BSSMAP_Emulation.ConnectionData cd;
+	f_ML3_patch_seq_nr_MS_NW(f_next_n_sd(last_n_sd, f_ML3_n_sd_idx(ussd_req_v)), l3_enc);
+	GSUP.send(ts_GSUP_E_AN_APDU(OSMO_GSUP_MSGT_E_PROCESS_ACCESS_SIGNALLING_REQUEST,
+				pars.imsi, remote_msc_name, local_msc_name,
+				valueof(t_GSUP_AN_APDU(OSMO_GSUP_AN_PROTO_48006,
+						enc_PDU_BSSAP(valueof(ts_BSSAP_DTAP(l3_enc)))
+						))
+				));
+
+	/* Expect GSUP message containing the SS payload */
+	gsup_req_complete := f_expect_gsup_msg(gsup_req);
+
+	/* Compose the response from HLR using received session ID */
+	var template GSUP_PDU gsup_rsp := ts_GSUP_PROC_SS_REQ(
+		imsi := g_pars.imsi,
+		sid := gsup_req_complete.ies[1].val.session_id,
+		state := OSMO_GSUP_SESSION_STATE_END,
+		ss := valueof(facility_rsp)
+	);
+
+	/* Finally, HLR terminates the session */
+	GSUP.send(gsup_rsp);
+
+	/* The USSD response goes out to remote MSC, on GSUP E instead of BSSAP */
+	var GSUP_PDU gsup_ussd_rsp;
+	GSUP.receive(tr_GSUP_E_AN_APDU(OSMO_GSUP_MSGT_E_FORWARD_ACCESS_SIGNALLING_REQUEST,
+				pars.imsi, destination_name := remote_msc_name)) -> value gsup_ussd_rsp;
+
+	var GSUP_IeValue an_apdu;
+	if (not f_gsup_find_ie(gsup_ussd_rsp, OSMO_GSUP_AN_APDU_IE, an_apdu)) {
+		setverdict(fail, "No AN-APDU in received GSUP message. Expected USSD response in DTAP, got", gsup_ussd_rsp);
+		mtc.stop;
+	}
+	var PDU_BSSAP bssap_dtap_mt := dec_PDU_BSSAP(an_apdu.an_apdu.pdu);
+	var PDU_ML3_NW_MS dtap_mt := dec_PDU_ML3_NW_MS(bssap_dtap_mt.pdu.dtap);
+	log("Expecting", ussd_rsp);
+	log("Got", dtap_mt);
+        if (not match(dtap_mt, ussd_rsp)) {
+		setverdict(fail, "Unexpected GSUP message. Expected USSD response in DTAP, got", gsup_ussd_rsp);
+		mtc.stop;
+	}
+	/**********************************/
+
+
+	/* inter-MSC handover back to the first MSC */
+	f_create_bssmap_exp_handoverRequest(193);
+	cil := { cIl_CGI := { ts_BSSMAP_CI_CGI('262'H, '42'H, 23, 42) } };
+
+	/* old BSS sends Handover Required, via inter-MSC E link: like
+	 * BSSAP.send(ts_BSSMAP_HandoverRequired(cause, cil));
+	 * but via GSUP */
+	GSUP.send(ts_GSUP_E_AN_APDU(OSMO_GSUP_MSGT_E_PREPARE_SUBSEQUENT_HANDOVER_REQUEST,
+				pars.imsi, remote_msc_name, local_msc_name,
+				valueof(t_GSUP_AN_APDU(OSMO_GSUP_AN_PROTO_48006,
+						enc_PDU_BSSAP(valueof(ts_BSSMAP_HandoverRequired(cause, cil)))
+						))
+				));
+
+	/* MSC asks local BSS to prepare Handover to it */
+	BSSAP.receive(tr_BSSMAP_HandoverRequest);
+
+	/* Make sure the new BSSAP conn continues with the correct N_SD sequence numbers */
+	f_bssmap_continue_after_n_sd(last_n_sd);
+
+	/* new BSS composes a RR Handover Command */
+	rr_ho_cmd := valueof(ts_RR_HandoverCommand);
+	rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
+	var BSSMAP_IE_AoIP_TransportLayerAddress tla := valueof(ts_BSSMAP_IE_AoIP_TLA4('01020304'O, 2342));
+	BSSAP.send(ts_BSSMAP_HandoverRequestAcknowledge(rr_ho_cmd_enc, lengthof(rr_ho_cmd_enc),
+							tla, ts_BSSMAP_IE_SpeechCodec({ts_CodecFR})));
+
+	/* HandoverCommand goes out via remote MSC-I */
+	var GSUP_PDU prep_subsq_ho_res;
+	GSUP.receive(tr_GSUP_E_AN_APDU(OSMO_GSUP_MSGT_E_PREPARE_SUBSEQUENT_HANDOVER_RESULT,
+				pars.imsi, destination_name := remote_msc_name)) -> value prep_subsq_ho_res;
+
+	/* MS shows up at the local BSS */
+	BSSAP.send(ts_BSSMAP_HandoverDetect);
+	f_sleep(0.1);
+	BSSAP.send(ts_BSSMAP_HandoverComplete);
+
+	/* MS has handovered to here, Clear Command goes out via remote MSC-I -- in form of a GSUP Close. */
+	GSUP.receive(tr_GSUP_E_NO_PDU(OSMO_GSUP_MSGT_E_CLOSE,
+				pars.imsi, destination_name := remote_msc_name));
+
+	/* Handover ends successfully. Call goes on for a little longer and then we hang up. */
+
+	f_sleep(1.0);
+	deactivate(ack_mdcx);
+
+	var default ccrel := activate(as_optional_cc_rel(cpars, true));
+	f_call_hangup(cpars, true);
+	f_sleep(1.0);
+	deactivate(ccrel);
+
+	setverdict(pass);
+}
+testcase TC_ho_inter_msc_out() runs on MTC_CT {
+	var BSC_ConnHdlr vc_conn;
+	f_init(1);
+
+	var BSC_ConnHdlrPars pars := f_init_pars(54);
+
+	vc_conn := f_start_handler_with_pars(refers(f_tc_ho_inter_msc_out), pars, 0);
+	vc_conn.done;
+}
+
+
 control {
 	execute( TC_cr_before_reset() );
 	execute( TC_lu_imsi_noauth_tmsi() );
@@ -4722,7 +5134,6 @@
 	execute( TC_lu_and_mt_ussd_during_mt_call() );
 	execute( TC_lu_and_mo_ussd_mo_release() );
 	execute( TC_lu_and_ss_session_timeout() );
-
 	execute( TC_cipher_complete_with_invalid_cipher() );
 
 	execute( TC_sgsap_reset() );
@@ -4748,7 +5159,12 @@
 	execute( TC_sgsap_lu_and_mt_call() );
 	execute( TC_sgsap_vlr_failure() );
 
-	/* Run this last: at the time of writing this test crashes the MSC */
+	execute( TC_ho_inter_bsc_unknown_cell() );
+	execute( TC_ho_inter_bsc() );
+
+	execute( TC_ho_inter_msc_out() );
+
+	// Run this last: at the time of writing this test crashes the MSC
 	execute( TC_lu_imsi_auth_tmsi_encr_3_1_log_msc_debug() );
 	execute( TC_gsup_mt_multi_part_sms() );
 	execute( TC_mo_cc_bssmap_clear() );

-- 
To view, visit https://gerrit.osmocom.org/13617
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-ttcn3-hacks
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: I7d76c982ad4e198534fa488609c41e8892b268ab
Gerrit-Change-Number: 13617
Gerrit-PatchSet: 1
Gerrit-Owner: Neels Hofmeyr <nhofmeyr at sysmocom.de>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20190412/0736d6cf/attachment.html>


More information about the gerrit-log mailing list