<p>Neels Hofmeyr <strong>merged</strong> this change.</p><p><a href="https://gerrit.osmocom.org/13617">View Change</a></p><div style="white-space:pre-wrap">Approvals:
Jenkins Builder: Verified
Neels Hofmeyr: Looks good to me, approved
</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">msc: add inter-BSC and inter-MSC Handover tests<br><br>Change-Id: I7d76c982ad4e198534fa488609c41e8892b268ab<br>---<br>M library/BSSMAP_Templates.ttcn<br>M library/GSUP_Types.ttcn<br>M library/L3_Templates.ttcn<br>M library/RAN_Emulation.ttcnpp<br>M msc/BSC_ConnectionHandler.ttcn<br>M msc/MSC_Tests.ttcn<br>6 files changed, 1,016 insertions(+), 93 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/library/BSSMAP_Templates.ttcn b/library/BSSMAP_Templates.ttcn</span><br><span>index 4df39d4..b7230cd 100644</span><br><span>--- a/library/BSSMAP_Templates.ttcn</span><br><span>+++ b/library/BSSMAP_Templates.ttcn</span><br><span>@@ -307,7 +307,7 @@</span><br><span> }</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-template BSSMAP_IE_CellIdentifierList ts_BSSMAP_IE_CidList(BSSMAP_FIELD_CellIdentificationList cid_list) := {</span><br><span style="color: hsl(120, 100%, 40%);">+template BSSMAP_IE_CellIdentifierList ts_BSSMAP_IE_CidList(template BSSMAP_FIELD_CellIdentificationList cid_list) := {</span><br><span> elementIdentifier := '1A'O,</span><br><span> lengthIndicator := 0, /* overwritten */</span><br><span> cellIdentifierDiscriminator := '0000'B, /* overwritten */</span><br><span>@@ -315,31 +315,6 @@</span><br><span> cellIdentificationList := cid_list</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-template PDU_BSSAP ts_BSSMAP_HandoReq(BssmapCause cause, BSSMAP_FIELD_CellIdentificationList cid_list)</span><br><span style="color: hsl(0, 100%, 40%);">-modifies ts_BSSAP_BSSMAP := {</span><br><span style="color: hsl(0, 100%, 40%);">- pdu := {</span><br><span style="color: hsl(0, 100%, 40%);">- bssmap := {</span><br><span style="color: hsl(0, 100%, 40%);">- handoverRequired := {</span><br><span style="color: hsl(0, 100%, 40%);">- messageType := '11'O,</span><br><span style="color: hsl(0, 100%, 40%);">- cause := ts_BSSMAP_IE_Cause(cause),</span><br><span style="color: hsl(0, 100%, 40%);">- responseRequest := omit,</span><br><span style="color: hsl(0, 100%, 40%);">- cellIdentifierList := ts_BSSMAP_IE_CidList(cid_list),</span><br><span style="color: hsl(0, 100%, 40%);">- circuitPoolList := omit,</span><br><span style="color: hsl(0, 100%, 40%);">- currentChannelType1 := omit,</span><br><span style="color: hsl(0, 100%, 40%);">- speechVersion := omit,</span><br><span style="color: hsl(0, 100%, 40%);">- queueingIndicator := omit,</span><br><span style="color: hsl(0, 100%, 40%);">- oldToNewBSSInfo := omit,</span><br><span style="color: hsl(0, 100%, 40%);">- sourceToTargetRNCTransparentInfo := omit,</span><br><span style="color: hsl(0, 100%, 40%);">- sourceToTargetRNCTransparentInfoCDMA := omit,</span><br><span style="color: hsl(0, 100%, 40%);">- gERANClassmark := omit,</span><br><span style="color: hsl(0, 100%, 40%);">- talkerPriority := omit,</span><br><span style="color: hsl(0, 100%, 40%);">- speechCodec := omit,</span><br><span style="color: hsl(0, 100%, 40%);">- cSG_Identifier := omit</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> const OCT1 ChRate_ANY := '00'O;</span><br><span> const OCT1 ChRate_TCHF := '08'O;</span><br><span> const OCT1 ChRate_TCHH := '09'O;</span><br><span>@@ -703,6 +678,33 @@</span><br><span> }</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+template PDU_BSSAP ts_BSSMAP_HandoverRequired(BssmapCause cause,</span><br><span style="color: hsl(120, 100%, 40%);">+ template BSSMAP_FIELD_CellIdentificationList cid_list)</span><br><span style="color: hsl(120, 100%, 40%);">+modifies ts_BSSAP_BSSMAP := {</span><br><span style="color: hsl(120, 100%, 40%);">+ pdu := {</span><br><span style="color: hsl(120, 100%, 40%);">+ bssmap := {</span><br><span style="color: hsl(120, 100%, 40%);">+ handoverRequired := {</span><br><span style="color: hsl(120, 100%, 40%);">+ messageType := '11'O,</span><br><span style="color: hsl(120, 100%, 40%);">+ cause := ts_BSSMAP_IE_Cause(cause),</span><br><span style="color: hsl(120, 100%, 40%);">+ responseRequest := omit,</span><br><span style="color: hsl(120, 100%, 40%);">+ cellIdentifierList := ts_BSSMAP_IE_CidList(cid_list),</span><br><span style="color: hsl(120, 100%, 40%);">+ circuitPoolList := omit,</span><br><span style="color: hsl(120, 100%, 40%);">+ currentChannelType1 := omit,</span><br><span style="color: hsl(120, 100%, 40%);">+ speechVersion := omit,</span><br><span style="color: hsl(120, 100%, 40%);">+ queueingIndicator := omit,</span><br><span style="color: hsl(120, 100%, 40%);">+ oldToNewBSSInfo := omit,</span><br><span style="color: hsl(120, 100%, 40%);">+ sourceToTargetRNCTransparentInfo := omit,</span><br><span style="color: hsl(120, 100%, 40%);">+ sourceToTargetRNCTransparentInfoCDMA := omit,</span><br><span style="color: hsl(120, 100%, 40%);">+ gERANClassmark := omit,</span><br><span style="color: hsl(120, 100%, 40%);">+ talkerPriority := omit,</span><br><span style="color: hsl(120, 100%, 40%);">+ speechCodec := omit,</span><br><span style="color: hsl(120, 100%, 40%);">+ cSG_Identifier := omit</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> template PDU_BSSAP tr_BSSMAP_HandoverRequired modifies tr_BSSAP_BSSMAP := {</span><br><span> pdu := {</span><br><span> bssmap := {</span><br><span>@@ -713,6 +715,38 @@</span><br><span> }</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+template PDU_BSSAP tr_BSSMAP_HandoverRequiredReject modifies tr_BSSAP_BSSMAP := {</span><br><span style="color: hsl(120, 100%, 40%);">+ pdu := {</span><br><span style="color: hsl(120, 100%, 40%);">+ bssmap := {</span><br><span style="color: hsl(120, 100%, 40%);">+ handoverRequiredReject := {</span><br><span style="color: hsl(120, 100%, 40%);">+ messageType := '1A'O</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+template PDU_BSSAP tr_BSSMAP_HandoverCommand</span><br><span style="color: hsl(120, 100%, 40%);">+modifies tr_BSSAP_BSSMAP := {</span><br><span style="color: hsl(120, 100%, 40%);">+ pdu := {</span><br><span style="color: hsl(120, 100%, 40%);">+ bssmap := {</span><br><span style="color: hsl(120, 100%, 40%);">+ handoverCommand := {</span><br><span style="color: hsl(120, 100%, 40%);">+ messageType := '13'O</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+template PDU_BSSAP tr_BSSMAP_HandoverSucceeded</span><br><span style="color: hsl(120, 100%, 40%);">+modifies tr_BSSAP_BSSMAP := {</span><br><span style="color: hsl(120, 100%, 40%);">+ pdu := {</span><br><span style="color: hsl(120, 100%, 40%);">+ bssmap := {</span><br><span style="color: hsl(120, 100%, 40%);">+ handoverSucceeded := {</span><br><span style="color: hsl(120, 100%, 40%);">+ messageType := '15'O</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> template (value) PDU_BSSAP ts_BSSMAP_HandoverCommand(octetstring layer3info)</span><br><span> modifies ts_BSSAP_BSSMAP := {</span><br><span> pdu := {</span><br><span>@@ -751,6 +785,16 @@</span><br><span> }</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+template PDU_BSSAP tr_BSSMAP_HandoverRequest modifies tr_BSSAP_BSSMAP := {</span><br><span style="color: hsl(120, 100%, 40%);">+ pdu := {</span><br><span style="color: hsl(120, 100%, 40%);">+ bssmap := {</span><br><span style="color: hsl(120, 100%, 40%);">+ handoverRequest := {</span><br><span style="color: hsl(120, 100%, 40%);">+ messageType := '10'O</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> template PDU_BSSAP ts_BSSMAP_HandoverRequest(</span><br><span> template BSSMAP_IE_CircuitIdentityCode cic := omit,</span><br><span> template BSSMAP_IE_AoIP_TransportLayerAddress aoip_tla := omit,</span><br><span>@@ -826,6 +870,41 @@</span><br><span> }</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+template PDU_BSSAP ts_BSSMAP_HandoverRequestAcknowledge(</span><br><span style="color: hsl(120, 100%, 40%);">+ template octetstring layer3info,</span><br><span style="color: hsl(120, 100%, 40%);">+ template LIN1 layer3infoLength,</span><br><span style="color: hsl(120, 100%, 40%);">+ template BSSMAP_IE_AoIP_TransportLayerAddress aoIPTransportLayer := omit,</span><br><span style="color: hsl(120, 100%, 40%);">+ template BSSMAP_IE_SpeechCodec speechCodec := omit,</span><br><span style="color: hsl(120, 100%, 40%);">+ template BSSMAP_IE_ChosenChannel chosenChannel := omit,</span><br><span style="color: hsl(120, 100%, 40%);">+ template BSSMAP_IE_ChosenEncryptionAlgorithm chosenEncryptionAlgorithm := omit)</span><br><span style="color: hsl(120, 100%, 40%);">+modifies ts_BSSAP_BSSMAP := {</span><br><span style="color: hsl(120, 100%, 40%);">+ pdu := {</span><br><span style="color: hsl(120, 100%, 40%);">+ bssmap := {</span><br><span style="color: hsl(120, 100%, 40%);">+ handoverRequestAck := {</span><br><span style="color: hsl(120, 100%, 40%);">+ messageType := '12'O,</span><br><span style="color: hsl(120, 100%, 40%);">+ layer3Information := {</span><br><span style="color: hsl(120, 100%, 40%);">+ elementIdentifier := '17'O,</span><br><span style="color: hsl(120, 100%, 40%);">+ lengthIndicator := layer3infoLength,</span><br><span style="color: hsl(120, 100%, 40%);">+ layer3info := layer3info</span><br><span style="color: hsl(120, 100%, 40%);">+ },</span><br><span style="color: hsl(120, 100%, 40%);">+ chosenChannel := chosenChannel,</span><br><span style="color: hsl(120, 100%, 40%);">+ chosenEncryptionAlgorithm := chosenEncryptionAlgorithm,</span><br><span style="color: hsl(120, 100%, 40%);">+ circuitPool := omit,</span><br><span style="color: hsl(120, 100%, 40%);">+ speechVersion := omit,</span><br><span style="color: hsl(120, 100%, 40%);">+ circuitIdentityCode := omit,</span><br><span style="color: hsl(120, 100%, 40%);">+ lSAIdentifier := omit,</span><br><span style="color: hsl(120, 100%, 40%);">+ newBSSToOldBSSInfo := omit,</span><br><span style="color: hsl(120, 100%, 40%);">+ interSystemInformation := omit,</span><br><span style="color: hsl(120, 100%, 40%);">+ talkerPriority := omit,</span><br><span style="color: hsl(120, 100%, 40%);">+ aoIPTransportLayer := aoIPTransportLayer,</span><br><span style="color: hsl(120, 100%, 40%);">+ codecList := omit,</span><br><span style="color: hsl(120, 100%, 40%);">+ speechCodec := speechCodec,</span><br><span style="color: hsl(120, 100%, 40%);">+ lCLS_bSS_Status := omit</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> template PDU_BSSAP tr_BSSMAP_HandoverDetect</span><br><span> modifies tr_BSSAP_BSSMAP := {</span><br><span> pdu := {</span><br><span>@@ -838,6 +917,18 @@</span><br><span> }</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+template PDU_BSSAP ts_BSSMAP_HandoverDetect</span><br><span style="color: hsl(120, 100%, 40%);">+modifies ts_BSSAP_BSSMAP := {</span><br><span style="color: hsl(120, 100%, 40%);">+ pdu := {</span><br><span style="color: hsl(120, 100%, 40%);">+ bssmap := {</span><br><span style="color: hsl(120, 100%, 40%);">+ handoverDetect := {</span><br><span style="color: hsl(120, 100%, 40%);">+ messageType := '1B'O,</span><br><span style="color: hsl(120, 100%, 40%);">+ talkerPriority := omit</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> template PDU_BSSAP tr_BSSMAP_HandoverComplete</span><br><span> modifies tr_BSSAP_BSSMAP := {</span><br><span> pdu := {</span><br><span>@@ -856,6 +947,24 @@</span><br><span> }</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+template PDU_BSSAP ts_BSSMAP_HandoverComplete</span><br><span style="color: hsl(120, 100%, 40%);">+modifies ts_BSSAP_BSSMAP := {</span><br><span style="color: hsl(120, 100%, 40%);">+ pdu := {</span><br><span style="color: hsl(120, 100%, 40%);">+ bssmap := {</span><br><span style="color: hsl(120, 100%, 40%);">+ handoverComplete := {</span><br><span style="color: hsl(120, 100%, 40%);">+ messageType := '14'O,</span><br><span style="color: hsl(120, 100%, 40%);">+ rR_Cause := omit,</span><br><span style="color: hsl(120, 100%, 40%);">+ talkerPriority := omit,</span><br><span style="color: hsl(120, 100%, 40%);">+ speechCodec := omit,</span><br><span style="color: hsl(120, 100%, 40%);">+ codecList := omit,</span><br><span style="color: hsl(120, 100%, 40%);">+ chosenEncryptionAlgorithm := omit,</span><br><span style="color: hsl(120, 100%, 40%);">+ chosenChannel := omit,</span><br><span style="color: hsl(120, 100%, 40%);">+ lCLS_BSS_Status := omit</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> template PDU_BSSAP tr_BSSMAP_HandoverPerformed</span><br><span> modifies tr_BSSAP_BSSMAP := {</span><br><span> pdu := {</span><br><span>@@ -975,7 +1084,7 @@</span><br><span> messageType := '52'O,</span><br><span> iMSI := ts_BSSMAP_Imsi(imsi_digits),</span><br><span> tMSI := f_tmsi_or_omit(tmsi),</span><br><span style="color: hsl(0, 100%, 40%);">- cellIdentifierList := ts_BSSMAP_IE_CidList(valueof(cid_list)),</span><br><span style="color: hsl(120, 100%, 40%);">+ cellIdentifierList := ts_BSSMAP_IE_CidList(cid_list),</span><br><span> channelNeeded := chneed,</span><br><span> eMLPP_Priority := omit,</span><br><span> pagingInformation := omit /* only VGCS/VBS flag */</span><br><span>diff --git a/library/GSUP_Types.ttcn b/library/GSUP_Types.ttcn</span><br><span>index c024d37..73f4562 100644</span><br><span>--- a/library/GSUP_Types.ttcn</span><br><span>+++ b/library/GSUP_Types.ttcn</span><br><span>@@ -55,7 +55,16 @@</span><br><span> OSMO_GSUP_SM_ALERT_RSN_IE ('46'O),</span><br><span> </span><br><span> OSMO_GSUP_IMEI_IE ('50'O),</span><br><span style="color: hsl(0, 100%, 40%);">- OSMO_GSUP_IMEI_RESULT_IE ('51'O)</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_GSUP_IMEI_RESULT_IE ('51'O),</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_GSUP_MESSAGE_CLASS_IE ('0a'O),</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_GSUP_SOURCE_NAME_IE ('60'O),</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_GSUP_DESTINATION_NAME_IE ('61'O),</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_GSUP_AN_APDU_IE ('62'O),</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_GSUP_CAUSE_RR_IE ('63'O),</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_GSUP_CAUSE_BSSAP_IE ('64'O),</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_GSUP_CAUSE_SM_IE ('65'O)</span><br><span> } with { variant "FIELDLENGTH(8)" };</span><br><span> </span><br><span> type enumerated GSUP_MessageType {</span><br><span>@@ -103,7 +112,27 @@</span><br><span> </span><br><span> OSMO_GSUP_MSGT_CHECK_IMEI_REQUEST ('00110000'B),</span><br><span> OSMO_GSUP_MSGT_CHECK_IMEI_ERROR ('00110001'B),</span><br><span style="color: hsl(0, 100%, 40%);">- OSMO_GSUP_MSGT_CHECK_IMEI_RESULT ('00110010'B)</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_GSUP_MSGT_CHECK_IMEI_RESULT ('00110010'B),</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_GSUP_MSGT_E_PREPARE_HANDOVER_REQUEST ('00110100'B),</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_GSUP_MSGT_E_PREPARE_HANDOVER_ERROR ('00110101'B),</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_GSUP_MSGT_E_PREPARE_HANDOVER_RESULT ('00110110'B),</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_GSUP_MSGT_E_PREPARE_SUBSEQUENT_HANDOVER_REQUEST ('00111000'B),</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_GSUP_MSGT_E_PREPARE_SUBSEQUENT_HANDOVER_ERROR ('00111001'B),</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_GSUP_MSGT_E_PREPARE_SUBSEQUENT_HANDOVER_RESULT ('00111010'B),</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_GSUP_MSGT_E_SEND_END_SIGNAL_REQUEST ('00111100'B),</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_GSUP_MSGT_E_SEND_END_SIGNAL_ERROR ('00111101'B),</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_GSUP_MSGT_E_SEND_END_SIGNAL_RESULT ('00111110'B),</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_GSUP_MSGT_E_PROCESS_ACCESS_SIGNALLING_REQUEST ('01000000'B),</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_GSUP_MSGT_E_FORWARD_ACCESS_SIGNALLING_REQUEST ('01000100'B),</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_GSUP_MSGT_E_CLOSE ('01000111'B),</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_GSUP_MSGT_E_ABORT ('01001011'B),</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_GSUP_MSGT_E_ROUTING_ERROR ('01001110'B)</span><br><span> } with { variant "FIELDLENGTH(8)" };</span><br><span> </span><br><span> type enumerated GSUP_CancelType {</span><br><span>@@ -128,6 +157,14 @@</span><br><span> OSMO_GSUP_SESSION_STATE_END (3)</span><br><span> } with { variant "FIELDLENGTH(8)" };</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+type enumerated GSUP_Message_Class {</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_GSUP_MESSAGE_CLASS_UNSET (0),</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_GSUP_MESSAGE_CLASS_SUBSCRIBER_MANAGEMENT (1),</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_GSUP_MESSAGE_CLASS_SMS (2),</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_GSUP_MESSAGE_CLASS_USSD (3),</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_GSUP_MESSAGE_CLASS_INTER_MSC (4)</span><br><span style="color: hsl(120, 100%, 40%);">+} with { variant "FIELDLENGTH(8)" };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> type record GSUP_MSISDN {</span><br><span> uint8_t len,</span><br><span> hexstring digits optional</span><br><span>@@ -138,6 +175,16 @@</span><br><span> hexstring digits optional</span><br><span> } with { variant (len) "LENGTHTO(digits)" };</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+type enumerated GSUP_AN_PROTO {</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_GSUP_AN_PROTO_48006 (1),</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_GSUP_AN_PROTO_25413 (2)</span><br><span style="color: hsl(120, 100%, 40%);">+} with { variant "FIELDLENGTH(8)" };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+type record GSUP_AN_APDU {</span><br><span style="color: hsl(120, 100%, 40%);">+ GSUP_AN_PROTO proto,</span><br><span style="color: hsl(120, 100%, 40%);">+ octetstring pdu</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> type record GSUP_IE {</span><br><span> GSUP_IEI tag,</span><br><span> uint8_t len,</span><br><span>@@ -175,6 +222,13 @@</span><br><span> sm_alert_rsn, tag = OSMO_GSUP_SM_ALERT_RSN_IE;</span><br><span> imei, tag = OSMO_GSUP_IMEI_IE;</span><br><span> imei_result, tag = OSMO_GSUP_IMEI_RESULT_IE;</span><br><span style="color: hsl(120, 100%, 40%);">+ message_class, tag = OSMO_GSUP_MESSAGE_CLASS_IE;</span><br><span style="color: hsl(120, 100%, 40%);">+ source_name, tag = OSMO_GSUP_SOURCE_NAME_IE;</span><br><span style="color: hsl(120, 100%, 40%);">+ destination_name, tag = OSMO_GSUP_DESTINATION_NAME_IE;</span><br><span style="color: hsl(120, 100%, 40%);">+ an_apdu, tag = OSMO_GSUP_AN_APDU_IE;</span><br><span style="color: hsl(120, 100%, 40%);">+ cause_rr, tag = OSMO_GSUP_CAUSE_RR_IE;</span><br><span style="color: hsl(120, 100%, 40%);">+ cause_bssap, tag = OSMO_GSUP_CAUSE_BSSAP_IE;</span><br><span style="color: hsl(120, 100%, 40%);">+ cause_sm, tag = OSMO_GSUP_CAUSE_SM_IE;</span><br><span> )"</span><br><span> };</span><br><span> </span><br><span>@@ -219,7 +273,18 @@</span><br><span> GSUP_SM_ALERT_RSN_Type sm_alert_rsn,</span><br><span> </span><br><span> GSUP_IMEI imei,</span><br><span style="color: hsl(0, 100%, 40%);">- GSUP_IMEIResult imei_result</span><br><span style="color: hsl(120, 100%, 40%);">+ GSUP_IMEIResult imei_result,</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ GSUP_Message_Class message_class,</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ octetstring source_name,</span><br><span style="color: hsl(120, 100%, 40%);">+ octetstring destination_name,</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ GSUP_AN_APDU an_apdu,</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ OCT1 cause_rr,</span><br><span style="color: hsl(120, 100%, 40%);">+ OCT1 cause_bssap,</span><br><span style="color: hsl(120, 100%, 40%);">+ OCT1 cause_sm</span><br><span> };</span><br><span> </span><br><span> type record GSUP_PDU {</span><br><span>@@ -930,6 +995,70 @@</span><br><span> }</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+template GSUP_IE tr_GSUP_IE_Message_Class(template GSUP_Message_Class val) := {</span><br><span style="color: hsl(120, 100%, 40%);">+ tag := OSMO_GSUP_MESSAGE_CLASS_IE,</span><br><span style="color: hsl(120, 100%, 40%);">+ len := ?,</span><br><span style="color: hsl(120, 100%, 40%);">+ val := {</span><br><span style="color: hsl(120, 100%, 40%);">+ message_class := val</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+template (value) GSUP_IE ts_GSUP_IE_Message_Class(GSUP_Message_Class val) := {</span><br><span style="color: hsl(120, 100%, 40%);">+ tag := OSMO_GSUP_MESSAGE_CLASS_IE,</span><br><span style="color: hsl(120, 100%, 40%);">+ len := 0, /* overwritten */</span><br><span style="color: hsl(120, 100%, 40%);">+ val := {</span><br><span style="color: hsl(120, 100%, 40%);">+ message_class := val</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+template GSUP_IE tr_GSUP_IE_Source_Name(template octetstring name) := {</span><br><span style="color: hsl(120, 100%, 40%);">+ tag := OSMO_GSUP_SOURCE_NAME_IE,</span><br><span style="color: hsl(120, 100%, 40%);">+ len := ?,</span><br><span style="color: hsl(120, 100%, 40%);">+ val := {</span><br><span style="color: hsl(120, 100%, 40%);">+ source_name := name</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+template (value) GSUP_IE ts_GSUP_IE_Source_Name(octetstring name) := {</span><br><span style="color: hsl(120, 100%, 40%);">+ tag := OSMO_GSUP_SOURCE_NAME_IE,</span><br><span style="color: hsl(120, 100%, 40%);">+ len := 0, /* overwritten */</span><br><span style="color: hsl(120, 100%, 40%);">+ val := {</span><br><span style="color: hsl(120, 100%, 40%);">+ source_name := name</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+template GSUP_IE tr_GSUP_IE_Destination_Name(template octetstring name) := {</span><br><span style="color: hsl(120, 100%, 40%);">+ tag := OSMO_GSUP_DESTINATION_NAME_IE,</span><br><span style="color: hsl(120, 100%, 40%);">+ len := ?,</span><br><span style="color: hsl(120, 100%, 40%);">+ val := {</span><br><span style="color: hsl(120, 100%, 40%);">+ destination_name := name</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+template (value) GSUP_IE ts_GSUP_IE_Destination_Name(octetstring name) := {</span><br><span style="color: hsl(120, 100%, 40%);">+ tag := OSMO_GSUP_DESTINATION_NAME_IE,</span><br><span style="color: hsl(120, 100%, 40%);">+ len := 0, /* overwritten */</span><br><span style="color: hsl(120, 100%, 40%);">+ val := {</span><br><span style="color: hsl(120, 100%, 40%);">+ destination_name := name</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+template GSUP_IE tr_GSUP_IE_AN_APDU(template GSUP_AN_APDU an_apdu) := {</span><br><span style="color: hsl(120, 100%, 40%);">+ tag := OSMO_GSUP_AN_APDU_IE,</span><br><span style="color: hsl(120, 100%, 40%);">+ len := ?,</span><br><span style="color: hsl(120, 100%, 40%);">+ val := {</span><br><span style="color: hsl(120, 100%, 40%);">+ an_apdu := an_apdu</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+template (value) GSUP_IE ts_GSUP_IE_AN_APDU(GSUP_AN_APDU an_apdu) := {</span><br><span style="color: hsl(120, 100%, 40%);">+ tag := OSMO_GSUP_AN_APDU_IE,</span><br><span style="color: hsl(120, 100%, 40%);">+ len := 0, /* overwritten */</span><br><span style="color: hsl(120, 100%, 40%);">+ val := {</span><br><span style="color: hsl(120, 100%, 40%);">+ an_apdu := an_apdu</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> private function f_gen_ts_ss_ies(</span><br><span> hexstring imsi,</span><br><span> OCT4 sid,</span><br><span>@@ -962,14 +1091,20 @@</span><br><span> tr_GSUP_IE_SessionId(sid),</span><br><span> tr_GSUP_IE_SessionState(state)</span><br><span> };</span><br><span style="color: hsl(120, 100%, 40%);">+ var integer last_idx := 3;</span><br><span> </span><br><span> /* Optional SS payload */</span><br><span> if (istemplatekind(ss, "*")) {</span><br><span> ies[3] := *;</span><br><span style="color: hsl(120, 100%, 40%);">+ last_idx := last_idx + 1;</span><br><span> } else if (not istemplatekind(ss, "omit")) {</span><br><span> ies[3] := tr_GSUP_IE_SSInfo(ss);</span><br><span style="color: hsl(120, 100%, 40%);">+ last_idx := last_idx + 1;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ ies[last_idx] := tr_GSUP_IE_Message_Class(OSMO_GSUP_MESSAGE_CLASS_USSD);</span><br><span style="color: hsl(120, 100%, 40%);">+ last_idx := last_idx + 1;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> return ies;</span><br><span> }</span><br><span> </span><br><span>@@ -1036,7 +1171,8 @@</span><br><span> tr_GSUP_IE_IMSI(imsi),</span><br><span> tr_GSUP_IE_Cause(cause),</span><br><span> tr_GSUP_IE_SessionId(sid),</span><br><span style="color: hsl(0, 100%, 40%);">- tr_GSUP_IE_SessionState(state)</span><br><span style="color: hsl(120, 100%, 40%);">+ tr_GSUP_IE_SessionState(state),</span><br><span style="color: hsl(120, 100%, 40%);">+ tr_GSUP_IE_Message_Class(OSMO_GSUP_MESSAGE_CLASS_SMS)</span><br><span> }</span><br><span> );</span><br><span> </span><br><span>@@ -1069,7 +1205,8 @@</span><br><span> tr_GSUP_IE_SM_RP_MR(sm_rp_mr),</span><br><span> tr_GSUP_IE_SM_RP_DA(sm_rp_da),</span><br><span> tr_GSUP_IE_SM_RP_OA(sm_rp_oa),</span><br><span style="color: hsl(0, 100%, 40%);">- tr_GSUP_IE_SM_RP_UI(sm_rp_ui)</span><br><span style="color: hsl(120, 100%, 40%);">+ tr_GSUP_IE_SM_RP_UI(sm_rp_ui),</span><br><span style="color: hsl(120, 100%, 40%);">+ tr_GSUP_IE_Message_Class(OSMO_GSUP_MESSAGE_CLASS_SMS)</span><br><span> }</span><br><span> );</span><br><span> </span><br><span>@@ -1090,7 +1227,8 @@</span><br><span> OSMO_GSUP_MSGT_MO_FORWARD_SM_RESULT,</span><br><span> {</span><br><span> tr_GSUP_IE_IMSI(imsi),</span><br><span style="color: hsl(0, 100%, 40%);">- tr_GSUP_IE_SM_RP_MR(sm_rp_mr)</span><br><span style="color: hsl(120, 100%, 40%);">+ tr_GSUP_IE_SM_RP_MR(sm_rp_mr),</span><br><span style="color: hsl(120, 100%, 40%);">+ tr_GSUP_IE_Message_Class(OSMO_GSUP_MESSAGE_CLASS_SMS)</span><br><span> }</span><br><span> );</span><br><span> </span><br><span>@@ -1115,7 +1253,8 @@</span><br><span> {</span><br><span> tr_GSUP_IE_IMSI(imsi),</span><br><span> tr_GSUP_IE_SM_RP_MR(sm_rp_mr),</span><br><span style="color: hsl(0, 100%, 40%);">- tr_GSUP_IE_SM_RP_CAUSE(sm_rp_cause)</span><br><span style="color: hsl(120, 100%, 40%);">+ tr_GSUP_IE_SM_RP_CAUSE(sm_rp_cause),</span><br><span style="color: hsl(120, 100%, 40%);">+ tr_GSUP_IE_Message_Class(OSMO_GSUP_MESSAGE_CLASS_SMS)</span><br><span> }</span><br><span> );</span><br><span> </span><br><span>@@ -1162,7 +1301,8 @@</span><br><span> tr_GSUP_IE_SM_RP_DA(sm_rp_da),</span><br><span> tr_GSUP_IE_SM_RP_OA(sm_rp_oa),</span><br><span> tr_GSUP_IE_SM_RP_UI(sm_rp_ui),</span><br><span style="color: hsl(0, 100%, 40%);">- tr_GSUP_IE_SM_RP_MMS(sm_rp_mms)</span><br><span style="color: hsl(120, 100%, 40%);">+ tr_GSUP_IE_SM_RP_MMS(sm_rp_mms),</span><br><span style="color: hsl(120, 100%, 40%);">+ tr_GSUP_IE_Message_Class(OSMO_GSUP_MESSAGE_CLASS_SMS)</span><br><span> }</span><br><span> );</span><br><span> </span><br><span>@@ -1183,7 +1323,8 @@</span><br><span> OSMO_GSUP_MSGT_MT_FORWARD_SM_RESULT,</span><br><span> {</span><br><span> tr_GSUP_IE_IMSI(imsi),</span><br><span style="color: hsl(0, 100%, 40%);">- tr_GSUP_IE_SM_RP_MR(sm_rp_mr)</span><br><span style="color: hsl(120, 100%, 40%);">+ tr_GSUP_IE_SM_RP_MR(sm_rp_mr),</span><br><span style="color: hsl(120, 100%, 40%);">+ tr_GSUP_IE_Message_Class(OSMO_GSUP_MESSAGE_CLASS_SMS)</span><br><span> }</span><br><span> );</span><br><span> </span><br><span>@@ -1208,7 +1349,8 @@</span><br><span> {</span><br><span> tr_GSUP_IE_IMSI(imsi),</span><br><span> tr_GSUP_IE_SM_RP_MR(sm_rp_mr),</span><br><span style="color: hsl(0, 100%, 40%);">- tr_GSUP_IE_SM_RP_CAUSE(sm_rp_cause)</span><br><span style="color: hsl(120, 100%, 40%);">+ tr_GSUP_IE_SM_RP_CAUSE(sm_rp_cause),</span><br><span style="color: hsl(120, 100%, 40%);">+ tr_GSUP_IE_Message_Class(OSMO_GSUP_MESSAGE_CLASS_SMS)</span><br><span> }</span><br><span> );</span><br><span> </span><br><span>@@ -1233,7 +1375,8 @@</span><br><span> {</span><br><span> tr_GSUP_IE_IMSI(imsi),</span><br><span> tr_GSUP_IE_SM_RP_MR(sm_rp_mr),</span><br><span style="color: hsl(0, 100%, 40%);">- tr_GSUP_IE_SM_ALERT_RSN(sm_alert_rsn)</span><br><span style="color: hsl(120, 100%, 40%);">+ tr_GSUP_IE_SM_ALERT_RSN(sm_alert_rsn),</span><br><span style="color: hsl(120, 100%, 40%);">+ tr_GSUP_IE_Message_Class(OSMO_GSUP_MESSAGE_CLASS_SMS)</span><br><span> }</span><br><span> );</span><br><span> </span><br><span>@@ -1254,7 +1397,8 @@</span><br><span> OSMO_GSUP_MSGT_READY_FOR_SM_RESULT,</span><br><span> {</span><br><span> tr_GSUP_IE_IMSI(imsi),</span><br><span style="color: hsl(0, 100%, 40%);">- tr_GSUP_IE_SM_RP_MR(sm_rp_mr)</span><br><span style="color: hsl(120, 100%, 40%);">+ tr_GSUP_IE_SM_RP_MR(sm_rp_mr),</span><br><span style="color: hsl(120, 100%, 40%);">+ tr_GSUP_IE_Message_Class(OSMO_GSUP_MESSAGE_CLASS_SMS)</span><br><span> }</span><br><span> );</span><br><span> </span><br><span>@@ -1279,7 +1423,8 @@</span><br><span> {</span><br><span> tr_GSUP_IE_IMSI(imsi),</span><br><span> tr_GSUP_IE_SM_RP_MR(sm_rp_mr),</span><br><span style="color: hsl(0, 100%, 40%);">- tr_GSUP_IE_SM_RP_CAUSE(sm_rp_cause)</span><br><span style="color: hsl(120, 100%, 40%);">+ tr_GSUP_IE_SM_RP_CAUSE(sm_rp_cause),</span><br><span style="color: hsl(120, 100%, 40%);">+ tr_GSUP_IE_Message_Class(OSMO_GSUP_MESSAGE_CLASS_SMS)</span><br><span> }</span><br><span> );</span><br><span> </span><br><span>@@ -1293,5 +1438,79 @@</span><br><span> return false;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+template GSUP_AN_APDU t_GSUP_AN_APDU(</span><br><span style="color: hsl(120, 100%, 40%);">+ template GSUP_AN_PROTO an_proto := ?,</span><br><span style="color: hsl(120, 100%, 40%);">+ template octetstring pdu := ?</span><br><span style="color: hsl(120, 100%, 40%);">+) := {</span><br><span style="color: hsl(120, 100%, 40%);">+ proto := an_proto,</span><br><span style="color: hsl(120, 100%, 40%);">+ pdu := pdu</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+template GSUP_PDU tr_GSUP_E_AN_APDU(</span><br><span style="color: hsl(120, 100%, 40%);">+ template GSUP_MessageType msgt,</span><br><span style="color: hsl(120, 100%, 40%);">+ template hexstring imsi := ?,</span><br><span style="color: hsl(120, 100%, 40%);">+ template octetstring source_name := ?,</span><br><span style="color: hsl(120, 100%, 40%);">+ template octetstring destination_name := ?,</span><br><span style="color: hsl(120, 100%, 40%);">+ template GSUP_AN_APDU an_apdu := ?</span><br><span style="color: hsl(120, 100%, 40%);">+) := tr_GSUP(</span><br><span style="color: hsl(120, 100%, 40%);">+ msgt,</span><br><span style="color: hsl(120, 100%, 40%);">+ {</span><br><span style="color: hsl(120, 100%, 40%);">+ tr_GSUP_IE_IMSI(imsi),</span><br><span style="color: hsl(120, 100%, 40%);">+ tr_GSUP_IE_Message_Class(OSMO_GSUP_MESSAGE_CLASS_INTER_MSC),</span><br><span style="color: hsl(120, 100%, 40%);">+ tr_GSUP_IE_Source_Name(source_name),</span><br><span style="color: hsl(120, 100%, 40%);">+ tr_GSUP_IE_Destination_Name(destination_name),</span><br><span style="color: hsl(120, 100%, 40%);">+ tr_GSUP_IE_AN_APDU(an_apdu)</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+template GSUP_PDU tr_GSUP_E_NO_PDU(</span><br><span style="color: hsl(120, 100%, 40%);">+ template GSUP_MessageType msgt,</span><br><span style="color: hsl(120, 100%, 40%);">+ template hexstring imsi := ?,</span><br><span style="color: hsl(120, 100%, 40%);">+ template octetstring source_name := ?,</span><br><span style="color: hsl(120, 100%, 40%);">+ template octetstring destination_name := ?</span><br><span style="color: hsl(120, 100%, 40%);">+) := tr_GSUP(</span><br><span style="color: hsl(120, 100%, 40%);">+ msgt,</span><br><span style="color: hsl(120, 100%, 40%);">+ {</span><br><span style="color: hsl(120, 100%, 40%);">+ tr_GSUP_IE_IMSI(imsi),</span><br><span style="color: hsl(120, 100%, 40%);">+ tr_GSUP_IE_Message_Class(OSMO_GSUP_MESSAGE_CLASS_INTER_MSC),</span><br><span style="color: hsl(120, 100%, 40%);">+ tr_GSUP_IE_Source_Name(source_name),</span><br><span style="color: hsl(120, 100%, 40%);">+ tr_GSUP_IE_Destination_Name(destination_name)</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+template (value) GSUP_PDU ts_GSUP_E_AN_APDU(</span><br><span style="color: hsl(120, 100%, 40%);">+ GSUP_MessageType msgt,</span><br><span style="color: hsl(120, 100%, 40%);">+ hexstring imsi,</span><br><span style="color: hsl(120, 100%, 40%);">+ octetstring source_name,</span><br><span style="color: hsl(120, 100%, 40%);">+ octetstring destination_name,</span><br><span style="color: hsl(120, 100%, 40%);">+ GSUP_AN_APDU an_apdu</span><br><span style="color: hsl(120, 100%, 40%);">+) := ts_GSUP(</span><br><span style="color: hsl(120, 100%, 40%);">+ msgt,</span><br><span style="color: hsl(120, 100%, 40%);">+ {</span><br><span style="color: hsl(120, 100%, 40%);">+ valueof(ts_GSUP_IE_IMSI(imsi)),</span><br><span style="color: hsl(120, 100%, 40%);">+ valueof(ts_GSUP_IE_Message_Class(OSMO_GSUP_MESSAGE_CLASS_INTER_MSC)),</span><br><span style="color: hsl(120, 100%, 40%);">+ valueof(ts_GSUP_IE_Source_Name(source_name)),</span><br><span style="color: hsl(120, 100%, 40%);">+ valueof(ts_GSUP_IE_Destination_Name(destination_name)),</span><br><span style="color: hsl(120, 100%, 40%);">+ valueof(ts_GSUP_IE_AN_APDU(an_apdu))</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+template (value) GSUP_PDU ts_GSUP_E_PrepareHandoverResult(</span><br><span style="color: hsl(120, 100%, 40%);">+ hexstring imsi,</span><br><span style="color: hsl(120, 100%, 40%);">+ hexstring msisdn,</span><br><span style="color: hsl(120, 100%, 40%);">+ octetstring source_name,</span><br><span style="color: hsl(120, 100%, 40%);">+ octetstring destination_name,</span><br><span style="color: hsl(120, 100%, 40%);">+ GSUP_AN_APDU an_apdu</span><br><span style="color: hsl(120, 100%, 40%);">+) := ts_GSUP(</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_GSUP_MSGT_E_PREPARE_HANDOVER_RESULT,</span><br><span style="color: hsl(120, 100%, 40%);">+ {</span><br><span style="color: hsl(120, 100%, 40%);">+ valueof(ts_GSUP_IE_IMSI(imsi)),</span><br><span style="color: hsl(120, 100%, 40%);">+ valueof(ts_GSUP_IE_MSISDN(msisdn)),</span><br><span style="color: hsl(120, 100%, 40%);">+ valueof(ts_GSUP_IE_Message_Class(OSMO_GSUP_MESSAGE_CLASS_INTER_MSC)),</span><br><span style="color: hsl(120, 100%, 40%);">+ valueof(ts_GSUP_IE_Source_Name(source_name)),</span><br><span style="color: hsl(120, 100%, 40%);">+ valueof(ts_GSUP_IE_Destination_Name(destination_name)),</span><br><span style="color: hsl(120, 100%, 40%);">+ valueof(ts_GSUP_IE_AN_APDU(an_apdu))</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+);</span><br><span> </span><br><span> } with { encode "RAW"; variant "FIELDORDER(msb)" }</span><br><span>diff --git a/library/L3_Templates.ttcn b/library/L3_Templates.ttcn</span><br><span>index 4d71f27..cf6d64c 100644</span><br><span>--- a/library/L3_Templates.ttcn</span><br><span>+++ b/library/L3_Templates.ttcn</span><br><span>@@ -582,6 +582,59 @@</span><br><span> }</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+template PDU_ML3_NW_MS tr_RR_HandoverCommand := {</span><br><span style="color: hsl(120, 100%, 40%);">+ discriminator := '0110'B,</span><br><span style="color: hsl(120, 100%, 40%);">+ tiOrSkip := {</span><br><span style="color: hsl(120, 100%, 40%);">+ skipIndicator := '0000'B</span><br><span style="color: hsl(120, 100%, 40%);">+ },</span><br><span style="color: hsl(120, 100%, 40%);">+ msgs := {</span><br><span style="color: hsl(120, 100%, 40%);">+ rrm := {</span><br><span style="color: hsl(120, 100%, 40%);">+ handoverCommand := {</span><br><span style="color: hsl(120, 100%, 40%);">+ messageType := '00101011'B,</span><br><span style="color: hsl(120, 100%, 40%);">+ cellDescription := ?,</span><br><span style="color: hsl(120, 100%, 40%);">+ channelDescription2 := ?,</span><br><span style="color: hsl(120, 100%, 40%);">+ handoverReference := ?,</span><br><span style="color: hsl(120, 100%, 40%);">+ powerCommandAndAccesstype := ?,</span><br><span style="color: hsl(120, 100%, 40%);">+ synchronizationIndication := *,</span><br><span style="color: hsl(120, 100%, 40%);">+ frequencyShortListAfterTime := *,</span><br><span style="color: hsl(120, 100%, 40%);">+ frequencyListAfterTime := *,</span><br><span style="color: hsl(120, 100%, 40%);">+ cellChannelDescription := *,</span><br><span style="color: hsl(120, 100%, 40%);">+ multislotAllocation := *,</span><br><span style="color: hsl(120, 100%, 40%);">+ modeOfChannelSet1 := *,</span><br><span style="color: hsl(120, 100%, 40%);">+ modeOfChannelSet2 := *,</span><br><span style="color: hsl(120, 100%, 40%);">+ modeOfChannelSet3 := *,</span><br><span style="color: hsl(120, 100%, 40%);">+ modeOfChannelSet4 := *,</span><br><span style="color: hsl(120, 100%, 40%);">+ modeOfChannelSet5 := *,</span><br><span style="color: hsl(120, 100%, 40%);">+ modeOfChannelSet6 := *,</span><br><span style="color: hsl(120, 100%, 40%);">+ modeOfChannelSet7 := *,</span><br><span style="color: hsl(120, 100%, 40%);">+ modeOfChannelSet8 := *,</span><br><span style="color: hsl(120, 100%, 40%);">+ descrOf2ndCh_at := *,</span><br><span style="color: hsl(120, 100%, 40%);">+ modeOf2ndChannel := *,</span><br><span style="color: hsl(120, 100%, 40%);">+ frequencyChannelSequence_at := *,</span><br><span style="color: hsl(120, 100%, 40%);">+ mobileAllocation_at := *,</span><br><span style="color: hsl(120, 100%, 40%);">+ startingTime := *,</span><br><span style="color: hsl(120, 100%, 40%);">+ timeDifference := *,</span><br><span style="color: hsl(120, 100%, 40%);">+ timingAdvance := *,</span><br><span style="color: hsl(120, 100%, 40%);">+ frequencyShortListBeforeTime := *,</span><br><span style="color: hsl(120, 100%, 40%);">+ frequencyListBeforeTime := *,</span><br><span style="color: hsl(120, 100%, 40%);">+ descrOf1stCh_bt := *,</span><br><span style="color: hsl(120, 100%, 40%);">+ descrOf2ndCh_bt := *,</span><br><span style="color: hsl(120, 100%, 40%);">+ frequencyChannelSequence_bt := *,</span><br><span style="color: hsl(120, 100%, 40%);">+ mobileAllocation_bt := *,</span><br><span style="color: hsl(120, 100%, 40%);">+ cipherModeSetting := *,</span><br><span style="color: hsl(120, 100%, 40%);">+ vGCS_TargetModeIndication := *,</span><br><span style="color: hsl(120, 100%, 40%);">+ multiRateConfiguration := *,</span><br><span style="color: hsl(120, 100%, 40%);">+ dynamicARFCN_Mapping := *,</span><br><span style="color: hsl(120, 100%, 40%);">+ vGCS_Ciphering_Parameters := *,</span><br><span style="color: hsl(120, 100%, 40%);">+ dedicatedServiceInformation := *,</span><br><span style="color: hsl(120, 100%, 40%);">+ pLMNIndex := *,</span><br><span style="color: hsl(120, 100%, 40%);">+ extendedTSCSet_afterTime := *,</span><br><span style="color: hsl(120, 100%, 40%);">+ extendedTSCSet_beforeTime := *</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> function ts_CM3_TLV(template (omit) OCTN cm3) return template MobileStationClassmark3_TLV {</span><br><span> if (not isvalue(cm3)) {</span><br><span> return omit;</span><br><span>diff --git a/library/RAN_Emulation.ttcnpp b/library/RAN_Emulation.ttcnpp</span><br><span>index d6d74e2..843cc9e 100644</span><br><span>--- a/library/RAN_Emulation.ttcnpp</span><br><span>+++ b/library/RAN_Emulation.ttcnpp</span><br><span>@@ -133,6 +133,7 @@</span><br><span> RAN_Conn_Prim;</span><br><span> } with { extension "internal" };</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+type uint2_t N_Sd_Array[4];</span><br><span> </span><br><span> /* represents a single BSSAP connection over SCCP */</span><br><span> type record ConnectionData {</span><br><span>@@ -146,7 +147,7 @@</span><br><span> /* CIC that has been used for voice of this channel (BSC side) */</span><br><span> integer cic optional,</span><br><span> /* array of N(SD) values for MO DTAP messages, indexed by discriminator */</span><br><span style="color: hsl(0, 100%, 40%);">- uint2_t n_sd[4]</span><br><span style="color: hsl(120, 100%, 40%);">+ N_Sd_Array n_sd</span><br><span> }</span><br><span> </span><br><span> type record ImsiMapping {</span><br><span>@@ -671,30 +672,53 @@</span><br><span> return false;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-/* patch N(SD) into enc_l3, according to 24.007 11.2.3.2 */</span><br><span style="color: hsl(0, 100%, 40%);">-function f_ML3_patch_seq(inout ConnectionData cd, in PDU_ML3_MS_NW dtap, inout octetstring enc_l3) {</span><br><span style="color: hsl(120, 100%, 40%);">+function f_next_n_sd(inout N_Sd_Array n_sd, in integer n_sd_idx) return uint2_t {</span><br><span> var uint2_t seq_nr;</span><br><span style="color: hsl(0, 100%, 40%);">- if (ischosen(dtap.msgs.cc) or ischosen(dtap.msgs.mm) or ischosen(dtap.msgs.ss)) {</span><br><span style="color: hsl(0, 100%, 40%);">- seq_nr := cd.n_sd[0];</span><br><span style="color: hsl(0, 100%, 40%);">- cd.n_sd[0] := (cd.n_sd[0] + 1) mod 4;</span><br><span style="color: hsl(0, 100%, 40%);">- } else if (ischosen(dtap.msgs.gcc)) {</span><br><span style="color: hsl(0, 100%, 40%);">- seq_nr := cd.n_sd[1];</span><br><span style="color: hsl(0, 100%, 40%);">- cd.n_sd[1] := (cd.n_sd[1] + 1) mod 2;</span><br><span style="color: hsl(0, 100%, 40%);">- } else if (ischosen(dtap.msgs.bcc)) {</span><br><span style="color: hsl(0, 100%, 40%);">- seq_nr := cd.n_sd[2];</span><br><span style="color: hsl(0, 100%, 40%);">- cd.n_sd[2] := (cd.n_sd[2] + 1) mod 2;</span><br><span style="color: hsl(0, 100%, 40%);">- } else if (ischosen(dtap.msgs.loc)) {</span><br><span style="color: hsl(0, 100%, 40%);">- seq_nr := cd.n_sd[3];</span><br><span style="color: hsl(0, 100%, 40%);">- cd.n_sd[3] := (cd.n_sd[3] + 1) mod 2;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (n_sd_idx == 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ seq_nr := n_sd[0];</span><br><span style="color: hsl(120, 100%, 40%);">+ n_sd[0] := (n_sd[0] + 1) mod 4;</span><br><span style="color: hsl(120, 100%, 40%);">+ } else if (n_sd_idx >= 1 and n_sd_idx <= 3) {</span><br><span style="color: hsl(120, 100%, 40%);">+ seq_nr := n_sd[n_sd_idx];</span><br><span style="color: hsl(120, 100%, 40%);">+ n_sd[n_sd_idx] := (n_sd[n_sd_idx] + 1) mod 2;</span><br><span> } else {</span><br><span> /* no sequence number to patch */</span><br><span style="color: hsl(0, 100%, 40%);">- return;</span><br><span style="color: hsl(120, 100%, 40%);">+ seq_nr := 0;</span><br><span> }</span><br><span style="color: hsl(120, 100%, 40%);">+ return seq_nr;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* patch N(SD) into enc_l3, according to 24.007 11.2.3.2 */</span><br><span style="color: hsl(120, 100%, 40%);">+function f_ML3_patch_seq_nr(in uint2_t seq_nr, inout octetstring enc_l3) {</span><br><span> log("patching N(SD)=", seq_nr, " into dtap ", enc_l3);</span><br><span> enc_l3[1] := (enc_l3[1] and4b '3f'O) or4b bit2oct(int2bit(seq_nr, 8) << 6);</span><br><span> log("patched enc_l3: ", enc_l3);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+function f_ML3_n_sd_idx(in PDU_ML3_MS_NW dtap) return integer {</span><br><span style="color: hsl(120, 100%, 40%);">+ var uint2_t seq_nr;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ischosen(dtap.msgs.cc) or ischosen(dtap.msgs.mm) or ischosen(dtap.msgs.ss)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ } else if (ischosen(dtap.msgs.gcc)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+ } else if (ischosen(dtap.msgs.bcc)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ return 2;</span><br><span style="color: hsl(120, 100%, 40%);">+ } else if (ischosen(dtap.msgs.loc)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ return 3;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ /* no sequence number to patch */</span><br><span style="color: hsl(120, 100%, 40%);">+ return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* patch N(SD) into enc_l3, according to 24.007 11.2.3.2 */</span><br><span style="color: hsl(120, 100%, 40%);">+function f_ML3_patch_seq(inout ConnectionData cd, in PDU_ML3_MS_NW dtap, inout octetstring enc_l3) {</span><br><span style="color: hsl(120, 100%, 40%);">+ var integer n_sd_idx := f_ML3_n_sd_idx(dtap);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (n_sd_idx < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ return;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ var uint2_t seq_nr := f_next_n_sd(cd.n_sd, n_sd_idx);</span><br><span style="color: hsl(120, 100%, 40%);">+ f_ML3_patch_seq_nr(seq_nr, enc_l3);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> private altstep as_reset_ack() runs on RAN_Emulation_CT {</span><br><span> #ifdef RAN_EMULATION_BSSAP</span><br><span> var BSSAP_N_UNITDATA_ind ud_ind;</span><br><span>@@ -732,6 +756,8 @@</span><br><span> var BSSAP_Conn_Req creq;</span><br><span> var PDU_BSSAP bssap;</span><br><span> var RAN_ConnHdlr vc_conn;</span><br><span style="color: hsl(120, 100%, 40%);">+ var integer targetPointCode;</span><br><span style="color: hsl(120, 100%, 40%);">+ var N_Sd_Array last_n_sd;</span><br><span> </span><br><span> /* SCCP -> Client: UNIT-DATA (connectionless SCCP) from a BSC */</span><br><span> [] BSSAP.receive(BSSAP_N_UNITDATA_ind:?) -> value ud_ind {</span><br><span>@@ -823,7 +849,18 @@</span><br><span> ConnectionTable[idx].n_sd[0] := 1;</span><br><span> log("patch: N(SD) for ConnIdx ", idx, " set to 1");</span><br><span> }</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ [] PROC.getcall(RAN_last_n_sd:{?,-}) -> param(vc_conn) {</span><br><span style="color: hsl(120, 100%, 40%);">+ var integer idx := f_idx_by_comp(vc_conn);</span><br><span style="color: hsl(120, 100%, 40%);">+ last_n_sd := ConnectionTable[idx].n_sd;</span><br><span style="color: hsl(120, 100%, 40%);">+ PROC.reply(RAN_last_n_sd:{vc_conn, last_n_sd}) to vc_conn;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ [] PROC.getcall(RAN_continue_after_n_sd:{?,?}) -> param(last_n_sd, vc_conn) {</span><br><span style="color: hsl(120, 100%, 40%);">+ var integer idx := f_idx_by_comp(vc_conn);</span><br><span style="color: hsl(120, 100%, 40%);">+ ConnectionTable[idx].n_sd := last_n_sd;</span><br><span style="color: hsl(120, 100%, 40%);">+ PROC.reply(RAN_continue_after_n_sd:{last_n_sd, vc_conn}) to vc_conn;</span><br><span> }</span><br><span> #else</span><br><span> [false] CLIENT.receive {}</span><br><span>@@ -1045,6 +1082,7 @@</span><br><span> var octetstring l3_info;</span><br><span> var hexstring imsi;</span><br><span> var OCT4 tmsi;</span><br><span style="color: hsl(120, 100%, 40%);">+ var integer targetPointCode;</span><br><span> </span><br><span> alt {</span><br><span> [g_ran_ops.protocol == RAN_PROTOCOL_BSSAP] as_main_bssap();</span><br><span>@@ -1075,6 +1113,11 @@</span><br><span> PROC.reply(RAN_register:{l3_info, vc_hdlr}) to vc_hdlr;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ [] PROC.getcall(RAN_register_handoverRequest:{?,?}) -> param(targetPointCode, vc_hdlr) {</span><br><span style="color: hsl(120, 100%, 40%);">+ f_create_expect(omit, vc_hdlr, targetPointCode);</span><br><span style="color: hsl(120, 100%, 40%);">+ PROC.reply(RAN_register_handoverRequest:{targetPointCode, vc_hdlr}) to vc_hdlr;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> [] PROC.getcall(RAN_register_imsi:{?,?,?}) -> param(imsi, tmsi, vc_hdlr) {</span><br><span> f_create_imsi(imsi, tmsi, vc_hdlr);</span><br><span> PROC.reply(RAN_register_imsi:{imsi, tmsi, vc_hdlr}) to vc_hdlr;</span><br><span>@@ -1101,18 +1144,26 @@</span><br><span> type record ExpectData {</span><br><span> /* L3 payload based on which we can match it */</span><br><span> octetstring l3_payload optional,</span><br><span style="color: hsl(120, 100%, 40%);">+ integer handoverRequestPointCode optional,</span><br><span> /* component reference for this connection */</span><br><span> RAN_ConnHdlr vc_conn</span><br><span> }</span><br><span> </span><br><span> /* procedure based port to register for incoming connections */</span><br><span> signature RAN_register(in octetstring l3, in RAN_ConnHdlr hdlr);</span><br><span style="color: hsl(120, 100%, 40%);">+signature RAN_register_handoverRequest(in integer targetPointCode, in RAN_ConnHdlr hdlr);</span><br><span> </span><br><span> /* procedure based port to register for incoming IMSI/TMSI */</span><br><span> signature RAN_register_imsi(in hexstring imsi, in OCT4 tmsi, in RAN_ConnHdlr hdlr);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/* If DTAP happens across other channels (e.g. GSUP), provide manual advancing of the n_sd sequence number */</span><br><span style="color: hsl(120, 100%, 40%);">+signature RAN_last_n_sd(in RAN_ConnHdlr hdlr, out N_Sd_Array last_n_sd);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Update conn's n_sd sequence nr after the connection was taken over from elsewhere */</span><br><span style="color: hsl(120, 100%, 40%);">+signature RAN_continue_after_n_sd(N_Sd_Array last_n_sd, in RAN_ConnHdlr hdlr);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> type port RAN_PROC_PT procedure {</span><br><span style="color: hsl(0, 100%, 40%);">- inout RAN_register, RAN_register_imsi;</span><br><span style="color: hsl(120, 100%, 40%);">+ inout RAN_register, RAN_register_imsi, RAN_register_handoverRequest, RAN_last_n_sd, RAN_continue_after_n_sd;</span><br><span> } with { extension "internal" };</span><br><span> </span><br><span> #ifdef RAN_EMULATION_BSSAP</span><br><span>@@ -1121,16 +1172,35 @@</span><br><span> runs on RAN_Emulation_CT return RAN_ConnHdlr {</span><br><span> var RAN_ConnHdlr ret := null;</span><br><span> var octetstring l3_info;</span><br><span style="color: hsl(120, 100%, 40%);">+ var boolean handoverRequest := false;</span><br><span style="color: hsl(120, 100%, 40%);">+ var integer handoverRequestPointCode;</span><br><span> var integer i;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- if (not ischosen(conn_ind.userData.pdu.bssmap.completeLayer3Information)) {</span><br><span style="color: hsl(0, 100%, 40%);">- setverdict(fail, "N-CONNECT.ind with L3 != COMPLETE L3");</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ischosen(conn_ind.userData.pdu.bssmap.completeLayer3Information)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ l3_info := conn_ind.userData.pdu.bssmap.completeLayer3Information.layer3Information.layer3info;</span><br><span style="color: hsl(120, 100%, 40%);">+ log("ExpectedCreateCallback completeLayer3Information");</span><br><span style="color: hsl(120, 100%, 40%);">+ } else if (ischosen(conn_ind.userData.pdu.bssmap.handoverRequest)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ handoverRequest := true;</span><br><span style="color: hsl(120, 100%, 40%);">+ handoverRequestPointCode := bit2int(conn_ind.calledAddress.signPointCode);</span><br><span style="color: hsl(120, 100%, 40%);">+ log("ExpectedCreateCallback handoverRequest ", handoverRequestPointCode);</span><br><span style="color: hsl(120, 100%, 40%);">+ } else {</span><br><span style="color: hsl(120, 100%, 40%);">+ setverdict(fail, "N-CONNECT.ind with L3 != COMPLETE L3 nor a Handover Request");</span><br><span> mtc.stop;</span><br><span> return ret;</span><br><span> }</span><br><span style="color: hsl(0, 100%, 40%);">- l3_info := conn_ind.userData.pdu.bssmap.completeLayer3Information.layer3Information.layer3info;</span><br><span> </span><br><span> for (i := 0; i < sizeof(ExpectTable); i:= i+1) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (handoverRequest) {</span><br><span style="color: hsl(120, 100%, 40%);">+ log("ExpectTable[", i, "].handoverRequestPointCode = ", ExpectTable[i].handoverRequestPointCode,</span><br><span style="color: hsl(120, 100%, 40%);">+ " ==? ", handoverRequestPointCode);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ExpectTable[i].handoverRequestPointCode == handoverRequestPointCode) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ret := ExpectTable[i].vc_conn;</span><br><span style="color: hsl(120, 100%, 40%);">+ log("Found Expect[", i, "] for handoverRequest handled at ", ret);</span><br><span style="color: hsl(120, 100%, 40%);">+ return ret;</span><br><span style="color: hsl(120, 100%, 40%);">+ } else {</span><br><span style="color: hsl(120, 100%, 40%);">+ continue;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span> if (not ispresent(ExpectTable[i].l3_payload)) {</span><br><span> continue;</span><br><span> }</span><br><span>@@ -1185,14 +1255,26 @@</span><br><span> }</span><br><span> #endif</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-private function f_create_expect(octetstring l3, RAN_ConnHdlr hdlr)</span><br><span style="color: hsl(120, 100%, 40%);">+private function f_create_expect(template octetstring l3, RAN_ConnHdlr hdlr,</span><br><span style="color: hsl(120, 100%, 40%);">+ template integer handoverRequestPointCode := omit)</span><br><span> runs on RAN_Emulation_CT {</span><br><span> var integer i;</span><br><span style="color: hsl(120, 100%, 40%);">+ log("f_create_expect(l3 := ", l3, ", handoverRequest := ", handoverRequestPointCode);</span><br><span> for (i := 0; i < sizeof(ExpectTable); i := i+1) {</span><br><span style="color: hsl(0, 100%, 40%);">- if (not ispresent(ExpectTable[i].l3_payload)) {</span><br><span style="color: hsl(0, 100%, 40%);">- ExpectTable[i].l3_payload := l3;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (not ispresent(ExpectTable[i].l3_payload)</span><br><span style="color: hsl(120, 100%, 40%);">+ and not ispresent(ExpectTable[i].handoverRequestPointCode)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ispresent(l3)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ExpectTable[i].l3_payload := valueof(l3);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ispresent(handoverRequestPointCode)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ExpectTable[i].handoverRequestPointCode := valueof(handoverRequestPointCode);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span> ExpectTable[i].vc_conn := hdlr;</span><br><span style="color: hsl(0, 100%, 40%);">- log("Created Expect[", i, "] for ", l3, " to be handled at ", hdlr);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ispresent(handoverRequestPointCode)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ log("Created Expect[", i, "] for handoverRequest to be handled at ", hdlr);</span><br><span style="color: hsl(120, 100%, 40%);">+ } else {</span><br><span style="color: hsl(120, 100%, 40%);">+ log("Created Expect[", i, "] for ", l3, " to be handled at ", hdlr);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span> return;</span><br><span> }</span><br><span> }</span><br><span>@@ -1218,6 +1300,7 @@</span><br><span> runs on RAN_Emulation_CT {</span><br><span> for (var integer i := 0; i < sizeof(ExpectTable); i := i+1) {</span><br><span> ExpectTable[i].l3_payload := omit;</span><br><span style="color: hsl(120, 100%, 40%);">+ ExpectTable[i].handoverRequestPointCode := omit;</span><br><span> }</span><br><span> }</span><br><span> </span><br><span>diff --git a/msc/BSC_ConnectionHandler.ttcn b/msc/BSC_ConnectionHandler.ttcn</span><br><span>index 44d3c6d..1cec69c 100644</span><br><span>--- a/msc/BSC_ConnectionHandler.ttcn</span><br><span>+++ b/msc/BSC_ConnectionHandler.ttcn</span><br><span>@@ -1133,6 +1133,27 @@</span><br><span> }</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+function f_create_bssmap_exp_handoverRequest(integer targetPointCode) runs on BSC_ConnHdlr {</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSAP_PROC.call(RAN_register_handoverRequest:{targetPointCode, self}) {</span><br><span style="color: hsl(120, 100%, 40%);">+ [] BSSAP_PROC.getreply(RAN_register_handoverRequest:{?, ?}) {};</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+function f_bssmap_last_n_sd() runs on BSC_ConnHdlr return N_Sd_Array {</span><br><span style="color: hsl(120, 100%, 40%);">+ var N_Sd_Array last_n_sd;</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSAP_PROC.call(RAN_last_n_sd:{self, -}) {</span><br><span style="color: hsl(120, 100%, 40%);">+ [] BSSAP_PROC.getreply(RAN_last_n_sd:{self, ?}) -> param(last_n_sd) {</span><br><span style="color: hsl(120, 100%, 40%);">+ return last_n_sd;</span><br><span style="color: hsl(120, 100%, 40%);">+ };</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+function f_bssmap_continue_after_n_sd(N_Sd_Array last_n_sd) runs on BSC_ConnHdlr {</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSAP_PROC.call(RAN_continue_after_n_sd:{last_n_sd, self}) {</span><br><span style="color: hsl(120, 100%, 40%);">+ [] BSSAP_PROC.getreply(RAN_continue_after_n_sd:{last_n_sd, self});</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> type record SmsParametersTp {</span><br><span> OCT1 msg_ref,</span><br><span> TP_DA da,</span><br><span>diff --git a/msc/MSC_Tests.ttcn b/msc/MSC_Tests.ttcn</span><br><span>index 709a73c..3a6711b 100644</span><br><span>--- a/msc/MSC_Tests.ttcn</span><br><span>+++ b/msc/MSC_Tests.ttcn</span><br><span>@@ -468,31 +468,6 @@</span><br><span> }</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-template PDU_BSSAP ts_BSSMAP_HandoReq(BssmapCause cause, BSSMAP_IE_CellIdentifierList cid_list)</span><br><span style="color: hsl(0, 100%, 40%);">-modifies ts_BSSAP_BSSMAP := {</span><br><span style="color: hsl(0, 100%, 40%);">- pdu := {</span><br><span style="color: hsl(0, 100%, 40%);">- bssmap := {</span><br><span style="color: hsl(0, 100%, 40%);">- handoverRequired := {</span><br><span style="color: hsl(0, 100%, 40%);">- messageType := '11'O,</span><br><span style="color: hsl(0, 100%, 40%);">- cause := ts_BSSMAP_IE_Cause(cause),</span><br><span style="color: hsl(0, 100%, 40%);">- responseRequest := omit,</span><br><span style="color: hsl(0, 100%, 40%);">- cellIdentifierList := cid_list,</span><br><span style="color: hsl(0, 100%, 40%);">- circuitPoolList := omit,</span><br><span style="color: hsl(0, 100%, 40%);">- currentChannelType1 := omit,</span><br><span style="color: hsl(0, 100%, 40%);">- speechVersion := omit,</span><br><span style="color: hsl(0, 100%, 40%);">- queueingIndicator := omit,</span><br><span style="color: hsl(0, 100%, 40%);">- oldToNewBSSInfo := omit,</span><br><span style="color: hsl(0, 100%, 40%);">- sourceToTargetRNCTransparentInfo := omit,</span><br><span style="color: hsl(0, 100%, 40%);">- sourceToTargetRNCTransparentInfoCDMA := omit,</span><br><span style="color: hsl(0, 100%, 40%);">- gERANClassmark := omit,</span><br><span style="color: hsl(0, 100%, 40%);">- talkerPriority := omit,</span><br><span style="color: hsl(0, 100%, 40%);">- speechCodec := omit,</span><br><span style="color: hsl(0, 100%, 40%);">- cSG_Identifier := omit</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> type function void_fn(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr;</span><br><span> </span><br><span> /* FIXME: move into BSC_ConnectionHandler? */</span><br><span>@@ -536,14 +511,14 @@</span><br><span> return pars;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-function f_start_handler_with_pars(void_fn fn, BSC_ConnHdlrPars pars) runs on MTC_CT return BSC_ConnHdlr {</span><br><span style="color: hsl(120, 100%, 40%);">+function f_start_handler_with_pars(void_fn fn, BSC_ConnHdlrPars pars, integer bssap_idx := 0) runs on MTC_CT return BSC_ConnHdlr {</span><br><span> var BSC_ConnHdlr vc_conn;</span><br><span style="color: hsl(0, 100%, 40%);">- var charstring id := testcasename();</span><br><span style="color: hsl(120, 100%, 40%);">+ var charstring id := testcasename() & int2str(bssap_idx);</span><br><span> </span><br><span> vc_conn := BSC_ConnHdlr.create(id);</span><br><span> /* BSSMAP part / A interface */</span><br><span style="color: hsl(0, 100%, 40%);">- connect(vc_conn:BSSAP, g_bssap[pars.ran_idx].vc_RAN:CLIENT);</span><br><span style="color: hsl(0, 100%, 40%);">- connect(vc_conn:BSSAP_PROC, g_bssap[pars.ran_idx].vc_RAN:PROC);</span><br><span style="color: hsl(120, 100%, 40%);">+ connect(vc_conn:BSSAP, g_bssap[pars.ran_idx + bssap_idx].vc_RAN:CLIENT);</span><br><span style="color: hsl(120, 100%, 40%);">+ connect(vc_conn:BSSAP_PROC, g_bssap[pars.ran_idx + bssap_idx].vc_RAN:PROC);</span><br><span> /* MNCC part */</span><br><span> connect(vc_conn:MNCC, vc_MNCC:MNCC_CLIENT);</span><br><span> connect(vc_conn:MNCC_PROC, vc_MNCC:MNCC_PROC);</span><br><span>@@ -4776,6 +4751,464 @@</span><br><span> *</span><br><span> */</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+private function f_tc_ho_inter_bsc_unknown_cell(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {</span><br><span style="color: hsl(120, 100%, 40%);">+ f_init_handler(pars);</span><br><span style="color: hsl(120, 100%, 40%);">+ var CallParameters cpars := valueof(t_CallParams('12345'H, 0));</span><br><span style="color: hsl(120, 100%, 40%);">+ cpars.bss_rtp_port := 1110;</span><br><span style="color: hsl(120, 100%, 40%);">+ cpars.mgcp_connection_id_bss := '22222'H;</span><br><span style="color: hsl(120, 100%, 40%);">+ cpars.mgcp_connection_id_mss := '33333'H;</span><br><span style="color: hsl(120, 100%, 40%);">+ cpars.mgcp_ep := "rtpbridge/1@mgw";</span><br><span style="color: hsl(120, 100%, 40%);">+ cpars.mo_call := true;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ f_perform_lu();</span><br><span style="color: hsl(120, 100%, 40%);">+ f_mo_call_establish(cpars);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ f_sleep(1.0);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ var myBSSMAP_Cause cause_val := GSM0808_CAUSE_BETTER_CELL;</span><br><span style="color: hsl(120, 100%, 40%);">+ var BssmapCause cause := enum2int(cause_val);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ var template BSSMAP_FIELD_CellIdentificationList cil;</span><br><span style="color: hsl(120, 100%, 40%);">+ cil := { cIl_LAI := { ts_BSSMAP_CI_LAI('023'H, '42'H, 999) } };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSAP.send(ts_BSSMAP_HandoverRequired(cause, cil));</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSAP.receive(tr_BSSMAP_HandoverRequiredReject);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ f_call_hangup(cpars, true);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+testcase TC_ho_inter_bsc_unknown_cell() runs on MTC_CT {</span><br><span style="color: hsl(120, 100%, 40%);">+ var BSC_ConnHdlr vc_conn;</span><br><span style="color: hsl(120, 100%, 40%);">+ f_init();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ vc_conn := f_start_handler(refers(f_tc_ho_inter_bsc_unknown_cell), 53);</span><br><span style="color: hsl(120, 100%, 40%);">+ vc_conn.done;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+private altstep as_mgcp_ack_all_mdcx(CallParameters cpars) runs on BSC_ConnHdlr {</span><br><span style="color: hsl(120, 100%, 40%);">+ var MgcpCommand mgcp_cmd;</span><br><span style="color: hsl(120, 100%, 40%);">+ [] MGCP.receive(tr_MDCX) -> value mgcp_cmd {</span><br><span style="color: hsl(120, 100%, 40%);">+ var SDP_Message sdp := valueof(ts_SDP(cpars.mgw_rtp_ip_mss, cpars.mgw_rtp_ip_mss,</span><br><span style="color: hsl(120, 100%, 40%);">+ hex2str(cpars.mgcp_call_id), "42",</span><br><span style="color: hsl(120, 100%, 40%);">+ cpars.mgw_rtp_port_mss,</span><br><span style="color: hsl(120, 100%, 40%);">+ { int2str(cpars.rtp_payload_type) },</span><br><span style="color: hsl(120, 100%, 40%);">+ { valueof(ts_SDP_rtpmap(cpars.rtp_payload_type,</span><br><span style="color: hsl(120, 100%, 40%);">+ cpars.rtp_sdp_format)),</span><br><span style="color: hsl(120, 100%, 40%);">+ valueof(ts_SDP_ptime(20)) }));</span><br><span style="color: hsl(120, 100%, 40%);">+ MGCP.send(ts_MDCX_ACK(mgcp_cmd.line.trans_id, cpars.mgcp_connection_id_mss, sdp));</span><br><span style="color: hsl(120, 100%, 40%);">+ repeat;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+private function f_tc_ho_inter_bsc0(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {</span><br><span style="color: hsl(120, 100%, 40%);">+ var CallParameters cpars := valueof(t_CallParams('12345'H, 0));</span><br><span style="color: hsl(120, 100%, 40%);">+ cpars.bss_rtp_port := 1110;</span><br><span style="color: hsl(120, 100%, 40%);">+ cpars.mgcp_connection_id_bss := '22222'H;</span><br><span style="color: hsl(120, 100%, 40%);">+ cpars.mgcp_connection_id_mss := '33333'H;</span><br><span style="color: hsl(120, 100%, 40%);">+ cpars.mgcp_ep := "rtpbridge/1@mgw";</span><br><span style="color: hsl(120, 100%, 40%);">+ cpars.mo_call := true;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ f_init_handler(pars);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ f_vty_transceive(MSCVTY, "configure terminal");</span><br><span style="color: hsl(120, 100%, 40%);">+ f_vty_transceive(MSCVTY, "msc");</span><br><span style="color: hsl(120, 100%, 40%);">+ f_vty_transceive(MSCVTY, "neighbor a cgi 262 42 23 42 ran-pc 0.24.1");</span><br><span style="color: hsl(120, 100%, 40%);">+ f_vty_transceive(MSCVTY, "neighbor a lac 5 ran-pc 0.24.2");</span><br><span style="color: hsl(120, 100%, 40%);">+ f_vty_transceive(MSCVTY, "exit");</span><br><span style="color: hsl(120, 100%, 40%);">+ f_vty_transceive(MSCVTY, "exit");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ f_perform_lu();</span><br><span style="color: hsl(120, 100%, 40%);">+ f_mo_call_establish(cpars);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ f_sleep(1.0);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ var default ack_mdcx := activate(as_mgcp_ack_all_mdcx(cpars));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ var myBSSMAP_Cause cause_val := GSM0808_CAUSE_BETTER_CELL;</span><br><span style="color: hsl(120, 100%, 40%);">+ var BssmapCause cause := enum2int(cause_val);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ var template BSSMAP_FIELD_CellIdentificationList cil;</span><br><span style="color: hsl(120, 100%, 40%);">+ cil := { cIl_LAI := { ts_BSSMAP_CI_LAI('023'H, '42'H, 5) } };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* old BSS sends Handover Required */</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSAP.send(ts_BSSMAP_HandoverRequired(cause, cil));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Now the action goes on in f_tc_ho_inter_bsc1() */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* MSC forwards the RR Handover Command to old BSS */</span><br><span style="color: hsl(120, 100%, 40%);">+ var PDU_BSSAP ho_command;</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSAP.receive(tr_BSSMAP_HandoverCommand) -> value ho_command;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ log("GOT HandoverCommand", ho_command);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSAP.receive(tr_BSSMAP_HandoverSucceeded);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* f_tc_ho_inter_bsc1() completes Handover, then expecting a Clear here. */</span><br><span style="color: hsl(120, 100%, 40%);">+ f_expect_clear();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ log("FIRST inter-BSC Handover done");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* ------------------------ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Ok, that went well, now the other BSC is handovering back here --</span><br><span style="color: hsl(120, 100%, 40%);">+ * from now on this here is the new BSS. */</span><br><span style="color: hsl(120, 100%, 40%);">+ f_create_bssmap_exp_handoverRequest(193);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ var PDU_BSSAP ho_request;</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSAP.receive(tr_BSSMAP_HandoverRequest) -> value ho_request;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* new BSS composes a RR Handover Command */</span><br><span style="color: hsl(120, 100%, 40%);">+ var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);</span><br><span style="color: hsl(120, 100%, 40%);">+ var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);</span><br><span style="color: hsl(120, 100%, 40%);">+ var BSSMAP_IE_AoIP_TransportLayerAddress tla := valueof(ts_BSSMAP_IE_AoIP_TLA4('01020304'O, 2342));</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSAP.send(ts_BSSMAP_HandoverRequestAcknowledge(rr_ho_cmd_enc, lengthof(rr_ho_cmd_enc),</span><br><span style="color: hsl(120, 100%, 40%);">+ tla, ts_BSSMAP_IE_SpeechCodec({ts_CodecFR})));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Now f_tc_ho_inter_bsc1() expects HandoverCommand */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ f_sleep(0.5);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Notify that the MS is now over here */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSAP.send(ts_BSSMAP_HandoverDetect);</span><br><span style="color: hsl(120, 100%, 40%);">+ f_sleep(0.1);</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSAP.send(ts_BSSMAP_HandoverComplete);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ f_sleep(3.0);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ deactivate(ack_mdcx);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ var default ccrel := activate(as_optional_cc_rel(cpars, true));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* blatant cheating */</span><br><span style="color: hsl(120, 100%, 40%);">+ var N_Sd_Array last_n_sd := f_bssmap_last_n_sd();</span><br><span style="color: hsl(120, 100%, 40%);">+ last_n_sd[0] := 3;</span><br><span style="color: hsl(120, 100%, 40%);">+ f_bssmap_continue_after_n_sd(last_n_sd);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ f_call_hangup(cpars, true);</span><br><span style="color: hsl(120, 100%, 40%);">+ f_sleep(1.0);</span><br><span style="color: hsl(120, 100%, 40%);">+ deactivate(ccrel);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ setverdict(pass);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+private function f_tc_ho_inter_bsc1(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {</span><br><span style="color: hsl(120, 100%, 40%);">+ f_init_handler(pars);</span><br><span style="color: hsl(120, 100%, 40%);">+ f_create_bssmap_exp_handoverRequest(194);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ var PDU_BSSAP ho_request;</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSAP.receive(tr_BSSMAP_HandoverRequest) -> value ho_request;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* new BSS composes a RR Handover Command */</span><br><span style="color: hsl(120, 100%, 40%);">+ var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);</span><br><span style="color: hsl(120, 100%, 40%);">+ var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);</span><br><span style="color: hsl(120, 100%, 40%);">+ var BSSMAP_IE_AoIP_TransportLayerAddress tla := valueof(ts_BSSMAP_IE_AoIP_TLA4('01020304'O, 2342));</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSAP.send(ts_BSSMAP_HandoverRequestAcknowledge(rr_ho_cmd_enc, lengthof(rr_ho_cmd_enc),</span><br><span style="color: hsl(120, 100%, 40%);">+ tla, ts_BSSMAP_IE_SpeechCodec({ts_CodecFR})));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Now f_tc_ho_inter_bsc0() expects HandoverCommand */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ f_sleep(0.5);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Notify that the MS is now over here */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSAP.send(ts_BSSMAP_HandoverDetect);</span><br><span style="color: hsl(120, 100%, 40%);">+ f_sleep(0.1);</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSAP.send(ts_BSSMAP_HandoverComplete);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ f_sleep(3.0);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Now I'd like to f_call_hangup() but we don't know any cpars here. So</span><br><span style="color: hsl(120, 100%, 40%);">+ * ... handover back to the first BSC :P */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ var myBSSMAP_Cause cause_val := GSM0808_CAUSE_BETTER_CELL;</span><br><span style="color: hsl(120, 100%, 40%);">+ var BssmapCause cause := enum2int(cause_val);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ var template BSSMAP_FIELD_CellIdentificationList cil;</span><br><span style="color: hsl(120, 100%, 40%);">+ cil := { cIl_LAI := { ts_BSSMAP_CI_LAI('262'H, '42'H, 23) } };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* old BSS sends Handover Required */</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSAP.send(ts_BSSMAP_HandoverRequired(cause, cil));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Now the action goes on in f_tc_ho_inter_bsc0() */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* MSC forwards the RR Handover Command to old BSS */</span><br><span style="color: hsl(120, 100%, 40%);">+ var PDU_BSSAP ho_command;</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSAP.receive(tr_BSSMAP_HandoverCommand) -> value ho_command;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ log("GOT HandoverCommand", ho_command);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSAP.receive(tr_BSSMAP_HandoverSucceeded);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* f_tc_ho_inter_bsc1() completes Handover, then expecting a Clear here. */</span><br><span style="color: hsl(120, 100%, 40%);">+ f_expect_clear();</span><br><span style="color: hsl(120, 100%, 40%);">+ setverdict(pass);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+testcase TC_ho_inter_bsc() runs on MTC_CT {</span><br><span style="color: hsl(120, 100%, 40%);">+ var BSC_ConnHdlr vc_conn0;</span><br><span style="color: hsl(120, 100%, 40%);">+ var BSC_ConnHdlr vc_conn1;</span><br><span style="color: hsl(120, 100%, 40%);">+ f_init(2);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ var BSC_ConnHdlrPars pars0 := f_init_pars(53);</span><br><span style="color: hsl(120, 100%, 40%);">+ var BSC_ConnHdlrPars pars1 := f_init_pars(53);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ vc_conn0 := f_start_handler_with_pars(refers(f_tc_ho_inter_bsc0), pars0, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+ vc_conn1 := f_start_handler_with_pars(refers(f_tc_ho_inter_bsc1), pars1, 1);</span><br><span style="color: hsl(120, 100%, 40%);">+ vc_conn0.done;</span><br><span style="color: hsl(120, 100%, 40%);">+ vc_conn1.done;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+function f_ML3_patch_seq_nr_MS_NW(in uint2_t seq_nr, inout octetstring enc_l3) {</span><br><span style="color: hsl(120, 100%, 40%);">+ log("MS_NW patching N(SD)=", seq_nr, " into dtap ", enc_l3);</span><br><span style="color: hsl(120, 100%, 40%);">+ enc_l3[2] := (enc_l3[2] and4b '3f'O) or4b bit2oct(int2bit(seq_nr, 8) << 6);</span><br><span style="color: hsl(120, 100%, 40%);">+ log("MS_NW patched enc_l3: ", enc_l3);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+private function f_tc_ho_inter_msc_out(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {</span><br><span style="color: hsl(120, 100%, 40%);">+ var CallParameters cpars := valueof(t_CallParams('12345'H, 0));</span><br><span style="color: hsl(120, 100%, 40%);">+ cpars.bss_rtp_port := 1110;</span><br><span style="color: hsl(120, 100%, 40%);">+ cpars.mgcp_connection_id_bss := '22222'H;</span><br><span style="color: hsl(120, 100%, 40%);">+ cpars.mgcp_connection_id_mss := '33333'H;</span><br><span style="color: hsl(120, 100%, 40%);">+ cpars.mgcp_ep := "rtpbridge/1@mgw";</span><br><span style="color: hsl(120, 100%, 40%);">+ cpars.mo_call := true;</span><br><span style="color: hsl(120, 100%, 40%);">+ var hexstring ho_number := f_gen_msisdn(99999);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ f_init_handler(pars);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ f_create_mncc_expect(hex2str(ho_number));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ f_vty_transceive(MSCVTY, "configure terminal");</span><br><span style="color: hsl(120, 100%, 40%);">+ f_vty_transceive(MSCVTY, "msc");</span><br><span style="color: hsl(120, 100%, 40%);">+ f_vty_transceive(MSCVTY, "neighbor a cgi 017 017 1 1 msc-ipa-name msc-017-017-1");</span><br><span style="color: hsl(120, 100%, 40%);">+ f_vty_transceive(MSCVTY, "exit");</span><br><span style="color: hsl(120, 100%, 40%);">+ f_vty_transceive(MSCVTY, "exit");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ f_perform_lu();</span><br><span style="color: hsl(120, 100%, 40%);">+ f_mo_call_establish(cpars);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ f_sleep(1.0);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ var default ack_mdcx := activate(as_mgcp_ack_all_mdcx(cpars));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ var myBSSMAP_Cause cause_val := GSM0808_CAUSE_BETTER_CELL;</span><br><span style="color: hsl(120, 100%, 40%);">+ var BssmapCause cause := enum2int(cause_val);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ var template BSSMAP_FIELD_CellIdentificationList cil;</span><br><span style="color: hsl(120, 100%, 40%);">+ cil := { cIl_LAI := { ts_BSSMAP_CI_LAI('017'H, '017'H, 1) } };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* old BSS sends Handover Required */</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSAP.send(ts_BSSMAP_HandoverRequired(cause, cil));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* The target cell 017-017 LAC 1 is configured to be a remote MSC of name "msc-017-017-1".</span><br><span style="color: hsl(120, 100%, 40%);">+ * This MSC tries to reach the other MSC via GSUP. */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ var octetstring remote_msc_name := '6D73632D3031372D3031372D3100'O; /* "msc-017-017-1\0" as octetstring */</span><br><span style="color: hsl(120, 100%, 40%);">+ var GSUP_PDU prep_ho_req;</span><br><span style="color: hsl(120, 100%, 40%);">+ GSUP.receive(tr_GSUP_E_AN_APDU(OSMO_GSUP_MSGT_E_PREPARE_HANDOVER_REQUEST,</span><br><span style="color: hsl(120, 100%, 40%);">+ pars.imsi, destination_name := remote_msc_name)) -> value prep_ho_req;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ var GSUP_IeValue source_name_ie;</span><br><span style="color: hsl(120, 100%, 40%);">+ f_gsup_find_ie(prep_ho_req, OSMO_GSUP_SOURCE_NAME_IE, source_name_ie);</span><br><span style="color: hsl(120, 100%, 40%);">+ var octetstring local_msc_name := source_name_ie.source_name;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Remote MSC has figured out its BSC and signals success */</span><br><span style="color: hsl(120, 100%, 40%);">+ var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);</span><br><span style="color: hsl(120, 100%, 40%);">+ var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);</span><br><span style="color: hsl(120, 100%, 40%);">+ var PDU_BSSAP ho_req_ack := valueof(ts_BSSMAP_HandoverRequestAcknowledge(rr_ho_cmd_enc, lengthof(rr_ho_cmd_enc),</span><br><span style="color: hsl(120, 100%, 40%);">+ aoIPTransportLayer := omit,</span><br><span style="color: hsl(120, 100%, 40%);">+ speechCodec := ts_BSSMAP_IE_SpeechCodec({ts_CodecFR})));</span><br><span style="color: hsl(120, 100%, 40%);">+ GSUP.send(ts_GSUP_E_PrepareHandoverResult(</span><br><span style="color: hsl(120, 100%, 40%);">+ pars.imsi,</span><br><span style="color: hsl(120, 100%, 40%);">+ ho_number,</span><br><span style="color: hsl(120, 100%, 40%);">+ remote_msc_name, local_msc_name,</span><br><span style="color: hsl(120, 100%, 40%);">+ valueof(t_GSUP_AN_APDU(OSMO_GSUP_AN_PROTO_48006, enc_PDU_BSSAP(ho_req_ack)))));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* MSC forwards the RR Handover Command to old BSS */</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSAP.receive(tr_BSSMAP_HandoverCommand);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* The MS shows up at remote new BSS */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ GSUP.send(ts_GSUP_E_AN_APDU(OSMO_GSUP_MSGT_E_PROCESS_ACCESS_SIGNALLING_REQUEST,</span><br><span style="color: hsl(120, 100%, 40%);">+ pars.imsi, remote_msc_name, local_msc_name,</span><br><span style="color: hsl(120, 100%, 40%);">+ valueof(t_GSUP_AN_APDU(OSMO_GSUP_AN_PROTO_48006,</span><br><span style="color: hsl(120, 100%, 40%);">+ enc_PDU_BSSAP(valueof(ts_BSSMAP_HandoverDetect))))));</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSAP.receive(tr_BSSMAP_HandoverSucceeded);</span><br><span style="color: hsl(120, 100%, 40%);">+ f_sleep(0.1);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Save the MS sequence counters for use on the other connection */</span><br><span style="color: hsl(120, 100%, 40%);">+ var N_Sd_Array last_n_sd := f_bssmap_last_n_sd();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ GSUP.send(ts_GSUP_E_AN_APDU(OSMO_GSUP_MSGT_E_SEND_END_SIGNAL_REQUEST,</span><br><span style="color: hsl(120, 100%, 40%);">+ pars.imsi, remote_msc_name, local_msc_name,</span><br><span style="color: hsl(120, 100%, 40%);">+ valueof(t_GSUP_AN_APDU(OSMO_GSUP_AN_PROTO_48006,</span><br><span style="color: hsl(120, 100%, 40%);">+ enc_PDU_BSSAP(valueof(ts_BSSMAP_HandoverComplete))))));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* The local BSS conn clears, all communication goes via remote MSC now */</span><br><span style="color: hsl(120, 100%, 40%);">+ f_expect_clear();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /**********************************/</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Play through some signalling across the inter-MSC link.</span><br><span style="color: hsl(120, 100%, 40%);">+ * This is a copy of f_tc_lu_and_mo_ussd_single_request() translated into GSUP AN-APDUs. */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (false) {</span><br><span style="color: hsl(120, 100%, 40%);">+ var template OCTN facility_req := f_USSD_FACILITY_IE_INVOKE(</span><br><span style="color: hsl(120, 100%, 40%);">+ invoke_id := 5, /* Phone may not start from 0 or 1 */</span><br><span style="color: hsl(120, 100%, 40%);">+ op_code := SS_OP_CODE_PROCESS_USS_REQ,</span><br><span style="color: hsl(120, 100%, 40%);">+ ussd_string := "*#100#"</span><br><span style="color: hsl(120, 100%, 40%);">+ );</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ var template OCTN facility_rsp := f_USSD_FACILITY_IE_RETURN_RESULT(</span><br><span style="color: hsl(120, 100%, 40%);">+ invoke_id := 5, /* InvokeID shall be the same for both REQ and RSP */</span><br><span style="color: hsl(120, 100%, 40%);">+ op_code := SS_OP_CODE_PROCESS_USS_REQ,</span><br><span style="color: hsl(120, 100%, 40%);">+ ussd_string := "Your extension is " & hex2str(g_pars.msisdn) & "\r"</span><br><span style="color: hsl(120, 100%, 40%);">+ )</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Compose a new SS/REGISTER message with request */</span><br><span style="color: hsl(120, 100%, 40%);">+ var template (value) PDU_ML3_MS_NW ussd_req := ts_ML3_MO_SS_REGISTER(</span><br><span style="color: hsl(120, 100%, 40%);">+ tid := 1, /* We just need a single transaction */</span><br><span style="color: hsl(120, 100%, 40%);">+ ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */</span><br><span style="color: hsl(120, 100%, 40%);">+ facility := valueof(facility_req)</span><br><span style="color: hsl(120, 100%, 40%);">+ );</span><br><span style="color: hsl(120, 100%, 40%);">+ var PDU_ML3_MS_NW ussd_req_v := valueof(ussd_req);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Compose SS/RELEASE_COMPLETE template with expected response */</span><br><span style="color: hsl(120, 100%, 40%);">+ var template PDU_ML3_NW_MS ussd_rsp := tr_ML3_MT_SS_RELEASE_COMPLETE(</span><br><span style="color: hsl(120, 100%, 40%);">+ tid := 1, /* Response should arrive within the same transaction */</span><br><span style="color: hsl(120, 100%, 40%);">+ ti_flag := c_TIF_REPL, /* Sent to the side that originates the TI */</span><br><span style="color: hsl(120, 100%, 40%);">+ facility := valueof(facility_rsp)</span><br><span style="color: hsl(120, 100%, 40%);">+ );</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Compose expected MSC -> HLR message */</span><br><span style="color: hsl(120, 100%, 40%);">+ var template GSUP_PDU gsup_req := tr_GSUP_PROC_SS_REQ(</span><br><span style="color: hsl(120, 100%, 40%);">+ imsi := g_pars.imsi,</span><br><span style="color: hsl(120, 100%, 40%);">+ state := OSMO_GSUP_SESSION_STATE_BEGIN,</span><br><span style="color: hsl(120, 100%, 40%);">+ ss := valueof(facility_req)</span><br><span style="color: hsl(120, 100%, 40%);">+ );</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* To be used for sending response with correct session ID */</span><br><span style="color: hsl(120, 100%, 40%);">+ var GSUP_PDU gsup_req_complete;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Request own number */</span><br><span style="color: hsl(120, 100%, 40%);">+ /* From remote MSC instead of BSSAP directly */</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Patch the correct N_SD value into the message. */</span><br><span style="color: hsl(120, 100%, 40%);">+ var octetstring l3_enc := enc_PDU_ML3_MS_NW(ussd_req_v);</span><br><span style="color: hsl(120, 100%, 40%);">+ var RAN_Emulation.ConnectionData cd;</span><br><span style="color: hsl(120, 100%, 40%);">+ f_ML3_patch_seq_nr_MS_NW(f_next_n_sd(last_n_sd, f_ML3_n_sd_idx(ussd_req_v)), l3_enc);</span><br><span style="color: hsl(120, 100%, 40%);">+ GSUP.send(ts_GSUP_E_AN_APDU(OSMO_GSUP_MSGT_E_PROCESS_ACCESS_SIGNALLING_REQUEST,</span><br><span style="color: hsl(120, 100%, 40%);">+ pars.imsi, remote_msc_name, local_msc_name,</span><br><span style="color: hsl(120, 100%, 40%);">+ valueof(t_GSUP_AN_APDU(OSMO_GSUP_AN_PROTO_48006,</span><br><span style="color: hsl(120, 100%, 40%);">+ enc_PDU_BSSAP(valueof(ts_BSSAP_DTAP(l3_enc)))</span><br><span style="color: hsl(120, 100%, 40%);">+ ))</span><br><span style="color: hsl(120, 100%, 40%);">+ ));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Expect GSUP message containing the SS payload */</span><br><span style="color: hsl(120, 100%, 40%);">+ gsup_req_complete := f_expect_gsup_msg(gsup_req);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Compose the response from HLR using received session ID */</span><br><span style="color: hsl(120, 100%, 40%);">+ var template GSUP_PDU gsup_rsp := ts_GSUP_PROC_SS_REQ(</span><br><span style="color: hsl(120, 100%, 40%);">+ imsi := g_pars.imsi,</span><br><span style="color: hsl(120, 100%, 40%);">+ sid := gsup_req_complete.ies[1].val.session_id,</span><br><span style="color: hsl(120, 100%, 40%);">+ state := OSMO_GSUP_SESSION_STATE_END,</span><br><span style="color: hsl(120, 100%, 40%);">+ ss := valueof(facility_rsp)</span><br><span style="color: hsl(120, 100%, 40%);">+ );</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Finally, HLR terminates the session */</span><br><span style="color: hsl(120, 100%, 40%);">+ GSUP.send(gsup_rsp);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* The USSD response goes out to remote MSC, on GSUP E instead of BSSAP */</span><br><span style="color: hsl(120, 100%, 40%);">+ var GSUP_PDU gsup_ussd_rsp;</span><br><span style="color: hsl(120, 100%, 40%);">+ GSUP.receive(tr_GSUP_E_AN_APDU(OSMO_GSUP_MSGT_E_FORWARD_ACCESS_SIGNALLING_REQUEST,</span><br><span style="color: hsl(120, 100%, 40%);">+ pars.imsi, destination_name := remote_msc_name)) -> value gsup_ussd_rsp;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ var GSUP_IeValue an_apdu;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (not f_gsup_find_ie(gsup_ussd_rsp, OSMO_GSUP_AN_APDU_IE, an_apdu)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ setverdict(fail, "No AN-APDU in received GSUP message. Expected USSD response in DTAP, got", gsup_ussd_rsp);</span><br><span style="color: hsl(120, 100%, 40%);">+ mtc.stop;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ var PDU_BSSAP bssap_dtap_mt := dec_PDU_BSSAP(an_apdu.an_apdu.pdu);</span><br><span style="color: hsl(120, 100%, 40%);">+ var PDU_ML3_NW_MS dtap_mt := dec_PDU_ML3_NW_MS(bssap_dtap_mt.pdu.dtap);</span><br><span style="color: hsl(120, 100%, 40%);">+ log("Expecting", ussd_rsp);</span><br><span style="color: hsl(120, 100%, 40%);">+ log("Got", dtap_mt);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (not match(dtap_mt, ussd_rsp)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ setverdict(fail, "Unexpected GSUP message. Expected USSD response in DTAP, got", gsup_ussd_rsp);</span><br><span style="color: hsl(120, 100%, 40%);">+ mtc.stop;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ /**********************************/</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* inter-MSC handover back to the first MSC */</span><br><span style="color: hsl(120, 100%, 40%);">+ f_create_bssmap_exp_handoverRequest(193);</span><br><span style="color: hsl(120, 100%, 40%);">+ cil := { cIl_CGI := { ts_BSSMAP_CI_CGI('262'H, '42'H, 23, 42) } };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* old BSS sends Handover Required, via inter-MSC E link: like</span><br><span style="color: hsl(120, 100%, 40%);">+ * BSSAP.send(ts_BSSMAP_HandoverRequired(cause, cil));</span><br><span style="color: hsl(120, 100%, 40%);">+ * but via GSUP */</span><br><span style="color: hsl(120, 100%, 40%);">+ GSUP.send(ts_GSUP_E_AN_APDU(OSMO_GSUP_MSGT_E_PREPARE_SUBSEQUENT_HANDOVER_REQUEST,</span><br><span style="color: hsl(120, 100%, 40%);">+ pars.imsi, remote_msc_name, local_msc_name,</span><br><span style="color: hsl(120, 100%, 40%);">+ valueof(t_GSUP_AN_APDU(OSMO_GSUP_AN_PROTO_48006,</span><br><span style="color: hsl(120, 100%, 40%);">+ enc_PDU_BSSAP(valueof(ts_BSSMAP_HandoverRequired(cause, cil)))</span><br><span style="color: hsl(120, 100%, 40%);">+ ))</span><br><span style="color: hsl(120, 100%, 40%);">+ ));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* MSC asks local BSS to prepare Handover to it */</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSAP.receive(tr_BSSMAP_HandoverRequest);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Make sure the new BSSAP conn continues with the correct N_SD sequence numbers */</span><br><span style="color: hsl(120, 100%, 40%);">+ f_bssmap_continue_after_n_sd(last_n_sd);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* new BSS composes a RR Handover Command */</span><br><span style="color: hsl(120, 100%, 40%);">+ rr_ho_cmd := valueof(ts_RR_HandoverCommand);</span><br><span style="color: hsl(120, 100%, 40%);">+ rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);</span><br><span style="color: hsl(120, 100%, 40%);">+ var BSSMAP_IE_AoIP_TransportLayerAddress tla := valueof(ts_BSSMAP_IE_AoIP_TLA4('01020304'O, 2342));</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSAP.send(ts_BSSMAP_HandoverRequestAcknowledge(rr_ho_cmd_enc, lengthof(rr_ho_cmd_enc),</span><br><span style="color: hsl(120, 100%, 40%);">+ tla, ts_BSSMAP_IE_SpeechCodec({ts_CodecFR})));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* HandoverCommand goes out via remote MSC-I */</span><br><span style="color: hsl(120, 100%, 40%);">+ var GSUP_PDU prep_subsq_ho_res;</span><br><span style="color: hsl(120, 100%, 40%);">+ GSUP.receive(tr_GSUP_E_AN_APDU(OSMO_GSUP_MSGT_E_PREPARE_SUBSEQUENT_HANDOVER_RESULT,</span><br><span style="color: hsl(120, 100%, 40%);">+ pars.imsi, destination_name := remote_msc_name)) -> value prep_subsq_ho_res;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* MS shows up at the local BSS */</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSAP.send(ts_BSSMAP_HandoverDetect);</span><br><span style="color: hsl(120, 100%, 40%);">+ f_sleep(0.1);</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSAP.send(ts_BSSMAP_HandoverComplete);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Handover Succeeded message */</span><br><span style="color: hsl(120, 100%, 40%);">+ GSUP.receive(tr_GSUP_E_AN_APDU(OSMO_GSUP_MSGT_E_FORWARD_ACCESS_SIGNALLING_REQUEST,</span><br><span style="color: hsl(120, 100%, 40%);">+ pars.imsi, destination_name := remote_msc_name));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* MS has handovered to here, Clear Command goes out via remote MSC-I -- in form of a GSUP Close. */</span><br><span style="color: hsl(120, 100%, 40%);">+ GSUP.receive(tr_GSUP_E_NO_PDU(OSMO_GSUP_MSGT_E_CLOSE,</span><br><span style="color: hsl(120, 100%, 40%);">+ pars.imsi, destination_name := remote_msc_name));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Handover ends successfully. Call goes on for a little longer and then we hang up. */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ f_sleep(1.0);</span><br><span style="color: hsl(120, 100%, 40%);">+ deactivate(ack_mdcx);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* FIXME: the inter-MSC call has put a number of MNCC messages in the queue, which above code should expect and</span><br><span style="color: hsl(120, 100%, 40%);">+ * clear out. The f_call_hangup() expects an MNCC_REL_IND, so, for the time being, just clear the MNCC messages</span><br><span style="color: hsl(120, 100%, 40%);">+ * before starting the call hangup. Instead of this, the individual messages should be tested for above. */</span><br><span style="color: hsl(120, 100%, 40%);">+ MNCC.clear;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ var default ccrel := activate(as_optional_cc_rel(cpars, true));</span><br><span style="color: hsl(120, 100%, 40%);">+ f_call_hangup(cpars, true);</span><br><span style="color: hsl(120, 100%, 40%);">+ f_sleep(1.0);</span><br><span style="color: hsl(120, 100%, 40%);">+ deactivate(ccrel);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ setverdict(pass);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+testcase TC_ho_inter_msc_out() runs on MTC_CT {</span><br><span style="color: hsl(120, 100%, 40%);">+ var BSC_ConnHdlr vc_conn;</span><br><span style="color: hsl(120, 100%, 40%);">+ f_init(1);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ var BSC_ConnHdlrPars pars := f_init_pars(54);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ vc_conn := f_start_handler_with_pars(refers(f_tc_ho_inter_msc_out), pars, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+ vc_conn.done;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> control {</span><br><span> execute( TC_cr_before_reset() );</span><br><span> execute( TC_lu_imsi_noauth_tmsi() );</span><br><span>@@ -4870,6 +5303,11 @@</span><br><span> execute( TC_sgsap_lu_and_mt_call() );</span><br><span> execute( TC_sgsap_vlr_failure() );</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ execute( TC_ho_inter_bsc_unknown_cell() );</span><br><span style="color: hsl(120, 100%, 40%);">+ execute( TC_ho_inter_bsc() );</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ execute( TC_ho_inter_msc_out() );</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* Run this last: at the time of writing this test crashes the MSC */</span><br><span> execute( TC_lu_imsi_auth_tmsi_encr_3_1_log_msc_debug() );</span><br><span> execute( TC_gsup_mt_multi_part_sms() );</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/13617">change 13617</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/13617"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: osmo-ttcn3-hacks </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: merged </div>
<div style="display:none"> Gerrit-Change-Id: I7d76c982ad4e198534fa488609c41e8892b268ab </div>
<div style="display:none"> Gerrit-Change-Number: 13617 </div>
<div style="display:none"> Gerrit-PatchSet: 6 </div>
<div style="display:none"> Gerrit-Owner: Neels Hofmeyr <nhofmeyr@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: Harald Welte <laforge@gnumonks.org> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins Builder (1000002) </div>
<div style="display:none"> Gerrit-Reviewer: Neels Hofmeyr <nhofmeyr@sysmocom.de> </div>