140cb5e5dSvi /*
240cb5e5dSvi  * CDDL HEADER START
340cb5e5dSvi  *
440cb5e5dSvi  * The contents of this file are subject to the terms of the
540cb5e5dSvi  * Common Development and Distribution License (the "License").
640cb5e5dSvi  * You may not use this file except in compliance with the License.
740cb5e5dSvi  *
840cb5e5dSvi  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
940cb5e5dSvi  * or http://www.opensolaris.org/os/licensing.
1040cb5e5dSvi  * See the License for the specific language governing permissions
1140cb5e5dSvi  * and limitations under the License.
1240cb5e5dSvi  *
1340cb5e5dSvi  * When distributing Covered Code, include this CDDL HEADER in each
1440cb5e5dSvi  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1540cb5e5dSvi  * If applicable, add the following below this CDDL HEADER, with the
1640cb5e5dSvi  * fields enclosed by brackets "[]" replaced with your own identifying
1740cb5e5dSvi  * information: Portions Copyright [yyyy] [name of copyright owner]
1840cb5e5dSvi  *
1940cb5e5dSvi  * CDDL HEADER END
2040cb5e5dSvi  */
2140cb5e5dSvi 
2240cb5e5dSvi /*
232c2c4183Svi  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
2440cb5e5dSvi  * Use is subject to license terms.
2540cb5e5dSvi  */
2640cb5e5dSvi 
272c2c4183Svi #include <stdlib.h>
282c2c4183Svi #include <assert.h>
292c2c4183Svi #include <errno.h>
302c2c4183Svi #include <strings.h>
312c2c4183Svi #include <pthread.h>
322c2c4183Svi #include <sip.h>
332c2c4183Svi 
3440cb5e5dSvi #include "sip_msg.h"
3540cb5e5dSvi #include "sip_miscdefs.h"
3640cb5e5dSvi #include "sip_xaction.h"
3740cb5e5dSvi 
3840cb5e5dSvi /*
3940cb5e5dSvi  * Hold transaction
4040cb5e5dSvi  */
4140cb5e5dSvi void
sip_hold_trans(sip_transaction_t sip_trans)4240cb5e5dSvi sip_hold_trans(sip_transaction_t sip_trans)
4340cb5e5dSvi {
4440cb5e5dSvi 	sip_xaction_t	*_trans;
4540cb5e5dSvi 
4640cb5e5dSvi 	if (sip_trans == NULL)
4740cb5e5dSvi 		return;
4840cb5e5dSvi 	_trans = (sip_xaction_t *)sip_trans;
4940cb5e5dSvi 	(void) pthread_mutex_lock(&((_trans)->sip_xaction_mutex));
5040cb5e5dSvi 	SIP_XACTION_REFCNT_INCR(_trans);
5140cb5e5dSvi 	(void) pthread_mutex_unlock(&((_trans)->sip_xaction_mutex));
5240cb5e5dSvi }
5340cb5e5dSvi 
5440cb5e5dSvi /*
5540cb5e5dSvi  * Release transaction
5640cb5e5dSvi  */
5740cb5e5dSvi void
sip_release_trans(sip_transaction_t sip_trans)5840cb5e5dSvi sip_release_trans(sip_transaction_t sip_trans)
5940cb5e5dSvi {
6040cb5e5dSvi 	sip_xaction_t	*_trans;
6140cb5e5dSvi 
6240cb5e5dSvi 	if (sip_trans == NULL)
6340cb5e5dSvi 		return;
6440cb5e5dSvi 	_trans = (sip_xaction_t *)sip_trans;
6540cb5e5dSvi 	SIP_XACTION_REFCNT_DECR(_trans);
6640cb5e5dSvi }
6740cb5e5dSvi 
6840cb5e5dSvi /*
6940cb5e5dSvi  * Given a message get the client/server transaction. The caller is
7040cb5e5dSvi  * responsible for doing a sip_release_trans().
7140cb5e5dSvi  */
7240cb5e5dSvi const struct sip_xaction *
sip_get_trans(sip_msg_t sip_msg,int which,int * error)7340cb5e5dSvi sip_get_trans(sip_msg_t sip_msg, int which, int *error)
7440cb5e5dSvi {
7540cb5e5dSvi 	if (error != NULL)
7640cb5e5dSvi 		*error = 0;
7740cb5e5dSvi 	if (sip_msg == NULL) {
7840cb5e5dSvi 		if (error != NULL)
7940cb5e5dSvi 			*error = EINVAL;
8040cb5e5dSvi 		return (NULL);
8140cb5e5dSvi 	}
8240cb5e5dSvi 	return ((sip_transaction_t)sip_xaction_get(NULL, sip_msg, B_FALSE,
8340cb5e5dSvi 	    which, NULL));
8440cb5e5dSvi }
8540cb5e5dSvi 
8640cb5e5dSvi /*
8740cb5e5dSvi  * Get the last response sent for this transaction
8840cb5e5dSvi  */
8940cb5e5dSvi const struct sip_message *
sip_get_trans_resp_msg(sip_transaction_t sip_trans,int * error)9040cb5e5dSvi sip_get_trans_resp_msg(sip_transaction_t sip_trans, int *error)
9140cb5e5dSvi {
9240cb5e5dSvi 	sip_xaction_t	*_trans;
9340cb5e5dSvi 
9440cb5e5dSvi 	if (error != NULL)
9540cb5e5dSvi 		*error = 0;
9640cb5e5dSvi 	if (sip_trans == NULL) {
9740cb5e5dSvi 		if (error != NULL)
9840cb5e5dSvi 			*error = EINVAL;
9940cb5e5dSvi 		return (NULL);
10040cb5e5dSvi 	}
10140cb5e5dSvi 	_trans = (sip_xaction_t *)sip_trans;
10240cb5e5dSvi 	if ((_trans->sip_xaction_last_msg != NULL) &&
10340cb5e5dSvi 	    !sip_msg_is_request((sip_msg_t)_trans->sip_xaction_last_msg,
10440cb5e5dSvi 	    error)) {
10540cb5e5dSvi 		return (_trans->sip_xaction_last_msg);
10640cb5e5dSvi 	} else if (!sip_msg_is_request((sip_msg_t)
10740cb5e5dSvi 	    _trans->sip_xaction_orig_msg, error)) {
10840cb5e5dSvi 		return (_trans->sip_xaction_orig_msg);
10940cb5e5dSvi 	}
11040cb5e5dSvi 	return (NULL);
11140cb5e5dSvi }
11240cb5e5dSvi 
11340cb5e5dSvi /*
11440cb5e5dSvi  * Get the SIP message that created this transaction
11540cb5e5dSvi  */
11640cb5e5dSvi const struct sip_message *
sip_get_trans_orig_msg(sip_transaction_t sip_trans,int * error)11740cb5e5dSvi sip_get_trans_orig_msg(sip_transaction_t sip_trans, int *error)
11840cb5e5dSvi {
11940cb5e5dSvi 	if (error != NULL)
12040cb5e5dSvi 		*error = 0;
12140cb5e5dSvi 	if (sip_trans == NULL) {
12240cb5e5dSvi 		if (error != NULL)
12340cb5e5dSvi 			*error = EINVAL;
12440cb5e5dSvi 		return (NULL);
12540cb5e5dSvi 	}
12640cb5e5dSvi 	return (((sip_xaction_t *)sip_trans)->sip_xaction_orig_msg);
12740cb5e5dSvi }
12840cb5e5dSvi 
12940cb5e5dSvi /*
13040cb5e5dSvi  * Get the connection object that was used to send the last message for this
13140cb5e5dSvi  * transaction.
13240cb5e5dSvi  */
13340cb5e5dSvi const struct sip_conn_object *
sip_get_trans_conn_obj(sip_transaction_t sip_trans,int * error)13440cb5e5dSvi sip_get_trans_conn_obj(sip_transaction_t sip_trans, int *error)
13540cb5e5dSvi {
13640cb5e5dSvi 	if (error != NULL)
13740cb5e5dSvi 		*error = 0;
13840cb5e5dSvi 	if (sip_trans == NULL) {
13940cb5e5dSvi 		if (error != NULL)
14040cb5e5dSvi 			*error = EINVAL;
14140cb5e5dSvi 		return (NULL);
14240cb5e5dSvi 	}
14340cb5e5dSvi 	return (((sip_xaction_t *)sip_trans)->sip_xaction_conn_obj);
14440cb5e5dSvi }
14540cb5e5dSvi 
14640cb5e5dSvi /*
14740cb5e5dSvi  * Get the transaction method
14840cb5e5dSvi  */
14940cb5e5dSvi sip_method_t
sip_get_trans_method(sip_transaction_t sip_trans,int * error)15040cb5e5dSvi sip_get_trans_method(sip_transaction_t sip_trans, int *error)
15140cb5e5dSvi {
15240cb5e5dSvi 	if (error != NULL)
15340cb5e5dSvi 		*error = 0;
15440cb5e5dSvi 
15540cb5e5dSvi 	if (sip_trans == NULL) {
15640cb5e5dSvi 		if (error != NULL)
15740cb5e5dSvi 			*error = EINVAL;
15840cb5e5dSvi 		return (-1);
15940cb5e5dSvi 	}
16040cb5e5dSvi 	return (((sip_xaction_t *)sip_trans)->sip_xaction_method);
16140cb5e5dSvi }
16240cb5e5dSvi 
16340cb5e5dSvi /*
16440cb5e5dSvi  * Get the transaction id. Caller frees string
16540cb5e5dSvi  */
16640cb5e5dSvi char *
sip_get_trans_branchid(sip_transaction_t trans,int * error)16740cb5e5dSvi sip_get_trans_branchid(sip_transaction_t trans, int *error)
16840cb5e5dSvi {
16940cb5e5dSvi 	sip_xaction_t	*xaction = (sip_xaction_t *)trans;
17040cb5e5dSvi 	char		*bid;
17140cb5e5dSvi 
17240cb5e5dSvi 	if (error != NULL)
17340cb5e5dSvi 		*error = 0;
17440cb5e5dSvi 	if (xaction == NULL || xaction->sip_xaction_branch_id == NULL) {
17540cb5e5dSvi 		if (error != NULL)
17640cb5e5dSvi 			*error = EINVAL;
17740cb5e5dSvi 		return (NULL);
17840cb5e5dSvi 	}
17940cb5e5dSvi 	bid = malloc(strlen(xaction->sip_xaction_branch_id) + 1);
18040cb5e5dSvi 	if (bid == NULL) {
18140cb5e5dSvi 		if (error != NULL)
18240cb5e5dSvi 			*error = ENOMEM;
18340cb5e5dSvi 		return (NULL);
18440cb5e5dSvi 	}
18540cb5e5dSvi 	(void) strncpy(bid, xaction->sip_xaction_branch_id,
18640cb5e5dSvi 	    strlen(xaction->sip_xaction_branch_id));
18740cb5e5dSvi 	bid[strlen(xaction->sip_xaction_branch_id)] = '\0';
18840cb5e5dSvi 	return (bid);
18940cb5e5dSvi }
19040cb5e5dSvi 
19140cb5e5dSvi /*
19240cb5e5dSvi  * Get the transaction state
19340cb5e5dSvi  */
19440cb5e5dSvi int
sip_get_trans_state(sip_transaction_t trans,int * error)19540cb5e5dSvi sip_get_trans_state(sip_transaction_t trans, int *error)
19640cb5e5dSvi {
19740cb5e5dSvi 	sip_xaction_t	*xaction = (sip_xaction_t *)trans;
19840cb5e5dSvi 
19940cb5e5dSvi 	if (error != NULL)
20040cb5e5dSvi 		*error = 0;
20140cb5e5dSvi 	if (xaction == NULL) {
20240cb5e5dSvi 		if (error != NULL)
20340cb5e5dSvi 			*error = EINVAL;
204*559f8b54SToomas Soome 		return (0);
20540cb5e5dSvi 	}
20640cb5e5dSvi 	return (xaction->sip_xaction_state);
20740cb5e5dSvi }
208