laforge has submitted this change. ( 
https://gerrit.osmocom.org/c/osmo-ttcn3-hacks/+/42241?usp=email )

Change subject: 5gc: Introduce test TC_handover_inter_ngran_xn
......................................................................

5gc: Introduce test TC_handover_inter_ngran_xn

Change-Id: I4de3f0a02ddbccc85988754a4cd83fe67b1453dc
---
M 5gc/C5G_Tests.ttcn
M 5gc/ConnHdlr.ttcn
M 5gc/expected-results.xml
M library/NGAP_Emulation.ttcn
M library/NGAP_Functions.ttcn
M library/ngap/NGAP_EncDec.cc
M library/ngap/NGAP_Templates.ttcn
M library/ngap/NGAP_Types.ttcn
8 files changed, 228 insertions(+), 16 deletions(-)

Approvals:
  Jenkins Builder: Verified
  laforge: Looks good to me, approved
  osmith: Looks good to me, but someone else must approve




diff --git a/5gc/C5G_Tests.ttcn b/5gc/C5G_Tests.ttcn
index 3844f95..028178d 100644
--- a/5gc/C5G_Tests.ttcn
+++ b/5gc/C5G_Tests.ttcn
@@ -613,6 +613,69 @@
        vc_conn.done;
 }

+/* 3GPP TS 23.502 4.9.1.2.2 Xn based inter NG-RAN handover without User Plane 
function re-allocation */
+private function f_TC_handover_inter_ngran_xn_source() runs on ConnHdlr {
+       f_register();
+       f_pdu_sess_establish();
+       f_sleep(1.0);
+       f_ping4(g_pars.ue_pars.sess_pars.run_prog_pars.ping_hostname);
+
+       var NG_NAS_UE_State nus := f_ngap_obtain_nus(g_pars.ue_pars.ran_id);
+
+       /* TODO: conditional, transmit "1a. RAN Usage data report" */
+       COORD.send(Handover_Xn_Pars:{source_amf_id := g_pars.ue_pars.amf_id,
+                                    guti := g_pars.ue_pars.guti,
+                                    pti := g_pars.ue_pars.pti,
+                                    sess_pars := g_pars.ue_pars.sess_pars,
+                                    kset_id := g_pars.kset_id,
+                                    nus := nus });
+}
+private function f_TC_handover_inter_ngran_xn_target() runs on ConnHdlr {
+       var Handover_Xn_Pars ho_xn_pars;
+
+       COORD.receive(Handover_Xn_Pars:?) -> value ho_xn_pars;
+       log("HANDOVER STARTED!");
+       g_pars.ue_pars.guti := ho_xn_pars.guti;
+       g_pars.ue_pars.pti := ho_xn_pars.pti;
+       g_pars.ue_pars.sess_pars.id := ho_xn_pars.sess_pars.id;
+       g_pars.ue_pars.sess_pars.cn_gtpu_ip := ho_xn_pars.sess_pars.cn_gtpu_ip;
+       g_pars.ue_pars.sess_pars.cn_gtpu_teid := 
ho_xn_pars.sess_pars.cn_gtpu_teid;
+       g_pars.ue_pars.sess_pars.qos_rules := ho_xn_pars.sess_pars.qos_rules;
+       g_pars.ue_pars.sess_pars.ue_ip := ho_xn_pars.sess_pars.ue_ip;
+       g_pars.kset_id := ho_xn_pars.kset_id;
+
+       f_n2_path_switch(ho_xn_pars.source_amf_id);
+       f_ngap_set_nus(g_pars.ue_pars.ran_id, ho_xn_pars.nus)
+       f_sleep(1.0);
+
+       f_pdu_sess_create_tun();
+       f_ping4(g_pars.ue_pars.sess_pars.run_prog_pars.ping_hostname);
+
+       f_pdu_sess_release();
+       f_deregister();
+}
+testcase TC_handover_inter_ngran_xn() runs on MTC_CT {
+       var ConnHdlr vc_conn[2];
+       var integer i;
+
+       f_init();
+       f_ngap_setup(0);
+       f_ngap_setup(1);
+
+       var ConnHdlrPars pars := f_init_pars(ue_idx := 0, c5g_idx := 0);
+       vc_conn[0] := f_start_handler_create(ngap_idx := 0);
+       vc_conn[1] := f_start_handler_create(ngap_idx := 1);
+       connect(vc_conn[0]:COORD, vc_conn[1]:COORD);
+
+       f_start_handler_run(vc_conn[0], 
refers(f_TC_handover_inter_ngran_xn_source), pars);
+       pars.c5g_idx := 1;
+       pars.ue_pars.sess_pars.ran_gtpu_teid := 
int2oct(oct2int(pars.ue_pars.sess_pars.ran_gtpu_teid) + 1, 4);
+       f_start_handler_run(vc_conn[1], 
refers(f_TC_handover_inter_ngran_xn_target), pars);
+
+       vc_conn[0].done;
+       vc_conn[1].done;
+}
+
 control {
        execute( TC_ng_setup() );
        execute( TC_ng_setup_unknown_global_gnb_id_plmn() );
@@ -638,6 +701,8 @@
        execute( TC_connection_inactive() );
        execute( TC_connection_suspend() );

+       execute( TC_handover_inter_ngran_xn() );
+
 }

 /* TODO:
diff --git a/5gc/ConnHdlr.ttcn b/5gc/ConnHdlr.ttcn
index ce7d38f..da0d3d9 100644
--- a/5gc/ConnHdlr.ttcn
+++ b/5gc/ConnHdlr.ttcn
@@ -49,8 +49,8 @@
 import from GTPv1U_Emulation all;
 import from UECUPS_Types all;

-/* (maximum) number of emulated eNBs */
-const integer NUM_NGRAN := 1;
+/* (maximum) number of emulated gNBs */
+const integer NUM_NGRAN := 2;

 /* parameters of emulated gNB / ng-eNB */
 type record NGRANParams {
@@ -112,7 +112,25 @@
        boolean exp_CoreNetworkAssistanceInformationForInactive
 }

