140cb5e5dSvi117747 /* 240cb5e5dSvi117747 * CDDL HEADER START 340cb5e5dSvi117747 * 440cb5e5dSvi117747 * The contents of this file are subject to the terms of the 540cb5e5dSvi117747 * Common Development and Distribution License (the "License"). 640cb5e5dSvi117747 * You may not use this file except in compliance with the License. 740cb5e5dSvi117747 * 840cb5e5dSvi117747 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 940cb5e5dSvi117747 * or http://www.opensolaris.org/os/licensing. 1040cb5e5dSvi117747 * See the License for the specific language governing permissions 1140cb5e5dSvi117747 * and limitations under the License. 1240cb5e5dSvi117747 * 1340cb5e5dSvi117747 * When distributing Covered Code, include this CDDL HEADER in each 1440cb5e5dSvi117747 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 1540cb5e5dSvi117747 * If applicable, add the following below this CDDL HEADER, with the 1640cb5e5dSvi117747 * fields enclosed by brackets "[]" replaced with your own identifying 1740cb5e5dSvi117747 * information: Portions Copyright [yyyy] [name of copyright owner] 1840cb5e5dSvi117747 * 1940cb5e5dSvi117747 * CDDL HEADER END 2040cb5e5dSvi117747 */ 2140cb5e5dSvi117747 2240cb5e5dSvi117747 /* 23*943efbc3Sgm209912 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 2440cb5e5dSvi117747 * Use is subject to license terms. 2540cb5e5dSvi117747 */ 2640cb5e5dSvi117747 2740cb5e5dSvi117747 #pragma ident "%Z%%M% %I% %E% SMI" 2840cb5e5dSvi117747 292c2c4183Svi117747 #include <stdlib.h> 302c2c4183Svi117747 #include <assert.h> 312c2c4183Svi117747 #include <errno.h> 322c2c4183Svi117747 #include <pthread.h> 332c2c4183Svi117747 #include <sip.h> 342c2c4183Svi117747 3540cb5e5dSvi117747 #include "sip_msg.h" 3640cb5e5dSvi117747 #include "sip_miscdefs.h" 372c2c4183Svi117747 #include "sip_parse_uri.h" 3840cb5e5dSvi117747 #include "sip_dialog.h" 3940cb5e5dSvi117747 4040cb5e5dSvi117747 /* 4140cb5e5dSvi117747 * Create a request using the state maintained in the dialog. 4240cb5e5dSvi117747 */ 4340cb5e5dSvi117747 sip_msg_t 4440cb5e5dSvi117747 sip_create_dialog_req(sip_method_t method, sip_dialog_t dialog, 4540cb5e5dSvi117747 char *transport, char *sent_by, int sent_by_port, char *via_param, 4640cb5e5dSvi117747 uint32_t maxforward, int cseq) 4740cb5e5dSvi117747 { 4840cb5e5dSvi117747 _sip_dialog_t *_dialog; 4940cb5e5dSvi117747 sip_msg_t sip_msg; 5040cb5e5dSvi117747 char *uri; 5140cb5e5dSvi117747 int oldseq = 0; 5240cb5e5dSvi117747 5340cb5e5dSvi117747 if (!sip_manage_dialog || dialog == NULL || transport == NULL || 5440cb5e5dSvi117747 sent_by == NULL) { 5540cb5e5dSvi117747 return (NULL); 5640cb5e5dSvi117747 } 5740cb5e5dSvi117747 if ((sip_msg = sip_new_msg()) == NULL) 5840cb5e5dSvi117747 return (NULL); 5940cb5e5dSvi117747 _dialog = (_sip_dialog_t *)dialog; 6040cb5e5dSvi117747 (void) pthread_mutex_lock(&_dialog->sip_dlg_mutex); 6140cb5e5dSvi117747 /* 6240cb5e5dSvi117747 * Depending on the route set, if any, the request URI could either 6340cb5e5dSvi117747 * be the contact URI or the 1st URI from the route set. 6440cb5e5dSvi117747 */ 6540cb5e5dSvi117747 uri = (char *)sip_dialog_req_uri(_dialog); 6640cb5e5dSvi117747 if (uri == NULL) 6740cb5e5dSvi117747 goto err_ret; 6840cb5e5dSvi117747 if (sip_add_request_line(sip_msg, method, uri) != 0) { 6940cb5e5dSvi117747 free(uri); 7040cb5e5dSvi117747 goto err_ret; 7140cb5e5dSvi117747 } 7240cb5e5dSvi117747 free(uri); 7340cb5e5dSvi117747 if (sip_copy_header(sip_msg, _dialog->sip_dlg_local_uri_tag, NULL) != 0) 7440cb5e5dSvi117747 goto err_ret; 7540cb5e5dSvi117747 if (sip_copy_header(sip_msg, _dialog->sip_dlg_remote_uri_tag, NULL) != 7640cb5e5dSvi117747 0) { 7740cb5e5dSvi117747 goto err_ret; 7840cb5e5dSvi117747 } 79d8a40387Sgm209912 if (sip_copy_header(sip_msg, _dialog->sip_dlg_local_contact, NULL) != 0) 80d8a40387Sgm209912 goto err_ret; 8140cb5e5dSvi117747 if (sip_add_via(sip_msg, transport, sent_by, sent_by_port, via_param) != 8240cb5e5dSvi117747 0) { 8340cb5e5dSvi117747 goto err_ret; 8440cb5e5dSvi117747 } 8540cb5e5dSvi117747 if (sip_add_maxforward(sip_msg, maxforward) != 0) 8640cb5e5dSvi117747 goto err_ret; 8740cb5e5dSvi117747 if (sip_copy_header(sip_msg, _dialog->sip_dlg_call_id, NULL) != 0) 8840cb5e5dSvi117747 goto err_ret; 8940cb5e5dSvi117747 if (cseq < 0) { 9040cb5e5dSvi117747 if (_dialog->sip_dlg_local_cseq == 0) 9140cb5e5dSvi117747 _dialog->sip_dlg_local_cseq = 1; 9240cb5e5dSvi117747 oldseq = _dialog->sip_dlg_local_cseq; 9340cb5e5dSvi117747 cseq = ++_dialog->sip_dlg_local_cseq; 9440cb5e5dSvi117747 } 9540cb5e5dSvi117747 if (sip_add_cseq(sip_msg, method, cseq) != 0) { 9640cb5e5dSvi117747 _dialog->sip_dlg_local_cseq = oldseq; 9740cb5e5dSvi117747 goto err_ret; 9840cb5e5dSvi117747 } 9940cb5e5dSvi117747 /* 10040cb5e5dSvi117747 * The route set, even if empty, overrides any pre-existing route set. 10140cb5e5dSvi117747 * If the route set is empty, the UAC MUST NOT add a Route header 10240cb5e5dSvi117747 * field to the request. 10340cb5e5dSvi117747 */ 10440cb5e5dSvi117747 (void) sip_delete_header_by_name(sip_msg, SIP_ROUTE); 10540cb5e5dSvi117747 10640cb5e5dSvi117747 if (_dialog->sip_dlg_route_set != NULL) { 10740cb5e5dSvi117747 if (sip_copy_header(sip_msg, _dialog->sip_dlg_route_set, 10840cb5e5dSvi117747 NULL) != 0) { 10940cb5e5dSvi117747 _dialog->sip_dlg_local_cseq = oldseq; 11040cb5e5dSvi117747 goto err_ret; 11140cb5e5dSvi117747 } 11240cb5e5dSvi117747 } 11340cb5e5dSvi117747 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex); 11440cb5e5dSvi117747 return (sip_msg); 11540cb5e5dSvi117747 err_ret: 11640cb5e5dSvi117747 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex); 11740cb5e5dSvi117747 sip_free_msg(sip_msg); 11840cb5e5dSvi117747 return (NULL); 11940cb5e5dSvi117747 } 12040cb5e5dSvi117747 12140cb5e5dSvi117747 /* 122df4705eaSgm209912 * Create a request using the state maintained in the dialog. The request will 123df4705eaSgm209912 * not have Contact header. 124df4705eaSgm209912 */ 125df4705eaSgm209912 sip_msg_t 126df4705eaSgm209912 sip_create_dialog_req_nocontact(sip_method_t method, sip_dialog_t dialog, 127df4705eaSgm209912 char *transport, char *sent_by, int sent_by_port, char *via_param, 128df4705eaSgm209912 uint32_t maxforward, int cseq) 129df4705eaSgm209912 { 130df4705eaSgm209912 sip_msg_t sip_msg; 131df4705eaSgm209912 132df4705eaSgm209912 sip_msg = sip_create_dialog_req(method, dialog, transport, sent_by, 133df4705eaSgm209912 sent_by_port, via_param, maxforward, cseq); 134df4705eaSgm209912 if (sip_msg != NULL) { 135df4705eaSgm209912 if (sip_delete_header_by_name(sip_msg, SIP_CONTACT) != 0) { 136df4705eaSgm209912 sip_free_msg(sip_msg); 137df4705eaSgm209912 return (NULL); 138df4705eaSgm209912 } 139df4705eaSgm209912 } 140df4705eaSgm209912 141df4705eaSgm209912 return (sip_msg); 142df4705eaSgm209912 } 143df4705eaSgm209912 144df4705eaSgm209912 /* 14540cb5e5dSvi117747 * Get the Dialog method 14640cb5e5dSvi117747 */ 14740cb5e5dSvi117747 int 14840cb5e5dSvi117747 sip_get_dialog_method(sip_dialog_t dialog, int *error) 14940cb5e5dSvi117747 { 15040cb5e5dSvi117747 _sip_dialog_t *_dialog; 15140cb5e5dSvi117747 15240cb5e5dSvi117747 if (error != NULL) 15340cb5e5dSvi117747 *error = 0; 15440cb5e5dSvi117747 if (!sip_manage_dialog) { 15540cb5e5dSvi117747 if (error != NULL) 15640cb5e5dSvi117747 *error = EINVAL; 15740cb5e5dSvi117747 return (0); 15840cb5e5dSvi117747 } 15940cb5e5dSvi117747 if (dialog == NULL) { 16040cb5e5dSvi117747 if (error != NULL) 16140cb5e5dSvi117747 *error = EINVAL; 16240cb5e5dSvi117747 return (0); 16340cb5e5dSvi117747 } 16440cb5e5dSvi117747 _dialog = (_sip_dialog_t *)dialog; 16540cb5e5dSvi117747 return (_dialog->sip_dlg_method); 16640cb5e5dSvi117747 } 16740cb5e5dSvi117747 16840cb5e5dSvi117747 /* 16940cb5e5dSvi117747 * Get the Dialog state 17040cb5e5dSvi117747 */ 17140cb5e5dSvi117747 int 17240cb5e5dSvi117747 sip_get_dialog_state(sip_dialog_t dialog, int *error) 17340cb5e5dSvi117747 { 17440cb5e5dSvi117747 _sip_dialog_t *_dialog; 17540cb5e5dSvi117747 17640cb5e5dSvi117747 if (error != NULL) 17740cb5e5dSvi117747 *error = 0; 17840cb5e5dSvi117747 if (!sip_manage_dialog) { 17940cb5e5dSvi117747 if (error != NULL) 18040cb5e5dSvi117747 *error = EINVAL; 18140cb5e5dSvi117747 return (0); 18240cb5e5dSvi117747 } 18340cb5e5dSvi117747 if (dialog == NULL) { 18440cb5e5dSvi117747 if (error != NULL) 18540cb5e5dSvi117747 *error = EINVAL; 18640cb5e5dSvi117747 return (0); 18740cb5e5dSvi117747 } 18840cb5e5dSvi117747 _dialog = (_sip_dialog_t *)dialog; 18940cb5e5dSvi117747 return (_dialog->sip_dlg_state); 19040cb5e5dSvi117747 } 19140cb5e5dSvi117747 19240cb5e5dSvi117747 /* 19340cb5e5dSvi117747 * Return the dialog callid 19440cb5e5dSvi117747 */ 19540cb5e5dSvi117747 const sip_str_t * 19640cb5e5dSvi117747 sip_get_dialog_callid(sip_dialog_t dialog, int *error) 19740cb5e5dSvi117747 { 19840cb5e5dSvi117747 _sip_dialog_t *_dialog; 19940cb5e5dSvi117747 const struct sip_value *val; 20040cb5e5dSvi117747 const sip_str_t *callid = NULL; 20140cb5e5dSvi117747 20240cb5e5dSvi117747 if (error != NULL) 20340cb5e5dSvi117747 *error = 0; 20440cb5e5dSvi117747 if (!sip_manage_dialog || dialog == NULL) { 20540cb5e5dSvi117747 if (error != NULL) 20640cb5e5dSvi117747 *error = EINVAL; 20740cb5e5dSvi117747 return (NULL); 20840cb5e5dSvi117747 } 20940cb5e5dSvi117747 _dialog = (_sip_dialog_t *)dialog; 21040cb5e5dSvi117747 (void) pthread_mutex_lock(&_dialog->sip_dlg_mutex); 21140cb5e5dSvi117747 if (dialog->sip_dlg_call_id != NULL) { 21240cb5e5dSvi117747 val = sip_get_header_value(_dialog->sip_dlg_call_id, error); 21340cb5e5dSvi117747 if (val == NULL) { 21440cb5e5dSvi117747 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex); 21540cb5e5dSvi117747 return (NULL); 21640cb5e5dSvi117747 } 21740cb5e5dSvi117747 callid = &((sip_hdr_value_t *)val)->str_val; 21840cb5e5dSvi117747 } 21940cb5e5dSvi117747 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex); 22040cb5e5dSvi117747 return (callid); 22140cb5e5dSvi117747 } 22240cb5e5dSvi117747 22340cb5e5dSvi117747 /* 22440cb5e5dSvi117747 * Return the dialog localtag. 22540cb5e5dSvi117747 */ 22640cb5e5dSvi117747 const sip_str_t * 22740cb5e5dSvi117747 sip_get_dialog_local_tag(sip_dialog_t dialog, int *error) 22840cb5e5dSvi117747 { 22940cb5e5dSvi117747 _sip_dialog_t *_dialog; 23040cb5e5dSvi117747 const sip_str_t *ltag = NULL; 23140cb5e5dSvi117747 const struct sip_value *val; 23240cb5e5dSvi117747 23340cb5e5dSvi117747 if (error != NULL) 23440cb5e5dSvi117747 *error = 0; 23540cb5e5dSvi117747 if (!sip_manage_dialog || dialog == NULL) { 23640cb5e5dSvi117747 if (error != NULL) 23740cb5e5dSvi117747 *error = EINVAL; 23840cb5e5dSvi117747 return (NULL); 23940cb5e5dSvi117747 } 24040cb5e5dSvi117747 _dialog = (_sip_dialog_t *)dialog; 24140cb5e5dSvi117747 (void) pthread_mutex_lock(&_dialog->sip_dlg_mutex); 24240cb5e5dSvi117747 if (dialog->sip_dlg_local_uri_tag != NULL) { 24340cb5e5dSvi117747 val = sip_get_header_value(_dialog->sip_dlg_local_uri_tag, 24440cb5e5dSvi117747 error); 24540cb5e5dSvi117747 if (val == NULL) { 24640cb5e5dSvi117747 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex); 24740cb5e5dSvi117747 return (NULL); 24840cb5e5dSvi117747 } 24940cb5e5dSvi117747 ltag = sip_get_param_value((sip_header_value_t)val, "tag", 25040cb5e5dSvi117747 error); 25140cb5e5dSvi117747 } 25240cb5e5dSvi117747 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex); 25340cb5e5dSvi117747 return (ltag); 25440cb5e5dSvi117747 } 25540cb5e5dSvi117747 25640cb5e5dSvi117747 /* 25740cb5e5dSvi117747 * Return the dialog remotetag 25840cb5e5dSvi117747 */ 25940cb5e5dSvi117747 const sip_str_t * 26040cb5e5dSvi117747 sip_get_dialog_remote_tag(sip_dialog_t dialog, int *error) 26140cb5e5dSvi117747 { 26240cb5e5dSvi117747 _sip_dialog_t *_dialog; 26340cb5e5dSvi117747 const sip_str_t *ttag = NULL; 26440cb5e5dSvi117747 const struct sip_value *val; 26540cb5e5dSvi117747 26640cb5e5dSvi117747 if (error != NULL) 26740cb5e5dSvi117747 *error = 0; 26840cb5e5dSvi117747 if (!sip_manage_dialog || dialog == NULL) { 26940cb5e5dSvi117747 if (error != NULL) 27040cb5e5dSvi117747 *error = EINVAL; 27140cb5e5dSvi117747 return (NULL); 27240cb5e5dSvi117747 } 27340cb5e5dSvi117747 _dialog = (_sip_dialog_t *)dialog; 27440cb5e5dSvi117747 (void) pthread_mutex_lock(&_dialog->sip_dlg_mutex); 27540cb5e5dSvi117747 if (dialog->sip_dlg_remote_uri_tag != NULL) { 27640cb5e5dSvi117747 val = sip_get_header_value(_dialog->sip_dlg_remote_uri_tag, 27740cb5e5dSvi117747 error); 27840cb5e5dSvi117747 if (val == NULL) { 27940cb5e5dSvi117747 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex); 28040cb5e5dSvi117747 return (NULL); 28140cb5e5dSvi117747 } 28240cb5e5dSvi117747 ttag = sip_get_param_value((sip_header_value_t)val, "tag", 28340cb5e5dSvi117747 error); 28440cb5e5dSvi117747 } 28540cb5e5dSvi117747 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex); 28640cb5e5dSvi117747 28740cb5e5dSvi117747 return (ttag); 28840cb5e5dSvi117747 } 28940cb5e5dSvi117747 29040cb5e5dSvi117747 /* 29140cb5e5dSvi117747 * Return the dialog localuri. 29240cb5e5dSvi117747 */ 29340cb5e5dSvi117747 const struct sip_uri * 29440cb5e5dSvi117747 sip_get_dialog_local_uri(sip_dialog_t dialog, int *error) 29540cb5e5dSvi117747 { 29640cb5e5dSvi117747 _sip_dialog_t *_dialog; 29740cb5e5dSvi117747 const _sip_uri_t *luri = NULL; 29840cb5e5dSvi117747 const struct sip_value *val; 29940cb5e5dSvi117747 30040cb5e5dSvi117747 if (error != NULL) 30140cb5e5dSvi117747 *error = 0; 30240cb5e5dSvi117747 if (!sip_manage_dialog || dialog == NULL) { 30340cb5e5dSvi117747 if (error != NULL) 30440cb5e5dSvi117747 *error = EINVAL; 30540cb5e5dSvi117747 return (NULL); 30640cb5e5dSvi117747 } 30740cb5e5dSvi117747 _dialog = (_sip_dialog_t *)dialog; 30840cb5e5dSvi117747 (void) pthread_mutex_lock(&_dialog->sip_dlg_mutex); 30940cb5e5dSvi117747 if (dialog->sip_dlg_local_uri_tag != NULL) { 31040cb5e5dSvi117747 val = sip_get_header_value(_dialog->sip_dlg_local_uri_tag, 31140cb5e5dSvi117747 error); 31240cb5e5dSvi117747 if (val == NULL) { 31340cb5e5dSvi117747 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex); 31440cb5e5dSvi117747 return (NULL); 31540cb5e5dSvi117747 } 31640cb5e5dSvi117747 luri = val->sip_value_parse_uri; 31740cb5e5dSvi117747 } 31840cb5e5dSvi117747 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex); 31940cb5e5dSvi117747 32040cb5e5dSvi117747 return ((sip_uri_t)luri); 32140cb5e5dSvi117747 } 32240cb5e5dSvi117747 32340cb5e5dSvi117747 /* 32440cb5e5dSvi117747 * Return the dialog remoteuri. 32540cb5e5dSvi117747 */ 32640cb5e5dSvi117747 const struct sip_uri * 32740cb5e5dSvi117747 sip_get_dialog_remote_uri(sip_dialog_t dialog, int *error) 32840cb5e5dSvi117747 { 32940cb5e5dSvi117747 _sip_dialog_t *_dialog; 33040cb5e5dSvi117747 const _sip_uri_t *ruri = NULL; 33140cb5e5dSvi117747 const struct sip_value *val; 33240cb5e5dSvi117747 33340cb5e5dSvi117747 if (error != NULL) 33440cb5e5dSvi117747 *error = 0; 33540cb5e5dSvi117747 if (!sip_manage_dialog || dialog == NULL) { 33640cb5e5dSvi117747 if (error != NULL) 33740cb5e5dSvi117747 *error = EINVAL; 33840cb5e5dSvi117747 return (NULL); 33940cb5e5dSvi117747 } 34040cb5e5dSvi117747 _dialog = (_sip_dialog_t *)dialog; 34140cb5e5dSvi117747 (void) pthread_mutex_lock(&_dialog->sip_dlg_mutex); 34240cb5e5dSvi117747 if (dialog->sip_dlg_remote_uri_tag != NULL) { 34340cb5e5dSvi117747 val = sip_get_header_value(dialog->sip_dlg_remote_uri_tag, 34440cb5e5dSvi117747 error); 34540cb5e5dSvi117747 if (val == NULL) { 34640cb5e5dSvi117747 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex); 34740cb5e5dSvi117747 return (NULL); 34840cb5e5dSvi117747 } 34940cb5e5dSvi117747 ruri = val->sip_value_parse_uri; 35040cb5e5dSvi117747 } 35140cb5e5dSvi117747 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex); 35240cb5e5dSvi117747 return ((sip_uri_t)ruri); 35340cb5e5dSvi117747 } 35440cb5e5dSvi117747 35540cb5e5dSvi117747 /* 35640cb5e5dSvi117747 * Return the dialog remotetarg. 35740cb5e5dSvi117747 */ 35840cb5e5dSvi117747 const struct sip_uri * 35940cb5e5dSvi117747 sip_get_dialog_remote_target_uri(sip_dialog_t dialog, int *error) 36040cb5e5dSvi117747 { 36140cb5e5dSvi117747 _sip_dialog_t *_dialog; 36240cb5e5dSvi117747 const struct sip_uri *rtarg = NULL; 36340cb5e5dSvi117747 const struct sip_value *val; 36440cb5e5dSvi117747 36540cb5e5dSvi117747 if (error != NULL) 36640cb5e5dSvi117747 *error = 0; 36740cb5e5dSvi117747 if (!sip_manage_dialog || dialog == NULL) { 36840cb5e5dSvi117747 if (error != NULL) 36940cb5e5dSvi117747 *error = EINVAL; 37040cb5e5dSvi117747 return (NULL); 37140cb5e5dSvi117747 } 37240cb5e5dSvi117747 _dialog = (_sip_dialog_t *)dialog; 37340cb5e5dSvi117747 (void) pthread_mutex_lock(&_dialog->sip_dlg_mutex); 37440cb5e5dSvi117747 if (dialog->sip_dlg_remote_target != NULL) { 37540cb5e5dSvi117747 val = sip_get_header_value(_dialog->sip_dlg_remote_target, 37640cb5e5dSvi117747 error); 37740cb5e5dSvi117747 if (val == NULL) { 37840cb5e5dSvi117747 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex); 37940cb5e5dSvi117747 return (NULL); 38040cb5e5dSvi117747 } 38140cb5e5dSvi117747 rtarg = val->sip_value_parse_uri; 38240cb5e5dSvi117747 } 38340cb5e5dSvi117747 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex); 38440cb5e5dSvi117747 38540cb5e5dSvi117747 return ((sip_uri_t)rtarg); 38640cb5e5dSvi117747 } 38740cb5e5dSvi117747 38840cb5e5dSvi117747 /* 389df4705eaSgm209912 * Return the dialog local contact uri. 390df4705eaSgm209912 */ 391df4705eaSgm209912 const struct sip_uri * 392df4705eaSgm209912 sip_get_dialog_local_contact_uri(sip_dialog_t dialog, int *error) 393df4705eaSgm209912 { 394df4705eaSgm209912 _sip_dialog_t *_dialog; 395df4705eaSgm209912 const struct sip_uri *lcuri = NULL; 396df4705eaSgm209912 const struct sip_value *val; 397df4705eaSgm209912 398df4705eaSgm209912 if (error != NULL) 399df4705eaSgm209912 *error = 0; 400df4705eaSgm209912 if (!sip_manage_dialog || dialog == NULL) { 401df4705eaSgm209912 if (error != NULL) 402df4705eaSgm209912 *error = EINVAL; 403df4705eaSgm209912 return (NULL); 404df4705eaSgm209912 } 405df4705eaSgm209912 _dialog = (_sip_dialog_t *)dialog; 406df4705eaSgm209912 (void) pthread_mutex_lock(&_dialog->sip_dlg_mutex); 407df4705eaSgm209912 if (dialog->sip_dlg_local_contact != NULL) { 408df4705eaSgm209912 val = sip_get_header_value(_dialog->sip_dlg_local_contact, 409df4705eaSgm209912 error); 410df4705eaSgm209912 if (val == NULL) { 411df4705eaSgm209912 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex); 412df4705eaSgm209912 return (NULL); 413df4705eaSgm209912 } 414df4705eaSgm209912 lcuri = val->sip_value_parse_uri; 415df4705eaSgm209912 } 416df4705eaSgm209912 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex); 417df4705eaSgm209912 418df4705eaSgm209912 return ((sip_uri_t)lcuri); 419df4705eaSgm209912 } 420df4705eaSgm209912 421df4705eaSgm209912 /* 42240cb5e5dSvi117747 * Return the dialog route set 42340cb5e5dSvi117747 */ 42440cb5e5dSvi117747 const sip_str_t * 42540cb5e5dSvi117747 sip_get_dialog_route_set(sip_dialog_t dialog, int *error) 42640cb5e5dSvi117747 { 42740cb5e5dSvi117747 _sip_dialog_t *_dialog; 42840cb5e5dSvi117747 42940cb5e5dSvi117747 if (error != NULL) 43040cb5e5dSvi117747 *error = 0; 43140cb5e5dSvi117747 if (!sip_manage_dialog || dialog == NULL) { 43240cb5e5dSvi117747 if (error != NULL) 43340cb5e5dSvi117747 *error = EINVAL; 43440cb5e5dSvi117747 return (NULL); 43540cb5e5dSvi117747 } 43640cb5e5dSvi117747 _dialog = (_sip_dialog_t *)dialog; 43740cb5e5dSvi117747 if (_dialog->sip_dlg_rset.sip_str_len > 0) 43840cb5e5dSvi117747 return (&_dialog->sip_dlg_rset); 43940cb5e5dSvi117747 return (NULL); 44040cb5e5dSvi117747 } 44140cb5e5dSvi117747 44240cb5e5dSvi117747 /* 44340cb5e5dSvi117747 * Return the dialog secure 44440cb5e5dSvi117747 */ 44540cb5e5dSvi117747 boolean_t 44640cb5e5dSvi117747 sip_is_dialog_secure(sip_dialog_t dialog, int *error) 44740cb5e5dSvi117747 { 44840cb5e5dSvi117747 _sip_dialog_t *_dialog; 44940cb5e5dSvi117747 boolean_t issecure; 45040cb5e5dSvi117747 45140cb5e5dSvi117747 if (error != NULL) 45240cb5e5dSvi117747 *error = 0; 45340cb5e5dSvi117747 if (!sip_manage_dialog || dialog == NULL) { 45440cb5e5dSvi117747 if (error != NULL) 45540cb5e5dSvi117747 *error = EINVAL; 45640cb5e5dSvi117747 return (B_FALSE); 45740cb5e5dSvi117747 } 45840cb5e5dSvi117747 _dialog = (_sip_dialog_t *)dialog; 45940cb5e5dSvi117747 (void) pthread_mutex_lock(&_dialog->sip_dlg_mutex); 46040cb5e5dSvi117747 issecure = _dialog->sip_dlg_secure; 46140cb5e5dSvi117747 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex); 46240cb5e5dSvi117747 return (issecure); 46340cb5e5dSvi117747 } 46440cb5e5dSvi117747 46540cb5e5dSvi117747 /* 46640cb5e5dSvi117747 * Return the dialog local cseq 46740cb5e5dSvi117747 */ 46840cb5e5dSvi117747 uint32_t 46940cb5e5dSvi117747 sip_get_dialog_local_cseq(sip_dialog_t dialog, int *error) 47040cb5e5dSvi117747 { 47140cb5e5dSvi117747 _sip_dialog_t *_dialog; 47240cb5e5dSvi117747 uint32_t cseq; 47340cb5e5dSvi117747 47440cb5e5dSvi117747 if (error != NULL) 47540cb5e5dSvi117747 *error = 0; 47640cb5e5dSvi117747 if (!sip_manage_dialog || dialog == NULL) { 47740cb5e5dSvi117747 if (error != NULL) 47840cb5e5dSvi117747 *error = EINVAL; 47940cb5e5dSvi117747 return (0); 48040cb5e5dSvi117747 } 48140cb5e5dSvi117747 _dialog = (_sip_dialog_t *)dialog; 48240cb5e5dSvi117747 (void) pthread_mutex_lock(&_dialog->sip_dlg_mutex); 48340cb5e5dSvi117747 cseq = _dialog->sip_dlg_local_cseq; 48440cb5e5dSvi117747 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex); 48540cb5e5dSvi117747 return (cseq); 48640cb5e5dSvi117747 } 48740cb5e5dSvi117747 48840cb5e5dSvi117747 /* 48940cb5e5dSvi117747 * Return the dialog remote cseq 49040cb5e5dSvi117747 */ 49140cb5e5dSvi117747 uint32_t 49240cb5e5dSvi117747 sip_get_dialog_remote_cseq(sip_dialog_t dialog, int *error) 49340cb5e5dSvi117747 { 49440cb5e5dSvi117747 _sip_dialog_t *_dialog; 49540cb5e5dSvi117747 uint32_t cseq; 49640cb5e5dSvi117747 49740cb5e5dSvi117747 if (error != NULL) 49840cb5e5dSvi117747 *error = 0; 49940cb5e5dSvi117747 if (!sip_manage_dialog || dialog == NULL) { 50040cb5e5dSvi117747 if (error != NULL) 50140cb5e5dSvi117747 *error = EINVAL; 50240cb5e5dSvi117747 return (0); 50340cb5e5dSvi117747 } 50440cb5e5dSvi117747 _dialog = (_sip_dialog_t *)dialog; 50540cb5e5dSvi117747 (void) pthread_mutex_lock(&_dialog->sip_dlg_mutex); 50640cb5e5dSvi117747 cseq = _dialog->sip_dlg_remote_cseq; 50740cb5e5dSvi117747 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex); 50840cb5e5dSvi117747 return (cseq); 50940cb5e5dSvi117747 } 51040cb5e5dSvi117747 51140cb5e5dSvi117747 /* 51240cb5e5dSvi117747 * Return the dialog type 51340cb5e5dSvi117747 */ 51440cb5e5dSvi117747 int 51540cb5e5dSvi117747 sip_get_dialog_type(sip_dialog_t dialog, int *error) 51640cb5e5dSvi117747 { 51740cb5e5dSvi117747 _sip_dialog_t *_dialog; 51840cb5e5dSvi117747 int type; 51940cb5e5dSvi117747 52040cb5e5dSvi117747 if (error != NULL) 52140cb5e5dSvi117747 *error = 0; 52240cb5e5dSvi117747 if (!sip_manage_dialog || dialog == NULL) { 52340cb5e5dSvi117747 if (error != NULL) 52440cb5e5dSvi117747 *error = EINVAL; 52540cb5e5dSvi117747 return (-1); 52640cb5e5dSvi117747 } 52740cb5e5dSvi117747 _dialog = (_sip_dialog_t *)dialog; 52840cb5e5dSvi117747 (void) pthread_mutex_lock(&_dialog->sip_dlg_mutex); 52940cb5e5dSvi117747 type = _dialog->sip_dlg_type; 53040cb5e5dSvi117747 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex); 53140cb5e5dSvi117747 return (type); 53240cb5e5dSvi117747 } 53340cb5e5dSvi117747 534*943efbc3Sgm209912 /* 535*943efbc3Sgm209912 * Return the number of messages exchanged within a dialog. 536*943efbc3Sgm209912 */ 537*943efbc3Sgm209912 int 538*943efbc3Sgm209912 sip_get_dialog_msgcnt(sip_dialog_t dialog, int *error) 539*943efbc3Sgm209912 { 540*943efbc3Sgm209912 _sip_dialog_t *_dialog; 541*943efbc3Sgm209912 int nmsgs; 542*943efbc3Sgm209912 543*943efbc3Sgm209912 if (error != NULL) 544*943efbc3Sgm209912 *error = 0; 545*943efbc3Sgm209912 if (!sip_manage_dialog || dialog == NULL) { 546*943efbc3Sgm209912 if (error != NULL) 547*943efbc3Sgm209912 *error = EINVAL; 548*943efbc3Sgm209912 return (-1); 549*943efbc3Sgm209912 } 550*943efbc3Sgm209912 _dialog = (_sip_dialog_t *)dialog; 551*943efbc3Sgm209912 (void) pthread_mutex_lock(&_dialog->sip_dlg_mutex); 552*943efbc3Sgm209912 nmsgs = _dialog->sip_dlg_msgcnt; 553*943efbc3Sgm209912 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex); 554*943efbc3Sgm209912 return (nmsgs); 555*943efbc3Sgm209912 } 55640cb5e5dSvi117747 55740cb5e5dSvi117747 /* 55840cb5e5dSvi117747 * Partial dialog ? 55940cb5e5dSvi117747 */ 56040cb5e5dSvi117747 boolean_t 56140cb5e5dSvi117747 sip_incomplete_dialog(sip_dialog_t dialog) 56240cb5e5dSvi117747 { 56340cb5e5dSvi117747 _sip_dialog_t *_dialog; 56440cb5e5dSvi117747 boolean_t isnew; 56540cb5e5dSvi117747 56640cb5e5dSvi117747 if (!sip_manage_dialog || dialog == NULL) 56740cb5e5dSvi117747 return (B_FALSE); 56840cb5e5dSvi117747 _dialog = (_sip_dialog_t *)dialog; 56940cb5e5dSvi117747 (void) pthread_mutex_lock(&_dialog->sip_dlg_mutex); 57040cb5e5dSvi117747 isnew = _dialog->sip_dlg_state == SIP_DLG_NEW; 57140cb5e5dSvi117747 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex); 57240cb5e5dSvi117747 return (isnew); 57340cb5e5dSvi117747 } 57440cb5e5dSvi117747 57540cb5e5dSvi117747 /* 57640cb5e5dSvi117747 * Hold dialog 57740cb5e5dSvi117747 */ 57840cb5e5dSvi117747 void 57940cb5e5dSvi117747 sip_hold_dialog(sip_dialog_t dialog) 58040cb5e5dSvi117747 { 58140cb5e5dSvi117747 _sip_dialog_t *_dialog; 58240cb5e5dSvi117747 58340cb5e5dSvi117747 if (!sip_manage_dialog || dialog == NULL) 58440cb5e5dSvi117747 return; 58540cb5e5dSvi117747 _dialog = (_sip_dialog_t *)dialog; 58640cb5e5dSvi117747 (void) pthread_mutex_lock(&_dialog->sip_dlg_mutex); 58740cb5e5dSvi117747 SIP_DLG_REFCNT_INCR(_dialog); 58840cb5e5dSvi117747 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex); 58940cb5e5dSvi117747 } 59040cb5e5dSvi117747 59140cb5e5dSvi117747 /* 59240cb5e5dSvi117747 * Release dialog 59340cb5e5dSvi117747 */ 59440cb5e5dSvi117747 void 59540cb5e5dSvi117747 sip_release_dialog(sip_dialog_t dialog) 59640cb5e5dSvi117747 { 59740cb5e5dSvi117747 _sip_dialog_t *_dialog; 59840cb5e5dSvi117747 59940cb5e5dSvi117747 if (!sip_manage_dialog || dialog == NULL) 60040cb5e5dSvi117747 return; 60140cb5e5dSvi117747 _dialog = (_sip_dialog_t *)dialog; 60240cb5e5dSvi117747 SIP_DLG_REFCNT_DECR(_dialog); 60340cb5e5dSvi117747 } 60440cb5e5dSvi117747 60540cb5e5dSvi117747 /* 60640cb5e5dSvi117747 * Delete a dialog 60740cb5e5dSvi117747 */ 60840cb5e5dSvi117747 void 60940cb5e5dSvi117747 sip_delete_dialog(sip_dialog_t dialog) 61040cb5e5dSvi117747 { 61140cb5e5dSvi117747 if (!sip_manage_dialog || dialog == NULL) 61240cb5e5dSvi117747 return; 61340cb5e5dSvi117747 sip_dialog_terminate(dialog, NULL); 61440cb5e5dSvi117747 } 615