dexter has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-ttcn3-hacks/+/33898 )
Change subject: S1AP_Emulation: improve accessibility of unit-data ......................................................................
S1AP_Emulation: improve accessibility of unit-data
When S1AP unit-data is passed around, there is always the problem that it is routed to the MTC_CT. The reason for this is that S1AP_Emulation cannot determine a specific receiver component because unit-data does not contain any addressing fields that would identifiy a specific eNB or UE.
Unfortunately it can be a huge problem when developing test fixtures that use unit-data from inside a ConnHdlr component. It is no problem to send unit-data using S1AP.send(), but it is impossible to receive unit-data through the same path.
The solution that is proposed in this patch uses a mechanism that sends unit-data to all ConnHdlr components that it knows from previous activities.
Related: OS#5760 Change-Id: I041b45b247e365b0d4ee8645c07dc5f26007af82 --- M library/S1AP_Emulation.ttcn 1 file changed, 70 insertions(+), 2 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-ttcn3-hacks refs/changes/98/33898/1
diff --git a/library/S1AP_Emulation.ttcn b/library/S1AP_Emulation.ttcn index a907483..a1cc443 100644 --- a/library/S1AP_Emulation.ttcn +++ b/library/S1AP_Emulation.ttcn @@ -96,6 +96,12 @@ NAS_UE_State nus };
+/* represents a single S1AP UnitData Association. This association basically represents a table with components that + * are subscribed to receive UnitData traffic. */ +type record AssociationDataUnitdata { + S1AP_ConnHdlr comp_ref /* component handling this UE connection */ +}; + type component S1AP_Emulation_CT { /* Port facing to the UDP SUT */ port S1AP_CODEC_PT S1AP; @@ -105,7 +111,8 @@ port S1AP_Conn_PT S1AP_CLIENT; /* currently tracked connections */ var AssociationData S1apAssociationTable[16]; - /* pending expected CRCX */ + var AssociationDataUnitdata S1apAssociationUnitdataTable[16]; + /* pending expected S1AP Association (UE oriented) */ var ExpectData S1apExpectTable[8]; /* procedure based port to register for incoming connections */ port S1APEM_PROC_PT S1AP_PROC; @@ -249,6 +256,29 @@ return -1; }
+private function f_s1ap_id_table_unitdata_add(S1AP_ConnHdlr comp_ref) +runs on S1AP_Emulation_CT return integer { + var integer i; + + /* Make sure a component reference is not added twice */ + for (i := 0; i < sizeof(S1apAssociationUnitdataTable); i := i+1) { + if (S1apAssociationUnitdataTable[i].comp_ref == comp_ref) { + return i; + } + } + + for (i := 0; i < sizeof(S1apAssociationUnitdataTable); i := i+1) { + if (S1apAssociationUnitdataTable[i].comp_ref == null) { + S1apAssociationUnitdataTable[i].comp_ref := comp_ref; + return i; + } + } + + testcase.stop("S1AP Unitdata Association Table full!"); + return -1; +} + + private function f_s1ap_id_table_del(S1AP_ConnHdlr comp_ref, ENB_UE_S1AP_ID enb_id) runs on S1AP_Emulation_CT { var integer i; @@ -274,6 +304,11 @@ S1apAssociationTable[i].cgi := omit; S1apAssociationTable[i].tai := omit; S1apAssociationTable[i].nus := valueof(t_NAS_UE_State(g_pars.role)); + S1apAssociationTable[i].comp_ref := null; + } + + for (var integer i := 0; i < sizeof(S1apAssociationUnitdataTable); i := i+1) { + S1apAssociationUnitdataTable[i].comp_ref := null; } }
@@ -434,6 +469,7 @@ [] S1AP_CLIENT.receive(S1AP_PDU:?) -> value msg sender vc_conn { /* Pass message through */ /* FIXME: validate S1AP_IDs ? */ + f_s1ap_id_table_unitdata_add(vc_conn); S1AP.send(t_S1AP_Send(g_s1ap_conn_id, msg)); }
@@ -446,7 +482,14 @@ /* S1AP received from peer (MME) */ [] S1AP.receive(tr_S1AP_RecvFrom_R(?)) -> value mrf { if (match(mrf.msg, tr_S1AP_nonUErelated)) { - /* non-UE-related S1AP message */ + /* non-UE-related S1AP message, send it to all subscribed components and to + * unitdata_cb. */ + for (var integer i := 0; i < sizeof(S1apAssociationUnitdataTable); i := i+1) { + if (S1apAssociationUnitdataTable[i].comp_ref != null) { + vc_conn := S1apAssociationUnitdataTable[i].comp_ref; + S1AP_CLIENT.send(mrf.msg) to vc_conn; + } + } var template S1AP_PDU resp := ops.unitdata_cb.apply(mrf.msg); if (isvalue(resp)) { S1AP.send(t_S1AP_Send(g_s1ap_conn_id, valueof(resp)));