+/* Kind of 3GPP TS 38.423 9.1.1.1 HANDOVER REQUEST plus
+ * 3GPP TS 38.423 8.2.4 RETRIEVE UE CONTEXT RESPONSE (see 9.1.1.9 and 9.2.1.13 
too). */
+type record Handover_Xn_Pars {
+       AMF_UE_NGAP_ID source_amf_id,
+       octetstring guti,
+       ProcedureTransactionIdentifier pti,
+       PDUSessionParams sess_pars,
+       NAS_KeySetIdentifier kset_id,
+       NG_NAS_UE_State nus /* 3GPP TS 38.423 9.2.1.13 UE Context Information */
+};
+
+type port ConnHdlr_Coord_PT message
+{
+       inout charstring, Handover_Xn_Pars;
+} with { extension "internal" };
+
 type component ConnHdlr extends NGAP_ConnHdlr, GTP1U_ConnHdlr {
+       port ConnHdlr_Coord_PT COORD;
+
        var ConnHdlrPars g_pars;
        var UeDerivedKeys g_keys;

@@ -217,6 +235,16 @@
        return valueof(st);
 }

+function f_UESecurityCapabilities() runs on ConnHdlr return 
UESecurityCapabilities
+{
+       var template (value) UESecurityCapabilities cap;
+       cap := m_uESecurityCapabilities(p_nRencryptionAlgorithms := 
'0000000000000000'B,
+                                       p_nRintegrityProtectionAlgorithms := 
'0000000000000000'B,
+                                       p_eUTRAencryptionAlgorithms := 
'0000000000000000'B,
+                                       p_eUTRAintegrityProtectionAlgorithms := 
'0000000000000000'B);
+       return valueof(cap);
+}
+
 /* 3GPP TS 24.501 5.4.1.3.2, 3GPP TS 33.501 6.1.3.2 */
 private altstep as_ngap_handle_auth(boolean allow_resync := true) runs on 
ConnHdlr {
        var NG_NAS_DL_Message_Type rx_nas;
@@ -881,6 +909,43 @@
                                        g_pars.ue_pars.ran_id)));
 }

