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 #include <stdlib.h> 28 #include <assert.h> 29 #include <errno.h> 30 #include <strings.h> 31 #include <pthread.h> 32 #include <sip.h> 33 34 #include "sip_msg.h" 35 #include "sip_miscdefs.h" 36 #include "sip_xaction.h" 37 38 /* 39 * Hold transaction 40 */ 41 void 42 sip_hold_trans(sip_transaction_t sip_trans) 43 { 44 sip_xaction_t *_trans; 45 46 if (sip_trans == NULL) 47 return; 48 _trans = (sip_xaction_t *)sip_trans; 49 (void) pthread_mutex_lock(&((_trans)->sip_xaction_mutex)); 50 SIP_XACTION_REFCNT_INCR(_trans); 51 (void) pthread_mutex_unlock(&((_trans)->sip_xaction_mutex)); 52 } 53 54 /* 55 * Release transaction 56 */ 57 void 58 sip_release_trans(sip_transaction_t sip_trans) 59 { 60 sip_xaction_t *_trans; 61 62 if (sip_trans == NULL) 63 return; 64 _trans = (sip_xaction_t *)sip_trans; 65 SIP_XACTION_REFCNT_DECR(_trans); 66 } 67 68 /* 69 * Given a message get the client/server transaction. The caller is 70 * responsible for doing a sip_release_trans(). 71 */ 72 const struct sip_xaction * 73 sip_get_trans(sip_msg_t sip_msg, int which, int *error) 74 { 75 if (error != NULL) 76 *error = 0; 77 if (sip_msg == NULL) { 78 if (error != NULL) 79 *error = EINVAL; 80 return (NULL); 81 } 82 return ((sip_transaction_t)sip_xaction_get(NULL, sip_msg, B_FALSE, 83 which, NULL)); 84 } 85 86 /* 87 * Get the last response sent for this transaction 88 */ 89 const struct sip_message * 90 sip_get_trans_resp_msg(sip_transaction_t sip_trans, int *error) 91 { 92 sip_xaction_t *_trans; 93 94 if (error != NULL) 95 *error = 0; 96 if (sip_trans == NULL) { 97 if (error != NULL) 98 *error = EINVAL; 99 return (NULL); 100 } 101 _trans = (sip_xaction_t *)sip_trans; 102 if ((_trans->sip_xaction_last_msg != NULL) && 103 !sip_msg_is_request((sip_msg_t)_trans->sip_xaction_last_msg, 104 error)) { 105 return (_trans->sip_xaction_last_msg); 106 } else if (!sip_msg_is_request((sip_msg_t) 107 _trans->sip_xaction_orig_msg, error)) { 108 return (_trans->sip_xaction_orig_msg); 109 } 110 return (NULL); 111 } 112 113 /* 114 * Get the SIP message that created this transaction 115 */ 116 const struct sip_message * 117 sip_get_trans_orig_msg(sip_transaction_t sip_trans, int *error) 118 { 119 if (error != NULL) 120 *error = 0; 121 if (sip_trans == NULL) { 122 if (error != NULL) 123 *error = EINVAL; 124 return (NULL); 125 } 126 return (((sip_xaction_t *)sip_trans)->sip_xaction_orig_msg); 127 } 128 129 /* 130 * Get the connection object that was used to send the last message for this 131 * transaction. 132 */ 133 const struct sip_conn_object * 134 sip_get_trans_conn_obj(sip_transaction_t sip_trans, int *error) 135 { 136 if (error != NULL) 137 *error = 0; 138 if (sip_trans == NULL) { 139 if (error != NULL) 140 *error = EINVAL; 141 return (NULL); 142 } 143 return (((sip_xaction_t *)sip_trans)->sip_xaction_conn_obj); 144 } 145 146 /* 147 * Get the transaction method 148 */ 149 sip_method_t 150 sip_get_trans_method(sip_transaction_t sip_trans, int *error) 151 { 152 if (error != NULL) 153 *error = 0; 154 155 if (sip_trans == NULL) { 156 if (error != NULL) 157 *error = EINVAL; 158 return (-1); 159 } 160 return (((sip_xaction_t *)sip_trans)->sip_xaction_method); 161 } 162 163 /* 164 * Get the transaction id. Caller frees string 165 */ 166 char * 167 sip_get_trans_branchid(sip_transaction_t trans, int *error) 168 { 169 sip_xaction_t *xaction = (sip_xaction_t *)trans; 170 char *bid; 171 172 if (error != NULL) 173 *error = 0; 174 if (xaction == NULL || xaction->sip_xaction_branch_id == NULL) { 175 if (error != NULL) 176 *error = EINVAL; 177 return (NULL); 178 } 179 bid = malloc(strlen(xaction->sip_xaction_branch_id) + 1); 180 if (bid == NULL) { 181 if (error != NULL) 182 *error = ENOMEM; 183 return (NULL); 184 } 185 (void) strncpy(bid, xaction->sip_xaction_branch_id, 186 strlen(xaction->sip_xaction_branch_id)); 187 bid[strlen(xaction->sip_xaction_branch_id)] = '\0'; 188 return (bid); 189 } 190 191 /* 192 * Get the transaction state 193 */ 194 int 195 sip_get_trans_state(sip_transaction_t trans, int *error) 196 { 197 sip_xaction_t *xaction = (sip_xaction_t *)trans; 198 199 if (error != NULL) 200 *error = 0; 201 if (xaction == NULL) { 202 if (error != NULL) 203 *error = EINVAL; 204 return (0); 205 } 206 return (xaction->sip_xaction_state); 207 } 208