Add hnbgw tests

Some tests for osmo-hnbgw with mgw support:
* hnb register
* ranap connect/disconnect
* rab assignment/release

Change-Id: I0a2fb795aec83337eda8d9972e6ff264ead61076
This commit is contained in:
Daniel Willmann 2022-01-05 09:12:34 +01:00 committed by daniel
parent c6ac6950c2
commit 19b8d909e5
8 changed files with 1696 additions and 0 deletions

18
hnbgw/HNBGW_Tests.cfg Normal file
View File

@ -0,0 +1,18 @@
[ORDERED_INCLUDE]
# Common configuration, shared between test suites
"../Common.cfg"
# testsuite specific configuration, not expected to change
"./HNBGW_Tests.default"
# Local configuration below
[LOGGING]
[TESTPORT_PARAMETERS]
[MODULE_PARAMETERS]
[MAIN_CONTROLLER]
[EXECUTE]
HNBGW_Tests.control

28
hnbgw/HNBGW_Tests.default Normal file
View File

@ -0,0 +1,28 @@
[LOGGING]
mtc.FileMask := LOG_ALL | TTCN_DEBUG | TTCN_MATCHING | DEBUG_ENCDEC;
[TESTPORT_PARAMETERS]
*.HNBGWVTY.CTRL_MODE := "client"
*.HNBGWVTY.CTRL_HOSTNAME := "127.0.0.1"
*.HNBGWVTY.CTRL_PORTNUM := "4261"
*.HNBGWVTY.CTRL_LOGIN_SKIPPED := "yes"
*.HNBGWVTY.CTRL_DETECT_SERVER_DISCONNECTED := "yes"
*.HNBGWVTY.CTRL_READMODE := "buffered"
*.HNBGWVTY.CTRL_CLIENT_CLEANUP_LINEFEED := "yes"
*.HNBGWVTY.CTRL_DETECT_CONNECTION_ESTABLISHMENT_RESULT := "yes"
*.HNBGWVTY.PROMPT1 := "OsmoHNBGW> "
*.STATSVTY.CTRL_MODE := "client"
*.STATSVTY.CTRL_HOSTNAME := "127.0.0.1"
*.STATSVTY.CTRL_PORTNUM := "4262"
*.STATSVTY.CTRL_LOGIN_SKIPPED := "yes"
*.STATSVTY.CTRL_DETECT_SERVER_DISCONNECTED := "yes"
*.STATSVTY.CTRL_READMODE := "buffered"
*.STATSVTY.CTRL_CLIENT_CLEANUP_LINEFEED := "yes"
*.STATSVTY.CTRL_DETECT_CONNECTION_ESTABLISHMENT_RESULT := "yes"
*.STATSVTY.PROMPT1 := "OsmoHNBGW> "
*.LLSK.socket_type := "SEQPACKET"
[MODULE_PARAMETERS]
Osmocom_VTY_Functions.mp_prompt_prefix := "OsmoHNBGW";
[EXECUTE]

1019
hnbgw/HNBGW_Tests.ttcn Normal file

File diff suppressed because it is too large Load Diff

104
hnbgw/gen_links.sh Executable file
View File

