osmo-ttcn3-hacks/library/SIP_Templates.ttcn

414 lines
11 KiB
Plaintext

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
}
}