dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / lib / libsip / common / sip_dialog_ui.c
blob998ad452187d52cd05c177765e2b0c5da3ce3d35
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
29 #include <stdlib.h>
30 #include <assert.h>
31 #include <errno.h>
32 #include <pthread.h>
33 #include <sip.h>
35 #include "sip_msg.h"
36 #include "sip_miscdefs.h"
37 #include "sip_parse_uri.h"
38 #include "sip_dialog.h"
41 * Create a request using the state maintained in the dialog.
43 sip_msg_t
44 sip_create_dialog_req(sip_method_t method, sip_dialog_t dialog,
45 char *transport, char *sent_by, int sent_by_port, char *via_param,
46 uint32_t maxforward, int cseq)
48 _sip_dialog_t *_dialog;
49 sip_msg_t sip_msg;
50 char *uri;
51 int oldseq = 0;
53 if (!sip_manage_dialog || dialog == NULL || transport == NULL ||
54 sent_by == NULL) {
55 return (NULL);
57 if ((sip_msg = sip_new_msg()) == NULL)
58 return (NULL);
59 _dialog = (_sip_dialog_t *)dialog;
60 (void) pthread_mutex_lock(&_dialog->sip_dlg_mutex);
62 * Depending on the route set, if any, the request URI could either
63 * be the contact URI or the 1st URI from the route set.
65 uri = (char *)sip_dialog_req_uri(_dialog);
66 if (uri == NULL)
67 goto err_ret;
68 if (sip_add_request_line(sip_msg, method, uri) != 0) {
69 free(uri);
70 goto err_ret;
72 free(uri);
73 if (sip_copy_header(sip_msg, _dialog->sip_dlg_local_uri_tag, NULL) != 0)
74 goto err_ret;
75 if (sip_copy_header(sip_msg, _dialog->sip_dlg_remote_uri_tag, NULL) !=
76 0) {
77 goto err_ret;
79 if (sip_copy_header(sip_msg, _dialog->sip_dlg_local_contact, NULL) != 0)
80 goto err_ret;
81 if (sip_add_via(sip_msg, transport, sent_by, sent_by_port, via_param) !=
82 0) {
83 goto err_ret;
85 if (sip_add_maxforward(sip_msg, maxforward) != 0)
86 goto err_ret;
87 if (sip_copy_header(sip_msg, _dialog->sip_dlg_call_id, NULL) != 0)
88 goto err_ret;
89 if (cseq < 0) {
90 if (_dialog->sip_dlg_local_cseq == 0)
91 _dialog->sip_dlg_local_cseq = 1;
92 oldseq = _dialog->sip_dlg_local_cseq;
93 cseq = ++_dialog->sip_dlg_local_cseq;
95 if (sip_add_cseq(sip_msg, method, cseq) != 0) {
96 _dialog->sip_dlg_local_cseq = oldseq;
97 goto err_ret;
100 * The route set, even if empty, overrides any pre-existing route set.
101 * If the route set is empty, the UAC MUST NOT add a Route header
102 * field to the request.
104 (void) sip_delete_header_by_name(sip_msg, SIP_ROUTE);
106 if (_dialog->sip_dlg_route_set != NULL) {
107 if (sip_copy_header(sip_msg, _dialog->sip_dlg_route_set,
108 NULL) != 0) {
109 _dialog->sip_dlg_local_cseq = oldseq;
110 goto err_ret;
113 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex);
114 return (sip_msg);
115 err_ret:
116 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex);
117 sip_free_msg(sip_msg);
118 return (NULL);
122 * Create a request using the state maintained in the dialog. The request will
123 * not have Contact header.
125 sip_msg_t
126 sip_create_dialog_req_nocontact(sip_method_t method, sip_dialog_t dialog,
127 char *transport, char *sent_by, int sent_by_port, char *via_param,
128 uint32_t maxforward, int cseq)
130 sip_msg_t sip_msg;
132 sip_msg = sip_create_dialog_req(method, dialog, transport, sent_by,
133 sent_by_port, via_param, maxforward, cseq);
134 if (sip_msg != NULL) {
135 if (sip_delete_header_by_name(sip_msg, SIP_CONTACT) != 0) {
136 sip_free_msg(sip_msg);
137 return (NULL);
141 return (sip_msg);
145 * Get the Dialog method
148 sip_get_dialog_method(sip_dialog_t dialog, int *error)
150 _sip_dialog_t *_dialog;
152 if (error != NULL)
153 *error = 0;
154 if (!sip_manage_dialog) {
155 if (error != NULL)
156 *error = EINVAL;
157 return (0);
159 if (dialog == NULL) {
160 if (error != NULL)
161 *error = EINVAL;
162 return (0);
164 _dialog = (_sip_dialog_t *)dialog;
165 return (_dialog->sip_dlg_method);
169 * Get the Dialog state
172 sip_get_dialog_state(sip_dialog_t dialog, int *error)
174 _sip_dialog_t *_dialog;
176 if (error != NULL)
177 *error = 0;
178 if (!sip_manage_dialog) {
179 if (error != NULL)
180 *error = EINVAL;
181 return (0);
183 if (dialog == NULL) {
184 if (error != NULL)
185 *error = EINVAL;
186 return (0);
188 _dialog = (_sip_dialog_t *)dialog;
189 return (_dialog->sip_dlg_state);
193 * Return the dialog callid
195 const sip_str_t *
196 sip_get_dialog_callid(sip_dialog_t dialog, int *error)
198 _sip_dialog_t *_dialog;
199 const struct sip_value *val;
200 const sip_str_t *callid = NULL;
202 if (error != NULL)
203 *error = 0;
204 if (!sip_manage_dialog || dialog == NULL) {
205 if (error != NULL)
206 *error = EINVAL;
207 return (NULL);
209 _dialog = (_sip_dialog_t *)dialog;
210 (void) pthread_mutex_lock(&_dialog->sip_dlg_mutex);
211 if (dialog->sip_dlg_call_id != NULL) {
212 val = sip_get_header_value(_dialog->sip_dlg_call_id, error);
213 if (val == NULL) {
214 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex);
215 return (NULL);
217 callid = &((sip_hdr_value_t *)val)->str_val;
219 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex);
220 return (callid);
224 * Return the dialog localtag.
226 const sip_str_t *
227 sip_get_dialog_local_tag(sip_dialog_t dialog, int *error)
229 _sip_dialog_t *_dialog;
230 const sip_str_t *ltag = NULL;
231 const struct sip_value *val;
233 if (error != NULL)
234 *error = 0;
235 if (!sip_manage_dialog || dialog == NULL) {
236 if (error != NULL)
237 *error = EINVAL;
238 return (NULL);
240 _dialog = (_sip_dialog_t *)dialog;
241 (void) pthread_mutex_lock(&_dialog->sip_dlg_mutex);
242 if (dialog->sip_dlg_local_uri_tag != NULL) {
243 val = sip_get_header_value(_dialog->sip_dlg_local_uri_tag,
244 error);
245 if (val == NULL) {
246 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex);
247 return (NULL);
249 ltag = sip_get_param_value((sip_header_value_t)val, "tag",
250 error);
252 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex);
253 return (ltag);
257 * Return the dialog remotetag
259 const sip_str_t *
260 sip_get_dialog_remote_tag(sip_dialog_t dialog, int *error)
262 _sip_dialog_t *_dialog;
263 const sip_str_t *ttag = NULL;
264 const struct sip_value *val;
266 if (error != NULL)
267 *error = 0;
268 if (!sip_manage_dialog || dialog == NULL) {
269 if (error != NULL)
270 *error = EINVAL;
271 return (NULL);
273 _dialog = (_sip_dialog_t *)dialog;
274 (void) pthread_mutex_lock(&_dialog->sip_dlg_mutex);
275 if (dialog->sip_dlg_remote_uri_tag != NULL) {
276 val = sip_get_header_value(_dialog->sip_dlg_remote_uri_tag,
277 error);
278 if (val == NULL) {
279 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex);
280 return (NULL);
282 ttag = sip_get_param_value((sip_header_value_t)val, "tag",
283 error);
285 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex);
287 return (ttag);
291 * Return the dialog localuri.
293 const struct sip_uri *
294 sip_get_dialog_local_uri(sip_dialog_t dialog, int *error)
296 _sip_dialog_t *_dialog;
297 const _sip_uri_t *luri = NULL;
298 const struct sip_value *val;
300 if (error != NULL)
301 *error = 0;
302 if (!sip_manage_dialog || dialog == NULL) {
303 if (error != NULL)
304 *error = EINVAL;
305 return (NULL);
307 _dialog = (_sip_dialog_t *)dialog;
308 (void) pthread_mutex_lock(&_dialog->sip_dlg_mutex);
309 if (dialog->sip_dlg_local_uri_tag != NULL) {
310 val = sip_get_header_value(_dialog->sip_dlg_local_uri_tag,
311 error);
312 if (val == NULL) {
313 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex);
314 return (NULL);
316 luri = val->sip_value_parse_uri;
318 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex);
320 return ((sip_uri_t)luri);
324 * Return the dialog remoteuri.
326 const struct sip_uri *
327 sip_get_dialog_remote_uri(sip_dialog_t dialog, int *error)
329 _sip_dialog_t *_dialog;
330 const _sip_uri_t *ruri = NULL;
331 const struct sip_value *val;
333 if (error != NULL)
334 *error = 0;
335 if (!sip_manage_dialog || dialog == NULL) {
336 if (error != NULL)
337 *error = EINVAL;
338 return (NULL);
340 _dialog = (_sip_dialog_t *)dialog;
341 (void) pthread_mutex_lock(&_dialog->sip_dlg_mutex);
342 if (dialog->sip_dlg_remote_uri_tag != NULL) {
343 val = sip_get_header_value(dialog->sip_dlg_remote_uri_tag,
344 error);
345 if (val == NULL) {
346 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex);
347 return (NULL);
349 ruri = val->sip_value_parse_uri;
351 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex);
352 return ((sip_uri_t)ruri);
356 * Return the dialog remotetarg.
358 const struct sip_uri *
359 sip_get_dialog_remote_target_uri(sip_dialog_t dialog, int *error)
361 _sip_dialog_t *_dialog;
362 const struct sip_uri *rtarg = NULL;
363 const struct sip_value *val;
365 if (error != NULL)
366 *error = 0;
367 if (!sip_manage_dialog || dialog == NULL) {
368 if (error != NULL)
369 *error = EINVAL;
370 return (NULL);
372 _dialog = (_sip_dialog_t *)dialog;
373 (void) pthread_mutex_lock(&_dialog->sip_dlg_mutex);
374 if (dialog->sip_dlg_remote_target != NULL) {
375 val = sip_get_header_value(_dialog->sip_dlg_remote_target,
376 error);
377 if (val == NULL) {
378 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex);
379 return (NULL);
381 rtarg = val->sip_value_parse_uri;
383 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex);
385 return ((sip_uri_t)rtarg);
389 * Return the dialog local contact uri.
391 const struct sip_uri *
392 sip_get_dialog_local_contact_uri(sip_dialog_t dialog, int *error)
394 _sip_dialog_t *_dialog;
395 const struct sip_uri *lcuri = NULL;
396 const struct sip_value *val;
398 if (error != NULL)
399 *error = 0;
400 if (!sip_manage_dialog || dialog == NULL) {
401 if (error != NULL)
402 *error = EINVAL;
403 return (NULL);
405 _dialog = (_sip_dialog_t *)dialog;
406 (void) pthread_mutex_lock(&_dialog->sip_dlg_mutex);
407 if (dialog->sip_dlg_local_contact != NULL) {
408 val = sip_get_header_value(_dialog->sip_dlg_local_contact,
409 error);
410 if (val == NULL) {
411 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex);
412 return (NULL);
414 lcuri = val->sip_value_parse_uri;
416 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex);
418 return ((sip_uri_t)lcuri);
422 * Return the dialog route set
424 const sip_str_t *
425 sip_get_dialog_route_set(sip_dialog_t dialog, int *error)
427 _sip_dialog_t *_dialog;
429 if (error != NULL)
430 *error = 0;
431 if (!sip_manage_dialog || dialog == NULL) {
432 if (error != NULL)
433 *error = EINVAL;
434 return (NULL);
436 _dialog = (_sip_dialog_t *)dialog;
437 if (_dialog->sip_dlg_rset.sip_str_len > 0)
438 return (&_dialog->sip_dlg_rset);
439 return (NULL);
443 * Return the dialog secure
445 boolean_t
446 sip_is_dialog_secure(sip_dialog_t dialog, int *error)
448 _sip_dialog_t *_dialog;
449 boolean_t issecure;
451 if (error != NULL)
452 *error = 0;
453 if (!sip_manage_dialog || dialog == NULL) {
454 if (error != NULL)
455 *error = EINVAL;
456 return (B_FALSE);
458 _dialog = (_sip_dialog_t *)dialog;
459 (void) pthread_mutex_lock(&_dialog->sip_dlg_mutex);
460 issecure = _dialog->sip_dlg_secure;
461 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex);
462 return (issecure);
466 * Return the dialog local cseq
468 uint32_t
469 sip_get_dialog_local_cseq(sip_dialog_t dialog, int *error)
471 _sip_dialog_t *_dialog;
472 uint32_t cseq;
474 if (error != NULL)
475 *error = 0;
476 if (!sip_manage_dialog || dialog == NULL) {
477 if (error != NULL)
478 *error = EINVAL;
479 return (0);
481 _dialog = (_sip_dialog_t *)dialog;
482 (void) pthread_mutex_lock(&_dialog->sip_dlg_mutex);
483 cseq = _dialog->sip_dlg_local_cseq;
484 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex);
485 return (cseq);
489 * Return the dialog remote cseq
491 uint32_t
492 sip_get_dialog_remote_cseq(sip_dialog_t dialog, int *error)
494 _sip_dialog_t *_dialog;
495 uint32_t cseq;
497 if (error != NULL)
498 *error = 0;
499 if (!sip_manage_dialog || dialog == NULL) {
500 if (error != NULL)
501 *error = EINVAL;
502 return (0);
504 _dialog = (_sip_dialog_t *)dialog;
505 (void) pthread_mutex_lock(&_dialog->sip_dlg_mutex);
506 cseq = _dialog->sip_dlg_remote_cseq;
507 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex);
508 return (cseq);
512 * Return the dialog type
515 sip_get_dialog_type(sip_dialog_t dialog, int *error)
517 _sip_dialog_t *_dialog;
518 int type;
520 if (error != NULL)
521 *error = 0;
522 if (!sip_manage_dialog || dialog == NULL) {
523 if (error != NULL)
524 *error = EINVAL;
525 return (-1);
527 _dialog = (_sip_dialog_t *)dialog;
528 (void) pthread_mutex_lock(&_dialog->sip_dlg_mutex);
529 type = _dialog->sip_dlg_type;
530 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex);
531 return (type);
535 * Return the number of messages exchanged within a dialog.
538 sip_get_dialog_msgcnt(sip_dialog_t dialog, int *error)
540 _sip_dialog_t *_dialog;
541 int nmsgs;
543 if (error != NULL)
544 *error = 0;
545 if (!sip_manage_dialog || dialog == NULL) {
546 if (error != NULL)
547 *error = EINVAL;
548 return (-1);
550 _dialog = (_sip_dialog_t *)dialog;
551 (void) pthread_mutex_lock(&_dialog->sip_dlg_mutex);
552 nmsgs = _dialog->sip_dlg_msgcnt;
553 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex);
554 return (nmsgs);
558 * Partial dialog ?
560 boolean_t
561 sip_incomplete_dialog(sip_dialog_t dialog)
563 _sip_dialog_t *_dialog;
564 boolean_t isnew;
566 if (!sip_manage_dialog || dialog == NULL)
567 return (B_FALSE);
568 _dialog = (_sip_dialog_t *)dialog;
569 (void) pthread_mutex_lock(&_dialog->sip_dlg_mutex);
570 isnew = _dialog->sip_dlg_state == SIP_DLG_NEW;
571 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex);
572 return (isnew);
576 * Hold dialog
578 void
579 sip_hold_dialog(sip_dialog_t dialog)
581 _sip_dialog_t *_dialog;
583 if (!sip_manage_dialog || dialog == NULL)
584 return;
585 _dialog = (_sip_dialog_t *)dialog;
586 (void) pthread_mutex_lock(&_dialog->sip_dlg_mutex);
587 SIP_DLG_REFCNT_INCR(_dialog);
588 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex);
592 * Release dialog
594 void
595 sip_release_dialog(sip_dialog_t dialog)
597 _sip_dialog_t *_dialog;
599 if (!sip_manage_dialog || dialog == NULL)
600 return;
601 _dialog = (_sip_dialog_t *)dialog;
602 SIP_DLG_REFCNT_DECR(_dialog);
606 * Delete a dialog
608 void
609 sip_delete_dialog(sip_dialog_t dialog)
611 if (!sip_manage_dialog || dialog == NULL)
612 return;
613 sip_dialog_terminate(dialog, NULL);