@ -0,0 +1,104 @@
#!/bin/bash
BASEDIR=../deps
. ../gen_links.sh.inc
#DIR=$BASEDIR/titan.TestPorts.UNIX_DOMAIN_SOCKETasp/src
#FILES="UD_PT.cc UD_PT.hh UD_PortType.ttcn UD_Types.ttcn"
#gen_links $DIR $FILES
DIR=$BASEDIR/titan.Libraries.TCCUsefulFunctions/src
FILES="TCCInterface_Functions.ttcn TCCConversion_Functions.ttcn TCCConversion.cc TCCInterface.cc TCCInterface_ip.h"
FILES+=" TCCEncoding_Functions.ttcn TCCEncoding.cc " # GSM 7-bit coding
gen_links $DIR $FILES
DIR=$BASEDIR/titan.TestPorts.Common_Components.Socket-API/src
FILES="Socket_API_Definitions.ttcn"
gen_links $DIR $FILES
DIR=$BASEDIR/titan.ProtocolModules.MobileL3_v13.4.0/src
FILES="MobileL3_CC_Types.ttcn MobileL3_CommonIE_Types.ttcn MobileL3_GMM_SM_Types.ttcn MobileL3_MM_Types.ttcn MobileL3_RRM_Types.ttcn MobileL3_SMS_Types.ttcn MobileL3_SS_Types.ttcn MobileL3_Types.ttcn"
gen_links $DIR $FILES
# Required by MGCP and IPA
DIR=$BASEDIR/titan.TestPorts.IPL4asp/src
FILES="IPL4asp_Functions.ttcn IPL4asp_PT.cc IPL4asp_PT.hh IPL4asp_PortType.ttcn IPL4asp_Types.ttcn IPL4asp_discovery.cc IPL4asp_protocol_L234.hh"
gen_links $DIR $FILES
# required by SCCP Emulation
DIR=$BASEDIR/titan.ProtocolEmulations.M3UA/src
FILES="M3UA_Emulation.ttcn"
gen_links $DIR $FILES
# required by SCCP Emulation
DIR=$BASEDIR/titan.TestPorts.MTP3asp/src
FILES="MTP3asp_PortType.ttcn MTP3asp_Types.ttcn"
gen_links $DIR $FILES
DIR=$BASEDIR/titan.ProtocolEmulations.SCCP/src
FILES="SCCP_Emulation.ttcn SCCP_Mapping.ttcnpp SCCP_Types.ttcn SCCPasp_Types.ttcn"
gen_links $DIR $FILES
DIR=$BASEDIR/titan.ProtocolModules.BSSMAP/src
FILES="BSSAP_Types.ttcn"
gen_links $DIR $FILES
# required by M3UA_Emulation
DIR=$BASEDIR/titan.ProtocolModules.M3UA/src
FILES="M3UA_Types.ttcn"
gen_links $DIR $FILES
# required by M3UA_Emulation
DIR=$BASEDIR/titan.TestPorts.SCTPasp/src
FILES="SCTPasp_PT.cc SCTPasp_PT.hh SCTPasp_PortType.ttcn SCTPasp_Types.ttcn"
gen_links $DIR $FILES
# required by SCCP Emulation
DIR=$BASEDIR/titan.ProtocolEmulations.M3UA/src
FILES="M3UA_Emulation.ttcn"
gen_links $DIR $FILES
DIR=$BASEDIR/titan.TestPorts.UNIX_DOMAIN_SOCKETasp/src
FILES="UD_PT.cc UD_PT.hh UD_PortType.ttcn UD_Types.ttcn"
gen_links $DIR $FILES
DIR=$BASEDIR/titan.ProtocolModules.SDP/src
FILES="SDP_EncDec.cc SDP_Types.ttcn SDP_parse_.tab.c SDP_parse_.tab.h SDP_parse_parser.h SDP_parser.l
SDP_parser.y lex.SDP_parse_.c"
gen_links $DIR $FILES
DIR=$BASEDIR/titan.ProtocolModules.RTP/src
FILES="RTP_EncDec.cc RTP_Types.ttcn"
gen_links $DIR $FILES
DIR=$BASEDIR/titan.TestPorts.TELNETasp/src
FILES="TELNETasp_PT.cc TELNETasp_PT.hh TELNETasp_PortType.ttcn"
gen_links $DIR $FILES
DIR=../library/hnbap
FILES="HNBAP_CommonDataTypes.asn HNBAP_Constants.asn HNBAP_Containers.asn HNBAP_IEs.asn HNBAP_PDU_Contents.asn HNBAP_PDU_Descriptions.asn "
FILES+="HNBAP_EncDec.cc HNBAP_Types.ttcn HNBAP_Templates.ttcn "
gen_links $DIR $FILES
DIR=../library/rua
FILES="RUA_CommonDataTypes.asn RUA_Constants.asn RUA_Containers.asn RUA_IEs.asn RUA_PDU_Contents.asn RUA_PDU_Descriptions.asn "
FILES+="RUA_EncDec.cc RUA_Types.ttcn RUA_Templates.ttcn "
gen_links $DIR $FILES
DIR=../library/ranap
FILES="RANAP_CommonDataTypes.asn RANAP_Constants.asn RANAP_Containers.asn RANAP_IEs.asn RANAP_PDU_Contents.asn RANAP_PDU_Descriptions.asn "
FILES+="RANAP_Types.ttcn RANAP_Templates.ttcn RANAP_CodecPort.ttcn RANAP_EncDec.cc "
gen_links $DIR $FILES
DIR=../library
FILES="Iuh_Types.ttcn Iuh_CodecPort.ttcn Iuh_CodecPort_CtrlFunctDef.cc Iuh_CodecPort_CtrlFunct.ttcn Iuh_Emulation.ttcn DNS_Helpers.ttcn "
FILES+="MGCP_Emulation.ttcn MGCP_Types.ttcn MGCP_Templates.ttcn MGCP_CodecPort.ttcn MGCP_CodecPort_CtrlFunct.ttcn MGCP_CodecPort_CtrlFunctDef.cc "
FILES+="RAN_Adapter.ttcnpp RAN_Emulation.ttcnpp BSSAP_CodecPort.ttcn SCCP_Templates.ttcn "
FILES+="Misc_Helpers.ttcn General_Types.ttcn Osmocom_Types.ttcn GSM_Types.ttcn Osmocom_VTY_Functions.ttcn Native_Functions.ttcn Native_FunctionDefs.cc IPA_Types.ttcn IPA_CodecPort.ttcn IPA_CodecPort_CtrlFunct.ttcn IPA_CodecPort_CtrlFunctDef.cc IPA_Emulation.ttcnpp Osmocom_CTRL_Types.ttcn Osmocom_CTRL_Functions.ttcn Osmocom_CTRL_Adapter.ttcn RTP_CodecPort.ttcn RTP_CodecPort_CtrlFunct.ttcn RTP_CodecPort_CtrlFunctDef.cc RTP_Emulation.ttcn IuUP_Types.ttcn IuUP_EncDec.cc IuUP_Emulation.ttcn "
FILES+="StatsD_Types.ttcn StatsD_CodecPort.ttcn StatsD_CodecPort_CtrlFunct.ttcn StatsD_CodecPort_CtrlFunctdef.cc StatsD_Checker.ttcn "
FILES+="RUA_Emulation.ttcn "
gen_links $DIR $FILES
ignore_pp_results

