SIP_Templates: Rework templates to make them more extensible

The existing template system in SIP_Templates made it difficult to craft
specific templates, since it was usually skipping several layers of
fields when passing parameters.

This commit reworks some of those templates, adds news templates, and
cleans formatting for others, as a preparation for further work which
will be done when adding Asterisk_Tests testsuite.

Change-Id: Ifd14213e9c2b8f5061f828a63ef47844828d94ea
This commit is contained in:
Pau Espin 2024-03-28 20:21:38 +01:00 committed by pespin
parent 6052a342fe
commit fb34d863c3
2 changed files with 312 additions and 192 deletions

View File

@ -11,59 +11,142 @@ type record SipAddr {
const charstring c_SIP_VERSION := "SIP/2.0";
template (value) SipUrl ts_SipUrl(charstring user_or_tel, charstring host, integer portnr) := {
template (value) SipUrl ts_SipUrl(template (value) HostPort host_port,
template (omit) UserInfo user_info := omit) := {
scheme := "sip",
userInfo := {
userOrTelephoneSubscriber := user_or_tel,
password := omit
},
hostPort := {
host := host,
portField := portnr
},
userInfo := user_info,
hostPort := host_port,
urlParameters := omit,
headers := omit
}
template SipUrl tr_SipUrl(template charstring user_or_tel,
template charstring host,
template integer portnr) := {
template (present) SipUrl tr_SipUrl(template (present) HostPort host_port := ?,
template UserInfo user_info := *) := {
scheme := "sip",
userInfo := {
userOrTelephoneSubscriber := user_or_tel,
password := *
},
hostPort := {
host := host,
portField := portnr
},
userInfo := user_info,
hostPort := host_port,
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 (value) SipUrl ts_SipUrlHost(template (value) charstring host)
:= ts_SipUrl(ts_HostPort(host));
// [20.10]
template (present) NameAddr tr_NameAddr(template (present) SipUrl addrSpec := ?,
template charstring displayName := *) := {
displayName := displayName,
addrSpec := addrSpec
}
template SipAddr tr_SipAddr(template charstring user_or_tel,
template charstring host,
template integer portnr) := {
template (value) NameAddr ts_NameAddr(template (value) SipUrl addrSpec,
template (omit) charstring displayName := omit) := {
displayName := displayName,
addrSpec := addrSpec
}
template (present) Addr_Union tr_Addr_Union_NameAddr(template (present) NameAddr nameAddr := ?) := {
nameAddr := nameAddr
}
template (value) Addr_Union ts_Addr_Union_NameAddr(template (value) NameAddr nameAddr) := {
nameAddr := nameAddr
}
template (present) Addr_Union tr_Addr_Union_SipUrl(template (present) SipUrl sipUrl := ?) := {
addrSpecUnion := sipUrl
}
template (value) Addr_Union ts_Addr_Union_SipUrl(template (value) SipUrl sipUrl) := {
addrSpecUnion := sipUrl
}
template (present) ContactAddress tr_ContactAddress(template (present) Addr_Union addressField := ?,
template SemicolonParam_List contactParams := *) := {
addressField := addressField,
contactParams := contactParams
}
template (value) ContactAddress ts_ContactAddress(template (value) Addr_Union addressField,
template (omit) SemicolonParam_List contactParams := omit) := {
addressField := addressField,
contactParams := contactParams
}
template (present) Contact tr_Contact(template (present) ContactAddress_List contactAddresses := ?) := {
fieldName := CONTACT_E,
contactBody := {
contactAddresses := contactAddresses
}
}
template (value) Contact ts_Contact(template (value) ContactAddress_List contactAddresses) := {
fieldName := CONTACT_E,
contactBody := {
contactAddresses := contactAddresses
}
}
template (value) Contact ts_ContactWildcard := {
fieldName := CONTACT_E,
contactBody := {
wildcard := "*"
}
}
template (present) Contact tr_Contact_SipAddr(template (present) SipAddr contact_addr := ?)
:= tr_Contact({ tr_ContactAddress(contact_addr.addr, contact_addr.params) });
private function f_tr_Contact_SipAddr(template SipAddr contact_addr) return template Contact
{
if (istemplatekind(contact_addr, "omit")) {
return omit;
} else if (istemplatekind(contact_addr, "*")) {
return *;
}
return tr_Contact_SipAddr(contact_addr);
}
template (value) Contact ts_Contact_SipAddr(template (value) SipAddr contact_addr)
:= ts_Contact({ ts_ContactAddress(contact_addr.addr, contact_addr.params) });
private function ts_Contact_SipAddr_omit(template (omit) SipAddr contact_addr := omit) return template (omit) Contact
{
if (istemplatekind(contact_addr, "omit")) {
return omit;
}
return ts_Contact_SipAddr(contact_addr);
}
// [20.19]
template (value) Expires ts_Expires(template (value) DeltaSec deltaSec := "7200") := {
fieldName := EXPIRES_E,
deltaSec := deltaSec
}
template (value) SipAddr ts_SipAddr(template (value) HostPort host_port,
template (omit) UserInfo user_info := omit,
template (omit) charstring displayName := omit,
template (omit) SemicolonParam_List params := omit) := {
addr := {
nameAddr := {
displayName := *,
addrSpec := tr_SipUrl(user_or_tel, host, portnr)
displayName := displayName,
addrSpec := ts_SipUrl(host_port, user_info)
}
},
params := *
params := params
}
template (present) SipAddr tr_SipAddr(template (present) HostPort host_port := ?,
template UserInfo user_info := *,
template charstring displayName := *,
template SemicolonParam_List params := *) := {
addr := {
nameAddr := {
displayName := displayName,
addrSpec := tr_SipUrl(host_port, user_info)
}
},
params := 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;
function tr_SipAddr_from_val(SipAddr tin) return template (present) SipAddr {
var template (present) SipAddr ret := tin;
if (tin.addr.nameAddr.displayName == omit) {
ret.addr.nameAddr.displayName := *;
}
@ -76,7 +159,11 @@ function tr_SipAddr_from_val(SipAddr tin) return template SipAddr {
return ret;
}
template (value) HostPort ts_HostPort(template (omit) charstring host := omit,
template (omit) integer portField := omit) := {
host := host,
portField := portField
}
function tr_HostPort(template HostPort hp) return template HostPort {
var template HostPort hpout := hp;
/* if the port number is 5060, it may be omitted */
@ -86,15 +173,28 @@ function tr_HostPort(template HostPort hp) return template HostPort {
return hpout;
}
template (value) RequestLine ts_SIP_ReqLine(Method method, template (value) SipUrl uri,
template (value) UserInfo ts_UserInfo(template (value) charstring userOrTelephoneSubscriber,
template (omit) charstring password := omit) := {
userOrTelephoneSubscriber := userOrTelephoneSubscriber,
password := password
}
template (present) UserInfo tr_UserInfo(template (present) charstring userOrTelephoneSubscriber := ?,
template charstring password := *) := {
userOrTelephoneSubscriber := userOrTelephoneSubscriber,
password := password
}
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) := {
template (present) RequestLine tr_SIP_ReqLine(template (present) Method method := ?,
template (present) SipUrl uri := ?,
template (present) charstring ver := c_SIP_VERSION) := {
method := method,
requestUri := uri,
sipVersion := ver
@ -105,7 +205,8 @@ template (value) StatusLine ts_SIP_StatusLine(integer status_code, charstring re
statusCode := status_code,
reasonPhrase := reason
}
template StatusLine tr_SIP_StatusLine(template integer status_code, template charstring reason) := {
template (present) StatusLine tr_SIP_StatusLine(template integer status_code,
template charstring reason) := {
sipVersion := "SIP/2.0",
statusCode := status_code,
reasonPhrase := reason
@ -141,28 +242,41 @@ template (value) ContentType ts_CT_SDP := {
mediaType := "application/sdp"
};
template (value) Via ts_Via_from(SipAddr from_addr) := {
template (value) Via ts_Via_from(template (value) HostPort addr) := {
fieldName := VIA_E,
viaBody := {
{
sentProtocol := { "SIP", "2.0", "UDP" },
sentBy := from_addr.addr.nameAddr.addrSpec.hostPort,
sentBy := addr,
viaParams := omit
}
}
}
template (present) Via tr_Via_from(template (present) HostPort host_port := ?,
template SemicolonParam_List viaParams := *) := {
fieldName := VIA_E,
viaBody := {
{
sentProtocol := { "SIP", "2.0", "UDP" },
sentBy := host_port,
viaParams := viaParams
}
}
}
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 := {
template (value) MessageHeader ts_SIP_msgHeader_empty := c_SIP_msgHeader_empty;
template (value) MessageHeader
ts_SIP_msgh_std(template (value) CallidString call_id,
template (value) SipAddr from_addr,
template (value) SipAddr to_addr,
template (omit) Contact contact,
template (value) charstring method,
template (value) integer seq_nr,
template (value) Via via,
template (omit) ContentType content_type := omit,
template (value) Method_List allow_methods := c_SIP_defaultMethods,
template (omit) Expires expires := omit
) modifies ts_SIP_msgHeader_empty := {
allow := {
fieldName := ALLOW_E,
methods := allow_methods
@ -171,13 +285,14 @@ template (value) MessageHeader ts_SIP_msgh_std( CallidString call_id,
fieldName := CALL_ID_E,
callid := call_id
},
contact := ts_Contact(contact_addr),
contact := contact,
contentType := content_type,
cSeq := {
fieldName := CSEQ_E,
seqNumber := seq_nr,
method := method
},
expires := expires,
fromField := {
fieldName := FROM_E,
addressField := from_addr.addr,
@ -197,49 +312,6 @@ template (value) MessageHeader ts_SIP_msgh_std( CallidString call_id,
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;
@ -248,34 +320,38 @@ function tr_AllowMethods(template Method_List allow_methods) return template All
} else if (istemplatekind(allow_methods, "?")) {
return ?;
}
var template Allow ret := {
var template (present) 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 := {
template (present) MessageHeader
tr_SIP_msgh_std(template CallidString call_id,
template SipAddr from_addr,
template SipAddr to_addr,
template Contact contact,
template (present) Via via := tr_Via_from(?),
template charstring method,
template ContentType content_type := *,
template integer seq_nr := ?,
template Method_List allow_methods := *,
template Expires expires := *
) modifies t_SIP_msgHeader_any := {
allow := tr_AllowMethods(allow_methods),
callId := {
fieldName := CALL_ID_E,
callid := call_id
},
contact := tr_Contact(contact_addr),
contact := contact,
contentType := content_type,
cSeq := {
fieldName := CSEQ_E,
seqNumber := seq_nr,
method := method
},
expires := expires,
fromField := {
fieldName := FROM_E,
addressField := from_addr.addr,
@ -287,105 +363,143 @@ template MessageHeader tr_SIP_msgh_std( template CallidString call_id,
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 := *
}
}
}
via := via
}
template (value) PDU_SIP_Request ts_SIP_INVITE( CallidString call_id,
SipAddr from_addr,
SipAddr to_addr,
integer seq_nr,
template (omit) charstring body
) := {
template (value) PDU_SIP_Request
ts_SIP_REGISTER(template (value) SipUrl sip_url_host_port,
template (value) CallidString call_id,
template (value) SipAddr from_addr,
template (value) SipAddr to_addr,
template (value) Via via,
integer seq_nr,
template (omit) Contact contact,
template (omit) Expires expires,
template (omit) charstring body := omit) := {
requestLine := ts_SIP_ReqLine(REGISTER_E, sip_url_host_port),
msgHeader := ts_SIP_msgh_std(call_id, from_addr, to_addr, contact,
"REGISTER", seq_nr, via,
f_ContentTypeOrOmit(ts_CT_SDP, body),
expires := expires),
messageBody := body,
payload := omit
}
template (present) PDU_SIP_Request
tr_SIP_REGISTER(template (present) SipUrl sip_url_host_port := ?,
template (present) CallidString call_id := ?,
template (present) SipAddr from_addr := ?,
template (present) SipAddr to_addr := ?,
template integer seq_nr := *,
template Contact contact := *,
template Expires expires := *,
template charstring body := *) := {
requestLine := tr_SIP_ReqLine(REGISTER_E, sip_url_host_port),
msgHeader := tr_SIP_msgh_std(call_id, from_addr, to_addr, contact,
tr_Via_from(tr_HostPort(from_addr.addr.nameAddr.addrSpec.hostPort)),
"INVITE", *, seq_nr,
expires := expires),
messageBody := body,
payload := omit
}
template (value) PDU_SIP_Request
ts_SIP_INVITE(CallidString call_id,
SipAddr from_addr,
SipAddr to_addr,
integer seq_nr,
template (omit) charstring body := omit) := {
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)),
msgHeader := ts_SIP_msgh_std(call_id, from_addr, to_addr,
ts_Contact_SipAddr(from_addr),
"INVITE", seq_nr,
ts_Via_from(from_addr.addr.nameAddr.addrSpec.hostPort),
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
) := {
template (present) 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),
msgHeader := tr_SIP_msgh_std(call_id, from_addr, to_addr, ?,
tr_Via_from(tr_HostPort(from_addr.addr.nameAddr.addrSpec.hostPort)),
"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
) := {
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)),
ts_Via_from(from_addr.addr.nameAddr.addrSpec.hostPort),
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
) := {
template (present) 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),
msgHeader := tr_SIP_msgh_std(call_id, from_addr, to_addr, omit,
tr_Via_from(tr_HostPort(from_addr.addr.nameAddr.addrSpec.hostPort)),
"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
) := {
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)),
msgHeader := ts_SIP_msgh_std(call_id, from_addr, to_addr,
ts_Contact_SipAddr(from_addr),
"ACK", seq_nr,
ts_Via_from(from_addr.addr.nameAddr.addrSpec.hostPort),
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
) := {
template (present) 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),
msgHeader := tr_SIP_msgh_std(call_id, from_addr, to_addr, *,
tr_Via_from(tr_HostPort(from_addr.addr.nameAddr.addrSpec.hostPort)),
"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
) := {
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)),
@ -393,18 +507,20 @@ template (value) PDU_SIP_Response ts_SIP_Response( CallidString call_id,
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 := ?
) := {
template (present) PDU_SIP_Response
tr_SIP_Response(template CallidString call_id,
template SipAddr from_addr,
template SipAddr to_addr,
template Contact contact,
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),
msgHeader := tr_SIP_msgh_std(call_id, from_addr, to_addr, contact,
tr_Via_from(tr_HostPort(from_addr.addr.nameAddr.addrSpec.hostPort)),
method, *, seq_nr),
messageBody := body,
payload := omit
}

View File

@ -99,12 +99,16 @@ private template (value) CallPars t_CallPars(boolean is_mo, boolean mncc_with_sd
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.comp.sip_url_ext := valueof(ts_SipAddr(ts_HostPort(mp_local_host, 5060),
ts_UserInfo(cp.called)));
cp.comp.sip_url_gsm := valueof(ts_SipAddr(ts_HostPort(mp_osmosip_host, 5060),
ts_UserInfo(cp.calling)));
cp.mncc_call_id := f_sip_rand_seq_nr();
} 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_url_ext := valueof(ts_SipAddr(ts_HostPort(mp_local_host, 5060),
ts_UserInfo(cp.calling)));
cp.comp.sip_url_gsm := valueof(ts_SipAddr(ts_HostPort(mp_osmosip_host, 5060),
ts_UserInfo(cp.called)));
cp.comp.sip_call_id := hex2str(f_rnd_hexstring(15));
}
cp.comp.sip_seq_nr := f_sip_rand_seq_nr();
@ -338,7 +342,7 @@ function f_establish_mt(inout CallPars cp) runs on ConnHdlr {
}
/* OSC -> SIP: OSC confirms call establishment to SIP side */
as_SIP_expect_resp(tr_SIP_Response(cp.comp.sip_call_id, sip_addr_ext, sip_addr_gsm, contact_addr := ?,
as_SIP_expect_resp(tr_SIP_Response(cp.comp.sip_call_id, sip_addr_ext, sip_addr_gsm, contact := ?,
method := "INVITE", status_code := 200,
seq_nr := ?, reason := "OK",
body := expect_sdp_to_sip));