1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include <stdlib.h> 30 #include <assert.h> 31 #include <errno.h> 32 #include <strings.h> 33 #include <pthread.h> 34 #include <sip.h> 35 36 #include "sip_msg.h" 37 #include "sip_miscdefs.h" 38 #include "sip_xaction.h" 39 40 /* 41 * Hold transaction 42 */ 43 void 44 sip_hold_trans(sip_transaction_t sip_trans) 45 { 46 sip_xaction_t *_trans; 47 48 if (sip_trans == NULL) 49 return; 50 _trans = (sip_xaction_t *)sip_trans; 51 (void) pthread_mutex_lock(&((_trans)->sip_xaction_mutex)); 52 SIP_XACTION_REFCNT_INCR(_trans); 53 (void) pthread_mutex_unlock(&((_trans)->sip_xaction_mutex)); 54 } 55 56 /* 57 * Release transaction 58 */ 59 void 60 sip_release_trans(sip_transaction_t sip_trans) 61 { 62 sip_xaction_t *_trans; 63 64 if (sip_trans == NULL) 65 return; 66 _trans = (sip_xaction_t *)sip_trans; 67 SIP_XACTION_REFCNT_DECR(_trans); 68 } 69 70 /* 71 * Given a message get the client/server transaction. The caller is 72 * responsible for doing a sip_release_trans(). 73 */ 74 const struct sip_xaction * 75 sip_get_trans(sip_msg_t sip_msg, int which, int *error) 76 { 77 if (error != NULL) 78 *error = 0; 79 if (sip_msg == NULL) { 80 if (error != NULL) 81 *error = EINVAL; 82 return (NULL); 83 } 84 return ((sip_transaction_t)sip_xaction_get(NULL, sip_msg, B_FALSE, 85 which, NULL)); 86 } 87 88 /* 89 * Get the last response sent for this transaction 90 */ 91 const struct sip_message * 92 sip_get_trans_resp_msg(sip_transaction_t sip_trans, int *error) 93 { 94 sip_xaction_t *_trans; 95 96 if (error != NULL) 97 *error = 0; 98 if (sip_trans == NULL) { 99 if (error != NULL) 100 *error = EINVAL; 101 return (NULL); 102 } 103 _trans = (sip_xaction_t *)sip_trans; 104 if ((_trans->sip_xaction_last_msg != NULL) && 105 !sip_msg_is_request((sip_msg_t)_trans->sip_xaction_last_msg, 106 error)) { 107 return (_trans->sip_xaction_last_msg); 108 } else if (!sip_msg_is_request((sip_msg_t) 109 _trans->sip_xaction_orig_msg, error)) { 110 return (_trans->sip_xaction_orig_msg); 111 } 112 return (NULL); 113 } 114 115 /* 116 * Get the SIP message that created this transaction 117 */ 118 const struct sip_message * 119 sip_get_trans_orig_msg(sip_transaction_t sip_trans, int *error) 120 { 121 if (error != NULL) 122 *error = 0; 123 if (sip_trans == NULL) { 124 if (error != NULL) 125 *error = EINVAL; 126 return (NULL); 127 } 128 return (((sip_xaction_t *)sip_trans)->sip_xaction_orig_msg); 129 } 130 131 /* 132 * Get the connection object that was used to send the last message for this 133 * transaction. 134 */ 135 const struct sip_conn_object * 136 sip_get_trans_conn_obj(sip_transaction_t sip_trans, int *error) 137 { 138 if (error != NULL) 139 *error = 0; 140 if (sip_trans == NULL) { 141 if (error != NULL) 142 *error = EINVAL; 143 return (NULL); 144 } 145 return (((sip_xaction_t *)sip_trans)->sip_xaction_conn_obj); 146 } 147 148 /* 149 * Get the transaction method 150 */ 151 sip_method_t 152 sip_get_trans_method(sip_transaction_t sip_trans, int *error) 153 { 154 if (error != NULL) 155 *error = 0; 156 157 if (sip_trans == NULL) { 158 if (error != NULL) 159 *error = EINVAL; 160 return (-1); 161 } 162 return (((sip_xaction_t *)sip_trans)->sip_xaction_method); 163 } 164 165 /* 166 * Get the transaction id. Caller frees string 167 */ 168 char * 169 sip_get_trans_branchid(sip_transaction_t trans, int *error) 170 { 171 sip_xaction_t *xaction = (sip_xaction_t *)trans; 172 char *bid; 173 174 if (error != NULL) 175 *error = 0; 176 if (xaction == NULL || xaction->sip_xaction_branch_id == NULL) { 177 if (error != NULL) 178 *error = EINVAL; 179 return (NULL); 180 } 181 bid = malloc(strlen(xaction->sip_xaction_branch_id) + 1); 182 if (bid == NULL) { 183 if (error != NULL) 184 *error = ENOMEM; 185 return (NULL); 186 } 187 (void) strncpy(bid, xaction->sip_xaction_branch_id, 188 strlen(xaction->sip_xaction_branch_id)); 189 bid[strlen(xaction->sip_xaction_branch_id)] = '\0'; 190 return (bid); 191 } 192 193 /* 194 * Get the transaction state 195 */ 196 int 197 sip_get_trans_state(sip_transaction_t trans, int *error) 198 { 199 sip_xaction_t *xaction = (sip_xaction_t *)trans; 200 201 if (error != NULL) 202 *error = 0; 203 if (xaction == NULL) { 204 if (error != NULL) 205 *error = EINVAL; 206 return (NULL); 207 } 208 return (xaction->sip_xaction_state); 209 } 210