blob: 9ddadb0298b8986f57928b9acf5ec10a74ad5caa [file] [log] [blame]
Tristan Matthews0a329cc2013-07-17 13:20:14 -04001/* $Id$ */
2/*
3 * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
4 * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20#include <pjsip/sip_dialog.h>
21#include <pjsip/sip_ua_layer.h>
22#include <pjsip/sip_errno.h>
23#include <pjsip/sip_endpoint.h>
24#include <pjsip/sip_parser.h>
25#include <pjsip/sip_module.h>
26#include <pjsip/sip_util.h>
27#include <pjsip/sip_transaction.h>
28#include <pj/assert.h>
29#include <pj/os.h>
30#include <pj/string.h>
31#include <pj/pool.h>
32#include <pj/guid.h>
33#include <pj/rand.h>
34#include <pj/array.h>
35#include <pj/except.h>
36#include <pj/hash.h>
37#include <pj/log.h>
38
39#define THIS_FILE "sip_dialog.c"
40
41long pjsip_dlg_lock_tls_id;
42
43/* Config */
44pj_bool_t pjsip_include_allow_hdr_in_dlg = PJSIP_INCLUDE_ALLOW_HDR_IN_DLG;
45
46/* Contact header string */
47static const pj_str_t HCONTACT = { "Contact", 7 };
48
49
50PJ_DEF(pj_bool_t) pjsip_method_creates_dialog(const pjsip_method *m)
51{
52 const pjsip_method subscribe = { PJSIP_OTHER_METHOD, {"SUBSCRIBE", 9}};
53 const pjsip_method refer = { PJSIP_OTHER_METHOD, {"REFER", 5}};
54 const pjsip_method notify = { PJSIP_OTHER_METHOD, {"NOTIFY", 6}};
55 const pjsip_method update = { PJSIP_OTHER_METHOD, {"UPDATE", 6}};
56
57 return m->id == PJSIP_INVITE_METHOD ||
58 (pjsip_method_cmp(m, &subscribe)==0) ||
59 (pjsip_method_cmp(m, &refer)==0) ||
60 (pjsip_method_cmp(m, &notify)==0) ||
61 (pjsip_method_cmp(m, &update)==0);
62}
63
64static pj_status_t create_dialog( pjsip_user_agent *ua,
65 pjsip_dialog **p_dlg)
66{
67 pjsip_endpoint *endpt;
68 pj_pool_t *pool;
69 pjsip_dialog *dlg;
70 pj_status_t status;
71
72 endpt = pjsip_ua_get_endpt(ua);
73 if (!endpt)
74 return PJ_EINVALIDOP;
75
76 pool = pjsip_endpt_create_pool(endpt, "dlg%p",
77 PJSIP_POOL_LEN_DIALOG,
78 PJSIP_POOL_INC_DIALOG);
79 if (!pool)
80 return PJ_ENOMEM;
81
82 dlg = PJ_POOL_ZALLOC_T(pool, pjsip_dialog);
83 PJ_ASSERT_RETURN(dlg != NULL, PJ_ENOMEM);
84
85 dlg->pool = pool;
86 pj_ansi_snprintf(dlg->obj_name, sizeof(dlg->obj_name), "dlg%p", dlg);
87 dlg->ua = ua;
88 dlg->endpt = endpt;
89 dlg->state = PJSIP_DIALOG_STATE_NULL;
90 dlg->add_allow = pjsip_include_allow_hdr_in_dlg;
91
92 pj_list_init(&dlg->inv_hdr);
93 pj_list_init(&dlg->rem_cap_hdr);
94
95 status = pj_mutex_create_recursive(pool, dlg->obj_name, &dlg->mutex_);
96 if (status != PJ_SUCCESS)
97 goto on_error;
98
99 pjsip_target_set_init(&dlg->target_set);
100
101 *p_dlg = dlg;
102 return PJ_SUCCESS;
103
104on_error:
105 if (dlg->mutex_)
106 pj_mutex_destroy(dlg->mutex_);
107 pjsip_endpt_release_pool(endpt, pool);
108 return status;
109}
110
111static void destroy_dialog( pjsip_dialog *dlg )
112{
113 if (dlg->mutex_) {
114 pj_mutex_destroy(dlg->mutex_);
115 dlg->mutex_ = NULL;
116 }
117 if (dlg->tp_sel.type != PJSIP_TPSELECTOR_NONE) {
118 pjsip_tpselector_dec_ref(&dlg->tp_sel);
119 pj_bzero(&dlg->tp_sel, sizeof(pjsip_tpselector));
120 }
121 pjsip_endpt_release_pool(dlg->endpt, dlg->pool);
122}
123
124
125/*
126 * Create an UAC dialog.
127 */
128PJ_DEF(pj_status_t) pjsip_dlg_create_uac( pjsip_user_agent *ua,
129 const pj_str_t *local_uri,
130 const pj_str_t *local_contact,
131 const pj_str_t *remote_uri,
132 const pj_str_t *target,
133 pjsip_dialog **p_dlg)
134{
135 pj_status_t status;
136 pj_str_t tmp;
137 pjsip_dialog *dlg;
138
139 /* Check arguments. */
140 PJ_ASSERT_RETURN(ua && local_uri && remote_uri && p_dlg, PJ_EINVAL);
141
142 /* Create dialog instance. */
143 status = create_dialog(ua, &dlg);
144 if (status != PJ_SUCCESS)
145 return status;
146
147 /* Parse target. */
148 pj_strdup_with_null(dlg->pool, &tmp, target ? target : remote_uri);
149 dlg->target = pjsip_parse_uri(dlg->pool, tmp.ptr, tmp.slen, 0);
150 if (!dlg->target) {
151 status = PJSIP_EINVALIDURI;
152 goto on_error;
153 }
154
155 /* Put any header param in the target URI into INVITE header list. */
156 if (PJSIP_URI_SCHEME_IS_SIP(dlg->target) ||
157 PJSIP_URI_SCHEME_IS_SIPS(dlg->target))
158 {
159 pjsip_param *param;
160 pjsip_sip_uri *uri = (pjsip_sip_uri*)pjsip_uri_get_uri(dlg->target);
161
162 param = uri->header_param.next;
163 while (param != &uri->header_param) {
164 pjsip_hdr *hdr;
165 int c;
166
167 c = param->value.ptr[param->value.slen];
168 param->value.ptr[param->value.slen] = '\0';
169
170 hdr = (pjsip_hdr*)
171 pjsip_parse_hdr(dlg->pool, &param->name, param->value.ptr,
172 param->value.slen, NULL);
173
174 param->value.ptr[param->value.slen] = (char)c;
175
176 if (hdr == NULL) {
177 status = PJSIP_EINVALIDURI;
178 goto on_error;
179 }
180 pj_list_push_back(&dlg->inv_hdr, hdr);
181
182 param = param->next;
183 }
184
185 /* Now must remove any header params from URL, since that would
186 * create another header in pjsip_endpt_create_request().
187 */
188 pj_list_init(&uri->header_param);
189 }
190
191 /* Add target to the target set */
192 pjsip_target_set_add_uri(&dlg->target_set, dlg->pool, dlg->target, 0);
193
194 /* Init local info. */
195 dlg->local.info = pjsip_from_hdr_create(dlg->pool);
196 pj_strdup_with_null(dlg->pool, &dlg->local.info_str, local_uri);
197 dlg->local.info->uri = pjsip_parse_uri(dlg->pool,
198 dlg->local.info_str.ptr,
199 dlg->local.info_str.slen, 0);
200 if (!dlg->local.info->uri) {
201 status = PJSIP_EINVALIDURI;
202 goto on_error;
203 }
204
205 /* Generate local tag. */
206 pj_create_unique_string(dlg->pool, &dlg->local.info->tag);
207
208 /* Calculate hash value of local tag. */
209 dlg->local.tag_hval = pj_hash_calc_tolower(0, NULL,
210 &dlg->local.info->tag);
211
212 /* Randomize local CSeq. */
213 dlg->local.first_cseq = pj_rand() & 0x7FFF;
214 dlg->local.cseq = dlg->local.first_cseq;
215
216 /* Init local contact. */
217 pj_strdup_with_null(dlg->pool, &tmp,
218 local_contact ? local_contact : local_uri);
219 dlg->local.contact = (pjsip_contact_hdr*)
220 pjsip_parse_hdr(dlg->pool, &HCONTACT, tmp.ptr,
221 tmp.slen, NULL);
222 if (!dlg->local.contact) {
223 status = PJSIP_EINVALIDURI;
224 goto on_error;
225 }
226
227 /* Init remote info. */
228 dlg->remote.info = pjsip_to_hdr_create(dlg->pool);
229 pj_strdup_with_null(dlg->pool, &dlg->remote.info_str, remote_uri);
230 dlg->remote.info->uri = pjsip_parse_uri(dlg->pool,
231 dlg->remote.info_str.ptr,
232 dlg->remote.info_str.slen, 0);
233 if (!dlg->remote.info->uri) {
234 status = PJSIP_EINVALIDURI;
235 goto on_error;
236 }
237
238 /* Remove header param from remote.info_str, if any */
239 if (PJSIP_URI_SCHEME_IS_SIP(dlg->remote.info->uri) ||
240 PJSIP_URI_SCHEME_IS_SIPS(dlg->remote.info->uri))
241 {
242 pjsip_sip_uri *sip_uri = (pjsip_sip_uri *)
243 pjsip_uri_get_uri(dlg->remote.info->uri);
244 if (!pj_list_empty(&sip_uri->header_param)) {
245 pj_str_t tmp;
246
247 /* Remove all header param */
248 pj_list_init(&sip_uri->header_param);
249
250 /* Print URI */
251 tmp.ptr = (char*) pj_pool_alloc(dlg->pool,
252 dlg->remote.info_str.slen);
253 tmp.slen = pjsip_uri_print(PJSIP_URI_IN_FROMTO_HDR,
254 sip_uri, tmp.ptr,
255 dlg->remote.info_str.slen);
256
257 if (tmp.slen < 1) {
258 status = PJSIP_EURITOOLONG;
259 goto on_error;
260 }
261
262 /* Assign remote.info_str */
263 dlg->remote.info_str = tmp;
264 }
265 }
266
267
268 /* Initialize remote's CSeq to -1. */
269 dlg->remote.cseq = dlg->remote.first_cseq = -1;
270
271 /* Initial role is UAC. */
272 dlg->role = PJSIP_ROLE_UAC;
273
274 /* Secure? */
275 dlg->secure = PJSIP_URI_SCHEME_IS_SIPS(dlg->target);
276
277 /* Generate Call-ID header. */
278 dlg->call_id = pjsip_cid_hdr_create(dlg->pool);
279 pj_create_unique_string(dlg->pool, &dlg->call_id->id);
280
281 /* Initial route set is empty. */
282 pj_list_init(&dlg->route_set);
283
284 /* Init client authentication session. */
285 status = pjsip_auth_clt_init(&dlg->auth_sess, dlg->endpt,
286 dlg->pool, 0);
287 if (status != PJ_SUCCESS)
288 goto on_error;
289
290 /* Register this dialog to user agent. */
291 status = pjsip_ua_register_dlg( ua, dlg );
292 if (status != PJ_SUCCESS)
293 goto on_error;
294
295
296 /* Done! */
297 *p_dlg = dlg;
298
299
300 PJ_LOG(5,(dlg->obj_name, "UAC dialog created"));
301
302 return PJ_SUCCESS;
303
304on_error:
305 destroy_dialog(dlg);
306 return status;
307}
308
309
310/*
311 * Create UAS dialog.
312 */
313PJ_DEF(pj_status_t) pjsip_dlg_create_uas( pjsip_user_agent *ua,
314 pjsip_rx_data *rdata,
315 const pj_str_t *contact,
316 pjsip_dialog **p_dlg)
317{
318 pj_status_t status;
319 pjsip_hdr *pos = NULL;
320 pjsip_contact_hdr *contact_hdr;
321 pjsip_rr_hdr *rr;
322 pjsip_transaction *tsx = NULL;
323 pj_str_t tmp;
324 enum { TMP_LEN=128};
325 pj_ssize_t len;
326 pjsip_dialog *dlg;
327
328 /* Check arguments. */
329 PJ_ASSERT_RETURN(ua && rdata && p_dlg, PJ_EINVAL);
330
331 /* rdata must have request message. */
332 PJ_ASSERT_RETURN(rdata->msg_info.msg->type == PJSIP_REQUEST_MSG,
333 PJSIP_ENOTREQUESTMSG);
334
335 /* Request must not have To tag.
336 * This should have been checked in the user agent (or application?).
337 */
338 PJ_ASSERT_RETURN(rdata->msg_info.to->tag.slen == 0, PJ_EINVALIDOP);
339
340 /* The request must be a dialog establishing request. */
341 PJ_ASSERT_RETURN(
342 pjsip_method_creates_dialog(&rdata->msg_info.msg->line.req.method),
343 PJ_EINVALIDOP);
344
345 /* Create dialog instance. */
346 status = create_dialog(ua, &dlg);
347 if (status != PJ_SUCCESS)
348 return status;
349
350 /* Temprary string for getting the string representation of
351 * both local and remote URI.
352 */
353 tmp.ptr = (char*) pj_pool_alloc(rdata->tp_info.pool, TMP_LEN);
354
355 /* Init local info from the To header. */
356 dlg->local.info = (pjsip_fromto_hdr*)
357 pjsip_hdr_clone(dlg->pool, rdata->msg_info.to);
358 pjsip_fromto_hdr_set_from(dlg->local.info);
359
360 /* Generate local tag. */
361 pj_create_unique_string(dlg->pool, &dlg->local.info->tag);
362
363
364 /* Print the local info. */
365 len = pjsip_uri_print(PJSIP_URI_IN_FROMTO_HDR,
366 dlg->local.info->uri, tmp.ptr, TMP_LEN);
367 if (len < 1) {
368 pj_ansi_strcpy(tmp.ptr, "<-error: uri too long->");
369 tmp.slen = pj_ansi_strlen(tmp.ptr);
370 } else
371 tmp.slen = len;
372
373 /* Save the local info. */
374 pj_strdup(dlg->pool, &dlg->local.info_str, &tmp);
375
376 /* Calculate hash value of local tag. */
377 dlg->local.tag_hval = pj_hash_calc_tolower(0, NULL, &dlg->local.info->tag);
378
379
380 /* Randomize local cseq */
381 dlg->local.first_cseq = pj_rand() & 0x7FFF;
382 dlg->local.cseq = dlg->local.first_cseq;
383
384 /* Init local contact. */
385 /* TODO:
386 * Section 12.1.1, paragraph about using SIPS URI in Contact.
387 * If the request that initiated the dialog contained a SIPS URI
388 * in the Request-URI or in the top Record-Route header field value,
389 * if there was any, or the Contact header field if there was no
390 * Record-Route header field, the Contact header field in the response
391 * MUST be a SIPS URI.
392 */
393 if (contact) {
394 pj_str_t tmp;
395
396 pj_strdup_with_null(dlg->pool, &tmp, contact);
397 dlg->local.contact = (pjsip_contact_hdr*)
398 pjsip_parse_hdr(dlg->pool, &HCONTACT, tmp.ptr,
399 tmp.slen, NULL);
400 if (!dlg->local.contact) {
401 status = PJSIP_EINVALIDURI;
402 goto on_error;
403 }
404
405 } else {
406 dlg->local.contact = pjsip_contact_hdr_create(dlg->pool);
407 dlg->local.contact->uri = dlg->local.info->uri;
408 }
409
410 /* Init remote info from the From header. */
411 dlg->remote.info = (pjsip_fromto_hdr*)
412 pjsip_hdr_clone(dlg->pool, rdata->msg_info.from);
413 pjsip_fromto_hdr_set_to(dlg->remote.info);
414
415 /* Print the remote info. */
416 len = pjsip_uri_print(PJSIP_URI_IN_FROMTO_HDR,
417 dlg->remote.info->uri, tmp.ptr, TMP_LEN);
418 if (len < 1) {
419 pj_ansi_strcpy(tmp.ptr, "<-error: uri too long->");
420 tmp.slen = pj_ansi_strlen(tmp.ptr);
421 } else
422 tmp.slen = len;
423
424 /* Save the remote info. */
425 pj_strdup(dlg->pool, &dlg->remote.info_str, &tmp);
426
427
428 /* Init remote's contact from Contact header.
429 * Iterate the Contact URI until we find sip: or sips: scheme.
430 */
431 do {
432 contact_hdr = (pjsip_contact_hdr*)
433 pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT,
434 pos);
435 if (contact_hdr) {
436 if (!contact_hdr->uri ||
437 (!PJSIP_URI_SCHEME_IS_SIP(contact_hdr->uri) &&
438 !PJSIP_URI_SCHEME_IS_SIPS(contact_hdr->uri)))
439 {
440 pos = (pjsip_hdr*)contact_hdr->next;
441 if (pos == &rdata->msg_info.msg->hdr)
442 contact_hdr = NULL;
443 } else {
444 break;
445 }
446 }
447 } while (contact_hdr);
448
449 if (!contact_hdr) {
450 status = PJSIP_ERRNO_FROM_SIP_STATUS(PJSIP_SC_BAD_REQUEST);
451 goto on_error;
452 }
453
454 dlg->remote.contact = (pjsip_contact_hdr*)
455 pjsip_hdr_clone(dlg->pool, (pjsip_hdr*)contact_hdr);
456
457 /* Init remote's CSeq from CSeq header */
458 dlg->remote.cseq = dlg->remote.first_cseq = rdata->msg_info.cseq->cseq;
459
460 /* Set initial target to remote's Contact. */
461 dlg->target = dlg->remote.contact->uri;
462
463 /* Initial role is UAS */
464 dlg->role = PJSIP_ROLE_UAS;
465
466 /* Secure?
467 * RFC 3261 Section 12.1.1:
468 * If the request arrived over TLS, and the Request-URI contained a
469 * SIPS URI, the 'secure' flag is set to TRUE.
470 */
471 dlg->secure = PJSIP_TRANSPORT_IS_SECURE(rdata->tp_info.transport) &&
472 PJSIP_URI_SCHEME_IS_SIPS(rdata->msg_info.msg->line.req.uri);
473
474 /* Call-ID */
475 dlg->call_id = (pjsip_cid_hdr*)
476 pjsip_hdr_clone(dlg->pool, rdata->msg_info.cid);
477
478 /* Route set.
479 * RFC 3261 Section 12.1.1:
480 * The route set MUST be set to the list of URIs in the Record-Route
481 * header field from the request, taken in order and preserving all URI
482 * parameters. If no Record-Route header field is present in the request,
483 * the route set MUST be set to the empty set.
484 */
485 pj_list_init(&dlg->route_set);
486 rr = rdata->msg_info.record_route;
487 while (rr != NULL) {
488 pjsip_route_hdr *route;
489
490 /* Clone the Record-Route, change the type to Route header. */
491 route = (pjsip_route_hdr*) pjsip_hdr_clone(dlg->pool, rr);
492 pjsip_routing_hdr_set_route(route);
493
494 /* Add to route set. */
495 pj_list_push_back(&dlg->route_set, route);
496
497 /* Find next Record-Route header. */
498 rr = rr->next;
499 if (rr == (void*)&rdata->msg_info.msg->hdr)
500 break;
501 rr = (pjsip_route_hdr*) pjsip_msg_find_hdr(rdata->msg_info.msg,
502 PJSIP_H_RECORD_ROUTE, rr);
503 }
504 dlg->route_set_frozen = PJ_TRUE;
505
506 /* Init client authentication session. */
507 status = pjsip_auth_clt_init(&dlg->auth_sess, dlg->endpt,
508 dlg->pool, 0);
509 if (status != PJ_SUCCESS)
510 goto on_error;
511
512 /* Create UAS transaction for this request. */
513 status = pjsip_tsx_create_uas(dlg->ua, rdata, &tsx);
514 if (status != PJ_SUCCESS)
515 goto on_error;
516
517 /* Associate this dialog to the transaction. */
518 tsx->mod_data[dlg->ua->id] = dlg;
519
520 /* Increment tsx counter */
521 ++dlg->tsx_count;
522
523 /* Calculate hash value of remote tag. */
524 dlg->remote.tag_hval = pj_hash_calc_tolower(0, NULL, &dlg->remote.info->tag);
525
526 /* Update remote capabilities info */
527 pjsip_dlg_update_remote_cap(dlg, rdata->msg_info.msg, PJ_TRUE);
528
529 /* Register this dialog to user agent. */
530 status = pjsip_ua_register_dlg( ua, dlg );
531 if (status != PJ_SUCCESS)
532 goto on_error;
533
534 /* Put this dialog in rdata's mod_data */
535 rdata->endpt_info.mod_data[ua->id] = dlg;
536
537 PJ_TODO(DIALOG_APP_TIMER);
538
539 /* Feed the first request to the transaction. */
540 pjsip_tsx_recv_msg(tsx, rdata);
541
542 /* Done. */
543 *p_dlg = dlg;
544 PJ_LOG(5,(dlg->obj_name, "UAS dialog created"));
545 return PJ_SUCCESS;
546
547on_error:
548 if (tsx) {
549 pjsip_tsx_terminate(tsx, 500);
550 pj_assert(dlg->tsx_count>0);
551 --dlg->tsx_count;
552 }
553
554 destroy_dialog(dlg);
555 return status;
556}
557
558
559/*
560 * Bind dialog to a specific transport/listener.
561 */
562PJ_DEF(pj_status_t) pjsip_dlg_set_transport( pjsip_dialog *dlg,
563 const pjsip_tpselector *sel)
564{
565 /* Validate */
566 PJ_ASSERT_RETURN(dlg && sel, PJ_EINVAL);
567
568 /* Start locking the dialog. */
569 pjsip_dlg_inc_lock(dlg);
570
571 /* Decrement reference counter of previous transport selector */
572 pjsip_tpselector_dec_ref(&dlg->tp_sel);
573
574 /* Copy transport selector structure .*/
575 pj_memcpy(&dlg->tp_sel, sel, sizeof(*sel));
576
577 /* Increment reference counter */
578 pjsip_tpselector_add_ref(&dlg->tp_sel);
579
580 /* Unlock dialog. */
581 pjsip_dlg_dec_lock(dlg);
582
583 return PJ_SUCCESS;
584}
585
586/*
587 * Set "sent-by" field of Via header.
588 */
589PJ_DEF(pj_status_t) pjsip_dlg_set_via_sent_by( pjsip_dialog *dlg,
590 pjsip_host_port *via_addr,
591 pjsip_transport *via_tp)
592{
593 PJ_ASSERT_RETURN(dlg, PJ_EINVAL);
594
595 if (!via_addr)
596 pj_bzero(&dlg->via_addr, sizeof(dlg->via_addr));
597 else {
598 if (pj_strcmp(&dlg->via_addr.host, &via_addr->host))
599 pj_strdup(dlg->pool, &dlg->via_addr.host, &via_addr->host);
600 dlg->via_addr.port = via_addr->port;
601 }
602 dlg->via_tp = via_tp;
603
604 return PJ_SUCCESS;
605}
606
607
608/*
609 * Create forked dialog from a response.
610 */
611PJ_DEF(pj_status_t) pjsip_dlg_fork( const pjsip_dialog *first_dlg,
612 const pjsip_rx_data *rdata,
613 pjsip_dialog **new_dlg )
614{
615 pjsip_dialog *dlg;
616 const pjsip_msg *msg = rdata->msg_info.msg;
617 const pjsip_hdr *end_hdr, *hdr;
618 const pjsip_contact_hdr *contact;
619 pj_status_t status;
620
621 /* Check arguments. */
622 PJ_ASSERT_RETURN(first_dlg && rdata && new_dlg, PJ_EINVAL);
623
624 /* rdata must be response message. */
625 PJ_ASSERT_RETURN(msg->type == PJSIP_RESPONSE_MSG,
626 PJSIP_ENOTRESPONSEMSG);
627
628 /* Status code MUST be 1xx (but not 100), or 2xx */
629 status = msg->line.status.code;
630 PJ_ASSERT_RETURN( (status/100==1 && status!=100) ||
631 (status/100==2), PJ_EBUG);
632
633 /* To tag must present in the response. */
634 PJ_ASSERT_RETURN(rdata->msg_info.to->tag.slen != 0, PJSIP_EMISSINGTAG);
635
636 /* Find Contact header in the response */
637 contact = (const pjsip_contact_hdr*)
638 pjsip_msg_find_hdr(msg, PJSIP_H_CONTACT, NULL);
639 if (contact == NULL || contact->uri == NULL)
640 return PJSIP_EMISSINGHDR;
641
642 /* Create the dialog. */
643 status = create_dialog((pjsip_user_agent*)first_dlg->ua, &dlg);
644 if (status != PJ_SUCCESS)
645 return status;
646
647 /* Set remote target from the response. */
648 dlg->target = (pjsip_uri*) pjsip_uri_clone(dlg->pool, contact->uri);
649
650 /* Clone local info. */
651 dlg->local.info = (pjsip_fromto_hdr*)
652 pjsip_hdr_clone(dlg->pool, first_dlg->local.info);
653
654 /* Clone local tag. */
655 pj_strdup(dlg->pool, &dlg->local.info->tag, &first_dlg->local.info->tag);
656 dlg->local.tag_hval = first_dlg->local.tag_hval;
657
658 /* Clone local CSeq. */
659 dlg->local.first_cseq = first_dlg->local.first_cseq;
660 dlg->local.cseq = first_dlg->local.cseq;
661
662 /* Clone local Contact. */
663 dlg->local.contact = (pjsip_contact_hdr*)
664 pjsip_hdr_clone(dlg->pool, first_dlg->local.contact);
665
666 /* Clone remote info. */
667 dlg->remote.info = (pjsip_fromto_hdr*)
668 pjsip_hdr_clone(dlg->pool, first_dlg->remote.info);
669
670 /* Set remote tag from the response. */
671 pj_strdup(dlg->pool, &dlg->remote.info->tag, &rdata->msg_info.to->tag);
672
673 /* Initialize remote's CSeq to -1. */
674 dlg->remote.cseq = dlg->remote.first_cseq = -1;
675
676 /* Initial role is UAC. */
677 dlg->role = PJSIP_ROLE_UAC;
678
679 /* Dialog state depends on the response. */
680 status = msg->line.status.code/100;
681 if (status == 1 || status == 2)
682 dlg->state = PJSIP_DIALOG_STATE_ESTABLISHED;
683 else {
684 pj_assert(!"Invalid status code");
685 dlg->state = PJSIP_DIALOG_STATE_NULL;
686 }
687
688 /* Secure? */
689 dlg->secure = PJSIP_URI_SCHEME_IS_SIPS(dlg->target);
690
691 /* Clone Call-ID header. */
692 dlg->call_id = (pjsip_cid_hdr*)
693 pjsip_hdr_clone(dlg->pool, first_dlg->call_id);
694
695 /* Get route-set from the response. */
696 pj_list_init(&dlg->route_set);
697 end_hdr = &msg->hdr;
698 for (hdr=msg->hdr.prev; hdr!=end_hdr; hdr=hdr->prev) {
699 if (hdr->type == PJSIP_H_RECORD_ROUTE) {
700 pjsip_route_hdr *r;
701 r = (pjsip_route_hdr*) pjsip_hdr_clone(dlg->pool, hdr);
702 pjsip_routing_hdr_set_route(r);
703 pj_list_push_back(&dlg->route_set, r);
704 }
705 }
706
707 //dlg->route_set_frozen = PJ_TRUE;
708
709 /* Clone client authentication session. */
710 status = pjsip_auth_clt_clone(dlg->pool, &dlg->auth_sess,
711 &first_dlg->auth_sess);
712 if (status != PJ_SUCCESS)
713 goto on_error;
714
715 /* Register this dialog to user agent. */
716 status = pjsip_ua_register_dlg(dlg->ua, dlg );
717 if (status != PJ_SUCCESS)
718 goto on_error;
719
720
721 /* Done! */
722 *new_dlg = dlg;
723
724 PJ_LOG(5,(dlg->obj_name, "Forked dialog created"));
725 return PJ_SUCCESS;
726
727on_error:
728 destroy_dialog(dlg);
729 return status;
730}
731
732
733/*
734 * Destroy dialog.
735 */
736static pj_status_t unregister_and_destroy_dialog( pjsip_dialog *dlg )
737{
738 pj_status_t status;
739
740 /* Lock must have been held. */
741
742 /* Check dialog state. */
743 /* Number of sessions must be zero. */
744 PJ_ASSERT_RETURN(dlg->sess_count==0, PJ_EINVALIDOP);
745
746 /* MUST not have pending transactions. */
747 PJ_ASSERT_RETURN(dlg->tsx_count==0, PJ_EINVALIDOP);
748
749 /* Unregister from user agent. */
750 status = pjsip_ua_unregister_dlg(dlg->ua, dlg);
751 if (status != PJ_SUCCESS) {
752 pj_assert(!"Unexpected failed unregistration!");
753 return status;
754 }
755
756 /* Log */
757 PJ_LOG(5,(dlg->obj_name, "Dialog destroyed"));
758
759 /* Destroy this dialog. */
760 destroy_dialog(dlg);
761
762 return PJ_SUCCESS;
763}
764
765
766/*
767 * Forcefully terminate dialog.
768 */
769PJ_DEF(pj_status_t) pjsip_dlg_terminate( pjsip_dialog *dlg )
770{
771 /* Number of sessions must be zero. */
772 PJ_ASSERT_RETURN(dlg->sess_count==0, PJ_EINVALIDOP);
773
774 /* MUST not have pending transactions. */
775 PJ_ASSERT_RETURN(dlg->tsx_count==0, PJ_EINVALIDOP);
776
777 return unregister_and_destroy_dialog(dlg);
778}
779
780
781/*
782 * Set route_set
783 */
784PJ_DEF(pj_status_t) pjsip_dlg_set_route_set( pjsip_dialog *dlg,
785 const pjsip_route_hdr *route_set )
786{
787 pjsip_route_hdr *r;
788
789 PJ_ASSERT_RETURN(dlg, PJ_EINVAL);
790
791 pjsip_dlg_inc_lock(dlg);
792
793 /* Clear route set. */
794 pj_list_init(&dlg->route_set);
795
796 if (!route_set) {
797 pjsip_dlg_dec_lock(dlg);
798 return PJ_SUCCESS;
799 }
800
801 r = route_set->next;
802 while (r != route_set) {
803 pjsip_route_hdr *new_r;
804
805 new_r = (pjsip_route_hdr*) pjsip_hdr_clone(dlg->pool, r);
806 pj_list_push_back(&dlg->route_set, new_r);
807
808 r = r->next;
809 }
810
811 pjsip_dlg_dec_lock(dlg);
812 return PJ_SUCCESS;
813}
814
815
816/*
817 * Increment session counter.
818 */
819PJ_DEF(pj_status_t) pjsip_dlg_inc_session( pjsip_dialog *dlg,
820 pjsip_module *mod )
821{
822 PJ_ASSERT_RETURN(dlg && mod, PJ_EINVAL);
823
824 pj_log_push_indent();
825
826 pjsip_dlg_inc_lock(dlg);
827 ++dlg->sess_count;
828 pjsip_dlg_dec_lock(dlg);
829
830 PJ_LOG(5,(dlg->obj_name, "Session count inc to %d by %.*s",
831 dlg->sess_count, (int)mod->name.slen, mod->name.ptr));
832
833 pj_log_pop_indent();
834 return PJ_SUCCESS;
835}
836
837/*
838 * Lock dialog and increment session counter temporarily
839 * to prevent it from being deleted. In addition, it must lock
840 * the user agent's dialog table first, to prevent deadlock.
841 */
842PJ_DEF(void) pjsip_dlg_inc_lock(pjsip_dialog *dlg)
843{
844 PJ_LOG(6,(dlg->obj_name, "Entering pjsip_dlg_inc_lock(), sess_count=%d",
845 dlg->sess_count));
846
847 pj_mutex_lock(dlg->mutex_);
848 dlg->sess_count++;
849
850 PJ_LOG(6,(dlg->obj_name, "Leaving pjsip_dlg_inc_lock(), sess_count=%d",
851 dlg->sess_count));
852}
853
854/* Try to acquire dialog's mutex, but bail out if mutex can not be
855 * acquired immediately.
856 */
857PJ_DEF(pj_status_t) pjsip_dlg_try_inc_lock(pjsip_dialog *dlg)
858{
859 pj_status_t status;
860
861 PJ_LOG(6,(dlg->obj_name,"Entering pjsip_dlg_try_inc_lock(), sess_count=%d",
862 dlg->sess_count));
863
864 status = pj_mutex_trylock(dlg->mutex_);
865 if (status != PJ_SUCCESS) {
866 PJ_LOG(6,(dlg->obj_name, "pjsip_dlg_try_inc_lock() failed"));
867 return status;
868 }
869
870 dlg->sess_count++;
871
872 PJ_LOG(6,(dlg->obj_name, "Leaving pjsip_dlg_try_inc_lock(), sess_count=%d",
873 dlg->sess_count));
874
875 return PJ_SUCCESS;
876}
877
878
879/*
880 * Unlock dialog and decrement session counter.
881 * It may delete the dialog!
882 */
883PJ_DEF(void) pjsip_dlg_dec_lock(pjsip_dialog *dlg)
884{
885 PJ_ASSERT_ON_FAIL(dlg!=NULL, return);
886
887 PJ_LOG(6,(dlg->obj_name, "Entering pjsip_dlg_dec_lock(), sess_count=%d",
888 dlg->sess_count));
889
890 pj_assert(dlg->sess_count > 0);
891 --dlg->sess_count;
892
893 if (dlg->sess_count==0 && dlg->tsx_count==0) {
894 pj_mutex_unlock(dlg->mutex_);
895 pj_mutex_lock(dlg->mutex_);
896 unregister_and_destroy_dialog(dlg);
897 } else {
898 pj_mutex_unlock(dlg->mutex_);
899 }
900
901 PJ_LOG(6,(THIS_FILE, "Leaving pjsip_dlg_dec_lock() (dlg=%p)", dlg));
902}
903
904
905
906/*
907 * Decrement session counter.
908 */
909PJ_DEF(pj_status_t) pjsip_dlg_dec_session( pjsip_dialog *dlg,
910 pjsip_module *mod)
911{
912 PJ_ASSERT_RETURN(dlg, PJ_EINVAL);
913
914 pj_log_push_indent();
915
916 PJ_LOG(5,(dlg->obj_name, "Session count dec to %d by %.*s",
917 dlg->sess_count-1, (int)mod->name.slen, mod->name.ptr));
918
919 pjsip_dlg_inc_lock(dlg);
920 --dlg->sess_count;
921 pjsip_dlg_dec_lock(dlg);
922
923 pj_log_pop_indent();
924 return PJ_SUCCESS;
925}
926
927/*
928 * Check if the module is registered as a usage
929 */
930PJ_DEF(pj_bool_t) pjsip_dlg_has_usage( pjsip_dialog *dlg,
931 pjsip_module *mod)
932{
933 unsigned index;
934 pj_bool_t found = PJ_FALSE;
935
936 pjsip_dlg_inc_lock(dlg);
937 for (index=0; index<dlg->usage_cnt; ++index) {
938 if (dlg->usage[index] == mod) {
939 found = PJ_TRUE;
940 break;
941 }
942 }
943 pjsip_dlg_dec_lock(dlg);
944
945 return found;
946}
947
948/*
949 * Add usage.
950 */
951PJ_DEF(pj_status_t) pjsip_dlg_add_usage( pjsip_dialog *dlg,
952 pjsip_module *mod,
953 void *mod_data )
954{
955 unsigned index;
956
957 PJ_ASSERT_RETURN(dlg && mod, PJ_EINVAL);
958 PJ_ASSERT_RETURN(mod->id >= 0 && mod->id < PJSIP_MAX_MODULE,
959 PJ_EINVAL);
960 PJ_ASSERT_RETURN(dlg->usage_cnt < PJSIP_MAX_MODULE, PJ_EBUG);
961
962 PJ_LOG(5,(dlg->obj_name,
963 "Module %.*s added as dialog usage, data=%p",
964 (int)mod->name.slen, mod->name.ptr, mod_data));
965
966 pjsip_dlg_inc_lock(dlg);
967
968 /* Usages are sorted on priority, lowest number first.
969 * Find position to put the new module, also makes sure that
970 * this module has not been registered before.
971 */
972 for (index=0; index<dlg->usage_cnt; ++index) {
973 if (dlg->usage[index] == mod) {
974 /* Module may be registered more than once in the same dialog.
975 * For example, when call transfer fails, application may retry
976 * call transfer on the same dialog.
977 * So return PJ_SUCCESS here.
978 */
979 PJ_LOG(4,(dlg->obj_name,
980 "Module %.*s already registered as dialog usage, "
981 "updating the data %p",
982 (int)mod->name.slen, mod->name.ptr, mod_data));
983 dlg->mod_data[mod->id] = mod_data;
984
985 pjsip_dlg_dec_lock(dlg);
986 return PJ_SUCCESS;
987
988 //pj_assert(!"This module is already registered");
989 //pjsip_dlg_dec_lock(dlg);
990 //return PJSIP_ETYPEEXISTS;
991 }
992
993 if (dlg->usage[index]->priority > mod->priority)
994 break;
995 }
996
997 /* index holds position to put the module.
998 * Insert module at this index.
999 */
1000 pj_array_insert(dlg->usage, sizeof(dlg->usage[0]), dlg->usage_cnt,
1001 index, &mod);
1002
1003 /* Set module data. */
1004 dlg->mod_data[mod->id] = mod_data;
1005
1006 /* Increment count. */
1007 ++dlg->usage_cnt;
1008
1009 pjsip_dlg_dec_lock(dlg);
1010
1011 return PJ_SUCCESS;
1012}
1013
1014
1015/*
1016 * Attach module specific data to the dialog. Application can also set
1017 * the value directly by accessing dlg->mod_data[module_id].
1018 */
1019PJ_DEF(pj_status_t) pjsip_dlg_set_mod_data( pjsip_dialog *dlg,
1020 int mod_id,
1021 void *data )
1022{
1023 PJ_ASSERT_RETURN(dlg, PJ_EINVAL);
1024 PJ_ASSERT_RETURN(mod_id >= 0 && mod_id < PJSIP_MAX_MODULE,
1025 PJ_EINVAL);
1026 dlg->mod_data[mod_id] = data;
1027 return PJ_SUCCESS;
1028}
1029
1030/**
1031 * Get module specific data previously attached to the dialog. Application
1032 * can also get value directly by accessing dlg->mod_data[module_id].
1033 */
1034PJ_DEF(void*) pjsip_dlg_get_mod_data( pjsip_dialog *dlg,
1035 int mod_id)
1036{
1037 PJ_ASSERT_RETURN(dlg, NULL);
1038 PJ_ASSERT_RETURN(mod_id >= 0 && mod_id < PJSIP_MAX_MODULE,
1039 NULL);
1040 return dlg->mod_data[mod_id];
1041}
1042
1043
1044/*
1045 * Create a new request within dialog (i.e. after the dialog session has been
1046 * established). The construction of such requests follows the rule in
1047 * RFC3261 section 12.2.1.
1048 */
1049static pj_status_t dlg_create_request_throw( pjsip_dialog *dlg,
1050 const pjsip_method *method,
1051 int cseq,
1052 pjsip_tx_data **p_tdata )
1053{
1054 pjsip_tx_data *tdata;
1055 pjsip_contact_hdr *contact;
1056 pjsip_route_hdr *route, *end_list;
1057 pj_status_t status;
1058
1059 /* Contact Header field.
1060 * Contact can only be present in requests that establish dialog (in the
1061 * core SIP spec, only INVITE).
1062 */
1063 if (pjsip_method_creates_dialog(method))
1064 contact = dlg->local.contact;
1065 else
1066 contact = NULL;
1067
1068 /*
1069 * Create the request by cloning from the headers in the
1070 * dialog.
1071 */
1072 status = pjsip_endpt_create_request_from_hdr(dlg->endpt,
1073 method,
1074 dlg->target,
1075 dlg->local.info,
1076 dlg->remote.info,
1077 contact,
1078 dlg->call_id,
1079 cseq,
1080 NULL,
1081 &tdata);
1082 if (status != PJ_SUCCESS)
1083 return status;
1084
1085 /* Just copy dialog route-set to Route header.
1086 * The transaction will do the processing as specified in Section 12.2.1
1087 * of RFC 3261 in function tsx_process_route() in sip_transaction.c.
1088 */
1089 route = dlg->route_set.next;
1090 end_list = &dlg->route_set;
1091 for (; route != end_list; route = route->next ) {
1092 pjsip_route_hdr *r;
1093 r = (pjsip_route_hdr*) pjsip_hdr_shallow_clone( tdata->pool, route );
1094 pjsip_routing_hdr_set_route(r);
1095 pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)r);
1096 }
1097
1098 /* Copy authorization headers, if request is not ACK or CANCEL. */
1099 if (method->id != PJSIP_ACK_METHOD && method->id != PJSIP_CANCEL_METHOD) {
1100 status = pjsip_auth_clt_init_req( &dlg->auth_sess, tdata );
1101 if (status != PJ_SUCCESS)
1102 return status;
1103 }
1104
1105 /* Done. */
1106 *p_tdata = tdata;
1107
1108 return PJ_SUCCESS;
1109}
1110
1111
1112
1113/*
1114 * Create outgoing request.
1115 */
1116PJ_DEF(pj_status_t) pjsip_dlg_create_request( pjsip_dialog *dlg,
1117 const pjsip_method *method,
1118 int cseq,
1119 pjsip_tx_data **p_tdata)
1120{
1121 pj_status_t status;
1122 pjsip_tx_data *tdata = NULL;
1123 PJ_USE_EXCEPTION;
1124
1125 PJ_ASSERT_RETURN(dlg && method && p_tdata, PJ_EINVAL);
1126
1127 /* Lock dialog. */
1128 pjsip_dlg_inc_lock(dlg);
1129
1130 /* Use outgoing CSeq and increment it by one. */
1131 if (cseq < 0)
1132 cseq = dlg->local.cseq + 1;
1133
1134 /* Keep compiler happy */
1135 status = PJ_EBUG;
1136
1137 /* Create the request. */
1138 PJ_TRY {
1139 status = dlg_create_request_throw(dlg, method, cseq, &tdata);
1140 }
1141 PJ_CATCH_ANY {
1142 status = PJ_ENOMEM;
1143 }
1144 PJ_END;
1145
1146 /* Failed! Delete transmit data. */
1147 if (status != PJ_SUCCESS && tdata) {
1148 pjsip_tx_data_dec_ref( tdata );
1149 tdata = NULL;
1150 }
1151
1152 /* Unlock dialog. */
1153 pjsip_dlg_dec_lock(dlg);
1154
1155 *p_tdata = tdata;
1156
1157 return status;
1158}
1159
1160
1161/*
1162 * Send request statefully, and update dialog'c CSeq.
1163 */
1164PJ_DEF(pj_status_t) pjsip_dlg_send_request( pjsip_dialog *dlg,
1165 pjsip_tx_data *tdata,
1166 int mod_data_id,
1167 void *mod_data)
1168{
1169 pjsip_transaction *tsx;
1170 pjsip_msg *msg = tdata->msg;
1171 pj_status_t status;
1172
1173 /* Check arguments. */
1174 PJ_ASSERT_RETURN(dlg && tdata && tdata->msg, PJ_EINVAL);
1175 PJ_ASSERT_RETURN(tdata->msg->type == PJSIP_REQUEST_MSG,
1176 PJSIP_ENOTREQUESTMSG);
1177
1178 pj_log_push_indent();
1179 PJ_LOG(5,(dlg->obj_name, "Sending %s",
1180 pjsip_tx_data_get_info(tdata)));
1181
1182 /* Lock and increment session */
1183 pjsip_dlg_inc_lock(dlg);
1184
1185 /* If via_addr is set, use this address for the Via header. */
1186 if (dlg->via_addr.host.slen > 0) {
1187 tdata->via_addr = dlg->via_addr;
1188 tdata->via_tp = dlg->via_tp;
1189 }
1190
1191 /* Update dialog's CSeq and message's CSeq if request is not
1192 * ACK nor CANCEL.
1193 */
1194 if (msg->line.req.method.id != PJSIP_CANCEL_METHOD &&
1195 msg->line.req.method.id != PJSIP_ACK_METHOD)
1196 {
1197 pjsip_cseq_hdr *ch;
1198
1199 ch = PJSIP_MSG_CSEQ_HDR(msg);
1200 PJ_ASSERT_RETURN(ch!=NULL, PJ_EBUG);
1201
1202 ch->cseq = dlg->local.cseq++;
1203
1204 /* Force the whole message to be re-printed. */
1205 pjsip_tx_data_invalidate_msg( tdata );
1206 }
1207
1208 /* Create a new transaction if method is not ACK.
1209 * The transaction user is the user agent module.
1210 */
1211 if (msg->line.req.method.id != PJSIP_ACK_METHOD) {
1212 int tsx_count;
1213
1214 status = pjsip_tsx_create_uac(dlg->ua, tdata, &tsx);
1215 if (status != PJ_SUCCESS)
1216 goto on_error;
1217
1218 /* Set transport selector */
1219 status = pjsip_tsx_set_transport(tsx, &dlg->tp_sel);
1220 pj_assert(status == PJ_SUCCESS);
1221
1222 /* Attach this dialog to the transaction, so that user agent
1223 * will dispatch events to this dialog.
1224 */
1225 tsx->mod_data[dlg->ua->id] = dlg;
1226
1227 /* Copy optional caller's mod_data, if present */
1228 if (mod_data_id >= 0 && mod_data_id < PJSIP_MAX_MODULE)
1229 tsx->mod_data[mod_data_id] = mod_data;
1230
1231 /* Increment transaction counter. */
1232 tsx_count = ++dlg->tsx_count;
1233
1234 /* Send the message. */
1235 status = pjsip_tsx_send_msg(tsx, tdata);
1236 if (status != PJ_SUCCESS) {
1237 if (dlg->tsx_count == tsx_count)
1238 pjsip_tsx_terminate(tsx, tsx->status_code);
1239 goto on_error;
1240 }
1241
1242 } else {
1243 /* Set transport selector */
1244 pjsip_tx_data_set_transport(tdata, &dlg->tp_sel);
1245
1246 /* Send request */
1247 status = pjsip_endpt_send_request_stateless(dlg->endpt, tdata,
1248 NULL, NULL);
1249 if (status != PJ_SUCCESS)
1250 goto on_error;
1251
1252 }
1253
1254 /* Unlock dialog, may destroy dialog. */
1255 pjsip_dlg_dec_lock(dlg);
1256 pj_log_pop_indent();
1257 return PJ_SUCCESS;
1258
1259on_error:
1260 /* Unlock dialog, may destroy dialog. */
1261 pjsip_dlg_dec_lock(dlg);
1262
1263 /* Whatever happen delete the message. */
1264 pjsip_tx_data_dec_ref( tdata );
1265 pj_log_pop_indent();
1266 return status;
1267}
1268
1269/* Add standard headers for certain types of response */
1270static void dlg_beautify_response(pjsip_dialog *dlg,
1271 pj_bool_t add_headers,
1272 int st_code,
1273 pjsip_tx_data *tdata)
1274{
1275 pjsip_cseq_hdr *cseq;
1276 int st_class;
1277 const pjsip_hdr *c_hdr;
1278 pjsip_hdr *hdr;
1279
1280 cseq = PJSIP_MSG_CSEQ_HDR(tdata->msg);
1281 pj_assert(cseq != NULL);
1282
1283 st_class = st_code / 100;
1284
1285 /* Contact, Allow, Supported header. */
1286 if (add_headers && pjsip_method_creates_dialog(&cseq->method)) {
1287 /* Add Contact header for 1xx, 2xx, 3xx and 485 response. */
1288 if (st_class==2 || st_class==3 || (st_class==1 && st_code != 100) ||
1289 st_code==485)
1290 {
1291 /* Add contact header only if one is not present. */
1292 if (pjsip_msg_find_hdr(tdata->msg, PJSIP_H_CONTACT, NULL) == 0 &&
1293 pjsip_msg_find_hdr_by_name(tdata->msg, &HCONTACT, NULL) == 0)
1294 {
1295 hdr = (pjsip_hdr*) pjsip_hdr_clone(tdata->pool,
1296 dlg->local.contact);
1297 pjsip_msg_add_hdr(tdata->msg, hdr);
1298 }
1299 }
1300
1301 /* Add Allow header in 18x, 2xx and 405 response. */
1302 if ((((st_code/10==18 || st_class==2) && dlg->add_allow)
1303 || st_code==405) &&
1304 pjsip_msg_find_hdr(tdata->msg, PJSIP_H_ALLOW, NULL)==NULL)
1305 {
1306 c_hdr = pjsip_endpt_get_capability(dlg->endpt,
1307 PJSIP_H_ALLOW, NULL);
1308 if (c_hdr) {
1309 hdr = (pjsip_hdr*) pjsip_hdr_clone(tdata->pool, c_hdr);
1310 pjsip_msg_add_hdr(tdata->msg, hdr);
1311 }
1312 }
1313
1314 /* Add Supported header in 2xx response. */
1315 if (st_class==2 &&
1316 pjsip_msg_find_hdr(tdata->msg, PJSIP_H_SUPPORTED, NULL)==NULL)
1317 {
1318 c_hdr = pjsip_endpt_get_capability(dlg->endpt,
1319 PJSIP_H_SUPPORTED, NULL);
1320 if (c_hdr) {
1321 hdr = (pjsip_hdr*) pjsip_hdr_clone(tdata->pool, c_hdr);
1322 pjsip_msg_add_hdr(tdata->msg, hdr);
1323 }
1324 }
1325
1326 }
1327
1328 /* Add To tag in all responses except 100 */
1329 if (st_code != 100) {
1330 pjsip_to_hdr *to;
1331
1332 to = PJSIP_MSG_TO_HDR(tdata->msg);
1333 pj_assert(to != NULL);
1334
1335 to->tag = dlg->local.info->tag;
1336
1337 if (dlg->state == PJSIP_DIALOG_STATE_NULL)
1338 dlg->state = PJSIP_DIALOG_STATE_ESTABLISHED;
1339 }
1340}
1341
1342
1343/*
1344 * Create response.
1345 */
1346PJ_DEF(pj_status_t) pjsip_dlg_create_response( pjsip_dialog *dlg,
1347 pjsip_rx_data *rdata,
1348 int st_code,
1349 const pj_str_t *st_text,
1350 pjsip_tx_data **p_tdata)
1351{
1352 pj_status_t status;
1353 pjsip_tx_data *tdata;
1354
1355 /* Create generic response.
1356 * This will initialize response's Via, To, From, Call-ID, CSeq
1357 * and Record-Route headers from the request.
1358 */
1359 status = pjsip_endpt_create_response(dlg->endpt,
1360 rdata, st_code, st_text, &tdata);
1361 if (status != PJ_SUCCESS)
1362 return status;
1363
1364 /* Lock the dialog. */
1365 pjsip_dlg_inc_lock(dlg);
1366
1367 dlg_beautify_response(dlg, PJ_FALSE, st_code, tdata);
1368
1369 /* Unlock the dialog. */
1370 pjsip_dlg_dec_lock(dlg);
1371
1372 /* Done. */
1373 *p_tdata = tdata;
1374 return PJ_SUCCESS;
1375}
1376
1377/*
1378 * Modify response.
1379 */
1380PJ_DEF(pj_status_t) pjsip_dlg_modify_response( pjsip_dialog *dlg,
1381 pjsip_tx_data *tdata,
1382 int st_code,
1383 const pj_str_t *st_text)
1384{
1385 pjsip_hdr *hdr;
1386
1387 PJ_ASSERT_RETURN(dlg && tdata && tdata->msg, PJ_EINVAL);
1388 PJ_ASSERT_RETURN(tdata->msg->type == PJSIP_RESPONSE_MSG,
1389 PJSIP_ENOTRESPONSEMSG);
1390 PJ_ASSERT_RETURN(st_code >= 100 && st_code <= 699, PJ_EINVAL);
1391
1392 /* Lock and increment session */
1393 pjsip_dlg_inc_lock(dlg);
1394
1395 /* Replace status code and reason */
1396 tdata->msg->line.status.code = st_code;
1397 if (st_text) {
1398 pj_strdup(tdata->pool, &tdata->msg->line.status.reason, st_text);
1399 } else {
1400 tdata->msg->line.status.reason = *pjsip_get_status_text(st_code);
1401 }
1402
1403 /* Remove existing Contact header (without this, when dialog sent
1404 * 180 and then 302, the Contact in 302 will not get updated).
1405 */
1406 hdr = (pjsip_hdr*) pjsip_msg_find_hdr(tdata->msg, PJSIP_H_CONTACT, NULL);
1407 if (hdr)
1408 pj_list_erase(hdr);
1409
1410 /* Add tag etc. if necessary */
1411 dlg_beautify_response(dlg, st_code/100 <= 2, st_code, tdata);
1412
1413
1414 /* Must add reference counter, since tsx_send_msg() will decrement it */
1415 pjsip_tx_data_add_ref(tdata);
1416
1417 /* Force to re-print message. */
1418 pjsip_tx_data_invalidate_msg(tdata);
1419
1420 /* Unlock dialog and dec session, may destroy dialog. */
1421 pjsip_dlg_dec_lock(dlg);
1422
1423 return PJ_SUCCESS;
1424}
1425
1426/*
1427 * Send response statefully.
1428 */
1429PJ_DEF(pj_status_t) pjsip_dlg_send_response( pjsip_dialog *dlg,
1430 pjsip_transaction *tsx,
1431 pjsip_tx_data *tdata)
1432{
1433 pj_status_t status;
1434
1435 /* Sanity check. */
1436 PJ_ASSERT_RETURN(dlg && tsx && tdata && tdata->msg, PJ_EINVAL);
1437 PJ_ASSERT_RETURN(tdata->msg->type == PJSIP_RESPONSE_MSG,
1438 PJSIP_ENOTRESPONSEMSG);
1439
1440 /* The transaction must belong to this dialog. */
1441 PJ_ASSERT_RETURN(tsx->mod_data[dlg->ua->id] == dlg, PJ_EINVALIDOP);
1442
1443 pj_log_push_indent();
1444
1445 PJ_LOG(5,(dlg->obj_name, "Sending %s",
1446 pjsip_tx_data_get_info(tdata)));
1447
1448 /* Check that transaction method and cseq match the response.
1449 * This operation is sloooww (search CSeq header twice), that's why
1450 * we only do it in debug mode.
1451 */
1452#if defined(PJ_DEBUG) && PJ_DEBUG!=0
1453 PJ_ASSERT_RETURN( PJSIP_MSG_CSEQ_HDR(tdata->msg)->cseq == tsx->cseq &&
1454 pjsip_method_cmp(&PJSIP_MSG_CSEQ_HDR(tdata->msg)->method,
1455 &tsx->method)==0,
1456 PJ_EINVALIDOP);
1457#endif
1458
1459 /* Must acquire dialog first, to prevent deadlock */
1460 pjsip_dlg_inc_lock(dlg);
1461
1462 /* Last chance to add mandatory headers before the response is
1463 * sent.
1464 */
1465 dlg_beautify_response(dlg, PJ_TRUE, tdata->msg->line.status.code, tdata);
1466
1467 /* If the dialog is locked to transport, make sure that transaction
1468 * is locked to the same transport too.
1469 */
1470 if (dlg->tp_sel.type != tsx->tp_sel.type ||
1471 dlg->tp_sel.u.ptr != tsx->tp_sel.u.ptr)
1472 {
1473 status = pjsip_tsx_set_transport(tsx, &dlg->tp_sel);
1474 pj_assert(status == PJ_SUCCESS);
1475 }
1476
1477 /* Ask transaction to send the response */
1478 status = pjsip_tsx_send_msg(tsx, tdata);
1479
1480 /* This function must decrement transmit data request counter
1481 * regardless of the operation status. The transaction only
1482 * decrements the counter if the operation is successful.
1483 */
1484 if (status != PJ_SUCCESS) {
1485 pjsip_tx_data_dec_ref(tdata);
1486 }
1487
1488 pjsip_dlg_dec_lock(dlg);
1489 pj_log_pop_indent();
1490
1491 return status;
1492}
1493
1494
1495/*
1496 * Combo function to create and send response statefully.
1497 */
1498PJ_DEF(pj_status_t) pjsip_dlg_respond( pjsip_dialog *dlg,
1499 pjsip_rx_data *rdata,
1500 int st_code,
1501 const pj_str_t *st_text,
1502 const pjsip_hdr *hdr_list,
1503 const pjsip_msg_body *body )
1504{
1505 pj_status_t status;
1506 pjsip_tx_data *tdata;
1507
1508 /* Sanity check. */
1509 PJ_ASSERT_RETURN(dlg && rdata && rdata->msg_info.msg, PJ_EINVAL);
1510 PJ_ASSERT_RETURN(rdata->msg_info.msg->type == PJSIP_REQUEST_MSG,
1511 PJSIP_ENOTREQUESTMSG);
1512
1513 /* The transaction must belong to this dialog. */
1514 PJ_ASSERT_RETURN(pjsip_rdata_get_tsx(rdata) &&
1515 pjsip_rdata_get_tsx(rdata)->mod_data[dlg->ua->id] == dlg,
1516 PJ_EINVALIDOP);
1517
1518 /* Create the response. */
1519 status = pjsip_dlg_create_response(dlg, rdata, st_code, st_text, &tdata);
1520 if (status != PJ_SUCCESS)
1521 return status;
1522
1523 /* Add additional header, if any */
1524 if (hdr_list) {
1525 const pjsip_hdr *hdr;
1526
1527 hdr = hdr_list->next;
1528 while (hdr != hdr_list) {
1529 pjsip_msg_add_hdr(tdata->msg,
1530 (pjsip_hdr*)pjsip_hdr_clone(tdata->pool, hdr));
1531 hdr = hdr->next;
1532 }
1533 }
1534
1535 /* Add the message body, if any. */
1536 if (body) {
1537 tdata->msg->body = pjsip_msg_body_clone( tdata->pool, body);
1538 }
1539
1540 /* Send the response. */
1541 return pjsip_dlg_send_response(dlg, pjsip_rdata_get_tsx(rdata), tdata);
1542}
1543
1544
1545/* This function is called by user agent upon receiving incoming request
1546 * message.
1547 */
1548void pjsip_dlg_on_rx_request( pjsip_dialog *dlg, pjsip_rx_data *rdata )
1549{
1550 pj_status_t status;
1551 pjsip_transaction *tsx = NULL;
1552 pj_bool_t processed = PJ_FALSE;
1553 unsigned i;
1554
1555 PJ_LOG(5,(dlg->obj_name, "Received %s",
1556 pjsip_rx_data_get_info(rdata)));
1557 pj_log_push_indent();
1558
1559 /* Lock dialog and increment session. */
1560 pjsip_dlg_inc_lock(dlg);
1561
1562 /* Check CSeq */
1563 if (rdata->msg_info.cseq->cseq <= dlg->remote.cseq &&
1564 rdata->msg_info.msg->line.req.method.id != PJSIP_ACK_METHOD &&
1565 rdata->msg_info.msg->line.req.method.id != PJSIP_CANCEL_METHOD)
1566 {
1567 /* Invalid CSeq.
1568 * Respond statelessly with 500 (Internal Server Error)
1569 */
1570 pj_str_t warn_text;
1571
1572 /* Unlock dialog and dec session, may destroy dialog. */
1573 pjsip_dlg_dec_lock(dlg);
1574
1575 pj_assert(pjsip_rdata_get_tsx(rdata) == NULL);
1576 warn_text = pj_str("Invalid CSeq");
1577 pjsip_endpt_respond_stateless(dlg->endpt,
1578 rdata, 500, &warn_text, NULL, NULL);
1579 pj_log_pop_indent();
1580 return;
1581 }
1582
1583 /* Update CSeq. */
1584 dlg->remote.cseq = rdata->msg_info.cseq->cseq;
1585
1586 /* Update To tag if necessary.
1587 * This only happens if UAS sends a new request before answering
1588 * our request (e.g. UAS sends NOTIFY before answering our
1589 * SUBSCRIBE request).
1590 */
1591 if (dlg->remote.info->tag.slen == 0) {
1592 pj_strdup(dlg->pool, &dlg->remote.info->tag,
1593 &rdata->msg_info.from->tag);
1594 }
1595
1596 /* Create UAS transaction for this request. */
1597 if (pjsip_rdata_get_tsx(rdata) == NULL &&
1598 rdata->msg_info.msg->line.req.method.id != PJSIP_ACK_METHOD)
1599 {
1600 status = pjsip_tsx_create_uas(dlg->ua, rdata, &tsx);
1601 if (status != PJ_SUCCESS) {
1602 /* Once case for this is when re-INVITE contains same
1603 * Via branch value as previous INVITE (ticket #965).
1604 */
1605 char errmsg[PJ_ERR_MSG_SIZE];
1606 pj_str_t reason;
1607
1608 reason = pj_strerror(status, errmsg, sizeof(errmsg));
1609 pjsip_endpt_respond_stateless(dlg->endpt, rdata, 500, &reason,
1610 NULL, NULL);
1611 goto on_return;
1612 }
1613
1614 /* Put this dialog in the transaction data. */
1615 tsx->mod_data[dlg->ua->id] = dlg;
1616
1617 /* Add transaction count. */
1618 ++dlg->tsx_count;
1619 }
1620
1621 /* Update the target URI if this is a target refresh request.
1622 * We have passed the basic checking for the request, I think we
1623 * should update the target URI regardless of whether the request
1624 * is accepted or not (e.g. when re-INVITE is answered with 488,
1625 * we would still need to update the target URI, otherwise our
1626 * target URI would be wrong, wouldn't it).
1627 */
1628 if (pjsip_method_creates_dialog(&rdata->msg_info.cseq->method)) {
1629 pjsip_contact_hdr *contact;
1630
1631 contact = (pjsip_contact_hdr*)
1632 pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT,
1633 NULL);
1634 if (contact && contact->uri &&
1635 (dlg->remote.contact==NULL ||
1636 pjsip_uri_cmp(PJSIP_URI_IN_REQ_URI,
1637 dlg->remote.contact->uri,
1638 contact->uri)))
1639 {
1640 dlg->remote.contact = (pjsip_contact_hdr*)
1641 pjsip_hdr_clone(dlg->pool, contact);
1642 dlg->target = dlg->remote.contact->uri;
1643 }
1644 }
1645
1646 /* Report the request to dialog usages. */
1647 for (i=0; i<dlg->usage_cnt; ++i) {
1648
1649 if (!dlg->usage[i]->on_rx_request)
1650 continue;
1651
1652 processed = (*dlg->usage[i]->on_rx_request)(rdata);
1653
1654 if (processed)
1655 break;
1656 }
1657
1658 /* Feed the first request to the transaction. */
1659 if (tsx)
1660 pjsip_tsx_recv_msg(tsx, rdata);
1661
1662 /* If no dialog usages has claimed the processing of the transaction,
1663 * and if transaction has not sent final response, respond with
1664 * 500/Internal Server Error.
1665 */
1666 if (!processed && tsx && tsx->status_code < 200) {
1667 pjsip_tx_data *tdata;
1668 const pj_str_t reason = { "Unhandled by dialog usages", 26};
1669
1670 PJ_LOG(4,(tsx->obj_name, "%s was unhandled by "
1671 "dialog usages, sending 500 response",
1672 pjsip_rx_data_get_info(rdata)));
1673
1674 status = pjsip_dlg_create_response(dlg, rdata, 500, &reason, &tdata);
1675 if (status == PJ_SUCCESS) {
1676 status = pjsip_dlg_send_response(dlg, tsx, tdata);
1677 }
1678 }
1679
1680on_return:
1681 /* Unlock dialog and dec session, may destroy dialog. */
1682 pjsip_dlg_dec_lock(dlg);
1683 pj_log_pop_indent();
1684}
1685
1686/* Update route-set from incoming message */
1687static void dlg_update_routeset(pjsip_dialog *dlg, const pjsip_rx_data *rdata)
1688{
1689 const pjsip_hdr *hdr, *end_hdr;
1690 pj_int32_t msg_cseq;
1691 const pjsip_msg *msg;
1692
1693 msg = rdata->msg_info.msg;
1694 msg_cseq = rdata->msg_info.cseq->cseq;
1695
1696 /* Ignore if route set has been frozen */
1697 if (dlg->route_set_frozen)
1698 return;
1699
1700 /* Only update route set if this message belongs to the same
1701 * transaction as the initial transaction that establishes dialog.
1702 */
1703 if (dlg->role == PJSIP_ROLE_UAC) {
1704
1705 /* Ignore subsequent request from remote */
1706 if (msg->type != PJSIP_RESPONSE_MSG)
1707 return;
1708
1709 /* Ignore subsequent responses with higher CSeq than initial CSeq.
1710 * Unfortunately this would be broken when the first request is
1711 * challenged!
1712 */
1713 //if (msg_cseq != dlg->local.first_cseq)
1714 // return;
1715
1716 } else {
1717
1718 /* For callee dialog, route set should have been set by initial
1719 * request and it will have been rejected by dlg->route_set_frozen
1720 * check above.
1721 */
1722 pj_assert(!"Should not happen");
1723
1724 }
1725
1726 /* Based on the checks above, we should only get response message here */
1727 pj_assert(msg->type == PJSIP_RESPONSE_MSG);
1728
1729 /* Ignore if this is not 1xx or 2xx response */
1730 if (msg->line.status.code >= 300)
1731 return;
1732
1733 /* Reset route set */
1734 pj_list_init(&dlg->route_set);
1735
1736 /* Update route set */
1737 end_hdr = &msg->hdr;
1738 for (hdr=msg->hdr.prev; hdr!=end_hdr; hdr=hdr->prev) {
1739 if (hdr->type == PJSIP_H_RECORD_ROUTE) {
1740 pjsip_route_hdr *r;
1741 r = (pjsip_route_hdr*) pjsip_hdr_clone(dlg->pool, hdr);
1742 pjsip_routing_hdr_set_route(r);
1743 pj_list_push_back(&dlg->route_set, r);
1744 }
1745 }
1746
1747 PJ_LOG(5,(dlg->obj_name, "Route-set updated"));
1748
1749 /* Freeze the route set only when the route set comes in 2xx response.
1750 * If it is in 1xx response, prepare to recompute the route set when
1751 * the 2xx response comes in.
1752 *
1753 * There is a debate whether route set should be frozen when the dialog
1754 * is established with reliable provisional response, but I think
1755 * it is safer to not freeze the route set (thus recompute the route set
1756 * upon receiving 2xx response). Also RFC 3261 says so in 13.2.2.4.
1757 *
1758 * The pjsip_method_creates_dialog() check protects from wrongly
1759 * freezing the route set upon receiving 200/OK response for PRACK.
1760 */
1761 if (pjsip_method_creates_dialog(&rdata->msg_info.cseq->method) &&
1762 PJSIP_IS_STATUS_IN_CLASS(msg->line.status.code, 200))
1763 {
1764 dlg->route_set_frozen = PJ_TRUE;
1765 PJ_LOG(5,(dlg->obj_name, "Route-set frozen"));
1766 }
1767}
1768
1769
1770/* This function is called by user agent upon receiving incoming response
1771 * message.
1772 */
1773void pjsip_dlg_on_rx_response( pjsip_dialog *dlg, pjsip_rx_data *rdata )
1774{
1775 unsigned i;
1776 int res_code;
1777
1778 PJ_LOG(5,(dlg->obj_name, "Received %s",
1779 pjsip_rx_data_get_info(rdata)));
1780 pj_log_push_indent();
1781
1782 /* Lock the dialog and inc session. */
1783 pjsip_dlg_inc_lock(dlg);
1784
1785 /* Check that rdata already has dialog in mod_data. */
1786 pj_assert(pjsip_rdata_get_dlg(rdata) == dlg);
1787
1788 /* Keep the response's status code */
1789 res_code = rdata->msg_info.msg->line.status.code;
1790
1791 /* When we receive response that establishes dialog, update To tag,
1792 * route set and dialog target.
1793 *
1794 * The second condition of the "if" is a workaround for forking.
1795 * Originally, the dialog takes the first To tag seen and set it as
1796 * the remote tag. If the tag in 2xx response is different than this
1797 * tag, ACK will be sent with wrong To tag and incoming request with
1798 * this tag will be rejected with 481.
1799 *
1800 * The workaround for this is to take the To tag received in the
1801 * 2xx response and set it as remote tag.
1802 *
1803 * New update:
1804 * We also need to update the dialog for 1xx responses, to handle the
1805 * case when 100rel is used, otherwise PRACK will be sent to the
1806 * wrong target.
1807 */
1808 if ((dlg->state == PJSIP_DIALOG_STATE_NULL &&
1809 pjsip_method_creates_dialog(&rdata->msg_info.cseq->method) &&
1810 (res_code > 100 && res_code < 300) &&
1811 rdata->msg_info.to->tag.slen)
1812 ||
1813 (dlg->role==PJSIP_ROLE_UAC &&
1814 !dlg->uac_has_2xx &&
1815 res_code > 100 &&
1816 res_code/100 <= 2 &&
1817 pjsip_method_creates_dialog(&rdata->msg_info.cseq->method) &&
1818 pj_stricmp(&dlg->remote.info->tag, &rdata->msg_info.to->tag)))
1819 {
1820 pjsip_contact_hdr *contact;
1821
1822 /* Update remote capability info, when To tags in the dialog remote
1823 * info and the incoming response are different, e.g: first response
1824 * with To-tag or forking, apply strict update.
1825 */
1826 pjsip_dlg_update_remote_cap(dlg, rdata->msg_info.msg,
1827 pj_stricmp(&dlg->remote.info->tag,
1828 &rdata->msg_info.to->tag));
1829
1830 /* Update To tag. */
1831 pj_strdup(dlg->pool, &dlg->remote.info->tag, &rdata->msg_info.to->tag);
1832 /* No need to update remote's tag_hval since its never used. */
1833
1834 /* RFC 3271 Section 12.1.2:
1835 * The route set MUST be set to the list of URIs in the Record-Route
1836 * header field from the response, taken in reverse order and
1837 * preserving all URI parameters. If no Record-Route header field
1838 * is present in the response, the route set MUST be set to the
1839 * empty set. This route set, even if empty, overrides any pre-existing
1840 * route set for future requests in this dialog.
1841 */
1842 dlg_update_routeset(dlg, rdata);
1843
1844 /* The remote target MUST be set to the URI from the Contact header
1845 * field of the response.
1846 */
1847 contact = (pjsip_contact_hdr*)
1848 pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT,
1849 NULL);
1850 if (contact && contact->uri &&
1851 (dlg->remote.contact==NULL ||
1852 pjsip_uri_cmp(PJSIP_URI_IN_REQ_URI,
1853 dlg->remote.contact->uri,
1854 contact->uri)))
1855 {
1856 dlg->remote.contact = (pjsip_contact_hdr*)
1857 pjsip_hdr_clone(dlg->pool, contact);
1858 dlg->target = dlg->remote.contact->uri;
1859 }
1860
1861 dlg->state = PJSIP_DIALOG_STATE_ESTABLISHED;
1862
1863 /* Prevent dialog from being updated just in case more 2xx
1864 * gets through this dialog (it shouldn't happen).
1865 */
1866 if (dlg->role==PJSIP_ROLE_UAC && !dlg->uac_has_2xx &&
1867 res_code/100==2)
1868 {
1869 dlg->uac_has_2xx = PJ_TRUE;
1870 }
1871 }
1872
1873 /* Update remote target (again) when receiving 2xx response messages
1874 * that's defined as target refresh.
1875 *
1876 * Also upon receiving 2xx response, recheck again the route set.
1877 * This is for compatibility with RFC 2543, as described in Section
1878 * 13.2.2.4 of RFC 3261:
1879
1880 If the dialog identifier in the 2xx response matches the dialog
1881 identifier of an existing dialog, the dialog MUST be transitioned to
1882 the "confirmed" state, and the route set for the dialog MUST be
1883 recomputed based on the 2xx response using the procedures of Section
1884 12.2.1.2.
1885
1886 Note that the only piece of state that is recomputed is the route
1887 set. Other pieces of state such as the highest sequence numbers
1888 (remote and local) sent within the dialog are not recomputed. The
1889 route set only is recomputed for backwards compatibility. RFC
1890 2543 did not mandate mirroring of the Record-Route header field in
1891 a 1xx, only 2xx.
1892 */
1893 if (pjsip_method_creates_dialog(&rdata->msg_info.cseq->method) &&
1894 res_code/100 == 2)
1895 {
1896 pjsip_contact_hdr *contact;
1897
1898 contact = (pjsip_contact_hdr*) pjsip_msg_find_hdr(rdata->msg_info.msg,
1899 PJSIP_H_CONTACT,
1900 NULL);
1901 if (contact && contact->uri &&
1902 (dlg->remote.contact==NULL ||
1903 pjsip_uri_cmp(PJSIP_URI_IN_REQ_URI,
1904 dlg->remote.contact->uri,
1905 contact->uri)))
1906 {
1907 dlg->remote.contact = (pjsip_contact_hdr*)
1908 pjsip_hdr_clone(dlg->pool, contact);
1909 dlg->target = dlg->remote.contact->uri;
1910 }
1911
1912 dlg_update_routeset(dlg, rdata);
1913
1914 /* Update remote capability info after the first 2xx response
1915 * (ticket #1539). Note that the remote capability retrieved here
1916 * will be assumed to remain unchanged for the duration of the dialog.
1917 */
1918 if (dlg->role==PJSIP_ROLE_UAC && !dlg->uac_has_2xx) {
1919 pjsip_dlg_update_remote_cap(dlg, rdata->msg_info.msg, PJ_FALSE);
1920 dlg->uac_has_2xx = PJ_TRUE;
1921 }
1922 }
1923
1924 /* Pass to dialog usages. */
1925 for (i=0; i<dlg->usage_cnt; ++i) {
1926 pj_bool_t processed;
1927
1928 if (!dlg->usage[i]->on_rx_response)
1929 continue;
1930
1931 processed = (*dlg->usage[i]->on_rx_response)(rdata);
1932
1933 if (processed)
1934 break;
1935 }
1936
1937 /* Handle the case of forked response, when the application creates
1938 * the forked dialog but not the invite session. In this case, the
1939 * forked 200/OK response will be unhandled, and we must send ACK
1940 * here.
1941 */
1942 if (dlg->usage_cnt==0) {
1943 pj_status_t status;
1944
1945 if (rdata->msg_info.cseq->method.id==PJSIP_INVITE_METHOD &&
1946 rdata->msg_info.msg->line.status.code/100 == 2)
1947 {
1948 pjsip_tx_data *ack;
1949
1950 status = pjsip_dlg_create_request(dlg, &pjsip_ack_method,
1951 rdata->msg_info.cseq->cseq,
1952 &ack);
1953 if (status == PJ_SUCCESS)
1954 status = pjsip_dlg_send_request(dlg, ack, -1, NULL);
1955 } else if (rdata->msg_info.msg->line.status.code==401 ||
1956 rdata->msg_info.msg->line.status.code==407)
1957 {
1958 pjsip_transaction *tsx = pjsip_rdata_get_tsx(rdata);
1959 pjsip_tx_data *tdata;
1960
1961 status = pjsip_auth_clt_reinit_req( &dlg->auth_sess,
1962 rdata, tsx->last_tx,
1963 &tdata);
1964
1965 if (status == PJ_SUCCESS) {
1966 /* Re-send request. */
1967 status = pjsip_dlg_send_request(dlg, tdata, -1, NULL);
1968 }
1969 }
1970 }
1971
1972 /* Unhandled response does not necessarily mean error because
1973 dialog usages may choose to process the transaction state instead.
1974 if (i==dlg->usage_cnt) {
1975 PJ_LOG(4,(dlg->obj_name, "%s was not claimed by any dialog usages",
1976 pjsip_rx_data_get_info(rdata)));
1977 }
1978 */
1979
1980 /* Unlock dialog and dec session, may destroy dialog. */
1981 pjsip_dlg_dec_lock(dlg);
1982
1983 pj_log_pop_indent();
1984}
1985
1986/* This function is called by user agent upon receiving transaction
1987 * state notification.
1988 */
1989void pjsip_dlg_on_tsx_state( pjsip_dialog *dlg,
1990 pjsip_transaction *tsx,
1991 pjsip_event *e )
1992{
1993 unsigned i;
1994
1995 PJ_LOG(5,(dlg->obj_name, "Transaction %s state changed to %s",
1996 tsx->obj_name, pjsip_tsx_state_str(tsx->state)));
1997 pj_log_push_indent();
1998
1999 /* Lock the dialog and increment session. */
2000 pjsip_dlg_inc_lock(dlg);
2001
2002 /* Pass to dialog usages. */
2003 for (i=0; i<dlg->usage_cnt; ++i) {
2004
2005 if (!dlg->usage[i]->on_tsx_state)
2006 continue;
2007
2008 (*dlg->usage[i]->on_tsx_state)(tsx, e);
2009 }
2010
2011
2012 /* It is possible that the transaction is terminated and this function
2013 * is called while we're calling on_tsx_state(). So only decrement
2014 * the tsx_count if we're still attached to the transaction.
2015 */
2016 if (tsx->state == PJSIP_TSX_STATE_TERMINATED &&
2017 tsx->mod_data[dlg->ua->id] == dlg)
2018 {
2019 pj_assert(dlg->tsx_count>0);
2020 --dlg->tsx_count;
2021 tsx->mod_data[dlg->ua->id] = NULL;
2022 }
2023
2024 /* Unlock dialog and dec session, may destroy dialog. */
2025 pjsip_dlg_dec_lock(dlg);
2026 pj_log_pop_indent();
2027}
2028
2029
2030/*
2031 * Check if the specified capability is supported by remote.
2032 */
2033PJ_DEF(pjsip_dialog_cap_status) pjsip_dlg_remote_has_cap(
2034 pjsip_dialog *dlg,
2035 int htype,
2036 const pj_str_t *hname,
2037 const pj_str_t *token)
2038{
2039 const pjsip_generic_array_hdr *hdr;
2040 pjsip_dialog_cap_status cap_status = PJSIP_DIALOG_CAP_UNSUPPORTED;
2041 unsigned i;
2042
2043 PJ_ASSERT_RETURN(dlg && token, PJSIP_DIALOG_CAP_UNKNOWN);
2044
2045 pjsip_dlg_inc_lock(dlg);
2046
2047 hdr = (const pjsip_generic_array_hdr*)
2048 pjsip_dlg_get_remote_cap_hdr(dlg, htype, hname);
2049 if (!hdr) {
2050 cap_status = PJSIP_DIALOG_CAP_UNKNOWN;
2051 } else {
2052 for (i=0; i<hdr->count; ++i) {
2053 if (!pj_stricmp(&hdr->values[i], token)) {
2054 cap_status = PJSIP_DIALOG_CAP_SUPPORTED;
2055 break;
2056 }
2057 }
2058 }
2059
2060 pjsip_dlg_dec_lock(dlg);
2061
2062 return cap_status;
2063}
2064
2065
2066/*
2067 * Update remote capability of ACCEPT, ALLOW, and SUPPORTED from
2068 * the received message.
2069 */
2070PJ_DEF(pj_status_t) pjsip_dlg_update_remote_cap(pjsip_dialog *dlg,
2071 const pjsip_msg *msg,
2072 pj_bool_t strict)
2073{
2074 pjsip_hdr_e htypes[] =
2075 { PJSIP_H_ACCEPT, PJSIP_H_ALLOW, PJSIP_H_SUPPORTED };
2076 unsigned i;
2077
2078 PJ_ASSERT_RETURN(dlg && msg, PJ_EINVAL);
2079
2080 pjsip_dlg_inc_lock(dlg);
2081
2082 /* Retrieve all specified capability header types */
2083 for (i = 0; i < PJ_ARRAY_SIZE(htypes); ++i) {
2084 const pjsip_generic_array_hdr *hdr;
2085 pj_status_t status;
2086
2087 /* Find this capability type in the message */
2088 hdr = (const pjsip_generic_array_hdr*)
2089 pjsip_msg_find_hdr(msg, htypes[i], NULL);
2090 if (!hdr) {
2091 /* Not found.
2092 * If strict update is specified, remote this capability type
2093 * from the capability list.
2094 */
2095 if (strict)
2096 pjsip_dlg_remove_remote_cap_hdr(dlg, htypes[i], NULL);
2097 } else {
2098 /* Found, a capability type may be specified in multiple headers,
2099 * so combine all the capability tags/values into a temporary
2100 * header.
2101 */
2102 pjsip_generic_array_hdr tmp_hdr;
2103
2104 /* Init temporary header */
2105 pjsip_generic_array_hdr_init(dlg->pool, &tmp_hdr, NULL);
2106 pj_memcpy(&tmp_hdr, hdr, sizeof(pjsip_hdr));
2107
2108 while (hdr) {
2109 unsigned j;
2110
2111 /* Append the header content to temporary header */
2112 for(j=0; j<hdr->count &&
2113 tmp_hdr.count<PJSIP_GENERIC_ARRAY_MAX_COUNT; ++j)
2114 {
2115 tmp_hdr.values[tmp_hdr.count++] = hdr->values[j];
2116 }
2117
2118 /* Get the next header for this capability */
2119 hdr = (const pjsip_generic_array_hdr*)
2120 pjsip_msg_find_hdr(msg, htypes[i], hdr->next);
2121 }
2122
2123 /* Save this capability */
2124 status = pjsip_dlg_set_remote_cap_hdr(dlg, &tmp_hdr);
2125 if (status != PJ_SUCCESS) {
2126 pjsip_dlg_dec_lock(dlg);
2127 return status;
2128 }
2129 }
2130 }
2131
2132 pjsip_dlg_dec_lock(dlg);
2133
2134 return PJ_SUCCESS;
2135}
2136
2137
2138/*
2139 * Get the value of the specified capability header field of remote.
2140 */
2141PJ_DEF(const pjsip_hdr*) pjsip_dlg_get_remote_cap_hdr(pjsip_dialog *dlg,
2142 int htype,
2143 const pj_str_t *hname)
2144{
2145 pjsip_hdr *hdr;
2146
2147 /* Check arguments. */
2148 PJ_ASSERT_RETURN(dlg, NULL);
2149 PJ_ASSERT_RETURN((htype != PJSIP_H_OTHER) || (hname && hname->slen),
2150 NULL);
2151
2152 pjsip_dlg_inc_lock(dlg);
2153
2154 hdr = dlg->rem_cap_hdr.next;
2155 while (hdr != &dlg->rem_cap_hdr) {
2156 if ((htype != PJSIP_H_OTHER && htype == hdr->type) ||
2157 (htype == PJSIP_H_OTHER && pj_stricmp(&hdr->name, hname) == 0))
2158 {
2159 pjsip_dlg_dec_lock(dlg);
2160 return hdr;
2161 }
2162 hdr = hdr->next;
2163 }
2164
2165 pjsip_dlg_dec_lock(dlg);
2166
2167 return NULL;
2168}
2169
2170
2171/*
2172 * Set remote capability header from a SIP header containing array
2173 * of capability tags/values.
2174 */
2175PJ_DEF(pj_status_t) pjsip_dlg_set_remote_cap_hdr(
2176 pjsip_dialog *dlg,
2177 const pjsip_generic_array_hdr *cap_hdr)
2178{
2179 pjsip_generic_array_hdr *hdr;
2180
2181 /* Check arguments. */
2182 PJ_ASSERT_RETURN(dlg && cap_hdr, PJ_EINVAL);
2183
2184 pjsip_dlg_inc_lock(dlg);
2185
2186 /* Find the header. */
2187 hdr = (pjsip_generic_array_hdr*)
2188 pjsip_dlg_get_remote_cap_hdr(dlg, cap_hdr->type, &cap_hdr->name);
2189
2190 /* Quick compare if the capability is up to date */
2191 if (hdr && hdr->count == cap_hdr->count) {
2192 unsigned i;
2193 pj_bool_t uptodate = PJ_TRUE;
2194
2195 for (i=0; i<hdr->count; ++i) {
2196 if (pj_stricmp(&hdr->values[i], &cap_hdr->values[i]))
2197 uptodate = PJ_FALSE;
2198 }
2199
2200 /* Capability is up to date, just return PJ_SUCCESS */
2201 if (uptodate) {
2202 pjsip_dlg_dec_lock(dlg);
2203 return PJ_SUCCESS;
2204 }
2205 }
2206
2207 /* Remove existing capability header if any */
2208 if (hdr)
2209 pj_list_erase(hdr);
2210
2211 /* Add the new capability header */
2212 hdr = (pjsip_generic_array_hdr*) pjsip_hdr_clone(dlg->pool, cap_hdr);
2213 hdr->type = cap_hdr->type;
2214 pj_strdup(dlg->pool, &hdr->name, &cap_hdr->name);
2215 pj_list_push_back(&dlg->rem_cap_hdr, hdr);
2216
2217 pjsip_dlg_dec_lock(dlg);
2218
2219 /* Done. */
2220 return PJ_SUCCESS;
2221}
2222
2223/*
2224 * Remove a remote capability header.
2225 */
2226PJ_DEF(pj_status_t) pjsip_dlg_remove_remote_cap_hdr(pjsip_dialog *dlg,
2227 int htype,
2228 const pj_str_t *hname)
2229{
2230 pjsip_generic_array_hdr *hdr;
2231
2232 /* Check arguments. */
2233 PJ_ASSERT_RETURN(dlg, PJ_EINVAL);
2234 PJ_ASSERT_RETURN((htype != PJSIP_H_OTHER) || (hname && hname->slen),
2235 PJ_EINVAL);
2236
2237 pjsip_dlg_inc_lock(dlg);
2238
2239 hdr = (pjsip_generic_array_hdr*)
2240 pjsip_dlg_get_remote_cap_hdr(dlg, htype, hname);
2241 if (!hdr) {
2242 pjsip_dlg_dec_lock(dlg);
2243 return PJ_ENOTFOUND;
2244 }
2245
2246 pj_list_erase(hdr);
2247
2248 pjsip_dlg_dec_lock(dlg);
2249
2250 return PJ_SUCCESS;
2251}