35
hnbgw/osmo-hnbgw.cfg Normal file
View File

@ -0,0 +1,35 @@
!
! OsmoHNBGW (1.1.0) configuration saved from vty
!!
!
log stderr
logging filter all 1
logging color 1
logging print category-hex 1
logging print category 1
logging print thread-id 0
logging print extended-timestamp 1
logging print file 1
logging level set-all debug
!
line vty
no login
!
cs7 instance 0
point-code 0.23.5
sccp-address msc
routing-indicator PC
point-code 0.23.4
sccp-address sgsn
routing-indicator PC
point-code 0.23.1
hnbgw
log-prefix hnb-id
iuh
local-ip 127.0.0.1
local-port 29169
hnbap-allow-tmsi 1
iucs
remote-addr msc
iups
remote-addr sgsn

52
hnbgw/osmo-stp.cfg Normal file
View File

@ -0,0 +1,52 @@
!
! OsmoSTP (0.8.1) configuration saved from vty
!!
!
log stderr
logging filter all 1
logging color 1
logging print category 1
logging timestamp 1
logging print extended-timestamp 1
logging level lglobal notice
logging level llapd notice
logging level linp notice
logging level lmux notice
logging level lmi notice
logging level lmib notice
logging level lsms notice
logging level lctrl notice
logging level lgtp notice
logging level lstats notice
logging level lgsup notice
logging level loap notice
logging level lss7 debug
logging level lsccp debug
logging level lsua debug
logging level lm3ua debug
logging level lmgcp notice
!
line vty
no login
!
cs7 instance 0
xua rkm routing-key-allocation dynamic-permitted
asp virt-msc0-0 23905 2905 m3ua
local-ip 127.0.0.1
remote-ip 127.0.0.1
as virt-msc0 m3ua
asp virt-msc0-0
routing-key 1 0.23.4
asp virt-sgsn0-0 23906 2905 m3ua
local-ip 127.0.0.1
remote-ip 127.0.0.1
as virt-sgsn0 m3ua
asp virt-sgsn0-0
routing-key 2 0.23.1
route-table system
update route 0.23.4 7.255.7 linkset virt-msc0
update route 0.23.1 7.255.7 linkset virt-sgsn0
listen m3ua 2905
accept-asp-connections dynamic-permitted

