blob: 72a4426398431418e0c746a7b11546a9cdf9d51f [file] [log] [blame]
Harald Welteb0d93602018-03-20 18:09:34 +01001module SIP_Templates {
2
3import from SIPmsg_Types all;
Pau Espin Pedrol05eaa1a2024-04-02 12:56:26 +02004import from TCCConversion_Functions all;
5import from TCCOpenSecurity_Functions all;
Pau Espin Pedrol95ad6a02024-04-18 16:52:46 +02006import from TCCDateTime_Functions all;
Pau Espin Pedrol05eaa1a2024-04-02 12:56:26 +02007import from Native_Functions all;
Pau Espin Pedrol6052a342024-03-28 20:20:46 +01008import from Osmocom_Types all;
Pau Espin Pedrol05eaa1a2024-04-02 12:56:26 +02009import from Misc_Helpers all;
Harald Welteb0d93602018-03-20 18:09:34 +010010
11/* wrapper type to encapsulate the Addr_Union + parameter list used in From, To. ... */
12type record SipAddr {
13 Addr_Union addr,
14 SemicolonParam_List params optional
15}
16
17const charstring c_SIP_VERSION := "SIP/2.0";
18
Pau Espin Pedrol05eaa1a2024-04-02 12:56:26 +020019template (value) GenericParam ts_Param(template (value) charstring id,
20 template (omit) charstring paramValue := omit) := {
21 id := id,
22 paramValue := paramValue
23}
24template (present) GenericParam tr_Param(template (present) charstring id := ?,
25 template charstring paramValue := *) := {
26 id := id,
27 paramValue := paramValue
28}
29function f_ts_Param_omit(template (value) charstring id,
30 template (omit) charstring paramValue := omit)
31 return template (omit) GenericParam
32{
33 if (istemplatekind(paramValue, "omit")) {
34 return omit;
35 }
36 return ts_Param(id, paramValue);
37}
38
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +010039template (value) SipUrl ts_SipUrl(template (value) HostPort host_port,
Pau Espin Pedrol4e6672c2024-05-22 17:03:53 +020040 template (omit) UserInfo user_info := omit,
41 template (value) charstring scheme := "sip") := {
42 scheme := scheme,
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +010043 userInfo := user_info,
44 hostPort := host_port,
Harald Welteb0d93602018-03-20 18:09:34 +010045 urlParameters := omit,
46 headers := omit
47}
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +010048template (present) SipUrl tr_SipUrl(template (present) HostPort host_port := ?,
Pau Espin Pedrol4e6672c2024-05-22 17:03:53 +020049 template UserInfo user_info := *,
50 template (present) charstring scheme := "sip") := {
51 scheme := scheme,
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +010052 userInfo := user_info,
53 hostPort := host_port,
Harald Welteb0d93602018-03-20 18:09:34 +010054 urlParameters := *,
55 headers := *
56}
57
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +020058template (value) SipUrl ts_SipUrlHost(template (value) charstring host,
Pau Espin Pedrol4e6672c2024-05-22 17:03:53 +020059 template (omit) integer portField := omit,
60 template (value) charstring scheme := "sip")
61 := ts_SipUrl(ts_HostPort(host, portField), scheme := scheme);
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +020062
63function ts_SipUrl_from_Addr_Union(template (value) Addr_Union au)
64return template (value) SipUrl {
65 if (ischosen(au.nameAddr)) {
66 return au.nameAddr.addrSpec;
67 } else { /* au.addrSpecUnion */
68 return au.addrSpecUnion;
69 }
70}
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +010071
Pau Espin Pedrolcb3a15b2024-05-13 16:25:11 +020072// [20.5]
73template (present) Allow tr_Allow(template Method_List methods := *) := {
74 fieldName := ALLOW_E,
75 methods := methods
76}
77template (value) Allow ts_Allow(template (omit) Method_List methods := omit) := {
78 fieldName := ALLOW_E,
79 methods := methods
80}
81
Pau Espin Pedrola674d612024-05-14 19:56:33 +020082template (present) Credentials tr_Credentials_DigestResponse(template (present) CommaParam_List digestResponse) := {
83 digestResponse := digestResponse
84}
Pau Espin Pedrol05eaa1a2024-04-02 12:56:26 +020085template (value) Credentials ts_Credentials_DigestResponse(template (value) CommaParam_List digestResponse) := {
86 digestResponse := digestResponse
87}
88
89template (value) Credentials ts_Credentials_DigestResponseMD5(
90 template (value) charstring username,
91 template (value) charstring realm,
92 template (value) charstring nonce,
93 template (value) charstring uri,
94 template (value) charstring response,
95 template (value) charstring opaque,
96 template (value) charstring algorithm := "MD5",
97 template (value) charstring qop := "auth",
98 template (omit) charstring cnonce := omit,
99 template (omit) charstring nc := omit
100 ) := {
101 digestResponse := {
102 // Already added by digestResponse automatically:
103 //ts_Param("Digest", omit),
104 ts_Param("username", f_sip_str_quote(username)),
105 ts_Param("realm", f_sip_str_quote(realm)),
106 ts_Param("nonce", f_sip_str_quote(nonce)),
107 ts_Param("uri", f_sip_str_quote(uri)),
108 ts_Param("response", f_sip_str_quote(response)),
109 ts_Param("opaque", f_sip_str_quote(opaque)),
110 ts_Param("algorithm", algorithm),
111 ts_Param("qop", qop),
112 // FIXME: If "omit" is passed, these below end up in;
113 // "Dynamic test case error: Performing a valueof or send operation on a non-specific template of type @SIPmsg_Types.GenericParam"
114 f_ts_Param_omit("cnonce", f_sip_str_quote(cnonce)),
115 f_ts_Param_omit("nc", nc)
116 }
117}
118
119template (value) Credentials ts_Credentials_OtherAuth(template (value) OtherAuth otherResponse) := {
120 otherResponse := otherResponse
121}
122
Pau Espin Pedrola674d612024-05-14 19:56:33 +0200123template (present) Authorization tr_Authorization(template (present) Credentials body) := {
124 fieldName := AUTHORIZATION_E,
125 body := body
126}
Pau Espin Pedrol05eaa1a2024-04-02 12:56:26 +0200127template (value) Authorization ts_Authorization(template (value) Credentials body) := {
128 fieldName := AUTHORIZATION_E,
129 body := body
130}
131
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100132// [20.10]
133template (present) NameAddr tr_NameAddr(template (present) SipUrl addrSpec := ?,
134 template charstring displayName := *) := {
135 displayName := displayName,
136 addrSpec := addrSpec
Harald Welteb0d93602018-03-20 18:09:34 +0100137}
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100138template (value) NameAddr ts_NameAddr(template (value) SipUrl addrSpec,
139 template (omit) charstring displayName := omit) := {
140 displayName := displayName,
141 addrSpec := addrSpec
142}
143
144template (present) Addr_Union tr_Addr_Union_NameAddr(template (present) NameAddr nameAddr := ?) := {
145 nameAddr := nameAddr
146}
147template (value) Addr_Union ts_Addr_Union_NameAddr(template (value) NameAddr nameAddr) := {
148 nameAddr := nameAddr
149}
150
151template (present) Addr_Union tr_Addr_Union_SipUrl(template (present) SipUrl sipUrl := ?) := {
152 addrSpecUnion := sipUrl
153}
154template (value) Addr_Union ts_Addr_Union_SipUrl(template (value) SipUrl sipUrl) := {
155 addrSpecUnion := sipUrl
156}
157
158
159template (present) ContactAddress tr_ContactAddress(template (present) Addr_Union addressField := ?,
160 template SemicolonParam_List contactParams := *) := {
161 addressField := addressField,
162 contactParams := contactParams
163}
164template (value) ContactAddress ts_ContactAddress(template (value) Addr_Union addressField,
165 template (omit) SemicolonParam_List contactParams := omit) := {
166 addressField := addressField,
167 contactParams := contactParams
168}
169
170template (present) Contact tr_Contact(template (present) ContactAddress_List contactAddresses := ?) := {
171 fieldName := CONTACT_E,
172 contactBody := {
173 contactAddresses := contactAddresses
174 }
175}
176template (value) Contact ts_Contact(template (value) ContactAddress_List contactAddresses) := {
177 fieldName := CONTACT_E,
178 contactBody := {
179 contactAddresses := contactAddresses
180 }
181}
182
183template (value) Contact ts_ContactWildcard := {
184 fieldName := CONTACT_E,
185 contactBody := {
186 wildcard := "*"
187 }
188}
189
190template (present) Contact tr_Contact_SipAddr(template (present) SipAddr contact_addr := ?)
191 := tr_Contact({ tr_ContactAddress(contact_addr.addr, contact_addr.params) });
192
193private function f_tr_Contact_SipAddr(template SipAddr contact_addr) return template Contact
194{
195 if (istemplatekind(contact_addr, "omit")) {
196 return omit;
197 } else if (istemplatekind(contact_addr, "*")) {
198 return *;
199 }
200 return tr_Contact_SipAddr(contact_addr);
201}
202
203template (value) Contact ts_Contact_SipAddr(template (value) SipAddr contact_addr)
204 := ts_Contact({ ts_ContactAddress(contact_addr.addr, contact_addr.params) });
205private function ts_Contact_SipAddr_omit(template (omit) SipAddr contact_addr := omit) return template (omit) Contact
206{
207 if (istemplatekind(contact_addr, "omit")) {
208 return omit;
209 }
210 return ts_Contact_SipAddr(contact_addr);
211}
212
213
Pau Espin Pedrol5c36a652024-05-14 16:05:59 +0200214// [20.14]
215template (value) ContentLength ts_ContentLength(template (value) integer len := 0) := {
216 fieldName := CONTENT_LENGTH_E,
217 len := len
218}
219template (present) ContentLength tr_ContentLength(template (present) integer len := ?) := {
220 fieldName := CONTENT_LENGTH_E,
221 len := len
222}
223
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100224// [20.19]
225template (value) Expires ts_Expires(template (value) DeltaSec deltaSec := "7200") := {
226 fieldName := EXPIRES_E,
227 deltaSec := deltaSec
228}
229
Pau Espin Pedrol0c5c6472024-05-21 13:13:49 +0200230// [RFC3455 5.4] + 3GPP 24.229 V8.7.0
231template (present) Access_net_spec tr_Access_net_spec(template (present) charstring access_type := ?,
232 template SemicolonParam_List access_info := *) := {
233 access_type := access_type,
234 access_info := access_info
235}
236template (present) Access_net_spec tr_Access_net_spec_EUTRAN(template (present) charstring uli_str := ?) := {
237 access_type := "3GPP-E-UTRAN-FDD",
238 access_info := {tr_Param("utran-cell-id-3gpp", uli_str)}
239}
240
241// [RFC3455 5.4] + 3GPP 24.229 V8.7.0
242template (present) P_Access_Network_Info tr_P_Access_Network_Info(template (present) Access_net_spec_list access_net_specs := ?) := {
243 fieldName := P_ACCESS_NETWORK_INFO,
244 access_net_specs := access_net_specs
245}
246
Pau Espin Pedrol4e6672c2024-05-22 17:03:53 +0200247// [RFC3455 4.1]
248template (present) P_Assoc_uri_spec tr_P_Assoc_uri_spec(template (present) NameAddr p_asso_uri := ?,
249 template SemicolonParam_List ai_params := *) := {
250 p_asso_uri := p_asso_uri,
251 ai_params := ai_params
252}
253template (value) P_Assoc_uri_spec ts_P_Assoc_uri_spec(template (value) NameAddr p_asso_uri,
254 template (omit) SemicolonParam_List ai_params := omit) := {
255 p_asso_uri := p_asso_uri,
256 ai_params := ai_params
257}
258
259// [RFC3455 4.1]
260template (present) P_Associated_Uri tr_P_Associated_Uri(template (present) P_Assoc_uri_spec_list p_assoc_uris := ?) := {
261 fieldName := P_ASSOCIATED_URI,
262 p_assoc_uris := p_assoc_uris
263}
264template (value) P_Associated_Uri ts_P_Associated_Uri(template (value) P_Assoc_uri_spec_list p_assoc_uris := {}) := {
265 fieldName := P_ASSOCIATED_URI,
266 p_assoc_uris := p_assoc_uris
267}
Pau Espin Pedrol73f6a312024-05-10 20:30:16 +0200268
269// [20.32]
270template (value) Require ts_Require(template (value) OptionTag_List optionsTags := {}) := {
271 fieldName := REQUIRE_E,
272 optionsTags := optionsTags
273}
274template (present) Require tr_Require(template (present) OptionTag_List optionsTags := ?) := {
275 fieldName := REQUIRE_E,
276 optionsTags := optionsTags
277}
278
Pau Espin Pedrol52cc2e52024-05-13 17:50:20 +0200279// [20.35 RFC2616 14.38]
280template (value) Server ts_Server(template (value) ServerVal_List serverBody := {}) := {
281 fieldName := SERVER_E,
282 serverBody := serverBody
283}
284template (present) Server tr_Server(template (present) ServerVal_List serverBody := ?) := {
285 fieldName := SERVER_E,
286 serverBody := serverBody
287}
288
Pau Espin Pedrol73f6a312024-05-10 20:30:16 +0200289// [20.37]
290template (value) Supported ts_Supported(template (value) OptionTag_List optionsTags := {}) := {
291 fieldName := SUPPORTED_E,
292 optionsTags := optionsTags
293}
294template (present) Supported tr_Supported(template (present) OptionTag_List optionsTags := ?) := {
295 fieldName := SUPPORTED_E,
296 optionsTags := optionsTags
297}
298
Pau Espin Pedrol13c50ac2024-05-13 17:48:09 +0200299// [20.41 RFC2616 14.43]
300template (value) UserAgent ts_UserAgent(template (value) ServerVal_List userAgentBody := {}) := {
301 fieldName := USER_AGENT_E,
302 userAgentBody := userAgentBody
303}
304template (present) UserAgent tr_UserAgent(template (present) ServerVal_List userAgentBody := ?) := {
305 fieldName := USER_AGENT_E,
306 userAgentBody := userAgentBody
307}
308
Pau Espin Pedrol73f6a312024-05-10 20:30:16 +0200309
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100310template (value) SipAddr ts_SipAddr(template (value) HostPort host_port,
311 template (omit) UserInfo user_info := omit,
312 template (omit) charstring displayName := omit,
313 template (omit) SemicolonParam_List params := omit) := {
Harald Welteb0d93602018-03-20 18:09:34 +0100314 addr := {
315 nameAddr := {
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100316 displayName := displayName,
317 addrSpec := ts_SipUrl(host_port, user_info)
Harald Welteb0d93602018-03-20 18:09:34 +0100318 }
319 },
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100320 params := params
321}
322template (present) SipAddr tr_SipAddr(template (present) HostPort host_port := ?,
323 template UserInfo user_info := *,
324 template charstring displayName := *,
325 template SemicolonParam_List params := *) := {
326 addr := {
327 nameAddr := {
328 displayName := displayName,
329 addrSpec := tr_SipUrl(host_port, user_info)
330 }
331 },
332 params := params
Harald Welteb0d93602018-03-20 18:09:34 +0100333}
334
335/* build a receive template from a value: substitute '*' for omit */
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200336function tr_SipUrl_from_val(template (value) SipUrl tin) return template (present) SipUrl {
337 var template (present) SipUrl ret := tin;
338
339 /* if the port number is 5060, it may be omitted */
340 if (ispresent(tin.hostPort.portField) and
341 valueof(tin.hostPort.portField) == 5060) {
342 ret.hostPort.portField := 5060 ifpresent;
343 }
344 if (not ispresent(tin.userInfo.password)) {
345 ret.userInfo.password := *;
346 }
347
348 return ret;
349}
350function tr_SipAddr_from_val(template (value) SipAddr tin) return template (present) SipAddr {
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100351 var template (present) SipAddr ret := tin;
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200352
353 if (not ispresent(tin.addr.nameAddr.displayName)) {
Harald Welteb0d93602018-03-20 18:09:34 +0100354 ret.addr.nameAddr.displayName := *;
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200355 } else if (f_str_tolower(f_sip_str_unquote(tin.addr.nameAddr.displayName)) == "anonymous") {
356 /* if the user is Anonymous, it may be omitted */
357 ret.addr.nameAddr.displayName := tin.addr.nameAddr.displayName ifpresent;
Harald Welteb0d93602018-03-20 18:09:34 +0100358 }
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200359
360 ret.addr.nameAddr.addrSpec := tr_SipUrl_from_val(tin.addr.nameAddr.addrSpec);
361
362 if (not ispresent(tin.params)) {
Harald Welteb0d93602018-03-20 18:09:34 +0100363 ret.params := *;
364 }
365 return ret;
366}
367
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200368function ts_SipAddr_from_Addr_Union(template (value) Addr_Union au,
369 template (omit) SemicolonParam_List params := omit)
370return template (value) SipAddr {
371 var template (value) SipUrl addrSpec := ts_SipUrl_from_Addr_Union(au);
372 var template (omit) charstring displayName;
373
374 if (ischosen(au.nameAddr)) {
375 displayName := au.nameAddr.displayName;
376 } else { /* au.addrSpecUnion */
377 displayName := omit
378 }
379
380 return ts_SipAddr(addrSpec.hostPort,
381 addrSpec.userInfo,
382 displayName,
383 params);
384}
385
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100386template (value) HostPort ts_HostPort(template (omit) charstring host := omit,
387 template (omit) integer portField := omit) := {
388 host := host,
389 portField := portField
390}
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200391
392template (present) HostPort tr_HostPort(template charstring host := *,
393 template integer portField := *) := {
394 host := host,
395 portField := portField
396}
397function f_tr_HostPort(template charstring host := *,
398 template integer portField := *)
399return template (present) HostPort {
400 return f_tr_HostPort_opt_defport(tr_HostPort(host, portField));
401}
402function f_tr_HostPort_opt_defport(template (present) HostPort hp) return template (present) HostPort {
403 var template (present) HostPort hpout := hp;
Harald Welteb0d93602018-03-20 18:09:34 +0100404 /* if the port number is 5060, it may be omitted */
405 if (isvalue(hp.portField) and valueof(hp.portField) == 5060) {
406 hpout.portField := 5060 ifpresent;
407 }
408 return hpout;
409}
410
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200411function f_tr_SipUrl_opt_defport(template (present) SipUrl url) return template (present) SipUrl {
412 var template (present) SipUrl urlout := url;
413 urlout.hostPort := f_tr_HostPort_opt_defport(url.hostPort);
414 return urlout;
415}
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100416
417template (value) UserInfo ts_UserInfo(template (value) charstring userOrTelephoneSubscriber,
418 template (omit) charstring password := omit) := {
419 userOrTelephoneSubscriber := userOrTelephoneSubscriber,
420 password := password
421}
422template (present) UserInfo tr_UserInfo(template (present) charstring userOrTelephoneSubscriber := ?,
423 template charstring password := *) := {
424 userOrTelephoneSubscriber := userOrTelephoneSubscriber,
425 password := password
426}
427
428template (value) RequestLine ts_SIP_ReqLine(Method method,
429 template (value) SipUrl uri,
Harald Welteb0d93602018-03-20 18:09:34 +0100430 charstring ver := c_SIP_VERSION) := {
431 method := method,
432 requestUri := uri,
433 sipVersion := ver
434}
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100435template (present) RequestLine tr_SIP_ReqLine(template (present) Method method := ?,
436 template (present) SipUrl uri := ?,
437 template (present) charstring ver := c_SIP_VERSION) := {
Harald Welteb0d93602018-03-20 18:09:34 +0100438 method := method,
439 requestUri := uri,
440 sipVersion := ver
441}
442
443template (value) StatusLine ts_SIP_StatusLine(integer status_code, charstring reason) := {
444 sipVersion := "SIP/2.0",
445 statusCode := status_code,
446 reasonPhrase := reason
447}
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100448template (present) StatusLine tr_SIP_StatusLine(template integer status_code,
449 template charstring reason) := {
Harald Welteb0d93602018-03-20 18:09:34 +0100450 sipVersion := "SIP/2.0",
451 statusCode := status_code,
452 reasonPhrase := reason
453}
454
455
456template (value) PDU_SIP_Request ts_SIP_req(template (value) RequestLine rl) := {
457 requestLine := rl,
458 msgHeader := c_SIP_msgHeader_empty,
459 messageBody := omit,
460 payload := omit
461}
462
463const Method_List c_SIP_defaultMethods := {
464 "INVITE", "ACK", "BYE", "CANCEL", "OPTIONS", "PRACK", "MESSAGE", "SUBSCRIBE",
465 "NOTIFY", "REFER", "UPDATE" };
466
467private function f_ContentTypeOrOmit(template (omit) ContentType ct, template (omit) charstring body)
468return template (omit) ContentType {
469 /* if user explicitly stated no content type */
470 if (istemplatekind(ct, "omit")) {
471 return omit;
472 }
473 /* if there's no body, then there's no content-type either */
474 if (istemplatekind(body, "omit")) {
475 return omit;
476 }
477 return ct;
478}
479
Pau Espin Pedrol5c36a652024-05-14 16:05:59 +0200480private function f_ContentLength(template (omit) charstring body)
481return template (value) ContentLength {
482 /* rfc3261 20.14: "If no body is present in a message, then the
483 * Content-Length header field value MUST be set to zero." */
484 if (istemplatekind(body, "omit")) {
485 return ts_ContentLength(0);
486 }
487 return ts_ContentLength(lengthof(body));
488}
489
Harald Welteb0d93602018-03-20 18:09:34 +0100490template (value) ContentType ts_CT_SDP := {
491 fieldName := CONTENT_TYPE_E,
492 mediaType := "application/sdp"
493};
494
Pau Espin Pedrol2a833372024-05-10 20:23:22 +0200495template (value) Via ts_Via_from(template (value) HostPort addr,
496 template (value) charstring transport := "UDP") := {
Harald Welteb0d93602018-03-20 18:09:34 +0100497 fieldName := VIA_E,
498 viaBody := {
499 {
Pau Espin Pedrol2a833372024-05-10 20:23:22 +0200500 sentProtocol := { "SIP", "2.0", transport },
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100501 sentBy := addr,
Harald Welteb0d93602018-03-20 18:09:34 +0100502 viaParams := omit
503 }
504 }
505}
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100506template (present) Via tr_Via_from(template (present) HostPort host_port := ?,
Pau Espin Pedrol2a833372024-05-10 20:23:22 +0200507 template (present) charstring transport := ?,
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100508 template SemicolonParam_List viaParams := *) := {
509 fieldName := VIA_E,
510 viaBody := {
511 {
Pau Espin Pedrol2a833372024-05-10 20:23:22 +0200512 sentProtocol := { "SIP", "2.0", ? },
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100513 sentBy := host_port,
514 viaParams := viaParams
515 }
516 }
Pau Espin Pedrol05eaa1a2024-04-02 12:56:26 +0200517}
518
519template (present) OtherAuth
520tr_OtherAuth(template (present) charstring authScheme := ?,
521 template (present) CommaParam_List authParams := ?) := {
522 authScheme := authScheme,
523 authParams := authParams
524}
525
526template (value) OtherAuth
527ts_OtherAuth(template (value) charstring authScheme,
528 template (value) CommaParam_List authParams) := {
529 authScheme := authScheme,
530 authParams := authParams
531}
532
533template (present) Challenge
534tr_Challenge_digestCln(template (present) CommaParam_List digestCln := ?) := {
535 digestCln := digestCln
536}
537
538template (value) Challenge
539ts_Challenge_digestCln(template (value) CommaParam_List digestCln) := {
540 digestCln := digestCln
541}
542
543template (present) Challenge
544tr_Challenge_otherChallenge(template (present) OtherAuth otherChallenge := ?) := {
545 otherChallenge := otherChallenge
546}
547
548template (value) Challenge
549ts_Challenge_otherChallenge(template (value) OtherAuth otherChallenge) := {
550 otherChallenge := otherChallenge
551}
552
553template (present) WwwAuthenticate
554tr_WwwAuthenticate(template (present) Challenge_list challenge := ?) := {
555 fieldName := WWW_AUTHENTICATE_E,
556 challenge := challenge
557}
558
559template (value) WwwAuthenticate
560ts_WwwAuthenticate(template (value) Challenge_list challenge) := {
561 fieldName := WWW_AUTHENTICATE_E,
562 challenge := challenge
563}
Harald Welteb0d93602018-03-20 18:09:34 +0100564
Pau Espin Pedrol73f6a312024-05-10 20:30:16 +0200565// RFC3329
566template (present) Security_client
567tr_Security_client(template (present) Security_mechanism_list sec_mechanism_list := ?) := {
568 fieldName := SECURITY_CLIENT_E,
569 sec_mechanism_list := sec_mechanism_list
570}
571template (value) Security_client
572ts_Security_client(template (value) Security_mechanism_list sec_mechanism_list) := {
573 fieldName := SECURITY_CLIENT_E,
574 sec_mechanism_list := sec_mechanism_list
575}
576
Pau Espin Pedrol7f411562024-05-13 13:58:41 +0200577template (present) Security_server
578tr_Security_server(template (present) Security_mechanism_list sec_mechanism_list := ?) := {
579 fieldName := SECURITY_SERVER_E,
580 sec_mechanism_list := sec_mechanism_list
581}
582template (value) Security_server
583ts_Security_server(template (value) Security_mechanism_list sec_mechanism_list) := {
584 fieldName := SECURITY_SERVER_E,
585 sec_mechanism_list := sec_mechanism_list
586}
587
Pau Espin Pedrol73f6a312024-05-10 20:30:16 +0200588template (present) Security_mechanism
589tr_Security_mechanism(template (present) charstring name := ?,
590 template SemicolonParam_List params := *) := {
591 mechanism_name := name,
592 mechanism_params := params
593}
594template (value) Security_mechanism
595ts_Security_mechanism(template (value) charstring name,
596 template (omit) SemicolonParam_List params := omit) := {
597 mechanism_name := name,
598 mechanism_params := params
599}
600
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100601template (value) MessageHeader ts_SIP_msgHeader_empty := c_SIP_msgHeader_empty;
602template (value) MessageHeader
603ts_SIP_msgh_std(template (value) CallidString call_id,
604 template (value) SipAddr from_addr,
605 template (value) SipAddr to_addr,
606 template (omit) Contact contact,
607 template (value) charstring method,
608 template (value) integer seq_nr,
609 template (value) Via via,
Pau Espin Pedrol5c36a652024-05-14 16:05:59 +0200610 template (omit) ContentLength content_length := ts_ContentLength(0),
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100611 template (omit) ContentType content_type := omit,
Pau Espin Pedrol05eaa1a2024-04-02 12:56:26 +0200612 template (omit)Authorization authorization := omit,
Pau Espin Pedrolcb3a15b2024-05-13 16:25:11 +0200613 template (omit) Allow allow := ts_Allow(c_SIP_defaultMethods),
Pau Espin Pedrol89d8c952024-05-10 20:28:24 +0200614 template (omit) Expires expires := omit,
Pau Espin Pedrol4e6672c2024-05-22 17:03:53 +0200615 template (omit) P_Associated_Uri p_associated_uri := omit,
Pau Espin Pedrol73f6a312024-05-10 20:30:16 +0200616 template (omit) Require require := omit,
617 template (omit) Security_client security_client := omit,
Pau Espin Pedrol7f411562024-05-13 13:58:41 +0200618 template (omit) Security_server security_server := omit,
Pau Espin Pedrol52cc2e52024-05-13 17:50:20 +0200619 template (omit) Server server := omit,
Pau Espin Pedrol73f6a312024-05-10 20:30:16 +0200620 template (omit) Supported supported := omit,
Pau Espin Pedrol13c50ac2024-05-13 17:48:09 +0200621 template (omit) UserAgent userAgent := ts_UserAgent({ "osmo-ttcn3-hacks/0.23" }),
Pau Espin Pedrol89d8c952024-05-10 20:28:24 +0200622 template (omit) WwwAuthenticate wwwAuthenticate := omit
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100623 ) modifies ts_SIP_msgHeader_empty := {
Pau Espin Pedrolcb3a15b2024-05-13 16:25:11 +0200624 allow := allow,
Pau Espin Pedrol05eaa1a2024-04-02 12:56:26 +0200625 authorization := authorization,
Harald Welteb0d93602018-03-20 18:09:34 +0100626 callId := {
627 fieldName := CALL_ID_E,
628 callid := call_id
629 },
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100630 contact := contact,
Pau Espin Pedrol5c36a652024-05-14 16:05:59 +0200631 contentLength := content_length,
Harald Welteb0d93602018-03-20 18:09:34 +0100632 contentType := content_type,
633 cSeq := {
634 fieldName := CSEQ_E,
635 seqNumber := seq_nr,
636 method := method
637 },
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100638 expires := expires,
Harald Welteb0d93602018-03-20 18:09:34 +0100639 fromField := {
640 fieldName := FROM_E,
641 addressField := from_addr.addr,
642 fromParams := from_addr.params
643 },
Pau Espin Pedrol4e6672c2024-05-22 17:03:53 +0200644 p_associated_uri := p_associated_uri,
Pau Espin Pedrol73f6a312024-05-10 20:30:16 +0200645 require := require,
646 security_client := security_client,
Pau Espin Pedrol7f411562024-05-13 13:58:41 +0200647 security_server := security_server,
Pau Espin Pedrol52cc2e52024-05-13 17:50:20 +0200648 server := server,
Pau Espin Pedrol73f6a312024-05-10 20:30:16 +0200649 supported := supported,
Harald Welteb0d93602018-03-20 18:09:34 +0100650 toField := {
651 fieldName := TO_E,
652 addressField := to_addr.addr,
653 toParams := to_addr.params
654 },
Pau Espin Pedrol13c50ac2024-05-13 17:48:09 +0200655 userAgent := userAgent,
Pau Espin Pedrol89d8c952024-05-10 20:28:24 +0200656 via := via,
657 wwwAuthenticate := wwwAuthenticate
Harald Welteb0d93602018-03-20 18:09:34 +0100658}
659
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100660template (present) MessageHeader
661tr_SIP_msgh_std(template CallidString call_id,
662 template SipAddr from_addr,
663 template SipAddr to_addr,
664 template Contact contact,
665 template (present) Via via := tr_Via_from(?),
666 template charstring method,
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100667 template integer seq_nr := ?,
Pau Espin Pedrol5c36a652024-05-14 16:05:59 +0200668 template ContentLength content_length := *,
669 template ContentType content_type := *,
Pau Espin Pedrolcb3a15b2024-05-13 16:25:11 +0200670 template Allow allow := *,
Pau Espin Pedrola674d612024-05-14 19:56:33 +0200671 template Authorization authorization := *,
Pau Espin Pedrol05eaa1a2024-04-02 12:56:26 +0200672 template Expires expires := *,
Pau Espin Pedrol4e6672c2024-05-22 17:03:53 +0200673 template P_Associated_Uri p_associated_uri := *,
Pau Espin Pedrol73f6a312024-05-10 20:30:16 +0200674 template Require require := *,
675 template Security_client security_client := *,
Pau Espin Pedrol7f411562024-05-13 13:58:41 +0200676 template Security_server security_server := *,
Pau Espin Pedrol52cc2e52024-05-13 17:50:20 +0200677 template Server server := *,
Pau Espin Pedrol73f6a312024-05-10 20:30:16 +0200678 template Supported supported := *,
Pau Espin Pedrol13c50ac2024-05-13 17:48:09 +0200679 template UserAgent userAgent := *,
Pau Espin Pedrol05eaa1a2024-04-02 12:56:26 +0200680 template WwwAuthenticate wwwAuthenticate := *
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100681 ) modifies t_SIP_msgHeader_any := {
Pau Espin Pedrolcb3a15b2024-05-13 16:25:11 +0200682 allow := allow,
Pau Espin Pedrola674d612024-05-14 19:56:33 +0200683 authorization := authorization,
Harald Welteb0d93602018-03-20 18:09:34 +0100684 callId := {
685 fieldName := CALL_ID_E,
686 callid := call_id
687 },
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100688 contact := contact,
Pau Espin Pedrol5c36a652024-05-14 16:05:59 +0200689 contentLength := content_length,
Harald Welteb0d93602018-03-20 18:09:34 +0100690 contentType := content_type,
691 cSeq := {
692 fieldName := CSEQ_E,
693 seqNumber := seq_nr,
694 method := method
695 },
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100696 expires := expires,
Harald Welteb0d93602018-03-20 18:09:34 +0100697 fromField := {
698 fieldName := FROM_E,
699 addressField := from_addr.addr,
700 fromParams := from_addr.params
701 },
Pau Espin Pedrol4e6672c2024-05-22 17:03:53 +0200702 p_associated_uri := p_associated_uri,
Pau Espin Pedrol73f6a312024-05-10 20:30:16 +0200703 require := require,
704 security_client := security_client,
Pau Espin Pedrol7f411562024-05-13 13:58:41 +0200705 security_server := security_server,
Pau Espin Pedrol52cc2e52024-05-13 17:50:20 +0200706 server := server,
Pau Espin Pedrol73f6a312024-05-10 20:30:16 +0200707 supported := supported,
Harald Welteb0d93602018-03-20 18:09:34 +0100708 toField := {
709 fieldName := TO_E,
710 addressField := to_addr.addr,
711 toParams := to_addr.params
712 },
Pau Espin Pedrol13c50ac2024-05-13 17:48:09 +0200713 userAgent := userAgent,
Pau Espin Pedrol05eaa1a2024-04-02 12:56:26 +0200714 via := via,
715 wwwAuthenticate := wwwAuthenticate
Harald Welteb0d93602018-03-20 18:09:34 +0100716}
717
718
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100719template (value) PDU_SIP_Request
720ts_SIP_REGISTER(template (value) SipUrl sip_url_host_port,
721 template (value) CallidString call_id,
722 template (value) SipAddr from_addr,
723 template (value) SipAddr to_addr,
724 template (value) Via via,
725 integer seq_nr,
726 template (omit) Contact contact,
727 template (omit) Expires expires,
Pau Espin Pedrol05eaa1a2024-04-02 12:56:26 +0200728 template (omit) Authorization authorization := omit,
Pau Espin Pedrol73f6a312024-05-10 20:30:16 +0200729 template (omit) Require require := omit,
730 template (omit) Security_client security_client := omit,
731 template (omit) Supported supported := omit,
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100732 template (omit) charstring body := omit) := {
733 requestLine := ts_SIP_ReqLine(REGISTER_E, sip_url_host_port),
734 msgHeader := ts_SIP_msgh_std(call_id, from_addr, to_addr, contact,
735 "REGISTER", seq_nr, via,
Pau Espin Pedrol5c36a652024-05-14 16:05:59 +0200736 content_length := f_ContentLength(body),
737 content_type := f_ContentTypeOrOmit(ts_CT_SDP, body),
Pau Espin Pedrol05eaa1a2024-04-02 12:56:26 +0200738 authorization := authorization,
Pau Espin Pedrol73f6a312024-05-10 20:30:16 +0200739 expires := expires,
740 require := require,
741 security_client := security_client,
742 supported := supported),
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100743 messageBody := body,
744 payload := omit
745}
746template (present) PDU_SIP_Request
747tr_SIP_REGISTER(template (present) SipUrl sip_url_host_port := ?,
748 template (present) CallidString call_id := ?,
749 template (present) SipAddr from_addr := ?,
750 template (present) SipAddr to_addr := ?,
Pau Espin Pedrol0dd3f262024-04-25 17:04:43 +0200751 template (present) Via via := tr_Via_from(f_tr_HostPort_opt_defport(?)),
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100752 template integer seq_nr := *,
Pau Espin Pedrola674d612024-05-14 19:56:33 +0200753 template Authorization authorization := *,
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100754 template Contact contact := *,
755 template Expires expires := *,
Pau Espin Pedrol73f6a312024-05-10 20:30:16 +0200756 template Require require := *,
757 template Security_client security_client := *,
758 template Supported supported := *,
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100759 template charstring body := *) := {
760 requestLine := tr_SIP_ReqLine(REGISTER_E, sip_url_host_port),
761 msgHeader := tr_SIP_msgh_std(call_id, from_addr, to_addr, contact,
Pau Espin Pedrol5c36a652024-05-14 16:05:59 +0200762 via, "REGISTER", seq_nr,
Pau Espin Pedrola674d612024-05-14 19:56:33 +0200763 authorization := authorization,
Pau Espin Pedrol73f6a312024-05-10 20:30:16 +0200764 expires := expires,
765 require := require,
766 security_client := security_client,
767 supported := supported),
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100768 messageBody := body,
769 payload := omit
770}
771
772template (value) PDU_SIP_Request
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200773ts_SIP_INVITE(template (value) CallidString call_id,
774 template (value) SipAddr from_addr,
775 template (value) SipAddr to_addr,
776 template (value) Via via,
777 template (value) Contact contact,
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100778 integer seq_nr,
779 template (omit) charstring body := omit) := {
Harald Welteb0d93602018-03-20 18:09:34 +0100780 requestLine := ts_SIP_ReqLine(INVITE_E, to_addr.addr.nameAddr.addrSpec),
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200781 msgHeader := ts_SIP_msgh_std(call_id, from_addr, to_addr, contact,
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100782 "INVITE", seq_nr,
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200783 via,
Pau Espin Pedrol5c36a652024-05-14 16:05:59 +0200784 content_length := f_ContentLength(body),
785 content_type := f_ContentTypeOrOmit(ts_CT_SDP, body)),
Harald Welteb0d93602018-03-20 18:09:34 +0100786 messageBody := body,
787 payload := omit
788}
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100789template (present) PDU_SIP_Request
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200790tr_SIP_INVITE(template (present) SipUrl uri,
791 template CallidString call_id,
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100792 template SipAddr from_addr,
793 template SipAddr to_addr,
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200794 template Via via := tr_Via_from(f_tr_HostPort_opt_defport(?)),
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100795 template integer seq_nr,
796 template charstring body) := {
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200797 requestLine := tr_SIP_ReqLine(INVITE_E, uri),
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100798 msgHeader := tr_SIP_msgh_std(call_id, from_addr, to_addr, ?,
Pau Espin Pedrol5c36a652024-05-14 16:05:59 +0200799 via, "INVITE", seq_nr),
Harald Welteb0d93602018-03-20 18:09:34 +0100800 messageBody := body,
801 payload := omit
802}
803
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100804template (value) PDU_SIP_Request
805ts_SIP_BYE(CallidString call_id,
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200806 template (value) SipAddr from_addr,
807 template (value) SipAddr to_addr,
808 template (value) Via via,
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100809 integer seq_nr,
810 template (omit) charstring body) := {
Harald Welteb0d93602018-03-20 18:09:34 +0100811 requestLine := ts_SIP_ReqLine(BYE_E, to_addr.addr.nameAddr.addrSpec),
812 msgHeader := ts_SIP_msgh_std(call_id, from_addr, to_addr, omit, "BYE", seq_nr,
Pau Espin Pedrol5c36a652024-05-14 16:05:59 +0200813 via,
814 content_length := f_ContentLength(body),
815 content_type := f_ContentTypeOrOmit(ts_CT_SDP, body)),
Harald Welteb0d93602018-03-20 18:09:34 +0100816 messageBody := body,
817 payload := omit
818}
819
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100820template (present) PDU_SIP_Request
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200821tr_SIP_BYE(template (present) SipUrl uri,
822 template CallidString call_id,
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100823 template SipAddr from_addr,
824 template SipAddr to_addr,
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200825 template Via via,
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100826 template integer seq_nr,
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200827 template charstring body := *) := {
828 requestLine := tr_SIP_ReqLine(BYE_E, uri),
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100829 msgHeader := tr_SIP_msgh_std(call_id, from_addr, to_addr, omit,
Pau Espin Pedrol5c36a652024-05-14 16:05:59 +0200830 via, "BYE", seq_nr),
Harald Welteb0d93602018-03-20 18:09:34 +0100831 messageBody := body,
832 payload := omit
833}
834
835
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100836template (value) PDU_SIP_Request
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200837ts_SIP_ACK(template (value) CallidString call_id,
838 template (value) SipAddr from_addr,
839 template (value) SipAddr to_addr,
840 template (value) Via via,
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100841 integer seq_nr,
842 template (omit) charstring body) := {
Harald Welteb0d93602018-03-20 18:09:34 +0100843 requestLine := ts_SIP_ReqLine(ACK_E, to_addr.addr.nameAddr.addrSpec),
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100844 msgHeader := ts_SIP_msgh_std(call_id, from_addr, to_addr,
845 ts_Contact_SipAddr(from_addr),
846 "ACK", seq_nr,
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200847 via,
Pau Espin Pedrol5c36a652024-05-14 16:05:59 +0200848 content_length := f_ContentLength(body),
849 content_type := f_ContentTypeOrOmit(ts_CT_SDP, body)),
Harald Welteb0d93602018-03-20 18:09:34 +0100850 messageBody := body,
851 payload := omit
852}
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100853template (present) PDU_SIP_Request
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200854tr_SIP_ACK(template (present) SipUrl uri,
855 template CallidString call_id,
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100856 template SipAddr from_addr,
857 template SipAddr to_addr,
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200858 template Via via,
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100859 template integer seq_nr,
860 template charstring body) := {
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200861 requestLine := tr_SIP_ReqLine(ACK_E, uri),
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100862 msgHeader := tr_SIP_msgh_std(call_id, from_addr, to_addr, *,
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200863 via,
Pau Espin Pedrol5c36a652024-05-14 16:05:59 +0200864 "ACK", seq_nr),
Harald Welteb0d93602018-03-20 18:09:34 +0100865 messageBody := body,
866 payload := omit
867}
868
Pau Espin Pedrol32167d82024-04-10 13:14:51 +0200869template (present) PDU_SIP_Request
870tr_SIP_CANCEL(template (present) SipUrl uri,
871 template (present) CallidString call_id,
872 template (present) SipAddr from_addr,
873 template (present) SipAddr to_addr,
874 template (present) Via via,
875 template (present) integer seq_nr,
876 template charstring body := *) := {
877 requestLine := tr_SIP_ReqLine(CANCEL_E, uri),
878 msgHeader := tr_SIP_msgh_std(call_id, from_addr, to_addr, *,
879 via,
Pau Espin Pedrol5c36a652024-05-14 16:05:59 +0200880 "CANCEL", seq_nr),
Pau Espin Pedrol32167d82024-04-10 13:14:51 +0200881 messageBody := body,
882 payload := omit
883}
884
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100885template (value) PDU_SIP_Response
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200886ts_SIP_Response(template (value) CallidString call_id,
887 template (value) SipAddr from_addr,
888 template (value) SipAddr to_addr,
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100889 charstring method,
890 integer status_code,
891 integer seq_nr,
892 charstring reason,
893 Via via,
Pau Espin Pedrola674d612024-05-14 19:56:33 +0200894 template (omit) Allow allow := omit,
Pau Espin Pedrol4e6672c2024-05-22 17:03:53 +0200895 template (omit) P_Associated_Uri p_associated_uri := omit,
Pau Espin Pedrola674d612024-05-14 19:56:33 +0200896 template (omit) Require require := omit,
897 template (omit) Server server := omit,
898 template (omit) Supported supported := omit,
899 template (omit) UserAgent userAgent := omit,
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100900 template (omit) charstring body := omit) := {
Harald Welteb0d93602018-03-20 18:09:34 +0100901 statusLine := ts_SIP_StatusLine(status_code, reason),
902 msgHeader := ts_SIP_msgh_std(call_id, from_addr, to_addr, omit, method, seq_nr,
Pau Espin Pedrol5c36a652024-05-14 16:05:59 +0200903 via,
904 content_length := f_ContentLength(body),
Pau Espin Pedrola674d612024-05-14 19:56:33 +0200905 content_type := f_ContentTypeOrOmit(ts_CT_SDP, body),
906 allow := allow,
Pau Espin Pedrol4e6672c2024-05-22 17:03:53 +0200907 p_associated_uri := p_associated_uri,
Pau Espin Pedrola674d612024-05-14 19:56:33 +0200908 require := require,
909 server := server,
910 supported := supported,
911 userAgent := userAgent),
Harald Welteb0d93602018-03-20 18:09:34 +0100912 messageBody := body,
913 payload := omit
914}
Pau Espin Pedrol1b5f7ba2024-05-13 16:38:38 +0200915/* 100 Trying */
916template (value) PDU_SIP_Response
917ts_SIP_Response_Trying(
918 template (value) CallidString call_id,
919 template (value) SipAddr from_addr,
920 template (value) SipAddr to_addr,
921 Via via,
922 integer seq_nr,
923 charstring method := "INVITE",
Pau Espin Pedrola2812ec2024-05-10 20:30:44 +0200924 template (omit) Allow allow := omit,
925 template (omit) Server server := omit,
926 template (omit) UserAgent userAgent := omit,
Pau Espin Pedrol1b5f7ba2024-05-13 16:38:38 +0200927 template (omit) charstring body := omit) := {
928 statusLine := ts_SIP_StatusLine(100, "Trying"),
929 msgHeader := ts_SIP_msgh_std(call_id, from_addr, to_addr, omit, method, seq_nr,
Pau Espin Pedrol5c36a652024-05-14 16:05:59 +0200930 via,
931 content_length := f_ContentLength(body),
Pau Espin Pedrola2812ec2024-05-10 20:30:44 +0200932 content_type := f_ContentTypeOrOmit(ts_CT_SDP, body),
933 allow := allow,
934 server := server,
935 userAgent := userAgent),
Pau Espin Pedrol1b5f7ba2024-05-13 16:38:38 +0200936 messageBody := body,
937 payload := omit
938}
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200939/* 180 Ringing */
940template (value) PDU_SIP_Response
941ts_SIP_Response_Ringing(
942 template (value) CallidString call_id,
943 template (value) SipAddr from_addr,
944 template (value) SipAddr to_addr,
945 Via via,
946 integer seq_nr,
947 charstring method := "INVITE",
948 template (omit) charstring body := omit) := {
949 statusLine := ts_SIP_StatusLine(180, "Ringing"),
950 msgHeader := ts_SIP_msgh_std(call_id, from_addr, to_addr, omit, method, seq_nr,
Pau Espin Pedrol5c36a652024-05-14 16:05:59 +0200951 via,
952 content_length := f_ContentLength(body),
953 content_type := f_ContentTypeOrOmit(ts_CT_SDP, body)),
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200954 messageBody := body,
955 payload := omit
956}
957
Pau Espin Pedrola2812ec2024-05-10 20:30:44 +0200958/* 401 Unauthorized */
959template (value) PDU_SIP_Response
960ts_SIP_Response_Unauthorized(
961 template (value) CallidString call_id,
962 template (value) SipAddr from_addr,
963 template (value) SipAddr to_addr,
964 Via via,
965 template (value) WwwAuthenticate wwwAuthenticate,
966 integer seq_nr,
967 charstring method := "REGISTER",
968 template (omit) Allow allow := omit,
Pau Espin Pedrol4e6672c2024-05-22 17:03:53 +0200969 template (omit) P_Associated_Uri p_associated_uri := omit,
Pau Espin Pedrola2812ec2024-05-10 20:30:44 +0200970 template (omit) Security_server security_server := omit,
971 template (omit) Server server := omit,
972 template (omit) Supported supported := omit,
973 template (omit) UserAgent userAgent := omit,
974 template (omit) charstring body := omit) := {
975 statusLine := ts_SIP_StatusLine(401, "Unauthorized"),
976 msgHeader := ts_SIP_msgh_std(call_id, from_addr, to_addr, omit, method, seq_nr,
977 via,
978 content_length := f_ContentLength(body),
979 content_type := f_ContentTypeOrOmit(ts_CT_SDP, body),
980 allow := allow,
Pau Espin Pedrol4e6672c2024-05-22 17:03:53 +0200981 p_associated_uri := p_associated_uri,
Pau Espin Pedrola2812ec2024-05-10 20:30:44 +0200982 security_server := security_server,
983 server := server,
984 supported := supported,
985 userAgent := userAgent,
986 wwwAuthenticate := wwwAuthenticate),
987 messageBody := body,
988 payload := omit
989}
990
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100991template (present) PDU_SIP_Response
992tr_SIP_Response(template CallidString call_id,
993 template SipAddr from_addr,
994 template SipAddr to_addr,
Pau Espin Pedrol05eaa1a2024-04-02 12:56:26 +0200995 template (present) Via via := tr_Via_from(?),
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100996 template Contact contact,
997 template charstring method,
998 template integer status_code,
999 template integer seq_nr := ?,
1000 template charstring reason := ?,
Pau Espin Pedrol05eaa1a2024-04-02 12:56:26 +02001001 template charstring body := *) := {
Harald Welteb0d93602018-03-20 18:09:34 +01001002 statusLine := tr_SIP_StatusLine(status_code, reason),
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +01001003 msgHeader := tr_SIP_msgh_std(call_id, from_addr, to_addr, contact,
Pau Espin Pedrol05eaa1a2024-04-02 12:56:26 +02001004 via,
Pau Espin Pedrol5c36a652024-05-14 16:05:59 +02001005 method, seq_nr),
Harald Welteb0d93602018-03-20 18:09:34 +01001006 messageBody := body,
1007 payload := omit
1008}
1009
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +02001010/* Expect during first REGISTER/INVITE/... when authorization is required: */
Pau Espin Pedrol37ee0ed2024-03-28 21:17:12 +01001011template (present) PDU_SIP_Response
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +02001012tr_SIP_Response_Unauthorized(
Pau Espin Pedrol37ee0ed2024-03-28 21:17:12 +01001013 template CallidString call_id,
1014 template SipAddr from_addr,
1015 template SipAddr to_addr,
1016 template (present) Via via := tr_Via_from(?),
1017 template Contact contact := *,
Pau Espin Pedrol05eaa1a2024-04-02 12:56:26 +02001018 template (present) WwwAuthenticate wwwAuthenticate := ?,
Pau Espin Pedrol37ee0ed2024-03-28 21:17:12 +01001019 template integer seq_nr := ?,
1020 template charstring method := "REGISTER",
1021 template integer status_code := 401,
1022 template charstring reason := "Unauthorized",
1023 template charstring body := *) := {
1024 statusLine := tr_SIP_StatusLine(status_code, reason),
1025 msgHeader := tr_SIP_msgh_std(call_id, from_addr, to_addr, contact,
1026 via,
Pau Espin Pedrol5c36a652024-05-14 16:05:59 +02001027 method, seq_nr,
Pau Espin Pedrol05eaa1a2024-04-02 12:56:26 +02001028 wwwAuthenticate := wwwAuthenticate),
Pau Espin Pedrol37ee0ed2024-03-28 21:17:12 +01001029 messageBody := body,
1030 payload := omit
1031}
Harald Welteb0d93602018-03-20 18:09:34 +01001032
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +02001033/* 100 Trying */
1034template (present) PDU_SIP_Response
1035tr_SIP_Response_Trying(
1036 template CallidString call_id,
1037 template SipAddr from_addr,
1038 template SipAddr to_addr,
1039 template (present) Via via := tr_Via_from(?),
1040 template integer seq_nr := ?,
1041 template charstring method := "INVITE",
1042 template integer status_code := 100,
1043 template charstring reason := "Trying",
1044 template charstring body := *) := {
1045 statusLine := tr_SIP_StatusLine(status_code, reason),
1046 msgHeader := tr_SIP_msgh_std(call_id, from_addr, to_addr, omit,
1047 via,
Pau Espin Pedrol5c36a652024-05-14 16:05:59 +02001048 method, seq_nr),
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +02001049 messageBody := body,
1050 payload := omit
1051}
1052
1053/* 180 Ringing */
1054template (present) PDU_SIP_Response
1055tr_SIP_Response_Ringing(
1056 template CallidString call_id,
1057 template SipAddr from_addr,
1058 template SipAddr to_addr,
1059 template (present) Via via := tr_Via_from(?),
1060 template integer seq_nr := ?,
1061 template charstring method := "INVITE",
1062 template integer status_code := 180,
1063 template charstring reason := "Ringing",
1064 template charstring body := *) := {
1065 statusLine := tr_SIP_StatusLine(status_code, reason),
1066 msgHeader := tr_SIP_msgh_std(call_id, from_addr, to_addr, *,
1067 via,
Pau Espin Pedrol5c36a652024-05-14 16:05:59 +02001068 method, seq_nr),
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +02001069 messageBody := body,
1070 payload := omit
1071}
1072
1073/****************
1074 * FUNCTIONS:
1075 ****************/
1076
Pau Espin Pedrol05eaa1a2024-04-02 12:56:26 +02001077function f_sip_param_find(GenericParam_List li,
1078 template (present) charstring id := ?)
1079return template (omit) GenericParam {
1080 var integer i;
1081
1082 for (i := 0; i < lengthof(li); i := i + 1) {
1083 if (not ispresent(li[i])) {
1084 continue;
1085 }
1086 if (match(li[i].id, id)) {
1087 return li[i];
1088 }
1089 }
1090 return omit;
1091}
1092
1093function f_sip_param_find_or_fail(GenericParam_List li,
1094 template (present) charstring id := ?)
1095return GenericParam {
1096 var template (omit) GenericParam parameter;
1097 parameter := f_sip_param_find(li, id);
1098 if (istemplatekind(parameter, "omit")) {
1099 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
1100 log2str("Param ", id, " not found in ", li));
1101 }
1102 return valueof(parameter);
1103}
1104
1105function f_sip_param_get_value(GenericParam_List li,
1106 template (present) charstring id := ?)
1107return template (omit) charstring {
1108 var template (omit) GenericParam parameter;
1109 parameter := f_sip_param_find(li, id);
1110 if (istemplatekind(parameter, "omit")) {
1111 return omit;
1112 }
1113 return parameter.paramValue;
1114}
1115
1116function f_sip_param_get_value_or_fail(GenericParam_List li,
1117 template (present) charstring id := ?)
1118return template (omit) charstring {
1119 var GenericParam parameter;
1120 parameter := f_sip_param_find_or_fail(li, id);
1121 return parameter.paramValue;
1122}
1123
1124function f_sip_param_get_value_present_or_fail(GenericParam_List li,
1125 template (present) charstring id := ?)
1126return charstring {
1127 var GenericParam parameter;
1128 parameter := f_sip_param_find_or_fail(li, id);
1129 if (not ispresent(parameter.paramValue)) {
1130 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
1131 log2str("Param ", id, " value not present in ", li));
1132 }
1133 return parameter.paramValue;
1134}
1135
1136function f_sip_param_match_value(GenericParam_List li,
1137 template (present) charstring id := ?,
1138 template charstring exp_paramValue := *)
1139return boolean {
1140 var template (omit) charstring val;
1141 val := f_sip_param_get_value_or_fail(li, id);
1142 if (istemplatekind(val, "omit")) {
1143 return istemplatekind(val, "omit") or istemplatekind(val, "*");
1144 }
1145 return match(valueof(val), exp_paramValue);
1146}
1147
1148function f_sip_param_match_value_or_fail(GenericParam_List li,
1149 template (present) charstring id := ?,
1150 template charstring exp_paramValue := *)
1151{
1152 var template (omit) charstring val := f_sip_param_get_value_or_fail(li, id);
1153 if (istemplatekind(val, "omit")) {
1154 if (istemplatekind(val, "omit") or istemplatekind(val, "*")) {
1155 return;
1156 } else {
1157 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
1158 log2str("Param ", id, " match failed: val ", val,
1159 " vs exp ", exp_paramValue));
1160 }
1161 }
1162 if (not match(valueof(val), exp_paramValue)) {
1163 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
1164 log2str("Param ", id, " match failed: val ", val,
1165 " vs exp ", exp_paramValue));
1166 }
1167}
1168
1169function f_sip_param_remove(template (omit) GenericParam_List li_tpl, charstring id)
1170return GenericParam_List {
1171 var integer i;
1172 var GenericParam_List li;
1173 var GenericParam_List new_li := {};
1174
1175 if (istemplatekind(li_tpl, "omit")) {
1176 return {};
1177 }
1178
1179 li := valueof(li_tpl);
1180 for (i := 0; i < lengthof(li); i := i + 1) {
1181 if (not ispresent(li[i]) or
1182 not match(li[i].id, id)) {
1183 new_li := new_li & {li[i]};
1184 }
1185 }
1186 return new_li;
1187}
1188
1189function f_sip_param_set(template (omit) GenericParam_List li_tpl, charstring id, charstring val)
1190return GenericParam_List {
1191 var integer i;
1192 var GenericParam_List li;
1193 var GenericParam_List new_li := {};
1194 var boolean found := false;
1195
1196 if (istemplatekind(li_tpl, "omit")) {
1197 return { valueof(ts_Param(id, val)) };
1198 }
1199
1200 li := valueof(li_tpl);
1201 for (i := 0; i < lengthof(li); i := i + 1) {
1202 if (not ispresent(li[i]) or
1203 not match(li[i].id, id)) {
1204 new_li := new_li & {li[i]};
1205 continue;
1206 }
1207 new_li := new_li & { valueof(ts_Param(li[i].id, val)) };
1208 found := true;
1209 }
1210
1211 if (not found) {
1212 new_li := new_li & { valueof(ts_Param(id, val)) };
1213 }
1214 return new_li;
1215}
1216
1217/* Make sure string is quoted. */
1218function f_sip_str_quote(template (value) charstring val) return charstring {
1219 var charstring str := valueof(val);
1220 if (lengthof(str) == 0) {
1221 return "";
1222 }
1223
1224 if (str[0] != "\"") {
1225 return "\"" & str & "\"";
1226 }
1227 return str;
1228}
1229
1230/* Make sure string is unquoted.
1231 * Similar to unq() in RFC 2617 */
1232function f_sip_str_unquote(template (value) charstring val) return charstring {
1233 var charstring str := valueof(val);
1234 var integer len := lengthof(str);
1235
1236 if (len <= 1) {
1237 return str;
1238 }
1239
1240 if (str[0] == "\"" and str[len - 1] == "\"") {
1241 return substr(str, 1, len - 2);
1242 }
1243 return str;
1244}
1245
1246/* RFC 2617 3.2.2.2 A1 */
1247function f_sip_digest_A1(charstring user, charstring realm, charstring password) return charstring {
1248
1249 /* RFC 2617 3.2.2.2 A1 */
1250 var charstring A1 := f_sip_str_unquote(user) & ":" &
1251 f_sip_str_unquote(realm) & ":" &
1252 password;
1253 var charstring digestA1 := f_str_tolower(f_calculateMD5(A1));
1254 log("A1: md5('", A1, "') = ", digestA1);
1255 return digestA1;
1256}
1257
1258/* RFC 2617 3.2.2.2 A2 */
1259function f_sip_digest_A2(charstring method, charstring uri) return charstring {
1260
1261 var charstring A2 := method & ":" & uri
1262 var charstring digestA2 := f_str_tolower(f_calculateMD5(A2));
1263 log("A2: md5('", A2, "') = ", digestA2);
1264 return digestA2;
1265}
1266
1267/* RFC 2617 3.2.2.1 Request-Digest */
1268function f_sip_digest_RequestDigest(charstring digestA1, charstring nonce,
1269 charstring nc, charstring cnonce,
1270 charstring qop, charstring digestA2) return charstring {
1271 var charstring digest_data := f_sip_str_unquote(nonce) & ":" &
1272 nc & ":" &
1273 cnonce & ":" &
1274 f_sip_str_unquote(qop) & ":" &
1275 digestA2;
1276 var charstring req_digest := f_sip_digest_KD(digestA1, digest_data);
1277 log("Request-Digest: md5('", digestA1, ":", digest_data ,"') = ", req_digest);
1278 return req_digest;
1279}
1280
1281/* RFC 2617 3.2.1 The WWW-Authenticate Response Header
1282 * KD(secret, data) = H(concat(secret, ":", data))
1283 */
1284function f_sip_digest_KD(charstring secret, charstring data) return charstring {
1285 return f_str_tolower(f_calculateMD5(secret & ":" & data));
1286}
1287
1288/* Digest Auth: RFC 2617 */
1289function f_sip_digest_gen_Authorization(WwwAuthenticate www_authenticate,
1290 charstring user, charstring password,
1291 charstring method, charstring uri,
1292 charstring cnonce := "0a4f113b", integer nc_int := 1) return Authorization {
1293 var CommaParam_List digestCln;
1294 var template (value) Authorization authorization;
1295 var template (value) Credentials cred;
1296 var template (omit) GenericParam rx_param;
1297
1298 digestCln := www_authenticate.challenge[0].digestCln;
1299
1300 var charstring algorithm;
1301 rx_param := f_sip_param_find(digestCln, "algorithm");
1302 if (istemplatekind(rx_param, "omit")) {
1303 /* Assume MD5 if not set */
1304 algorithm := "MD5"
1305 } else {
1306 algorithm := valueof(rx_param.paramValue);
1307 if (f_strstr(algorithm, "MD5") == -1) {
1308 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
1309 log2str("Unexpected algorithm: ", algorithm));
1310 }
1311 }
1312
1313 var charstring realm := f_sip_param_get_value_present_or_fail(digestCln, "realm");
1314 var charstring nonce := f_sip_param_get_value_present_or_fail(digestCln, "nonce");
1315 var charstring opaque := f_sip_param_get_value_present_or_fail(digestCln, "opaque");
1316 var charstring qop := f_sip_param_get_value_present_or_fail(digestCln, "qop");
1317
1318 if (f_strstr(qop, "auth") == -1) {
1319 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str("Unexpected qop: ", qop));
1320 }
1321 var charstring selected_qop := "auth";
1322
1323 /* RFC 2617 3.2.2.2 A1 */
1324 var charstring digestA1 := f_sip_digest_A1(user, realm, password);
1325 /* RFC 2617 3.2.2.3 A2 */
1326 var charstring digestA2 := f_sip_digest_A2(method, uri);
1327
1328 /* RFC 2617 3.2.2.1 Request-Digest */
1329 var charstring nc := f_str_tolower(hex2str(int2hex(nc_int, 8)));
1330 var charstring req_digest := f_sip_digest_RequestDigest(digestA1, nonce,
1331 nc, cnonce,
1332 selected_qop, digestA2);
1333
1334 cred := ts_Credentials_DigestResponseMD5(user, realm, nonce,
1335 uri, req_digest,
1336 opaque, algorithm, selected_qop, cnonce, nc);
1337
1338 authorization := ts_Authorization(cred);
1339 return valueof(authorization);
1340}
1341
1342/* RFC 2617 3.5 Example */
1343function f_sip_digest_selftest() {
1344/*
1345The following example assumes that an access-protected document is
1346being requested from the server via a GET request. The URI of the
1347document is "http://www.nowhere.org/dir/index.html". Both client and
1348server know that the username for this document is "Mufasa", and the
1349password is "Circle Of Life" (with one space between each of the
1350three words).
1351
1352HTTP/1.1 401 Unauthorized
1353WWW-Authenticate: Digest
1354 realm="testrealm@host.com",
1355 qop="auth,auth-int",
1356 nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093",
1357 opaque="5ccc069c403ebaf9f0171e9517f40e41"
1358
1359Authorization: Digest username="Mufasa",
1360 realm="testrealm@host.com",
1361 nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093",
1362 uri="/dir/index.html",
1363 qop=auth,
1364 nc=00000001,
1365 cnonce="0a4f113b",
1366 response="6629fae49393a05397450978507c4ef1",
1367 opaque="5ccc069c403ebaf9f0171e9517f40e41"
1368*/
1369 var template (value) CommaParam_List digestCln := {
1370 ts_Param("realm", f_sip_str_quote("testrealm@host.com")),
1371 ts_Param("qop", f_sip_str_quote("auth,auth-int")),
1372 ts_Param("nonce", f_sip_str_quote("dcd98b7102dd2f0e8b11d0f600bfb0c093")),
1373 ts_Param("opaque", f_sip_str_quote("5ccc069c403ebaf9f0171e9517f40e41"))
1374 };
1375 var template (value) WwwAuthenticate www_authenticate :=
1376 ts_WwwAuthenticate( { ts_Challenge_digestCln(digestCln) } )
1377
1378 var Authorization authorization :=
1379 f_sip_digest_gen_Authorization(valueof(www_authenticate),
1380 "Mufasa",
1381 "Circle Of Life",
1382 "GET",
1383 "/dir/index.html",
1384 cnonce := "0a4f113b",
1385 nc_int := 1);
1386
1387 var CommaParam_List digestResp := authorization.body.digestResponse;
1388 f_sip_param_match_value_or_fail(digestResp, "realm", f_sip_str_quote("testrealm@host.com"));
1389 f_sip_param_match_value_or_fail(digestResp, "nonce", f_sip_str_quote("dcd98b7102dd2f0e8b11d0f600bfb0c093"));
1390 f_sip_param_match_value_or_fail(digestResp, "uri", f_sip_str_quote("/dir/index.html"));
1391 f_sip_param_match_value_or_fail(digestResp, "qop", "auth");
1392 f_sip_param_match_value_or_fail(digestResp, "nc", "00000001");
1393 f_sip_param_match_value_or_fail(digestResp, "cnonce", f_sip_str_quote("0a4f113b"));
1394 f_sip_param_match_value_or_fail(digestResp, "response", f_sip_str_quote("6629fae49393a05397450978507c4ef1"));
1395 f_sip_param_match_value_or_fail(digestResp, "opaque", f_sip_str_quote("5ccc069c403ebaf9f0171e9517f40e41"));
1396}
1397
Pau Espin Pedrol6052a342024-03-28 20:20:46 +01001398/* RFC 3261 8.1.1.5:
1399 * "The sequence number value MUST be expressible as a 32-bit unsigned integer
1400 * and MUST be less than 2**31."
1401 */
1402function f_sip_rand_seq_nr() return integer {
1403 /* 2**31 = 2147483648 */
1404 return f_rnd_int(2147483648)
1405}
Harald Welteb0d93602018-03-20 18:09:34 +01001406
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +02001407function f_sip_next_seq_nr(integer seq_nr) return integer {
1408 return (seq_nr + 1) mod 2147483648;
1409}
1410
1411function f_sip_Request_inc_seq_nr(inout template (value) PDU_SIP_Request req) {
1412 req.msgHeader.cSeq.seqNumber := f_sip_next_seq_nr(valueof(req.msgHeader.cSeq.seqNumber));
1413}
1414
Pau Espin Pedrol05eaa1a2024-04-02 12:56:26 +02001415function f_sip_rand_tag() return charstring {
Pau Espin Pedrol95ad6a02024-04-18 16:52:46 +02001416 /* Tags shall have at least 32 bit of randomness */
Pau Espin Pedrol05eaa1a2024-04-02 12:56:26 +02001417 var integer rnd_int := f_rnd_int(4294967296);
Pau Espin Pedrol95ad6a02024-04-18 16:52:46 +02001418 /* Make collisions harder by appending time to the final string: */
1419 var integer ts_int := f_time_ms() mod 4294967296;
1420 return hex2str(int2hex(rnd_int, 8)) & "-" & hex2str(int2hex(ts_int, 8));
Pau Espin Pedrol05eaa1a2024-04-02 12:56:26 +02001421}
1422
1423/* Generate a "branch" tag value.
1424 * RFC 3261 p.105 section 8:
1425 * "A common way to create this value is to compute a
1426 * cryptographic hash of the To tag, From tag, Call-ID header
1427 * field, the Request-URI of the request received (before
1428 * translation), the topmost Via header, and the sequence number
1429 * from the CSeq header field, in addition to any Proxy-Require
1430 * and Proxy-Authorization header fields that may be present. The
1431 * algorithm used to compute the hash is implementation-dependent,
1432 * but MD5 (RFC 1321 [35]),expressed in hexadecimal, is a reasonable
1433 * choice."
1434 * See also Section 8.1.1.7:
1435 * "The branch ID inserted by an element compliant with this
1436 * specification MUST always begin with the characters "z9hG4bK"."
1437 */
1438const charstring sip_magic_cookie := "z9hG4bK";
1439function f_sip_gen_branch(charstring tag_to,
1440 charstring tag_from,
1441 charstring tag_call_id,
1442 integer cseq) return charstring {
1443 var charstring str := tag_to & tag_from & tag_call_id & int2str(cseq);
1444 var charstring hash := f_calculateMD5(str);
1445 var charstring branch := sip_magic_cookie & hash;
1446 return branch;
1447}
1448
1449function f_sip_HostPort_to_str(HostPort host_port) return charstring {
1450 var charstring str := "";
1451 if (ispresent(host_port.host)) {
1452 str := host_port.host;
1453 }
1454 if (ispresent(host_port.portField)) {
1455 str := str & ":" & int2str(host_port.portField);
1456 }
1457 return str;
1458}
1459
1460function f_sip_SipUrl_to_str(SipUrl uri) return charstring {
Pau Espin Pedrolb0dbf7a2024-05-22 18:12:15 +02001461 var charstring str := uri.scheme & ":";
1462 if (ispresent(uri.userInfo)) {
1463 str := str & uri.userInfo.userOrTelephoneSubscriber & "@";
1464 }
1465 str := str & f_sip_HostPort_to_str(uri.hostPort);
Pau Espin Pedrol05eaa1a2024-04-02 12:56:26 +02001466 return str;
1467}
1468
1469function f_sip_NameAddr_to_str(NameAddr naddr) return charstring {
1470 if (ispresent(naddr.displayName)) {
1471 return naddr.displayName & " <" & f_sip_SipUrl_to_str(naddr.addrSpec) & ">";
1472 } else {
1473 return f_sip_SipUrl_to_str(naddr.addrSpec);
1474 }
1475}
1476
1477function f_sip_SipAddr_to_str(SipAddr sip_addr) return charstring {
1478 if (ischosen(sip_addr.addr.nameAddr)) {
1479 return f_sip_NameAddr_to_str(sip_addr.addr.nameAddr);
1480 } else {
1481 return f_sip_SipUrl_to_str(sip_addr.addr.addrSpecUnion);
1482 }
1483}
1484
Harald Welteb0d93602018-03-20 18:09:34 +01001485}