Harald Welte has submitted this change and it was merged.

Change subject: More progress on osmo-sip-connector tests
......................................................................


More progress on osmo-sip-connector tests

Change-Id: I34a5d7929264c7f5f21d3868a5f919874ffa106c
---
M library/MNCC_Types.ttcn
M library/SIP_Emulation.ttcn
A library/SIP_Templates.ttcn
M sip/SIP_Tests.cfg
M sip/SIP_Tests.default
M sip/SIP_Tests.ttcn
M sip/gen_links.sh
7 files changed, 798 insertions(+), 47 deletions(-)

Approvals:
  Harald Welte: Looks good to me, approved
  Jenkins Builder: Verified



diff --git a/library/MNCC_Types.ttcn b/library/MNCC_Types.ttcn
index 39f9dce..19af236 100644
--- a/library/MNCC_Types.ttcn
+++ b/library/MNCC_Types.ttcn
@@ -512,6 +512,39 @@
                }
        }
 };
+template MNCC_PDU tr_MNCC_SETUP_req(template uint32_t call_id := ?,
+                                   template charstring called := ?,
+                                   template charstring calling := *,
+                                   template charstring imsi := ?) := {
+       msg_type := MNCC_SETUP_REQ,
+       u := {
+               signal := {     /* See 24.008 9.3.23.1 */
+                       callref := call_id,
+                       bearer_cap := *,                                /* 
mandatory in CC */
+                       called := tr_MNCC_number(called),               /* 
optional */
+                       calling := tr_MNCC_number(calling),             /* 
optional */
+                       redirecting := *,                               /* 
optional */
+                       connected := omit,
+                       cause := omit,
+                       progress := *,                                  /* 
optional */
+                       useruser := *,                                  /* 
optional */
+                       facility := *,                                  /* 
optional */
+                       cccap := omit,
+                       ssversion := omit,
+                       clir_sup := 0,
+                       clir_inv := 0,
+                       signal := *,                                    /* 
optional */
+                       keypad := omit,
+                       more := 0,
+                       notify := 0,
+                       emergency := *,
+                       imsi := imsi,
+                       lchan_type := ?,
+                       lchan_mode := ?
+               }
+       }
+};
+
 
 /* MO: MSC <- MNCC: Respons to SETUP.ind */
 template MNCC_PDU ts_MNCC_SETUP_rsp(uint32_t call_id, charstring imsi := "",
@@ -653,9 +686,9 @@
                        redirecting := omit,
                        connected := connected,
                        cause := omit,
-                       progress := *,
-                       useruser := *,
-                       facility := *,
+                       progress := omit,
+                       useruser := omit,
+                       facility := omit,
                        cccap := omit,
                        ssversion := omit,
                        clir_sup := 0,
@@ -664,10 +697,10 @@
                        keypad := omit,
                        more := 0,
                        notify := 0,
-                       emergency := *,
+                       emergency := omit,
                        imsi := "",
-                       lchan_type := ?,
-                       lchan_mode := ?
+                       lchan_type := 0,
+                       lchan_mode := 0
                }
        }
 }
@@ -807,6 +840,39 @@
                }
        }
 }
+template MNCC_PDU ts_MNCC_CALL_CONF_ind(uint32_t call_id,
+                                       template (omit) MNCC_bearer_cap bcap := 
omit,
+                                       template (omit) MNCC_cause cause := 
omit,
+                                       template (omit) MNCC_cccap cccap := 
omit) := {
+       msg_type := MNCC_CALL_CONF_IND,
+       u := {
+               signal := {     /* See 24.008 9.3.2 */
+                       callref := call_id,
+                       bearer_cap := bcap,
+                       called := omit,
+                       calling := omit,
+                       redirecting := omit,
+                       connected := omit,
+                       cause := cause,
+                       progress := omit,
+                       useruser := omit,
+                       facility := omit,
+                       cccap := cccap,
+                       ssversion := omit,
+                       clir_sup := 0,
+                       clir_inv := 0,
+                       signal := omit,
+                       keypad := omit,
+                       more := 0,
+                       notify := 0,
+                       emergency := omit,
+                       imsi := "",
+                       lchan_type := 0,
+                       lchan_mode := 0
+               }
+       }
+}
+
 
 /* MO: MSC <- MNCC: CALL_PROC.req; call establishment initiated in network */
 template MNCC_PDU ts_MNCC_CALL_PROC_req(uint32_t call_id, template 
MNCC_bearer_cap bcap := omit,
@@ -1007,6 +1073,39 @@
                }
        }
 }
+template (value) MNCC_PDU ts_MNCC_ALERT_ind(uint32_t call_id,
+                                   template (omit) MNCC_progress prog := omit,
+                                   template (omit) charstring fac := omit,
+                                   template (omit) MNCC_useruser uu := omit) 
:= {
+       msg_type := MNCC_ALERT_IND,
+       u := {
+               signal := {     /* See 24.008 9.3.1 */
+                       callref := call_id,
+                       bearer_cap := omit,
+                       called := omit,
+                       calling := omit,
+                       redirecting := omit,
+                       connected := omit,
+                       cause := omit,
+                       progress := prog,
+                       useruser := uu,
+                       facility := fac,
+                       cccap := omit,
+                       ssversion := omit,
+                       clir_sup := 0,
+                       clir_inv := 0,
+                       signal := omit,
+                       keypad := omit,
+                       more := 0,
+                       notify := 0,
+                       emergency := omit,
+                       imsi := "",
+                       lchan_type := 0,
+                       lchan_mode := 0
+               }
+       }
+}
+
 
 /*   : MSC <- MNCC: NOTIFY.req; request to send information pertaining to a 
call (such as user suspended) */
 template MNCC_PDU ts_MNCC_NOTIFY_req(uint32_t call_id, MNCC_notify notify) := {
@@ -1794,6 +1893,22 @@
                }
        }
 }
