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