xref: /titanic_50/usr/src/lib/libsip/common/sip_xaction_ui.c (revision 2c2c41837e330b002c4220a39638150db504fe0e)
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*2c2c4183Svi117747  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
2440cb5e5dSvi117747  * Use is subject to license terms.
2540cb5e5dSvi117747  */
2640cb5e5dSvi117747 
2740cb5e5dSvi117747 #pragma ident	"%Z%%M%	%I%	%E% SMI"
2840cb5e5dSvi117747 
29*2c2c4183Svi117747 #include <stdlib.h>
30*2c2c4183Svi117747 #include <assert.h>
31*2c2c4183Svi117747 #include <errno.h>
32*2c2c4183Svi117747 #include <strings.h>
33*2c2c4183Svi117747 #include <pthread.h>
34*2c2c4183Svi117747 #include <sip.h>
35*2c2c4183Svi117747 
3640cb5e5dSvi117747 #include "sip_msg.h"
3740cb5e5dSvi117747 #include "sip_miscdefs.h"
3840cb5e5dSvi117747 #include "sip_xaction.h"
3940cb5e5dSvi117747 
4040cb5e5dSvi117747 /*
4140cb5e5dSvi117747  * Hold transaction
4240cb5e5dSvi117747  */
4340cb5e5dSvi117747 void
sip_hold_trans(sip_transaction_t sip_trans)4440cb5e5dSvi117747 sip_hold_trans(sip_transaction_t sip_trans)
4540cb5e5dSvi117747 {
4640cb5e5dSvi117747 	sip_xaction_t	*_trans;
4740cb5e5dSvi117747 
4840cb5e5dSvi117747 	if (sip_trans == NULL)
4940cb5e5dSvi117747 		return;
5040cb5e5dSvi117747 	_trans = (sip_xaction_t *)sip_trans;
5140cb5e5dSvi117747 	(void) pthread_mutex_lock(&((_trans)->sip_xaction_mutex));
5240cb5e5dSvi117747 	SIP_XACTION_REFCNT_INCR(_trans);
5340cb5e5dSvi117747 	(void) pthread_mutex_unlock(&((_trans)->sip_xaction_mutex));
5440cb5e5dSvi117747 }
5540cb5e5dSvi117747 
5640cb5e5dSvi117747 /*
5740cb5e5dSvi117747  * Release transaction
5840cb5e5dSvi117747  */
5940cb5e5dSvi117747 void
sip_release_trans(sip_transaction_t sip_trans)6040cb5e5dSvi117747 sip_release_trans(sip_transaction_t sip_trans)
6140cb5e5dSvi117747 {
6240cb5e5dSvi117747 	sip_xaction_t	*_trans;
6340cb5e5dSvi117747 
6440cb5e5dSvi117747 	if (sip_trans == NULL)
6540cb5e5dSvi117747 		return;
6640cb5e5dSvi117747 	_trans = (sip_xaction_t *)sip_trans;
6740cb5e5dSvi117747 	SIP_XACTION_REFCNT_DECR(_trans);
6840cb5e5dSvi117747 }
6940cb5e5dSvi117747 
7040cb5e5dSvi117747 /*
7140cb5e5dSvi117747  * Given a message get the client/server transaction. The caller is
7240cb5e5dSvi117747  * responsible for doing a sip_release_trans().
7340cb5e5dSvi117747  */
7440cb5e5dSvi117747 const struct sip_xaction *
sip_get_trans(sip_msg_t sip_msg,int which,int * error)7540cb5e5dSvi117747 sip_get_trans(sip_msg_t sip_msg, int which, int *error)
7640cb5e5dSvi117747 {
7740cb5e5dSvi117747 	if (error != NULL)
7840cb5e5dSvi117747 		*error = 0;
7940cb5e5dSvi117747 	if (sip_msg == NULL) {
8040cb5e5dSvi117747 		if (error != NULL)
8140cb5e5dSvi117747 			*error = EINVAL;
8240cb5e5dSvi117747 		return (NULL);
8340cb5e5dSvi117747 	}
8440cb5e5dSvi117747 	return ((sip_transaction_t)sip_xaction_get(NULL, sip_msg, B_FALSE,
8540cb5e5dSvi117747 	    which, NULL));
8640cb5e5dSvi117747 }
8740cb5e5dSvi117747 
8840cb5e5dSvi117747 /*
8940cb5e5dSvi117747  * Get the last response sent for this transaction
9040cb5e5dSvi117747  */
9140cb5e5dSvi117747 const struct sip_message *
sip_get_trans_resp_msg(sip_transaction_t sip_trans,int * error)9240cb5e5dSvi117747 sip_get_trans_resp_msg(sip_transaction_t sip_trans, int *error)
9340cb5e5dSvi117747 {
9440cb5e5dSvi117747 	sip_xaction_t	*_trans;
9540cb5e5dSvi117747 
9640cb5e5dSvi117747 	if (error != NULL)
9740cb5e5dSvi117747 		*error = 0;
9840cb5e5dSvi117747 	if (sip_trans == NULL) {
9940cb5e5dSvi117747 		if (error != NULL)
10040cb5e5dSvi117747 			*error = EINVAL;
10140cb5e5dSvi117747 		return (NULL);
10240cb5e5dSvi117747 	}
10340cb5e5dSvi117747 	_trans = (sip_xaction_t *)sip_trans;
10440cb5e5dSvi117747 	if ((_trans->sip_xaction_last_msg != NULL) &&
10540cb5e5dSvi117747 	    !sip_msg_is_request((sip_msg_t)_trans->sip_xaction_last_msg,
10640cb5e5dSvi117747 	    error)) {
10740cb5e5dSvi117747 		return (_trans->sip_xaction_last_msg);
10840cb5e5dSvi117747 	} else if (!sip_msg_is_request((sip_msg_t)
10940cb5e5dSvi117747 	    _trans->sip_xaction_orig_msg, error)) {
11040cb5e5dSvi117747 		return (_trans->sip_xaction_orig_msg);
11140cb5e5dSvi117747 	}
11240cb5e5dSvi117747 	return (NULL);
11340cb5e5dSvi117747 }
11440cb5e5dSvi117747 
11540cb5e5dSvi117747 /*
11640cb5e5dSvi117747  * Get the SIP message that created this transaction
11740cb5e5dSvi117747  */
11840cb5e5dSvi117747 const struct sip_message *
sip_get_trans_orig_msg(sip_transaction_t sip_trans,int * error)11940cb5e5dSvi117747 sip_get_trans_orig_msg(sip_transaction_t sip_trans, int *error)
12040cb5e5dSvi117747 {
12140cb5e5dSvi117747 	if (error != NULL)
12240cb5e5dSvi117747 		*error = 0;
12340cb5e5dSvi117747 	if (sip_trans == NULL) {
12440cb5e5dSvi117747 		if (error != NULL)
12540cb5e5dSvi117747 			*error = EINVAL;
12640cb5e5dSvi117747 		return (NULL);
12740cb5e5dSvi117747 	}
12840cb5e5dSvi117747 	return (((sip_xaction_t *)sip_trans)->sip_xaction_orig_msg);
12940cb5e5dSvi117747 }
13040cb5e5dSvi117747 
13140cb5e5dSvi117747 /*
13240cb5e5dSvi117747  * Get the connection object that was used to send the last message for this
13340cb5e5dSvi117747  * transaction.
13440cb5e5dSvi117747  */
13540cb5e5dSvi117747 const struct sip_conn_object *
sip_get_trans_conn_obj(sip_transaction_t sip_trans,int * error)13640cb5e5dSvi117747 sip_get_trans_conn_obj(sip_transaction_t sip_trans, int *error)
13740cb5e5dSvi117747 {
13840cb5e5dSvi117747 	if (error != NULL)
13940cb5e5dSvi117747 		*error = 0;
14040cb5e5dSvi117747 	if (sip_trans == NULL) {
14140cb5e5dSvi117747 		if (error != NULL)
14240cb5e5dSvi117747 			*error = EINVAL;
14340cb5e5dSvi117747 		return (NULL);
14440cb5e5dSvi117747 	}
14540cb5e5dSvi117747 	return (((sip_xaction_t *)sip_trans)->sip_xaction_conn_obj);
14640cb5e5dSvi117747 }
14740cb5e5dSvi117747 
14840cb5e5dSvi117747 /*
14940cb5e5dSvi117747  * Get the transaction method
15040cb5e5dSvi117747  */
15140cb5e5dSvi117747 sip_method_t
sip_get_trans_method(sip_transaction_t sip_trans,int * error)15240cb5e5dSvi117747 sip_get_trans_method(sip_transaction_t sip_trans, int *error)
15340cb5e5dSvi117747 {
15440cb5e5dSvi117747 	if (error != NULL)
15540cb5e5dSvi117747 		*error = 0;
15640cb5e5dSvi117747 
15740cb5e5dSvi117747 	if (sip_trans == NULL) {
15840cb5e5dSvi117747 		if (error != NULL)
15940cb5e5dSvi117747 			*error = EINVAL;
16040cb5e5dSvi117747 		return (-1);
16140cb5e5dSvi117747 	}
16240cb5e5dSvi117747 	return (((sip_xaction_t *)sip_trans)->sip_xaction_method);
16340cb5e5dSvi117747 }
16440cb5e5dSvi117747 
16540cb5e5dSvi117747 /*
16640cb5e5dSvi117747  * Get the transaction id. Caller frees string
16740cb5e5dSvi117747  */
16840cb5e5dSvi117747 char *
sip_get_trans_branchid(sip_transaction_t trans,int * error)16940cb5e5dSvi117747 sip_get_trans_branchid(sip_transaction_t trans, int *error)
17040cb5e5dSvi117747 {
17140cb5e5dSvi117747 	sip_xaction_t	*xaction = (sip_xaction_t *)trans;
17240cb5e5dSvi117747 	char		*bid;
17340cb5e5dSvi117747 
17440cb5e5dSvi117747 	if (error != NULL)
17540cb5e5dSvi117747 		*error = 0;
17640cb5e5dSvi117747 	if (xaction == NULL || xaction->sip_xaction_branch_id == NULL) {
17740cb5e5dSvi117747 		if (error != NULL)
17840cb5e5dSvi117747 			*error = EINVAL;
17940cb5e5dSvi117747 		return (NULL);
18040cb5e5dSvi117747 	}
18140cb5e5dSvi117747 	bid = malloc(strlen(xaction->sip_xaction_branch_id) + 1);
18240cb5e5dSvi117747 	if (bid == NULL) {
18340cb5e5dSvi117747 		if (error != NULL)
18440cb5e5dSvi117747 			*error = ENOMEM;
18540cb5e5dSvi117747 		return (NULL);
18640cb5e5dSvi117747 	}
18740cb5e5dSvi117747 	(void) strncpy(bid, xaction->sip_xaction_branch_id,
18840cb5e5dSvi117747 	    strlen(xaction->sip_xaction_branch_id));
18940cb5e5dSvi117747 	bid[strlen(xaction->sip_xaction_branch_id)] = '\0';
19040cb5e5dSvi117747 	return (bid);
19140cb5e5dSvi117747 }
19240cb5e5dSvi117747 
19340cb5e5dSvi117747 /*
19440cb5e5dSvi117747  * Get the transaction state
19540cb5e5dSvi117747  */
19640cb5e5dSvi117747 int
sip_get_trans_state(sip_transaction_t trans,int * error)19740cb5e5dSvi117747 sip_get_trans_state(sip_transaction_t trans, int *error)
19840cb5e5dSvi117747 {
19940cb5e5dSvi117747 	sip_xaction_t	*xaction = (sip_xaction_t *)trans;
20040cb5e5dSvi117747 
20140cb5e5dSvi117747 	if (error != NULL)
20240cb5e5dSvi117747 		*error = 0;
20340cb5e5dSvi117747 	if (xaction == NULL) {
20440cb5e5dSvi117747 		if (error != NULL)
20540cb5e5dSvi117747 			*error = EINVAL;
20640cb5e5dSvi117747 		return (NULL);
20740cb5e5dSvi117747 	}
20840cb5e5dSvi117747 	return (xaction->sip_xaction_state);
20940cb5e5dSvi117747 }
210