+template MNCC_PDU tr_MNCC_RTP_CONNECT(template uint32_t call_id,
+                                     template uint32_t ip := ?,
+                                     template uint32_t rtp_port := ?,
+                                     template uint32_t pt := ?) := {
+       msg_type := MNCC_RTP_CONNECT,
+       u := {
+               rtp := {
+                       callref := call_id,
+                       ip := ip,
+                       rtp_port := rtp_port,
+                       payload_type := pt,
+                       payload_msg_type := 0
+               }
+       }
+}
+
 
 /* MSC <- MNCC: RTP_FREE.req; request connect of RTP */
 template MNCC_PDU ts_MNCC_RTP_FREE(uint32_t call_id) := 
ts_MNCC_SIMPLE_RTP(MNCC_RTP_FREE, call_id);
diff --git a/library/SIP_Emulation.ttcn b/library/SIP_Emulation.ttcn
index 57ec704..3957b8f 100644
--- a/library/SIP_Emulation.ttcn
+++ b/library/SIP_Emulation.ttcn
@@ -70,7 +70,7 @@
        sipVersion := ?
 }
 
-template PDU_SIP_Request tr_SIP_INVITE := {
+private template PDU_SIP_Request tr_SIP_INVITE := {
        requestLine := tr_ReqLine(INVITE_E),
        msgHeader := t_SIP_msgHeader_any,
        messageBody := *,
diff --git a/library/SIP_Templates.ttcn b/library/SIP_Templates.ttcn
new file mode 100644
index 0000000..75681a9
--- /dev/null
+++ b/library/SIP_Templates.ttcn
@@ -0,0 +1,413 @@
+module SIP_Templates {
+
+import from SIPmsg_Types all;
+
+/* wrapper type to encapsulate the Addr_Union + parameter list used in From, 
To. ... */
+type record SipAddr {
+       Addr_Union              addr,
+       SemicolonParam_List     params optional
+}
+
+const charstring c_SIP_VERSION := "SIP/2.0";
+
+template (value) SipUrl ts_SipUrl(charstring user_or_tel, charstring host, 
integer portnr) := {
+       scheme := "sip",
+       userInfo := {
+               userOrTelephoneSubscriber := user_or_tel,
+               password := omit
+       },
+       hostPort := {
+               host := host,
+               portField := portnr
+       },
+       urlParameters := omit,
+       headers := omit
+}
+template SipUrl tr_SipUrl(template charstring user_or_tel,
+                         template charstring host,
+                         template integer portnr) := {
+       scheme := "sip",
+       userInfo := {
+               userOrTelephoneSubscriber := user_or_tel,
+               password := *
+       },
+       hostPort := {
+               host := host,
+               portField := portnr
+       },
+       urlParameters := *,
+       headers := *
+}
+
+template (value) SipAddr ts_SipAddr(charstring user_or_tel, charstring host, 
integer portnr) := {
+       addr := {
+               nameAddr := {
+                       displayName := omit,
+                       addrSpec := ts_SipUrl(user_or_tel, host, portnr)
+               }
+       },
+       params := omit
+}
+template SipAddr tr_SipAddr(template charstring user_or_tel,
+                               template charstring host,
+                               template integer portnr) := {
+       addr := {
+               nameAddr := {
+                       displayName := *,
+                       addrSpec := tr_SipUrl(user_or_tel, host, portnr)
+               }
+       },
+       params := *
+}
+
+/* build a receive template from a value: substitute '*' for omit */
+function tr_SipAddr_from_val(SipAddr tin) return template SipAddr {
+       var template SipAddr ret := tin;
+       if (tin.addr.nameAddr.displayName == omit) {
+               ret.addr.nameAddr.displayName := *;
+       }
+       if (tin.addr.nameAddr.addrSpec.userInfo.password == omit) {
+               ret.addr.nameAddr.addrSpec.userInfo.password := *;
+       }
+       if (tin.params == omit) {
+               ret.params := *;
+       }
+       return ret;
+}
+
+
+function tr_HostPort(template HostPort hp) return template HostPort {
+       var template HostPort hpout := hp;
+       /* if the port number is 5060, it may be omitted */
+       if (isvalue(hp.portField) and valueof(hp.portField) == 5060) {
+               hpout.portField := 5060 ifpresent;
+       }
+       return hpout;
+}
+
+template (value) RequestLine ts_SIP_ReqLine(Method method, template (value) 
SipUrl uri,
+                                           charstring ver := c_SIP_VERSION) := 
{
+       method := method,
+       requestUri := uri,
+       sipVersion := ver
+}
+template RequestLine tr_SIP_ReqLine(template Method method,
+                                   template SipUrl uri,
+                                   template charstring ver := c_SIP_VERSION) 
:= {
+       method := method,
+       requestUri := uri,
+       sipVersion := ver
+}
+
+template (value) StatusLine ts_SIP_StatusLine(integer status_code, charstring 
reason) := {
+       sipVersion := "SIP/2.0",
+       statusCode := status_code,
+       reasonPhrase := reason
+}
+template StatusLine tr_SIP_StatusLine(template integer status_code, template 
charstring reason) := {
+       sipVersion := "SIP/2.0",
+       statusCode := status_code,
+       reasonPhrase := reason
+}
+
+
+template (value) PDU_SIP_Request ts_SIP_req(template (value) RequestLine rl) 
:= {
+       requestLine := rl,
+       msgHeader := c_SIP_msgHeader_empty,
+       messageBody := omit,
+       payload := omit
+}
+
+const Method_List c_SIP_defaultMethods := {
+       "INVITE", "ACK", "BYE", "CANCEL", "OPTIONS", "PRACK", "MESSAGE", 
"SUBSCRIBE",
+       "NOTIFY", "REFER", "UPDATE" };
+
+private function f_ContentTypeOrOmit(template (omit) ContentType ct, template 
(omit) charstring body)
+return template (omit) ContentType {
+       /* if user explicitly stated no content type */
+       if (istemplatekind(ct, "omit")) {
+               return omit;
+       }
+       /* if there's no body, then there's no content-type either */
+       if (istemplatekind(body, "omit")) {
+               return omit;
+       }
+       return ct;
+}
+
+template (value) ContentType ts_CT_SDP := {
+       fieldName := CONTENT_TYPE_E,
+       mediaType := "application/sdp"
+};
+
+template (value) Via ts_Via_from(SipAddr from_addr) := {
+       fieldName := VIA_E,
+       viaBody := {
+               {
+                       sentProtocol := { "SIP", "2.0", "UDP" },
+                       sentBy := from_addr.addr.nameAddr.addrSpec.hostPort,
+                       viaParams := omit
+               }
+       }
+}
+
+template (value) MessageHeader ts_SIP_msgHeader_empty :=c_SIP_msgHeader_empty;
+template (value) MessageHeader ts_SIP_msgh_std( CallidString call_id,
+                                               SipAddr from_addr,
+                                               SipAddr to_addr,
+                                               template (omit) SipAddr 
contact_addr,
+                                               charstring method,
+                                               integer seq_nr,
+                                               template (value) Via via,
+                                               template (omit) ContentType 
content_type := omit,
+                                               Method_List allow_methods := 
c_SIP_defaultMethods
+                                       ) modifies ts_SIP_msgHeader_empty := {
+       allow := {
+               fieldName := ALLOW_E,
+               methods := allow_methods
+       },
+       callId := {
+               fieldName := CALL_ID_E,
+               callid := call_id
+       },
+       contact := ts_Contact(contact_addr),
+       contentType := content_type,
+       cSeq := {
+               fieldName := CSEQ_E,
+               seqNumber := seq_nr,
+               method := method
+       },
+       fromField := {
+               fieldName := FROM_E,
+               addressField := from_addr.addr,
+               fromParams := from_addr.params
+       },
+       toField := {
+               fieldName := TO_E,
+               addressField := to_addr.addr,
+               toParams := to_addr.params
+       },
+       userAgent := {
+               fieldName := USER_AGENT_E,
+               userAgentBody := {
+                       "osmo-ttcn3-hacks/0.23"
+               }
+       },
+       via := via
+}
+
+private function tr_Contact(template SipAddr contact_addr) return template 
Contact
+{
+       if (istemplatekind(contact_addr, "omit")) {
+               return omit;
+       } else if (istemplatekind(contact_addr, "*")) {
+               return *;
+       } else if (istemplatekind(contact_addr, "?")) {
+               return ?;
+       }
+       var template Contact ret := {
+               fieldName := CONTACT_E,
+               contactBody := {
+                       contactAddresses := {
+                               {
+                                       addressField := contact_addr.addr,
+                                       contactParams := contact_addr.params
+                               }
+                       }
+               }
+       };
+       return ret;
+}
+
+private function ts_Contact(template (omit) SipAddr contact_addr) return 
template (omit) Contact
+{
+       if (istemplatekind(contact_addr, "omit")) {
+               return omit;
+       }
+       var template (omit) Contact ret := {
+               fieldName := CONTACT_E,
+               contactBody := {
+                       contactAddresses := {
+                               {
+                                       addressField := contact_addr.addr,
+                                       contactParams := contact_addr.params
+                               }
+                       }
+               }
+       };
+       return ret;
+}
+
+
+function tr_AllowMethods(template Method_List allow_methods) return template 
Allow {
+       if (istemplatekind(allow_methods, "omit")) {
+               return omit;
+       } else if (istemplatekind(allow_methods, "*")) {
+               return *;
+       } else if (istemplatekind(allow_methods, "?")) {
+               return ?;
+       }
+       var template Allow ret := {
+               fieldName := ALLOW_E,
+               methods := allow_methods
+       }
+       return ret
+}
+
+template MessageHeader tr_SIP_msgh_std( template CallidString call_id,
+                                       template SipAddr from_addr,
+                                       template SipAddr to_addr,
+                                       template SipAddr contact_addr,
+                                       template charstring method,
+                                       template ContentType content_type := *,
+                                       template integer seq_nr := ?,
+                                       template Method_List allow_methods := *
+                               ) modifies t_SIP_msgHeader_any := {
+       allow := tr_AllowMethods(allow_methods),
+       callId := {
+               fieldName := CALL_ID_E,
+               callid := call_id
+       },
+       contact := tr_Contact(contact_addr),
+       contentType := content_type,
+       cSeq := {
+               fieldName := CSEQ_E,
+               seqNumber := seq_nr,
+               method := method
+       },
+       fromField := {
+               fieldName := FROM_E,
+               addressField := from_addr.addr,
+               fromParams := from_addr.params
+       },
+       toField := {
+               fieldName := TO_E,
+               addressField := to_addr.addr,
+               toParams := to_addr.params
+       },
+       userAgent := *,
+       via := {
+               fieldName := VIA_E,
+               viaBody := {
+                       {
+                               sentProtocol := { "SIP", "2.0", "UDP" },
+                               sentBy := 
tr_HostPort(from_addr.addr.nameAddr.addrSpec.hostPort),
+                               viaParams := *
+                       }
+               }
+       }
+}
+
+
+template (value) PDU_SIP_Request ts_SIP_INVITE( CallidString call_id,
+                                               SipAddr from_addr,
+                                               SipAddr to_addr,
+                                               integer seq_nr,
+                                               template (omit) charstring body
+                                               ) := {
+       requestLine := ts_SIP_ReqLine(INVITE_E, to_addr.addr.nameAddr.addrSpec),
+       msgHeader := ts_SIP_msgh_std(call_id, from_addr, to_addr, from_addr, 
"INVITE", seq_nr,
+                                    ts_Via_from(from_addr), 
f_ContentTypeOrOmit(ts_CT_SDP, body)),
+       messageBody := body,
+       payload := omit
+}
+template PDU_SIP_Request tr_SIP_INVITE( template CallidString call_id,
+                                       template SipAddr from_addr,
+                                       template SipAddr to_addr,
+                                       template integer seq_nr,
+                                       template charstring body
+                                               ) := {
+       requestLine := tr_SIP_ReqLine(INVITE_E, to_addr.addr.nameAddr.addrSpec),
+       msgHeader := tr_SIP_msgh_std(call_id, from_addr, to_addr, ?, "INVITE", 
*, seq_nr),
+       messageBody := body,
+       payload := omit
+}
+
+template (value) PDU_SIP_Request ts_SIP_BYE( CallidString call_id,
+                                            SipAddr from_addr,
+                                            SipAddr to_addr,
+                                            integer seq_nr,
+                                            template (omit) charstring body
+                                               ) := {
+       requestLine := ts_SIP_ReqLine(BYE_E, to_addr.addr.nameAddr.addrSpec),
+       msgHeader := ts_SIP_msgh_std(call_id, from_addr, to_addr, omit, "BYE", 
seq_nr,
+                                    ts_Via_from(from_addr), 
f_ContentTypeOrOmit(ts_CT_SDP, body)),
+       messageBody := body,
+       payload := omit
+}
+
+template PDU_SIP_Request tr_SIP_BYE( template CallidString call_id,
+                                       template SipAddr from_addr,
+                                       template SipAddr to_addr,
+                                       template integer seq_nr,
+                                       template charstring body
+                                               ) := {
+       requestLine := tr_SIP_ReqLine(BYE_E, to_addr.addr.nameAddr.addrSpec),
+       msgHeader := tr_SIP_msgh_std(call_id, from_addr, to_addr, omit, "BYE", 
*, seq_nr),
+       messageBody := body,
+       payload := omit
+}
+
+
+template (value) PDU_SIP_Request ts_SIP_ACK( CallidString call_id,
+                                               SipAddr from_addr,
+                                               SipAddr to_addr,
+                                               integer seq_nr,
+                                               template (omit) charstring body
+                                               ) := {
+       requestLine := ts_SIP_ReqLine(ACK_E, to_addr.addr.nameAddr.addrSpec),
+       msgHeader := ts_SIP_msgh_std(call_id, from_addr, to_addr, from_addr, 
"ACK", seq_nr,
+                                    ts_Via_from(from_addr), 
f_ContentTypeOrOmit(ts_CT_SDP, body)),
+       messageBody := body,
+       payload := omit
+}
+template PDU_SIP_Request tr_SIP_ACK( template CallidString call_id,
+                                    template SipAddr from_addr,
+                                    template SipAddr to_addr,
+                                    template integer seq_nr,
+                                    template charstring body
+                                               ) := {
+       requestLine := tr_SIP_ReqLine(ACK_E, to_addr.addr.nameAddr.addrSpec),
+       msgHeader := tr_SIP_msgh_std(call_id, from_addr, to_addr, *, "ACK", *, 
seq_nr),
+       messageBody := body,
+       payload := omit
+}
+
+
+
+template (value) PDU_SIP_Response ts_SIP_Response( CallidString call_id,
+                                                  SipAddr from_addr,
+                                                  SipAddr to_addr,
+                                                  charstring method,
+                                                  integer status_code,
+                                                  integer seq_nr,
+                                                  charstring reason,
+                                                  Via via,
+                                                  template (omit) charstring 
body := omit
+                                                       ) := {
+       statusLine := ts_SIP_StatusLine(status_code, reason),
+       msgHeader := ts_SIP_msgh_std(call_id, from_addr, to_addr, omit, method, 
seq_nr,
+                                    via, f_ContentTypeOrOmit(ts_CT_SDP, body)),
+       messageBody := body,
+       payload := omit
+}
+
+template PDU_SIP_Response tr_SIP_Response( template CallidString call_id,
+                                          template SipAddr from_addr,
+                                          template SipAddr to_addr,
+                                          template SipAddr contact_addr,
+                                          template charstring method,
+                                          template integer status_code,
+                                          template integer seq_nr := ?,
+                                          template charstring reason := ?,
+                                          template charstring body := ?
+                                               ) := {
+       statusLine := tr_SIP_StatusLine(status_code, reason),
+       msgHeader := tr_SIP_msgh_std(call_id, from_addr, to_addr, contact_addr, 
method, *, seq_nr),
+       messageBody := body,
+       payload := omit
+}
+
+
+
+}
diff --git a/sip/SIP_Tests.cfg b/sip/SIP_Tests.cfg
index db435af..222d3a1 100644
--- a/sip/SIP_Tests.cfg
+++ b/sip/SIP_Tests.cfg
@@ -7,6 +7,8 @@
 # Local configuration below
 
 [LOGGING]
+"SIP_Test-SIP".FileMask := ERROR | WARNING
+"SIP_Test-MNCC".FileMask := ERROR | WARNING
 
 [TESTPORT_PARAMETERS]
 
diff --git a/sip/SIP_Tests.default b/sip/SIP_Tests.default
index b0abf18..5f7de90 100644
--- a/sip/SIP_Tests.default
+++ b/sip/SIP_Tests.default
@@ -13,7 +13,7 @@
 *.SIPVTY.CTRL_DETECT_SERVER_DISCONNECTED := "yes"
 *.SIPVTY.CTRL_READMODE := "buffered"
 *.SIPVTY.CTRL_CLIENT_CLEANUP_LINEFEED := "yes"
-*.SIPVTY.PROMPT1 := "OsmoMNCC> "
+*.SIPVTY.PROMPT1 := "OsmoSIPcon> "
 
 *.SIP.local_sip_port := "5060"
 *.SIP.default_local_address := "127.0.0.2"
@@ -23,7 +23,7 @@
 
 
 [MODULE_PARAMETERS]
-Osmocom_VTY_Functions.mp_prompt_prefix := "OsmoMNCC";
+Osmocom_VTY_Functions.mp_prompt_prefix := "OsmoSIPcon";
 
 [MAIN_CONTROLLER]
 
diff --git a/sip/SIP_Tests.ttcn b/sip/SIP_Tests.ttcn
index de2f498..f690dc7 100644
--- a/sip/SIP_Tests.ttcn
+++ b/sip/SIP_Tests.ttcn
@@ -17,9 +17,10 @@
 
 import from SIP_Emulation all;
 import from SIPmsg_Types all;
+import from SIP_Templates all;
 
 modulepar {
-       //charstring mp_local_host := "127.0.0.2;
+       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";
@@ -38,7 +39,48 @@
 }
 
 type record ConnHdlrPars {
-       float t_guard
+       float t_guard,
+       CallPars g_cp optional
+}
+
+type record CallPars {
+       boolean is_mo,
+       charstring calling,
+       charstring called,
+
+       uint32_t mncc_call_id optional,
+
+       CallParsComputed comp optional
+}
+
+type record CallParsComputed {
+       CallidString sip_call_id,
+       SipAddr sip_url_ext,
+       SipAddr sip_url_gsm,
+       charstring sip_body,
+       integer sip_seq_nr
+}
+
+private template (value) CallPars t_CallPars(boolean is_mo) := {
+       is_mo := is_mo,
+       calling := "12345",
+       called := "98766",
+       mncc_call_id := omit,
+       comp := omit
+}
+
+private function f_CallPars_compute(inout CallPars cp) {
+       if (cp.is_mo) {
+               cp.comp.sip_url_ext := valueof(ts_SipAddr(cp.called, 
mp_local_host, 5060));
+               cp.comp.sip_url_gsm := valueof(ts_SipAddr(cp.calling, 
mp_osmosip_host, 5060));
+               cp.mncc_call_id := f_rnd_int(429496725);
+       } else {
+               cp.comp.sip_url_ext := valueof(ts_SipAddr(cp.calling, 
mp_local_host, 5060));
+               cp.comp.sip_url_gsm := valueof(ts_SipAddr(cp.called, 
mp_osmosip_host, 5060));
+               cp.comp.sip_call_id := hex2str(f_rnd_hexstring(15));
+       }
+       cp.comp.sip_seq_nr := f_rnd_int(4294967295);
+       cp.comp.sip_body := "";
 }
 
 
@@ -105,67 +147,246 @@
 
 
 template (value) ConnHdlrPars t_Pars := {
-       t_guard := 30.0
+       t_guard := 30.0,
+       g_cp := omit
 }
 
-private function f_TC_mo_setup(charstring id) runs on ConnHdlr {
+/* Establish a mobile terminated call described in 'cp' */
+function f_establish_mt(inout CallPars cp) runs on ConnHdlr {
+       var template SipAddr sip_addr_gsm := 
tr_SipAddr_from_val(cp.comp.sip_url_gsm);
+       var template SipAddr sip_addr_ext := 
tr_SipAddr_from_val(cp.comp.sip_url_ext);
        var PDU_SIP_Request sip_req;
+       var MNCC_PDU mncc;
 
-       var MNCC_number dst := valueof(ts_MNCC_number("01234567"));
-       var MNCC_number src := valueof(ts_MNCC_number("112"));
+       /* Ask MNCC_Emulation to "expect" a call to the given called number */
+       f_create_mncc_expect(cp.called);
 
-       f_create_sip_expect(valueof(ts_SIP_Url("+01234567")));
+       /* OSC <- SIP: A party sends SIP invite for a MT-call into OSC */
+       SIP.send(ts_SIP_INVITE(cp.comp.sip_call_id, cp.comp.sip_url_ext, 
cp.comp.sip_url_gsm,
+                               cp.comp.sip_seq_nr, cp.comp.sip_body));
+       /* MSC <- OSC: OSC generates MNCC_SETUP_REQ from INVITE */
+       MNCC.receive(tr_MNCC_SETUP_req) -> value mncc {
+               cp.mncc_call_id := mncc.u.signal.callref;
+               }
+       /* OSC -> SIP */
+       SIP.receive(tr_SIP_Response(cp.comp.sip_call_id, sip_addr_ext, 
sip_addr_gsm, *,
+                                   "INVITE", 100, ?, "Trying", *));
 
-       log("sending mncc setup");
-       MNCC.send(ts_MNCC_SETUP_ind(2342, dst, src, "262420123456789"));
+       /* MSC -> OSC: After MS sends CALL CONF in response to SETUP */
+       MNCC.send(ts_MNCC_CALL_CONF_ind(cp.mncc_call_id));
+       /* MSC <- OSC: OSC asks MSC to create RTP socket */
+       MNCC.receive(tr_MNCC_RTP_CREATE(cp.mncc_call_id));
+       MNCC.send(ts_MNCC_RTP_CREATE(cp.mncc_call_id));
 
-       MNCC.receive(tr_MNCC_RTP_CREATE(2342));
-       MNCC.send(ts_MNCC_RTP_CREATE(2342));
+       /* MSC -> OSC: After MS is ringing and sent CC ALERTING */
+       MNCC.send(ts_MNCC_ALERT_ind(cp.mncc_call_id));
+       SIP.clear;
+       SIP.receive(tr_SIP_Response(cp.comp.sip_call_id, sip_addr_ext, 
sip_addr_gsm, *,
+                                   "INVITE", 180, ?, "Ringing", *));
 
-       SIP.receive(PDU_SIP_Request:?) -> value sip_req {
-               log(sip_req);
+       /* MSC -> OSC: After MT user has picked up and sent CC CONNECT */
+       MNCC.send(ts_MNCC_SETUP_CNF(cp.mncc_call_id));
+
+       SIP.clear;
+       interleave {
+       /* MSC <- OSC: OSC asks MSC to connect its RTP stream to remote end */
+       [] MNCC.receive(tr_MNCC_RTP_CONNECT(cp.mncc_call_id)) {}
+       /* OSC -> SIP: OSC confirms call establishment to SIP side */
+       [] SIP.receive(tr_SIP_Response(cp.comp.sip_call_id, sip_addr_ext, 
sip_addr_gsm, ?,
+                                       "INVITE", 200, ?, "OK", ?)) {}
        }
+       /* OSC <- SIP: SIP world acknowledges "200 OK" */
+       SIP.send(ts_SIP_ACK(cp.comp.sip_call_id, cp.comp.sip_url_ext, 
cp.comp.sip_url_gsm,
+                           cp.comp.sip_seq_nr, omit));
+       /* MSC <- OSC: OSC sends SETUP COMPL to MNCC (which triggers CC CONNECT 
ACK */
+       MNCC.receive(tr_MNCC_SETUP_COMPL_req(cp.mncc_call_id));
 }
 
-testcase TC_mo_setup() runs on test_CT {
+/* Establish a mobile originated call described in 'cp' */
+function f_establish_mo(inout CallPars cp) runs on ConnHdlr {
+       var MNCC_number dst := valueof(ts_MNCC_number(cp.called, 
GSM48_TON_UNKNOWN));
+       var MNCC_number src := valueof(ts_MNCC_number(cp.calling, 
GSM48_TON_UNKNOWN));
+       var template SipAddr sip_addr_gsm := 
tr_SipAddr_from_val(cp.comp.sip_url_gsm);
+       var template SipAddr sip_addr_ext := 
tr_SipAddr_from_val(cp.comp.sip_url_ext);
+       var PDU_SIP_Request sip_req;
+       var integer seq_nr;
+
+       f_create_sip_expect(cp.comp.sip_url_ext.addr.nameAddr.addrSpec);
+
+       /* MSC -> OSC: MSC sends SETUP.ind after CC SETUP was received from MS 
*/
+       MNCC.send(ts_MNCC_SETUP_ind(cp.mncc_call_id, dst, src, 
"262420123456789"));
+       /* MSC <- OSC: Create GSM side RTP socket */
+       MNCC.receive(tr_MNCC_RTP_CREATE(cp.mncc_call_id)) {
+               var MNCC_PDU mncc := 
valueof(ts_MNCC_RTP_CREATE(cp.mncc_call_id));
+               mncc.u.rtp.payload_msg_type := oct2int('0300'O);
+               MNCC.send(mncc);        /* FIXME: port/ip */
+               }
+       /* OSC -> SIP: Send INVITE with GSM side IP/Port in SDP */
+       SIP.receive(tr_SIP_INVITE(?, sip_addr_gsm, sip_addr_ext, ?, ?)) -> 
value sip_req {
+               cp.comp.sip_url_gsm.params := 
sip_req.msgHeader.fromField.fromParams;
+               cp.comp.sip_call_id := sip_req.msgHeader.callId.callid;
+               seq_nr := sip_req.msgHeader.cSeq.seqNumber;
+               }
+       /* OSC <- SIP: Notify call is proceeding */
+       SIP.send(ts_SIP_Response(cp.comp.sip_call_id, cp.comp.sip_url_gsm, 
cp.comp.sip_url_ext,
+                                "INVITE", 100, seq_nr, "Trying", 
sip_req.msgHeader.via));
+       /* MSC <- OSC: "100 Trying" translated to MNCC_CALL_PROC_REQ */
+       MNCC.receive(tr_MNCC_CALL_PROC_req(cp.mncc_call_id));
+
+       /* OSC <- SIP: SIP-terminated user is ringing now */
+       SIP.send(ts_SIP_Response(cp.comp.sip_call_id, cp.comp.sip_url_gsm, 
cp.comp.sip_url_ext,
+                                "INVITE", 180, seq_nr, "Ringing", 
sip_req.msgHeader.via));
+
+       /* MSC <- OSC: "180 Ringing" translated to MNCC_ALERT_REQ */
+       MNCC.receive(tr_MNCC_ALERT_req(cp.mncc_call_id)) {}
+
+       /* OSC <- SIP: SIP-terminated user has accepted the call */
+       SIP.send(ts_SIP_Response(cp.comp.sip_call_id, cp.comp.sip_url_gsm, 
cp.comp.sip_url_ext,
+                                "INVITE", 200, seq_nr, "OK", 
sip_req.msgHeader.via,
+                                cp.comp.sip_body));
+       MNCC.receive(tr_MNCC_RTP_CONNECT(cp.mncc_call_id));
+       /* MSC <- OSC: "200 OK" translated to MNCC_SETUP_RSP */
+       MNCC.receive(tr_MNCC_SETUP_rsp(cp.mncc_call_id));
+
+       /* MSC -> OSC: CC CONNECT ACK was received from MS */
+       MNCC.send(ts_MNCC_SETUP_COMPL_ind(cp.mncc_call_id));
+       /* OSC -> SIP: Acknowledge the call */
+       SIP.receive(tr_SIP_ACK(cp.comp.sip_call_id, sip_addr_gsm, sip_addr_ext, 
?, omit));
+}
+
+/* Release call from the mobile side */
+function f_release_mobile(inout CallPars cp) runs on ConnHdlr {
+       var template SipAddr sip_addr_gsm := 
tr_SipAddr_from_val(cp.comp.sip_url_gsm);
+       var template SipAddr sip_addr_ext := 
tr_SipAddr_from_val(cp.comp.sip_url_ext);
+       var PDU_SIP_Request sip_req;
+       SIP.clear;
+       /* MSC -> OSC: Simulate a CC DISCONNET from the MT user */
+       MNCC.send(ts_MNCC_DISC_ind(cp.mncc_call_id, ts_MNCC_cause(0)));
+       /* OSC -> SIP: Expect BYE from OSC to SIP side */
+       SIP.receive(tr_SIP_BYE(cp.comp.sip_call_id, sip_addr_gsm, sip_addr_ext, 
?, *)) -> value sip_req {
+               cp.comp.sip_url_gsm.params := 
sip_req.msgHeader.fromField.fromParams;
+       }
+       /* OSC <- SIP: Acknowledge the BYE */
+       SIP.send(ts_SIP_Response(cp.comp.sip_call_id, cp.comp.sip_url_gsm, 
cp.comp.sip_url_ext,
+                                        "BYE", 200, 
sip_req.msgHeader.cSeq.seqNumber, "OK",
+                                        sip_req.msgHeader.via));
+       /* MSC <- OSC: Send REL_REQ to MSC, triggers CC RELEASE REQ to MS */
+       MNCC.receive(tr_MNCC_REL_req(cp.mncc_call_id)); // CAUSE?
+       /* MSC -> OSC: MS has responded with CC CLEAR COMPL, triggers 
MNCC_REL_CNF */
+       MNCC.send(ts_MNCC_REL_cnf(cp.mncc_call_id, ts_MNCC_cause(0)));
+}
+
+/* Release call from the SIP side */
+function f_release_sip(inout CallPars cp) runs on ConnHdlr {
+       var template SipAddr sip_addr_gsm := 
tr_SipAddr_from_val(cp.comp.sip_url_gsm);
+       var template SipAddr sip_addr_ext := 
tr_SipAddr_from_val(cp.comp.sip_url_ext);
+       /* OSC <- SIP: SIP-side sends a BYE to OSC */
+       SIP.send(ts_SIP_BYE(cp.comp.sip_call_id, cp.comp.sip_url_ext, 
cp.comp.sip_url_gsm,
+                           cp.comp.sip_seq_nr, omit));
+       /* MSC <- OSC: Expect OSC to cause MNCC Disconnect Request */
+       MNCC.receive(tr_MNCC_DISC_req(cp.mncc_call_id));
+       /* MSC -> OSC: Indicate GSM side release */
+       MNCC.send(ts_MNCC_REL_ind(cp.mncc_call_id, ts_MNCC_cause(0)));
+       /* OSC -> SIP: Confirmation to SIP side */
+       SIP.receive(tr_SIP_Response(cp.comp.sip_call_id, sip_addr_ext, 
sip_addr_gsm, *,
+                                   "BYE", 200, cp.comp.sip_seq_nr, "OK", 
omit));
+}
+
+/* Successful MT Call, which is subsequently released by GSM side */
+private function f_TC_mt_success_rel_gsm(charstring id) runs on ConnHdlr {
+       var CallPars cp := valueof(t_CallPars(false));
+       f_CallPars_compute(cp);
+       cp.comp.sip_body := "v=0\r\no=Osmocom 0 0 IN IP4 0.0.0.0\r\ns=GSM 
Call\r\nc=IN IP4 0.0.0.0\r\nt=0 0\r\nm=audio 0 RTP/AVP 0\r\na=rtpmap:0 
GSM/8000\r\n";
+       f_sleep(3.0)
+
+       f_establish_mt(cp);
+       /* now call is fully established */
+       f_sleep(2.0);
+       f_release_mobile(cp);
+       setverdict(pass);
+}
+testcase TC_mt_success_rel_gsm() 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 := f_start_handler(refers(f_TC_mt_success_rel_gsm), pars);
+       vc_conn.done;
+}
+
+/* Successful MT Call, which is subsequently released by SIP side */
+private function f_TC_mt_success_rel_sip(charstring id) runs on ConnHdlr {
+       var CallPars cp := valueof(t_CallPars(false));
+       f_CallPars_compute(cp);
+       cp.comp.sip_body := "v=0\r\no=Osmocom 0 0 IN IP4 0.0.0.0\r\ns=GSM 
Call\r\nc=IN IP4 0.0.0.0\r\nt=0 0\r\nm=audio 0 RTP/AVP 0\r\na=rtpmap:0 
GSM/8000\r\n";
+       f_sleep(3.0)
+
+       f_establish_mt(cp);
+       /* now call is fully established */
+       f_sleep(2.0);
+       f_release_sip(cp);
+       setverdict(pass);
+}
+testcase TC_mt_success_rel_sip() 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_mt_success_rel_sip), pars);
        vc_conn.done;
 }
 
 
+/* Successful MO Call, which is subsequently released by GSM side */
+private function f_TC_mo_success_rel_gsm(charstring id) runs on ConnHdlr {
+       var CallPars cp := valueof(t_CallPars(true));
+       f_CallPars_compute(cp);
+       cp.comp.sip_body := "v=0\r\no=Osmocom 0 0 IN IP4 0.0.0.0\r\ns=GSM 
Call\r\nc=IN IP4 0.0.0.0\r\nt=0 0\r\nm=audio 0 RTP/AVP 0\r\na=rtpmap:0 
GSM/8000\r\n";
+       f_sleep(3.0)
 
-
-
-/* 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
+       f_establish_mo(cp);
+       /* now call is fully established */
+       f_sleep(2.0);
+       f_release_mobile(cp);
+       setverdict(pass);
+}
+testcase TC_mo_success_rel_gsm() 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_success_rel_gsm), pars);
+       vc_conn.done;
 }
 
