diff options
author | Pau Espin Pedrol <pespin@sysmocom.de> | 2021-12-02 20:12:25 +0100 |
---|---|---|
committer | laforge <laforge@osmocom.org> | 2021-12-15 14:23:23 +0000 |
commit | 9e183726904c6cc2632186c523b0d58993fa287c (patch) | |
tree | 98e864a4ceecf864e50a20ee951e8642f8d6feb8 | |
parent | 32fb54e61059ded6dd1695447e9dee2d7a2f21c4 (diff) |
hnodeb: Add gtp SAPI
Change-Id: Ie4de00641089abbd03273ce5a2d9325659ac7d42
-rw-r--r-- | hnodeb/HNBGW_ConnectionHandler.ttcn | 57 | ||||
-rw-r--r-- | hnodeb/HNB_Tests.ttcn | 62 | ||||
-rwxr-xr-x | hnodeb/gen_links.sh | 6 | ||||
-rwxr-xr-x | hnodeb/regen_makefile.sh | 3 | ||||
-rw-r--r-- | library/HNBLLIF_Templates.ttcn | 127 | ||||
-rw-r--r-- | library/HNBLLIF_Types.ttcn | 104 |
6 files changed, 352 insertions, 7 deletions
diff --git a/hnodeb/HNBGW_ConnectionHandler.ttcn b/hnodeb/HNBGW_ConnectionHandler.ttcn index 3c4bc6f4..b069a116 100644 --- a/hnodeb/HNBGW_ConnectionHandler.ttcn +++ b/hnodeb/HNBGW_ConnectionHandler.ttcn @@ -34,8 +34,13 @@ import from HNBLLIF_CodecPort all; import from HNBLLIF_Types all; import from HNBLLIF_Templates all; +import from GTP_Emulation all; +import from GTP_Templates all; +import from GTP_CodecPort all; +import from GTPU_Types all; + /* this component represents a single Iuh connection at the HNBGW. */ -type component HNBGW_ConnHdlr extends StatsD_ConnHdlr { +type component HNBGW_ConnHdlr extends StatsD_ConnHdlr, GTP_ConnHdlr { port TELNETasp_PT HNBVTY; port HNBAP_PT HNBAP; port RUA_PT RUA; @@ -46,6 +51,10 @@ type component HNBGW_ConnHdlr extends StatsD_ConnHdlr { var RTP_Emulation_CT vc_RTPEM; port RTPEM_CTRL_PT RTPEM_CTRL; port RTPEM_DATA_PT RTPEM_DATA; + + var GTP_Emulation_CT vc_GTP; + + var TestHdlrParams g_pars; var boolean g_vty_initialized := false; @@ -60,11 +69,8 @@ function f_HNBGW_ConnHdlr_init_vty() runs on HNBGW_ConnHdlr { } } -/* initialize all parameters */ -function f_HNBGW_ConnHdlr_init(charstring id, TestHdlrParams pars) runs on HNBGW_ConnHdlr { +private function f_HNBGW_ConnHdlr_init_iuh(charstring id) runs on HNBGW_ConnHdlr { var Iuh_Emulation_CT vc_Iuh; - - g_pars := valueof(pars); vc_Iuh := Iuh_Emulation_CT.create(id & "-HNBGW"); connect(self:HNBAP, vc_Iuh:HNBAP); connect(self:RUA, vc_Iuh:RUA); @@ -75,7 +81,30 @@ function f_HNBGW_ConnHdlr_init(charstring id, TestHdlrParams pars) runs on HNBGW iuh_pars.local_ip := g_pars.hnbgw_addr; iuh_pars.local_sctp_port := g_pars.hnbgw_port; vc_Iuh.start(Iuh_Emulation.main(iuh_pars, id & "-Iuh")); +} + +private function f_HNBGW_ConnHdlr_init_gtp(charstring id) runs on HNBGW_ConnHdlr { + id := id & "-GTP"; + + var GtpEmulationCfg gtp_cfg := { + gtpc_bind_ip := g_pars.hnbgw_addr, + gtpc_bind_port := GTP1C_PORT, + gtpu_bind_ip := g_pars.hnbgw_addr, + gtpu_bind_port := GTP1U_PORT, + sgsn_role := false + }; + + vc_GTP := GTP_Emulation_CT.create(id); + connect(self:GTP, vc_GTP:CLIENT); + connect(self:GTP_PROC, vc_GTP:CLIENT_PROC); + vc_GTP.start(GTP_Emulation.main(gtp_cfg)); +} +/* initialize all parameters */ +function f_HNBGW_ConnHdlr_init(charstring id, TestHdlrParams pars) runs on HNBGW_ConnHdlr { + g_pars := valueof(pars); + f_HNBGW_ConnHdlr_init_iuh(id); + f_HNBGW_ConnHdlr_init_gtp(id); f_HNBGW_ConnHdlr_init_vty(); /* Connect to HNB on LLSK and do HELLO ping-pong */ @@ -115,6 +144,13 @@ function f_start_hnbllif(HNBLLIF_CODEC_PT pt, charstring id, charstring hnbllif_ Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for HNBLLIF HELLO.REQ SAPI=AUDIO"); } } + pt.send(t_SD_HNBLLIF(hnbllif_conn_id, ts_HNBLLIF_CTL_HELLO_REQ(HNBLL_IF_SAPI_GTP, 0))); + alt { + [] as_hnbllif_hello_cnf(pt, hnbllif_conn_id, last_hello_cnf, HNBLL_IF_SAPI_GTP, 0); + [] T.timeout { + Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for HNBLLIF HELLO.REQ SAPI=GTP"); + } + } } type record TestHdlrParams { @@ -151,6 +187,17 @@ template (value) TestHdlrParams t_def_TestHdlrPars := { sac := 4 } +template (value) GtpPeer ts_GtpPeerU(charstring ip) := { + connId := 1, + remName := ip, + remPort := GTP1U_PORT +} + +function f_gtpu_send(uint32_t tei, octetstring payload) runs on HNBGW_ConnHdlr { + var GtpPeer peer := valueof(ts_GtpPeerU(g_pars.hnodeb_addr)); + GTP.send(ts_GTP1U_GPDU(peer, 0 /*seq*/, int2oct(tei, 4), payload)); +} + /* HNBLLIF socket may at any time receive a new INFO.ind */ altstep as_hnbllif_hello_cnf(HNBLLIF_CODEC_PT pt, integer hnbllif_conn_id, out HNBLLIF_Message last_hello_cnf, diff --git a/hnodeb/HNB_Tests.ttcn b/hnodeb/HNB_Tests.ttcn index 05cd2bf5..ca42e5c2 100644 --- a/hnodeb/HNB_Tests.ttcn +++ b/hnodeb/HNB_Tests.ttcn @@ -52,6 +52,10 @@ import from HNBLLIF_CodecPort all; import from HNBLLIF_Types all; import from HNBLLIF_Templates all; +import from GTPU_Types all; +import from GTP_Templates all; +import from GTP_Emulation all; + modulepar { /* IP address at which the HNodeB can be reached */ charstring mp_hnodeb_ip := "127.0.0.1"; @@ -359,12 +363,70 @@ testcase TC_cs_mo_call() runs on test_CT { f_shutdown_helper(); } +private function f_tc_ps_mo_gtp_ping_pong(charstring id) runs on HNBGW_ConnHdlr { + const integer context_id := 30; + const bitstring context_id_bstr := '000000000000000000011110'B; /* encoded context_id */ + const Establishment_Cause est_cause := normal_call; + var uint32_t remote_tei := 8888; + var uint32_t local_tei; + var octetstring gtp_payload := f_rnd_octstring(40); + var HNBLLIF_send_data sd; + + f_gtp_register_teid(int2oct(remote_tei, 4)); + + f_handle_hnbap_hnb_register_req(); + + LLSK.receive(f_llsk_rx(tr_HNBLLIF_IUH_CONFIGURE_IND(g_pars.mcc, g_pars.mnc, g_pars.cell_identity, + g_pars.lac, g_pars.rac, g_pars.sac, g_pars.rnc_id))); + + /* Now an UE attempts CM Service Request: */ + LLSK.send(f_llsk_tx(ts_HNBLLIF_IUH_CONN_ESTABLISH_REQ(context_id, 1, enum2int(est_cause), hex2oct(ranap_cm_service_req)))); + /* The related RUA Connect + RANAP message is received on Iuh: */ + RUA.receive(tr_RUA_Connect(ps_domain, context_id_bstr, est_cause, hex2oct(ranap_cm_service_req))); + + /* Now HNBGW answers with RUA-DirectTransfer(RANAP-RabASsReq) */ + RUA.send(ts_RUA_DirectTransfer(ps_domain, context_id_bstr, hex2oct(ranap_rab_ass_req))); + + /* Now on LLSK first the Conn establishment is confirmed and then we receive data */ + LLSK.receive(f_llsk_rx(tr_HNBLLIF_IUH_CONN_ESTABLISH_CNF(context_id, 1, 0))); + LLSK.receive(f_llsk_rx(tr_HNBLLIF_IUH_CONN_DATA_IND(context_id, 1, hex2oct(ranap_rab_ass_req)))); + + /* Now LLSK provides the remote TransportLayerAddress from RabAssReq and asks SUT to provide a local address: */ + LLSK.send(f_llsk_tx(ts_HNBLLIF_GTP_CONN_ESTABLISH_REQ(context_id, remote_tei, HNBLL_IF_ADDR_TYPE_IPV4, + f_HNBLLIF_Addr(HNBLL_IF_ADDR_TYPE_IPV4, g_pars.hnbgw_addr)))); + LLSK.receive(f_llsk_rx(tr_HNBLLIF_GTP_CONN_ESTABLISH_CNF(context_id, ?, 0, + HNBLL_IF_ADDR_TYPE_IPV4, ?))) -> value sd; + local_tei := sd.data.u.gtp.u.conn_establish.u.cnf.local_tei; + + /* Forward GTP data in both directions */ + LLSK.send(f_llsk_tx(ts_HNBLLIF_GTP_CONN_DATA_REQ(context_id, remote_tei, gtp_payload))); + GTP.receive(tr_GTPU_GPDU(ts_GtpPeerU(g_pars.hnodeb_addr), int2oct(remote_tei, 4), gtp_payload)); + f_gtpu_send(local_tei, gtp_payload); + LLSK.receive(f_llsk_rx(tr_HNBLLIF_GTP_CONN_DATA_IND(context_id, local_tei, gtp_payload))); + + /* Done, release GTP conn */ + LLSK.send(f_llsk_tx(ts_HNBLLIF_GTP_CONN_RELEASE_REQ(context_id, remote_tei))); + + /* UE sends Iu Release Complete to release the conn */ + LLSK.send(f_llsk_tx(ts_HNBLLIF_IUH_CONN_RELEASE_REQ(context_id, 1, 0, 0, hex2oct(iu_release_compl)))); + RUA.receive(tr_RUA_Disconnect(ps_domain, context_id_bstr, ts_RUA_Cause(normal), hex2oct(iu_release_compl))); +} +testcase TC_ps_mo_gtp_ping_pong() runs on test_CT { + var HNBGW_ConnHdlr vc_conn; + + f_init(); + vc_conn := f_start_handler(refers(f_tc_ps_mo_gtp_ping_pong)); + vc_conn.done; + f_shutdown_helper(); +} + control { execute( TC_hnb_register_request_accept() ); execute( TC_hnb_register_request_reject() ); execute( TC_mo_conn() ); execute( TC_paging() ); execute( TC_cs_mo_call() ); + execute( TC_ps_mo_gtp_ping_pong() ); } } diff --git a/hnodeb/gen_links.sh b/hnodeb/gen_links.sh index 6ddb4c0f..84495e9f 100755 --- a/hnodeb/gen_links.sh +++ b/hnodeb/gen_links.sh @@ -44,6 +44,10 @@ DIR=$BASEDIR/titan.TestPorts.TELNETasp/src FILES="TELNETasp_PT.cc TELNETasp_PT.hh TELNETasp_PortType.ttcn" gen_links $DIR $FILES +DIR=$BASEDIR/titan.ProtocolModules.GTP_v13.5.0/src +FILES="GTPC_EncDec.cc GTPC_Types.ttcn GTPU_EncDec.cc GTPU_Types.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 " @@ -59,7 +63,7 @@ FILES="HNBLLIF_Types.ttcn HNBLLIF_Templates.ttcn HNBLLIF_CodecPort.ttcn " FILES+="Iuh_Types.ttcn Iuh_CodecPort.ttcn Iuh_CodecPort_CtrlFunctDef.cc Iuh_CodecPort_CtrlFunct.ttcn Iuh_Emulation.ttcn DNS_Helpers.ttcn " FILES+="Misc_Helpers.ttcn General_Types.ttcn Osmocom_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+="GTP_CodecPort.ttcn GTP_CodecPort_CtrlFunct.ttcn GTP_CodecPort_CtrlFunctDef.cc GTP_Emulation.ttcn GTP_Templates.ttcn IPCP_Types.ttcn GSM_Types.ttcn " gen_links $DIR $FILES ignore_pp_results diff --git a/hnodeb/regen_makefile.sh b/hnodeb/regen_makefile.sh index 2d135046..10f5c215 100755 --- a/hnodeb/regen_makefile.sh +++ b/hnodeb/regen_makefile.sh @@ -25,6 +25,9 @@ FILES=" HNBAP_EncDec.cc RUA_EncDec.cc UD_PT.cc + GTPC_EncDec.cc + GTPU_EncDec.cc + GTP_CodecPort_CtrlFunctDef.cc " export CPPFLAGS_TTCN3=" diff --git a/library/HNBLLIF_Templates.ttcn b/library/HNBLLIF_Templates.ttcn index 3fa49b7b..78cf89a4 100644 --- a/library/HNBLLIF_Templates.ttcn +++ b/library/HNBLLIF_Templates.ttcn @@ -367,4 +367,131 @@ template (value) HNBLLIF_Message ts_HNBLLIF_AUDIO_CONN_DATA_REQ(template (value) } } } + + +/********************** + * GTP SAPI + **********************/ +template (value) HNBLLIF_Message ts_HNBLLIF_GTP_CONN_ESTABLISH_REQ(template (value) uint32_t context_id, + template (value) uint32_t remote_tei, + template (value) HNBLLIF_AddrType remote_gtpu_address_type, + template (value) HNBLLIF_Addr remote_gtpu_addr) := { + sapi := HNBLL_IF_SAPI_GTP, + u := { + gtp := { + prim := HNBLL_IF_GTP_MSG_CONN_ESTABLISH, + u := { + conn_establish := { + op := HNBLL_IF_OP_REQUEST, + u := { + req := { + context_id := context_id, + remote_tei := remote_tei, + reserved := 0, + remote_gtpu_address_type := remote_gtpu_address_type, + remote_gtpu_addr := remote_gtpu_addr + } + } + } + } + } + } +} + +template (present) HNBLLIF_Message tr_HNBLLIF_GTP_CONN_ESTABLISH_CNF(template (present) uint32_t context_id := ?, + template (present) uint32_t local_tei := ?, + template (present) uint8_t error_code := ?, + template (present) HNBLLIF_AddrType local_gtpu_address_type := ?, + template (present) HNBLLIF_Addr local_gtpu_addr := ?) := { + sapi := HNBLL_IF_SAPI_GTP, + u := { + gtp := { + prim := HNBLL_IF_GTP_MSG_CONN_ESTABLISH, + u := { + conn_establish := { + op := HNBLL_IF_OP_CONFIRM, + u := { + cnf := { + context_id := context_id, + local_tei := local_tei, + error_code := error_code, + local_gtpu_address_type := local_gtpu_address_type, + local_gtpu_addr := local_gtpu_addr + } + } + } + } + } + } +} + +template (value) HNBLLIF_Message ts_HNBLLIF_GTP_CONN_RELEASE_REQ(template (value) uint32_t context_id, + template (value) uint32_t remote_tei) := { + sapi := HNBLL_IF_SAPI_GTP, + u := { + gtp := { + prim := HNBLL_IF_GTP_MSG_CONN_RELEASE, + u := { + conn_release := { + op := HNBLL_IF_OP_REQUEST, + u := { + req := { + context_id := context_id, + remote_tei := remote_tei + } + } + } + } + } + } +} + +template (present) HNBLLIF_Message tr_HNBLLIF_GTP_CONN_DATA_IND(template (present) uint32_t context_id := ?, + template (present) uint32_t local_tei := ?, + template (present) octetstring data := ?) := { + sapi := HNBLL_IF_SAPI_GTP, + u := { + gtp := { + prim := HNBLL_IF_GTP_MSG_CONN_DATA, + u := { + conn_data := { + op := HNBLL_IF_OP_INDICATION, + u := { + ind := { + context_id := context_id, + local_tei := local_tei, + data_len := ?, + data := data + } + } + } + } + } + } +} + +template (value) HNBLLIF_Message ts_HNBLLIF_GTP_CONN_DATA_REQ(template (value) uint32_t context_id, + template (value) uint32_t remote_tei, + template (value) octetstring data) := { + sapi := HNBLL_IF_SAPI_GTP, + u := { + gtp := { + prim := HNBLL_IF_GTP_MSG_CONN_DATA, + u := { + conn_data := { + op := HNBLL_IF_OP_REQUEST, + u := { + req := { + context_id := context_id, + remote_tei := remote_tei, + data_len := lengthof(data), + data := data + } + } + } + } + } + } +} + } with { encode "RAW" variant "BYTEORDER(first)" }; diff --git a/library/HNBLLIF_Types.ttcn b/library/HNBLLIF_Types.ttcn index befd7bb7..95f91fc6 100644 --- a/library/HNBLLIF_Types.ttcn +++ b/library/HNBLLIF_Types.ttcn @@ -330,6 +330,106 @@ type record HNBLLIF_AUDIO_PrimHdr { other, OTHERWISE)" }; +/********************** + * GTP SAPI + **********************/ +type enumerated HNBLLIF_GTP_MsgType { + HNBLL_IF_GTP_MSG_CONN_ESTABLISH ('0000'O), + HNBLL_IF_GTP_MSG_CONN_RELEASE ('0001'O), + HNBLL_IF_GTP_MSG_CONN_DATA ('0002'O) +} with { variant "FIELDLENGTH(16)" }; + +/* CONN_ESTABLISH */ +type record HNBLLIF_GTP_conn_establish_req { + uint32_t context_id, + uint32_t remote_tei, + uint8_t reserved, + HNBLLIF_AddrType remote_gtpu_address_type, + HNBLLIF_Addr remote_gtpu_addr +} with { variant "" }; + +type record HNBLLIF_GTP_conn_establish_cnf { + uint32_t context_id, + uint32_t local_tei, + uint8_t error_code, + HNBLLIF_AddrType local_gtpu_address_type, + HNBLLIF_Addr local_gtpu_addr +} with { variant "" }; + +type union HNBLLIF_GTP_PrimOpUnion_conn_establish { + HNBLLIF_GTP_conn_establish_req req, + HNBLLIF_GTP_conn_establish_cnf cnf, + octetstring other +} with { variant "" }; +type record HNBLLIF_GTP_PrimOp_conn_establish { + HNBLLIF_Operation op, + HNBLLIF_GTP_PrimOpUnion_conn_establish u +} with { variant (u) "CROSSTAG( req, op = HNBLL_IF_OP_REQUEST; + cnf, op = HNBLL_IF_OP_CONFIRM; + other, OTHERWISE)" +}; + +/* CONN_RELEASE */ +type record HNBLLIF_GTP_conn_release_req { + uint32_t context_id, + uint32_t remote_tei +} with { variant "" }; + +type union HNBLLIF_GTP_PrimOpUnion_conn_release { + HNBLLIF_GTP_conn_release_req req, + octetstring other +} with { variant "" }; +type record HNBLLIF_GTP_PrimOp_conn_release { + HNBLLIF_Operation op, + HNBLLIF_GTP_PrimOpUnion_conn_release u +} with { variant (u) "CROSSTAG( req, op = HNBLL_IF_OP_REQUEST; + other, OTHERWISE)" +}; + +/* CONN_DATA */ +type record HNBLLIF_GTP_conn_data_req { + uint32_t context_id, + uint32_t remote_tei, + uint32_t data_len, + octetstring data /* RANAP message */ +} with { variant (data_len) "LENGTHTO (data)" }; + +type record HNBLLIF_GTP_conn_data_ind { + uint32_t context_id, + uint32_t local_tei, + uint32_t data_len, + octetstring data /* RANAP message */ +} with { variant (data_len) "LENGTHTO (data)" }; + +type union HNBLLIF_GTP_PrimOpUnion_conn_data { + HNBLLIF_GTP_conn_data_req req, + HNBLLIF_GTP_conn_data_ind ind, + octetstring other +} with { variant "" }; +type record HNBLLIF_GTP_PrimOp_conn_data { + HNBLLIF_Operation op, + HNBLLIF_GTP_PrimOpUnion_conn_data u +} with { variant (u) "CROSSTAG( req, op = HNBLL_IF_OP_REQUEST; + ind, op = HNBLL_IF_OP_INDICATION; + other, OTHERWISE)" +}; + +type union HNBLLIF_GTP_PrimUnion { + HNBLLIF_GTP_PrimOp_conn_establish conn_establish, + HNBLLIF_GTP_PrimOp_conn_release conn_release, + HNBLLIF_GTP_PrimOp_conn_data conn_data, + octetstring other +} with { variant "" }; + +type record HNBLLIF_GTP_PrimHdr { + HNBLLIF_GTP_MsgType prim, + HNBLLIF_GTP_PrimUnion u +} with { variant (u) "CROSSTAG( conn_establish, prim = HNBLL_IF_GTP_MSG_CONN_ESTABLISH; + conn_release, prim = HNBLL_IF_GTP_MSG_CONN_RELEASE; + conn_data, prim = HNBLL_IF_GTP_MSG_CONN_DATA; + other, OTHERWISE)" +}; + /********************** * General @@ -345,7 +445,7 @@ type octetstring HNBLLIF_Addr length(16); type enumerated HNBLLIF_Sapi { HNBLL_IF_SAPI_CTL (-1), HNBLL_IF_SAPI_IUH ('00000001'O), - //HNBLL_IF_SAPI_GTP ('00000002'O), + HNBLL_IF_SAPI_GTP ('00000002'O), HNBLL_IF_SAPI_AUDIO ('00000003'O) } with { variant "FIELDLENGTH(32)" variant "COMP(2scompl)" @@ -361,6 +461,7 @@ type enumerated HNBLLIF_Operation { type union HNBLLIF_SapiUnion { HNBLLIF_CTL_PrimHdr ctl, HNBLLIF_IUH_PrimHdr iuh, + HNBLLIF_GTP_PrimHdr gtp, HNBLLIF_AUDIO_PrimHdr audio, octetstring other } with { variant "" }; @@ -370,6 +471,7 @@ type record HNBLLIF_Message { HNBLLIF_SapiUnion u } with { variant (u) "CROSSTAG( ctl, sapi = HNBLL_IF_SAPI_CTL; iuh, sapi = HNBLL_IF_SAPI_IUH; + gtp, sapi = HNBLL_IF_SAPI_GTP; audio, sapi = HNBLL_IF_SAPI_AUDIO; other, OTHERWISE)" }; |