+/* 3GPP TS 38.413 8.4.4 Path Switch Request
+ * 3GPP TS 38.413 9.2.3.8 PATH SWITCH REQUEST
+ * 3GPP TS 23.502 4.9.1.2.2 Xn based inter NG-RAN handover without User Plane 
function re-allocation */
+function f_n2_path_switch(AMF_UE_NGAP_ID source_amf_id) runs on ConnHdlr
+{
+       var template (value) UPTransportLayerInformation utla;
+       var template (value) PathSwitchRequestTransfer transfer;
+       var octetstring transfer_enc;
+       var template (value) PDUSessionResourceToBeSwitchedDLItem it;
+       var template (value) NGAP_PDU tx_pdu;
+       var NGAP_PDU rx_pdu;
+
+       utla := m_uPTransportLayerInformation_gTPTunnel(
+                       m_gTPTunnel(p_tla := 
oct2bit(f_inet_addr(g_pars.ue_pars.sess_pars.ran_gtpu_ip)),
+                                   p_gtp_teid := 
g_pars.ue_pars.sess_pars.ran_gtpu_teid));
+       transfer := m_pathSwitchRequestTransfer(p_dL_NGU_UP_TNLInformation := 
utla,
+                                               p_qosFlowAcceptedList := { 
m_qosFlowAcceptedItem(1) },
+                                               p_dL_NGU_TNLInformationReused 
:= omit,
+                                               p_userPlaneSecurityInformation 
:= omit);
+       transfer_enc := enc_NGAP_PathSwitchRequestTransfer(valueof(transfer));
+       it := 
m_pDUSessionResourceToBeSwitchedDLItem(g_pars.ue_pars.sess_pars.id,
+                                                    transfer_enc);
+
+       tx_pdu := m_ngap_initMsg(m_n2_PathSwitchRequest(
+                                       g_pars.ue_pars.ran_id,
+                                       source_amf_id,
+                                       f_ULI(),
+                                       f_UESecurityCapabilities(),
+                                       { it }));
+       NGAP.send(tx_pdu);
+       NGAP.receive(mw_ngap_succMsg(mw_n2_PathSwitchRequestAcknowledge(?, 
g_pars.ue_pars.ran_id))) -> value rx_pdu;
+
+       /* Update amf_id: */
+       var PathSwitchRequestAcknowledge path_switch_ack := 
rx_pdu.successfulOutcome.value_.PathSwitchRequestAcknowledge;
+       g_pars.ue_pars.amf_id := 
path_switch_ack.protocolIEs[0].value_.aMF_UE_NGAP_ID;
+}
+
 /* Handle a PDUSessionResourceSetupRequestTransfer contained inside NGAP 
InitialContextSetupRequest and return a Result for InitialContextSetupResponse 
*/
 private function 
f_pdu_handle_session_resource_released_item(PDUSessionResourceToReleaseItemRelCmd
 cmd) runs on ConnHdlr return PDUSessionResourceReleasedItemRelRes
 {
diff --git a/5gc/expected-results.xml b/5gc/expected-results.xml
index 22a18be..2333f8d 100644
--- a/5gc/expected-results.xml
+++ b/5gc/expected-results.xml
@@ -23,4 +23,5 @@
       C5G_Tests.ttcn:MASKED TC_connection_suspend testcase
     </failure>
   </testcase>
+  <testcase classname='C5G_Tests' name='TC_handover_inter_ngran_xn' 
time='MASKED'/>
 </testsuite>
diff --git a/library/NGAP_Emulation.ttcn b/library/NGAP_Emulation.ttcn
index 22eb605..d050d2f 100644
--- a/library/NGAP_Emulation.ttcn
+++ b/library/NGAP_Emulation.ttcn
@@ -117,12 +117,16 @@
 signature NGAPEM_register(in AMF_UE_NGAP_ID amf_id, in RAN_UE_NGAP_ID ran_id, 
in NGAP_ConnHdlr hdlr);
 signature NGAPEM_register_proc(in integer procedureCode, in NGAP_ConnHdlr 
hdlr);
 signature NGAPEM_obtain_amf_id() return AMF_UE_NGAP_ID;
+signature NGAPEM_obtain_nus(in RAN_UE_NGAP_ID ran_id) return NG_NAS_UE_State;
+signature NGAPEM_set_nus(in RAN_UE_NGAP_ID ran_id, in NG_NAS_UE_State nus);
 //signature NGAPEM_derive_nas_token(in octetstring kasme, in NGAP_ConnHdlr 
hdlr, out OCT32 nas_token);

 type port NGAPEM_PROC_PT procedure {
        inout NGAPEM_register;
        inout NGAPEM_register_proc;
        inout NGAPEM_obtain_amf_id;
+       inout NGAPEM_obtain_nus;
+       inout NGAPEM_set_nus;
        //inout NGAPEM_derive_nas_token;
 } with { extension "internal" };

@@ -288,13 +292,18 @@
        return -1; /* make ttcn3 compiler happy */
 }