-template (value) ASP_SIP_open ts_SIP_open(SIP_comm_adress addr) := {
-       addr := addr
-}
+/* Successful MO Call, which is subsequently released by SIP side */
+private function f_TC_mo_success_rel_sip(charstring id) runs on ConnHdlr {
+       var CallPars cp := valueof(t_CallPars(true));
+       f_CallPars_compute(cp);
+       cp.comp.sip_body := "v=0\r\no=Osmocom 0 0 IN IP4 0.0.0.0\r\ns=GSM 
Call\r\nc=IN IP4 0.0.0.0\r\nt=0 0\r\nm=audio 0 RTP/AVP 0\r\na=rtpmap:0 
GSM/8000\r\n";
+       f_sleep(3.0)
 
+       f_establish_mo(cp);
+       /* now call is fully established */
+       f_sleep(2.0);
+       f_release_sip(cp);
+       setverdict(pass);
+}
+testcase TC_mo_success_rel_sip() 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_success_rel_sip), pars);
+       vc_conn.done;
+}
 
 
 control {
-       execute( TC_mo_setup() );
+       execute( TC_mt_success_rel_gsm() );
+       execute( TC_mt_success_rel_sip() );
+       execute( TC_mo_success_rel_gsm() );
+       execute( TC_mo_success_rel_sip() );
 }
 
 
diff --git a/sip/gen_links.sh b/sip/gen_links.sh
index ff64056..37c0a70 100755
--- a/sip/gen_links.sh
+++ b/sip/gen_links.sh
@@ -43,7 +43,7 @@
 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 "
+FILES+="SIP_Emulation.ttcn SIP_Templates.ttcn "
 gen_links $DIR $FILES
 
 ignore_pp_results

-- 
To view, visit https://gerrit.osmocom.org/7466
To unsubscribe, visit https://gerrit.osmocom.org/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I34a5d7929264c7f5f21d3868a5f919874ffa106c
Gerrit-PatchSet: 2
Gerrit-Project: osmo-ttcn3-hacks
Gerrit-Branch: master
Gerrit-Owner: Harald Welte <lafo...@gnumonks.org>
Gerrit-Reviewer: Harald Welte <lafo...@gnumonks.org>
Gerrit-Reviewer: Jenkins Builder

Reply via email to