# 0 "IPA_Emulation.ttcnpp" # 0 "" # 0 "" # 1 "IPA_Emulation.ttcnpp" module IPA_Emulation { # 21 "IPA_Emulation.ttcnpp" import from IPA_Types all; import from IPA_CodecPort all; import from IPA_CodecPort_CtrlFunct all; import from IPL4asp_Types all; import from IPL4asp_PortType all; import from Socket_API_Definitions all; import from RSL_Types all; import from AbisOML_Types all; # 56 "IPA_Emulation.ttcnpp" import from Osmocom_CTRL_Types all; import from PCUIF_Types all; modulepar { boolean mp_ipa_mgcp_uses_osmo_ext := true; } type enumerated IpaMode { IPA_MODE_CLIENT, IPA_MODE_SERVER } type enumerated IpaInitBehavior { IPA_INIT_SEND_IPA_ID_GET, IPA_INIT_SEND_IPA_ID_ACK } type record ASP_IPA_Unitdata { IpaStreamId streamId, IpaExtStreamId streamIdExt optional, octetstring payload } type enumerated ASP_IPA_EventType { ASP_IPA_EVENT_DOWN, ASP_IPA_EVENT_UP, ASP_IPA_EVENT_ID_RESP, ASP_IPA_EVENT_ID_ACK } type record ASP_IPA_Event { ASP_IPA_EventType ev_type, integer conn_id, IpaCcmIdResp id_resp optional } template (value) ASP_IPA_Event ts_ASP_IPA_EV(ASP_IPA_EventType ev_type, integer conn_id, template (omit) IpaCcmIdResp id_resp := omit) := { ev_type := ev_type, conn_id := conn_id, id_resp := id_resp } template ASP_IPA_Event tr_ASP_IPA_EV(template ASP_IPA_EventType ev_type, template integer conn_id := ?, template IpaCcmIdResp id_resp := *) := { ev_type := ev_type, conn_id := conn_id, id_resp := id_resp } template ASP_IPA_Unitdata t_ASP_IPA_UD(IpaStreamId sid, octetstring pl, template IpaExtStreamId esid := omit) := { streamId := sid, streamIdExt := esid, payload := pl } type record ASP_RSL_Unitdata { integer conn_id optional, IpaStreamId streamId, RSL_Message rsl }; template (value) ASP_RSL_Unitdata ts_ASP_RSL_UD(template (value) RSL_Message rsl, IpaStreamId sid := IPAC_PROTO_RSL_TRX0, template (omit) integer conn_id := omit) := { conn_id := conn_id, streamId := sid, rsl := rsl } template ASP_RSL_Unitdata tr_ASP_RSL_UD(template (present) RSL_Message rsl, template IpaStreamId sid := IPAC_PROTO_RSL_TRX0, template integer conn_id := *) := { conn_id := conn_id, streamId := sid, rsl := rsl } template IpaStreamId t_IpaSidRSL := ( IPAC_PROTO_RSL_TRX0, IPAC_PROTO_RSL_TRX1, IPAC_PROTO_RSL_TRX2, IPAC_PROTO_RSL_TRX3 ); type port IPA_SP_PT message { inout ASP_IPA_Unitdata, ASP_IPA_Event; } with { extension "internal" } # 166 "IPA_Emulation.ttcnpp" type port IPA_RSL_PT message { inout ASP_RSL_Unitdata, ASP_IPA_Event; } with { extension "internal" } type port IPA_OML_PT message { inout OML_PDU, octetstring, ASP_IPA_Event; } with { extension "internal" } type port IPA_CTRL_PT message { inout CtrlMessage, ASP_IPA_Event; } with { extension "internal" } # 200 "IPA_Emulation.ttcnpp" type port IPA_OSMO_PCU_PT message { inout PCUIF_Message, ASP_IPA_Event; } with { extension "internal" } type component IPA_Emulation_CT { port IPA_CODEC_PT IPA_PORT; port IPA_CFG_PT CFG_PORT; # 223 "IPA_Emulation.ttcnpp" port IPA_RSL_PT IPA_RSL_PORT; port IPA_OML_PT IPA_OML_PORT; port IPA_CTRL_PT IPA_CTRL_PORT; # 243 "IPA_Emulation.ttcnpp" port IPA_OSMO_PCU_PT IPA_OSMO_PCU_PORT; port IPA_SP_PT IPA_SP_PORT; var boolean g_initialized := false; var boolean g_is_bsc_mgw; var IPL4asp_Types.ConnectionId g_self_conn_id := -1; var IPL4asp_Types.ConnectionId g_last_conn_id := -1; var IpaMode g_mode; var boolean g_ccm_enabled; var IpaInitBehavior g_init_behavior; var boolean g_server_stop_on_ipa_ev_down := true; var IPA_CCM_Parameters g_ccm_pars := c_IPA_default_ccm_pars; } type record IPA_CCM_Parameters { charstring ser_nr optional, charstring name optional, charstring location1 optional, charstring location2 optional, charstring equip_version optional, charstring sw_version optional, charstring ip_addr optional, charstring mac_addr optional, charstring unit_id optional, charstring osmo_rand optional } const IPA_CCM_Parameters c_IPA_default_ccm_pars := { ser_nr := "", name := "mahlzeit", location1 := "", location2 := "", equip_version := "", sw_version := "", ip_addr := "", mac_addr := "", unit_id := "0/1/2", osmo_rand := "" }; signature IPA_CFG_disconnect(inout IPL4asp_Types.Result res); signature IPA_CFG_chg_ccm_enabled(in boolean res); type port IPA_CFG_PT procedure { inout IPA_CFG_disconnect; inout IPA_CFG_chg_ccm_enabled; } with { extension "internal" }; function f_ipa_cfg_disconnect(IPA_CFG_PT pt, inout IPL4asp_Types.Result res) { pt.call(IPA_CFG_disconnect:{res}) { [] pt.getreply(IPA_CFG_disconnect:{?}) -> param (res) {}; } } function f_ipa_cfg_chg_ccm_enabled(IPA_CFG_PT pt, boolean ccm_enabled) { pt.call(IPA_CFG_chg_ccm_enabled:{ccm_enabled}) { [] pt.getreply(IPA_CFG_chg_ccm_enabled:{ccm_enabled}); } } function f_connect(charstring remote_host, IPL4asp_Types.PortNumber remote_port, charstring local_host, IPL4asp_Types.PortNumber local_port, IPA_CCM_Parameters ccm_pars := c_IPA_default_ccm_pars) runs on IPA_Emulation_CT { var IPL4asp_Types.Result res; res := IPA_CodecPort_CtrlFunct.f_IPL4_connect(IPA_PORT, remote_host, remote_port, local_host, local_port, 0, { tcp:={} }); if (not ispresent(res.connId)) { setverdict(fail, "Could not connect IPA socket from ", local_host, " port ", local_port, " to ", remote_host, " port ", remote_port, "; check your configuration"); mtc.stop; } g_self_conn_id := res.connId; g_ccm_pars := ccm_pars; g_is_bsc_mgw := true; } function f_bind(charstring local_host, IPL4asp_Types.PortNumber local_port, IPA_CCM_Parameters ccm_pars := c_IPA_default_ccm_pars) runs on IPA_Emulation_CT { var IPL4asp_Types.Result res; res := IPA_CodecPort_CtrlFunct.f_IPL4_listen(IPA_PORT, local_host, local_port, { tcp:={} }); if (not ispresent(res.connId)) { setverdict(fail, "Could not listen IPA socket ", local_host, ":", local_port, ", check your configuration"); mtc.stop; } g_self_conn_id := res.connId; g_ccm_pars := ccm_pars; g_is_bsc_mgw := false; } private function f_close() runs on IPA_Emulation_CT return IPL4asp_Types.Result { var IPL4asp_Types.Result res; select (g_mode) { case (IPA_MODE_CLIENT) { res := IPA_CodecPort_CtrlFunct.f_IPL4_close(IPA_PORT, g_self_conn_id, {tcp := {}}); g_self_conn_id := -1; } case (IPA_MODE_SERVER) { res := IPA_CodecPort_CtrlFunct.f_IPL4_close(IPA_PORT, g_last_conn_id, {tcp := {}}); g_last_conn_id := -1; } case else { setverdict(fail, "Unknown mode"); mtc.stop; } } return res; } # 373 "IPA_Emulation.ttcnpp" private template IpaCcmRespPart t_IdRespPart(IpaCcmIdTag tag, charstring payload) := { len := 0, tag := tag, data := char2oct(payload) & '00'O } private function f_send_IPA_EVT(template (value) ASP_IPA_Event evt) runs on IPA_Emulation_CT { if (IPA_SP_PORT.checkstate("Connected")) { IPA_SP_PORT.send(evt); } if (IPA_RSL_PORT.checkstate("Connected")) { IPA_RSL_PORT.send(evt); } if (IPA_OML_PORT.checkstate("Connected")) { IPA_OML_PORT.send(evt); } if (IPA_CTRL_PORT.checkstate("Connected")) { IPA_CTRL_PORT.send(evt); } # 409 "IPA_Emulation.ttcnpp" if (IPA_OSMO_PCU_PORT.checkstate("Connected")) { IPA_OSMO_PCU_PORT.send(evt); } } private function f_ccm_make_id_resp(PDU_IPA_CCM get) runs on IPA_Emulation_CT return PDU_IPA_CCM { var integer i; var PDU_IPA_CCM resp := { msg_type := IPAC_MSGT_ID_RESP, u := { resp := {} } } if (not ispresent(get.u)) { return resp; } for (i := 0; i < sizeof(get.u.get); i := i + 1) { var IpaCcmIdTag tag := get.u.get[i].tag; var charstring foo; select (tag) { case (IPAC_IDTAG_SERNR) { foo := g_ccm_pars.ser_nr; } case (IPAC_IDTAG_UNITNAME) { foo := g_ccm_pars.name; } case (IPAC_IDTAG_LOCATION1) { foo := g_ccm_pars.location1; } case (IPAC_IDTAG_LOCATION2) { foo := g_ccm_pars.location2; } case (IPAC_IDTAG_EQUIPVERS) { foo := g_ccm_pars.equip_version; } case (IPAC_IDTAG_SWVERSION) { foo := g_ccm_pars.sw_version; } case (IPAC_IDTAG_IPADDR) { foo := g_ccm_pars.ip_addr; } case (IPAC_IDTAG_MACADDR) { foo := g_ccm_pars.mac_addr; } case (IPAC_IDTAG_UNITID) { foo := g_ccm_pars.unit_id; } case (IPAC_IDTAG_OSMO_RAND) { foo := g_ccm_pars.osmo_rand; } case else { foo := "unknown"; } } resp.u.resp[sizeof(resp.u.resp)] := valueof(t_IdRespPart(tag, foo)); } return resp; } private function f_ccm_tx(PDU_IPA_CCM ccm, IPL4asp_Types.ConnectionId conn_id) runs on IPA_Emulation_CT { var IPA_Send ipa_tx := valueof(t_IPA_Send(conn_id, IPAC_PROTO_CCM, enc_PDU_IPA_CCM(ccm))); log("CCM Tx:", ccm); IPA_PORT.send(ipa_tx); } template PDU_IPA_CCM ts_IPA_PONG := { msg_type := IPAC_MSGT_PONG, u := omit } template PDU_IPA_CCM ts_IPA_ACK := { msg_type := IPAC_MSGT_ID_ACK, u := omit } template PDU_IPA_CCM ts_IPA_ID_GET := { msg_type := IPAC_MSGT_ID_GET, u := { get := { { 1, IPAC_IDTAG_UNITNAME }, { 1, IPAC_IDTAG_UNITID } } } } template PDU_IPA_CCM tr_IPA_ID_RESP := { msg_type := IPAC_MSGT_ID_RESP, u := { resp := { { ?, IPAC_IDTAG_UNITNAME, ? }, { ?, IPAC_IDTAG_UNITID, ? } } } } private function f_ccm_rx_client(PDU_IPA_CCM ccm) runs on IPA_Emulation_CT { select (ccm.msg_type) { case (IPAC_MSGT_PING) { f_ccm_tx(valueof(ts_IPA_PONG), g_self_conn_id); } case (IPAC_MSGT_ID_ACK) { f_send_IPA_EVT(ts_ASP_IPA_EV(ASP_IPA_EVENT_ID_ACK, g_self_conn_id)); } case (IPAC_MSGT_ID_GET) { f_ccm_tx(f_ccm_make_id_resp(ccm), g_self_conn_id); } case else { log("Unknown/unsupported IPA CCM message type", ccm); } } } private function f_ccm_rx_server(PDU_IPA_CCM ccm, IPL4asp_Types.ConnectionId conn_id) runs on IPA_Emulation_CT { select (ccm.msg_type) { case (IPAC_MSGT_PING) { f_ccm_tx(valueof(ts_IPA_PONG), conn_id); } case (IPAC_MSGT_ID_ACK) { f_send_IPA_EVT(ts_ASP_IPA_EV(ASP_IPA_EVENT_ID_ACK, conn_id)); } case (IPAC_MSGT_ID_RESP) { log("IPA ID RESP: ", ccm.u.resp); if (not match(ccm, tr_IPA_ID_RESP)) { log("IPA identity response ", ccm.u.resp, " mismatch"); return; } f_send_IPA_EVT(ts_ASP_IPA_EV(ASP_IPA_EVENT_ID_RESP, conn_id, ccm.u.resp)); f_ccm_tx(valueof(ts_IPA_ACK), conn_id); } case else { log("Unknown/unsupported IPA CCM message type", ccm); } } } private function f_to_asp(IPA_RecvFrom ipa_rx) return ASP_IPA_Unitdata { var ASP_IPA_Unitdata ret := { streamId := ipa_rx.streamId, streamIdExt := ipa_rx.streamIdExt, payload := ipa_rx.msg } return ret; } private function f_from_asp(IPL4asp_Types.ConnectionId connId, ASP_IPA_Unitdata ipa_tx) return IPA_Send { var IPA_Send ret := valueof(t_IPA_Send(connId, ipa_tx.streamId, ipa_tx.payload, ipa_tx.streamIdExt)); return ret; } private function f_from_rsl(IPL4asp_Types.ConnectionId connId, ASP_RSL_Unitdata rsl_tx) return IPA_Send { var octetstring payload := enc_RSL_Message(rsl_tx.rsl); if (rsl_tx.conn_id != omit) { connId := rsl_tx.conn_id; } return valueof(t_IPA_Send(connId, rsl_tx.streamId, payload)); } private function f_from_oml(IPL4asp_Types.ConnectionId connId, OML_PDU oml_tx) return IPA_Send { var octetstring payload := enc_OML_PDU(oml_tx); var IPA_Send ret := valueof(t_IPA_Send(connId, IPAC_PROTO_OML, payload)); return ret; } function main_client(charstring remote_host, IPL4asp_Types.PortNumber remote_port, charstring local_host, IPL4asp_Types.PortNumber local_port, IPA_CCM_Parameters ccm_pars := c_IPA_default_ccm_pars, boolean ccm_enabled := true) runs on IPA_Emulation_CT { g_mode := IPA_MODE_CLIENT; g_ccm_enabled := ccm_enabled; f_connect(remote_host, remote_port, local_host, local_port, ccm_pars); if (g_ccm_enabled) { f_ccm_tx(valueof(ts_IPA_ACK), g_self_conn_id); } f_send_IPA_EVT(ts_ASP_IPA_EV(ASP_IPA_EVENT_UP, g_self_conn_id)); ScanEvents(); } function main_server(charstring local_host, IPL4asp_Types.PortNumber local_port, boolean ccm_enabled := true, IpaInitBehavior init_behavior := IPA_INIT_SEND_IPA_ID_GET, boolean server_stop_on_ipa_ev_down := true) runs on IPA_Emulation_CT { g_mode := IPA_MODE_SERVER; g_ccm_enabled := ccm_enabled; g_init_behavior := init_behavior; g_server_stop_on_ipa_ev_down := server_stop_on_ipa_ev_down; f_bind(local_host, local_port); ScanEvents(); } private function f_ctrl_to_user(octetstring msg) runs on IPA_Emulation_CT { var charstring msg_ch := oct2char(msg); IPA_CTRL_PORT.send(dec_CtrlMessage(msg_ch)); } # 654 "IPA_Emulation.ttcnpp" private function f_osmo_pcu_to_user(octetstring msg) runs on IPA_Emulation_CT { var PCUIF_Message pcuif_msg := dec_PCUIF_Message(msg); IPA_OSMO_PCU_PORT.send(pcuif_msg); } # 682 "IPA_Emulation.ttcnpp" private function f_ipa_conn_id() runs on IPA_Emulation_CT return IPL4asp_Types.ConnectionId { var IPL4asp_Types.ConnectionId conn_id; select (g_mode) { case (IPA_MODE_CLIENT) { conn_id := g_self_conn_id; } case (IPA_MODE_SERVER) { conn_id := g_last_conn_id; } case else { setverdict(fail, "Unknown mode"); mtc.stop; } } if (conn_id == -1) { setverdict(fail, "Connection is not established"); mtc.stop; } return conn_id; } private function ScanEvents() runs on IPA_Emulation_CT { var IPA_RecvFrom ipa_rx; var ASP_Event asp_evt; var Socket_API_Definitions.PortEvent port_evt; var octetstring payload; var ASP_IPA_Unitdata ipa_ud; var IPL4asp_Types.Result res; var boolean cfg_chg_ccm_enabled; var CtrlMessage ctrl_msg; # 726 "IPA_Emulation.ttcnpp" var ASP_RSL_Unitdata rsl; var OML_PDU oml; var PCUIF_Message pcu; var f_IPL4_getMsgLen vl_f := refers(f_IPL4_fixedMsgLen); IPA_CodecPort_CtrlFunct.f_IPL4_setGetMsgLen(IPA_PORT, g_self_conn_id, vl_f, {0, 2, 3, 1, 0}); while (true) { alt { [g_ccm_enabled] IPA_PORT.receive(IPA_RecvFrom:{?,IPAC_PROTO_CCM,omit,?}) -> value ipa_rx { var PDU_IPA_CCM ccm := dec_PDU_IPA_CCM(ipa_rx.msg); log("CCM Rx:", ccm); select (g_mode) { case (IPA_MODE_CLIENT) { f_ccm_rx_client(ccm); } case (IPA_MODE_SERVER) { f_ccm_rx_server(ccm, ipa_rx.connId); } case else { setverdict(fail, "Unknown mode"); mtc.stop; } } } [] IPA_PORT.receive(IPA_RecvFrom:?) -> value ipa_rx { select (ipa_rx.streamId) { # 776 "IPA_Emulation.ttcnpp" case (t_IpaSidRSL) { rsl := valueof(ts_ASP_RSL_UD( rsl := dec_RSL_Message(ipa_rx.msg), sid := ipa_rx.streamId, conn_id := ipa_rx.connId )); IPA_RSL_PORT.send(rsl); } case (IPAC_PROTO_OML) { oml := dec_OML_PDU(ipa_rx.msg) IPA_OML_PORT.send(oml); } case (IPAC_PROTO_OSMO) { select (ipa_rx.streamIdExt) { case (IPAC_PROTO_EXT_CTRL) { f_ctrl_to_user(ipa_rx.msg); } # 814 "IPA_Emulation.ttcnpp" case (IPAC_PROTO_EXT_OSMO_PCU) { f_osmo_pcu_to_user(ipa_rx.msg); } case else { IPA_SP_PORT.send(f_to_asp(ipa_rx)); } } } case else { IPA_SP_PORT.send(f_to_asp(ipa_rx)); } } } [] IPA_PORT.receive(ASP_Event:{connOpened:=?}) -> value asp_evt { g_last_conn_id := asp_evt.connOpened.connId; log("Established a new IPA connection (conn_id=", g_last_conn_id, ")"); f_send_IPA_EVT(ts_ASP_IPA_EV(ASP_IPA_EVENT_UP, g_last_conn_id)); if (g_mode == IPA_MODE_SERVER and g_ccm_enabled) { select (g_init_behavior) { case (IPA_INIT_SEND_IPA_ID_GET) { f_ccm_tx(valueof(ts_IPA_ID_GET), g_last_conn_id); } case (IPA_INIT_SEND_IPA_ID_ACK) { f_ccm_tx(valueof(ts_IPA_ACK), g_last_conn_id); } } } } [] IPA_PORT.receive(ASP_Event:{connClosed:=?}) -> value asp_evt { log("IPA: Closed"); g_self_conn_id := -1; f_send_IPA_EVT(ts_ASP_IPA_EV(ASP_IPA_EVENT_DOWN, asp_evt.connClosed.connId)); if (g_mode != IPA_MODE_SERVER or g_server_stop_on_ipa_ev_down) { self.stop; } } [] IPA_PORT.receive(Socket_API_Definitions.PortEvent:{result:={errorCode:=ERROR_SOCKET, connId:=?, os_error_code:=?, os_error_text:=?}}) -> value port_evt { log("PortEvent: ERROR_SOCKET: ", port_evt); g_self_conn_id := -1; f_send_IPA_EVT(ts_ASP_IPA_EV(ASP_IPA_EVENT_DOWN, port_evt.result.connId)); self.stop; } # 887 "IPA_Emulation.ttcnpp" [] IPA_CTRL_PORT.receive(CtrlMessage:?) -> value ctrl_msg { payload := char2oct(enc_CtrlMessage(ctrl_msg)); ipa_ud := valueof(t_ASP_IPA_UD(IPAC_PROTO_OSMO, payload, IPAC_PROTO_EXT_CTRL)); IPA_PORT.send(f_from_asp(f_ipa_conn_id(), ipa_ud)); } # 912 "IPA_Emulation.ttcnpp" [] IPA_OSMO_PCU_PORT.receive(PCUIF_Message:?) -> value pcu { payload := enc_PCUIF_Message(pcu); ipa_ud := valueof(t_ASP_IPA_UD(IPAC_PROTO_OSMO, payload, IPAC_PROTO_EXT_OSMO_PCU)); IPA_PORT.send(f_from_asp(f_ipa_conn_id(), ipa_ud)); } [] IPA_RSL_PORT.receive(ASP_RSL_Unitdata:?) -> value rsl { IPA_PORT.send(f_from_rsl(f_ipa_conn_id(), rsl)); } [] IPA_OML_PORT.receive(OML_PDU:?) -> value oml { IPA_PORT.send(f_from_oml(f_ipa_conn_id(), oml)); } [] IPA_OML_PORT.receive(octetstring:?) -> value payload { IPA_PORT.send(t_IPA_Send(f_ipa_conn_id(), IPAC_PROTO_OML, payload)); } [] IPA_SP_PORT.receive(ASP_IPA_Unitdata: ?) -> value ipa_ud { IPA_PORT.send(f_from_asp(f_ipa_conn_id(), ipa_ud)); } [] CFG_PORT.getcall(IPA_CFG_disconnect:{?}) { res := f_close(); CFG_PORT.reply(IPA_CFG_disconnect:{res}); } [] CFG_PORT.getcall(IPA_CFG_chg_ccm_enabled:{?})-> param(cfg_chg_ccm_enabled) { g_ccm_enabled := cfg_chg_ccm_enabled; CFG_PORT.reply(IPA_CFG_chg_ccm_enabled:{cfg_chg_ccm_enabled}); } } } } type component IPA_EventWaiter_CT { port IPA_SP_PT IPA_SP_PORT; } function waiter_main(template ASP_IPA_Event wait_for := tr_ASP_IPA_EV(ASP_IPA_EVENT_ID_ACK)) runs on IPA_EventWaiter_CT { alt { [] IPA_SP_PORT.receive(wait_for) { setverdict(pass); } [] IPA_SP_PORT.receive { repeat; } } } }