-private function f_assoc_id_by_comp(NGAP_ConnHdlr client)
+private function f_assoc_id_by_comp(NGAP_ConnHdlr client, template (omit) 
RAN_UE_NGAP_ID ran_id := omit)
 runs on NGAP_Emulation_CT return integer {
        var integer i;
        for (i := 0; i < sizeof(NGapAssociationTable); i := i+1) {
-               if (NGapAssociationTable[i].comp_ref == client) {
-                       return i;
+               if (NGapAssociationTable[i].comp_ref != client) {
+                       continue;
                }
+               if (not istemplatekind(ran_id, "omit") and
+                   not match(NGapAssociationTable[i].ran_ue_ngap_id, ran_id)) {
+                       continue;
+               }
+               return i;
        }
        setverdict(fail, "NGAP Association Table not found by component ", 
client);
        mtc.stop;
@@ -481,6 +490,7 @@
                var charstring vlr_name, amf_name;
                var integer ai;
                var octetstring kasme;
+               var NG_NAS_UE_State nus;

                alt {
                /* Configuration primitive from client */
@@ -518,6 +528,15 @@
                        /* Pass message through */
                        NGAP.send(t_NGAP_Send(g_ngap_conn_id, msg));
                        }
+               /* NGAP from client: PathSwitch */
+               [] 
NGAP_CLIENT.receive(mw_ngap_initMsg(mw_n2_PathSwitchRequest)) -> value msg 
sender vc_conn {
+                       /* create a table entry about this connection */
+                       ai := f_ngap_id_table_add(vc_conn, omit, 
valueof(f_NGAP_get_RAN_UE_NGAP_ID(msg)));
+                       /* Store ULI so we can use it for generating 
UlNasTransport from NAS */
+                       NGapAssociationTable[ai].uli := 
msg.initiatingMessage.value_.PathSwitchRequest.protocolIEs[2].value_.userLocationInformation;
+                       /* Pass message through */
+                       NGAP.send(t_NGAP_Send(g_ngap_conn_id, msg));
+                       }
                /* NAS from client: Wrap in NGAP Uplink NAS Transport */
                [] NGAP_CLIENT.receive(NG_NAS_UL_Message_Type:?) -> value 
ul_nas_msg sender vc_conn {
                        var integer assoc_id := f_assoc_id_by_comp(vc_conn);
@@ -612,6 +631,15 @@
                        amf_id := NGapAssociationTable[i].amf_ue_ngap_id;
                        NGAP_PROC.reply(NGAPEM_obtain_amf_id:{} value amf_id) 
to vc_conn;
                        }
+               [] NGAP_PROC.getcall(NGAPEM_obtain_nus:{?}) -> param(ran_id) 
sender vc_conn {
+                       var integer i := f_assoc_id_by_comp(vc_conn, ran_id);
+                       NGAP_PROC.reply(NGAPEM_obtain_nus:{ran_id} value 
NGapAssociationTable[i].nus) to vc_conn;
+                       }
+               [] NGAP_PROC.getcall(NGAPEM_set_nus:{?, ?}) -> param(ran_id, 
nus) sender vc_conn {
+                       var integer i := f_assoc_id_by_comp(vc_conn, ran_id);
+                       NGapAssociationTable[i].nus := nus;
+                       NGAP_PROC.reply(NGAPEM_set_nus:{ran_id, nus}) to 
vc_conn;
+                       }
 //             [] NGAP_PROC.getcall(NGAPEM_derive_nas_token:{?, ?, -}) -> 
param(kasme, vc_conn) {
 //                     var integer assoc_id := f_assoc_id_by_comp(vc_conn);
 //                     var OCT32 nas_token := f_kdf_nas_token(kasme, 
NGapAssociationTable[assoc_id].nus.tx_count)
@@ -721,4 +749,19 @@
        }
 }

+function f_ngap_obtain_nus(RAN_UE_NGAP_ID ran_id) runs on NGAP_ConnHdlr return 
NG_NAS_UE_State {
+       var NG_NAS_UE_State nus;
+       NGAP_PROC.call(NGAPEM_obtain_nus:{ran_id}) {
+               [] NGAP_PROC.getreply(NGAPEM_obtain_nus:{ran_id}) -> value nus {
+                       return nus;
+               }
+       }
+}
+
+function f_ngap_set_nus(RAN_UE_NGAP_ID ran_id, NG_NAS_UE_State nus) runs on 
NGAP_ConnHdlr {
+       NGAP_PROC.call(NGAPEM_set_nus:{ran_id, nus}) {
+               [] NGAP_PROC.getreply(NGAPEM_set_nus:{ran_id, nus});
+       }
+}
+
 }