40
hnbgw/regen_makefile.sh Executable file
View File

@ -0,0 +1,40 @@
#!/bin/sh
NAME=HNBGW_Tests
FILES="
*.asn
*.c
*.ttcn
*.ttcnpp
IPA_CodecPort_CtrlFunctDef.cc
IPL4asp_PT.cc
IPL4asp_discovery.cc
IuUP_EncDec.cc
Iuh_CodecPort_CtrlFunctDef.cc
Native_FunctionDefs.cc
RTP_CodecPort_CtrlFunctDef.cc
RTP_EncDec.cc
SCTPasp_PT.cc
SDP_EncDec.cc
StatsD_CodecPort_CtrlFunctdef.cc
TCCConversion.cc
TCCEncoding.cc
TCCInterface.cc
TELNETasp_PT.cc
HNBAP_EncDec.cc
RUA_EncDec.cc
RANAP_EncDec.cc
MGCP_CodecPort_CtrlFunctDef.cc
UD_PT.cc
"
export CPPFLAGS_TTCN3="
-DIPA_EMULATION_CTRL
-DRAN_EMULATION_RANAP
-DUSE_MTP3_DISTRIBUTOR
"
../regen-makefile.sh -e $NAME $FILES
sed -i -e 's/^LINUX_LIBS = -lxml2 -lsctp/LINUX_LIBS = -lxml2 -lsctp -lfftranscode/' Makefile

400
library/RUA_Emulation.ttcn Normal file
View File

