diff --git a/library/MNCC_Emulation.ttcn b/library/MNCC_Emulation.ttcn index 60ec58b32..856575e05 100644 --- a/library/MNCC_Emulation.ttcn +++ b/library/MNCC_Emulation.ttcn @@ -193,7 +193,7 @@ runs on MNCC_Emulation_CT { } -function f_connect(charstring sock) runs on MNCC_Emulation_CT { +private function f_connect(charstring sock) runs on MNCC_Emulation_CT { var UD_connect_result res; timer T := 5.0; @@ -215,6 +215,40 @@ function f_connect(charstring sock) runs on MNCC_Emulation_CT { } } +private function f_listen(charstring sock) runs on MNCC_Emulation_CT { + var UD_listen_result res; + var UD_connected udc; + timer T := 5.0; + + T.start; + MNCC.send(UD_listen:{sock}); + alt { + [] MNCC.receive(UD_listen_result:?) -> value res { + if (ispresent(res.result) and ispresent(res.result.result_code) and res.result.result_code == ERROR) { + setverdict(fail, "Error listening to MNCC socket", res); + self.stop; + } else { + g_mncc_ud_id := res.id; + } + } + [] T.timeout { + setverdict(fail, "Timeout listening to MNCC socket"); + self.stop; + } + } + + T.start; + alt { + [] MNCC.receive(UD_connected:?) -> value udc { + g_mncc_ud_id := res.id; + } + [] T.timeout { + setverdict(fail, "Timeout waiting for MNCC connection"); + self.stop; + } + } +} + /* call-back type, to be provided by specific implementation; called when new SCCP connection * arrives */ type function MnccCreateCallback(MNCC_PDU conn_ind, charstring id) @@ -228,9 +262,14 @@ type record MnccOps { MnccUnitdataCallback unitdata_cb } -function main(MnccOps ops, charstring id, charstring sock) runs on MNCC_Emulation_CT { +function main(MnccOps ops, charstring id, charstring sock, boolean role_server := false) +runs on MNCC_Emulation_CT { - f_connect(sock); + if (role_server) { + f_listen(sock); + } else { + f_connect(sock); + } f_expect_table_init(); f_call_table_init(); @@ -289,15 +328,19 @@ function main(MnccOps ops, charstring id, charstring sock) runs on MNCC_Emulatio f_call_table_del(call_id); } - /* Client -> MNCC Socket: SETUP.req: forward + add call table entry */ - [] MNCC_CLIENT.receive(MNCC_PDU:{msg_type := MNCC_SETUP_REQ, u:=?}) -> value mncc sender vc_conn { - /* add to call table */ - f_call_table_add(vc_conn, f_mncc_get_call_id(mncc)); + /* Client -> MNCC Socket: Normal message */ + [] MNCC_CLIENT.receive(MNCC_PDU:?) -> value mncc sender vc_conn { + if (mncc.msg_type == MNCC_SETUP_REQ and not role_server) { + /* ConnHdlr -> MNCC Server: SETUP.req: add to call table */ + f_call_table_add(vc_conn, f_mncc_get_call_id(mncc)); + } else if (mncc.msg_type == MNCC_SETUP_IND and role_server) { + /* ConnHdlr -> MNCC Client: SETUP.ind: add to call table */ + f_call_table_add(vc_conn, f_mncc_get_call_id(mncc)); + } /* forward to MNCC socket */ MNCC.send(t_SD_MNCC(g_mncc_ud_id, mncc)); } - /* Client -> MNCC Socket: Normal message */ [] MNCC_CLIENT.receive(MNCC_PDU:?) -> value mncc sender vc_conn { /* forward to MNCC socket */ MNCC.send(t_SD_MNCC(g_mncc_ud_id, mncc)); diff --git a/library/MNCC_Types.ttcn b/library/MNCC_Types.ttcn index 001b4b8d3..8d47efbff 100644 --- a/library/MNCC_Types.ttcn +++ b/library/MNCC_Types.ttcn @@ -561,7 +561,38 @@ template MNCC_PDU tr_MNCC_SETUP_ind(template uint32_t call_id := ?, template MNC lchan_mode := ? } } - +} +template (value) MNCC_PDU ts_MNCC_SETUP_ind(uint32_t call_id, MNCC_number called, + template (omit) MNCC_number calling := omit, + template (omit) charstring imsi := omit, + template (value) MNCC_bearer_cap bcap := ts_MNCC_bcap_voice) := { + msg_type := MNCC_SETUP_IND, + u := { + signal := { /* See 24.008 9.3.23.2 */ + callref := call_id, + bearer_cap := valueof(bcap), /* mandatory */ + called := called, /* mandatory */ + calling := calling, /* optional */ + redirecting := omit, + connected := omit, + cause := omit, + progress := omit, + useruser := omit, /* optional */ + facility := omit, /* optional */ + cccap := omit, /* optional */ + ssversion := omit, /* optional */ + clir_sup := 0, /* optional */ + clir_inv := 0, /* optional */ + signal := omit, + keypad := omit, + more := 0, + notify := 0, + emergency := omit, + imsi := imsi, + lchan_type := 0, + lchan_mode := 0 + } + } } /* MO: MSC <- MNCC: SETUP.cnf; Response to SETUP.ind */ diff --git a/library/SIP_Emulation.ttcn b/library/SIP_Emulation.ttcn new file mode 100644 index 000000000..57ec70435 --- /dev/null +++ b/library/SIP_Emulation.ttcn @@ -0,0 +1,408 @@ +module SIP_Emulation { + +/* SIP Emulation, runs on top of SIPmsg_PT. It multiplexes/demultiplexes + * the individual calls, so there can be separate TTCN-3 components handling + * each of the calls + * + * The SIP_Emulation.main() function processes SIP message from the SIPmsg + * socket via the SIPmsg_PT, and dispatches them to the per-connection components. + * + * Outbound SIP calls are initiated by sending a PDU_SIP_Request messages + * to the component running the SIP_Emulation.main() function. + * + * For each new inbound call, the SipOps.create_cb() is called. It can create + * or resolve a TTCN-3 component, and returns a component reference to which that inbound + * call is routed/dispatched. + * + * If a pre-existing component wants to register to handle a future inbound call, it can + * do so by registering an "expect" with the expected destination phone number. This is e.g. useful + * if you are simulating MNCC + SIP, and first trigger a connection from MNCC side in a + * component which then subsequently should also handle the SIP emulation. + * + * (C) 2018 by Harald Welte + * All rights reserved. + * + * Released under the terms of GNU General Public License, Version 2 or + * (at your option) any later version. + */ + +import from SIPmsg_Types all; +import from SIPmsg_PortType all; + +type component SIP_ConnHdlr { + /* ports towards SIP Emulation core / call dispatcher */ + port SIP_Conn_PT SIP; + port SIPEM_PROC_PT SIP_PROC; +} + +/* port between individual per-call components and this dispatcher */ +type port SIP_Conn_PT message { + inout PDU_SIP_Request, PDU_SIP_Response; +} with { extension "internal" }; + +/* represents a single SIP Call */ +type record CallData { + /* reference to the instance of the per-connection component */ + SIP_ConnHdlr comp_ref, + CallidString call_id +} + +type component SIP_Emulation_CT { + /* SIP test port on bottom side */ + port SIPmsg_PT SIP; + /* SIP port to the per-call clients */ + port SIP_Conn_PT CLIENT; + + var CallData SipCallTable[16]; + var ExpectData SipExpectTable[16]; + + /* procedure based port to register for incoming connections */ + port SIPEM_PROC_PT CLIENT_PROC; +}; + +private function f_sip_init() runs on SIP_Emulation_CT { + map(self:SIP, system:SIP); +} + +template RequestLine tr_ReqLine(template Method method) := { + method := method, + requestUri := ?, + sipVersion := ? +} + +template PDU_SIP_Request tr_SIP_INVITE := { + requestLine := tr_ReqLine(INVITE_E), + msgHeader := t_SIP_msgHeader_any, + messageBody := *, + payload := * +} + + +template SipUrl tr_SIP_Url(template charstring user_or_num, + template charstring host := *, + template integer portField := *) := { + scheme := "sip", + userInfo := { + userOrTelephoneSubscriber := user_or_num, + password := * + }, + hostPort := { + host := host, + portField := portField + }, + urlParameters := *, + headers := * +} +template (value) SipUrl ts_SIP_Url(charstring user_or_num, + template (omit) charstring host := omit, + template (omit) integer portField := omit) := { + scheme := "sip", + userInfo := { + userOrTelephoneSubscriber := user_or_num, + password := omit + }, + hostPort := { + host := host, + portField := portField + }, + urlParameters := omit, + headers := omit +} + +template Addr_Union tr_SIP_Addr(template SipUrl sip_url) := { + nameAddr := { + displayName := *, + addrSpec := sip_url + } +} +template (value) Addr_Union ts_SIP_Addr(template (value) SipUrl sip_url) := { + nameAddr := { + displayName := omit, + addrSpec := sip_url + } +} + +template To tr_SIP_To(template Addr_Union addr) := { + fieldName := TO_E, + addressField := addr, + toParams := * +} +template (value) To ts_SIP_To(template (value) Addr_Union addr) := { + fieldName := TO_E, + addressField := addr, + toParams := omit +} + +/* resolve component reference by connection ID */ +private function f_call_id_known(CallidString call_id) +runs on SIP_Emulation_CT return boolean { + var integer i; + for (i := 0; i < sizeof(SipCallTable); i := i+1) { + if (SipCallTable[i].call_id == call_id) { + return true; + } + } + return false; +} + +/* resolve component reference by connection ID */ +private function f_comp_by_call_id(CallidString call_id) +runs on SIP_Emulation_CT return SIP_ConnHdlr { + var integer i; + for (i := 0; i < sizeof(SipCallTable); i := i+1) { + if (SipCallTable[i].call_id == call_id) { + return SipCallTable[i].comp_ref; + } + } + setverdict(fail, "SIP Call table not found by SIP Call ID ", call_id); + self.stop; +} + +/* resolve connection ID by component reference */ +private function f_call_id_by_comp(SIP_ConnHdlr client) +runs on SIP_Emulation_CT return CallidString { + for (var integer i := 0; i < sizeof(SipCallTable); i := i+1) { + if (SipCallTable[i].comp_ref == client) { + return SipCallTable[i].call_id; + } + } + setverdict(fail, "SIP Call table not found by component ", client); + self.stop; +} + +private function f_expect_table_init() +runs on SIP_Emulation_CT { + for (var integer i := 0; i < sizeof(SipExpectTable); i := i+1) { + SipExpectTable[i].sip_to := omit; + SipExpectTable[i].vc_conn := null; + } +} + +private function f_call_table_init() +runs on SIP_Emulation_CT { + for (var integer i := 0; i < sizeof(SipCallTable); i := i+1) { + SipCallTable[i].comp_ref := null; + SipCallTable[i].call_id := ""; + } +} + +private function f_call_table_add(SIP_ConnHdlr comp_ref, CallidString call_id) +runs on SIP_Emulation_CT { + for (var integer i := 0; i < sizeof(SipCallTable); i := i+1) { + if (SipCallTable[i].call_id == "") { + SipCallTable[i].comp_ref := comp_ref; + SipCallTable[i].call_id := call_id; + log("Added SIP Call Table entry [", i, "] for ", call_id, " at ", comp_ref); + return; + } + } + setverdict(fail, "SIP Call table full"); + self.stop; +} + +private function f_call_table_del(CallidString call_id) +runs on SIP_Emulation_CT { + for (var integer i := 0; i < sizeof(SipCallTable); i := i+1) { + if (SipCallTable[i].call_id == call_id) { + SipCallTable[i].comp_ref := null; + SipCallTable[i].call_id := ""; + log("Deleted SIP Call Table entry [", i, "] for ", call_id); + return; + } + } + setverdict(fail, "SIP Call table attempt to delete non-existant ", call_id); + self.stop; +} + +/* call-back type, to be provided by specific implementation; called when new call connection + * arrives */ +type function SipCreateCallback(PDU_SIP_Request sip_req, charstring id) +runs on SIP_Emulation_CT return SIP_ConnHdlr; + +type record SipOps { + SipCreateCallback create_cb +}; + +function f_init_sip(inout SIP_Emulation_CT ct, charstring id) { + id := id & "-SIP"; + + var SipOps ops := { + create_cb := refers(SIP_Emulation.ExpectedCreateCallback) + }; + + ct := SIP_Emulation_CT.create(id); + map(ct:SIP, system:SIP); + ct.start(SIP_Emulation.main(ops, id)); +} + +function main(SipOps ops, charstring id) +runs on SIP_Emulation_CT { + + f_sip_init(); + f_expect_table_init(); + f_call_table_init(); + + while (true) { + var SIP_ConnHdlr vc_hdlr, vc_conn; + var PDU_SIP_Request sip_req; + var PDU_SIP_Response sip_resp; + var SipUrl sip_to; + + alt { + /* SIP INVITE was received on SIP socket/port */ + [] SIP.receive(tr_SIP_INVITE) -> value sip_req { + var CallidString call_id := sip_req.msgHeader.callId.callid; + if (f_call_id_known(call_id)) { + /* re-invite? */ + vc_conn := f_comp_by_call_id(call_id); + } else { + /* new INVITE: check expect */ + vc_conn := ops.create_cb.apply(sip_req, id); + f_call_table_add(vc_conn, call_id); + } + CLIENT.send(sip_req) to vc_conn; + } + /* other SIP request was received on SIP socket/port */ + [] SIP.receive(PDU_SIP_Request:?) -> value sip_req { + var CallidString call_id := sip_req.msgHeader.callId.callid; + if (f_call_id_known(call_id)) { + vc_conn := f_comp_by_call_id(call_id); + CLIENT.send(sip_req) to vc_conn; + } else { + setverdict(fail, "SIP Request for unknown call ", call_id); + self.stop; + } + } + /* SIP response was received on SIP socket/port */ + [] SIP.receive(PDU_SIP_Response:?) -> value sip_resp { + var CallidString call_id := sip_resp.msgHeader.callId.callid; + if (f_call_id_known(call_id)) { + vc_conn := f_comp_by_call_id(call_id); + CLIENT.send(sip_resp) to vc_conn; + } else { + setverdict(fail, "SIP Response for unknown call ", call_id); + self.stop; + } + } + + /* a ConnHdlr is sending us a SIP INVITE: Forward to SIP port */ + [] CLIENT.receive(tr_SIP_INVITE) -> value sip_req sender vc_conn { + var CallidString call_id := sip_req.msgHeader.callId.callid; + if (f_call_id_known(call_id)) { + /* re-invite? */ + vc_conn := f_comp_by_call_id(call_id); + } else { + /* new INVITE: add to table */ + f_call_table_add(vc_conn, call_id); + } + SIP.send(sip_req); + } + /* a ConnHdlr is sending us a SIP request: Forward to SIP port */ + [] CLIENT.receive(PDU_SIP_Request:?) -> value sip_req sender vc_conn { + SIP.send(sip_req); + } + /* a ConnHdlr is sending us a SIP request: Forward to SIP port */ + [] CLIENT.receive(PDU_SIP_Response:?) -> value sip_resp sender vc_conn { + SIP.send(sip_resp); + } + + [] CLIENT_PROC.getcall(SIPEM_register:{?,?}) -> param(sip_to, vc_hdlr) { + f_create_expect(sip_to, vc_hdlr); + CLIENT_PROC.reply(SIPEM_register:{sip_to, vc_hdlr}); + } + + } + } +} + +/*********************************************************************** + * "Expect" Handling (mapping for expected incoming SIP callds from IUT) + ***********************************************************************/ + +/* data about an expected future incoming connection */ +type record ExpectData { + /* SIP "To" (destination number) based on which we can match */ + SipUrl sip_to optional, + /* component reference registered for the connection */ + SIP_ConnHdlr vc_conn +} + +/* procedure based port to register for incoming calls */ +signature SIPEM_register(SipUrl sip_to, SIP_ConnHdlr vc_conn); + +type port SIPEM_PROC_PT procedure { + inout SIPEM_register; +} with { extension "internal" }; + + +/* CreateCallback that can be used as create_cb and will use the expect table */ +function ExpectedCreateCallback(PDU_SIP_Request sip_req, charstring id) +runs on SIP_Emulation_CT return SIP_ConnHdlr { + var SIP_ConnHdlr ret := null; + var SipUrl sip_to; + var integer i; + + if (sip_req.requestLine.method != INVITE_E) { + setverdict(fail, "SIP ExpectedCreateCallback needs INVITE"); + return ret; + } + sip_to := sip_req.msgHeader.toField.addressField.nameAddr.addrSpec; + + for (i := 0; i < sizeof(SipExpectTable); i := i+1) { + if (not ispresent(SipExpectTable[i].sip_to)) { + continue; + } + /* build a template, use '*' for all 'omit' values */ + var template SipUrl t_exp := SipExpectTable[i].sip_to; + if (not ispresent(t_exp.hostPort.host)) { + t_exp.hostPort.host := *; + } + if (not ispresent(t_exp.hostPort.portField)) { + t_exp.hostPort.portField := *; + } + if (not ispresent(t_exp.urlParameters)) { + t_exp.urlParameters := *; + } + if (not ispresent(t_exp.headers)) { + t_exp.headers := *; + } + /* match against the constructed template */ + if (match(sip_to, t_exp)) { + ret := SipExpectTable[i].vc_conn; + /* release this entry to be used again */ + SipExpectTable[i].sip_to := omit; + SipExpectTable[i].vc_conn := null; + log("Found SipExpect[", i, "] for ", sip_to, " handled at ", ret); + return ret; + } + } + + setverdict(fail, "Couldn't find SipExpect for incoming call ", sip_to); + return ret; +} + +/* server/emulation side function to create expect */ +private function f_create_expect(SipUrl sip_to, SIP_ConnHdlr hdlr) +runs on SIP_Emulation_CT { + var integer i; + for (i := 0; i < sizeof(SipExpectTable); i := i+1) { + if (not ispresent(SipExpectTable[i].sip_to)) { + SipExpectTable[i].sip_to := sip_to; + SipExpectTable[i].vc_conn := hdlr; + log("Created SipExpect[", i, "] for ", sip_to, " to be handled at ", hdlr); + return; + } + } + setverdict(fail, "No space left in SipExpectTable"); +} + +/* client/conn_hdlr side function to use procedure port to create expect in emulation */ +function f_create_sip_expect(SipUrl sip_to) runs on SIP_ConnHdlr { + SIP_PROC.call(SIPEM_register:{sip_to, self}) { + [] SIP_PROC.getreply(SIPEM_register:{?,?}) {}; + } +} + + + +} diff --git a/sip/SIP_Tests.cfg b/sip/SIP_Tests.cfg new file mode 100644 index 000000000..db435afd2 --- /dev/null +++ b/sip/SIP_Tests.cfg @@ -0,0 +1,18 @@ +[ORDERED_INCLUDE] +# Common configuration, shared between test suites +"../Common.cfg" +# testsuite specific configuration, not expected to change +"./SIP_Tests.default" + +# Local configuration below + +[LOGGING] + +[TESTPORT_PARAMETERS] + +[MODULE_PARAMETERS] + +[MAIN_CONTROLLER] + +[EXECUTE] +SIP_Tests.control diff --git a/sip/SIP_Tests.default b/sip/SIP_Tests.default new file mode 100644 index 000000000..b0abf189f --- /dev/null +++ b/sip/SIP_Tests.default @@ -0,0 +1,30 @@ +[LOGGING] +FileMask := LOG_ALL | TTCN_MATCHING; + +"IPA-CTRL-IPA".FileMask := ERROR | WARNING; +mtc.FileMask := ERROR | WARNING; + +[TESTPORT_PARAMETERS] +"SIP_Test-MNCC".MNCC.socket_type := "SEQPACKET"; +*.SIPVTY.CTRL_MODE := "client" +*.SIPVTY.CTRL_HOSTNAME := "127.0.0.1" +*.SIPVTY.CTRL_PORTNUM := "4256" +*.SIPVTY.CTRL_LOGIN_SKIPPED := "yes" +*.SIPVTY.CTRL_DETECT_SERVER_DISCONNECTED := "yes" +*.SIPVTY.CTRL_READMODE := "buffered" +*.SIPVTY.CTRL_CLIENT_CLEANUP_LINEFEED := "yes" +*.SIPVTY.PROMPT1 := "OsmoMNCC> " + +*.SIP.local_sip_port := "5060" +*.SIP.default_local_address := "127.0.0.2" +*.SIP.default_sip_protocol := "UDP" +*.SIP.default_dest_port := "5060" +*.SIP.default_dest_address := "127.0.0.1" + + +[MODULE_PARAMETERS] +Osmocom_VTY_Functions.mp_prompt_prefix := "OsmoMNCC"; + +[MAIN_CONTROLLER] + +[EXECUTE] diff --git a/sip/SIP_Tests.ttcn b/sip/SIP_Tests.ttcn new file mode 100644 index 000000000..de2f49879 --- /dev/null +++ b/sip/SIP_Tests.ttcn @@ -0,0 +1,173 @@ +module SIP_Tests { + +import from General_Types all; +import from Osmocom_Types all; + +import from Osmocom_CTRL_Functions all; +import from Osmocom_CTRL_Types all; +import from Osmocom_CTRL_Adapter all; + +import from TELNETasp_PortType all; +import from Osmocom_VTY_Functions all; + +import from MNCC_Emulation all; +import from MNCC_Types all; + +import from SDP_Types all; + +import from SIP_Emulation all; +import from SIPmsg_Types all; + +modulepar { + //charstring mp_local_host := "127.0.0.2; + charstring mp_osmosip_host := "127.0.0.1"; + integer mp_osmosip_port_ctrl := -1; /* RFU */ + charstring mp_mncc := "/tmp/mncc"; +} + +type component test_CT extends CTRL_Adapter_CT { + var MNCC_Emulation_CT vc_MNCC; + var SIP_Emulation_CT vc_SIP; + + port TELNETasp_PT SIPVTY; +} + +type component ConnHdlr extends SIP_ConnHdlr, MNCC_ConnHdlr { + var ConnHdlrPars g_pars; + timer g_Tguard; +} + +type record ConnHdlrPars { + float t_guard +} + + +function f_init_mncc(charstring id) runs on test_CT { + id := id & "-MNCC"; + var MnccOps ops := { + create_cb := refers(MNCC_Emulation.ExpectedCreateCallback), + unitdata_cb := refers(MNCC_Emulation.DummyUnitdataCallback) + }; + + vc_MNCC := MNCC_Emulation_CT.create(id); + map(vc_MNCC:MNCC, system:MNCC_CODEC_PT); + vc_MNCC.start(MNCC_Emulation.main(ops, id, mp_mncc, true)); +} + +function f_init() runs on test_CT { + //f_ipa_ctrl_start(mp_osmosip_host, mp_osmosip_port_ctrl); + f_init_mncc("SIP_Test"); + log("end of f_init_mncc"); + f_init_sip(vc_SIP, "SIP_Test"); + log("end of f_init_sip"); + + map(self:SIPVTY, system:SIPVTY); + f_vty_set_prompts(SIPVTY); + f_vty_transceive(SIPVTY, "enable"); + log("end of f_init"); +} + +type function void_fn(charstring id) runs on ConnHdlr; + +function f_start_handler(void_fn fn, ConnHdlrPars pars) +runs on test_CT return ConnHdlr { + var ConnHdlr vc_conn; + var charstring id := testcasename(); + + vc_conn := ConnHdlr.create(id); + + connect(vc_conn:SIP, vc_SIP:CLIENT); + connect(vc_conn:SIP_PROC, vc_SIP:CLIENT_PROC); + + connect(vc_conn:MNCC, vc_MNCC:MNCC_CLIENT); + connect(vc_conn:MNCC_PROC, vc_MNCC:MNCC_PROC); + + vc_conn.start(f_handler_init(fn, id, pars)); + return vc_conn; +} + +private altstep as_Tguard() runs on ConnHdlr { + [] g_Tguard.timeout { + setverdict(fail, "Tguard timeout"); + self.stop; + } +} + +private function f_handler_init(void_fn fn, charstring id, ConnHdlrPars pars) +runs on ConnHdlr { + g_pars := pars; + g_Tguard.start(pars.t_guard); + activate(as_Tguard()); + + /* call the user-supied test case function */ + fn.apply(id); +} + + +template (value) ConnHdlrPars t_Pars := { + t_guard := 30.0 +} + +private function f_TC_mo_setup(charstring id) runs on ConnHdlr { + var PDU_SIP_Request sip_req; + + var MNCC_number dst := valueof(ts_MNCC_number("01234567")); + var MNCC_number src := valueof(ts_MNCC_number("112")); + + f_create_sip_expect(valueof(ts_SIP_Url("+01234567"))); + + log("sending mncc setup"); + MNCC.send(ts_MNCC_SETUP_ind(2342, dst, src, "262420123456789")); + + MNCC.receive(tr_MNCC_RTP_CREATE(2342)); + MNCC.send(ts_MNCC_RTP_CREATE(2342)); + + SIP.receive(PDU_SIP_Request:?) -> value sip_req { + log(sip_req); + } +} + +testcase TC_mo_setup() runs on test_CT { + var ConnHdlrPars pars; + var ConnHdlr vc_conn; + + f_init(); + + pars := valueof(t_Pars); + vc_conn := f_start_handler(refers(f_TC_mo_setup), pars); + vc_conn.done; +} + + + + + +/* SIP specifics */ + +const integer c_SIP_PORT := 5060; + +template (value) SIP_comm_adress ts_SipAddr(charstring rhost, + template (omit) charstring lhost := omit, + integer rport := c_SIP_PORT, + integer lport := c_SIP_PORT, + SIP_com_prot prot := UDP_E) := { + remote_host := rhost, + remote_port := rport, + local_host := lhost, + local_port := lport, + protocol := prot +} + +template (value) ASP_SIP_open ts_SIP_open(SIP_comm_adress addr) := { + addr := addr +} + + + +control { + execute( TC_mo_setup() ); +} + + + +} diff --git a/sip/gen_links.sh b/sip/gen_links.sh new file mode 100755 index 000000000..ff6405604 --- /dev/null +++ b/sip/gen_links.sh @@ -0,0 +1,49 @@ +#!/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" +gen_links $DIR $FILES + +DIR=$BASEDIR/titan.TestPorts.Common_Components.Socket-API/src +FILES="Socket_API_Definitions.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 + +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.SIPmsg/src +FILES="SIP_parse.h SIP_parse.y SIP_parse_.tab.h SIPmsg_PT.hh SIPmsg_Types.ttcn SIP_parse.l SIP_parse_.tab.c SIPmsg_PT.cc SIPmsg_PortType.ttcn lex.SIP_parse_.c" +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 +FILES="General_Types.ttcn GSM_Types.ttcn Osmocom_Types.ttcn MNCC_Types.ttcn MNCC_EncDec.cc MNCC_CodecPort.ttcn mncc.h MNCC_Emulation.ttcn Osmocom_VTY_Functions.ttcn Native_Functions.ttcn Native_FunctionDefs.cc " +FILES+="IPA_Types.ttcn IPA_Emulation.ttcnpp IPA_CodecPort.ttcn IPA_CodecPort_CtrlFunct.ttcn IPA_CodecPort_CtrlFunctDef.cc " +FILES+="Osmocom_CTRL_Types.ttcn Osmocom_CTRL_Functions.ttcn Osmocom_CTRL_Adapter.ttcn " +FILES+="RTP_CodecPort.ttcn RTP_CodecPort_CtrlFunctDef.cc " +FILES+="SIP_Emulation.ttcn " +gen_links $DIR $FILES + +ignore_pp_results diff --git a/sip/regen_makefile.sh b/sip/regen_makefile.sh new file mode 100755 index 000000000..86f71b8a6 --- /dev/null +++ b/sip/regen_makefile.sh @@ -0,0 +1,8 @@ +#!/bin/sh + +FILES="*.ttcn *.ttcnpp TCCConversion.cc TCCInterface.cc UD_PT.cc MNCC_EncDec.cc IPL4asp_PT.cc +IPL4asp_discovery.cc SDP_EncDec.cc RTP_EncDec.cc IPA_CodecPort_CtrlFunctDef.cc RTP_CodecPort_CtrlFunctDef.cc TELNETasp_PT.cc Native_FunctionDefs.cc SIPmsg_PT.cc *.c " + +export CPPFLAGS_TTCN3="" + +../regen-makefile.sh SIP_Tests.ttcn $FILES