blob: f251767eed4a9d687552b7a354055ea7c51043c7 [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}
Pau Espin Pedrol586eec52024-06-04 19:07:33 +0200229template (present) Expires tr_Expires(template (present) DeltaSec deltaSec := ?) := {
230 fieldName := EXPIRES_E,
231 deltaSec := deltaSec
232}
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100233
Pau Espin Pedrol41b0e072024-05-29 18:25:51 +0200234// [20.20]
235template (value) From ts_From(template (value) Addr_Union addressField,
236 template (omit) SemicolonParam_List fromParams := omit) := {
237 fieldName := FROM_E,
238 addressField := addressField,
239 fromParams := fromParams
240}
241template (present) From tr_From(template (present) Addr_Union addressField := ?,
242 template SemicolonParam_List fromParams := *) := {
243 fieldName := FROM_E,
244 addressField := addressField,
245 fromParams := fromParams
246}
247
Pau Espin Pedrol0c5c6472024-05-21 13:13:49 +0200248// [RFC3455 5.4] + 3GPP 24.229 V8.7.0
249template (present) Access_net_spec tr_Access_net_spec(template (present) charstring access_type := ?,
250 template SemicolonParam_List access_info := *) := {
251 access_type := access_type,
252 access_info := access_info
253}
254template (present) Access_net_spec tr_Access_net_spec_EUTRAN(template (present) charstring uli_str := ?) := {
255 access_type := "3GPP-E-UTRAN-FDD",
256 access_info := {tr_Param("utran-cell-id-3gpp", uli_str)}
257}
258
259// [RFC3455 5.4] + 3GPP 24.229 V8.7.0
260template (present) P_Access_Network_Info tr_P_Access_Network_Info(template (present) Access_net_spec_list access_net_specs := ?) := {
261 fieldName := P_ACCESS_NETWORK_INFO,
262 access_net_specs := access_net_specs
263}
264
Pau Espin Pedrol4e6672c2024-05-22 17:03:53 +0200265// [RFC3455 4.1]
266template (present) P_Assoc_uri_spec tr_P_Assoc_uri_spec(template (present) NameAddr p_asso_uri := ?,
267 template SemicolonParam_List ai_params := *) := {
268 p_asso_uri := p_asso_uri,
269 ai_params := ai_params
270}
271template (value) P_Assoc_uri_spec ts_P_Assoc_uri_spec(template (value) NameAddr p_asso_uri,
272 template (omit) SemicolonParam_List ai_params := omit) := {
273 p_asso_uri := p_asso_uri,
274 ai_params := ai_params
275}
276
277// [RFC3455 4.1]
278template (present) P_Associated_Uri tr_P_Associated_Uri(template (present) P_Assoc_uri_spec_list p_assoc_uris := ?) := {
279 fieldName := P_ASSOCIATED_URI,
280 p_assoc_uris := p_assoc_uris
281}
282template (value) P_Associated_Uri ts_P_Associated_Uri(template (value) P_Assoc_uri_spec_list p_assoc_uris := {}) := {
283 fieldName := P_ASSOCIATED_URI,
284 p_assoc_uris := p_assoc_uris
285}
Pau Espin Pedrol73f6a312024-05-10 20:30:16 +0200286
287// [20.32]
288template (value) Require ts_Require(template (value) OptionTag_List optionsTags := {}) := {
289 fieldName := REQUIRE_E,
290 optionsTags := optionsTags
291}
292template (present) Require tr_Require(template (present) OptionTag_List optionsTags := ?) := {
293 fieldName := REQUIRE_E,
294 optionsTags := optionsTags
295}
296
Pau Espin Pedrol52cc2e52024-05-13 17:50:20 +0200297// [20.35 RFC2616 14.38]
298template (value) Server ts_Server(template (value) ServerVal_List serverBody := {}) := {
299 fieldName := SERVER_E,
300 serverBody := serverBody
301}
302template (present) Server tr_Server(template (present) ServerVal_List serverBody := ?) := {
303 fieldName := SERVER_E,
304 serverBody := serverBody
305}
306
Pau Espin Pedrol73f6a312024-05-10 20:30:16 +0200307// [20.37]
308template (value) Supported ts_Supported(template (value) OptionTag_List optionsTags := {}) := {
309 fieldName := SUPPORTED_E,
310 optionsTags := optionsTags
311}
312template (present) Supported tr_Supported(template (present) OptionTag_List optionsTags := ?) := {
313 fieldName := SUPPORTED_E,
314 optionsTags := optionsTags
315}
316
Pau Espin Pedrol41b0e072024-05-29 18:25:51 +0200317// [20.39]
318template (value) To ts_To(template (value) Addr_Union addressField,
319 template (omit) SemicolonParam_List toParams := omit) := {
320 fieldName := TO_E,
321 addressField := addressField,
322 toParams := toParams
323}
324template (present) To tr_To(template (present) Addr_Union addressField := ?,
325 template SemicolonParam_List toParams := *) := {
326 fieldName := TO_E,
327 addressField := addressField,
328 toParams := toParams
329}
330
Pau Espin Pedrol13c50ac2024-05-13 17:48:09 +0200331// [20.41 RFC2616 14.43]
332template (value) UserAgent ts_UserAgent(template (value) ServerVal_List userAgentBody := {}) := {
333 fieldName := USER_AGENT_E,
334 userAgentBody := userAgentBody
335}
336template (present) UserAgent tr_UserAgent(template (present) ServerVal_List userAgentBody := ?) := {
337 fieldName := USER_AGENT_E,
338 userAgentBody := userAgentBody
339}
340
Pau Espin Pedrol73f6a312024-05-10 20:30:16 +0200341
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100342template (value) SipAddr ts_SipAddr(template (value) HostPort host_port,
343 template (omit) UserInfo user_info := omit,
344 template (omit) charstring displayName := omit,
345 template (omit) SemicolonParam_List params := omit) := {
Harald Welteb0d93602018-03-20 18:09:34 +0100346 addr := {
347 nameAddr := {
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100348 displayName := displayName,
349 addrSpec := ts_SipUrl(host_port, user_info)
Harald Welteb0d93602018-03-20 18:09:34 +0100350 }
351 },
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100352 params := params
353}
354template (present) SipAddr tr_SipAddr(template (present) HostPort host_port := ?,
355 template UserInfo user_info := *,
356 template charstring displayName := *,
357 template SemicolonParam_List params := *) := {
358 addr := {
359 nameAddr := {
360 displayName := displayName,
361 addrSpec := tr_SipUrl(host_port, user_info)
362 }
363 },
364 params := params
Harald Welteb0d93602018-03-20 18:09:34 +0100365}
366
367/* build a receive template from a value: substitute '*' for omit */
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200368function tr_SipUrl_from_val(template (value) SipUrl tin) return template (present) SipUrl {
369 var template (present) SipUrl ret := tin;
370
371 /* if the port number is 5060, it may be omitted */
372 if (ispresent(tin.hostPort.portField) and
373 valueof(tin.hostPort.portField) == 5060) {
374 ret.hostPort.portField := 5060 ifpresent;
375 }
376 if (not ispresent(tin.userInfo.password)) {
377 ret.userInfo.password := *;
378 }
379
380 return ret;
381}
Pau Espin Pedrol41b0e072024-05-29 18:25:51 +0200382function tr_Addr_Union_from_val(template (value) Addr_Union tin) return template (present) Addr_Union {
383 var template (present) Addr_Union ret := tin;
384
385 if (not ispresent(tin.nameAddr.displayName)) {
386 ret.nameAddr.displayName := *;
387 } else if (f_str_tolower(f_sip_str_unquote(tin.nameAddr.displayName)) == "anonymous") {
388 /* if the user is Anonymous, it may be omitted */
389 ret.nameAddr.displayName := tin.nameAddr.displayName ifpresent;
390 }
391
392 ret.nameAddr.addrSpec := tr_SipUrl_from_val(tin.nameAddr.addrSpec);
393
394 return ret;
395}
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200396function tr_SipAddr_from_val(template (value) SipAddr tin) return template (present) SipAddr {
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100397 var template (present) SipAddr ret := tin;
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200398
Pau Espin Pedrol41b0e072024-05-29 18:25:51 +0200399 ret.addr := tr_Addr_Union_from_val(tin.addr);
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200400
401 if (not ispresent(tin.params)) {
Harald Welteb0d93602018-03-20 18:09:34 +0100402 ret.params := *;
403 }
404 return ret;
405}
406
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200407function ts_SipAddr_from_Addr_Union(template (value) Addr_Union au,
408 template (omit) SemicolonParam_List params := omit)
409return template (value) SipAddr {
410 var template (value) SipUrl addrSpec := ts_SipUrl_from_Addr_Union(au);
411 var template (omit) charstring displayName;
412
413 if (ischosen(au.nameAddr)) {
414 displayName := au.nameAddr.displayName;
415 } else { /* au.addrSpecUnion */
416 displayName := omit
417 }
418
419 return ts_SipAddr(addrSpec.hostPort,
420 addrSpec.userInfo,
421 displayName,
422 params);
423}
424
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100425template (value) HostPort ts_HostPort(template (omit) charstring host := omit,
426 template (omit) integer portField := omit) := {
427 host := host,
428 portField := portField
429}
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200430
431template (present) HostPort tr_HostPort(template charstring host := *,
432 template integer portField := *) := {
433 host := host,
434 portField := portField
435}
436function f_tr_HostPort(template charstring host := *,
437 template integer portField := *)
438return template (present) HostPort {
439 return f_tr_HostPort_opt_defport(tr_HostPort(host, portField));
440}
441function f_tr_HostPort_opt_defport(template (present) HostPort hp) return template (present) HostPort {
442 var template (present) HostPort hpout := hp;
Harald Welteb0d93602018-03-20 18:09:34 +0100443 /* if the port number is 5060, it may be omitted */
444 if (isvalue(hp.portField) and valueof(hp.portField) == 5060) {
445 hpout.portField := 5060 ifpresent;
446 }
447 return hpout;
448}
449
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200450function f_tr_SipUrl_opt_defport(template (present) SipUrl url) return template (present) SipUrl {
451 var template (present) SipUrl urlout := url;
452 urlout.hostPort := f_tr_HostPort_opt_defport(url.hostPort);
453 return urlout;
454}
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100455
456template (value) UserInfo ts_UserInfo(template (value) charstring userOrTelephoneSubscriber,
457 template (omit) charstring password := omit) := {
458 userOrTelephoneSubscriber := userOrTelephoneSubscriber,
459 password := password
460}
461template (present) UserInfo tr_UserInfo(template (present) charstring userOrTelephoneSubscriber := ?,
462 template charstring password := *) := {
463 userOrTelephoneSubscriber := userOrTelephoneSubscriber,
464 password := password
465}
466
467template (value) RequestLine ts_SIP_ReqLine(Method method,
468 template (value) SipUrl uri,
Harald Welteb0d93602018-03-20 18:09:34 +0100469 charstring ver := c_SIP_VERSION) := {
470 method := method,
471 requestUri := uri,
472 sipVersion := ver
473}
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100474template (present) RequestLine tr_SIP_ReqLine(template (present) Method method := ?,
475 template (present) SipUrl uri := ?,
476 template (present) charstring ver := c_SIP_VERSION) := {
Harald Welteb0d93602018-03-20 18:09:34 +0100477 method := method,
478 requestUri := uri,
479 sipVersion := ver
480}
481
482template (value) StatusLine ts_SIP_StatusLine(integer status_code, charstring reason) := {
483 sipVersion := "SIP/2.0",
484 statusCode := status_code,
485 reasonPhrase := reason
486}
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100487template (present) StatusLine tr_SIP_StatusLine(template integer status_code,
488 template charstring reason) := {
Harald Welteb0d93602018-03-20 18:09:34 +0100489 sipVersion := "SIP/2.0",
490 statusCode := status_code,
491 reasonPhrase := reason
492}
493
494
495template (value) PDU_SIP_Request ts_SIP_req(template (value) RequestLine rl) := {
496 requestLine := rl,
497 msgHeader := c_SIP_msgHeader_empty,
498 messageBody := omit,
499 payload := omit
500}
501
502const Method_List c_SIP_defaultMethods := {
503 "INVITE", "ACK", "BYE", "CANCEL", "OPTIONS", "PRACK", "MESSAGE", "SUBSCRIBE",
504 "NOTIFY", "REFER", "UPDATE" };
505
506private function f_ContentTypeOrOmit(template (omit) ContentType ct, template (omit) charstring body)
507return template (omit) ContentType {
508 /* if user explicitly stated no content type */
509 if (istemplatekind(ct, "omit")) {
510 return omit;
511 }
512 /* if there's no body, then there's no content-type either */
513 if (istemplatekind(body, "omit")) {
514 return omit;
515 }
516 return ct;
517}
518
Pau Espin Pedrol5c36a652024-05-14 16:05:59 +0200519private function f_ContentLength(template (omit) charstring body)
520return template (value) ContentLength {
521 /* rfc3261 20.14: "If no body is present in a message, then the
522 * Content-Length header field value MUST be set to zero." */
523 if (istemplatekind(body, "omit")) {
524 return ts_ContentLength(0);
525 }
526 return ts_ContentLength(lengthof(body));
527}
528
Harald Welteb0d93602018-03-20 18:09:34 +0100529template (value) ContentType ts_CT_SDP := {
530 fieldName := CONTENT_TYPE_E,
531 mediaType := "application/sdp"
532};
533
Pau Espin Pedrol2a833372024-05-10 20:23:22 +0200534template (value) Via ts_Via_from(template (value) HostPort addr,
535 template (value) charstring transport := "UDP") := {
Harald Welteb0d93602018-03-20 18:09:34 +0100536 fieldName := VIA_E,
537 viaBody := {
538 {
Pau Espin Pedrol2a833372024-05-10 20:23:22 +0200539 sentProtocol := { "SIP", "2.0", transport },
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100540 sentBy := addr,
Harald Welteb0d93602018-03-20 18:09:34 +0100541 viaParams := omit
542 }
543 }
544}
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100545template (present) Via tr_Via_from(template (present) HostPort host_port := ?,
Pau Espin Pedrol2a833372024-05-10 20:23:22 +0200546 template (present) charstring transport := ?,
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100547 template SemicolonParam_List viaParams := *) := {
548 fieldName := VIA_E,
549 viaBody := {
550 {
Pau Espin Pedrol2a833372024-05-10 20:23:22 +0200551 sentProtocol := { "SIP", "2.0", ? },
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100552 sentBy := host_port,
553 viaParams := viaParams
554 }
555 }
Pau Espin Pedrol05eaa1a2024-04-02 12:56:26 +0200556}
557
558template (present) OtherAuth
559tr_OtherAuth(template (present) charstring authScheme := ?,
560 template (present) CommaParam_List authParams := ?) := {
561 authScheme := authScheme,
562 authParams := authParams
563}
564
565template (value) OtherAuth
566ts_OtherAuth(template (value) charstring authScheme,
567 template (value) CommaParam_List authParams) := {
568 authScheme := authScheme,
569 authParams := authParams
570}
571
572template (present) Challenge
573tr_Challenge_digestCln(template (present) CommaParam_List digestCln := ?) := {
574 digestCln := digestCln
575}
576
577template (value) Challenge
578ts_Challenge_digestCln(template (value) CommaParam_List digestCln) := {
579 digestCln := digestCln
580}
581
582template (present) Challenge
583tr_Challenge_otherChallenge(template (present) OtherAuth otherChallenge := ?) := {
584 otherChallenge := otherChallenge
585}
586
587template (value) Challenge
588ts_Challenge_otherChallenge(template (value) OtherAuth otherChallenge) := {
589 otherChallenge := otherChallenge
590}
591
592template (present) WwwAuthenticate
593tr_WwwAuthenticate(template (present) Challenge_list challenge := ?) := {
594 fieldName := WWW_AUTHENTICATE_E,
595 challenge := challenge
596}
597
598template (value) WwwAuthenticate
599ts_WwwAuthenticate(template (value) Challenge_list challenge) := {
600 fieldName := WWW_AUTHENTICATE_E,
601 challenge := challenge
602}
Harald Welteb0d93602018-03-20 18:09:34 +0100603
Pau Espin Pedrol73f6a312024-05-10 20:30:16 +0200604// RFC3329
605template (present) Security_client
606tr_Security_client(template (present) Security_mechanism_list sec_mechanism_list := ?) := {
607 fieldName := SECURITY_CLIENT_E,
608 sec_mechanism_list := sec_mechanism_list
609}
610template (value) Security_client
611ts_Security_client(template (value) Security_mechanism_list sec_mechanism_list) := {
612 fieldName := SECURITY_CLIENT_E,
613 sec_mechanism_list := sec_mechanism_list
614}
615
Pau Espin Pedrol7f411562024-05-13 13:58:41 +0200616template (present) Security_server
617tr_Security_server(template (present) Security_mechanism_list sec_mechanism_list := ?) := {
618 fieldName := SECURITY_SERVER_E,
619 sec_mechanism_list := sec_mechanism_list
620}
621template (value) Security_server
622ts_Security_server(template (value) Security_mechanism_list sec_mechanism_list) := {
623 fieldName := SECURITY_SERVER_E,
624 sec_mechanism_list := sec_mechanism_list
625}
626
Pau Espin Pedrol73f6a312024-05-10 20:30:16 +0200627template (present) Security_mechanism
628tr_Security_mechanism(template (present) charstring name := ?,
629 template SemicolonParam_List params := *) := {
630 mechanism_name := name,
631 mechanism_params := params
632}
633template (value) Security_mechanism
634ts_Security_mechanism(template (value) charstring name,
635 template (omit) SemicolonParam_List params := omit) := {
636 mechanism_name := name,
637 mechanism_params := params
638}
639
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100640template (value) MessageHeader ts_SIP_msgHeader_empty := c_SIP_msgHeader_empty;
641template (value) MessageHeader
642ts_SIP_msgh_std(template (value) CallidString call_id,
Pau Espin Pedrol41b0e072024-05-29 18:25:51 +0200643 template (value) From from_addr,
644 template (value) To to_addr,
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100645 template (omit) Contact contact,
646 template (value) charstring method,
647 template (value) integer seq_nr,
648 template (value) Via via,
Pau Espin Pedrol5c36a652024-05-14 16:05:59 +0200649 template (omit) ContentLength content_length := ts_ContentLength(0),
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100650 template (omit) ContentType content_type := omit,
Pau Espin Pedrol05eaa1a2024-04-02 12:56:26 +0200651 template (omit)Authorization authorization := omit,
Pau Espin Pedrolcb3a15b2024-05-13 16:25:11 +0200652 template (omit) Allow allow := ts_Allow(c_SIP_defaultMethods),
Pau Espin Pedrol89d8c952024-05-10 20:28:24 +0200653 template (omit) Expires expires := omit,
Pau Espin Pedrol4e6672c2024-05-22 17:03:53 +0200654 template (omit) P_Associated_Uri p_associated_uri := omit,
Pau Espin Pedrol73f6a312024-05-10 20:30:16 +0200655 template (omit) Require require := omit,
656 template (omit) Security_client security_client := omit,
Pau Espin Pedrol7f411562024-05-13 13:58:41 +0200657 template (omit) Security_server security_server := omit,
Pau Espin Pedrol52cc2e52024-05-13 17:50:20 +0200658 template (omit) Server server := omit,
Pau Espin Pedrol73f6a312024-05-10 20:30:16 +0200659 template (omit) Supported supported := omit,
Pau Espin Pedrol13c50ac2024-05-13 17:48:09 +0200660 template (omit) UserAgent userAgent := ts_UserAgent({ "osmo-ttcn3-hacks/0.23" }),
Pau Espin Pedrol89d8c952024-05-10 20:28:24 +0200661 template (omit) WwwAuthenticate wwwAuthenticate := omit
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100662 ) modifies ts_SIP_msgHeader_empty := {
Pau Espin Pedrolcb3a15b2024-05-13 16:25:11 +0200663 allow := allow,
Pau Espin Pedrol05eaa1a2024-04-02 12:56:26 +0200664 authorization := authorization,
Harald Welteb0d93602018-03-20 18:09:34 +0100665 callId := {
666 fieldName := CALL_ID_E,
667 callid := call_id
668 },
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100669 contact := contact,
Pau Espin Pedrol5c36a652024-05-14 16:05:59 +0200670 contentLength := content_length,
Harald Welteb0d93602018-03-20 18:09:34 +0100671 contentType := content_type,
672 cSeq := {
673 fieldName := CSEQ_E,
674 seqNumber := seq_nr,
675 method := method
676 },
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100677 expires := expires,
Pau Espin Pedrol41b0e072024-05-29 18:25:51 +0200678 fromField := from_addr,
Pau Espin Pedrol4e6672c2024-05-22 17:03:53 +0200679 p_associated_uri := p_associated_uri,
Pau Espin Pedrol73f6a312024-05-10 20:30:16 +0200680 require := require,
681 security_client := security_client,
Pau Espin Pedrol7f411562024-05-13 13:58:41 +0200682 security_server := security_server,
Pau Espin Pedrol52cc2e52024-05-13 17:50:20 +0200683 server := server,
Pau Espin Pedrol73f6a312024-05-10 20:30:16 +0200684 supported := supported,
Pau Espin Pedrol41b0e072024-05-29 18:25:51 +0200685 toField := to_addr,
Pau Espin Pedrol13c50ac2024-05-13 17:48:09 +0200686 userAgent := userAgent,
Pau Espin Pedrol89d8c952024-05-10 20:28:24 +0200687 via := via,
688 wwwAuthenticate := wwwAuthenticate
Harald Welteb0d93602018-03-20 18:09:34 +0100689}
690
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100691template (present) MessageHeader
692tr_SIP_msgh_std(template CallidString call_id,
Pau Espin Pedrol41b0e072024-05-29 18:25:51 +0200693 template From from_addr,
694 template To to_addr,
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100695 template Contact contact,
696 template (present) Via via := tr_Via_from(?),
697 template charstring method,
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100698 template integer seq_nr := ?,
Pau Espin Pedrol5c36a652024-05-14 16:05:59 +0200699 template ContentLength content_length := *,
700 template ContentType content_type := *,
Pau Espin Pedrolcb3a15b2024-05-13 16:25:11 +0200701 template Allow allow := *,
Pau Espin Pedrola674d612024-05-14 19:56:33 +0200702 template Authorization authorization := *,
Pau Espin Pedrol05eaa1a2024-04-02 12:56:26 +0200703 template Expires expires := *,
Pau Espin Pedrol4e6672c2024-05-22 17:03:53 +0200704 template P_Associated_Uri p_associated_uri := *,
Pau Espin Pedrol73f6a312024-05-10 20:30:16 +0200705 template Require require := *,
706 template Security_client security_client := *,
Pau Espin Pedrol7f411562024-05-13 13:58:41 +0200707 template Security_server security_server := *,
Pau Espin Pedrol52cc2e52024-05-13 17:50:20 +0200708 template Server server := *,
Pau Espin Pedrol73f6a312024-05-10 20:30:16 +0200709 template Supported supported := *,
Pau Espin Pedrol13c50ac2024-05-13 17:48:09 +0200710 template UserAgent userAgent := *,
Pau Espin Pedrol05eaa1a2024-04-02 12:56:26 +0200711 template WwwAuthenticate wwwAuthenticate := *
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100712 ) modifies t_SIP_msgHeader_any := {
Pau Espin Pedrolcb3a15b2024-05-13 16:25:11 +0200713 allow := allow,
Pau Espin Pedrola674d612024-05-14 19:56:33 +0200714 authorization := authorization,
Harald Welteb0d93602018-03-20 18:09:34 +0100715 callId := {
716 fieldName := CALL_ID_E,
717 callid := call_id
718 },
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100719 contact := contact,
Pau Espin Pedrol5c36a652024-05-14 16:05:59 +0200720 contentLength := content_length,
Harald Welteb0d93602018-03-20 18:09:34 +0100721 contentType := content_type,
722 cSeq := {
723 fieldName := CSEQ_E,
724 seqNumber := seq_nr,
725 method := method
726 },
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100727 expires := expires,
Pau Espin Pedrol41b0e072024-05-29 18:25:51 +0200728 fromField := from_addr,
Pau Espin Pedrol4e6672c2024-05-22 17:03:53 +0200729 p_associated_uri := p_associated_uri,
Pau Espin Pedrol73f6a312024-05-10 20:30:16 +0200730 require := require,
731 security_client := security_client,
Pau Espin Pedrol7f411562024-05-13 13:58:41 +0200732 security_server := security_server,
Pau Espin Pedrol52cc2e52024-05-13 17:50:20 +0200733 server := server,
Pau Espin Pedrol73f6a312024-05-10 20:30:16 +0200734 supported := supported,
Pau Espin Pedrol41b0e072024-05-29 18:25:51 +0200735 toField := to_addr,
Pau Espin Pedrol13c50ac2024-05-13 17:48:09 +0200736 userAgent := userAgent,
Pau Espin Pedrol05eaa1a2024-04-02 12:56:26 +0200737 via := via,
738 wwwAuthenticate := wwwAuthenticate
Harald Welteb0d93602018-03-20 18:09:34 +0100739}
740
741
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100742template (value) PDU_SIP_Request
743ts_SIP_REGISTER(template (value) SipUrl sip_url_host_port,
744 template (value) CallidString call_id,
Pau Espin Pedrol41b0e072024-05-29 18:25:51 +0200745 template (value) From from_addr,
746 template (value) To to_addr,
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100747 template (value) Via via,
748 integer seq_nr,
749 template (omit) Contact contact,
750 template (omit) Expires expires,
Pau Espin Pedrol05eaa1a2024-04-02 12:56:26 +0200751 template (omit) Authorization authorization := omit,
Pau Espin Pedrol73f6a312024-05-10 20:30:16 +0200752 template (omit) Require require := omit,
753 template (omit) Security_client security_client := omit,
754 template (omit) Supported supported := omit,
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100755 template (omit) charstring body := omit) := {
756 requestLine := ts_SIP_ReqLine(REGISTER_E, sip_url_host_port),
757 msgHeader := ts_SIP_msgh_std(call_id, from_addr, to_addr, contact,
758 "REGISTER", seq_nr, via,
Pau Espin Pedrol5c36a652024-05-14 16:05:59 +0200759 content_length := f_ContentLength(body),
760 content_type := f_ContentTypeOrOmit(ts_CT_SDP, body),
Pau Espin Pedrol05eaa1a2024-04-02 12:56:26 +0200761 authorization := authorization,
Pau Espin Pedrol73f6a312024-05-10 20:30:16 +0200762 expires := expires,
763 require := require,
764 security_client := security_client,
765 supported := supported),
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100766 messageBody := body,
767 payload := omit
768}
769template (present) PDU_SIP_Request
770tr_SIP_REGISTER(template (present) SipUrl sip_url_host_port := ?,
771 template (present) CallidString call_id := ?,
Pau Espin Pedrol41b0e072024-05-29 18:25:51 +0200772 template (present) From from_addr := ?,
773 template (present) To to_addr := ?,
Pau Espin Pedrol0dd3f262024-04-25 17:04:43 +0200774 template (present) Via via := tr_Via_from(f_tr_HostPort_opt_defport(?)),
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100775 template integer seq_nr := *,
Pau Espin Pedrola674d612024-05-14 19:56:33 +0200776 template Authorization authorization := *,
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100777 template Contact contact := *,
778 template Expires expires := *,
Pau Espin Pedrol73f6a312024-05-10 20:30:16 +0200779 template Require require := *,
780 template Security_client security_client := *,
781 template Supported supported := *,
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100782 template charstring body := *) := {
783 requestLine := tr_SIP_ReqLine(REGISTER_E, sip_url_host_port),
784 msgHeader := tr_SIP_msgh_std(call_id, from_addr, to_addr, contact,
Pau Espin Pedrol5c36a652024-05-14 16:05:59 +0200785 via, "REGISTER", seq_nr,
Pau Espin Pedrola674d612024-05-14 19:56:33 +0200786 authorization := authorization,
Pau Espin Pedrol73f6a312024-05-10 20:30:16 +0200787 expires := expires,
788 require := require,
789 security_client := security_client,
790 supported := supported),
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100791 messageBody := body,
792 payload := omit
793}
794
795template (value) PDU_SIP_Request
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200796ts_SIP_INVITE(template (value) CallidString call_id,
Pau Espin Pedrol41b0e072024-05-29 18:25:51 +0200797 template (value) From from_addr,
798 template (value) To to_addr,
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200799 template (value) Via via,
800 template (value) Contact contact,
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100801 integer seq_nr,
802 template (omit) charstring body := omit) := {
Pau Espin Pedrol41b0e072024-05-29 18:25:51 +0200803 requestLine := ts_SIP_ReqLine(INVITE_E, to_addr.addressField.nameAddr.addrSpec),
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200804 msgHeader := ts_SIP_msgh_std(call_id, from_addr, to_addr, contact,
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100805 "INVITE", seq_nr,
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200806 via,
Pau Espin Pedrol5c36a652024-05-14 16:05:59 +0200807 content_length := f_ContentLength(body),
808 content_type := f_ContentTypeOrOmit(ts_CT_SDP, body)),
Harald Welteb0d93602018-03-20 18:09:34 +0100809 messageBody := body,
810 payload := omit
811}
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100812template (present) PDU_SIP_Request
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200813tr_SIP_INVITE(template (present) SipUrl uri,
814 template CallidString call_id,
Pau Espin Pedrol41b0e072024-05-29 18:25:51 +0200815 template From from_addr,
816 template To to_addr,
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200817 template Via via := tr_Via_from(f_tr_HostPort_opt_defport(?)),
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100818 template integer seq_nr,
819 template charstring body) := {
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200820 requestLine := tr_SIP_ReqLine(INVITE_E, uri),
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100821 msgHeader := tr_SIP_msgh_std(call_id, from_addr, to_addr, ?,
Pau Espin Pedrol5c36a652024-05-14 16:05:59 +0200822 via, "INVITE", seq_nr),
Harald Welteb0d93602018-03-20 18:09:34 +0100823 messageBody := body,
824 payload := omit
825}
826
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100827template (value) PDU_SIP_Request
828ts_SIP_BYE(CallidString call_id,
Pau Espin Pedrol41b0e072024-05-29 18:25:51 +0200829 template (value) From from_addr,
830 template (value) To to_addr,
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200831 template (value) Via via,
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100832 integer seq_nr,
833 template (omit) charstring body) := {
Pau Espin Pedrol41b0e072024-05-29 18:25:51 +0200834 requestLine := ts_SIP_ReqLine(BYE_E, to_addr.addressField.nameAddr.addrSpec),
Harald Welteb0d93602018-03-20 18:09:34 +0100835 msgHeader := ts_SIP_msgh_std(call_id, from_addr, to_addr, omit, "BYE", seq_nr,
Pau Espin Pedrol5c36a652024-05-14 16:05:59 +0200836 via,
837 content_length := f_ContentLength(body),
838 content_type := f_ContentTypeOrOmit(ts_CT_SDP, body)),
Harald Welteb0d93602018-03-20 18:09:34 +0100839 messageBody := body,
840 payload := omit
841}
842
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100843template (present) PDU_SIP_Request
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200844tr_SIP_BYE(template (present) SipUrl uri,
845 template CallidString call_id,
Pau Espin Pedrol41b0e072024-05-29 18:25:51 +0200846 template From from_addr,
847 template To to_addr,
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200848 template Via via,
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100849 template integer seq_nr,
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200850 template charstring body := *) := {
851 requestLine := tr_SIP_ReqLine(BYE_E, uri),
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100852 msgHeader := tr_SIP_msgh_std(call_id, from_addr, to_addr, omit,
Pau Espin Pedrol5c36a652024-05-14 16:05:59 +0200853 via, "BYE", seq_nr),
Harald Welteb0d93602018-03-20 18:09:34 +0100854 messageBody := body,
855 payload := omit
856}
857
858
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100859template (value) PDU_SIP_Request
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200860ts_SIP_ACK(template (value) CallidString call_id,
Pau Espin Pedrol41b0e072024-05-29 18:25:51 +0200861 template (value) From from_addr,
862 template (value) To to_addr,
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200863 template (value) Via via,
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100864 integer seq_nr,
865 template (omit) charstring body) := {
Pau Espin Pedrol41b0e072024-05-29 18:25:51 +0200866 requestLine := ts_SIP_ReqLine(ACK_E, to_addr.addressField.nameAddr.addrSpec),
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100867 msgHeader := ts_SIP_msgh_std(call_id, from_addr, to_addr,
Pau Espin Pedrol41b0e072024-05-29 18:25:51 +0200868 ts_Contact({ ts_ContactAddress(from_addr.addressField, from_addr.fromParams) }),
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100869 "ACK", seq_nr,
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200870 via,
Pau Espin Pedrol5c36a652024-05-14 16:05:59 +0200871 content_length := f_ContentLength(body),
872 content_type := f_ContentTypeOrOmit(ts_CT_SDP, body)),
Harald Welteb0d93602018-03-20 18:09:34 +0100873 messageBody := body,
874 payload := omit
875}
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100876template (present) PDU_SIP_Request
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200877tr_SIP_ACK(template (present) SipUrl uri,
878 template CallidString call_id,
Pau Espin Pedrol41b0e072024-05-29 18:25:51 +0200879 template From from_addr,
880 template To to_addr,
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200881 template Via via,
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100882 template integer seq_nr,
883 template charstring body) := {
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200884 requestLine := tr_SIP_ReqLine(ACK_E, uri),
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100885 msgHeader := tr_SIP_msgh_std(call_id, from_addr, to_addr, *,
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200886 via,
Pau Espin Pedrol5c36a652024-05-14 16:05:59 +0200887 "ACK", seq_nr),
Harald Welteb0d93602018-03-20 18:09:34 +0100888 messageBody := body,
889 payload := omit
890}
891
Pau Espin Pedrol32167d82024-04-10 13:14:51 +0200892template (present) PDU_SIP_Request
893tr_SIP_CANCEL(template (present) SipUrl uri,
894 template (present) CallidString call_id,
Pau Espin Pedrol41b0e072024-05-29 18:25:51 +0200895 template (present) From from_addr,
896 template (present) To to_addr,
Pau Espin Pedrol32167d82024-04-10 13:14:51 +0200897 template (present) Via via,
898 template (present) integer seq_nr,
899 template charstring body := *) := {
900 requestLine := tr_SIP_ReqLine(CANCEL_E, uri),
901 msgHeader := tr_SIP_msgh_std(call_id, from_addr, to_addr, *,
902 via,
Pau Espin Pedrol5c36a652024-05-14 16:05:59 +0200903 "CANCEL", seq_nr),
Pau Espin Pedrol32167d82024-04-10 13:14:51 +0200904 messageBody := body,
905 payload := omit
906}
907
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100908template (value) PDU_SIP_Response
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200909ts_SIP_Response(template (value) CallidString call_id,
Pau Espin Pedrol41b0e072024-05-29 18:25:51 +0200910 template (value) From from_addr,
911 template (value) To to_addr,
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100912 charstring method,
913 integer status_code,
914 integer seq_nr,
915 charstring reason,
916 Via via,
Pau Espin Pedrola674d612024-05-14 19:56:33 +0200917 template (omit) Allow allow := omit,
Pau Espin Pedrol586eec52024-06-04 19:07:33 +0200918 template (omit) Contact contact := omit,
Pau Espin Pedrol4e6672c2024-05-22 17:03:53 +0200919 template (omit) P_Associated_Uri p_associated_uri := omit,
Pau Espin Pedrola674d612024-05-14 19:56:33 +0200920 template (omit) Require require := omit,
921 template (omit) Server server := omit,
922 template (omit) Supported supported := omit,
923 template (omit) UserAgent userAgent := omit,
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100924 template (omit) charstring body := omit) := {
Harald Welteb0d93602018-03-20 18:09:34 +0100925 statusLine := ts_SIP_StatusLine(status_code, reason),
Pau Espin Pedrol586eec52024-06-04 19:07:33 +0200926 msgHeader := ts_SIP_msgh_std(call_id, from_addr, to_addr, contact, method, seq_nr,
Pau Espin Pedrol5c36a652024-05-14 16:05:59 +0200927 via,
928 content_length := f_ContentLength(body),
Pau Espin Pedrola674d612024-05-14 19:56:33 +0200929 content_type := f_ContentTypeOrOmit(ts_CT_SDP, body),
930 allow := allow,
Pau Espin Pedrol4e6672c2024-05-22 17:03:53 +0200931 p_associated_uri := p_associated_uri,
Pau Espin Pedrola674d612024-05-14 19:56:33 +0200932 require := require,
933 server := server,
934 supported := supported,
935 userAgent := userAgent),
Harald Welteb0d93602018-03-20 18:09:34 +0100936 messageBody := body,
937 payload := omit
938}
Pau Espin Pedrol1b5f7ba2024-05-13 16:38:38 +0200939/* 100 Trying */
940template (value) PDU_SIP_Response
941ts_SIP_Response_Trying(
942 template (value) CallidString call_id,
Pau Espin Pedrol41b0e072024-05-29 18:25:51 +0200943 template (value) From from_addr,
944 template (value) To to_addr,
Pau Espin Pedrol1b5f7ba2024-05-13 16:38:38 +0200945 Via via,
946 integer seq_nr,
947 charstring method := "INVITE",
Pau Espin Pedrola2812ec2024-05-10 20:30:44 +0200948 template (omit) Allow allow := omit,
949 template (omit) Server server := omit,
950 template (omit) UserAgent userAgent := omit,
Pau Espin Pedrol1b5f7ba2024-05-13 16:38:38 +0200951 template (omit) charstring body := omit) := {
952 statusLine := ts_SIP_StatusLine(100, "Trying"),
953 msgHeader := ts_SIP_msgh_std(call_id, from_addr, to_addr, omit, method, seq_nr,
Pau Espin Pedrol5c36a652024-05-14 16:05:59 +0200954 via,
955 content_length := f_ContentLength(body),
Pau Espin Pedrola2812ec2024-05-10 20:30:44 +0200956 content_type := f_ContentTypeOrOmit(ts_CT_SDP, body),
957 allow := allow,
958 server := server,
959 userAgent := userAgent),
Pau Espin Pedrol1b5f7ba2024-05-13 16:38:38 +0200960 messageBody := body,
961 payload := omit
962}
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200963/* 180 Ringing */
964template (value) PDU_SIP_Response
965ts_SIP_Response_Ringing(
966 template (value) CallidString call_id,
Pau Espin Pedrol41b0e072024-05-29 18:25:51 +0200967 template (value) From from_addr,
968 template (value) To to_addr,
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200969 Via via,
970 integer seq_nr,
971 charstring method := "INVITE",
972 template (omit) charstring body := omit) := {
973 statusLine := ts_SIP_StatusLine(180, "Ringing"),
974 msgHeader := ts_SIP_msgh_std(call_id, from_addr, to_addr, omit, method, seq_nr,
Pau Espin Pedrol5c36a652024-05-14 16:05:59 +0200975 via,
976 content_length := f_ContentLength(body),
977 content_type := f_ContentTypeOrOmit(ts_CT_SDP, body)),
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200978 messageBody := body,
979 payload := omit
980}
981
Pau Espin Pedrola2812ec2024-05-10 20:30:44 +0200982/* 401 Unauthorized */
983template (value) PDU_SIP_Response
984ts_SIP_Response_Unauthorized(
985 template (value) CallidString call_id,
Pau Espin Pedrol41b0e072024-05-29 18:25:51 +0200986 template (value) From from_addr,
987 template (value) To to_addr,
Pau Espin Pedrola2812ec2024-05-10 20:30:44 +0200988 Via via,
989 template (value) WwwAuthenticate wwwAuthenticate,
990 integer seq_nr,
991 charstring method := "REGISTER",
992 template (omit) Allow allow := omit,
Pau Espin Pedrol4e6672c2024-05-22 17:03:53 +0200993 template (omit) P_Associated_Uri p_associated_uri := omit,
Pau Espin Pedrola2812ec2024-05-10 20:30:44 +0200994 template (omit) Security_server security_server := omit,
995 template (omit) Server server := omit,
996 template (omit) Supported supported := omit,
997 template (omit) UserAgent userAgent := omit,
998 template (omit) charstring body := omit) := {
999 statusLine := ts_SIP_StatusLine(401, "Unauthorized"),
1000 msgHeader := ts_SIP_msgh_std(call_id, from_addr, to_addr, omit, method, seq_nr,
1001 via,
1002 content_length := f_ContentLength(body),
1003 content_type := f_ContentTypeOrOmit(ts_CT_SDP, body),
1004 allow := allow,
Pau Espin Pedrol4e6672c2024-05-22 17:03:53 +02001005 p_associated_uri := p_associated_uri,
Pau Espin Pedrola2812ec2024-05-10 20:30:44 +02001006 security_server := security_server,
1007 server := server,
1008 supported := supported,
1009 userAgent := userAgent,
1010 wwwAuthenticate := wwwAuthenticate),
1011 messageBody := body,
1012 payload := omit
1013}
1014
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +01001015template (present) PDU_SIP_Response
1016tr_SIP_Response(template CallidString call_id,
Pau Espin Pedrol41b0e072024-05-29 18:25:51 +02001017 template From from_addr,
1018 template To to_addr,
Pau Espin Pedrol05eaa1a2024-04-02 12:56:26 +02001019 template (present) Via via := tr_Via_from(?),
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +01001020 template Contact contact,
1021 template charstring method,
1022 template integer status_code,
1023 template integer seq_nr := ?,
1024 template charstring reason := ?,
Pau Espin Pedrol05eaa1a2024-04-02 12:56:26 +02001025 template charstring body := *) := {
Harald Welteb0d93602018-03-20 18:09:34 +01001026 statusLine := tr_SIP_StatusLine(status_code, reason),
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +01001027 msgHeader := tr_SIP_msgh_std(call_id, from_addr, to_addr, contact,
Pau Espin Pedrol05eaa1a2024-04-02 12:56:26 +02001028 via,
Pau Espin Pedrol5c36a652024-05-14 16:05:59 +02001029 method, seq_nr),
Harald Welteb0d93602018-03-20 18:09:34 +01001030 messageBody := body,
1031 payload := omit
1032}
1033
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +02001034/* Expect during first REGISTER/INVITE/... when authorization is required: */
Pau Espin Pedrol37ee0ed2024-03-28 21:17:12 +01001035template (present) PDU_SIP_Response
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +02001036tr_SIP_Response_Unauthorized(
Pau Espin Pedrol37ee0ed2024-03-28 21:17:12 +01001037 template CallidString call_id,
Pau Espin Pedrol41b0e072024-05-29 18:25:51 +02001038 template From from_addr,
1039 template To to_addr,
Pau Espin Pedrol37ee0ed2024-03-28 21:17:12 +01001040 template (present) Via via := tr_Via_from(?),
1041 template Contact contact := *,
Pau Espin Pedrol05eaa1a2024-04-02 12:56:26 +02001042 template (present) WwwAuthenticate wwwAuthenticate := ?,
Pau Espin Pedrol37ee0ed2024-03-28 21:17:12 +01001043 template integer seq_nr := ?,
1044 template charstring method := "REGISTER",
1045 template integer status_code := 401,
1046 template charstring reason := "Unauthorized",
1047 template charstring body := *) := {
1048 statusLine := tr_SIP_StatusLine(status_code, reason),
1049 msgHeader := tr_SIP_msgh_std(call_id, from_addr, to_addr, contact,
1050 via,
Pau Espin Pedrol5c36a652024-05-14 16:05:59 +02001051 method, seq_nr,
Pau Espin Pedrol05eaa1a2024-04-02 12:56:26 +02001052 wwwAuthenticate := wwwAuthenticate),
Pau Espin Pedrol37ee0ed2024-03-28 21:17:12 +01001053 messageBody := body,
1054 payload := omit
1055}
Harald Welteb0d93602018-03-20 18:09:34 +01001056
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +02001057/* 100 Trying */
1058template (present) PDU_SIP_Response
1059tr_SIP_Response_Trying(
1060 template CallidString call_id,
Pau Espin Pedrol41b0e072024-05-29 18:25:51 +02001061 template From from_addr,
1062 template To to_addr,
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +02001063 template (present) Via via := tr_Via_from(?),
1064 template integer seq_nr := ?,
1065 template charstring method := "INVITE",
1066 template integer status_code := 100,
1067 template charstring reason := "Trying",
1068 template charstring body := *) := {
1069 statusLine := tr_SIP_StatusLine(status_code, reason),
1070 msgHeader := tr_SIP_msgh_std(call_id, from_addr, to_addr, omit,
1071 via,
Pau Espin Pedrol5c36a652024-05-14 16:05:59 +02001072 method, seq_nr),
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +02001073 messageBody := body,
1074 payload := omit
1075}
1076
1077/* 180 Ringing */
1078template (present) PDU_SIP_Response
1079tr_SIP_Response_Ringing(
1080 template CallidString call_id,
Pau Espin Pedrol41b0e072024-05-29 18:25:51 +02001081 template From from_addr,
1082 template To to_addr,
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +02001083 template (present) Via via := tr_Via_from(?),
1084 template integer seq_nr := ?,
1085 template charstring method := "INVITE",
1086 template integer status_code := 180,
1087 template charstring reason := "Ringing",
1088 template charstring body := *) := {
1089 statusLine := tr_SIP_StatusLine(status_code, reason),
1090 msgHeader := tr_SIP_msgh_std(call_id, from_addr, to_addr, *,
1091 via,
Pau Espin Pedrol5c36a652024-05-14 16:05:59 +02001092 method, seq_nr),
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +02001093 messageBody := body,
1094 payload := omit
1095}
1096
1097/****************
1098 * FUNCTIONS:
1099 ****************/
1100
Pau Espin Pedrol05eaa1a2024-04-02 12:56:26 +02001101function f_sip_param_find(GenericParam_List li,
1102 template (present) charstring id := ?)
1103return template (omit) GenericParam {
1104 var integer i;
1105
1106 for (i := 0; i < lengthof(li); i := i + 1) {
1107 if (not ispresent(li[i])) {
1108 continue;
1109 }
1110 if (match(li[i].id, id)) {
1111 return li[i];
1112 }
1113 }
1114 return omit;
1115}
1116
1117function f_sip_param_find_or_fail(GenericParam_List li,
1118 template (present) charstring id := ?)
1119return GenericParam {
1120 var template (omit) GenericParam parameter;
1121 parameter := f_sip_param_find(li, id);
1122 if (istemplatekind(parameter, "omit")) {
1123 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
1124 log2str("Param ", id, " not found in ", li));
1125 }
1126 return valueof(parameter);
1127}
1128
1129function f_sip_param_get_value(GenericParam_List li,
1130 template (present) charstring id := ?)
1131return template (omit) charstring {
1132 var template (omit) GenericParam parameter;
1133 parameter := f_sip_param_find(li, id);
1134 if (istemplatekind(parameter, "omit")) {
1135 return omit;
1136 }
1137 return parameter.paramValue;
1138}
1139
1140function f_sip_param_get_value_or_fail(GenericParam_List li,
1141 template (present) charstring id := ?)
1142return template (omit) charstring {
1143 var GenericParam parameter;
1144 parameter := f_sip_param_find_or_fail(li, id);
1145 return parameter.paramValue;
1146}
1147
1148function f_sip_param_get_value_present_or_fail(GenericParam_List li,
1149 template (present) charstring id := ?)
1150return charstring {
1151 var GenericParam parameter;
1152 parameter := f_sip_param_find_or_fail(li, id);
1153 if (not ispresent(parameter.paramValue)) {
1154 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
1155 log2str("Param ", id, " value not present in ", li));
1156 }
1157 return parameter.paramValue;
1158}
1159
1160function f_sip_param_match_value(GenericParam_List li,
1161 template (present) charstring id := ?,
1162 template charstring exp_paramValue := *)
1163return boolean {
1164 var template (omit) charstring val;
1165 val := f_sip_param_get_value_or_fail(li, id);
1166 if (istemplatekind(val, "omit")) {
1167 return istemplatekind(val, "omit") or istemplatekind(val, "*");
1168 }
1169 return match(valueof(val), exp_paramValue);
1170}
1171
1172function f_sip_param_match_value_or_fail(GenericParam_List li,
1173 template (present) charstring id := ?,
1174 template charstring exp_paramValue := *)
1175{
1176 var template (omit) charstring val := f_sip_param_get_value_or_fail(li, id);
1177 if (istemplatekind(val, "omit")) {
1178 if (istemplatekind(val, "omit") or istemplatekind(val, "*")) {
1179 return;
1180 } else {
1181 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
1182 log2str("Param ", id, " match failed: val ", val,
1183 " vs exp ", exp_paramValue));
1184 }
1185 }
1186 if (not match(valueof(val), exp_paramValue)) {
1187 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
1188 log2str("Param ", id, " match failed: val ", val,
1189 " vs exp ", exp_paramValue));
1190 }
1191}
1192
1193function f_sip_param_remove(template (omit) GenericParam_List li_tpl, charstring id)
1194return GenericParam_List {
1195 var integer i;
1196 var GenericParam_List li;
1197 var GenericParam_List new_li := {};
1198
1199 if (istemplatekind(li_tpl, "omit")) {
1200 return {};
1201 }
1202
1203 li := valueof(li_tpl);
1204 for (i := 0; i < lengthof(li); i := i + 1) {
1205 if (not ispresent(li[i]) or
1206 not match(li[i].id, id)) {
1207 new_li := new_li & {li[i]};
1208 }
1209 }
1210 return new_li;
1211}
1212
1213function f_sip_param_set(template (omit) GenericParam_List li_tpl, charstring id, charstring val)
1214return GenericParam_List {
1215 var integer i;
1216 var GenericParam_List li;
1217 var GenericParam_List new_li := {};
1218 var boolean found := false;
1219
1220 if (istemplatekind(li_tpl, "omit")) {
1221 return { valueof(ts_Param(id, val)) };
1222 }
1223
1224 li := valueof(li_tpl);
1225 for (i := 0; i < lengthof(li); i := i + 1) {
1226 if (not ispresent(li[i]) or
1227 not match(li[i].id, id)) {
1228 new_li := new_li & {li[i]};
1229 continue;
1230 }
1231 new_li := new_li & { valueof(ts_Param(li[i].id, val)) };
1232 found := true;
1233 }
1234
1235 if (not found) {
1236 new_li := new_li & { valueof(ts_Param(id, val)) };
1237 }
1238 return new_li;
1239}
1240
1241/* Make sure string is quoted. */
1242function f_sip_str_quote(template (value) charstring val) return charstring {
1243 var charstring str := valueof(val);
1244 if (lengthof(str) == 0) {
1245 return "";
1246 }
1247
1248 if (str[0] != "\"") {
1249 return "\"" & str & "\"";
1250 }
1251 return str;
1252}
1253
1254/* Make sure string is unquoted.
1255 * Similar to unq() in RFC 2617 */
1256function f_sip_str_unquote(template (value) charstring val) return charstring {
1257 var charstring str := valueof(val);
1258 var integer len := lengthof(str);
1259
1260 if (len <= 1) {
1261 return str;
1262 }
1263
1264 if (str[0] == "\"" and str[len - 1] == "\"") {
1265 return substr(str, 1, len - 2);
1266 }
1267 return str;
1268}
1269
1270/* RFC 2617 3.2.2.2 A1 */
1271function f_sip_digest_A1(charstring user, charstring realm, charstring password) return charstring {
1272
1273 /* RFC 2617 3.2.2.2 A1 */
1274 var charstring A1 := f_sip_str_unquote(user) & ":" &
1275 f_sip_str_unquote(realm) & ":" &
1276 password;
1277 var charstring digestA1 := f_str_tolower(f_calculateMD5(A1));
1278 log("A1: md5('", A1, "') = ", digestA1);
1279 return digestA1;
1280}
1281
1282/* RFC 2617 3.2.2.2 A2 */
1283function f_sip_digest_A2(charstring method, charstring uri) return charstring {
1284
1285 var charstring A2 := method & ":" & uri
1286 var charstring digestA2 := f_str_tolower(f_calculateMD5(A2));
1287 log("A2: md5('", A2, "') = ", digestA2);
1288 return digestA2;
1289}
1290
1291/* RFC 2617 3.2.2.1 Request-Digest */
1292function f_sip_digest_RequestDigest(charstring digestA1, charstring nonce,
1293 charstring nc, charstring cnonce,
1294 charstring qop, charstring digestA2) return charstring {
1295 var charstring digest_data := f_sip_str_unquote(nonce) & ":" &
1296 nc & ":" &
1297 cnonce & ":" &
1298 f_sip_str_unquote(qop) & ":" &
1299 digestA2;
1300 var charstring req_digest := f_sip_digest_KD(digestA1, digest_data);
1301 log("Request-Digest: md5('", digestA1, ":", digest_data ,"') = ", req_digest);
1302 return req_digest;
1303}
1304
1305/* RFC 2617 3.2.1 The WWW-Authenticate Response Header
1306 * KD(secret, data) = H(concat(secret, ":", data))
1307 */
1308function f_sip_digest_KD(charstring secret, charstring data) return charstring {
1309 return f_str_tolower(f_calculateMD5(secret & ":" & data));
1310}
1311
1312/* Digest Auth: RFC 2617 */
1313function f_sip_digest_gen_Authorization(WwwAuthenticate www_authenticate,
1314 charstring user, charstring password,
1315 charstring method, charstring uri,
1316 charstring cnonce := "0a4f113b", integer nc_int := 1) return Authorization {
1317 var CommaParam_List digestCln;
1318 var template (value) Authorization authorization;
1319 var template (value) Credentials cred;
1320 var template (omit) GenericParam rx_param;
1321
1322 digestCln := www_authenticate.challenge[0].digestCln;
1323
1324 var charstring algorithm;
1325 rx_param := f_sip_param_find(digestCln, "algorithm");
1326 if (istemplatekind(rx_param, "omit")) {
1327 /* Assume MD5 if not set */
1328 algorithm := "MD5"
1329 } else {
1330 algorithm := valueof(rx_param.paramValue);
1331 if (f_strstr(algorithm, "MD5") == -1) {
1332 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
1333 log2str("Unexpected algorithm: ", algorithm));
1334 }
1335 }
1336
1337 var charstring realm := f_sip_param_get_value_present_or_fail(digestCln, "realm");
1338 var charstring nonce := f_sip_param_get_value_present_or_fail(digestCln, "nonce");
1339 var charstring opaque := f_sip_param_get_value_present_or_fail(digestCln, "opaque");
1340 var charstring qop := f_sip_param_get_value_present_or_fail(digestCln, "qop");
1341
1342 if (f_strstr(qop, "auth") == -1) {
1343 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str("Unexpected qop: ", qop));
1344 }
1345 var charstring selected_qop := "auth";
1346
1347 /* RFC 2617 3.2.2.2 A1 */
1348 var charstring digestA1 := f_sip_digest_A1(user, realm, password);
1349 /* RFC 2617 3.2.2.3 A2 */
1350 var charstring digestA2 := f_sip_digest_A2(method, uri);
1351
1352 /* RFC 2617 3.2.2.1 Request-Digest */
1353 var charstring nc := f_str_tolower(hex2str(int2hex(nc_int, 8)));
1354 var charstring req_digest := f_sip_digest_RequestDigest(digestA1, nonce,
1355 nc, cnonce,
1356 selected_qop, digestA2);
1357
1358 cred := ts_Credentials_DigestResponseMD5(user, realm, nonce,
1359 uri, req_digest,
1360 opaque, algorithm, selected_qop, cnonce, nc);
1361
1362 authorization := ts_Authorization(cred);
1363 return valueof(authorization);
1364}
1365
1366/* RFC 2617 3.5 Example */
1367function f_sip_digest_selftest() {
1368/*
1369The following example assumes that an access-protected document is
1370being requested from the server via a GET request. The URI of the
1371document is "http://www.nowhere.org/dir/index.html". Both client and
1372server know that the username for this document is "Mufasa", and the
1373password is "Circle Of Life" (with one space between each of the
1374three words).
1375
1376HTTP/1.1 401 Unauthorized
1377WWW-Authenticate: Digest
1378 realm="testrealm@host.com",
1379 qop="auth,auth-int",
1380 nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093",
1381 opaque="5ccc069c403ebaf9f0171e9517f40e41"
1382
1383Authorization: Digest username="Mufasa",
1384 realm="testrealm@host.com",
1385 nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093",
1386 uri="/dir/index.html",
1387 qop=auth,
1388 nc=00000001,
1389 cnonce="0a4f113b",
1390 response="6629fae49393a05397450978507c4ef1",
1391 opaque="5ccc069c403ebaf9f0171e9517f40e41"
1392*/
1393 var template (value) CommaParam_List digestCln := {
1394 ts_Param("realm", f_sip_str_quote("testrealm@host.com")),
1395 ts_Param("qop", f_sip_str_quote("auth,auth-int")),
1396 ts_Param("nonce", f_sip_str_quote("dcd98b7102dd2f0e8b11d0f600bfb0c093")),
1397 ts_Param("opaque", f_sip_str_quote("5ccc069c403ebaf9f0171e9517f40e41"))
1398 };
1399 var template (value) WwwAuthenticate www_authenticate :=
1400 ts_WwwAuthenticate( { ts_Challenge_digestCln(digestCln) } )
1401
1402 var Authorization authorization :=
1403 f_sip_digest_gen_Authorization(valueof(www_authenticate),
1404 "Mufasa",
1405 "Circle Of Life",
1406 "GET",
1407 "/dir/index.html",
1408 cnonce := "0a4f113b",
1409 nc_int := 1);
1410
1411 var CommaParam_List digestResp := authorization.body.digestResponse;
1412 f_sip_param_match_value_or_fail(digestResp, "realm", f_sip_str_quote("testrealm@host.com"));
1413 f_sip_param_match_value_or_fail(digestResp, "nonce", f_sip_str_quote("dcd98b7102dd2f0e8b11d0f600bfb0c093"));
1414 f_sip_param_match_value_or_fail(digestResp, "uri", f_sip_str_quote("/dir/index.html"));
1415 f_sip_param_match_value_or_fail(digestResp, "qop", "auth");
1416 f_sip_param_match_value_or_fail(digestResp, "nc", "00000001");
1417 f_sip_param_match_value_or_fail(digestResp, "cnonce", f_sip_str_quote("0a4f113b"));
1418 f_sip_param_match_value_or_fail(digestResp, "response", f_sip_str_quote("6629fae49393a05397450978507c4ef1"));
1419 f_sip_param_match_value_or_fail(digestResp, "opaque", f_sip_str_quote("5ccc069c403ebaf9f0171e9517f40e41"));
1420}
1421
Pau Espin Pedrol6052a342024-03-28 20:20:46 +01001422/* RFC 3261 8.1.1.5:
1423 * "The sequence number value MUST be expressible as a 32-bit unsigned integer
1424 * and MUST be less than 2**31."
1425 */
1426function f_sip_rand_seq_nr() return integer {
1427 /* 2**31 = 2147483648 */
1428 return f_rnd_int(2147483648)
1429}
Harald Welteb0d93602018-03-20 18:09:34 +01001430
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +02001431function f_sip_next_seq_nr(integer seq_nr) return integer {
1432 return (seq_nr + 1) mod 2147483648;
1433}
1434
1435function f_sip_Request_inc_seq_nr(inout template (value) PDU_SIP_Request req) {
1436 req.msgHeader.cSeq.seqNumber := f_sip_next_seq_nr(valueof(req.msgHeader.cSeq.seqNumber));
1437}
1438
Pau Espin Pedrol05eaa1a2024-04-02 12:56:26 +02001439function f_sip_rand_tag() return charstring {
Pau Espin Pedrol95ad6a02024-04-18 16:52:46 +02001440 /* Tags shall have at least 32 bit of randomness */
Pau Espin Pedrol05eaa1a2024-04-02 12:56:26 +02001441 var integer rnd_int := f_rnd_int(4294967296);
Pau Espin Pedrol95ad6a02024-04-18 16:52:46 +02001442 /* Make collisions harder by appending time to the final string: */
1443 var integer ts_int := f_time_ms() mod 4294967296;
1444 return hex2str(int2hex(rnd_int, 8)) & "-" & hex2str(int2hex(ts_int, 8));
Pau Espin Pedrol05eaa1a2024-04-02 12:56:26 +02001445}
1446
1447/* Generate a "branch" tag value.
1448 * RFC 3261 p.105 section 8:
1449 * "A common way to create this value is to compute a
1450 * cryptographic hash of the To tag, From tag, Call-ID header
1451 * field, the Request-URI of the request received (before
1452 * translation), the topmost Via header, and the sequence number
1453 * from the CSeq header field, in addition to any Proxy-Require
1454 * and Proxy-Authorization header fields that may be present. The
1455 * algorithm used to compute the hash is implementation-dependent,
1456 * but MD5 (RFC 1321 [35]),expressed in hexadecimal, is a reasonable
1457 * choice."
1458 * See also Section 8.1.1.7:
1459 * "The branch ID inserted by an element compliant with this
1460 * specification MUST always begin with the characters "z9hG4bK"."
1461 */
1462const charstring sip_magic_cookie := "z9hG4bK";
1463function f_sip_gen_branch(charstring tag_to,
1464 charstring tag_from,
1465 charstring tag_call_id,
1466 integer cseq) return charstring {
1467 var charstring str := tag_to & tag_from & tag_call_id & int2str(cseq);
1468 var charstring hash := f_calculateMD5(str);
1469 var charstring branch := sip_magic_cookie & hash;
1470 return branch;
1471}
1472
1473function f_sip_HostPort_to_str(HostPort host_port) return charstring {
1474 var charstring str := "";
1475 if (ispresent(host_port.host)) {
1476 str := host_port.host;
1477 }
1478 if (ispresent(host_port.portField)) {
1479 str := str & ":" & int2str(host_port.portField);
1480 }
1481 return str;
1482}
1483
1484function f_sip_SipUrl_to_str(SipUrl uri) return charstring {
Pau Espin Pedrolb0dbf7a2024-05-22 18:12:15 +02001485 var charstring str := uri.scheme & ":";
1486 if (ispresent(uri.userInfo)) {
1487 str := str & uri.userInfo.userOrTelephoneSubscriber & "@";
1488 }
1489 str := str & f_sip_HostPort_to_str(uri.hostPort);
Pau Espin Pedrol05eaa1a2024-04-02 12:56:26 +02001490 return str;
1491}
1492
1493function f_sip_NameAddr_to_str(NameAddr naddr) return charstring {
1494 if (ispresent(naddr.displayName)) {
1495 return naddr.displayName & " <" & f_sip_SipUrl_to_str(naddr.addrSpec) & ">";
1496 } else {
1497 return f_sip_SipUrl_to_str(naddr.addrSpec);
1498 }
1499}
1500
Pau Espin Pedrol41b0e072024-05-29 18:25:51 +02001501function f_sip_Addr_Union_to_str(Addr_Union addru) return charstring {
1502 if (ischosen(addru.nameAddr)) {
1503 return f_sip_NameAddr_to_str(addru.nameAddr);
Pau Espin Pedrol05eaa1a2024-04-02 12:56:26 +02001504 } else {
Pau Espin Pedrol41b0e072024-05-29 18:25:51 +02001505 return f_sip_SipUrl_to_str(addru.addrSpecUnion);
Pau Espin Pedrol05eaa1a2024-04-02 12:56:26 +02001506 }
1507}
1508
Pau Espin Pedrol41b0e072024-05-29 18:25:51 +02001509function f_sip_SipAddr_to_str(SipAddr sip_addr) return charstring {
1510 return f_sip_Addr_Union_to_str(sip_addr.addr);
1511}
1512
Harald Welteb0d93602018-03-20 18:09:34 +01001513}