1*2882Svi117747 /*
2*2882Svi117747  * CDDL HEADER START
3*2882Svi117747  *
4*2882Svi117747  * The contents of this file are subject to the terms of the
5*2882Svi117747  * Common Development and Distribution License (the "License").
6*2882Svi117747  * You may not use this file except in compliance with the License.
7*2882Svi117747  *
8*2882Svi117747  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*2882Svi117747  * or http://www.opensolaris.org/os/licensing.
10*2882Svi117747  * See the License for the specific language governing permissions
11*2882Svi117747  * and limitations under the License.
12*2882Svi117747  *
13*2882Svi117747  * When distributing Covered Code, include this CDDL HEADER in each
14*2882Svi117747  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*2882Svi117747  * If applicable, add the following below this CDDL HEADER, with the
16*2882Svi117747  * fields enclosed by brackets "[]" replaced with your own identifying
17*2882Svi117747  * information: Portions Copyright [yyyy] [name of copyright owner]
18*2882Svi117747  *
19*2882Svi117747  * CDDL HEADER END
20*2882Svi117747  */
21*2882Svi117747 
22*2882Svi117747 /*
23*2882Svi117747  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
24*2882Svi117747  * Use is subject to license terms.
25*2882Svi117747  */
26*2882Svi117747 
27*2882Svi117747 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*2882Svi117747 
29*2882Svi117747 #include "sip_parse_uri.h"
30*2882Svi117747 #include "sip_msg.h"
31*2882Svi117747 #include "sip_miscdefs.h"
32*2882Svi117747 #include "sip_dialog.h"
33*2882Svi117747 #include "sip_xaction.h"
34*2882Svi117747 
35*2882Svi117747 /*
36*2882Svi117747  * Create a request using the state maintained in the dialog.
37*2882Svi117747  */
38*2882Svi117747 sip_msg_t
39*2882Svi117747 sip_create_dialog_req(sip_method_t method, sip_dialog_t dialog,
40*2882Svi117747     char *transport, char *sent_by, int sent_by_port, char *via_param,
41*2882Svi117747     uint32_t maxforward, int cseq)
42*2882Svi117747 {
43*2882Svi117747 	_sip_dialog_t	*_dialog;
44*2882Svi117747 	sip_msg_t	sip_msg;
45*2882Svi117747 	char		*uri;
46*2882Svi117747 	int		oldseq = 0;
47*2882Svi117747 
48*2882Svi117747 	if (!sip_manage_dialog || dialog == NULL || transport == NULL ||
49*2882Svi117747 	    sent_by == NULL) {
50*2882Svi117747 		return (NULL);
51*2882Svi117747 	}
52*2882Svi117747 	if ((sip_msg = sip_new_msg()) == NULL)
53*2882Svi117747 		return (NULL);
54*2882Svi117747 	_dialog = (_sip_dialog_t *)dialog;
55*2882Svi117747 	(void) pthread_mutex_lock(&_dialog->sip_dlg_mutex);
56*2882Svi117747 	/*
57*2882Svi117747 	 * Depending on the route set, if any, the request URI could either
58*2882Svi117747 	 * be the contact URI or the 1st URI from the route set.
59*2882Svi117747 	 */
60*2882Svi117747 	uri = (char *)sip_dialog_req_uri(_dialog);
61*2882Svi117747 	if (uri == NULL)
62*2882Svi117747 		goto err_ret;
63*2882Svi117747 	if (sip_add_request_line(sip_msg, method, uri) != 0) {
64*2882Svi117747 		free(uri);
65*2882Svi117747 		goto err_ret;
66*2882Svi117747 	}
67*2882Svi117747 	free(uri);
68*2882Svi117747 	if (sip_copy_header(sip_msg, _dialog->sip_dlg_local_uri_tag, NULL) != 0)
69*2882Svi117747 		goto err_ret;
70*2882Svi117747 	if (sip_copy_header(sip_msg, _dialog->sip_dlg_remote_uri_tag, NULL) !=
71*2882Svi117747 	    0) {
72*2882Svi117747 		goto err_ret;
73*2882Svi117747 	}
74*2882Svi117747 	if (sip_copy_header(sip_msg, _dialog->sip_dlg_remote_target, NULL) != 0)
75*2882Svi117747 		goto err_ret;
76*2882Svi117747 	if (sip_add_via(sip_msg, transport, sent_by, sent_by_port, via_param) !=
77*2882Svi117747 	    0) {
78*2882Svi117747 		goto err_ret;
79*2882Svi117747 	}
80*2882Svi117747 	if (sip_add_maxforward(sip_msg, maxforward) != 0)
81*2882Svi117747 		goto err_ret;
82*2882Svi117747 	if (sip_copy_header(sip_msg, _dialog->sip_dlg_call_id, NULL) != 0)
83*2882Svi117747 		goto err_ret;
84*2882Svi117747 	if (cseq < 0) {
85*2882Svi117747 		if (_dialog->sip_dlg_local_cseq == 0)
86*2882Svi117747 			_dialog->sip_dlg_local_cseq = 1;
87*2882Svi117747 		oldseq = _dialog->sip_dlg_local_cseq;
88*2882Svi117747 		cseq = ++_dialog->sip_dlg_local_cseq;
89*2882Svi117747 	}
90*2882Svi117747 	if (sip_add_cseq(sip_msg, method, cseq) != 0) {
91*2882Svi117747 		_dialog->sip_dlg_local_cseq = oldseq;
92*2882Svi117747 		goto err_ret;
93*2882Svi117747 	}
94*2882Svi117747 	/*
95*2882Svi117747 	 * The route set, even if empty, overrides any pre-existing route set.
96*2882Svi117747 	 * If the route set is empty, the UAC MUST NOT add a Route header
97*2882Svi117747 	 * field to the request.
98*2882Svi117747 	 */
99*2882Svi117747 	(void) sip_delete_header_by_name(sip_msg, SIP_ROUTE);
100*2882Svi117747 
101*2882Svi117747 	if (_dialog->sip_dlg_route_set != NULL) {
102*2882Svi117747 		if (sip_copy_header(sip_msg, _dialog->sip_dlg_route_set,
103*2882Svi117747 		    NULL) != 0) {
104*2882Svi117747 			_dialog->sip_dlg_local_cseq = oldseq;
105*2882Svi117747 			goto err_ret;
106*2882Svi117747 		}
107*2882Svi117747 	}
108*2882Svi117747 	(void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex);
109*2882Svi117747 	return (sip_msg);
110*2882Svi117747 err_ret:
111*2882Svi117747 	(void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex);
112*2882Svi117747 	sip_free_msg(sip_msg);
113*2882Svi117747 	return (NULL);
114*2882Svi117747 }
115*2882Svi117747 
116*2882Svi117747 /*
117*2882Svi117747  * Get the Dialog method
118*2882Svi117747  */
119*2882Svi117747 int
120*2882Svi117747 sip_get_dialog_method(sip_dialog_t dialog, int *error)
121*2882Svi117747 {
122*2882Svi117747 	_sip_dialog_t	*_dialog;
123*2882Svi117747 
124*2882Svi117747 	if (error != NULL)
125*2882Svi117747 		*error = 0;
126*2882Svi117747 	if (!sip_manage_dialog) {
127*2882Svi117747 		if (error != NULL)
128*2882Svi117747 			*error = EINVAL;
129*2882Svi117747 		return (0);
130*2882Svi117747 	}
131*2882Svi117747 	if (dialog == NULL) {
132*2882Svi117747 		if (error != NULL)
133*2882Svi117747 			*error = EINVAL;
134*2882Svi117747 		return (0);
135*2882Svi117747 	}
136*2882Svi117747 	_dialog = (_sip_dialog_t *)dialog;
137*2882Svi117747 	return (_dialog->sip_dlg_method);
138*2882Svi117747 }
139*2882Svi117747 
140*2882Svi117747 /*
141*2882Svi117747  * Get the Dialog state
142*2882Svi117747  */
143*2882Svi117747 int
144*2882Svi117747 sip_get_dialog_state(sip_dialog_t dialog, int *error)
145*2882Svi117747 {
146*2882Svi117747 	_sip_dialog_t	*_dialog;
147*2882Svi117747 
148*2882Svi117747 	if (error != NULL)
149*2882Svi117747 		*error = 0;
150*2882Svi117747 	if (!sip_manage_dialog) {
151*2882Svi117747 		if (error != NULL)
152*2882Svi117747 			*error = EINVAL;
153*2882Svi117747 		return (0);
154*2882Svi117747 	}
155*2882Svi117747 	if (dialog == NULL) {
156*2882Svi117747 		if (error != NULL)
157*2882Svi117747 			*error = EINVAL;
158*2882Svi117747 		return (0);
159*2882Svi117747 	}
160*2882Svi117747 	_dialog = (_sip_dialog_t *)dialog;
161*2882Svi117747 	return (_dialog->sip_dlg_state);
162*2882Svi117747 }
163*2882Svi117747 
164*2882Svi117747 /*
165*2882Svi117747  * Return the dialog callid
166*2882Svi117747  */
167*2882Svi117747 const sip_str_t *
168*2882Svi117747 sip_get_dialog_callid(sip_dialog_t dialog, int *error)
169*2882Svi117747 {
170*2882Svi117747 	_sip_dialog_t		*_dialog;
171*2882Svi117747 	const struct sip_value	*val;
172*2882Svi117747 	const sip_str_t		*callid = NULL;
173*2882Svi117747 
174*2882Svi117747 	if (error != NULL)
175*2882Svi117747 		*error = 0;
176*2882Svi117747 	if (!sip_manage_dialog || dialog == NULL) {
177*2882Svi117747 		if (error != NULL)
178*2882Svi117747 			*error = EINVAL;
179*2882Svi117747 		return (NULL);
180*2882Svi117747 	}
181*2882Svi117747 	_dialog = (_sip_dialog_t *)dialog;
182*2882Svi117747 	(void) pthread_mutex_lock(&_dialog->sip_dlg_mutex);
183*2882Svi117747 	if (dialog->sip_dlg_call_id != NULL) {
184*2882Svi117747 		val = sip_get_header_value(_dialog->sip_dlg_call_id, error);
185*2882Svi117747 		if (val == NULL) {
186*2882Svi117747 			(void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex);
187*2882Svi117747 			return (NULL);
188*2882Svi117747 		}
189*2882Svi117747 		callid = &((sip_hdr_value_t *)val)->str_val;
190*2882Svi117747 	}
191*2882Svi117747 	(void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex);
192*2882Svi117747 	return (callid);
193*2882Svi117747 }
194*2882Svi117747 
195*2882Svi117747 /*
196*2882Svi117747  * Return the dialog localtag.
197*2882Svi117747  */
198*2882Svi117747 const sip_str_t *
199*2882Svi117747 sip_get_dialog_local_tag(sip_dialog_t dialog, int *error)
200*2882Svi117747 {
201*2882Svi117747 	_sip_dialog_t		*_dialog;
202*2882Svi117747 	const sip_str_t		*ltag = NULL;
203*2882Svi117747 	const struct sip_value	*val;
204*2882Svi117747 
205*2882Svi117747 	if (error != NULL)
206*2882Svi117747 		*error = 0;
207*2882Svi117747 	if (!sip_manage_dialog || dialog == NULL) {
208*2882Svi117747 		if (error != NULL)
209*2882Svi117747 			*error = EINVAL;
210*2882Svi117747 		return (NULL);
211*2882Svi117747 	}
212*2882Svi117747 	_dialog = (_sip_dialog_t *)dialog;
213*2882Svi117747 	(void) pthread_mutex_lock(&_dialog->sip_dlg_mutex);
214*2882Svi117747 	if (dialog->sip_dlg_local_uri_tag != NULL) {
215*2882Svi117747 		val = sip_get_header_value(_dialog->sip_dlg_local_uri_tag,
216*2882Svi117747 		    error);
217*2882Svi117747 		if (val == NULL) {
218*2882Svi117747 			(void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex);
219*2882Svi117747 			return (NULL);
220*2882Svi117747 		}
221*2882Svi117747 		ltag = sip_get_param_value((sip_header_value_t)val, "tag",
222*2882Svi117747 		    error);
223*2882Svi117747 	}
224*2882Svi117747 	(void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex);
225*2882Svi117747 	return (ltag);
226*2882Svi117747 }
227*2882Svi117747 
228*2882Svi117747 /*
229*2882Svi117747  * Return the dialog remotetag
230*2882Svi117747  */
231*2882Svi117747 const sip_str_t *
232*2882Svi117747 sip_get_dialog_remote_tag(sip_dialog_t dialog, int *error)
233*2882Svi117747 {
234*2882Svi117747 	_sip_dialog_t		*_dialog;
235*2882Svi117747 	const sip_str_t		*ttag = NULL;
236*2882Svi117747 	const struct sip_value	*val;
237*2882Svi117747 
238*2882Svi117747 	if (error != NULL)
239*2882Svi117747 		*error = 0;
240*2882Svi117747 	if (!sip_manage_dialog || dialog == NULL) {
241*2882Svi117747 		if (error != NULL)
242*2882Svi117747 			*error = EINVAL;
243*2882Svi117747 		return (NULL);
244*2882Svi117747 	}
245*2882Svi117747 	_dialog = (_sip_dialog_t *)dialog;
246*2882Svi117747 	(void) pthread_mutex_lock(&_dialog->sip_dlg_mutex);
247*2882Svi117747 	if (dialog->sip_dlg_remote_uri_tag != NULL) {
248*2882Svi117747 		val = sip_get_header_value(_dialog->sip_dlg_remote_uri_tag,
249*2882Svi117747 		    error);
250*2882Svi117747 		if (val == NULL) {
251*2882Svi117747 			(void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex);
252*2882Svi117747 			return (NULL);
253*2882Svi117747 		}
254*2882Svi117747 		ttag = sip_get_param_value((sip_header_value_t)val, "tag",
255*2882Svi117747 		    error);
256*2882Svi117747 	}
257*2882Svi117747 	(void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex);
258*2882Svi117747 
259*2882Svi117747 	return (ttag);
260*2882Svi117747 }
261*2882Svi117747 
262*2882Svi117747 /*
263*2882Svi117747  * Return the dialog localuri.
264*2882Svi117747  */
265*2882Svi117747 const struct sip_uri *
266*2882Svi117747 sip_get_dialog_local_uri(sip_dialog_t dialog, int *error)
267*2882Svi117747 {
268*2882Svi117747 	_sip_dialog_t		*_dialog;
269*2882Svi117747 	const _sip_uri_t	*luri = NULL;
270*2882Svi117747 	const struct sip_value	*val;
271*2882Svi117747 
272*2882Svi117747 	if (error != NULL)
273*2882Svi117747 		*error = 0;
274*2882Svi117747 	if (!sip_manage_dialog || dialog == NULL) {
275*2882Svi117747 		if (error != NULL)
276*2882Svi117747 			*error = EINVAL;
277*2882Svi117747 		return (NULL);
278*2882Svi117747 	}
279*2882Svi117747 	_dialog = (_sip_dialog_t *)dialog;
280*2882Svi117747 	(void) pthread_mutex_lock(&_dialog->sip_dlg_mutex);
281*2882Svi117747 	if (dialog->sip_dlg_local_uri_tag != NULL) {
282*2882Svi117747 		val = sip_get_header_value(_dialog->sip_dlg_local_uri_tag,
283*2882Svi117747 		    error);
284*2882Svi117747 		if (val == NULL) {
285*2882Svi117747 			(void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex);
286*2882Svi117747 			return (NULL);
287*2882Svi117747 		}
288*2882Svi117747 		luri = val->sip_value_parse_uri;
289*2882Svi117747 	}
290*2882Svi117747 	(void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex);
291*2882Svi117747 
292*2882Svi117747 	return ((sip_uri_t)luri);
293*2882Svi117747 }
294*2882Svi117747 
295*2882Svi117747 /*
296*2882Svi117747  * Return the dialog remoteuri.
297*2882Svi117747  */
298*2882Svi117747 const struct sip_uri *
299*2882Svi117747 sip_get_dialog_remote_uri(sip_dialog_t dialog, int *error)
300*2882Svi117747 {
301*2882Svi117747 	_sip_dialog_t		*_dialog;
302*2882Svi117747 	const _sip_uri_t	*ruri = NULL;
303*2882Svi117747 	const struct sip_value	*val;
304*2882Svi117747 
305*2882Svi117747 	if (error != NULL)
306*2882Svi117747 		*error = 0;
307*2882Svi117747 	if (!sip_manage_dialog || dialog == NULL) {
308*2882Svi117747 		if (error != NULL)
309*2882Svi117747 			*error = EINVAL;
310*2882Svi117747 		return (NULL);
311*2882Svi117747 	}
312*2882Svi117747 	_dialog = (_sip_dialog_t *)dialog;
313*2882Svi117747 	(void) pthread_mutex_lock(&_dialog->sip_dlg_mutex);
314*2882Svi117747 	if (dialog->sip_dlg_remote_uri_tag != NULL) {
315*2882Svi117747 		val = sip_get_header_value(dialog->sip_dlg_remote_uri_tag,
316*2882Svi117747 		    error);
317*2882Svi117747 		if (val == NULL) {
318*2882Svi117747 			(void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex);
319*2882Svi117747 			return (NULL);
320*2882Svi117747 		}
321*2882Svi117747 		ruri = val->sip_value_parse_uri;
322*2882Svi117747 	}
323*2882Svi117747 	(void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex);
324*2882Svi117747 	return ((sip_uri_t)ruri);
325*2882Svi117747 }
326*2882Svi117747 
327*2882Svi117747 /*
328*2882Svi117747  * Return the dialog remotetarg.
329*2882Svi117747  */
330*2882Svi117747 const struct sip_uri *
331*2882Svi117747 sip_get_dialog_remote_target_uri(sip_dialog_t dialog, int *error)
332*2882Svi117747 {
333*2882Svi117747 	_sip_dialog_t		*_dialog;
334*2882Svi117747 	const struct sip_uri	*rtarg = NULL;
335*2882Svi117747 	const struct sip_value	*val;
336*2882Svi117747 
337*2882Svi117747 	if (error != NULL)
338*2882Svi117747 		*error = 0;
339*2882Svi117747 	if (!sip_manage_dialog || dialog == NULL) {
340*2882Svi117747 		if (error != NULL)
341*2882Svi117747 			*error = EINVAL;
342*2882Svi117747 		return (NULL);
343*2882Svi117747 	}
344*2882Svi117747 	_dialog = (_sip_dialog_t *)dialog;
345*2882Svi117747 	(void) pthread_mutex_lock(&_dialog->sip_dlg_mutex);
346*2882Svi117747 	if (dialog->sip_dlg_remote_target != NULL) {
347*2882Svi117747 		val = sip_get_header_value(_dialog->sip_dlg_remote_target,
348*2882Svi117747 		    error);
349*2882Svi117747 		if (val == NULL) {
350*2882Svi117747 			(void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex);
351*2882Svi117747 			return (NULL);
352*2882Svi117747 		}
353*2882Svi117747 		rtarg = val->sip_value_parse_uri;
354*2882Svi117747 	}
355*2882Svi117747 	(void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex);
356*2882Svi117747 
357*2882Svi117747 	return ((sip_uri_t)rtarg);
358*2882Svi117747 }
359*2882Svi117747 
360*2882Svi117747 /*
361*2882Svi117747  * Return the dialog route set
362*2882Svi117747  */
363*2882Svi117747 const sip_str_t *
364*2882Svi117747 sip_get_dialog_route_set(sip_dialog_t dialog, int *error)
365*2882Svi117747 {
366*2882Svi117747 	_sip_dialog_t		*_dialog;
367*2882Svi117747 
368*2882Svi117747 	if (error != NULL)
369*2882Svi117747 		*error = 0;
370*2882Svi117747 	if (!sip_manage_dialog || dialog == NULL) {
371*2882Svi117747 		if (error != NULL)
372*2882Svi117747 			*error = EINVAL;
373*2882Svi117747 		return (NULL);
374*2882Svi117747 	}
375*2882Svi117747 	_dialog = (_sip_dialog_t *)dialog;
376*2882Svi117747 	if (_dialog->sip_dlg_rset.sip_str_len > 0)
377*2882Svi117747 		return (&_dialog->sip_dlg_rset);
378*2882Svi117747 	return (NULL);
379*2882Svi117747 }
380*2882Svi117747 
381*2882Svi117747 /*
382*2882Svi117747  * Return the dialog secure
383*2882Svi117747  */
384*2882Svi117747 boolean_t
385*2882Svi117747 sip_is_dialog_secure(sip_dialog_t dialog, int *error)
386*2882Svi117747 {
387*2882Svi117747 	_sip_dialog_t	*_dialog;
388*2882Svi117747 	boolean_t	issecure;
389*2882Svi117747 
390*2882Svi117747 	if (error != NULL)
391*2882Svi117747 		*error = 0;
392*2882Svi117747 	if (!sip_manage_dialog || dialog == NULL) {
393*2882Svi117747 		if (error != NULL)
394*2882Svi117747 			*error = EINVAL;
395*2882Svi117747 		return (B_FALSE);
396*2882Svi117747 	}
397*2882Svi117747 	_dialog = (_sip_dialog_t *)dialog;
398*2882Svi117747 	(void) pthread_mutex_lock(&_dialog->sip_dlg_mutex);
399*2882Svi117747 	issecure = _dialog->sip_dlg_secure;
400*2882Svi117747 	(void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex);
401*2882Svi117747 	return (issecure);
402*2882Svi117747 }
403*2882Svi117747 
404*2882Svi117747 /*
405*2882Svi117747  * Return the dialog local cseq
406*2882Svi117747  */
407*2882Svi117747 uint32_t
408*2882Svi117747 sip_get_dialog_local_cseq(sip_dialog_t dialog, int *error)
409*2882Svi117747 {
410*2882Svi117747 	_sip_dialog_t	*_dialog;
411*2882Svi117747 	uint32_t	cseq;
412*2882Svi117747 
413*2882Svi117747 	if (error != NULL)
414*2882Svi117747 		*error = 0;
415*2882Svi117747 	if (!sip_manage_dialog || dialog == NULL) {
416*2882Svi117747 		if (error != NULL)
417*2882Svi117747 			*error = EINVAL;
418*2882Svi117747 		return (0);
419*2882Svi117747 	}
420*2882Svi117747 	_dialog = (_sip_dialog_t *)dialog;
421*2882Svi117747 	(void) pthread_mutex_lock(&_dialog->sip_dlg_mutex);
422*2882Svi117747 	cseq = _dialog->sip_dlg_local_cseq;
423*2882Svi117747 	(void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex);
424*2882Svi117747 	return (cseq);
425*2882Svi117747 }
426*2882Svi117747 
427*2882Svi117747 /*
428*2882Svi117747  * Return the dialog remote cseq
429*2882Svi117747  */
430*2882Svi117747 uint32_t
431*2882Svi117747 sip_get_dialog_remote_cseq(sip_dialog_t dialog, int *error)
432*2882Svi117747 {
433*2882Svi117747 	_sip_dialog_t	*_dialog;
434*2882Svi117747 	uint32_t	cseq;
435*2882Svi117747 
436*2882Svi117747 	if (error != NULL)
437*2882Svi117747 		*error = 0;
438*2882Svi117747 	if (!sip_manage_dialog || dialog == NULL) {
439*2882Svi117747 		if (error != NULL)
440*2882Svi117747 			*error = EINVAL;
441*2882Svi117747 		return (0);
442*2882Svi117747 	}
443*2882Svi117747 	_dialog = (_sip_dialog_t *)dialog;
444*2882Svi117747 	(void) pthread_mutex_lock(&_dialog->sip_dlg_mutex);
445*2882Svi117747 	cseq = _dialog->sip_dlg_remote_cseq;
446*2882Svi117747 	(void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex);
447*2882Svi117747 	return (cseq);
448*2882Svi117747 }
449*2882Svi117747 
450*2882Svi117747 /*
451*2882Svi117747  * Return the dialog type
452*2882Svi117747  */
453*2882Svi117747 int
454*2882Svi117747 sip_get_dialog_type(sip_dialog_t dialog, int *error)
455*2882Svi117747 {
456*2882Svi117747 	_sip_dialog_t	*_dialog;
457*2882Svi117747 	int		type;
458*2882Svi117747 
459*2882Svi117747 	if (error != NULL)
460*2882Svi117747 		*error = 0;
461*2882Svi117747 	if (!sip_manage_dialog || dialog == NULL) {
462*2882Svi117747 		if (error != NULL)
463*2882Svi117747 			*error = EINVAL;
464*2882Svi117747 		return (-1);
465*2882Svi117747 	}
466*2882Svi117747 	_dialog = (_sip_dialog_t *)dialog;
467*2882Svi117747 	(void) pthread_mutex_lock(&_dialog->sip_dlg_mutex);
468*2882Svi117747 	type = _dialog->sip_dlg_type;
469*2882Svi117747 	(void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex);
470*2882Svi117747 	return (type);
471*2882Svi117747 }
472*2882Svi117747 
473*2882Svi117747 
474*2882Svi117747 /*
475*2882Svi117747  * Partial dialog ?
476*2882Svi117747  */
477*2882Svi117747 boolean_t
478*2882Svi117747 sip_incomplete_dialog(sip_dialog_t dialog)
479*2882Svi117747 {
480*2882Svi117747 	_sip_dialog_t	*_dialog;
481*2882Svi117747 	boolean_t	isnew;
482*2882Svi117747 
483*2882Svi117747 	if (!sip_manage_dialog || dialog == NULL)
484*2882Svi117747 		return (B_FALSE);
485*2882Svi117747 	_dialog = (_sip_dialog_t *)dialog;
486*2882Svi117747 	(void) pthread_mutex_lock(&_dialog->sip_dlg_mutex);
487*2882Svi117747 	isnew = _dialog->sip_dlg_state == SIP_DLG_NEW;
488*2882Svi117747 	(void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex);
489*2882Svi117747 	return (isnew);
490*2882Svi117747 }
491*2882Svi117747 
492*2882Svi117747 /*
493*2882Svi117747  * Hold dialog
494*2882Svi117747  */
495*2882Svi117747 void
496*2882Svi117747 sip_hold_dialog(sip_dialog_t dialog)
497*2882Svi117747 {
498*2882Svi117747 	_sip_dialog_t	*_dialog;
499*2882Svi117747 
500*2882Svi117747 	if (!sip_manage_dialog || dialog == NULL)
501*2882Svi117747 		return;
502*2882Svi117747 	_dialog = (_sip_dialog_t *)dialog;
503*2882Svi117747 	(void) pthread_mutex_lock(&_dialog->sip_dlg_mutex);
504*2882Svi117747 	SIP_DLG_REFCNT_INCR(_dialog);
505*2882Svi117747 	(void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex);
506*2882Svi117747 }
507*2882Svi117747 
508*2882Svi117747 /*
509*2882Svi117747  * Release dialog
510*2882Svi117747  */
511*2882Svi117747 void
512*2882Svi117747 sip_release_dialog(sip_dialog_t dialog)
513*2882Svi117747 {
514*2882Svi117747 	_sip_dialog_t	*_dialog;
515*2882Svi117747 
516*2882Svi117747 	if (!sip_manage_dialog || dialog == NULL)
517*2882Svi117747 		return;
518*2882Svi117747 	_dialog = (_sip_dialog_t *)dialog;
519*2882Svi117747 	SIP_DLG_REFCNT_DECR(_dialog);
520*2882Svi117747 }
521*2882Svi117747 
522*2882Svi117747 /*
523*2882Svi117747  * Delete a dialog
524*2882Svi117747  */
525*2882Svi117747 void
526*2882Svi117747 sip_delete_dialog(sip_dialog_t dialog)
527*2882Svi117747 {
528*2882Svi117747 	if (!sip_manage_dialog || dialog == NULL)
529*2882Svi117747 		return;
530*2882Svi117747 	sip_dialog_terminate(dialog, NULL);
531*2882Svi117747 }
532