@ -0,0 +1,400 @@
module RUA_Emulation {
/* RUA_Emulation runs on top of Iuh_Emulation. It multiplexes/demultiplexes
* the individuao connections, so there can be separate TTCN-3 components
* handling each of the connections (one connection per UE).
*
* The RUA_Emulation.main() function processes RUA messages from the Iuh stack
* via the RUA_PT, and dispatches them to the per-connection components.
*
* Outbound RUA connections are initiated by sending a FIXME primitive to the
* RUA_Emulation component.
*
* For each new inbound connection, the RuaOps.create_cb() is called. It can create
* or resolve a TTCN-3 component, and returns a component reference to which that inbound
* connection is routed/dispatched.
*
* If a pre-existing component wants to register to handle future inbound connection,
* it can do so by registering an "expect" with the expected RANAP payload.
* (C) 2022 by Harald Welte <laforge@gnumonks.org>
* All rights reserved.
*
* Released under the terms of GNU General Public License, Version 2 or
* (at your option) any later version.
*/
import from General_Types all;
import from Osmocom_Types all;
import from Iuh_Emulation all;
import from RUA_Templates all;
//import from RUA_Constants all;
import from RUA_PDU_Descriptions all;
import from RUA_IEs all;
import from RANAP_PDU_Descriptions all;
//import from RANAP_Constants all;
import from RANAP_IEs all;
import from RANAP_Types all;
import from RANAP_Templates all;
modulepar {
integer mp_max_context_id := hex2int('FFFFFF'H);
}
/* General "base class" component definition, of which specific implementations
* derive themselves by means of the "extends" feature */
type component RUA_ConnHdlr {
port RUA_Conn_PT RUA;
}
/* port between individual per-connection components and this dispatcher */
type port RUA_Conn_PT message {
inout RANAP_PDU,
RUA_Conn_Req,
RUA_Disc_Req,
RUA_Disc_Ind;
} with { extension "internal" };
type record RUA_Conn_Req {
boolean ps_domain,
RANAP_PDU ranap
};
type record RUA_Disc_Req {
RANAP_PDU ranap,
RUA_IEs.Cause cause
};
type record RUA_Disc_Ind {
RUA_IEs.Cause cause
};
type bitstring ContextId length(24); // with { variant "FIELDLENGTH(24)" };
/* represents a single RANAP connection over RUA */
type record ConnectionData {
RUA_ConnHdlr comp_ref,
RUA_IEs.CN_DomainIndicator domain,
integer context_id
}
type component RUA_Emulation_CT {
/* port to the bottom side (Iuh) */
port RUA_PT RUA;
/* ports to the upper side (per-connection components) */
port RUA_Conn_PT CLIENT;
/* use 16 as this is also the number of SCCP connections that SCCP_Emulation can handle */
var ConnectionData ConnectionTable[16];
/* pending expected incoming connections */
//var ExpectData ExpectTable[8];
/* tables for mapping inbound unitdata (like paging) */
//var ImsiMapping ImsiTable[16];
/* procedure based port to register for incoming connections */
//port RUA_PROC_PT PROC;
var charstring g_rua_id;
var RuaOps g_rua_ops;
}
type function RanapCreateCallback(ContextId context_id, RUA_IEs.CN_DomainIndicator domain, charstring id)
runs on RUA_Emulation_CT return RUA_ConnHdlr;
type function RanapUnitdataCallback(RANAP_PDU ranap)
runs on RUA_Emulation_CT return template RANAP_PDU;
type record RuaOps {
RanapCreateCallback create_cb optional,
RanapUnitdataCallback unitdata_cb optional
//boolean deode_dtap
//boolean role_ms
};
private function f_context_id_known(ContextId context_id)
runs on RUA_Emulation_CT return boolean {
var integer i;
for (i := 0; i < sizeof(ConnectionTable); i := i+1) {
if (ConnectionTable[i].context_id == bit2int(context_id)){
return true;
}
}
return false;
}
private function f_comp_known(RUA_ConnHdlr client)
runs on RUA_Emulation_CT return boolean {
var integer i;
for (i := 0; i < sizeof(ConnectionTable); i := i+1) {
if (ConnectionTable[i].comp_ref == client) {
return true;
}
}
return false;
}
/* resolve connection ID by component reference */
private function f_context_id_by_comp(RUA_ConnHdlr client)
runs on RUA_Emulation_CT return ContextId {
for (var integer i := 0; i < sizeof(ConnectionTable); i := i+1) {
if (ConnectionTable[i].comp_ref == client) {
return int2bit(ConnectionTable[i].context_id, 24);
}
}
setverdict(fail, "RAN Connection table not found by component ", client);
mtc.stop;
}
/* resolve ConnectionTable index component reference */
private function f_idx_by_comp(RUA_ConnHdlr client)
runs on RUA_Emulation_CT return integer {
for (var integer i := 0; i < sizeof(ConnectionTable); i := i+1) {
if (ConnectionTable[i].comp_ref == client) {
return i;
}
}
setverdict(fail, "RAN Connection table not found by component ", client);
mtc.stop;
}
private function f_gen_context_id()
runs on RUA_Emulation_CT return ContextId {
var ContextId context_id;
do {
context_id := int2bit(float2int(rnd()*int2float(mp_max_context_id)), 24);
} while (f_context_id_known(context_id) == true);
return context_id;
}
private function f_conn_table_init()
runs on RUA_Emulation_CT {
for (var integer i := 0; i < sizeof(ConnectionTable); i := i+1) {
ConnectionTable[i].comp_ref := null;
ConnectionTable[i].context_id := -1;
}
/*
for (var integer i := 0; i < sizeof(ImsiTable); i := i+1) {
ImsiTable[i].comp_ref := null;
ImsiTable[i].imsi := omit;
ImsiTable[i].tmsi := 'FFFFFFFF'O;
}
*/
}
private function f_conn_table_add(RUA_ConnHdlr comp_ref, RUA_IEs.CN_DomainIndicator domain, ContextId context_id)
runs on RUA_Emulation_CT {
var integer int_context_id := bit2int(context_id);
for (var integer i := 0; i < sizeof(ConnectionTable); i := i+1) {
if (ConnectionTable[i].context_id == -1) {
ConnectionTable[i].comp_ref := comp_ref;
ConnectionTable[i].domain := domain;
ConnectionTable[i].context_id := int_context_id;
log("Added conn table entry ", i, comp_ref, int_context_id);
return;
}
}
testcase.stop("RUA Connection table full!");
}
private function f_conn_table_del(ContextId context_id)
runs on RUA_Emulation_CT {
var integer int_context_id := bit2int(context_id);
for (var integer i := 0; i < sizeof(ConnectionTable); i := i+1) {
if (ConnectionTable[i].context_id == int_context_id) {
log("Deleted conn table entry ", i,
ConnectionTable[i].comp_ref, int_context_id);
ConnectionTable[i].context_id := -1;
return
}
}
setverdict(fail, "RUA Connection table attempt to delete non-existant ", int_context_id);
mtc.stop;
}
/* resolve component reference by connection ID */
private function f_comp_by_context_id(ContextId context_id)
runs on RUA_Emulation_CT return RUA_ConnHdlr {
var integer int_context_id := bit2int(context_id);
for (var integer i := 0; i < sizeof(ConnectionTable); i := i+1) {
if (ConnectionTable[i].context_id == int_context_id) {
return ConnectionTable[i].comp_ref;
}
}
setverdict(fail, "RUA Connection table not found by RUA Context ID ", int_context_id);
mtc.stop;
}
private function CommonRanapUnitdataCallback(RANAP_PDU ranap)
runs on RUA_Emulation_CT return template RANAP_PDU {
/* TODO: paging */
return g_rua_ops.unitdata_cb.apply(ranap);
}
private function f_handle_userData_RANAP(RUA_ConnHdlr client, RANAP_PDU ranap)
runs on RUA_Emulation_CT {
/* TODO: L3 decoding, if requested */
CLIENT.send(ranap) to client;
}
private altstep as_reset_ack() runs on RUA_Emulation_CT {
var RUA_PDU rua_clt;
[] RUA.receive(tr_RUA_ConnectionlessTransfer(decmatch tr_RANAP_Reset)) -> value rua_clt {
var RANAP_PDU rx := dec_RANAP_PDU(rua_clt.initiatingMessage.value_.connectionlessTransfer.protocolIEs[0].value_.rANAP_Message);
var RANAP_IEs.CN_DomainIndicator dom;
dom := rx.initiatingMessage.value_.Reset.protocolIEs[1].value_.cN_DomainIndicator;
RUA.send(ts_RUA_ConnectionlessTransfer(enc_RANAP_PDU(valueof(ts_RANAP_ResetAck(dom)))));
}
}
private altstep as_main_rua() runs on RUA_Emulation_CT {
var RANAP_PDU ranap;
var RUA_PDU rua;
var octetstring ranap_enc;
var ContextId context_id;
var RUA_IEs.CN_DomainIndicator domain_ind;
var RUA_ConnHdlr vc_conn;
var RUA_Conn_Req creq;
var RUA_Disc_Req dreq;
var RUA_IEs.Cause cause;
/* RUA -> Client: UNIT-DATA (connectionless RUA) from CN */
[] RUA.receive(tr_RUA_ConnectionlessTransfer) -> value rua {
ranap := dec_RANAP_PDU(rua.initiatingMessage.value_.connectionlessTransfer.protocolIEs[0].value_.rANAP_Message);
var template RANAP_PDU resp;
resp := CommonRanapUnitdataCallback(ranap);
if (isvalue(resp)) {
RUA.send(ts_RUA_ConnectionlessTransfer(enc_RANAP_PDU(valueof(resp))));
}
}
/* RUA -> Client: new connection from CN */
[] RUA.receive(tr_RUA_Connect) -> value rua {
domain_ind := rua.initiatingMessage.value_.connect_.protocolIEs[0].value_.cN_DomainIndicator;
context_id := rua.initiatingMessage.value_.connect_.protocolIEs[1].value_.context_ID;
ranap_enc := rua.initiatingMessage.value_.connect_.protocolIEs[3].value_.rANAP_Message;
ranap := dec_RANAP_PDU(ranap_enc);
vc_conn := g_rua_ops.create_cb.apply(context_id, domain_ind, g_rua_id);
/* store mapping between client components and RUA contextId */
f_conn_table_add(vc_conn, domain_ind, context_id);
/* TODO: notify user about incoming connection? */
/* handle user payload */
f_handle_userData_RANAP(vc_conn, ranap);
}
/* RUA -> Client: connection-oriented data in existing connection */
[] RUA.receive(tr_RUA_DirectTransfer) -> value rua {
context_id := rua.initiatingMessage.value_.directTransfer.protocolIEs[1].value_.context_ID;
vc_conn := f_comp_by_context_id(context_id);
ranap_enc := rua.initiatingMessage.value_.directTransfer.protocolIEs[2].value_.rANAP_Message;
f_handle_userData_RANAP(vc_conn, dec_RANAP_PDU(ranap_enc));
}
/* RUA -> Client: disconnect of an existing connection */
[] RUA.receive(tr_RUA_Disconnect) -> value rua {
cause := rua.initiatingMessage.value_.disconnect_.protocolIEs[2].value_.cause;
context_id := rua.initiatingMessage.value_.disconnect_.protocolIEs[1].value_.context_ID;
vc_conn := f_comp_by_context_id(context_id);
/* send contained RANAP message to user */
ranap_enc := rua.initiatingMessage.value_.disconnect_.protocolIEs[3].value_.rANAP_Message;
f_handle_userData_RANAP(vc_conn, dec_RANAP_PDU(ranap_enc));
/* notify user of disconnect */
CLIENT.send(RUA_Disc_Ind:{cause});
f_conn_table_del(context_id);
}
/* RANAP from client through an existing RANAP connection */
[] CLIENT.receive(RANAP_PDU:?) -> value ranap sender vc_conn {
var integer idx := f_idx_by_comp(vc_conn);
context_id := int2bit(ConnectionTable[idx].context_id, 24);
domain_ind := ConnectionTable[idx].domain;
RUA.send(ts_RUA_DirectTransfer(domain_ind, context_id, enc_RANAP_PDU(ranap)));
}
/* Disconnect request from client */
[] CLIENT.receive(RUA_Disc_Req:?) -> value dreq sender vc_conn {
var octetstring enc_ranap := enc_RANAP_PDU(dreq.ranap);
var integer idx := f_idx_by_comp(vc_conn);
context_id := int2bit(ConnectionTable[idx].context_id, 24);
domain_ind := ConnectionTable[idx].domain;
RUA.send(ts_RUA_Disconnect(domain_ind, context_id, dreq.cause, enc_ranap));
f_conn_table_del(context_id);
}
/* RANAP from client, for a new RANAP connection */
[] CLIENT.receive(RUA_Conn_Req:?) -> value creq sender vc_conn {
var octetstring enc_ranap := enc_RANAP_PDU(creq.ranap);
if (f_comp_known(vc_conn) == false) {
/* unknown client, create new connection */
context_id := f_gen_context_id();
if (creq.ps_domain) {
domain_ind := ps_domain;
} else {
domain_ind := cs_domain;
}
f_conn_table_add(vc_conn, domain_ind, context_id);
RUA.send(ts_RUA_Connect(domain_ind, context_id, normal_call, enc_ranap));
} else {
/* known client, send via existing component */
context_id := f_context_id_by_comp(vc_conn);
RUA.send(ts_RUA_DirectTransfer(domain_ind, context_id, enc_ranap));
}
}
}
function f_ranap_reset(RANAP_IEs.CN_DomainIndicator dom) runs on RUA_Emulation_CT {
timer T := 5.0;
var RANAP_PDU tx := valueof(ts_RANAP_Reset(ts_RanapCause_om_intervention,dom));
RUA.send(ts_RUA_ConnectionlessTransfer(enc_RANAP_PDU(tx)));
T.start;
alt {
[] RUA.receive(tr_RUA_ConnectionlessTransfer(decmatch tr_RANAP_ResetAck)) {
log("RUA-RANAP: Received RESET-ACK in resposne to RESET, we're reay to go!");
}
[] as_reset_ack();
[] RUA.receive { repeat; }
[] T.timeout {
setverdict(fail, "RUA-RANAP: Timeout waiting for RESET-ACK after sending RESET");
mtc.stop;
}
}
}
function main(RuaOps ops, charstring id) runs on RUA_Emulation_CT {
g_rua_id := id;
g_rua_ops := ops;
f_conn_table_init();
//f_expect_table_init();
while (true) {
alt {
[] as_main_rua();
/*
[] PROC.getcall(RUA_Register:{?,?}) -> param(l3_info, vc_hdlr) {
f_create_expect(l3_info, vc_hdlr);
PROC.reply(RUA_register:{l3_info, vc_hdlr}) to vc_hdlr;
}
*/
}
}
}
}