blob: 9f45b9f1e2f3da851f4af83536df46095f545454 [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 Pedrol41b0e072024-05-29 18:25:51 +0200230// [20.20]
231template (value) From ts_From(template (value) Addr_Union addressField,
232 template (omit) SemicolonParam_List fromParams := omit) := {
233 fieldName := FROM_E,
234 addressField := addressField,
235 fromParams := fromParams
236}
237template (present) From tr_From(template (present) Addr_Union addressField := ?,
238 template SemicolonParam_List fromParams := *) := {
239 fieldName := FROM_E,
240 addressField := addressField,
241 fromParams := fromParams
242}
243
Pau Espin Pedrol0c5c6472024-05-21 13:13:49 +0200244// [RFC3455 5.4] + 3GPP 24.229 V8.7.0
245template (present) Access_net_spec tr_Access_net_spec(template (present) charstring access_type := ?,
246 template SemicolonParam_List access_info := *) := {
247 access_type := access_type,
248 access_info := access_info
249}
250template (present) Access_net_spec tr_Access_net_spec_EUTRAN(template (present) charstring uli_str := ?) := {
251 access_type := "3GPP-E-UTRAN-FDD",
252 access_info := {tr_Param("utran-cell-id-3gpp", uli_str)}
253}
254
255// [RFC3455 5.4] + 3GPP 24.229 V8.7.0
256template (present) P_Access_Network_Info tr_P_Access_Network_Info(template (present) Access_net_spec_list access_net_specs := ?) := {
257 fieldName := P_ACCESS_NETWORK_INFO,
258 access_net_specs := access_net_specs
259}
260
Pau Espin Pedrol4e6672c2024-05-22 17:03:53 +0200261// [RFC3455 4.1]
262template (present) P_Assoc_uri_spec tr_P_Assoc_uri_spec(template (present) NameAddr p_asso_uri := ?,
263 template SemicolonParam_List ai_params := *) := {
264 p_asso_uri := p_asso_uri,
265 ai_params := ai_params
266}
267template (value) P_Assoc_uri_spec ts_P_Assoc_uri_spec(template (value) NameAddr p_asso_uri,
268 template (omit) SemicolonParam_List ai_params := omit) := {
269 p_asso_uri := p_asso_uri,
270 ai_params := ai_params
271}
272
273// [RFC3455 4.1]
274template (present) P_Associated_Uri tr_P_Associated_Uri(template (present) P_Assoc_uri_spec_list p_assoc_uris := ?) := {
275 fieldName := P_ASSOCIATED_URI,
276 p_assoc_uris := p_assoc_uris
277}
278template (value) P_Associated_Uri ts_P_Associated_Uri(template (value) P_Assoc_uri_spec_list p_assoc_uris := {}) := {
279 fieldName := P_ASSOCIATED_URI,
280 p_assoc_uris := p_assoc_uris
281}
Pau Espin Pedrol73f6a312024-05-10 20:30:16 +0200282
283// [20.32]
284template (value) Require ts_Require(template (value) OptionTag_List optionsTags := {}) := {
285 fieldName := REQUIRE_E,
286 optionsTags := optionsTags
287}
288template (present) Require tr_Require(template (present) OptionTag_List optionsTags := ?) := {
289 fieldName := REQUIRE_E,
290 optionsTags := optionsTags
291}
292
Pau Espin Pedrol52cc2e52024-05-13 17:50:20 +0200293// [20.35 RFC2616 14.38]
294template (value) Server ts_Server(template (value) ServerVal_List serverBody := {}) := {
295 fieldName := SERVER_E,
296 serverBody := serverBody
297}
298template (present) Server tr_Server(template (present) ServerVal_List serverBody := ?) := {
299 fieldName := SERVER_E,
300 serverBody := serverBody
301}
302
Pau Espin Pedrol73f6a312024-05-10 20:30:16 +0200303// [20.37]
304template (value) Supported ts_Supported(template (value) OptionTag_List optionsTags := {}) := {
305 fieldName := SUPPORTED_E,
306 optionsTags := optionsTags
307}
308template (present) Supported tr_Supported(template (present) OptionTag_List optionsTags := ?) := {
309 fieldName := SUPPORTED_E,
310 optionsTags := optionsTags
311}
312
Pau Espin Pedrol41b0e072024-05-29 18:25:51 +0200313// [20.39]
314template (value) To ts_To(template (value) Addr_Union addressField,
315 template (omit) SemicolonParam_List toParams := omit) := {
316 fieldName := TO_E,
317 addressField := addressField,
318 toParams := toParams
319}
320template (present) To tr_To(template (present) Addr_Union addressField := ?,
321 template SemicolonParam_List toParams := *) := {
322 fieldName := TO_E,
323 addressField := addressField,
324 toParams := toParams
325}
326
Pau Espin Pedrol13c50ac2024-05-13 17:48:09 +0200327// [20.41 RFC2616 14.43]
328template (value) UserAgent ts_UserAgent(template (value) ServerVal_List userAgentBody := {}) := {
329 fieldName := USER_AGENT_E,
330 userAgentBody := userAgentBody
331}
332template (present) UserAgent tr_UserAgent(template (present) ServerVal_List userAgentBody := ?) := {
333 fieldName := USER_AGENT_E,
334 userAgentBody := userAgentBody
335}
336
Pau Espin Pedrol73f6a312024-05-10 20:30:16 +0200337
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100338template (value) SipAddr ts_SipAddr(template (value) HostPort host_port,
339 template (omit) UserInfo user_info := omit,
340 template (omit) charstring displayName := omit,
341 template (omit) SemicolonParam_List params := omit) := {
Harald Welteb0d93602018-03-20 18:09:34 +0100342 addr := {
343 nameAddr := {
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100344 displayName := displayName,
345 addrSpec := ts_SipUrl(host_port, user_info)
Harald Welteb0d93602018-03-20 18:09:34 +0100346 }
347 },
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100348 params := params
349}
350template (present) SipAddr tr_SipAddr(template (present) HostPort host_port := ?,
351 template UserInfo user_info := *,
352 template charstring displayName := *,
353 template SemicolonParam_List params := *) := {
354 addr := {
355 nameAddr := {
356 displayName := displayName,
357 addrSpec := tr_SipUrl(host_port, user_info)
358 }
359 },
360 params := params
Harald Welteb0d93602018-03-20 18:09:34 +0100361}
362
363/* build a receive template from a value: substitute '*' for omit */
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200364function tr_SipUrl_from_val(template (value) SipUrl tin) return template (present) SipUrl {
365 var template (present) SipUrl ret := tin;
366
367 /* if the port number is 5060, it may be omitted */
368 if (ispresent(tin.hostPort.portField) and
369 valueof(tin.hostPort.portField) == 5060) {
370 ret.hostPort.portField := 5060 ifpresent;
371 }
372 if (not ispresent(tin.userInfo.password)) {
373 ret.userInfo.password := *;
374 }
375
376 return ret;
377}
Pau Espin Pedrol41b0e072024-05-29 18:25:51 +0200378function tr_Addr_Union_from_val(template (value) Addr_Union tin) return template (present) Addr_Union {
379 var template (present) Addr_Union ret := tin;
380
381 if (not ispresent(tin.nameAddr.displayName)) {
382 ret.nameAddr.displayName := *;
383 } else if (f_str_tolower(f_sip_str_unquote(tin.nameAddr.displayName)) == "anonymous") {
384 /* if the user is Anonymous, it may be omitted */
385 ret.nameAddr.displayName := tin.nameAddr.displayName ifpresent;
386 }
387
388 ret.nameAddr.addrSpec := tr_SipUrl_from_val(tin.nameAddr.addrSpec);
389
390 return ret;
391}
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200392function tr_SipAddr_from_val(template (value) SipAddr tin) return template (present) SipAddr {
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100393 var template (present) SipAddr ret := tin;
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200394
Pau Espin Pedrol41b0e072024-05-29 18:25:51 +0200395 ret.addr := tr_Addr_Union_from_val(tin.addr);
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200396
397 if (not ispresent(tin.params)) {
Harald Welteb0d93602018-03-20 18:09:34 +0100398 ret.params := *;
399 }
400 return ret;
401}
402
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200403function ts_SipAddr_from_Addr_Union(template (value) Addr_Union au,
404 template (omit) SemicolonParam_List params := omit)
405return template (value) SipAddr {
406 var template (value) SipUrl addrSpec := ts_SipUrl_from_Addr_Union(au);
407 var template (omit) charstring displayName;
408
409 if (ischosen(au.nameAddr)) {
410 displayName := au.nameAddr.displayName;
411 } else { /* au.addrSpecUnion */
412 displayName := omit
413 }
414
415 return ts_SipAddr(addrSpec.hostPort,
416 addrSpec.userInfo,
417 displayName,
418 params);
419}
420
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100421template (value) HostPort ts_HostPort(template (omit) charstring host := omit,
422 template (omit) integer portField := omit) := {
423 host := host,
424 portField := portField
425}
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200426
427template (present) HostPort tr_HostPort(template charstring host := *,
428 template integer portField := *) := {
429 host := host,
430 portField := portField
431}
432function f_tr_HostPort(template charstring host := *,
433 template integer portField := *)
434return template (present) HostPort {
435 return f_tr_HostPort_opt_defport(tr_HostPort(host, portField));
436}
437function f_tr_HostPort_opt_defport(template (present) HostPort hp) return template (present) HostPort {
438 var template (present) HostPort hpout := hp;
Harald Welteb0d93602018-03-20 18:09:34 +0100439 /* if the port number is 5060, it may be omitted */
440 if (isvalue(hp.portField) and valueof(hp.portField) == 5060) {
441 hpout.portField := 5060 ifpresent;
442 }
443 return hpout;
444}
445
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200446function f_tr_SipUrl_opt_defport(template (present) SipUrl url) return template (present) SipUrl {
447 var template (present) SipUrl urlout := url;
448 urlout.hostPort := f_tr_HostPort_opt_defport(url.hostPort);
449 return urlout;
450}
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100451
452template (value) UserInfo ts_UserInfo(template (value) charstring userOrTelephoneSubscriber,
453 template (omit) charstring password := omit) := {
454 userOrTelephoneSubscriber := userOrTelephoneSubscriber,
455 password := password
456}
457template (present) UserInfo tr_UserInfo(template (present) charstring userOrTelephoneSubscriber := ?,
458 template charstring password := *) := {
459 userOrTelephoneSubscriber := userOrTelephoneSubscriber,
460 password := password
461}
462
463template (value) RequestLine ts_SIP_ReqLine(Method method,
464 template (value) SipUrl uri,
Harald Welteb0d93602018-03-20 18:09:34 +0100465 charstring ver := c_SIP_VERSION) := {
466 method := method,
467 requestUri := uri,
468 sipVersion := ver
469}
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100470template (present) RequestLine tr_SIP_ReqLine(template (present) Method method := ?,
471 template (present) SipUrl uri := ?,
472 template (present) charstring ver := c_SIP_VERSION) := {
Harald Welteb0d93602018-03-20 18:09:34 +0100473 method := method,
474 requestUri := uri,
475 sipVersion := ver
476}
477
478template (value) StatusLine ts_SIP_StatusLine(integer status_code, charstring reason) := {
479 sipVersion := "SIP/2.0",
480 statusCode := status_code,
481 reasonPhrase := reason
482}
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100483template (present) StatusLine tr_SIP_StatusLine(template integer status_code,
484 template charstring reason) := {
Harald Welteb0d93602018-03-20 18:09:34 +0100485 sipVersion := "SIP/2.0",
486 statusCode := status_code,
487 reasonPhrase := reason
488}
489
490
491template (value) PDU_SIP_Request ts_SIP_req(template (value) RequestLine rl) := {
492 requestLine := rl,
493 msgHeader := c_SIP_msgHeader_empty,
494 messageBody := omit,
495 payload := omit
496}
497
498const Method_List c_SIP_defaultMethods := {
499 "INVITE", "ACK", "BYE", "CANCEL", "OPTIONS", "PRACK", "MESSAGE", "SUBSCRIBE",
500 "NOTIFY", "REFER", "UPDATE" };
501
502private function f_ContentTypeOrOmit(template (omit) ContentType ct, template (omit) charstring body)
503return template (omit) ContentType {
504 /* if user explicitly stated no content type */
505 if (istemplatekind(ct, "omit")) {
506 return omit;
507 }
508 /* if there's no body, then there's no content-type either */
509 if (istemplatekind(body, "omit")) {
510 return omit;
511 }
512 return ct;
513}
514
Pau Espin Pedrol5c36a652024-05-14 16:05:59 +0200515private function f_ContentLength(template (omit) charstring body)
516return template (value) ContentLength {
517 /* rfc3261 20.14: "If no body is present in a message, then the
518 * Content-Length header field value MUST be set to zero." */
519 if (istemplatekind(body, "omit")) {
520 return ts_ContentLength(0);
521 }
522 return ts_ContentLength(lengthof(body));
523}
524
Harald Welteb0d93602018-03-20 18:09:34 +0100525template (value) ContentType ts_CT_SDP := {
526 fieldName := CONTENT_TYPE_E,
527 mediaType := "application/sdp"
528};
529
Pau Espin Pedrol2a833372024-05-10 20:23:22 +0200530template (value) Via ts_Via_from(template (value) HostPort addr,
531 template (value) charstring transport := "UDP") := {
Harald Welteb0d93602018-03-20 18:09:34 +0100532 fieldName := VIA_E,
533 viaBody := {
534 {
Pau Espin Pedrol2a833372024-05-10 20:23:22 +0200535 sentProtocol := { "SIP", "2.0", transport },
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100536 sentBy := addr,
Harald Welteb0d93602018-03-20 18:09:34 +0100537 viaParams := omit
538 }
539 }
540}
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100541template (present) Via tr_Via_from(template (present) HostPort host_port := ?,
Pau Espin Pedrol2a833372024-05-10 20:23:22 +0200542 template (present) charstring transport := ?,
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100543 template SemicolonParam_List viaParams := *) := {
544 fieldName := VIA_E,
545 viaBody := {
546 {
Pau Espin Pedrol2a833372024-05-10 20:23:22 +0200547 sentProtocol := { "SIP", "2.0", ? },
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100548 sentBy := host_port,
549 viaParams := viaParams
550 }
551 }
Pau Espin Pedrol05eaa1a2024-04-02 12:56:26 +0200552}
553
554template (present) OtherAuth
555tr_OtherAuth(template (present) charstring authScheme := ?,
556 template (present) CommaParam_List authParams := ?) := {
557 authScheme := authScheme,
558 authParams := authParams
559}
560
561template (value) OtherAuth
562ts_OtherAuth(template (value) charstring authScheme,
563 template (value) CommaParam_List authParams) := {
564 authScheme := authScheme,
565 authParams := authParams
566}
567
568template (present) Challenge
569tr_Challenge_digestCln(template (present) CommaParam_List digestCln := ?) := {
570 digestCln := digestCln
571}
572
573template (value) Challenge
574ts_Challenge_digestCln(template (value) CommaParam_List digestCln) := {
575 digestCln := digestCln
576}
577
578template (present) Challenge
579tr_Challenge_otherChallenge(template (present) OtherAuth otherChallenge := ?) := {
580 otherChallenge := otherChallenge
581}
582
583template (value) Challenge
584ts_Challenge_otherChallenge(template (value) OtherAuth otherChallenge) := {
585 otherChallenge := otherChallenge
586}
587
588template (present) WwwAuthenticate
589tr_WwwAuthenticate(template (present) Challenge_list challenge := ?) := {
590 fieldName := WWW_AUTHENTICATE_E,
591 challenge := challenge
592}
593
594template (value) WwwAuthenticate
595ts_WwwAuthenticate(template (value) Challenge_list challenge) := {
596 fieldName := WWW_AUTHENTICATE_E,
597 challenge := challenge
598}
Harald Welteb0d93602018-03-20 18:09:34 +0100599
Pau Espin Pedrol73f6a312024-05-10 20:30:16 +0200600// RFC3329
601template (present) Security_client
602tr_Security_client(template (present) Security_mechanism_list sec_mechanism_list := ?) := {
603 fieldName := SECURITY_CLIENT_E,
604 sec_mechanism_list := sec_mechanism_list
605}
606template (value) Security_client
607ts_Security_client(template (value) Security_mechanism_list sec_mechanism_list) := {
608 fieldName := SECURITY_CLIENT_E,
609 sec_mechanism_list := sec_mechanism_list
610}
611
Pau Espin Pedrol7f411562024-05-13 13:58:41 +0200612template (present) Security_server
613tr_Security_server(template (present) Security_mechanism_list sec_mechanism_list := ?) := {
614 fieldName := SECURITY_SERVER_E,
615 sec_mechanism_list := sec_mechanism_list
616}
617template (value) Security_server
618ts_Security_server(template (value) Security_mechanism_list sec_mechanism_list) := {
619 fieldName := SECURITY_SERVER_E,
620 sec_mechanism_list := sec_mechanism_list
621}
622
Pau Espin Pedrol73f6a312024-05-10 20:30:16 +0200623template (present) Security_mechanism
624tr_Security_mechanism(template (present) charstring name := ?,
625 template SemicolonParam_List params := *) := {
626 mechanism_name := name,
627 mechanism_params := params
628}
629template (value) Security_mechanism
630ts_Security_mechanism(template (value) charstring name,
631 template (omit) SemicolonParam_List params := omit) := {
632 mechanism_name := name,
633 mechanism_params := params
634}
635
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100636template (value) MessageHeader ts_SIP_msgHeader_empty := c_SIP_msgHeader_empty;
637template (value) MessageHeader
638ts_SIP_msgh_std(template (value) CallidString call_id,
Pau Espin Pedrol41b0e072024-05-29 18:25:51 +0200639 template (value) From from_addr,
640 template (value) To to_addr,
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100641 template (omit) Contact contact,
642 template (value) charstring method,
643 template (value) integer seq_nr,
644 template (value) Via via,
Pau Espin Pedrol5c36a652024-05-14 16:05:59 +0200645 template (omit) ContentLength content_length := ts_ContentLength(0),
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100646 template (omit) ContentType content_type := omit,
Pau Espin Pedrol05eaa1a2024-04-02 12:56:26 +0200647 template (omit)Authorization authorization := omit,
Pau Espin Pedrolcb3a15b2024-05-13 16:25:11 +0200648 template (omit) Allow allow := ts_Allow(c_SIP_defaultMethods),
Pau Espin Pedrol89d8c952024-05-10 20:28:24 +0200649 template (omit) Expires expires := omit,
Pau Espin Pedrol4e6672c2024-05-22 17:03:53 +0200650 template (omit) P_Associated_Uri p_associated_uri := omit,
Pau Espin Pedrol73f6a312024-05-10 20:30:16 +0200651 template (omit) Require require := omit,
652 template (omit) Security_client security_client := omit,
Pau Espin Pedrol7f411562024-05-13 13:58:41 +0200653 template (omit) Security_server security_server := omit,
Pau Espin Pedrol52cc2e52024-05-13 17:50:20 +0200654 template (omit) Server server := omit,
Pau Espin Pedrol73f6a312024-05-10 20:30:16 +0200655 template (omit) Supported supported := omit,
Pau Espin Pedrol13c50ac2024-05-13 17:48:09 +0200656 template (omit) UserAgent userAgent := ts_UserAgent({ "osmo-ttcn3-hacks/0.23" }),
Pau Espin Pedrol89d8c952024-05-10 20:28:24 +0200657 template (omit) WwwAuthenticate wwwAuthenticate := omit
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100658 ) modifies ts_SIP_msgHeader_empty := {
Pau Espin Pedrolcb3a15b2024-05-13 16:25:11 +0200659 allow := allow,
Pau Espin Pedrol05eaa1a2024-04-02 12:56:26 +0200660 authorization := authorization,
Harald Welteb0d93602018-03-20 18:09:34 +0100661 callId := {
662 fieldName := CALL_ID_E,
663 callid := call_id
664 },
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100665 contact := contact,
Pau Espin Pedrol5c36a652024-05-14 16:05:59 +0200666 contentLength := content_length,
Harald Welteb0d93602018-03-20 18:09:34 +0100667 contentType := content_type,
668 cSeq := {
669 fieldName := CSEQ_E,
670 seqNumber := seq_nr,
671 method := method
672 },
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100673 expires := expires,
Pau Espin Pedrol41b0e072024-05-29 18:25:51 +0200674 fromField := from_addr,
Pau Espin Pedrol4e6672c2024-05-22 17:03:53 +0200675 p_associated_uri := p_associated_uri,
Pau Espin Pedrol73f6a312024-05-10 20:30:16 +0200676 require := require,
677 security_client := security_client,
Pau Espin Pedrol7f411562024-05-13 13:58:41 +0200678 security_server := security_server,
Pau Espin Pedrol52cc2e52024-05-13 17:50:20 +0200679 server := server,
Pau Espin Pedrol73f6a312024-05-10 20:30:16 +0200680 supported := supported,
Pau Espin Pedrol41b0e072024-05-29 18:25:51 +0200681 toField := to_addr,
Pau Espin Pedrol13c50ac2024-05-13 17:48:09 +0200682 userAgent := userAgent,
Pau Espin Pedrol89d8c952024-05-10 20:28:24 +0200683 via := via,
684 wwwAuthenticate := wwwAuthenticate
Harald Welteb0d93602018-03-20 18:09:34 +0100685}
686
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100687template (present) MessageHeader
688tr_SIP_msgh_std(template CallidString call_id,
Pau Espin Pedrol41b0e072024-05-29 18:25:51 +0200689 template From from_addr,
690 template To to_addr,
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100691 template Contact contact,
692 template (present) Via via := tr_Via_from(?),
693 template charstring method,
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100694 template integer seq_nr := ?,
Pau Espin Pedrol5c36a652024-05-14 16:05:59 +0200695 template ContentLength content_length := *,
696 template ContentType content_type := *,
Pau Espin Pedrolcb3a15b2024-05-13 16:25:11 +0200697 template Allow allow := *,
Pau Espin Pedrola674d612024-05-14 19:56:33 +0200698 template Authorization authorization := *,
Pau Espin Pedrol05eaa1a2024-04-02 12:56:26 +0200699 template Expires expires := *,
Pau Espin Pedrol4e6672c2024-05-22 17:03:53 +0200700 template P_Associated_Uri p_associated_uri := *,
Pau Espin Pedrol73f6a312024-05-10 20:30:16 +0200701 template Require require := *,
702 template Security_client security_client := *,
Pau Espin Pedrol7f411562024-05-13 13:58:41 +0200703 template Security_server security_server := *,
Pau Espin Pedrol52cc2e52024-05-13 17:50:20 +0200704 template Server server := *,
Pau Espin Pedrol73f6a312024-05-10 20:30:16 +0200705 template Supported supported := *,
Pau Espin Pedrol13c50ac2024-05-13 17:48:09 +0200706 template UserAgent userAgent := *,
Pau Espin Pedrol05eaa1a2024-04-02 12:56:26 +0200707 template WwwAuthenticate wwwAuthenticate := *
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100708 ) modifies t_SIP_msgHeader_any := {
Pau Espin Pedrolcb3a15b2024-05-13 16:25:11 +0200709 allow := allow,
Pau Espin Pedrola674d612024-05-14 19:56:33 +0200710 authorization := authorization,
Harald Welteb0d93602018-03-20 18:09:34 +0100711 callId := {
712 fieldName := CALL_ID_E,
713 callid := call_id
714 },
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100715 contact := contact,
Pau Espin Pedrol5c36a652024-05-14 16:05:59 +0200716 contentLength := content_length,
Harald Welteb0d93602018-03-20 18:09:34 +0100717 contentType := content_type,
718 cSeq := {
719 fieldName := CSEQ_E,
720 seqNumber := seq_nr,
721 method := method
722 },
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100723 expires := expires,
Pau Espin Pedrol41b0e072024-05-29 18:25:51 +0200724 fromField := from_addr,
Pau Espin Pedrol4e6672c2024-05-22 17:03:53 +0200725 p_associated_uri := p_associated_uri,
Pau Espin Pedrol73f6a312024-05-10 20:30:16 +0200726 require := require,
727 security_client := security_client,
Pau Espin Pedrol7f411562024-05-13 13:58:41 +0200728 security_server := security_server,
Pau Espin Pedrol52cc2e52024-05-13 17:50:20 +0200729 server := server,
Pau Espin Pedrol73f6a312024-05-10 20:30:16 +0200730 supported := supported,
Pau Espin Pedrol41b0e072024-05-29 18:25:51 +0200731 toField := to_addr,
Pau Espin Pedrol13c50ac2024-05-13 17:48:09 +0200732 userAgent := userAgent,
Pau Espin Pedrol05eaa1a2024-04-02 12:56:26 +0200733 via := via,
734 wwwAuthenticate := wwwAuthenticate
Harald Welteb0d93602018-03-20 18:09:34 +0100735}
736
737
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100738template (value) PDU_SIP_Request
739ts_SIP_REGISTER(template (value) SipUrl sip_url_host_port,
740 template (value) CallidString call_id,
Pau Espin Pedrol41b0e072024-05-29 18:25:51 +0200741 template (value) From from_addr,
742 template (value) To to_addr,
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100743 template (value) Via via,
744 integer seq_nr,
745 template (omit) Contact contact,
746 template (omit) Expires expires,
Pau Espin Pedrol05eaa1a2024-04-02 12:56:26 +0200747 template (omit) Authorization authorization := omit,
Pau Espin Pedrol73f6a312024-05-10 20:30:16 +0200748 template (omit) Require require := omit,
749 template (omit) Security_client security_client := omit,
750 template (omit) Supported supported := omit,
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100751 template (omit) charstring body := omit) := {
752 requestLine := ts_SIP_ReqLine(REGISTER_E, sip_url_host_port),
753 msgHeader := ts_SIP_msgh_std(call_id, from_addr, to_addr, contact,
754 "REGISTER", seq_nr, via,
Pau Espin Pedrol5c36a652024-05-14 16:05:59 +0200755 content_length := f_ContentLength(body),
756 content_type := f_ContentTypeOrOmit(ts_CT_SDP, body),
Pau Espin Pedrol05eaa1a2024-04-02 12:56:26 +0200757 authorization := authorization,
Pau Espin Pedrol73f6a312024-05-10 20:30:16 +0200758 expires := expires,
759 require := require,
760 security_client := security_client,
761 supported := supported),
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100762 messageBody := body,
763 payload := omit
764}
765template (present) PDU_SIP_Request
766tr_SIP_REGISTER(template (present) SipUrl sip_url_host_port := ?,
767 template (present) CallidString call_id := ?,
Pau Espin Pedrol41b0e072024-05-29 18:25:51 +0200768 template (present) From from_addr := ?,
769 template (present) To to_addr := ?,
Pau Espin Pedrol0dd3f262024-04-25 17:04:43 +0200770 template (present) Via via := tr_Via_from(f_tr_HostPort_opt_defport(?)),
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100771 template integer seq_nr := *,
Pau Espin Pedrola674d612024-05-14 19:56:33 +0200772 template Authorization authorization := *,
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100773 template Contact contact := *,
774 template Expires expires := *,
Pau Espin Pedrol73f6a312024-05-10 20:30:16 +0200775 template Require require := *,
776 template Security_client security_client := *,
777 template Supported supported := *,
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100778 template charstring body := *) := {
779 requestLine := tr_SIP_ReqLine(REGISTER_E, sip_url_host_port),
780 msgHeader := tr_SIP_msgh_std(call_id, from_addr, to_addr, contact,
Pau Espin Pedrol5c36a652024-05-14 16:05:59 +0200781 via, "REGISTER", seq_nr,
Pau Espin Pedrola674d612024-05-14 19:56:33 +0200782 authorization := authorization,
Pau Espin Pedrol73f6a312024-05-10 20:30:16 +0200783 expires := expires,
784 require := require,
785 security_client := security_client,
786 supported := supported),
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100787 messageBody := body,
788 payload := omit
789}
790
791template (value) PDU_SIP_Request
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200792ts_SIP_INVITE(template (value) CallidString call_id,
Pau Espin Pedrol41b0e072024-05-29 18:25:51 +0200793 template (value) From from_addr,
794 template (value) To to_addr,
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200795 template (value) Via via,
796 template (value) Contact contact,
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100797 integer seq_nr,
798 template (omit) charstring body := omit) := {
Pau Espin Pedrol41b0e072024-05-29 18:25:51 +0200799 requestLine := ts_SIP_ReqLine(INVITE_E, to_addr.addressField.nameAddr.addrSpec),
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200800 msgHeader := ts_SIP_msgh_std(call_id, from_addr, to_addr, contact,
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100801 "INVITE", seq_nr,
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200802 via,
Pau Espin Pedrol5c36a652024-05-14 16:05:59 +0200803 content_length := f_ContentLength(body),
804 content_type := f_ContentTypeOrOmit(ts_CT_SDP, body)),
Harald Welteb0d93602018-03-20 18:09:34 +0100805 messageBody := body,
806 payload := omit
807}
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100808template (present) PDU_SIP_Request
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200809tr_SIP_INVITE(template (present) SipUrl uri,
810 template CallidString call_id,
Pau Espin Pedrol41b0e072024-05-29 18:25:51 +0200811 template From from_addr,
812 template To to_addr,
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200813 template Via via := tr_Via_from(f_tr_HostPort_opt_defport(?)),
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100814 template integer seq_nr,
815 template charstring body) := {
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200816 requestLine := tr_SIP_ReqLine(INVITE_E, uri),
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100817 msgHeader := tr_SIP_msgh_std(call_id, from_addr, to_addr, ?,
Pau Espin Pedrol5c36a652024-05-14 16:05:59 +0200818 via, "INVITE", seq_nr),
Harald Welteb0d93602018-03-20 18:09:34 +0100819 messageBody := body,
820 payload := omit
821}
822
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100823template (value) PDU_SIP_Request
824ts_SIP_BYE(CallidString call_id,
Pau Espin Pedrol41b0e072024-05-29 18:25:51 +0200825 template (value) From from_addr,
826 template (value) To to_addr,
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200827 template (value) Via via,
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100828 integer seq_nr,
829 template (omit) charstring body) := {
Pau Espin Pedrol41b0e072024-05-29 18:25:51 +0200830 requestLine := ts_SIP_ReqLine(BYE_E, to_addr.addressField.nameAddr.addrSpec),
Harald Welteb0d93602018-03-20 18:09:34 +0100831 msgHeader := ts_SIP_msgh_std(call_id, from_addr, to_addr, omit, "BYE", seq_nr,
Pau Espin Pedrol5c36a652024-05-14 16:05:59 +0200832 via,
833 content_length := f_ContentLength(body),
834 content_type := f_ContentTypeOrOmit(ts_CT_SDP, body)),
Harald Welteb0d93602018-03-20 18:09:34 +0100835 messageBody := body,
836 payload := omit
837}
838
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100839template (present) PDU_SIP_Request
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200840tr_SIP_BYE(template (present) SipUrl uri,
841 template CallidString call_id,
Pau Espin Pedrol41b0e072024-05-29 18:25:51 +0200842 template From from_addr,
843 template To to_addr,
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200844 template Via via,
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100845 template integer seq_nr,
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200846 template charstring body := *) := {
847 requestLine := tr_SIP_ReqLine(BYE_E, uri),
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100848 msgHeader := tr_SIP_msgh_std(call_id, from_addr, to_addr, omit,
Pau Espin Pedrol5c36a652024-05-14 16:05:59 +0200849 via, "BYE", seq_nr),
Harald Welteb0d93602018-03-20 18:09:34 +0100850 messageBody := body,
851 payload := omit
852}
853
854
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100855template (value) PDU_SIP_Request
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200856ts_SIP_ACK(template (value) CallidString call_id,
Pau Espin Pedrol41b0e072024-05-29 18:25:51 +0200857 template (value) From from_addr,
858 template (value) To to_addr,
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200859 template (value) Via via,
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100860 integer seq_nr,
861 template (omit) charstring body) := {
Pau Espin Pedrol41b0e072024-05-29 18:25:51 +0200862 requestLine := ts_SIP_ReqLine(ACK_E, to_addr.addressField.nameAddr.addrSpec),
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100863 msgHeader := ts_SIP_msgh_std(call_id, from_addr, to_addr,
Pau Espin Pedrol41b0e072024-05-29 18:25:51 +0200864 ts_Contact({ ts_ContactAddress(from_addr.addressField, from_addr.fromParams) }),
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100865 "ACK", seq_nr,
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200866 via,
Pau Espin Pedrol5c36a652024-05-14 16:05:59 +0200867 content_length := f_ContentLength(body),
868 content_type := f_ContentTypeOrOmit(ts_CT_SDP, body)),
Harald Welteb0d93602018-03-20 18:09:34 +0100869 messageBody := body,
870 payload := omit
871}
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100872template (present) PDU_SIP_Request
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200873tr_SIP_ACK(template (present) SipUrl uri,
874 template CallidString call_id,
Pau Espin Pedrol41b0e072024-05-29 18:25:51 +0200875 template From from_addr,
876 template To to_addr,
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200877 template Via via,
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100878 template integer seq_nr,
879 template charstring body) := {
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200880 requestLine := tr_SIP_ReqLine(ACK_E, uri),
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100881 msgHeader := tr_SIP_msgh_std(call_id, from_addr, to_addr, *,
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200882 via,
Pau Espin Pedrol5c36a652024-05-14 16:05:59 +0200883 "ACK", seq_nr),
Harald Welteb0d93602018-03-20 18:09:34 +0100884 messageBody := body,
885 payload := omit
886}
887
Pau Espin Pedrol32167d82024-04-10 13:14:51 +0200888template (present) PDU_SIP_Request
889tr_SIP_CANCEL(template (present) SipUrl uri,
890 template (present) CallidString call_id,
Pau Espin Pedrol41b0e072024-05-29 18:25:51 +0200891 template (present) From from_addr,
892 template (present) To to_addr,
Pau Espin Pedrol32167d82024-04-10 13:14:51 +0200893 template (present) Via via,
894 template (present) integer seq_nr,
895 template charstring body := *) := {
896 requestLine := tr_SIP_ReqLine(CANCEL_E, uri),
897 msgHeader := tr_SIP_msgh_std(call_id, from_addr, to_addr, *,
898 via,
Pau Espin Pedrol5c36a652024-05-14 16:05:59 +0200899 "CANCEL", seq_nr),
Pau Espin Pedrol32167d82024-04-10 13:14:51 +0200900 messageBody := body,
901 payload := omit
902}
903
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100904template (value) PDU_SIP_Response
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200905ts_SIP_Response(template (value) CallidString call_id,
Pau Espin Pedrol41b0e072024-05-29 18:25:51 +0200906 template (value) From from_addr,
907 template (value) To to_addr,
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100908 charstring method,
909 integer status_code,
910 integer seq_nr,
911 charstring reason,
912 Via via,
Pau Espin Pedrola674d612024-05-14 19:56:33 +0200913 template (omit) Allow allow := omit,
Pau Espin Pedrol4e6672c2024-05-22 17:03:53 +0200914 template (omit) P_Associated_Uri p_associated_uri := omit,
Pau Espin Pedrola674d612024-05-14 19:56:33 +0200915 template (omit) Require require := omit,
916 template (omit) Server server := omit,
917 template (omit) Supported supported := omit,
918 template (omit) UserAgent userAgent := omit,
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +0100919 template (omit) charstring body := omit) := {
Harald Welteb0d93602018-03-20 18:09:34 +0100920 statusLine := ts_SIP_StatusLine(status_code, reason),
921 msgHeader := ts_SIP_msgh_std(call_id, from_addr, to_addr, omit, method, seq_nr,
Pau Espin Pedrol5c36a652024-05-14 16:05:59 +0200922 via,
923 content_length := f_ContentLength(body),
Pau Espin Pedrola674d612024-05-14 19:56:33 +0200924 content_type := f_ContentTypeOrOmit(ts_CT_SDP, body),
925 allow := allow,
Pau Espin Pedrol4e6672c2024-05-22 17:03:53 +0200926 p_associated_uri := p_associated_uri,
Pau Espin Pedrola674d612024-05-14 19:56:33 +0200927 require := require,
928 server := server,
929 supported := supported,
930 userAgent := userAgent),
Harald Welteb0d93602018-03-20 18:09:34 +0100931 messageBody := body,
932 payload := omit
933}
Pau Espin Pedrol1b5f7ba2024-05-13 16:38:38 +0200934/* 100 Trying */
935template (value) PDU_SIP_Response
936ts_SIP_Response_Trying(
937 template (value) CallidString call_id,
Pau Espin Pedrol41b0e072024-05-29 18:25:51 +0200938 template (value) From from_addr,
939 template (value) To to_addr,
Pau Espin Pedrol1b5f7ba2024-05-13 16:38:38 +0200940 Via via,
941 integer seq_nr,
942 charstring method := "INVITE",
Pau Espin Pedrola2812ec2024-05-10 20:30:44 +0200943 template (omit) Allow allow := omit,
944 template (omit) Server server := omit,
945 template (omit) UserAgent userAgent := omit,
Pau Espin Pedrol1b5f7ba2024-05-13 16:38:38 +0200946 template (omit) charstring body := omit) := {
947 statusLine := ts_SIP_StatusLine(100, "Trying"),
948 msgHeader := ts_SIP_msgh_std(call_id, from_addr, to_addr, omit, method, seq_nr,
Pau Espin Pedrol5c36a652024-05-14 16:05:59 +0200949 via,
950 content_length := f_ContentLength(body),
Pau Espin Pedrola2812ec2024-05-10 20:30:44 +0200951 content_type := f_ContentTypeOrOmit(ts_CT_SDP, body),
952 allow := allow,
953 server := server,
954 userAgent := userAgent),
Pau Espin Pedrol1b5f7ba2024-05-13 16:38:38 +0200955 messageBody := body,
956 payload := omit
957}
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200958/* 180 Ringing */
959template (value) PDU_SIP_Response
960ts_SIP_Response_Ringing(
961 template (value) CallidString call_id,
Pau Espin Pedrol41b0e072024-05-29 18:25:51 +0200962 template (value) From from_addr,
963 template (value) To to_addr,
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200964 Via via,
965 integer seq_nr,
966 charstring method := "INVITE",
967 template (omit) charstring body := omit) := {
968 statusLine := ts_SIP_StatusLine(180, "Ringing"),
969 msgHeader := ts_SIP_msgh_std(call_id, from_addr, to_addr, omit, method, seq_nr,
Pau Espin Pedrol5c36a652024-05-14 16:05:59 +0200970 via,
971 content_length := f_ContentLength(body),
972 content_type := f_ContentTypeOrOmit(ts_CT_SDP, body)),
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +0200973 messageBody := body,
974 payload := omit
975}
976
Pau Espin Pedrola2812ec2024-05-10 20:30:44 +0200977/* 401 Unauthorized */
978template (value) PDU_SIP_Response
979ts_SIP_Response_Unauthorized(
980 template (value) CallidString call_id,
Pau Espin Pedrol41b0e072024-05-29 18:25:51 +0200981 template (value) From from_addr,
982 template (value) To to_addr,
Pau Espin Pedrola2812ec2024-05-10 20:30:44 +0200983 Via via,
984 template (value) WwwAuthenticate wwwAuthenticate,
985 integer seq_nr,
986 charstring method := "REGISTER",
987 template (omit) Allow allow := omit,
Pau Espin Pedrol4e6672c2024-05-22 17:03:53 +0200988 template (omit) P_Associated_Uri p_associated_uri := omit,
Pau Espin Pedrola2812ec2024-05-10 20:30:44 +0200989 template (omit) Security_server security_server := omit,
990 template (omit) Server server := omit,
991 template (omit) Supported supported := omit,
992 template (omit) UserAgent userAgent := omit,
993 template (omit) charstring body := omit) := {
994 statusLine := ts_SIP_StatusLine(401, "Unauthorized"),
995 msgHeader := ts_SIP_msgh_std(call_id, from_addr, to_addr, omit, method, seq_nr,
996 via,
997 content_length := f_ContentLength(body),
998 content_type := f_ContentTypeOrOmit(ts_CT_SDP, body),
999 allow := allow,
Pau Espin Pedrol4e6672c2024-05-22 17:03:53 +02001000 p_associated_uri := p_associated_uri,
Pau Espin Pedrola2812ec2024-05-10 20:30:44 +02001001 security_server := security_server,
1002 server := server,
1003 supported := supported,
1004 userAgent := userAgent,
1005 wwwAuthenticate := wwwAuthenticate),
1006 messageBody := body,
1007 payload := omit
1008}
1009
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +01001010template (present) PDU_SIP_Response
1011tr_SIP_Response(template CallidString call_id,
Pau Espin Pedrol41b0e072024-05-29 18:25:51 +02001012 template From from_addr,
1013 template To to_addr,
Pau Espin Pedrol05eaa1a2024-04-02 12:56:26 +02001014 template (present) Via via := tr_Via_from(?),
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +01001015 template Contact contact,
1016 template charstring method,
1017 template integer status_code,
1018 template integer seq_nr := ?,
1019 template charstring reason := ?,
Pau Espin Pedrol05eaa1a2024-04-02 12:56:26 +02001020 template charstring body := *) := {
Harald Welteb0d93602018-03-20 18:09:34 +01001021 statusLine := tr_SIP_StatusLine(status_code, reason),
Pau Espin Pedrolfb34d862024-03-28 20:21:38 +01001022 msgHeader := tr_SIP_msgh_std(call_id, from_addr, to_addr, contact,
Pau Espin Pedrol05eaa1a2024-04-02 12:56:26 +02001023 via,
Pau Espin Pedrol5c36a652024-05-14 16:05:59 +02001024 method, seq_nr),
Harald Welteb0d93602018-03-20 18:09:34 +01001025 messageBody := body,
1026 payload := omit
1027}
1028
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +02001029/* Expect during first REGISTER/INVITE/... when authorization is required: */
Pau Espin Pedrol37ee0ed2024-03-28 21:17:12 +01001030template (present) PDU_SIP_Response
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +02001031tr_SIP_Response_Unauthorized(
Pau Espin Pedrol37ee0ed2024-03-28 21:17:12 +01001032 template CallidString call_id,
Pau Espin Pedrol41b0e072024-05-29 18:25:51 +02001033 template From from_addr,
1034 template To to_addr,
Pau Espin Pedrol37ee0ed2024-03-28 21:17:12 +01001035 template (present) Via via := tr_Via_from(?),
1036 template Contact contact := *,
Pau Espin Pedrol05eaa1a2024-04-02 12:56:26 +02001037 template (present) WwwAuthenticate wwwAuthenticate := ?,
Pau Espin Pedrol37ee0ed2024-03-28 21:17:12 +01001038 template integer seq_nr := ?,
1039 template charstring method := "REGISTER",
1040 template integer status_code := 401,
1041 template charstring reason := "Unauthorized",
1042 template charstring body := *) := {
1043 statusLine := tr_SIP_StatusLine(status_code, reason),
1044 msgHeader := tr_SIP_msgh_std(call_id, from_addr, to_addr, contact,
1045 via,
Pau Espin Pedrol5c36a652024-05-14 16:05:59 +02001046 method, seq_nr,
Pau Espin Pedrol05eaa1a2024-04-02 12:56:26 +02001047 wwwAuthenticate := wwwAuthenticate),
Pau Espin Pedrol37ee0ed2024-03-28 21:17:12 +01001048 messageBody := body,
1049 payload := omit
1050}
Harald Welteb0d93602018-03-20 18:09:34 +01001051
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +02001052/* 100 Trying */
1053template (present) PDU_SIP_Response
1054tr_SIP_Response_Trying(
1055 template CallidString call_id,
Pau Espin Pedrol41b0e072024-05-29 18:25:51 +02001056 template From from_addr,
1057 template To to_addr,
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +02001058 template (present) Via via := tr_Via_from(?),
1059 template integer seq_nr := ?,
1060 template charstring method := "INVITE",
1061 template integer status_code := 100,
1062 template charstring reason := "Trying",
1063 template charstring body := *) := {
1064 statusLine := tr_SIP_StatusLine(status_code, reason),
1065 msgHeader := tr_SIP_msgh_std(call_id, from_addr, to_addr, omit,
1066 via,
Pau Espin Pedrol5c36a652024-05-14 16:05:59 +02001067 method, seq_nr),
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +02001068 messageBody := body,
1069 payload := omit
1070}
1071
1072/* 180 Ringing */
1073template (present) PDU_SIP_Response
1074tr_SIP_Response_Ringing(
1075 template CallidString call_id,
Pau Espin Pedrol41b0e072024-05-29 18:25:51 +02001076 template From from_addr,
1077 template To to_addr,
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +02001078 template (present) Via via := tr_Via_from(?),
1079 template integer seq_nr := ?,
1080 template charstring method := "INVITE",
1081 template integer status_code := 180,
1082 template charstring reason := "Ringing",
1083 template charstring body := *) := {
1084 statusLine := tr_SIP_StatusLine(status_code, reason),
1085 msgHeader := tr_SIP_msgh_std(call_id, from_addr, to_addr, *,
1086 via,
Pau Espin Pedrol5c36a652024-05-14 16:05:59 +02001087 method, seq_nr),
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +02001088 messageBody := body,
1089 payload := omit
1090}
1091
1092/****************
1093 * FUNCTIONS:
1094 ****************/
1095
Pau Espin Pedrol05eaa1a2024-04-02 12:56:26 +02001096function f_sip_param_find(GenericParam_List li,
1097 template (present) charstring id := ?)
1098return template (omit) GenericParam {
1099 var integer i;
1100
1101 for (i := 0; i < lengthof(li); i := i + 1) {
1102 if (not ispresent(li[i])) {
1103 continue;
1104 }
1105 if (match(li[i].id, id)) {
1106 return li[i];
1107 }
1108 }
1109 return omit;
1110}
1111
1112function f_sip_param_find_or_fail(GenericParam_List li,
1113 template (present) charstring id := ?)
1114return GenericParam {
1115 var template (omit) GenericParam parameter;
1116 parameter := f_sip_param_find(li, id);
1117 if (istemplatekind(parameter, "omit")) {
1118 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
1119 log2str("Param ", id, " not found in ", li));
1120 }
1121 return valueof(parameter);
1122}
1123
1124function f_sip_param_get_value(GenericParam_List li,
1125 template (present) charstring id := ?)
1126return template (omit) charstring {
1127 var template (omit) GenericParam parameter;
1128 parameter := f_sip_param_find(li, id);
1129 if (istemplatekind(parameter, "omit")) {
1130 return omit;
1131 }
1132 return parameter.paramValue;
1133}
1134
1135function f_sip_param_get_value_or_fail(GenericParam_List li,
1136 template (present) charstring id := ?)
1137return template (omit) charstring {
1138 var GenericParam parameter;
1139 parameter := f_sip_param_find_or_fail(li, id);
1140 return parameter.paramValue;
1141}
1142
1143function f_sip_param_get_value_present_or_fail(GenericParam_List li,
1144 template (present) charstring id := ?)
1145return charstring {
1146 var GenericParam parameter;
1147 parameter := f_sip_param_find_or_fail(li, id);
1148 if (not ispresent(parameter.paramValue)) {
1149 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
1150 log2str("Param ", id, " value not present in ", li));
1151 }
1152 return parameter.paramValue;
1153}
1154
1155function f_sip_param_match_value(GenericParam_List li,
1156 template (present) charstring id := ?,
1157 template charstring exp_paramValue := *)
1158return boolean {
1159 var template (omit) charstring val;
1160 val := f_sip_param_get_value_or_fail(li, id);
1161 if (istemplatekind(val, "omit")) {
1162 return istemplatekind(val, "omit") or istemplatekind(val, "*");
1163 }
1164 return match(valueof(val), exp_paramValue);
1165}
1166
1167function f_sip_param_match_value_or_fail(GenericParam_List li,
1168 template (present) charstring id := ?,
1169 template charstring exp_paramValue := *)
1170{
1171 var template (omit) charstring val := f_sip_param_get_value_or_fail(li, id);
1172 if (istemplatekind(val, "omit")) {
1173 if (istemplatekind(val, "omit") or istemplatekind(val, "*")) {
1174 return;
1175 } else {
1176 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
1177 log2str("Param ", id, " match failed: val ", val,
1178 " vs exp ", exp_paramValue));
1179 }
1180 }
1181 if (not match(valueof(val), exp_paramValue)) {
1182 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
1183 log2str("Param ", id, " match failed: val ", val,
1184 " vs exp ", exp_paramValue));
1185 }
1186}
1187
1188function f_sip_param_remove(template (omit) GenericParam_List li_tpl, charstring id)
1189return GenericParam_List {
1190 var integer i;
1191 var GenericParam_List li;
1192 var GenericParam_List new_li := {};
1193
1194 if (istemplatekind(li_tpl, "omit")) {
1195 return {};
1196 }
1197
1198 li := valueof(li_tpl);
1199 for (i := 0; i < lengthof(li); i := i + 1) {
1200 if (not ispresent(li[i]) or
1201 not match(li[i].id, id)) {
1202 new_li := new_li & {li[i]};
1203 }
1204 }
1205 return new_li;
1206}
1207
1208function f_sip_param_set(template (omit) GenericParam_List li_tpl, charstring id, charstring val)
1209return GenericParam_List {
1210 var integer i;
1211 var GenericParam_List li;
1212 var GenericParam_List new_li := {};
1213 var boolean found := false;
1214
1215 if (istemplatekind(li_tpl, "omit")) {
1216 return { valueof(ts_Param(id, val)) };
1217 }
1218
1219 li := valueof(li_tpl);
1220 for (i := 0; i < lengthof(li); i := i + 1) {
1221 if (not ispresent(li[i]) or
1222 not match(li[i].id, id)) {
1223 new_li := new_li & {li[i]};
1224 continue;
1225 }
1226 new_li := new_li & { valueof(ts_Param(li[i].id, val)) };
1227 found := true;
1228 }
1229
1230 if (not found) {
1231 new_li := new_li & { valueof(ts_Param(id, val)) };
1232 }
1233 return new_li;
1234}
1235
1236/* Make sure string is quoted. */
1237function f_sip_str_quote(template (value) charstring val) return charstring {
1238 var charstring str := valueof(val);
1239 if (lengthof(str) == 0) {
1240 return "";
1241 }
1242
1243 if (str[0] != "\"") {
1244 return "\"" & str & "\"";
1245 }
1246 return str;
1247}
1248
1249/* Make sure string is unquoted.
1250 * Similar to unq() in RFC 2617 */
1251function f_sip_str_unquote(template (value) charstring val) return charstring {
1252 var charstring str := valueof(val);
1253 var integer len := lengthof(str);
1254
1255 if (len <= 1) {
1256 return str;
1257 }
1258
1259 if (str[0] == "\"" and str[len - 1] == "\"") {
1260 return substr(str, 1, len - 2);
1261 }
1262 return str;
1263}
1264
1265/* RFC 2617 3.2.2.2 A1 */
1266function f_sip_digest_A1(charstring user, charstring realm, charstring password) return charstring {
1267
1268 /* RFC 2617 3.2.2.2 A1 */
1269 var charstring A1 := f_sip_str_unquote(user) & ":" &
1270 f_sip_str_unquote(realm) & ":" &
1271 password;
1272 var charstring digestA1 := f_str_tolower(f_calculateMD5(A1));
1273 log("A1: md5('", A1, "') = ", digestA1);
1274 return digestA1;
1275}
1276
1277/* RFC 2617 3.2.2.2 A2 */
1278function f_sip_digest_A2(charstring method, charstring uri) return charstring {
1279
1280 var charstring A2 := method & ":" & uri
1281 var charstring digestA2 := f_str_tolower(f_calculateMD5(A2));
1282 log("A2: md5('", A2, "') = ", digestA2);
1283 return digestA2;
1284}
1285
1286/* RFC 2617 3.2.2.1 Request-Digest */
1287function f_sip_digest_RequestDigest(charstring digestA1, charstring nonce,
1288 charstring nc, charstring cnonce,
1289 charstring qop, charstring digestA2) return charstring {
1290 var charstring digest_data := f_sip_str_unquote(nonce) & ":" &
1291 nc & ":" &
1292 cnonce & ":" &
1293 f_sip_str_unquote(qop) & ":" &
1294 digestA2;
1295 var charstring req_digest := f_sip_digest_KD(digestA1, digest_data);
1296 log("Request-Digest: md5('", digestA1, ":", digest_data ,"') = ", req_digest);
1297 return req_digest;
1298}
1299
1300/* RFC 2617 3.2.1 The WWW-Authenticate Response Header
1301 * KD(secret, data) = H(concat(secret, ":", data))
1302 */
1303function f_sip_digest_KD(charstring secret, charstring data) return charstring {
1304 return f_str_tolower(f_calculateMD5(secret & ":" & data));
1305}
1306
1307/* Digest Auth: RFC 2617 */
1308function f_sip_digest_gen_Authorization(WwwAuthenticate www_authenticate,
1309 charstring user, charstring password,
1310 charstring method, charstring uri,
1311 charstring cnonce := "0a4f113b", integer nc_int := 1) return Authorization {
1312 var CommaParam_List digestCln;
1313 var template (value) Authorization authorization;
1314 var template (value) Credentials cred;
1315 var template (omit) GenericParam rx_param;
1316
1317 digestCln := www_authenticate.challenge[0].digestCln;
1318
1319 var charstring algorithm;
1320 rx_param := f_sip_param_find(digestCln, "algorithm");
1321 if (istemplatekind(rx_param, "omit")) {
1322 /* Assume MD5 if not set */
1323 algorithm := "MD5"
1324 } else {
1325 algorithm := valueof(rx_param.paramValue);
1326 if (f_strstr(algorithm, "MD5") == -1) {
1327 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
1328 log2str("Unexpected algorithm: ", algorithm));
1329 }
1330 }
1331
1332 var charstring realm := f_sip_param_get_value_present_or_fail(digestCln, "realm");
1333 var charstring nonce := f_sip_param_get_value_present_or_fail(digestCln, "nonce");
1334 var charstring opaque := f_sip_param_get_value_present_or_fail(digestCln, "opaque");
1335 var charstring qop := f_sip_param_get_value_present_or_fail(digestCln, "qop");
1336
1337 if (f_strstr(qop, "auth") == -1) {
1338 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str("Unexpected qop: ", qop));
1339 }
1340 var charstring selected_qop := "auth";
1341
1342 /* RFC 2617 3.2.2.2 A1 */
1343 var charstring digestA1 := f_sip_digest_A1(user, realm, password);
1344 /* RFC 2617 3.2.2.3 A2 */
1345 var charstring digestA2 := f_sip_digest_A2(method, uri);
1346
1347 /* RFC 2617 3.2.2.1 Request-Digest */
1348 var charstring nc := f_str_tolower(hex2str(int2hex(nc_int, 8)));
1349 var charstring req_digest := f_sip_digest_RequestDigest(digestA1, nonce,
1350 nc, cnonce,
1351 selected_qop, digestA2);
1352
1353 cred := ts_Credentials_DigestResponseMD5(user, realm, nonce,
1354 uri, req_digest,
1355 opaque, algorithm, selected_qop, cnonce, nc);
1356
1357 authorization := ts_Authorization(cred);
1358 return valueof(authorization);
1359}
1360
1361/* RFC 2617 3.5 Example */
1362function f_sip_digest_selftest() {
1363/*
1364The following example assumes that an access-protected document is
1365being requested from the server via a GET request. The URI of the
1366document is "http://www.nowhere.org/dir/index.html". Both client and
1367server know that the username for this document is "Mufasa", and the
1368password is "Circle Of Life" (with one space between each of the
1369three words).
1370
1371HTTP/1.1 401 Unauthorized
1372WWW-Authenticate: Digest
1373 realm="testrealm@host.com",
1374 qop="auth,auth-int",
1375 nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093",
1376 opaque="5ccc069c403ebaf9f0171e9517f40e41"
1377
1378Authorization: Digest username="Mufasa",
1379 realm="testrealm@host.com",
1380 nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093",
1381 uri="/dir/index.html",
1382 qop=auth,
1383 nc=00000001,
1384 cnonce="0a4f113b",
1385 response="6629fae49393a05397450978507c4ef1",
1386 opaque="5ccc069c403ebaf9f0171e9517f40e41"
1387*/
1388 var template (value) CommaParam_List digestCln := {
1389 ts_Param("realm", f_sip_str_quote("testrealm@host.com")),
1390 ts_Param("qop", f_sip_str_quote("auth,auth-int")),
1391 ts_Param("nonce", f_sip_str_quote("dcd98b7102dd2f0e8b11d0f600bfb0c093")),
1392 ts_Param("opaque", f_sip_str_quote("5ccc069c403ebaf9f0171e9517f40e41"))
1393 };
1394 var template (value) WwwAuthenticate www_authenticate :=
1395 ts_WwwAuthenticate( { ts_Challenge_digestCln(digestCln) } )
1396
1397 var Authorization authorization :=
1398 f_sip_digest_gen_Authorization(valueof(www_authenticate),
1399 "Mufasa",
1400 "Circle Of Life",
1401 "GET",
1402 "/dir/index.html",
1403 cnonce := "0a4f113b",
1404 nc_int := 1);
1405
1406 var CommaParam_List digestResp := authorization.body.digestResponse;
1407 f_sip_param_match_value_or_fail(digestResp, "realm", f_sip_str_quote("testrealm@host.com"));
1408 f_sip_param_match_value_or_fail(digestResp, "nonce", f_sip_str_quote("dcd98b7102dd2f0e8b11d0f600bfb0c093"));
1409 f_sip_param_match_value_or_fail(digestResp, "uri", f_sip_str_quote("/dir/index.html"));
1410 f_sip_param_match_value_or_fail(digestResp, "qop", "auth");
1411 f_sip_param_match_value_or_fail(digestResp, "nc", "00000001");
1412 f_sip_param_match_value_or_fail(digestResp, "cnonce", f_sip_str_quote("0a4f113b"));
1413 f_sip_param_match_value_or_fail(digestResp, "response", f_sip_str_quote("6629fae49393a05397450978507c4ef1"));
1414 f_sip_param_match_value_or_fail(digestResp, "opaque", f_sip_str_quote("5ccc069c403ebaf9f0171e9517f40e41"));
1415}
1416
Pau Espin Pedrol6052a342024-03-28 20:20:46 +01001417/* RFC 3261 8.1.1.5:
1418 * "The sequence number value MUST be expressible as a 32-bit unsigned integer
1419 * and MUST be less than 2**31."
1420 */
1421function f_sip_rand_seq_nr() return integer {
1422 /* 2**31 = 2147483648 */
1423 return f_rnd_int(2147483648)
1424}
Harald Welteb0d93602018-03-20 18:09:34 +01001425
Pau Espin Pedrol7011bf42024-04-08 17:56:58 +02001426function f_sip_next_seq_nr(integer seq_nr) return integer {
1427 return (seq_nr + 1) mod 2147483648;
1428}
1429
1430function f_sip_Request_inc_seq_nr(inout template (value) PDU_SIP_Request req) {
1431 req.msgHeader.cSeq.seqNumber := f_sip_next_seq_nr(valueof(req.msgHeader.cSeq.seqNumber));
1432}
1433
Pau Espin Pedrol05eaa1a2024-04-02 12:56:26 +02001434function f_sip_rand_tag() return charstring {
Pau Espin Pedrol95ad6a02024-04-18 16:52:46 +02001435 /* Tags shall have at least 32 bit of randomness */
Pau Espin Pedrol05eaa1a2024-04-02 12:56:26 +02001436 var integer rnd_int := f_rnd_int(4294967296);
Pau Espin Pedrol95ad6a02024-04-18 16:52:46 +02001437 /* Make collisions harder by appending time to the final string: */
1438 var integer ts_int := f_time_ms() mod 4294967296;
1439 return hex2str(int2hex(rnd_int, 8)) & "-" & hex2str(int2hex(ts_int, 8));
Pau Espin Pedrol05eaa1a2024-04-02 12:56:26 +02001440}
1441
1442/* Generate a "branch" tag value.
1443 * RFC 3261 p.105 section 8:
1444 * "A common way to create this value is to compute a
1445 * cryptographic hash of the To tag, From tag, Call-ID header
1446 * field, the Request-URI of the request received (before
1447 * translation), the topmost Via header, and the sequence number
1448 * from the CSeq header field, in addition to any Proxy-Require
1449 * and Proxy-Authorization header fields that may be present. The
1450 * algorithm used to compute the hash is implementation-dependent,
1451 * but MD5 (RFC 1321 [35]),expressed in hexadecimal, is a reasonable
1452 * choice."
1453 * See also Section 8.1.1.7:
1454 * "The branch ID inserted by an element compliant with this
1455 * specification MUST always begin with the characters "z9hG4bK"."
1456 */
1457const charstring sip_magic_cookie := "z9hG4bK";
1458function f_sip_gen_branch(charstring tag_to,
1459 charstring tag_from,
1460 charstring tag_call_id,
1461 integer cseq) return charstring {
1462 var charstring str := tag_to & tag_from & tag_call_id & int2str(cseq);
1463 var charstring hash := f_calculateMD5(str);
1464 var charstring branch := sip_magic_cookie & hash;
1465 return branch;
1466}
1467
1468function f_sip_HostPort_to_str(HostPort host_port) return charstring {
1469 var charstring str := "";
1470 if (ispresent(host_port.host)) {
1471 str := host_port.host;
1472 }
1473 if (ispresent(host_port.portField)) {
1474 str := str & ":" & int2str(host_port.portField);
1475 }
1476 return str;
1477}
1478
1479function f_sip_SipUrl_to_str(SipUrl uri) return charstring {
Pau Espin Pedrolb0dbf7a2024-05-22 18:12:15 +02001480 var charstring str := uri.scheme & ":";
1481 if (ispresent(uri.userInfo)) {
1482 str := str & uri.userInfo.userOrTelephoneSubscriber & "@";
1483 }
1484 str := str & f_sip_HostPort_to_str(uri.hostPort);
Pau Espin Pedrol05eaa1a2024-04-02 12:56:26 +02001485 return str;
1486}
1487
1488function f_sip_NameAddr_to_str(NameAddr naddr) return charstring {
1489 if (ispresent(naddr.displayName)) {
1490 return naddr.displayName & " <" & f_sip_SipUrl_to_str(naddr.addrSpec) & ">";
1491 } else {
1492 return f_sip_SipUrl_to_str(naddr.addrSpec);
1493 }
1494}
1495
Pau Espin Pedrol41b0e072024-05-29 18:25:51 +02001496function f_sip_Addr_Union_to_str(Addr_Union addru) return charstring {
1497 if (ischosen(addru.nameAddr)) {
1498 return f_sip_NameAddr_to_str(addru.nameAddr);
Pau Espin Pedrol05eaa1a2024-04-02 12:56:26 +02001499 } else {
Pau Espin Pedrol41b0e072024-05-29 18:25:51 +02001500 return f_sip_SipUrl_to_str(addru.addrSpecUnion);
Pau Espin Pedrol05eaa1a2024-04-02 12:56:26 +02001501 }
1502}
1503
Pau Espin Pedrol41b0e072024-05-29 18:25:51 +02001504function f_sip_SipAddr_to_str(SipAddr sip_addr) return charstring {
1505 return f_sip_Addr_Union_to_str(sip_addr.addr);
1506}
1507
Harald Welteb0d93602018-03-20 18:09:34 +01001508}