OpenSolaris_b135/lib/libsip/common/sip_xaction_ui.c

Compare this file to the similar file:
Show the results in this format:

/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License (the "License").
 * You may not use this file except in compliance with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */

/*
 * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

#pragma ident	"%Z%%M%	%I%	%E% SMI"

#include <stdlib.h>
#include <assert.h>
#include <errno.h>
#include <strings.h>
#include <pthread.h>
#include <sip.h>

#include "sip_msg.h"
#include "sip_miscdefs.h"
#include "sip_xaction.h"

/*
 * Hold transaction
 */
void
sip_hold_trans(sip_transaction_t sip_trans)
{
	sip_xaction_t	*_trans;

	if (sip_trans == NULL)
		return;
	_trans = (sip_xaction_t *)sip_trans;
	(void) pthread_mutex_lock(&((_trans)->sip_xaction_mutex));
	SIP_XACTION_REFCNT_INCR(_trans);
	(void) pthread_mutex_unlock(&((_trans)->sip_xaction_mutex));
}

/*
 * Release transaction
 */
void
sip_release_trans(sip_transaction_t sip_trans)
{
	sip_xaction_t	*_trans;

	if (sip_trans == NULL)
		return;
	_trans = (sip_xaction_t *)sip_trans;
	SIP_XACTION_REFCNT_DECR(_trans);
}

/*
 * Given a message get the client/server transaction. The caller is
 * responsible for doing a sip_release_trans().
 */
const struct sip_xaction *
sip_get_trans(sip_msg_t sip_msg, int which, int *error)
{
	if (error != NULL)
		*error = 0;
	if (sip_msg == NULL) {
		if (error != NULL)
			*error = EINVAL;
		return (NULL);
	}
	return ((sip_transaction_t)sip_xaction_get(NULL, sip_msg, B_FALSE,
	    which, NULL));
}

/*
 * Get the last response sent for this transaction
 */
const struct sip_message *
sip_get_trans_resp_msg(sip_transaction_t sip_trans, int *error)
{
	sip_xaction_t	*_trans;

	if (error != NULL)
		*error = 0;
	if (sip_trans == NULL) {
		if (error != NULL)
			*error = EINVAL;
		return (NULL);
	}
	_trans = (sip_xaction_t *)sip_trans;
	if ((_trans->sip_xaction_last_msg != NULL) &&
	    !sip_msg_is_request((sip_msg_t)_trans->sip_xaction_last_msg,
	    error)) {
		return (_trans->sip_xaction_last_msg);
	} else if (!sip_msg_is_request((sip_msg_t)
	    _trans->sip_xaction_orig_msg, error)) {
		return (_trans->sip_xaction_orig_msg);
	}
	return (NULL);
}

/*
 * Get the SIP message that created this transaction
 */
const struct sip_message *
sip_get_trans_orig_msg(sip_transaction_t sip_trans, int *error)
{
	if (error != NULL)
		*error = 0;
	if (sip_trans == NULL) {
		if (error != NULL)
			*error = EINVAL;
		return (NULL);
	}
	return (((sip_xaction_t *)sip_trans)->sip_xaction_orig_msg);
}

/*
 * Get the connection object that was used to send the last message for this
 * transaction.
 */
const struct sip_conn_object *
sip_get_trans_conn_obj(sip_transaction_t sip_trans, int *error)
{
	if (error != NULL)
		*error = 0;
	if (sip_trans == NULL) {
		if (error != NULL)
			*error = EINVAL;
		return (NULL);
	}
	return (((sip_xaction_t *)sip_trans)->sip_xaction_conn_obj);
}

/*
 * Get the transaction method
 */
sip_method_t
sip_get_trans_method(sip_transaction_t sip_trans, int *error)
{
	if (error != NULL)
		*error = 0;

	if (sip_trans == NULL) {
		if (error != NULL)
			*error = EINVAL;
		return (-1);
	}
	return (((sip_xaction_t *)sip_trans)->sip_xaction_method);
}

/*
 * Get the transaction id. Caller frees string
 */
char *
sip_get_trans_branchid(sip_transaction_t trans, int *error)
{
	sip_xaction_t	*xaction = (sip_xaction_t *)trans;
	char		*bid;

	if (error != NULL)
		*error = 0;
	if (xaction == NULL || xaction->sip_xaction_branch_id == NULL) {
		if (error != NULL)
			*error = EINVAL;
		return (NULL);
	}
	bid = malloc(strlen(xaction->sip_xaction_branch_id) + 1);
	if (bid == NULL) {
		if (error != NULL)
			*error = ENOMEM;
		return (NULL);
	}
	(void) strncpy(bid, xaction->sip_xaction_branch_id,
	    strlen(xaction->sip_xaction_branch_id));
	bid[strlen(xaction->sip_xaction_branch_id)] = '\0';
	return (bid);
}

/*
 * Get the transaction state
 */
int
sip_get_trans_state(sip_transaction_t trans, int *error)
{
	sip_xaction_t	*xaction = (sip_xaction_t *)trans;

	if (error != NULL)
		*error = 0;
	if (xaction == NULL) {
		if (error != NULL)
			*error = EINVAL;
		return (NULL);
	}
	return (xaction->sip_xaction_state);
}