Change-Id: I34a5d7929264c7f5f21d3868a5f919874ffa106cchanges/66/7466/2
parent
9093839329
commit
b0d9360aac
@ -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 |
||||
} |
||||
|
||||
|
||||
|
||||
} |
Loading…
Reference in new issue