diff --git a/library/NGAP_Functions.ttcn b/library/NGAP_Functions.ttcn
index e1fcf6d..5d45c43 100644
--- a/library/NGAP_Functions.ttcn
+++ b/library/NGAP_Functions.ttcn
@@ -45,6 +45,9 @@
        } else if (ischosen(ngap.successfulOutcome)) {
                var SuccessfulOutcome so := ngap.successfulOutcome;
                select (so.procedureCode) {
+               case (id_PathSwitchRequest) {
+                       return 
so.value_.PathSwitchRequestAcknowledge.protocolIEs[0].value_.aMF_UE_NGAP_ID;
+                       }
                case (?) {
                        return omit;
                        /* TODO */
@@ -92,11 +95,17 @@
                case (id_PDUSessionResourceRelease) {
                        return 
im.value_.pDUSessionResourceReleaseCommand.protocolIEs[1].value_.rAN_UE_NGAP_ID;
                        }
+               case (id_PathSwitchRequest) {
+                       return 
im.value_.PathSwitchRequest.protocolIEs[0].value_.RAN_UE_NGAP_ID;
+                       }
                /* TODO */
                }
        } else if (ischosen(ngap.successfulOutcome)) {
                var SuccessfulOutcome so := ngap.successfulOutcome;
                select (so.procedureCode) {
+               case (id_PathSwitchRequest) {
+                       return 
so.value_.PathSwitchRequestAcknowledge.protocolIEs[1].value_.rAN_UE_NGAP_ID;
+                       }
                case (?) {
                        return omit;
                        /* TODO */
diff --git a/library/ngap/NGAP_EncDec.cc b/library/ngap/NGAP_EncDec.cc
index 8b825d5..9e3ccd2 100644
--- a/library/ngap/NGAP_EncDec.cc
+++ b/library/ngap/NGAP_EncDec.cc
@@ -129,4 +129,24 @@
        return ret;
 }

+OCTETSTRING enc__NGAP__PathSwitchRequestTransfer(const 
NGAP__IEs::PathSwitchRequestTransfer &p)
+{
+       TTCN_Buffer TTCN_buf;
+       TTCN_buf.clear();
+       p.encode(NGAP__IEs::PathSwitchRequestTransfer_descr_, TTCN_buf,
+                  TTCN_EncDec::CT_PER, PER_ALIGNED);
+       return OCTETSTRING(TTCN_buf.get_len(), TTCN_buf.get_data());
+}
+
+NGAP__IEs::PathSwitchRequestTransfer 
dec__NGAP__PathSwitchRequestTransfer(const OCTETSTRING &stream)
+{
+       NGAP__IEs::PathSwitchRequestTransfer ret;
+       TTCN_Buffer TTCN_buf;
+       TTCN_buf.clear();
+       TTCN_buf.put_os(stream);
+       ret.decode(NGAP__IEs::PathSwitchRequestTransfer_descr_, TTCN_buf,
+                  TTCN_EncDec::CT_PER, PER_ALIGNED);
+       return ret;
+}
+
 }
diff --git a/library/ngap/NGAP_Templates.ttcn b/library/ngap/NGAP_Templates.ttcn
index 0931687..6626cc1 100644
--- a/library/ngap/NGAP_Templates.ttcn
+++ b/library/ngap/NGAP_Templates.ttcn
@@ -4891,16 +4891,16 @@
                                               PathSwitchRequest := {
                                                                     
protocolIEs := {
                                                                                
     {
-                                                                               
         id := id_AMF_UE_NGAP_ID,
-                                                                               
         criticality := reject,
-                                                                               
         value_ := { AMF_UE_NGAP_ID := p_amfUeNgapID }
-                                                                               
     },
-                                                                               
     {
                                                                                
         id := id_RAN_UE_NGAP_ID,
                                                                                
         criticality := reject,
                                                                                
         value_ := { RAN_UE_NGAP_ID := p_ranUeNgapID }
                                                                                
     },
                                                                                
     {
+                                                                               
         id := id_SourceAMF_UE_NGAP_ID,
+                                                                               
         criticality := reject,
+                                                                               
         value_ := { AMF_UE_NGAP_ID := p_amfUeNgapID }
+                                                                               
     },
+                                                                               
     {
                                                                                
         id := id_UserLocationInformation,
                                                                                
         criticality := ignore,
                                                                                
         value_ := { UserLocationInformation := p_userLocationInformation }
@@ -4940,16 +4940,16 @@
                                               PathSwitchRequest := {
                                                                     
protocolIEs := {
                                                                                
     {
-                                                                               
         id := id_AMF_UE_NGAP_ID,
-                                                                               
         criticality := reject,
-                                                                               
         value_ := { AMF_UE_NGAP_ID := p_amfUeNgapID }
-                                                                               
     },
-                                                                               
     {
                                                                                
         id := id_RAN_UE_NGAP_ID,
                                                                                
         criticality := reject,
                                                                                
         value_ := { RAN_UE_NGAP_ID := p_ranUeNgapID }
                                                                                
     },
                                                                                
     {
+                                                                               
         id := id_SourceAMF_UE_NGAP_ID,
+                                                                               
         criticality := reject,
+                                                                               
         value_ := { AMF_UE_NGAP_ID := p_amfUeNgapID }
+                                                                               
     },
+                                                                               
     {
                                                                                
         id := id_UserLocationInformation,
                                                                                
         criticality := ignore,
                                                                                
         value_ := { UserLocationInformation := p_userLocationInformation }
@@ -5027,7 +5027,8 @@
                                                                                
                 template (present) AMF_UE_NGAP_ID p_amfUeNgapID := ?,
                                                                                
                 template (present) RAN_UE_NGAP_ID p_ranUeNgapID := ?,
                                                                                
                 template (present) SecurityContext p_securityContext := ?,
-                                                                               
                 template (present) PDUSessionResourceSwitchedList 
p_pDUSessionResourceSwitchedList := ?
+                                                                               
                 template (present) PDUSessionResourceSwitchedList 
p_pDUSessionResourceSwitchedList := ?,
+                                                                               
                 template (present) AllowedNSSAI p_allowedNSSAI := ?
                                                                                
                 ) := {
                             procedureCode := id_PathSwitchRequest,
                             criticality   := reject,
@@ -5053,6 +5054,11 @@
                                                                                
         id := id_PDUSessionResourceSwitchedList,
                                                                                
         criticality := ignore,
                                                                                
         value_ := { PDUSessionResourceSwitchedList := 
p_pDUSessionResourceSwitchedList }
+                                                                               
     },
+                                                                               
     {
+                                                                               
         id := id_AllowedNSSAI,
+                                                                               
         criticality := reject,
+                                                                               
         value_ := { AllowedNSSAI := p_allowedNSSAI }
                                                                                
     }
                                                                                
    }
                                                                     }
diff --git a/library/ngap/NGAP_Types.ttcn b/library/ngap/NGAP_Types.ttcn
index d9523b4..394cb24 100644
--- a/library/ngap/NGAP_Types.ttcn
+++ b/library/ngap/NGAP_Types.ttcn
@@ -20,4 +20,7 @@

        external function 
enc_NGAP_UEContextSuspendRequestTransfer(NGAP_IEs.UEContextSuspendRequestTransfer
 p) return octetstring;
        external function dec_NGAP_UEContextSuspendRequestTransfer(in 
octetstring pdu) return NGAP_IEs.UEContextSuspendRequestTransfer;
+
+       external function 
enc_NGAP_PathSwitchRequestTransfer(NGAP_IEs.PathSwitchRequestTransfer p) return 
octetstring;
+       external function dec_NGAP_PathSwitchRequestTransfer(in octetstring 
pdu) return NGAP_IEs.PathSwitchRequestTransfer;
 }

--
To view, visit https://gerrit.osmocom.org/c/osmo-ttcn3-hacks/+/42241?usp=email
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.osmocom.org/settings?usp=email

Gerrit-MessageType: merged
Gerrit-Project: osmo-ttcn3-hacks
Gerrit-Branch: master
Gerrit-Change-Id: I4de3f0a02ddbccc85988754a4cd83fe67b1453dc
Gerrit-Change-Number: 42241
Gerrit-PatchSet: 2
Gerrit-Owner: pespin <[email protected]>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: fixeria <[email protected]>
Gerrit-Reviewer: laforge <[email protected]>
Gerrit-Reviewer: osmith <[email protected]>

Reply via email to