12882Svi117747 /*
22882Svi117747 * CDDL HEADER START
32882Svi117747 *
42882Svi117747 * The contents of this file are subject to the terms of the
52882Svi117747 * Common Development and Distribution License (the "License").
62882Svi117747 * You may not use this file except in compliance with the License.
72882Svi117747 *
82882Svi117747 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
92882Svi117747 * or http://www.opensolaris.org/os/licensing.
102882Svi117747 * See the License for the specific language governing permissions
112882Svi117747 * and limitations under the License.
122882Svi117747 *
132882Svi117747 * When distributing Covered Code, include this CDDL HEADER in each
142882Svi117747 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
152882Svi117747 * If applicable, add the following below this CDDL HEADER, with the
162882Svi117747 * fields enclosed by brackets "[]" replaced with your own identifying
172882Svi117747 * information: Portions Copyright [yyyy] [name of copyright owner]
182882Svi117747 *
192882Svi117747 * CDDL HEADER END
202882Svi117747 */
212882Svi117747
222882Svi117747 /*
23*3439Svi117747 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
242882Svi117747 * Use is subject to license terms.
252882Svi117747 */
262882Svi117747
272882Svi117747 #pragma ident "%Z%%M% %I% %E% SMI"
282882Svi117747
29*3439Svi117747 #include <stdlib.h>
30*3439Svi117747 #include <assert.h>
31*3439Svi117747 #include <errno.h>
32*3439Svi117747 #include <strings.h>
33*3439Svi117747 #include <pthread.h>
34*3439Svi117747 #include <sip.h>
35*3439Svi117747
362882Svi117747 #include "sip_msg.h"
372882Svi117747 #include "sip_miscdefs.h"
382882Svi117747 #include "sip_xaction.h"
392882Svi117747
402882Svi117747 /*
412882Svi117747 * Hold transaction
422882Svi117747 */
432882Svi117747 void
sip_hold_trans(sip_transaction_t sip_trans)442882Svi117747 sip_hold_trans(sip_transaction_t sip_trans)
452882Svi117747 {
462882Svi117747 sip_xaction_t *_trans;
472882Svi117747
482882Svi117747 if (sip_trans == NULL)
492882Svi117747 return;
502882Svi117747 _trans = (sip_xaction_t *)sip_trans;
512882Svi117747 (void) pthread_mutex_lock(&((_trans)->sip_xaction_mutex));
522882Svi117747 SIP_XACTION_REFCNT_INCR(_trans);
532882Svi117747 (void) pthread_mutex_unlock(&((_trans)->sip_xaction_mutex));
542882Svi117747 }
552882Svi117747
562882Svi117747 /*
572882Svi117747 * Release transaction
582882Svi117747 */
592882Svi117747 void
sip_release_trans(sip_transaction_t sip_trans)602882Svi117747 sip_release_trans(sip_transaction_t sip_trans)
612882Svi117747 {
622882Svi117747 sip_xaction_t *_trans;
632882Svi117747
642882Svi117747 if (sip_trans == NULL)
652882Svi117747 return;
662882Svi117747 _trans = (sip_xaction_t *)sip_trans;
672882Svi117747 SIP_XACTION_REFCNT_DECR(_trans);
682882Svi117747 }
692882Svi117747
702882Svi117747 /*
712882Svi117747 * Given a message get the client/server transaction. The caller is
722882Svi117747 * responsible for doing a sip_release_trans().
732882Svi117747 */
742882Svi117747 const struct sip_xaction *
sip_get_trans(sip_msg_t sip_msg,int which,int * error)752882Svi117747 sip_get_trans(sip_msg_t sip_msg, int which, int *error)
762882Svi117747 {
772882Svi117747 if (error != NULL)
782882Svi117747 *error = 0;
792882Svi117747 if (sip_msg == NULL) {
802882Svi117747 if (error != NULL)
812882Svi117747 *error = EINVAL;
822882Svi117747 return (NULL);
832882Svi117747 }
842882Svi117747 return ((sip_transaction_t)sip_xaction_get(NULL, sip_msg, B_FALSE,
852882Svi117747 which, NULL));
862882Svi117747 }
872882Svi117747
882882Svi117747 /*
892882Svi117747 * Get the last response sent for this transaction
902882Svi117747 */
912882Svi117747 const struct sip_message *
sip_get_trans_resp_msg(sip_transaction_t sip_trans,int * error)922882Svi117747 sip_get_trans_resp_msg(sip_transaction_t sip_trans, int *error)
932882Svi117747 {
942882Svi117747 sip_xaction_t *_trans;
952882Svi117747
962882Svi117747 if (error != NULL)
972882Svi117747 *error = 0;
982882Svi117747 if (sip_trans == NULL) {
992882Svi117747 if (error != NULL)
1002882Svi117747 *error = EINVAL;
1012882Svi117747 return (NULL);
1022882Svi117747 }
1032882Svi117747 _trans = (sip_xaction_t *)sip_trans;
1042882Svi117747 if ((_trans->sip_xaction_last_msg != NULL) &&
1052882Svi117747 !sip_msg_is_request((sip_msg_t)_trans->sip_xaction_last_msg,
1062882Svi117747 error)) {
1072882Svi117747 return (_trans->sip_xaction_last_msg);
1082882Svi117747 } else if (!sip_msg_is_request((sip_msg_t)
1092882Svi117747 _trans->sip_xaction_orig_msg, error)) {
1102882Svi117747 return (_trans->sip_xaction_orig_msg);
1112882Svi117747 }
1122882Svi117747 return (NULL);
1132882Svi117747 }
1142882Svi117747
1152882Svi117747 /*
1162882Svi117747 * Get the SIP message that created this transaction
1172882Svi117747 */
1182882Svi117747 const struct sip_message *
sip_get_trans_orig_msg(sip_transaction_t sip_trans,int * error)1192882Svi117747 sip_get_trans_orig_msg(sip_transaction_t sip_trans, int *error)
1202882Svi117747 {
1212882Svi117747 if (error != NULL)
1222882Svi117747 *error = 0;
1232882Svi117747 if (sip_trans == NULL) {
1242882Svi117747 if (error != NULL)
1252882Svi117747 *error = EINVAL;
1262882Svi117747 return (NULL);
1272882Svi117747 }
1282882Svi117747 return (((sip_xaction_t *)sip_trans)->sip_xaction_orig_msg);
1292882Svi117747 }
1302882Svi117747
1312882Svi117747 /*
1322882Svi117747 * Get the connection object that was used to send the last message for this
1332882Svi117747 * transaction.
1342882Svi117747 */
1352882Svi117747 const struct sip_conn_object *
sip_get_trans_conn_obj(sip_transaction_t sip_trans,int * error)1362882Svi117747 sip_get_trans_conn_obj(sip_transaction_t sip_trans, int *error)
1372882Svi117747 {
1382882Svi117747 if (error != NULL)
1392882Svi117747 *error = 0;
1402882Svi117747 if (sip_trans == NULL) {
1412882Svi117747 if (error != NULL)
1422882Svi117747 *error = EINVAL;
1432882Svi117747 return (NULL);
1442882Svi117747 }
1452882Svi117747 return (((sip_xaction_t *)sip_trans)->sip_xaction_conn_obj);
1462882Svi117747 }
1472882Svi117747
1482882Svi117747 /*
1492882Svi117747 * Get the transaction method
1502882Svi117747 */
1512882Svi117747 sip_method_t
sip_get_trans_method(sip_transaction_t sip_trans,int * error)1522882Svi117747 sip_get_trans_method(sip_transaction_t sip_trans, int *error)
1532882Svi117747 {
1542882Svi117747 if (error != NULL)
1552882Svi117747 *error = 0;
1562882Svi117747
1572882Svi117747 if (sip_trans == NULL) {
1582882Svi117747 if (error != NULL)
1592882Svi117747 *error = EINVAL;
1602882Svi117747 return (-1);
1612882Svi117747 }
1622882Svi117747 return (((sip_xaction_t *)sip_trans)->sip_xaction_method);
1632882Svi117747 }
1642882Svi117747
1652882Svi117747 /*
1662882Svi117747 * Get the transaction id. Caller frees string
1672882Svi117747 */
1682882Svi117747 char *
sip_get_trans_branchid(sip_transaction_t trans,int * error)1692882Svi117747 sip_get_trans_branchid(sip_transaction_t trans, int *error)
1702882Svi117747 {
1712882Svi117747 sip_xaction_t *xaction = (sip_xaction_t *)trans;
1722882Svi117747 char *bid;
1732882Svi117747
1742882Svi117747 if (error != NULL)
1752882Svi117747 *error = 0;
1762882Svi117747 if (xaction == NULL || xaction->sip_xaction_branch_id == NULL) {
1772882Svi117747 if (error != NULL)
1782882Svi117747 *error = EINVAL;
1792882Svi117747 return (NULL);
1802882Svi117747 }
1812882Svi117747 bid = malloc(strlen(xaction->sip_xaction_branch_id) + 1);
1822882Svi117747 if (bid == NULL) {
1832882Svi117747 if (error != NULL)
1842882Svi117747 *error = ENOMEM;
1852882Svi117747 return (NULL);
1862882Svi117747 }
1872882Svi117747 (void) strncpy(bid, xaction->sip_xaction_branch_id,
1882882Svi117747 strlen(xaction->sip_xaction_branch_id));
1892882Svi117747 bid[strlen(xaction->sip_xaction_branch_id)] = '\0';
1902882Svi117747 return (bid);
1912882Svi117747 }
1922882Svi117747
1932882Svi117747 /*
1942882Svi117747 * Get the transaction state
1952882Svi117747 */
1962882Svi117747 int
sip_get_trans_state(sip_transaction_t trans,int * error)1972882Svi117747 sip_get_trans_state(sip_transaction_t trans, int *error)
1982882Svi117747 {
1992882Svi117747 sip_xaction_t *xaction = (sip_xaction_t *)trans;
2002882Svi117747
2012882Svi117747 if (error != NULL)
2022882Svi117747 *error = 0;
2032882Svi117747 if (xaction == NULL) {
2042882Svi117747 if (error != NULL)
2052882Svi117747 *error = EINVAL;
2062882Svi117747 return (NULL);
2072882Svi117747 }
2082882Svi117747 return (xaction->sip_xaction_state);
2092882Svi117747 }
210