Changeset 107 for pjproject/trunk/pjsip/src/pjsip/sip_transaction.c
- Timestamp:
- Jan 5, 2006 11:35:46 PM (18 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjsip/src/pjsip/sip_transaction.c
r106 r107 18 18 */ 19 19 #include <pjsip/sip_transaction.h> 20 #include <pjsip/sip_transport.h>21 #include <pjsip/sip_config.h>22 20 #include <pjsip/sip_util.h> 23 #include <pjsip/sip_ event.h>21 #include <pjsip/sip_module.h> 24 22 #include <pjsip/sip_endpoint.h> 25 23 #include <pjsip/sip_errno.h> 24 #include <pjsip/sip_event.h> 25 #include <pj/hash.h> 26 #include <pj/pool.h> 27 #include <pj/os.h> 28 #include <pj/string.h> 29 #include <pj/assert.h> 30 #include <pj/guid.h> 26 31 #include <pj/log.h> 27 #include <pj/string.h> 28 #include <pj/os.h> 29 #include <pj/guid.h> 30 #include <pj/pool.h> 31 #include <pj/assert.h> 32 33 #if 0 // XXX JUNK 34 /* Initialize TLS ID for transaction lock. */ 35 status = pj_thread_local_alloc(&pjsip_tsx_lock_tls_id); 36 if (status != PJ_SUCCESS) { 37 goto on_error; 38 } 39 pj_thread_local_set(pjsip_tsx_lock_tls_id, NULL); 40 41 42 /* Create hash table for transaction. */ 43 endpt->tsx_table = pj_hash_create( endpt->pool, PJSIP_MAX_TSX_COUNT ); 44 if (!endpt->tsx_table) { 45 status = PJ_ENOMEM; 46 goto on_error; 47 } 48 49 50 /* 51 * Create a new transaction. 52 * Endpoint must then initialize the new transaction as either UAS or UAC, and 53 * register it to the hash table. 54 */ 55 PJ_DEF(pj_status_t) pjsip_endpt_create_tsx(pjsip_endpoint *endpt, 56 pjsip_transaction **p_tsx) 57 { 58 pj_pool_t *pool; 59 60 PJ_ASSERT_RETURN(endpt && p_tsx, PJ_EINVAL); 61 62 PJ_LOG(5, (THIS_FILE, "pjsip_endpt_create_tsx()")); 63 64 /* Request one pool for the transaction. Mutex is locked there. */ 65 pool = pjsip_endpt_create_pool(endpt, "ptsx%p", 66 PJSIP_POOL_LEN_TSX, PJSIP_POOL_INC_TSX); 67 if (pool == NULL) { 68 return PJ_ENOMEM; 69 } 70 71 /* Create the transaction. */ 72 return pjsip_tsx_create(pool, endpt, p_tsx); 73 } 74 75 76 /* 77 * Register the transaction to the endpoint. 78 * This will put the transaction to the transaction hash table. Before calling 79 * this function, the transaction must be INITIALIZED as either UAS or UAC, so 80 * that the transaction key is built. 81 */ 82 PJ_DEF(void) pjsip_endpt_register_tsx( pjsip_endpoint *endpt, 83 pjsip_transaction *tsx) 84 { 85 PJ_LOG(5, (THIS_FILE, "pjsip_endpt_register_tsx(%s)", tsx->obj_name)); 86 87 pj_assert(tsx->transaction_key.slen != 0); 88 //pj_assert(tsx->state != PJSIP_TSX_STATE_NULL); 89 90 /* Lock hash table mutex. */ 91 pj_mutex_lock(endpt->tsx_table_mutex); 92 93 /* Register the transaction to the hash table. */ 94 pj_hash_set( tsx->pool, endpt->tsx_table, tsx->transaction_key.ptr, 95 tsx->transaction_key.slen, tsx); 96 97 /* Unlock mutex. */ 98 pj_mutex_unlock(endpt->tsx_table_mutex); 99 } 100 101 /* 102 * Find transaction by the key. 103 */ 104 PJ_DEF(pjsip_transaction*) pjsip_endpt_find_tsx( pjsip_endpoint *endpt, 105 const pj_str_t *key ) 106 { 107 pjsip_transaction *tsx; 108 109 PJ_LOG(5, (THIS_FILE, "pjsip_endpt_find_tsx()")); 110 111 /* Start lock mutex in the endpoint. */ 112 pj_mutex_lock(endpt->tsx_table_mutex); 113 114 /* Find the transaction in the hash table. */ 115 tsx = pj_hash_get( endpt->tsx_table, key->ptr, key->slen ); 116 117 /* Unlock mutex. */ 118 pj_mutex_unlock(endpt->tsx_table_mutex); 119 120 return tsx; 121 } 122 123 /* 124 * Create key. 125 */ 126 static void rdata_create_key( pjsip_rx_data *rdata) 127 { 128 pjsip_role_e role; 129 if (rdata->msg_info.msg->type == PJSIP_REQUEST_MSG) { 130 role = PJSIP_ROLE_UAS; 131 } else { 132 role = PJSIP_ROLE_UAC; 133 } 134 pjsip_tsx_create_key(rdata->tp_info.pool, &rdata->endpt_info.key, role, 135 &rdata->msg_info.cseq->method, rdata); 136 } 137 138 139 /* 140 * This is the callback that is called by the transport manager when it 141 * receives a message from the network. 142 */ 143 static void endpt_transport_callback( pjsip_endpoint *endpt, 144 pj_status_t status, 145 pjsip_rx_data *rdata ) 146 { 147 pjsip_msg *msg = rdata->msg_info.msg; 148 pjsip_transaction *tsx; 149 pj_bool_t a_new_transaction_just_been_created = PJ_FALSE; 150 151 PJ_LOG(5, (THIS_FILE, "endpt_transport_callback(rdata=%p)", rdata)); 152 153 if (status != PJ_SUCCESS) { 154 const char *src_addr = rdata->pkt_info.src_name; 155 int port = rdata->pkt_info.src_port; 156 PJSIP_ENDPT_LOG_ERROR((endpt, "transport", status, 157 "Src.addr=%s:%d, packet:--\n" 158 "%s\n" 159 "-- end of packet. Error", 160 src_addr, port, rdata->msg_info.msg_buf)); 161 return; 162 } 163 164 /* For response, check that the value in Via sent-by match the transport. 165 * If not matched, silently drop the response. 166 * Ref: RFC3261 Section 18.1.2 Receiving Response 167 */ 168 if (msg->type == PJSIP_RESPONSE_MSG) { 169 const pj_str_t *addr_addr; 170 int port = rdata->msg_info.via->sent_by.port; 171 pj_bool_t mismatch = PJ_FALSE; 172 if (port == 0) { 173 int type; 174 type = rdata->tp_info.transport->key.type; 175 port = pjsip_transport_get_default_port_for_type(type); 176 } 177 addr_addr = &rdata->tp_info.transport->local_name.host; 178 if (pj_strcmp(&rdata->msg_info.via->sent_by.host, addr_addr) != 0) 179 mismatch = PJ_TRUE; 180 else if (port != rdata->tp_info.transport->local_name.port) { 181 /* Port or address mismatch, we should discard response */ 182 /* But we saw one implementation (we don't want to name it to 183 * protect the innocence) which put wrong sent-by port although 184 * the "rport" parameter is correct. 185 * So we discard the response only if the port doesn't match 186 * both the port in sent-by and rport. We try to be lenient here! 187 */ 188 if (rdata->msg_info.via->rport_param != rdata->tp_info.transport->local_name.port) 189 mismatch = PJ_TRUE; 190 else { 191 PJ_LOG(4,(THIS_FILE, "Response %p has mismatch port in sent-by" 192 " but the rport parameter is correct", 193 rdata)); 194 } 195 } 196 197 if (mismatch) { 198 pjsip_event e; 199 200 PJSIP_EVENT_INIT_DISCARD_MSG(e, rdata, PJSIP_EINVALIDVIA); 201 endpt_do_event( endpt, &e ); 202 return; 203 } 204 } 205 206 /* Create key for transaction lookup. */ 207 rdata_create_key( rdata); 208 209 /* Find the transaction for the received message. */ 210 PJ_LOG(5, (THIS_FILE, "finding tsx with key=%.*s", 211 rdata->endpt_info.key.slen, rdata->endpt_info.key.ptr)); 212 213 /* Start lock mutex in the endpoint. */ 214 pj_mutex_lock(endpt->tsx_table_mutex); 215 216 /* Find the transaction in the hash table. */ 217 tsx = pj_hash_get( endpt->tsx_table, rdata->endpt_info.key.ptr, rdata->endpt_info.key.slen ); 218 219 /* Unlock mutex. */ 220 pj_mutex_unlock(endpt->tsx_table_mutex); 221 222 /* If the transaction is not found... */ 223 if (tsx == NULL || tsx->state == PJSIP_TSX_STATE_TERMINATED) { 224 225 /* 226 * For response message, discard the message, except if the response is 227 * an 2xx class response to INVITE, which in this case it must be 228 * passed to TU to be acked. 229 */ 230 if (msg->type == PJSIP_RESPONSE_MSG) { 231 232 /* Inform TU about the 200 message, only if it's INVITE. */ 233 if (PJSIP_IS_STATUS_IN_CLASS(msg->line.status.code, 200) && 234 rdata->msg_info.cseq->method.id == PJSIP_INVITE_METHOD) 235 { 236 pjsip_event e; 237 238 /* Should not happen for UA. Tsx theoritically lives until 239 * all responses are absorbed. 240 */ 241 pj_assert(0); 242 243 PJSIP_EVENT_INIT_RX_200_MSG(e, rdata); 244 endpt_do_event( endpt, &e ); 245 246 } else { 247 /* Just discard the response, inform TU. */ 248 pjsip_event e; 249 250 PJSIP_EVENT_INIT_DISCARD_MSG(e, rdata, 251 PJSIP_ERRNO_FROM_SIP_STATUS(PJSIP_SC_CALL_TSX_DOES_NOT_EXIST)); 252 endpt_do_event( endpt, &e ); 253 } 254 255 /* 256 * For non-ACK request message, create a new transaction. 257 */ 258 } else if (rdata->msg_info.msg->line.req.method.id != PJSIP_ACK_METHOD) { 259 260 pj_status_t status; 261 262 /* Create transaction, mutex is locked there. */ 263 status = pjsip_endpt_create_tsx(endpt, &tsx); 264 if (status != PJ_SUCCESS) { 265 PJSIP_ENDPT_LOG_ERROR((endpt, THIS_FILE, status, 266 "Unable to create transaction")); 267 return; 268 } 269 270 /* Initialize transaction as UAS. */ 271 pjsip_tsx_init_uas( tsx, rdata ); 272 273 /* Register transaction, mutex is locked there. */ 274 pjsip_endpt_register_tsx( endpt, tsx ); 275 276 a_new_transaction_just_been_created = PJ_TRUE; 277 } 278 } 279 280 /* If transaction is found (or newly created), pass the message. 281 * Otherwise if it's an ACK request, pass directly to TU. 282 */ 283 if (tsx && tsx->state != PJSIP_TSX_STATE_TERMINATED) { 284 /* Dispatch message to transaction. */ 285 pjsip_tsx_on_rx_msg( tsx, rdata ); 286 287 } else if (rdata->msg_info.msg->line.req.method.id == PJSIP_ACK_METHOD) { 288 /* 289 * This is an ACK message, but the INVITE transaction could not 290 * be found (possibly because the branch parameter in Via in ACK msg 291 * is different than the branch in original INVITE). This happens with 292 * SER! 293 */ 294 pjsip_event event; 295 296 PJSIP_EVENT_INIT_RX_ACK_MSG(event,rdata); 297 endpt_do_event( endpt, &event ); 298 } 299 300 /* 301 * If a new request message has just been receieved, but no modules 302 * seem to be able to handle the request message, then terminate the 303 * transaction. 304 * 305 * Ideally for cases like "unsupported method", we should be able to 306 * answer the request statelessly. But we can not do that since the 307 * endpoint shoule be able to be used as both user agent and proxy stack, 308 * and a proxy stack should be able to handle arbitrary methods. 309 */ 310 if (a_new_transaction_just_been_created && tsx->status_code < 100) { 311 /* Certainly no modules has sent any response message. 312 * Check that any modules has attached a module data. 313 */ 314 int i; 315 for (i=0; i<PJSIP_MAX_MODULE; ++i) { 316 if (tsx->module_data[i] != NULL) { 317 break; 318 } 319 } 320 if (i == PJSIP_MAX_MODULE) { 321 /* No modules have attached itself to the transaction. 322 * Terminate the transaction with 501/Not Implemented. 323 */ 324 pjsip_tx_data *tdata; 325 pj_status_t status; 326 327 if (tsx->method.id == PJSIP_OPTIONS_METHOD) { 328 status = pjsip_endpt_create_response(endpt, rdata, 200, 329 &tdata); 330 } else { 331 status = pjsip_endpt_create_response(endpt, rdata, 332 PJSIP_SC_METHOD_NOT_ALLOWED, 333 &tdata); 334 } 335 336 if (status != PJ_SUCCESS) { 337 PJSIP_ENDPT_LOG_ERROR((endpt, THIS_FILE, status, 338 "Unable to create response")); 339 return; 340 } 341 342 if (endpt->allow_hdr) { 343 pjsip_msg_add_hdr( tdata->msg, 344 pjsip_hdr_shallow_clone(tdata->pool, endpt->allow_hdr)); 345 } 346 pjsip_tsx_on_tx_msg( tsx, tdata ); 347 348 } else { 349 /* 350 * If a module has registered itself in the transaction but it 351 * hasn't responded the request, chances are the module wouldn't 352 * respond to the request at all. We terminate the request here 353 * with 500/Internal Server Error, to be safe. 354 */ 355 pjsip_tx_data *tdata; 356 pj_status_t status; 357 358 status = pjsip_endpt_create_response(endpt, rdata, 500, &tdata); 359 if (status != PJ_SUCCESS) { 360 PJSIP_ENDPT_LOG_ERROR((endpt, THIS_FILE, status, 361 "Unable to create response")); 362 return; 363 } 364 365 pjsip_tsx_on_tx_msg(tsx, tdata); 366 } 367 } 368 } 369 370 371 372 /* Transaction tables. */ 373 count = pj_hash_count(endpt->tsx_table); 374 PJ_LOG(3, (THIS_FILE, " Number of transactions: %u", count)); 375 376 if (count && detail) { 377 pj_hash_iterator_t it_val; 378 pj_hash_iterator_t *it; 379 pj_time_val now; 380 381 PJ_LOG(3, (THIS_FILE, " Dumping transaction tables:")); 382 383 pj_gettimeofday(&now); 384 it = pj_hash_first(endpt->tsx_table, &it_val); 385 386 while (it != NULL) { 387 int timeout_diff; 388 389 /* Get the transaction. No need to lock transaction's mutex 390 * since we already hold endpoint mutex, so that no transactions 391 * will be deleted. 392 */ 393 pjsip_transaction *tsx = pj_hash_this(endpt->tsx_table, it); 394 395 const char *role = (tsx->role == PJSIP_ROLE_UAS ? "UAS" : "UAC"); 396 397 if (tsx->timeout_timer._timer_id != -1) { 398 if (tsx->timeout_timer._timer_value.sec > now.sec) { 399 timeout_diff = tsx->timeout_timer._timer_value.sec - now.sec; 400 } else { 401 timeout_diff = now.sec - tsx->timeout_timer._timer_value.sec; 402 timeout_diff = 0 - timeout_diff; 403 } 404 } else { 405 timeout_diff = -1; 406 } 407 408 PJ_LOG(3, (THIS_FILE, " %s %s %10.*s %.9u %s t=%ds", 409 tsx->obj_name, role, 410 tsx->method.name.slen, tsx->method.name.ptr, 411 tsx->cseq, 412 pjsip_tsx_state_str(tsx->state), 413 timeout_diff)); 414 415 it = pj_hash_next(endpt->tsx_table, it); 416 } 417 } 418 419 420 421 #endif // XXX JUNK 422 423 /* Thread Local Storage ID for transaction lock (initialized by endpoint) */ 424 long pjsip_tsx_lock_tls_id; 425 426 /* State names */ 32 33 /***************************************************************************** 34 ** 35 ** Declarations and static variable definitions section. 36 ** 37 ***************************************************************************** 38 39 /* Prototypes. */ 40 static pj_status_t mod_tsx_layer_load(pjsip_endpoint *endpt); 41 static pj_status_t mod_tsx_layer_start(void); 42 static pj_status_t mod_tsx_layer_stop(void); 43 static pj_status_t mod_tsx_layer_unload(void); 44 static pj_bool_t mod_tsx_layer_on_rx_request(pjsip_rx_data *rdata); 45 static pj_bool_t mod_tsx_layer_on_rx_response(pjsip_rx_data *rdata); 46 47 /* Transaction layer module definition. */ 48 static struct mod_tsx_layer 49 { 50 struct pjsip_module mod; 51 pj_pool_t *pool; 52 pjsip_endpoint *endpt; 53 pj_mutex_t *mutex; 54 pj_hash_table_t *htable; 55 } mod_tsx_layer = 56 { { 57 NULL, NULL, /* List's prev and next. */ 58 { "mod-tsx-layer", 13 }, /* Module name. */ 59 -1, /* Module ID */ 60 PJSIP_MOD_PRIORITY_TSX_LAYER, /* Priority. */ 61 NULL, /* User_data. */ 62 0, /* Methods count. */ 63 { NULL }, /* Array of methods. */ 64 mod_tsx_layer_load, /* load(). */ 65 mod_tsx_layer_start, /* start() */ 66 mod_tsx_layer_stop, /* stop() */ 67 mod_tsx_layer_unload, /* unload() */ 68 mod_tsx_layer_on_rx_request, /* on_rx_request() */ 69 mod_tsx_layer_on_rx_response, /* on_rx_response() */ 70 NULL 71 } 72 }; 73 74 /* Thread Local Storage ID for transaction lock */ 75 static long pjsip_tsx_lock_tls_id; 76 77 /* Transaction state names */ 427 78 static const char *state_str[] = 428 79 { … … 440 91 static const char *role_name[] = 441 92 { 442 "Client", 443 "Server" 93 "UAC", 94 "UAS" 95 }; 96 97 /* Transport flag. */ 98 enum 99 { 100 TSX_HAS_PENDING_TRANSPORT = 1, 101 TSX_HAS_PENDING_RESCHED = 2, 102 TSX_HAS_PENDING_SEND = 4, 103 TSX_HAS_PENDING_DESTROY = 8, 444 104 }; 445 105 … … 469 129 }; 470 130 471 /* Function Prototypes */ 472 static pj_status_t pjsip_tsx_on_state_null( pjsip_transaction *tsx, 131 132 /* Prototypes. */ 133 static void lock_tsx(pjsip_transaction *tsx, struct tsx_lock_data *lck); 134 static pj_status_t unlock_tsx( pjsip_transaction *tsx, 135 struct tsx_lock_data *lck); 136 static pj_status_t tsx_on_state_null( pjsip_transaction *tsx, 473 137 pjsip_event *event); 474 static pj_status_t pjsip_tsx_on_state_calling(pjsip_transaction *tsx,138 static pj_status_t tsx_on_state_calling( pjsip_transaction *tsx, 475 139 pjsip_event *event); 476 static pj_status_t pjsip_tsx_on_state_trying(pjsip_transaction *tsx,140 static pj_status_t tsx_on_state_trying( pjsip_transaction *tsx, 477 141 pjsip_event *event); 478 static pj_status_t pjsip_tsx_on_state_proceeding_uas( pjsip_transaction *tsx,142 static pj_status_t tsx_on_state_proceeding_uas( pjsip_transaction *tsx, 479 143 pjsip_event *event); 480 static pj_status_t pjsip_tsx_on_state_proceeding_uac( pjsip_transaction *tsx,144 static pj_status_t tsx_on_state_proceeding_uac( pjsip_transaction *tsx, 481 145 pjsip_event *event); 482 static pj_status_t pjsip_tsx_on_state_completed_uas(pjsip_transaction *tsx,146 static pj_status_t tsx_on_state_completed_uas( pjsip_transaction *tsx, 483 147 pjsip_event *event); 484 static pj_status_t pjsip_tsx_on_state_completed_uac(pjsip_transaction *tsx,148 static pj_status_t tsx_on_state_completed_uac( pjsip_transaction *tsx, 485 149 pjsip_event *event); 486 static pj_status_t pjsip_tsx_on_state_confirmed(pjsip_transaction *tsx,150 static pj_status_t tsx_on_state_confirmed( pjsip_transaction *tsx, 487 151 pjsip_event *event); 488 static pj_status_t pjsip_tsx_on_state_terminated(pjsip_transaction *tsx,152 static pj_status_t tsx_on_state_terminated( pjsip_transaction *tsx, 489 153 pjsip_event *event); 490 static pj_status_t pjsip_tsx_on_state_destroyed(pjsip_transaction *tsx,154 static pj_status_t tsx_on_state_destroyed( pjsip_transaction *tsx, 491 155 pjsip_event *event); 492 493 static void tsx_timer_callback( pj_timer_heap_t *theap, 494 pj_timer_entry *entry); 495 static int tsx_send_msg( pjsip_transaction *tsx, 496 pjsip_tx_data *tdata); 497 static void lock_tsx( pjsip_transaction *tsx, struct 498 tsx_lock_data *lck ); 499 static pj_status_t unlock_tsx( pjsip_transaction *tsx, 500 struct tsx_lock_data *lck ); 156 static void tsx_timer_callback( pj_timer_heap_t *theap, 157 pj_timer_entry *entry); 158 static pj_status_t tsx_create( pjsip_module *tsx_user, 159 pjsip_transaction **p_tsx); 160 static void tsx_destroy( pjsip_transaction *tsx ); 161 static void tsx_resched_retransmission( pjsip_transaction *tsx ); 162 static pj_status_t tsx_retransmit( pjsip_transaction *tsx, int resched); 163 static int tsx_send_msg( pjsip_transaction *tsx, 164 pjsip_tx_data *tdata); 165 static void tsx_on_rx_msg( pjsip_transaction *tsx, 166 pjsip_rx_data *rdata ); 167 501 168 502 169 /* State handlers for UAC, indexed by state */ … … 504 171 pjsip_event *) = 505 172 { 506 & pjsip_tsx_on_state_null,507 & pjsip_tsx_on_state_calling,508 &pjsip_tsx_on_state_trying,509 & pjsip_tsx_on_state_proceeding_uac,510 & pjsip_tsx_on_state_completed_uac,511 & pjsip_tsx_on_state_confirmed,512 & pjsip_tsx_on_state_terminated,513 & pjsip_tsx_on_state_destroyed,173 &tsx_on_state_null, 174 &tsx_on_state_calling, 175 NULL, 176 &tsx_on_state_proceeding_uac, 177 &tsx_on_state_completed_uac, 178 &tsx_on_state_confirmed, 179 &tsx_on_state_terminated, 180 &tsx_on_state_destroyed, 514 181 }; 515 182 … … 518 185 pjsip_event *) = 519 186 { 520 & pjsip_tsx_on_state_null,521 &pjsip_tsx_on_state_calling,522 & pjsip_tsx_on_state_trying,523 & pjsip_tsx_on_state_proceeding_uas,524 & pjsip_tsx_on_state_completed_uas,525 & pjsip_tsx_on_state_confirmed,526 & pjsip_tsx_on_state_terminated,527 & pjsip_tsx_on_state_destroyed,187 &tsx_on_state_null, 188 NULL, 189 &tsx_on_state_trying, 190 &tsx_on_state_proceeding_uas, 191 &tsx_on_state_completed_uas, 192 &tsx_on_state_confirmed, 193 &tsx_on_state_terminated, 194 &tsx_on_state_destroyed, 528 195 }; 529 196 197 /***************************************************************************** 198 ** 199 ** Utilities 200 ** 201 ***************************************************************************** 202 */ 530 203 /* 531 204 * Get transaction state name. … … 543 216 return role_name[role]; 544 217 } 545 546 547 548 /*549 * Unregister the transaction from the hash table, and destroy the resources550 * from the transaction.551 */552 PJ_DEF(void) pjsip_endpt_destroy_tsx( pjsip_endpoint *endpt,553 pjsip_transaction *tsx)554 {555 PJ_LOG(5, (THIS_FILE, "pjsip_endpt_destroy_tsx(%s)", tsx->obj_name));556 557 pj_assert(tsx->state == PJSIP_TSX_STATE_DESTROYED);558 559 /* No need to lock transaction.560 * This function typically is called from the transaction callback, which561 * means that transaction mutex is being held.562 */563 pj_assert( pj_mutex_is_locked(tsx->mutex) );564 565 /* Lock endpoint. */566 pj_mutex_lock( endpt->tsx_table_mutex );567 568 /* Unregister from the hash table. */569 pj_hash_set( NULL, endpt->tsx_table, tsx->transaction_key.ptr,570 tsx->transaction_key.slen, NULL);571 572 /* Unlock endpoint mutex. */573 pj_mutex_unlock( endpt->tsx_table_mutex );574 575 /* Destroy transaction mutex. */576 pj_mutex_destroy( tsx->mutex );577 578 /* Release the pool for the transaction. */579 pj_pool_release(tsx->pool);580 581 PJ_LOG(4, (THIS_FILE, "tsx%p destroyed", tsx));582 }583 584 218 585 219 … … 644 278 *p++ = SEPARATOR; 645 279 646 /* Add Request-URI */647 /* This is BUG!648 * Response doesn't have Request-URI!649 *650 len = req_uri->vptr->print( PJSIP_URI_IN_REQ_URI, req_uri, p, end-p );651 p += len;652 *p++ = SEPARATOR;653 */654 655 280 /* Add method, except when method is INVITE or ACK. */ 656 281 if (method->id != PJSIP_INVITE_METHOD && method->id != PJSIP_ACK_METHOD) { … … 771 396 } 772 397 773 774 /* 775 * Create new transaction. 776 */ 777 PJ_DEF(pj_status_t) pjsip_tsx_create( pj_pool_t *pool, 778 pjsip_endpoint *endpt, 779 pjsip_transaction **p_tsx) 780 { 398 /***************************************************************************** 399 ** 400 ** Transaction layer module 401 ** 402 ***************************************************************************** 403 404 /* 405 * Create transaction layer module and registers it to the endpoint. 406 */ 407 PJ_DEF(pj_status_t) pjsip_tsx_layer_init(pjsip_endpoint *endpt) 408 { 409 pj_pool_t *pool; 410 pj_status_t status; 411 412 413 PJ_ASSERT_RETURN(mod_tsx_layer.endpt==NULL, PJ_EINVALIDOP); 414 415 416 /* Initialize TLS ID for transaction lock. */ 417 status = pj_thread_local_alloc(&pjsip_tsx_lock_tls_id); 418 if (status != PJ_SUCCESS) 419 return status; 420 421 pj_thread_local_set(pjsip_tsx_lock_tls_id, NULL); 422 423 /* 424 * Initialize transaction layer structure. 425 */ 426 427 /* Create pool for the module. */ 428 pool = pjsip_endpt_create_pool(endpt, "tsxlayer", 429 PJSIP_POOL_TSX_LAYER_LEN, 430 PJSIP_POOL_TSX_LAYER_INC ); 431 if (!pool) 432 return PJ_ENOMEM; 433 434 435 /* Initialize some attributes. */ 436 mod_tsx_layer.pool = pool; 437 mod_tsx_layer.endpt = endpt; 438 439 440 /* Create hash table. */ 441 mod_tsx_layer.htable = pj_hash_create( pool, PJSIP_MAX_TSX_COUNT ); 442 if (!mod_tsx_layer.htable) { 443 pjsip_endpt_release_pool(endpt, pool); 444 return PJ_ENOMEM; 445 } 446 447 /* Create mutex. */ 448 status = pj_mutex_create_recursive(pool, "tsxlayer", &mod_tsx_layer.mutex); 449 if (status != PJ_SUCCESS) { 450 pjsip_endpt_release_pool(endpt, pool); 451 return status; 452 } 453 454 /* 455 * Register transaction layer module to endpoint. 456 */ 457 status = pjsip_endpt_register_module( endpt, &mod_tsx_layer.mod ); 458 if (status != PJ_SUCCESS) { 459 pj_mutex_destroy(mod_tsx_layer.mutex); 460 pjsip_endpt_release_pool(endpt, pool); 461 return status; 462 } 463 464 return PJ_SUCCESS; 465 } 466 467 468 /* 469 * Get the instance of transaction layer module. 470 */ 471 PJ_DEF(pjsip_module*) pjsip_tsx_layer_instance(void) 472 { 473 return &mod_tsx_layer.mod; 474 } 475 476 477 /* 478 * Unregister and destroy transaction layer module. 479 */ 480 PJ_DEF(pj_status_t) pjsip_tsx_layer_destroy(void) 481 { 482 /* Are we registered? */ 483 PJ_ASSERT_RETURN(mod_tsx_layer.endpt!=NULL, PJ_EINVALIDOP); 484 485 /* Unregister from endpoint. 486 * Clean-ups will be done in the unload() module callback. 487 */ 488 return pjsip_endpt_unregister_module( mod_tsx_layer.endpt, 489 &mod_tsx_layer.mod); 490 } 491 492 493 /* 494 * Register the transaction to the hash table. 495 */ 496 static void mod_tsx_layer_register_tsx( pjsip_transaction *tsx) 497 { 498 pj_assert(tsx->transaction_key.slen != 0); 499 //pj_assert(tsx->state != PJSIP_TSX_STATE_NULL); 500 501 /* Lock hash table mutex. */ 502 pj_mutex_lock(mod_tsx_layer.mutex); 503 504 /* Register the transaction to the hash table. */ 505 pj_hash_set( tsx->pool, mod_tsx_layer.htable, tsx->transaction_key.ptr, 506 tsx->transaction_key.slen, tsx); 507 508 /* Unlock mutex. */ 509 pj_mutex_unlock(mod_tsx_layer.mutex); 510 } 511 512 513 /* 514 * Unregister the transaction from the hash table. 515 */ 516 static void mod_tsx_layer_unregister_tsx( pjsip_transaction *tsx) 517 { 518 pj_assert(tsx->transaction_key.slen != 0); 519 //pj_assert(tsx->state != PJSIP_TSX_STATE_NULL); 520 521 /* Lock hash table mutex. */ 522 pj_mutex_lock(mod_tsx_layer.mutex); 523 524 /* Register the transaction to the hash table. */ 525 pj_hash_set( NULL, mod_tsx_layer.htable, tsx->transaction_key.ptr, 526 tsx->transaction_key.slen, NULL); 527 528 /* Unlock mutex. */ 529 pj_mutex_unlock(mod_tsx_layer.mutex); 530 } 531 532 533 /* 534 * Find a transaction. 535 */ 536 PJ_DEF(pjsip_transaction*) pjsip_tsx_layer_find_tsx( const pj_str_t *key, 537 pj_bool_t lock ) 538 { 539 pjsip_transaction *tsx; 540 541 pj_mutex_lock(mod_tsx_layer.mutex); 542 tsx = pj_hash_get( mod_tsx_layer.htable, key->ptr, key->slen ); 543 pj_mutex_unlock(mod_tsx_layer.mutex); 544 545 546 /* Race condition! 547 * Transaction may gets deleted before we have chance to lock it. 548 */ 549 PJ_TODO(FIX_RACE_CONDITION_HERE); 550 if (tsx && lock) 551 pj_mutex_lock(tsx->mutex); 552 553 return tsx; 554 } 555 556 557 /* This module callback is called when module is being loaded by 558 * endpoint. It does nothing for this module. 559 */ 560 static pj_status_t mod_tsx_layer_load(pjsip_endpoint *endpt) 561 { 562 PJ_UNUSED_ARG(endpt); 563 return PJ_SUCCESS; 564 } 565 566 567 /* This module callback is called when module is being started by 568 * endpoint. It does nothing for this module. 569 */ 570 static pj_status_t mod_tsx_layer_start(void) 571 { 572 return PJ_SUCCESS; 573 } 574 575 576 /* This module callback is called when module is being stopped by 577 * endpoint. 578 */ 579 static pj_status_t mod_tsx_layer_stop(void) 580 { 581 pj_hash_iterator_t it_buf, *it; 582 583 pj_mutex_lock(mod_tsx_layer.mutex); 584 585 /* Destroy all transactions. */ 586 it = pj_hash_first(mod_tsx_layer.htable, &it_buf); 587 while (it) { 588 pjsip_transaction *tsx = pj_hash_this(mod_tsx_layer.htable, it); 589 if (tsx) 590 tsx_destroy(tsx); 591 it = pj_hash_next(mod_tsx_layer.htable, it); 592 } 593 594 pj_mutex_unlock(mod_tsx_layer.mutex); 595 return PJ_SUCCESS; 596 } 597 598 599 /* This module callback is called when module is being unloaded by 600 * endpoint. 601 */ 602 static pj_status_t mod_tsx_layer_unload(void) 603 { 604 /* Destroy mutex. */ 605 pj_mutex_destroy(mod_tsx_layer.mutex); 606 607 /* Release pool. */ 608 pjsip_endpt_release_pool(mod_tsx_layer.endpt, mod_tsx_layer.pool); 609 610 /* Mark as unregistered. */ 611 mod_tsx_layer.endpt = NULL; 612 613 return PJ_SUCCESS; 614 } 615 616 617 /* This module callback is called when endpoint has received an 618 * incoming request message. 619 */ 620 static pj_bool_t mod_tsx_layer_on_rx_request(pjsip_rx_data *rdata) 621 { 622 pj_str_t key; 623 pjsip_transaction *tsx; 624 625 pjsip_tsx_create_key(rdata->tp_info.pool, &key, PJSIP_ROLE_UAS, 626 &rdata->msg_info.cseq->method, rdata); 627 628 /* Find transaction. */ 629 pj_mutex_lock( mod_tsx_layer.mutex ); 630 tsx = pj_hash_get( mod_tsx_layer.htable, key.ptr, key.slen ); 631 if (tsx == NULL || tsx->state == PJSIP_TSX_STATE_TERMINATED) { 632 /* Transaction not found. 633 * Reject the request so that endpoint passes the request to 634 * upper layer modules. 635 */ 636 pj_mutex_unlock( mod_tsx_layer.mutex); 637 return PJ_FALSE; 638 } 639 640 /* Unlock hash table. */ 641 pj_mutex_unlock( mod_tsx_layer.mutex ); 642 643 /* Race condition! 644 * Transaction may gets deleted before we have chance to lock it 645 * in tsx_on_rx_msg(). 646 */ 647 PJ_TODO(FIX_RACE_CONDITION_HERE); 648 649 /* Pass the message to the transaction. */ 650 tsx_on_rx_msg(tsx, rdata ); 651 652 return PJ_TRUE; 653 } 654 655 656 /* This module callback is called when endpoint has received an 657 * incoming response message. 658 */ 659 static pj_bool_t mod_tsx_layer_on_rx_response(pjsip_rx_data *rdata) 660 { 661 pj_str_t key; 662 pjsip_transaction *tsx; 663 664 pjsip_tsx_create_key(rdata->tp_info.pool, &key, PJSIP_ROLE_UAC, 665 &rdata->msg_info.cseq->method, rdata); 666 667 /* Find transaction. */ 668 pj_mutex_lock( mod_tsx_layer.mutex ); 669 tsx = pj_hash_get( mod_tsx_layer.htable, key.ptr, key.slen ); 670 if (tsx == NULL || tsx->state == PJSIP_TSX_STATE_TERMINATED) { 671 /* Transaction not found. 672 * Reject the request so that endpoint passes the request to 673 * upper layer modules. 674 */ 675 pj_mutex_unlock( mod_tsx_layer.mutex); 676 return PJ_FALSE; 677 } 678 679 /* Unlock hash table. */ 680 pj_mutex_unlock( mod_tsx_layer.mutex ); 681 682 /* Race condition! 683 * Transaction may gets deleted before we have chance to lock it 684 * in tsx_on_rx_msg(). 685 */ 686 PJ_TODO(FIX_RACE_CONDITION_HERE); 687 688 /* Pass the message to the transaction. */ 689 tsx_on_rx_msg(tsx, rdata ); 690 691 return PJ_TRUE; 692 } 693 694 695 /* 696 * Get transaction instance in the rdata. 697 */ 698 PJ_DEF(pjsip_transaction*) pjsip_rdata_get_tsx( pjsip_rx_data *rdata ) 699 { 700 return rdata->endpt_info.mod_data[mod_tsx_layer.mod.id]; 701 } 702 703 704 /***************************************************************************** 705 ** 706 ** Transaction 707 ** 708 ***************************************************************************** 709 710 /* 711 * Lock transaction and set the value of Thread Local Storage. 712 */ 713 static void lock_tsx(pjsip_transaction *tsx, struct tsx_lock_data *lck) 714 { 715 struct tsx_lock_data *prev_data; 716 717 pj_mutex_lock(tsx->mutex); 718 prev_data = (struct tsx_lock_data *) 719 pj_thread_local_get(pjsip_tsx_lock_tls_id); 720 lck->prev = prev_data; 721 lck->tsx = tsx; 722 lck->is_alive = 1; 723 pj_thread_local_set(pjsip_tsx_lock_tls_id, lck); 724 } 725 726 727 /* 728 * Unlock transaction. 729 * This will selectively unlock the mutex ONLY IF the transaction has not been 730 * destroyed. The function knows whether the transaction has been destroyed 731 * because when transaction is destroyed the is_alive flag for the transaction 732 * will be set to zero. 733 */ 734 static pj_status_t unlock_tsx( pjsip_transaction *tsx, 735 struct tsx_lock_data *lck) 736 { 737 pj_assert( (void*)pj_thread_local_get(pjsip_tsx_lock_tls_id) == lck); 738 pj_assert( lck->tsx == tsx ); 739 pj_thread_local_set(pjsip_tsx_lock_tls_id, lck->prev); 740 if (lck->is_alive) 741 pj_mutex_unlock(tsx->mutex); 742 743 return lck->is_alive ? PJ_SUCCESS : PJSIP_ETSXDESTROYED; 744 } 745 746 747 /* Create and initialize basic transaction structure. 748 * This function is called by both UAC and UAS creation. 749 */ 750 static pj_status_t tsx_create( pjsip_module *tsx_user, 751 pjsip_transaction **p_tsx) 752 { 753 pj_pool_t *pool; 781 754 pjsip_transaction *tsx; 782 755 pj_status_t status; 783 756 784 tsx = pj_pool_calloc(pool, 1, sizeof(pjsip_transaction)); 785 757 pool = pjsip_endpt_create_pool( mod_tsx_layer.endpt, "tsx", 758 PJSIP_POOL_TSX_LEN, PJSIP_POOL_TSX_INC ); 759 if (!pool) 760 return PJ_ENOMEM; 761 762 tsx = pj_pool_zalloc(pool, sizeof(pjsip_transaction)); 786 763 tsx->pool = pool; 787 tsx->endpt = endpt; 764 tsx->tsx_user = tsx_user; 765 tsx->endpt = mod_tsx_layer.endpt; 766 767 pj_sprintf(tsx->obj_name, "tsx%p", tsx); 768 769 tsx->handle_200resp = 1; 788 770 tsx->retransmit_timer.id = TSX_TIMER_RETRANSMISSION; 789 771 tsx->retransmit_timer._timer_id = -1; … … 794 776 tsx->timeout_timer.user_data = tsx; 795 777 tsx->timeout_timer.cb = &tsx_timer_callback; 796 pj_sprintf(tsx->obj_name, "tsx%p", tsx);797 status = pj_mutex_create_recursive(pool, " mtsx%p", &tsx->mutex);778 779 status = pj_mutex_create_recursive(pool, "tsx%p", &tsx->mutex); 798 780 if (status != PJ_SUCCESS) { 781 pjsip_endpt_release_pool(mod_tsx_layer.endpt, pool); 799 782 return status; 800 783 } … … 804 787 } 805 788 806 /* 807 * Lock transaction and set the value of Thread Local Storage. 808 */ 809 static void lock_tsx(pjsip_transaction *tsx, struct tsx_lock_data *lck) 810 { 811 struct tsx_lock_data *prev_data; 812 813 pj_mutex_lock(tsx->mutex); 814 prev_data = (struct tsx_lock_data *) 815 pj_thread_local_get(pjsip_tsx_lock_tls_id); 816 lck->prev = prev_data; 817 lck->tsx = tsx; 818 lck->is_alive = 1; 819 pj_thread_local_set(pjsip_tsx_lock_tls_id, lck); 820 } 821 822 823 /* 824 * Unlock transaction. 825 * This will selectively unlock the mutex ONLY IF the transaction has not been 826 * destroyed. The function knows whether the transaction has been destroyed 827 * because when transaction is destroyed the is_alive flag for the transaction 828 * will be set to zero. 829 */ 830 static pj_status_t unlock_tsx( pjsip_transaction *tsx, 831 struct tsx_lock_data *lck) 832 { 833 pj_assert( (void*)pj_thread_local_get(pjsip_tsx_lock_tls_id) == lck); 834 pj_assert( lck->tsx == tsx ); 835 pj_thread_local_set(pjsip_tsx_lock_tls_id, lck->prev); 836 if (lck->is_alive) 837 pj_mutex_unlock(tsx->mutex); 838 839 return lck->is_alive ? PJ_SUCCESS : PJSIP_ETSXDESTROYED; 840 } 789 790 /* Destroy transaction. */ 791 static void tsx_destroy( pjsip_transaction *tsx ) 792 { 793 pj_mutex_destroy(tsx->mutex); 794 pjsip_endpt_release_pool(tsx->endpt, tsx->pool); 795 } 796 797 798 /* 799 * Callback when timer expires. 800 */ 801 static void tsx_timer_callback( pj_timer_heap_t *theap, pj_timer_entry *entry) 802 { 803 pjsip_event event; 804 pjsip_transaction *tsx = entry->user_data; 805 struct tsx_lock_data lck; 806 807 PJ_UNUSED_ARG(theap); 808 809 PJ_LOG(5,(tsx->obj_name, "got timer event (%s timer)", 810 (entry->id==TSX_TIMER_RETRANSMISSION ? "Retransmit":"Timeout"))); 811 812 813 if (entry->id == TSX_TIMER_RETRANSMISSION) { 814 PJSIP_EVENT_INIT_TIMER(event, &tsx->retransmit_timer); 815 } else { 816 PJSIP_EVENT_INIT_TIMER(event, &tsx->timeout_timer); 817 } 818 819 /* Dispatch event to transaction. */ 820 lock_tsx(tsx, &lck); 821 (*tsx->state_handler)(tsx, &event); 822 unlock_tsx(tsx, &lck); 823 } 824 841 825 842 826 /* … … 848 832 void *event_src ) 849 833 { 850 pjsip_event e;851 852 834 PJ_LOG(4, (tsx->obj_name, "STATE %s-->%s, cause = %s", 853 835 state_str[tsx->state], state_str[state], … … 865 847 866 848 /* Inform TU */ 867 PJSIP_EVENT_INIT_TSX_STATE(e, tsx, event_src_type, event_src); 868 pjsip_endpt_send_tsx_event( tsx->endpt, &e ); 849 if (tsx->tsx_user && tsx->tsx_user->on_tsx_state) { 850 pjsip_event e; 851 PJSIP_EVENT_INIT_TSX_STATE(e, tsx, event_src_type, event_src); 852 (*tsx->tsx_user->on_tsx_state)(tsx, &e); 853 } 854 869 855 870 856 /* When the transaction is terminated, release transport, and free the … … 872 858 */ 873 859 if (state == PJSIP_TSX_STATE_TERMINATED) { 860 pj_time_val timeout = {0, 0}; 874 861 875 862 /* Decrement transport reference counter. */ 876 if (tsx->transport && 877 tsx->transport_state == PJSIP_TSX_TRANSPORT_STATE_FINAL) 878 { 863 if (tsx->transport) { 879 864 pjsip_transport_dec_ref( tsx->transport ); 880 865 tsx->transport = NULL; … … 896 881 } 897 882 898 /* If transport is not pending, reschedule timeout timer to 899 * destroy this transaction. 900 */ 901 if (tsx->transport_state == PJSIP_TSX_TRANSPORT_STATE_FINAL) { 902 pj_time_val timeout = {0, 0}; 883 /* Reschedule timeout timer to destroy this transaction. */ 884 if (tsx->transport_flag & TSX_HAS_PENDING_TRANSPORT) { 885 tsx->transport_flag |= TSX_HAS_PENDING_DESTROY; 886 } else { 903 887 pjsip_endpt_schedule_timer( tsx->endpt, &tsx->timeout_timer, 904 888 &timeout); 905 889 } 890 906 891 907 892 } else if (state == PJSIP_TSX_STATE_DESTROYED) { … … 915 900 lck = lck->prev; 916 901 } 917 } 918 } 919 920 /* 921 * Look-up destination address and select which transport to be used to send 922 * the request message. The procedure used here follows the guidelines on 923 * sending the request in RFC3261 chapter 8.1.2. 924 * 925 * This function also modifies the message (request line and Route headers) 926 * accordingly. 927 */ 928 static pj_status_t tsx_process_route( pjsip_transaction *tsx, 929 pjsip_tx_data *tdata, 930 pjsip_host_info *send_addr ) 931 { 932 pjsip_route_hdr *route_hdr; 933 934 pj_assert(tdata->msg->type == PJSIP_REQUEST_MSG); 935 936 /* Get the first "Route" header from the message. If the message doesn't 937 * have any "Route" headers but the endpoint has, then copy the "Route" 938 * headers from the endpoint first. 939 */ 940 route_hdr = pjsip_msg_find_hdr(tdata->msg, PJSIP_H_ROUTE, NULL); 941 if (!route_hdr) { 942 const pjsip_route_hdr *hdr_list; 943 const pjsip_route_hdr *hdr; 944 hdr_list = (const pjsip_route_hdr*)pjsip_endpt_get_routing(tsx->endpt); 945 hdr = hdr_list->next; 946 while (hdr != hdr_list { 947 route_hdr = pjsip_hdr_shallow_clone(tdata->pool, hdr); 948 pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)route_hdr); 949 hdr = hdr->next; 950 } 951 } 952 953 return pjsip_get_request_addr(tdata, send_addr); 954 } 955 956 957 /* 958 * Callback from the transport job. 959 * This callback is called when asychronous transport connect() operation 960 * has completed, with or without error. 961 */ 962 static void tsx_transport_callback(pjsip_transport *tr, 963 void *token, 964 pj_status_t status) 965 { 966 char addr[PJ_MAX_HOSTNAME]; 967 pjsip_transaction *tsx = token; 968 struct tsx_lock_data lck; 969 970 pj_memcpy(addr, tsx->dest_name.addr.host.ptr, tsx->dest_name.addr.host.slen); 971 addr[tsx->dest_name.addr.host.slen] = '\0'; 972 973 974 if (status == PJ_SUCCESS) { 975 PJ_LOG(4, (tsx->obj_name, "%s connected to %s:%d", 976 tr->type_name, 977 addr, tsx->dest_name.addr.port)); 978 } else { 979 PJ_LOG(4, (tsx->obj_name, "%s unable to connect to %s:%d, status=%d", 980 tr->type_name, 981 addr, tsx->dest_name.addr.port, status)); 982 } 983 984 /* Lock transaction. */ 985 lock_tsx(tsx, &lck); 986 987 if (status != PJ_SUCCESS) { 988 tsx->transport_state = PJSIP_TSX_TRANSPORT_STATE_FINAL; 989 tsx->status_code = PJSIP_SC_TSX_TRANSPORT_ERROR; 990 991 tsx_set_state(tsx, PJSIP_TSX_STATE_TERMINATED, 992 PJSIP_EVENT_TRANSPORT_ERROR, (void*)status); 993 994 /* Unlock transaction. */ 995 unlock_tsx(tsx, &lck); 996 return; 997 } 998 999 /* See if transaction has already been terminated. 1000 * If so, schedule to destroy the transaction. 1001 */ 1002 if (tsx->state == PJSIP_TSX_STATE_TERMINATED) { 1003 pj_time_val timeout = {0, 0}; 1004 pjsip_endpt_schedule_timer( tsx->endpt, &tsx->timeout_timer, 1005 &timeout); 1006 1007 /* Unlock transaction. */ 1008 unlock_tsx(tsx, &lck); 1009 return; 1010 } 1011 1012 /* Add reference counter to the transport. */ 1013 pjsip_transport_add_ref(tr); 1014 1015 /* Mark transport as ready. */ 1016 tsx->transport_state = PJSIP_TSX_TRANSPORT_STATE_FINAL; 1017 tsx->transport = tr; 1018 1019 /* If there's a pending message to send, send it now. */ 1020 if (tsx->has_unsent_msg) { 1021 tsx_send_msg( tsx, tsx->last_tx ); 1022 } 1023 1024 /* Unlock transaction. */ 1025 unlock_tsx(tsx, &lck); 1026 } 1027 1028 /* 1029 * Callback from the resolver job. 1030 */ 1031 static void tsx_resolver_callback(pj_status_t status, 1032 void *token, 1033 const struct pjsip_server_addresses *addr) 1034 { 1035 pjsip_transaction *tsx = token; 1036 struct tsx_lock_data lck; 1037 pjsip_transport *tp; 1038 1039 PJ_LOG(4, (tsx->obj_name, "resolver job complete, status=%d", status)); 1040 1041 if (status != PJ_SUCCESS || addr->count == 0) { 1042 lock_tsx(tsx, &lck); 1043 tsx->status_code = PJSIP_SC_TSX_RESOLVE_ERROR; 1044 tsx_set_state(tsx, PJSIP_TSX_STATE_TERMINATED, 1045 PJSIP_EVENT_TRANSPORT_ERROR, (void*)status); 1046 unlock_tsx(tsx, &lck); 1047 return; 1048 } 1049 1050 /* Lock transaction. */ 1051 lock_tsx(tsx, &lck); 1052 1053 /* Copy server addresses. */ 1054 pj_memcpy(&tsx->remote_addr, addr, sizeof(*addr)); 1055 1056 /* Create/find the transport for the remote address. */ 1057 tsx->transport_state = PJSIP_TSX_TRANSPORT_STATE_CONNECTING; 1058 status = pjsip_endpt_alloc_transport( tsx->endpt, addr->entry[0].type, 1059 &addr->entry[0].addr, 1060 addr->entry[0].addr_len, 1061 &tp); 1062 tsx_transport_callback(tp, tsx, status); 1063 1064 /* Unlock transaction */ 1065 unlock_tsx(tsx, &lck); 1066 1067 /* There should be nothing to do after this point. 1068 * Execution for the transaction will resume when the callback for the 1069 * transport is called. 1070 */ 1071 } 1072 1073 /* 1074 * Initialize the transaction as UAC transaction. 1075 */ 1076 PJ_DEF(pj_status_t) pjsip_tsx_init_uac( pjsip_transaction *tsx, 1077 pjsip_tx_data *tdata) 1078 { 902 903 /* Unregister transaction. */ 904 mod_tsx_layer_unregister_tsx(tsx); 905 906 /* Destroy transaction. */ 907 tsx_destroy(tsx); 908 } 909 } 910 911 912 /* 913 * Create, initialize, and register UAC transaction. 914 */ 915 PJ_DEF(pj_status_t) pjsip_tsx_create_uac( pjsip_module *tsx_user, 916 pjsip_tx_data *tdata, 917 pjsip_transaction **p_tsx) 918 { 919 pjsip_transaction *tsx; 1079 920 pjsip_msg *msg; 1080 921 pjsip_cseq_hdr *cseq; 1081 922 pjsip_via_hdr *via; 923 struct tsx_lock_data lck; 1082 924 pj_status_t status; 1083 struct tsx_lock_data lck; 1084 1085 PJ_LOG(4,(tsx->obj_name, "initializing tsx as UAC (tdata=%p)", tdata)); 925 926 PJ_ASSERT_RETURN(tdata!=NULL && p_tsx!=NULL, PJ_EINVAL); 927 928 /* Keep shortcut */ 929 msg = tdata->msg; 930 931 /* Make sure CSeq header is present. */ 932 cseq = pjsip_msg_find_hdr(msg, PJSIP_H_CSEQ, NULL); 933 if (!cseq) { 934 pj_assert(!"CSeq header not present in outgoing message!"); 935 return PJSIP_EMISSINGHDR; 936 } 937 938 939 /* Create transaction instance. */ 940 status = tsx_create( tsx_user, &tsx); 941 if (status != PJ_SUCCESS) 942 return status; 943 1086 944 1087 945 /* Lock transaction. */ 1088 946 lock_tsx(tsx, &lck); 1089 947 1090 /* Keep shortcut */1091 msg = tdata->msg;1092 1093 948 /* Role is UAC. */ 1094 949 tsx->role = PJSIP_ROLE_UAC; … … 1096 951 /* Save method. */ 1097 952 pjsip_method_copy( tsx->pool, &tsx->method, &msg->line.req.method); 953 954 /* Save CSeq. */ 955 tsx->cseq = cseq->cseq; 1098 956 1099 957 /* Generate Via header if it doesn't exist. */ … … 1104 962 } 1105 963 964 /* Generate branch parameter if it doesn't exist. */ 1106 965 if (via->branch_param.slen == 0) { 1107 966 pj_str_t tmp; … … 1116 975 /* Save branch parameter. */ 1117 976 tsx->branch = via->branch_param; 977 1118 978 } else { 1119 979 /* Copy branch parameter. */ … … 1121 981 } 1122 982 1123 1124 /* Generate transaction key. */ 1125 status = create_tsx_key_3261( tsx->pool, &tsx->transaction_key, 1126 PJSIP_ROLE_UAC, &tsx->method, 1127 &via->branch_param); 1128 if (status != PJ_SUCCESS) { 1129 unlock_tsx(tsx, &lck); 1130 return status; 1131 } 983 /* Generate transaction key. */ 984 create_tsx_key_3261( tsx->pool, &tsx->transaction_key, 985 PJSIP_ROLE_UAC, &tsx->method, 986 &via->branch_param); 1132 987 1133 988 PJ_LOG(6, (tsx->obj_name, "tsx_key=%.*s", tsx->transaction_key.slen, 1134 989 tsx->transaction_key.ptr)); 1135 1136 /* Save CSeq. */1137 cseq = pjsip_msg_find_hdr(msg, PJSIP_H_CSEQ, NULL);1138 if (!cseq) {1139 pj_assert(!"CSeq header not present in outgoing message!");1140 unlock_tsx(tsx, &lck);1141 return PJSIP_EMISSINGHDR;1142 }1143 tsx->cseq = cseq->cseq;1144 1145 990 1146 991 /* Begin with State_Null. … … 1148 993 */ 1149 994 tsx->state = PJSIP_TSX_STATE_NULL; 1150 tsx->state_handler = &pjsip_tsx_on_state_null; 1151 1152 /* Get destination name from the message. */ 1153 status = tsx_process_route(tsx, tdata, &tsx->dest_name); 1154 if (status != PJ_SUCCESS) { 1155 tsx->transport_state = PJSIP_TSX_TRANSPORT_STATE_FINAL; 1156 tsx->status_code = PJSIP_SC_TSX_TRANSPORT_ERROR; 1157 tsx_set_state(tsx, PJSIP_TSX_STATE_TERMINATED, 1158 PJSIP_EVENT_TRANSPORT_ERROR, (void*)status); 1159 unlock_tsx(tsx, &lck); 1160 return status; 1161 } 1162 1163 /* Resolve destination. 1164 * This will start asynchronous resolver job, and when it finishes, 1165 * the callback will be called. 1166 */ 1167 PJ_LOG(5,(tsx->obj_name, "tsx resolving destination %.*s:%d", 1168 tsx->dest_name.addr.host.slen, 1169 tsx->dest_name.addr.host.ptr, 1170 tsx->dest_name.addr.port)); 1171 1172 tsx->transport_state = PJSIP_TSX_TRANSPORT_STATE_RESOLVING; 1173 pjsip_endpt_resolve( tsx->endpt, tsx->pool, &tsx->dest_name, 1174 tsx, &tsx_resolver_callback); 1175 1176 /* There should be nothing to do after this point. 1177 * Execution for the transaction will resume when the resolver callback is 1178 * called. 1179 */ 1180 1181 /* Unlock transaction and return. 1182 * If transaction has been destroyed WITHIN the current thread, the 1183 * unlock_tsx() function will return -1. 1184 */ 1185 return unlock_tsx(tsx, &lck); 1186 } 1187 1188 1189 /* 1190 * Initialize the transaction as UAS transaction. 1191 */ 1192 PJ_DEF(pj_status_t) pjsip_tsx_init_uas( pjsip_transaction *tsx, 1193 pjsip_rx_data *rdata) 1194 { 1195 pjsip_msg *msg = rdata->msg_info.msg; 995 tsx->state_handler = &tsx_on_state_null; 996 997 /* Save the message. */ 998 tsx->last_tx = tdata; 999 pjsip_tx_data_add_ref(tsx->last_tx); 1000 1001 1002 /* Register transaction to hash table. */ 1003 mod_tsx_layer_register_tsx(tsx); 1004 1005 1006 /* Unlock transaction and return. */ 1007 unlock_tsx(tsx, &lck); 1008 1009 *p_tsx = tsx; 1010 return PJ_SUCCESS; 1011 } 1012 1013 1014 /* 1015 * Create, initialize, and register UAS transaction. 1016 */ 1017 PJ_DEF(pj_status_t) pjsip_tsx_create_uas( pjsip_module *tsx_user, 1018 pjsip_rx_data *rdata, 1019 pjsip_transaction **p_tsx) 1020 { 1021 pjsip_transaction *tsx; 1022 pjsip_msg *msg; 1196 1023 pj_str_t *branch; 1197 1024 pjsip_cseq_hdr *cseq; … … 1199 1026 struct tsx_lock_data lck; 1200 1027 1201 PJ_LOG(4,(tsx->obj_name, "initializing tsx as UAS (rdata=%p)", rdata)); 1028 PJ_ASSERT_RETURN(rdata!=NULL && p_tsx!=NULL, PJ_EINVAL); 1029 1030 /* Keep shortcut to message */ 1031 msg = rdata->msg_info.msg; 1032 1033 /* Make sure this is a request message. */ 1034 PJ_ASSERT_RETURN(msg->type == PJSIP_REQUEST_MSG, PJSIP_ENOTREQUESTMSG); 1035 1036 /* Make sure CSeq header is present. */ 1037 cseq = rdata->msg_info.cseq; 1038 if (!cseq) 1039 return PJSIP_EMISSINGHDR; 1040 1041 /* Make sure Via header is present. */ 1042 if (rdata->msg_info.via == NULL) 1043 return PJSIP_EMISSINGHDR; 1044 1045 1046 /* 1047 * Create transaction instance. 1048 */ 1049 status = tsx_create( tsx_user, &tsx); 1050 if (status != PJ_SUCCESS) 1051 return status; 1052 1202 1053 1203 1054 /* Lock transaction. */ 1204 1055 lock_tsx(tsx, &lck); 1205 1056 1206 /* Keep shortcut to message */1207 msg = rdata->msg_info.msg;1208 1209 1057 /* Role is UAS */ 1210 1058 tsx->role = PJSIP_ROLE_UAS; … … 1212 1060 /* Save method. */ 1213 1061 pjsip_method_copy( tsx->pool, &tsx->method, &msg->line.req.method); 1062 1063 /* Save CSeq */ 1064 tsx->cseq = cseq->cseq; 1214 1065 1215 1066 /* Get transaction key either from branch for RFC3261 message, or … … 1219 1070 PJSIP_ROLE_UAS, &tsx->method, rdata); 1220 1071 if (status != PJ_SUCCESS) { 1221 unlock_tsx(tsx, &lck);1072 tsx_destroy(tsx); 1222 1073 return status; 1223 1074 } … … 1230 1081 tsx->transaction_key.ptr)); 1231 1082 1232 /* Save CSeq */ 1233 cseq = rdata->msg_info.cseq; 1234 tsx->cseq = cseq->cseq; 1235 1236 /* Begin with state NULL 1083 1084 /* Begin with state TRYING. 1237 1085 * Manually set-up the state becase we don't want to call the callback. 1238 1086 */ 1239 tsx->state = PJSIP_TSX_STATE_NULL; 1240 tsx->state_handler = &pjsip_tsx_on_state_null; 1241 1242 /* Get the transport to send the response. 1243 * According to section 18.2.2 of RFC3261, if the transport is reliable 1244 * then the response must be sent using that transport. 1087 tsx->state = PJSIP_TSX_STATE_TRYING; 1088 tsx->state_handler = &tsx_on_state_trying; 1089 1090 /* Get response address. */ 1091 status = pjsip_get_response_addr( tsx->pool, rdata, &tsx->res_addr ); 1092 if (status != PJ_SUCCESS) { 1093 tsx_destroy(tsx); 1094 return status; 1095 } 1096 1097 /* If it's decided that we should use current transport, keep the 1098 * transport. 1245 1099 */ 1246 /* In addition, RFC 3581 says, if Via has "rport" parameter specified, 1247 * then return the response using the same transport. 1248 */ 1249 if (PJSIP_TRANSPORT_IS_RELIABLE(rdata->tp_info.transport) || 1250 rdata->msg_info.via->rport_param >= 0) 1251 { 1252 tsx->transport = rdata->tp_info.transport; 1100 if (tsx->res_addr.transport) { 1101 tsx->transport = tsx->res_addr.transport; 1253 1102 pjsip_transport_add_ref(tsx->transport); 1254 tsx->transport_state = PJSIP_TSX_TRANSPORT_STATE_FINAL; 1255 1256 tsx->current_addr = 0; 1257 tsx->remote_addr.count = 1; 1258 tsx->remote_addr.entry[0].type = tsx->transport->key.type; 1259 pj_memcpy(&tsx->remote_addr.entry[0].addr, 1260 &rdata->pkt_info.src_addr, rdata->pkt_info.src_addr_len); 1261 1262 } else { 1263 pj_status_t status; 1264 1265 status = pjsip_get_response_addr(tsx->pool, rdata->tp_info.transport, 1266 rdata->msg_info.via, &tsx->dest_name); 1267 if (status != PJ_SUCCESS) { 1268 tsx->transport_state = PJSIP_TSX_TRANSPORT_STATE_FINAL; 1269 tsx->status_code = PJSIP_SC_TSX_TRANSPORT_ERROR; 1270 tsx_set_state(tsx, PJSIP_TSX_STATE_TERMINATED, 1271 PJSIP_EVENT_TRANSPORT_ERROR, (void*)status); 1272 unlock_tsx(tsx, &lck); 1273 return status; 1274 } 1275 1276 /* Resolve destination. 1277 * This will start asynchronous resolver job, and when it finishes, 1278 * the callback will be called. 1279 */ 1280 PJ_LOG(5,(tsx->obj_name, "tsx resolving destination %.*s:%d", 1281 tsx->dest_name.addr.host.slen, 1282 tsx->dest_name.addr.host.ptr, 1283 tsx->dest_name.addr.port)); 1284 1285 tsx->transport_state = PJSIP_TSX_TRANSPORT_STATE_RESOLVING; 1286 pjsip_endpt_resolve( tsx->endpt, tsx->pool, &tsx->dest_name, 1287 tsx, &tsx_resolver_callback); 1288 } 1289 1290 /* There should be nothing to do after this point. 1291 * Execution for the transaction will resume when the resolver callback is 1292 * called. 1293 */ 1294 1295 /* Unlock transaction and return. 1296 * If transaction has been destroyed WITHIN the current thread, the 1297 * unlock_tsx() function will return -1. 1298 */ 1299 return unlock_tsx(tsx, &lck); 1300 } 1301 1302 /* 1303 * Callback when timer expires. 1304 */ 1305 static void tsx_timer_callback( pj_timer_heap_t *theap, pj_timer_entry *entry) 1306 { 1307 pjsip_event event; 1308 pjsip_transaction *tsx = entry->user_data; 1103 pj_memcpy(&tsx->addr, &tsx->res_addr.addr, tsx->res_addr.addr_len); 1104 tsx->addr_len = tsx->res_addr.addr_len; 1105 } 1106 1107 1108 /* Register the transaction. */ 1109 mod_tsx_layer_register_tsx(tsx); 1110 1111 1112 /* Unlock transaction and return. */ 1113 unlock_tsx(tsx, &lck); 1114 1115 *p_tsx = tsx; 1116 return PJ_SUCCESS; 1117 } 1118 1119 1120 /* 1121 * Forcely terminate transaction. 1122 */ 1123 PJ_DEF(pj_status_t) pjsip_tsx_terminate( pjsip_transaction *tsx, int code ) 1124 { 1309 1125 struct tsx_lock_data lck; 1310 1126 1311 PJ_UNUSED_ARG(theap); 1312 1313 PJ_LOG(5,(tsx->obj_name, "got timer event (%s timer)", 1314 (entry->id==TSX_TIMER_RETRANSMISSION ? "Retransmit" : "Timeout"))); 1315 1316 1317 if (entry->id == TSX_TIMER_RETRANSMISSION) { 1318 PJSIP_EVENT_INIT_TIMER(event, &tsx->retransmit_timer); 1319 } else { 1320 PJSIP_EVENT_INIT_TIMER(event, &tsx->timeout_timer); 1321 } 1322 1323 /* Dispatch event to transaction. */ 1127 PJ_ASSERT_RETURN(tsx != NULL, PJ_EINVAL); 1128 PJ_ASSERT_RETURN(code >= 200, PJ_EINVAL); 1129 1324 1130 lock_tsx(tsx, &lck); 1325 (*tsx->state_handler)(tsx, &event); 1131 tsx->status_code = code; 1132 tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED, PJSIP_EVENT_USER, NULL); 1326 1133 unlock_tsx(tsx, &lck); 1327 } 1328 1329 /* 1330 * Transmit ACK message for 2xx/INVITE with this transaction. The ACK for 1331 * non-2xx/INVITE is automatically sent by the transaction. 1332 * This operation is only valid if the transaction is configured to handle ACK 1333 * (tsx->handle_ack is non-zero). If this attribute is not set, then the 1334 * transaction will comply with RFC-3261, i.e. it will set itself to 1335 * TERMINATED state when it receives 2xx/INVITE. 1336 */ 1337 PJ_DEF(void) pjsip_tsx_on_tx_ack( pjsip_transaction *tsx, pjsip_tx_data *tdata) 1338 { 1339 pjsip_msg *msg; 1340 pjsip_host_info dest_addr; 1341 pjsip_via_hdr *via; 1342 struct tsx_lock_data lck; 1343 pj_status_t status = PJ_SUCCESS; 1344 1345 /* Lock tsx. */ 1346 lock_tsx(tsx, &lck); 1347 1348 pj_assert(tsx->handle_ack != 0); 1349 1350 msg = tdata->msg; 1351 1352 /* Generate branch parameter if it doesn't exist. */ 1353 via = pjsip_msg_find_hdr(msg, PJSIP_H_VIA, NULL); 1354 if (via == NULL) { 1355 via = pjsip_via_hdr_create(tdata->pool); 1356 pjsip_msg_add_hdr(msg, (pjsip_hdr*) via); 1357 } 1358 1359 if (via->branch_param.slen == 0) { 1360 via->branch_param = tsx->branch; 1361 } else { 1362 pj_assert( pj_strcmp(&via->branch_param, &tsx->branch) == 0 ); 1363 } 1364 1365 /* Get destination name from the message. */ 1366 status = tsx_process_route(tsx, tdata, &dest_addr); 1367 if (status != 0){ 1368 goto on_error; 1369 } 1370 1371 /* Compare message's destination name with transaction's destination name. 1372 * If NOT equal, then we'll have to resolve the destination. 1373 */ 1374 if (dest_addr.type == tsx->dest_name.type && 1375 dest_addr.flag == tsx->dest_name.flag && 1376 dest_addr.addr.port == tsx->dest_name.addr.port && 1377 pj_stricmp(&dest_addr.addr.host, &tsx->dest_name.addr.host) == 0) 1378 { 1379 /* Equal destination. We can use current transport. */ 1380 pjsip_tsx_on_tx_msg(tsx, tdata); 1381 unlock_tsx(tsx, &lck); 1382 return; 1383 1384 } 1385 1386 /* New destination; we'll have to resolve host and create new transport. */ 1387 pj_memcpy(&tsx->dest_name, &dest_addr, sizeof(dest_addr)); 1388 pj_strdup(tsx->pool, &tsx->dest_name.addr.host, &dest_addr.addr.host); 1389 1390 PJ_LOG(5,(tsx->obj_name, "tsx resolving destination %.*s:%d", 1391 tsx->dest_name.addr.host.slen, 1392 tsx->dest_name.addr.host.ptr, 1393 tsx->dest_name.addr.port)); 1394 1395 tsx->transport_state = PJSIP_TSX_TRANSPORT_STATE_RESOLVING; 1396 pjsip_transport_dec_ref(tsx->transport); 1397 tsx->transport = NULL; 1398 1399 /* Put the message in queue. */ 1400 pjsip_tsx_on_tx_msg(tsx, tdata); 1401 1402 /* This is a bug! 1403 * We shouldn't change transaction's state before actually sending the 1404 * message. Otherwise transaction will terminate before message is sent, 1405 * and timeout timer will be scheduled. 1406 */ 1407 PJ_TODO(TSX_DONT_CHANGE_STATE_BEFORE_SENDING_ACK) 1408 1409 /* 1410 * This will start asynchronous resolver job, and when it finishes, 1411 * the callback will be called. 1412 */ 1413 1414 tsx->transport_state = PJSIP_TSX_TRANSPORT_STATE_RESOLVING; 1415 pjsip_endpt_resolve( tsx->endpt, tsx->pool, &tsx->dest_name, 1416 tsx, &tsx_resolver_callback); 1417 1418 unlock_tsx(tsx, &lck); 1419 1420 /* There should be nothing to do after this point. 1421 * Execution for the transaction will resume when the resolver callback is 1422 * called. 1423 */ 1424 return; 1425 1426 on_error: 1427 /* Failure condition. 1428 * Send TERMINATED event. 1429 */ 1430 tsx->status_code = PJSIP_SC_TSX_TRANSPORT_ERROR; 1431 1432 tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED, 1433 PJSIP_EVENT_TRANSPORT_ERROR, (void*)status); 1434 1435 unlock_tsx(tsx, &lck); 1134 1135 return PJ_SUCCESS; 1436 1136 } 1437 1137 … … 1440 1140 * This function is called by TU to send a message. 1441 1141 */ 1442 PJ_DEF( void) pjsip_tsx_on_tx_msg( pjsip_transaction *tsx,1443 pjsip_tx_data *tdata )1142 PJ_DEF(pj_status_t) pjsip_tsx_send_msg( pjsip_transaction *tsx, 1143 pjsip_tx_data *tdata ) 1444 1144 { 1445 1145 pjsip_event event; 1446 1146 struct tsx_lock_data lck; 1447 1147 pj_status_t status; 1148 1149 if (tdata == NULL) 1150 tdata = tsx->last_tx; 1151 1152 PJ_ASSERT_RETURN(tdata != NULL, PJ_EINVALIDOP); 1448 1153 1449 1154 PJ_LOG(5,(tsx->obj_name, "Request to transmit msg on state %s (tdata=%p)", … … 1456 1161 status = (*tsx->state_handler)(tsx, &event); 1457 1162 unlock_tsx(tsx, &lck); 1458 } 1163 1164 return status; 1165 } 1166 1459 1167 1460 1168 /* … … 1462 1170 * transaction is received. 1463 1171 */ 1464 PJ_DEF(void) pjsip_tsx_on_rx_msg( pjsip_transaction *tsx, 1465 pjsip_rx_data *rdata) 1172 static void tsx_on_rx_msg( pjsip_transaction *tsx, pjsip_rx_data *rdata) 1466 1173 { 1467 1174 pjsip_event event; … … 1472 1179 state_str[tsx->state], rdata)); 1473 1180 1181 /* Put the transaction in the rdata's mod_data. */ 1182 rdata->endpt_info.mod_data[mod_tsx_layer.mod.id] = tsx; 1183 1184 /* Init event. */ 1474 1185 PJSIP_EVENT_INIT_RX_MSG(event, tsx, rdata); 1475 1186 … … 1480 1191 } 1481 1192 1482 /* 1483 * Forcely terminate transaction. 1484 */ 1485 PJ_DEF(void) pjsip_tsx_terminate( pjsip_transaction *tsx, int code ) 1486 { 1193 1194 /* Callback called by send message framework */ 1195 static void send_msg_callback( pjsip_send_state *send_state, 1196 pj_ssize_t sent, pj_bool_t *cont ) 1197 { 1198 pjsip_transaction *tsx = send_state->token; 1487 1199 struct tsx_lock_data lck; 1488 1200 1489 1201 lock_tsx(tsx, &lck); 1490 tsx->status_code = code; 1491 tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED, 1492 PJSIP_EVENT_USER, NULL); 1202 1203 if (sent > 0) { 1204 /* Successfully sent! */ 1205 pj_assert(send_state->cur_transport != NULL); 1206 1207 if (tsx->transport != send_state->cur_transport) { 1208 if (tsx->transport) { 1209 pjsip_transport_dec_ref(tsx->transport); 1210 tsx->transport = NULL; 1211 } 1212 tsx->transport = send_state->cur_transport; 1213 pjsip_transport_add_ref(tsx->transport); 1214 } 1215 1216 /* Clear pending transport flag. */ 1217 tsx->transport_flag &= ~(TSX_HAS_PENDING_TRANSPORT); 1218 1219 /* Pending destroy? */ 1220 if (tsx->transport_flag & TSX_HAS_PENDING_DESTROY) { 1221 tsx_set_state( tsx, PJSIP_TSX_STATE_DESTROYED, 1222 PJSIP_EVENT_UNKNOWN, NULL ); 1223 unlock_tsx(tsx, &lck); 1224 return; 1225 } 1226 1227 /* Need to transmit a message? */ 1228 if (tsx->transport_flag & TSX_HAS_PENDING_SEND) { 1229 tsx->transport_flag &= ~(TSX_HAS_PENDING_SEND); 1230 tsx_send_msg(tsx, tsx->last_tx); 1231 } 1232 1233 /* Need to reschedule retransmission? */ 1234 if (tsx->transport_flag & TSX_HAS_PENDING_RESCHED) { 1235 tsx->transport_flag &= ~(TSX_HAS_PENDING_RESCHED); 1236 tsx_resched_retransmission(tsx); 1237 } 1238 1239 } else { 1240 /* Failed to send! */ 1241 pj_assert(sent != 0); 1242 1243 /* If transaction is using the same transport as the failed one, 1244 * release the transport. 1245 */ 1246 if (send_state->cur_transport==tsx->transport && 1247 tsx->transport != NULL) 1248 { 1249 pjsip_transport_dec_ref(tsx->transport); 1250 tsx->transport = NULL; 1251 } 1252 1253 if (!*cont) { 1254 PJ_LOG(4,(tsx->obj_name, "Failed to send message! status=%d", 1255 -sent)); 1256 1257 /* Clear pending transport flag. */ 1258 tsx->transport_flag &= ~(TSX_HAS_PENDING_TRANSPORT); 1259 1260 /* Terminate transaction. */ 1261 tsx->status_code = PJSIP_SC_TSX_TRANSPORT_ERROR; 1262 tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED, 1263 PJSIP_EVENT_TRANSPORT_ERROR, send_state->tdata ); 1264 } 1265 } 1493 1266 1494 1267 unlock_tsx(tsx, &lck); 1495 1268 } 1496 1269 1497 /* 1498 * Transport send completion callback. 1499 */ 1500 static void tsx_on_send_complete(void *token, pjsip_tx_data *tdata, 1501 pj_ssize_t bytes_sent) 1502 { 1503 PJ_UNUSED_ARG(token); 1504 PJ_UNUSED_ARG(tdata); 1505 1506 if (bytes_sent <= 0) { 1507 PJ_TODO(HANDLE_TRANSPORT_ERROR); 1508 } 1270 1271 /* Transport callback. */ 1272 static void transport_callback(void *token, pjsip_tx_data *tdata, 1273 pj_ssize_t sent) 1274 { 1275 if (sent < 0) { 1276 pjsip_transaction *tsx = token; 1277 struct tsx_lock_data lck; 1278 1279 PJ_LOG(4,(tsx->obj_name, "Failed to send message! status=%d", 1280 -sent)); 1281 1282 lock_tsx(tsx, &lck); 1283 1284 /* Dereference transport. */ 1285 pjsip_transport_dec_ref(tsx->transport); 1286 tsx->transport = NULL; 1287 1288 /* Terminate transaction. */ 1289 tsx->status_code = PJSIP_SC_TSX_TRANSPORT_ERROR; 1290 tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED, 1291 PJSIP_EVENT_TRANSPORT_ERROR, tdata ); 1292 1293 unlock_tsx(tsx, &lck); 1294 } 1509 1295 } 1510 1296 1511 1297 /* 1512 1298 * Send message to the transport. 1513 * If transport is not yet available, then do nothing. The message will be1514 * transmitted when transport connection completion callback is called.1515 1299 */ 1516 1300 static pj_status_t tsx_send_msg( pjsip_transaction *tsx, 1517 1301 pjsip_tx_data *tdata) 1518 1302 { 1519 pj_status_t status = PJ_SUCCESS; 1520 1521 PJ_LOG(5,(tsx->obj_name, "sending msg (tdata=%p)", tdata)); 1522 1523 if (tsx->transport_state == PJSIP_TSX_TRANSPORT_STATE_FINAL) { 1524 pjsip_event before_tx_event; 1525 1526 pj_assert(tsx->transport != NULL); 1527 1528 /* Make sure Via transport info is filled up properly for 1529 * requests. 1303 pj_status_t status = PJ_EBUG; 1304 1305 PJ_ASSERT_RETURN(tsx && tdata, PJ_EINVAL); 1306 1307 /* Send later if transport is still pending. */ 1308 if (tsx->transport_flag & TSX_HAS_PENDING_TRANSPORT) { 1309 tsx->transport_flag |= TSX_HAS_PENDING_SEND; 1310 return PJ_SUCCESS; 1311 } 1312 1313 if (tdata->msg->type == PJSIP_REQUEST_MSG) { 1314 /* If we have the transport, send the message using that transport. 1315 * Otherwise perform full transport resolution. 1530 1316 */ 1531 if (tdata->msg->type == PJSIP_REQUEST_MSG) { 1532 pjsip_via_hdr *via = (pjsip_via_hdr*) 1533 pjsip_msg_find_hdr(tdata->msg, PJSIP_H_VIA, NULL); 1534 1535 /* For request message, set "rport" parameter by default. */ 1536 if (tdata->msg->type == PJSIP_REQUEST_MSG) 1537 via->rport_param = 0; 1538 1539 /* Don't update Via sent-by on retransmission. */ 1540 if (via->sent_by.host.slen == 0) { 1541 pj_strdup2(tdata->pool, &via->transport, 1542 tsx->transport->type_name); 1543 pj_strdup(tdata->pool, &via->sent_by.host, 1544 &tsx->transport->local_name.host); 1545 via->sent_by.port = tsx->transport->local_name.port; 1317 if (tsx->transport) { 1318 status = pjsip_transport_send( tsx->transport, tdata, &tsx->addr, 1319 tsx->addr_len, tsx, 1320 &transport_callback); 1321 if (status == PJ_EPENDING) 1322 status = PJ_SUCCESS; 1323 1324 if (status != PJ_SUCCESS) { 1325 /* On error, release transport to force using full transport 1326 * resolution procedure. 1327 */ 1328 if (tsx->transport) { 1329 pjsip_transport_dec_ref(tsx->transport); 1330 tsx->transport = NULL; 1331 } 1332 tsx->addr_len = 0; 1546 1333 } 1547 1334 } 1548 1549 /* Notify everybody we're about to send message. */ 1550 PJSIP_EVENT_INIT_PRE_TX_MSG(before_tx_event, tsx, tdata, 1551 tsx->retransmit_count); 1552 pjsip_endpt_send_tsx_event( tsx->endpt, &before_tx_event ); 1553 1554 tsx->has_unsent_msg = 0; 1555 status = pjsip_transport_send(tsx->transport, tdata, 1556 &tsx->remote_addr.entry[tsx->current_addr].addr, 1557 tsx->remote_addr.entry[tsx->current_addr].addr_len, 1558 tsx, &tsx_on_send_complete); 1559 if (status != PJ_SUCCESS && status != PJ_EPENDING) { 1560 PJ_TODO(HANDLE_TRANSPORT_ERROR); 1561 goto on_error; 1562 } 1335 1336 if (!tsx->transport) { 1337 tsx->transport_flag |= TSX_HAS_PENDING_TRANSPORT; 1338 status = pjsip_endpt_send_request_stateless(tsx->endpt, tdata, tsx, 1339 &send_msg_callback); 1340 if (status == PJ_EPENDING) 1341 status = PJ_SUCCESS; 1342 } 1343 1563 1344 } else { 1564 tsx->has_unsent_msg = 1; 1565 } 1566 1567 return 0; 1568 1569 on_error: 1570 tsx->status_code = PJSIP_SC_TSX_TRANSPORT_ERROR; 1571 tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED, 1572 PJSIP_EVENT_TRANSPORT_ERROR, (void*)status); 1345 /* If we have the transport, send the message using that transport. 1346 * Otherwise perform full transport resolution. 1347 */ 1348 if (tsx->transport) { 1349 status = pjsip_transport_send( tsx->transport, tdata, 1350 &tsx->addr, tsx->addr_len, 1351 tsx, &transport_callback); 1352 if (status == PJ_EPENDING) 1353 status = PJ_SUCCESS; 1354 1355 if (status != PJ_SUCCESS) { 1356 if (tsx->transport) { 1357 pjsip_transport_dec_ref(tsx->transport); 1358 tsx->transport = NULL; 1359 } 1360 tsx->addr_len = 0; 1361 tsx->res_addr.transport = NULL; 1362 tsx->res_addr.addr_len = 0; 1363 } 1364 1365 } 1366 1367 if (!tsx->transport) { 1368 tsx->transport_flag |= TSX_HAS_PENDING_TRANSPORT; 1369 status = pjsip_endpt_send_response( tsx->endpt, &tsx->res_addr, 1370 tdata, tsx, 1371 &send_msg_callback); 1372 if (status == PJ_EPENDING) 1373 status = PJ_SUCCESS; 1374 } 1375 } 1376 1573 1377 return status; 1574 1378 } 1575 1379 1380 1576 1381 /* 1577 1382 * Retransmit last message sent. 1578 1383 */ 1579 static pj_status_t pjsip_tsx_retransmit( pjsip_transaction *tsx, 1580 int should_restart_timer) 1384 static void tsx_resched_retransmission( pjsip_transaction *tsx ) 1385 { 1386 pj_time_val timeout; 1387 int msec_time; 1388 1389 pj_assert((tsx->transport_flag & TSX_HAS_PENDING_TRANSPORT) == 0); 1390 1391 msec_time = (1 << (tsx->retransmit_count)) * PJSIP_T1_TIMEOUT; 1392 1393 if (msec_time>PJSIP_T2_TIMEOUT && tsx->method.id!=PJSIP_INVITE_METHOD) 1394 msec_time = PJSIP_T2_TIMEOUT; 1395 1396 timeout.sec = msec_time / 1000; 1397 timeout.msec = msec_time % 1000; 1398 pjsip_endpt_schedule_timer( tsx->endpt, &tsx->retransmit_timer, 1399 &timeout); 1400 } 1401 1402 /* 1403 * Retransmit last message sent. 1404 */ 1405 static pj_status_t tsx_retransmit( pjsip_transaction *tsx, int resched) 1581 1406 { 1582 1407 pj_status_t status; 1583 1408 1409 PJ_ASSERT_RETURN(tsx->last_tx!=NULL, PJ_EBUG); 1410 1584 1411 PJ_LOG(4,(tsx->obj_name, "retransmiting (tdata=%p, count=%d, restart?=%d)", 1585 tsx->last_tx, tsx->retransmit_count, should_restart_timer)); 1586 1587 pj_assert(tsx->last_tx != NULL); 1412 tsx->last_tx, tsx->retransmit_count, resched)); 1588 1413 1589 1414 ++tsx->retransmit_count; 1590 1415 1591 1416 status = tsx_send_msg( tsx, tsx->last_tx); 1592 if (status != PJ_SUCCESS) {1417 if (status != PJ_SUCCESS) 1593 1418 return status; 1594 }1595 1419 1596 1420 /* Restart timer T1. */ 1597 if (should_restart_timer) { 1598 pj_time_val timeout; 1599 int msec_time = (1 << (tsx->retransmit_count)) * PJSIP_T1_TIMEOUT; 1600 1601 if (tsx->method.id!=PJSIP_INVITE_METHOD && msec_time>PJSIP_T2_TIMEOUT) 1602 msec_time = PJSIP_T2_TIMEOUT; 1603 1604 timeout.sec = msec_time / 1000; 1605 timeout.msec = msec_time % 1000; 1606 pjsip_endpt_schedule_timer( tsx->endpt, &tsx->retransmit_timer, 1607 &timeout); 1421 if (resched) { 1422 if (tsx->transport_flag & TSX_HAS_PENDING_TRANSPORT) { 1423 tsx->transport_flag |= TSX_HAS_PENDING_RESCHED; 1424 } else { 1425 tsx_resched_retransmission(tsx); 1426 } 1608 1427 } 1609 1428 … … 1611 1430 } 1612 1431 1432 1613 1433 /* 1614 1434 * Handler for events in state Null. 1615 1435 */ 1616 static pj_status_t pjsip_tsx_on_state_null( pjsip_transaction *tsx,1617 1436 static pj_status_t tsx_on_state_null( pjsip_transaction *tsx, 1437 pjsip_event *event ) 1618 1438 { 1619 1439 pj_status_t status; 1620 1440 1621 pj_assert( tsx->state == PJSIP_TSX_STATE_NULL); 1622 pj_assert( tsx->last_tx == NULL ); 1623 pj_assert( tsx->has_unsent_msg == 0); 1441 pj_assert(tsx->state == PJSIP_TSX_STATE_NULL); 1624 1442 1625 1443 if (tsx->role == PJSIP_ROLE_UAS) { 1626 1444 1627 /* Set state to Trying. */ 1628 pj_assert(event->type == PJSIP_EVENT_RX_MSG); 1629 tsx_set_state( tsx, PJSIP_TSX_STATE_TRYING, 1630 PJSIP_EVENT_RX_MSG, event->body.rx_msg.rdata ); 1445 /* UAS doesn't have STATE_NULL. 1446 * State has moved from NULL after transaction is initialized. 1447 */ 1448 pj_assert(!"Bug bug bug!!"); 1449 return PJ_EBUG; 1631 1450 1632 1451 } else { 1633 pjsip_tx_data *tdata = event->body.tx_msg.tdata; 1452 pjsip_tx_data *tdata; 1453 1454 /* Must be transmit event. */ 1455 PJ_ASSERT_RETURN(event->type == PJSIP_EVENT_TX_MSG, PJ_EBUG); 1456 1457 /* Get the txdata */ 1458 tdata = event->body.tx_msg.tdata; 1634 1459 1635 1460 /* Save the message for retransmission. */ 1636 tsx->last_tx = tdata; 1637 pjsip_tx_data_add_ref(tdata); 1461 if (tsx->last_tx && tsx->last_tx != tdata) { 1462 pjsip_tx_data_dec_ref(tsx->last_tx); 1463 tsx->last_tx = NULL; 1464 } 1465 if (tsx->last_tx != tdata) { 1466 tsx->last_tx = tdata; 1467 pjsip_tx_data_add_ref(tdata); 1468 } 1638 1469 1639 1470 /* Send the message. */ … … 1652 1483 * transport is being used. 1653 1484 */ 1654 if (tsx->transport_state == PJSIP_TSX_TRANSPORT_STATE_FINAL && 1655 PJSIP_TRANSPORT_IS_RELIABLE(tsx->transport)==0) 1656 { 1657 pjsip_endpt_schedule_timer(tsx->endpt, &tsx->retransmit_timer, 1658 &t1_timer_val); 1485 if (!PJSIP_TRANSPORT_IS_RELIABLE(tsx->transport)) { 1659 1486 tsx->retransmit_count = 0; 1487 if (tsx->transport_flag & TSX_HAS_PENDING_TRANSPORT) { 1488 tsx->transport_flag |= TSX_HAS_PENDING_RESCHED; 1489 } else { 1490 pjsip_endpt_schedule_timer(tsx->endpt, &tsx->retransmit_timer, 1491 &t1_timer_val); 1492 } 1660 1493 } 1661 1494 … … 1668 1501 } 1669 1502 1503 1670 1504 /* 1671 1505 * State Calling is for UAC after it sends request but before any responses 1672 1506 * is received. 1673 1507 */ 1674 static pj_status_t pjsip_tsx_on_state_calling( pjsip_transaction *tsx,1675 1508 static pj_status_t tsx_on_state_calling( pjsip_transaction *tsx, 1509 pjsip_event *event ) 1676 1510 { 1677 1511 pj_assert(tsx->state == PJSIP_TSX_STATE_CALLING); … … 1684 1518 1685 1519 /* Retransmit the request. */ 1686 status = pjsip_tsx_retransmit( tsx, 1 );1520 status = tsx_retransmit( tsx, 1 ); 1687 1521 if (status != PJ_SUCCESS) { 1688 1522 return status; … … 1706 1540 1707 1541 /* Transaction is destroyed */ 1708 return PJSIP_ETSXDESTROYED;1542 //return PJSIP_ETSXDESTROYED; 1709 1543 1710 1544 } else if (event->type == PJSIP_EVENT_RX_MSG) { 1711 int code; 1545 pjsip_msg *msg; 1546 //int code; 1547 1548 /* Get message instance */ 1549 msg = event->body.rx_msg.rdata->msg_info.msg; 1550 1551 /* Better be a response message. */ 1552 if (msg->type != PJSIP_RESPONSE_MSG) 1553 return PJSIP_ENOTRESPONSEMSG; 1712 1554 1713 1555 /* Cancel retransmission timer A. */ … … 1723 1565 */ 1724 1566 /* Keep last_tx for authorization. */ 1725 code = event->body.rx_msg.rdata->msg_info.msg->line.status.code; 1726 if (tsx->method.id != PJSIP_INVITE_METHOD && code!=401 && code!=407) { 1727 pjsip_tx_data_dec_ref(tsx->last_tx); 1728 tsx->last_tx = NULL; 1729 } 1567 //blp: always keep last_tx until transaction is destroyed 1568 //code = msg->line.status.code; 1569 //if (tsx->method.id != PJSIP_INVITE_METHOD && code!=401 && code!=407) { 1570 // pjsip_tx_data_dec_ref(tsx->last_tx); 1571 // tsx->last_tx = NULL; 1572 //} 1730 1573 1731 1574 /* Processing is similar to state Proceeding. */ 1732 pjsip_tsx_on_state_proceeding_uac( tsx, event);1575 tsx_on_state_proceeding_uac( tsx, event); 1733 1576 1734 1577 } else { 1735 pj_assert( 0);1578 pj_assert(!"Unexpected event"); 1736 1579 return PJ_EBUG; 1737 1580 } … … 1739 1582 return PJ_SUCCESS; 1740 1583 } 1584 1741 1585 1742 1586 /* … … 1746 1590 * non-INVITE client transaction (bug in RFC?). 1747 1591 */ 1748 static pj_status_t pjsip_tsx_on_state_trying( pjsip_transaction *tsx,1749 1592 static pj_status_t tsx_on_state_trying( pjsip_transaction *tsx, 1593 pjsip_event *event) 1750 1594 { 1751 1595 pj_status_t status; … … 1762 1606 * response because we haven't sent any!). 1763 1607 */ 1764 //pj_assert(event->type == PJSIP_EVENT_TX_MSG);1765 1608 if (event->type != PJSIP_EVENT_TX_MSG) { 1766 1609 return PJ_SUCCESS; … … 1770 1613 * "Proceeding" state. 1771 1614 */ 1772 status = pjsip_tsx_on_state_proceeding_uas( tsx, event);1615 status = tsx_on_state_proceeding_uas( tsx, event); 1773 1616 1774 1617 /* Inform the TU of the state transision if state is still State_Trying */ 1775 1618 if (status==PJ_SUCCESS && tsx->state == PJSIP_TSX_STATE_TRYING) { 1619 1776 1620 tsx_set_state( tsx, PJSIP_TSX_STATE_PROCEEDING, 1777 1621 PJSIP_EVENT_TX_MSG, event->body.tx_msg.tdata); 1622 1778 1623 } 1779 1624 1780 1625 return status; 1781 1626 } 1627 1782 1628 1783 1629 /* … … 1785 1631 * This state happens after the TU sends provisional response. 1786 1632 */ 1787 static pj_status_t pjsip_tsx_on_state_proceeding_uas( pjsip_transaction *tsx,1788 1633 static pj_status_t tsx_on_state_proceeding_uas( pjsip_transaction *tsx, 1634 pjsip_event *event) 1789 1635 { 1790 1636 pj_assert(tsx->state == PJSIP_TSX_STATE_PROCEEDING || … … 1799 1645 pj_status_t status; 1800 1646 1801 /* Send last response. */ 1802 status = pjsip_tsx_retransmit( tsx, 0 ); 1803 if (status != PJ_SUCCESS) { 1804 return status; 1647 /* Must have last response sent. */ 1648 PJ_ASSERT_RETURN(tsx->last_tx != NULL, PJ_EBUG); 1649 1650 /* Send last response */ 1651 if (tsx->transport_flag & TSX_HAS_PENDING_TRANSPORT) { 1652 tsx->transport_flag |= TSX_HAS_PENDING_SEND; 1653 } else { 1654 status = tsx_send_msg(tsx, tsx->last_tx); 1655 if (status != PJ_SUCCESS) 1656 return status; 1805 1657 } 1806 1658 … … 1816 1668 1817 1669 /* This can only be a response message. */ 1818 pj_assert(msg->type == PJSIP_RESPONSE_MSG); 1819 1820 /* Status code must be higher than last sent. */ 1821 pj_assert(msg->line.status.code >= tsx->status_code); 1670 PJ_ASSERT_RETURN(msg->type==PJSIP_RESPONSE_MSG, PJSIP_ENOTRESPONSEMSG); 1822 1671 1823 1672 /* Update last status */ … … 1848 1697 pjsip_tx_data_add_ref( tdata ); 1849 1698 } 1699 1850 1700 tsx_set_state( tsx, PJSIP_TSX_STATE_PROCEEDING, 1851 1701 PJSIP_EVENT_TX_MSG, tdata ); … … 1853 1703 } else if (PJSIP_IS_STATUS_IN_CLASS(tsx->status_code, 200)) { 1854 1704 1855 if (tsx->method.id == PJSIP_INVITE_METHOD && tsx->handle_ ack==0) {1705 if (tsx->method.id == PJSIP_INVITE_METHOD && tsx->handle_200resp==0) { 1856 1706 1857 1707 /* 2xx class message is not saved, because retransmission … … 1862 1712 1863 1713 /* Transaction is destroyed. */ 1864 return PJSIP_ETSXDESTROYED;1714 //return PJSIP_ETSXDESTROYED; 1865 1715 1866 1716 } else { … … 1869 1719 if (tsx->method.id == PJSIP_INVITE_METHOD) { 1870 1720 tsx->retransmit_count = 0; 1871 pjsip_endpt_schedule_timer( tsx->endpt, 1872 &tsx->retransmit_timer, 1873 &t1_timer_val); 1721 if (tsx->transport_flag & TSX_HAS_PENDING_TRANSPORT) { 1722 tsx->transport_flag |= TSX_HAS_PENDING_RESCHED; 1723 } else { 1724 pjsip_endpt_schedule_timer( tsx->endpt, 1725 &tsx->retransmit_timer, 1726 &t1_timer_val); 1727 } 1874 1728 } 1875 1729 … … 1885 1739 * reliable transport. 1886 1740 */ 1887 if ( PJSIP_TRANSPORT_IS_RELIABLE(tsx->transport)==0) {1741 if (!PJSIP_TRANSPORT_IS_RELIABLE(tsx->transport)) { 1888 1742 timeout = timeout_timer_val; 1889 1743 } else { … … 1916 1770 * timer G will be scheduled (retransmission). 1917 1771 */ 1918 if ( PJSIP_TRANSPORT_IS_RELIABLE(tsx->transport)==0) {1772 if (!PJSIP_TRANSPORT_IS_RELIABLE(tsx->transport)) { 1919 1773 pjsip_cseq_hdr *cseq = pjsip_msg_find_hdr( msg, PJSIP_H_CSEQ, 1920 1774 NULL); 1921 1775 if (cseq->method.id == PJSIP_INVITE_METHOD) { 1922 1776 tsx->retransmit_count = 0; 1923 pjsip_endpt_schedule_timer(tsx->endpt, 1924 &tsx->retransmit_timer, 1925 &t1_timer_val); 1777 if (tsx->transport_flag & TSX_HAS_PENDING_TRANSPORT) { 1778 tsx->transport_flag |= TSX_HAS_PENDING_RESCHED; 1779 } else { 1780 pjsip_endpt_schedule_timer(tsx->endpt, 1781 &tsx->retransmit_timer, 1782 &t1_timer_val); 1783 } 1926 1784 } 1927 1785 } … … 1938 1796 } else if (event->type == PJSIP_EVENT_TIMER && 1939 1797 event->body.timer.entry == &tsx->retransmit_timer) { 1798 1940 1799 /* Retransmission timer elapsed. */ 1941 1800 pj_status_t status; 1942 1801 1802 /* Must not be triggered while transport is pending. */ 1803 pj_assert((tsx->transport_flag & TSX_HAS_PENDING_TRANSPORT) == 0); 1804 1943 1805 /* Must have last response to retransmit. */ 1944 1806 pj_assert(tsx->last_tx != NULL); 1945 1807 1946 1808 /* Retransmit the last response. */ 1947 status = pjsip_tsx_retransmit( tsx, 1 );1809 status = tsx_retransmit( tsx, 1 ); 1948 1810 if (status != PJ_SUCCESS) { 1949 1811 return status; … … 1954 1816 1955 1817 /* Timeout timer. should not happen? */ 1956 pj_assert( 0);1818 pj_assert(!"Should not happen(?)"); 1957 1819 1958 1820 tsx->status_code = PJSIP_SC_TSX_TIMEOUT; … … 1964 1826 1965 1827 } else { 1966 pj_assert( 0);1828 pj_assert(!"Unexpected event"); 1967 1829 return PJ_EBUG; 1968 1830 } … … 1970 1832 return PJ_SUCCESS; 1971 1833 } 1834 1972 1835 1973 1836 /* … … 1976 1839 * UAS. 1977 1840 */ 1978 static pj_status_t pjsip_tsx_on_state_proceeding_uac(pjsip_transaction *tsx,1979 1841 static pj_status_t tsx_on_state_proceeding_uac(pjsip_transaction *tsx, 1842 pjsip_event *event) 1980 1843 { 1981 1844 … … 1984 1847 1985 1848 if (event->type != PJSIP_EVENT_TIMER) { 1849 pjsip_msg *msg; 1850 1986 1851 /* Must be incoming response, because we should not retransmit 1987 1852 * request once response has been received. … … 1992 1857 } 1993 1858 1994 tsx->status_code = event->body.rx_msg.rdata->msg_info.msg->line.status.code; 1859 msg = event->body.rx_msg.rdata->msg_info.msg; 1860 1861 /* Must be a response message. */ 1862 if (msg->type != PJSIP_RESPONSE_MSG) { 1863 pj_assert(!"Expecting response message!"); 1864 return PJSIP_ENOTRESPONSEMSG; 1865 } 1866 1867 tsx->status_code = msg->line.status.code; 1995 1868 } else { 1996 1869 tsx->status_code = PJSIP_SC_TSX_TIMEOUT; … … 2011 1884 * handled in TU). For non-INVITE, state moves to Completed. 2012 1885 */ 2013 if (tsx->method.id == PJSIP_INVITE_METHOD && tsx->handle_ack == 0) {1886 if (tsx->method.id == PJSIP_INVITE_METHOD) { 2014 1887 tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED, 2015 1888 PJSIP_EVENT_RX_MSG, event->body.rx_msg.rdata ); 2016 return PJSIP_ETSXDESTROYED;1889 //return PJSIP_ETSXDESTROYED; 2017 1890 2018 1891 } else { … … 2047 1920 /* Generate and send ACK for INVITE. */ 2048 1921 if (tsx->method.id == PJSIP_INVITE_METHOD) { 2049 pjsip_endpt_create_ack( tsx->endpt, tsx->last_tx, 2050 event->body.rx_msg.rdata ); 1922 pjsip_tx_data *ack; 1923 1924 status = pjsip_endpt_create_ack( tsx->endpt, tsx->last_tx, 1925 event->body.rx_msg.rdata, 1926 &ack); 1927 if (status != PJ_SUCCESS) 1928 return status; 1929 1930 if (ack != tsx->last_tx) { 1931 pjsip_tx_data_dec_ref(tsx->last_tx); 1932 tsx->last_tx = ack; 1933 } 1934 2051 1935 status = tsx_send_msg( tsx, tsx->last_tx); 2052 1936 if (status != PJ_SUCCESS) { … … 2056 1940 2057 1941 /* Start Timer D with TD/T4 timer if unreliable transport is used. */ 2058 if ( PJSIP_TRANSPORT_IS_RELIABLE(tsx->transport) == 0) {1942 if (!PJSIP_TRANSPORT_IS_RELIABLE(tsx->transport)) { 2059 1943 if (tsx->method.id == PJSIP_INVITE_METHOD) { 2060 1944 timeout = td_timer_val; … … 2073 1957 } else { 2074 1958 // Shouldn't happen because there's no timer for this state. 2075 pj_assert( 0);1959 pj_assert(!"Unexpected event"); 2076 1960 return PJ_EBUG; 2077 1961 } … … 2080 1964 } 2081 1965 1966 2082 1967 /* 2083 1968 * Handler for events in Completed state for UAS 2084 1969 */ 2085 static pj_status_t pjsip_tsx_on_state_completed_uas( pjsip_transaction *tsx,2086 1970 static pj_status_t tsx_on_state_completed_uas( pjsip_transaction *tsx, 1971 pjsip_event *event) 2087 1972 { 2088 1973 pj_assert(tsx->state == PJSIP_TSX_STATE_COMPLETED); … … 2090 1975 if (event->type == PJSIP_EVENT_RX_MSG) { 2091 1976 pjsip_msg *msg = event->body.rx_msg.rdata->msg_info.msg; 2092 pjsip_cseq_hdr *cseq = pjsip_msg_find_hdr( msg, PJSIP_H_CSEQ, NULL ); 1977 1978 /* This must be a request message retransmission. */ 1979 if (msg->type != PJSIP_REQUEST_MSG) 1980 return PJSIP_ENOTREQUESTMSG; 2093 1981 2094 1982 /* On receive request retransmission, retransmit last response. */ 2095 if ( cseq->method.id != PJSIP_ACK_METHOD) {1983 if (msg->line.req.method.id != PJSIP_ACK_METHOD) { 2096 1984 pj_status_t status; 2097 1985 2098 status = pjsip_tsx_retransmit( tsx, 0 );1986 status = tsx_retransmit( tsx, 0 ); 2099 1987 if (status != PJ_SUCCESS) { 2100 1988 return status; … … 2123 2011 pj_status_t status; 2124 2012 2125 status = pjsip_tsx_retransmit( tsx, 1 );2013 status = tsx_retransmit( tsx, 1 ); 2126 2014 if (status != PJ_SUCCESS) { 2127 2015 return status; … … 2140 2028 PJSIP_EVENT_TIMER, &tsx->timeout_timer ); 2141 2029 2142 return PJSIP_ETSXDESTROYED;2030 //return PJSIP_ETSXDESTROYED; 2143 2031 2144 2032 } else { … … 2146 2034 tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED, 2147 2035 PJSIP_EVENT_TIMER, &tsx->timeout_timer ); 2148 return PJSIP_ETSXDESTROYED;2036 //return PJSIP_ETSXDESTROYED; 2149 2037 } 2150 2038 } … … 2152 2040 } else { 2153 2041 /* Ignore request to transmit. */ 2154 pj_assert(event->body.tx_msg.tdata == tsx->last_tx); 2042 PJ_ASSERT_RETURN(event->type == PJSIP_EVENT_TX_MSG && 2043 event->body.tx_msg.tdata == tsx->last_tx, 2044 PJ_EINVALIDOP); 2155 2045 } 2156 2046 … … 2158 2048 } 2159 2049 2050 2160 2051 /* 2161 2052 * Handler for events in Completed state for UAC transaction. 2162 2053 */ 2163 static pj_status_t pjsip_tsx_on_state_completed_uac( pjsip_transaction *tsx,2164 2054 static pj_status_t tsx_on_state_completed_uac( pjsip_transaction *tsx, 2055 pjsip_event *event) 2165 2056 { 2166 2057 pj_assert(tsx->state == PJSIP_TSX_STATE_COMPLETED); … … 2175 2066 2176 2067 /* Transaction has been destroyed. */ 2177 return PJSIP_ETSXDESTROYED;2068 //return PJSIP_ETSXDESTROYED; 2178 2069 2179 2070 } else if (event->type == PJSIP_EVENT_RX_MSG) { … … 2189 2080 pj_status_t status; 2190 2081 2191 status = pjsip_tsx_retransmit( tsx, 0 );2082 status = tsx_retransmit( tsx, 0 ); 2192 2083 if (status != PJ_SUCCESS) { 2193 2084 return status; … … 2200 2091 /* Just drop the response. */ 2201 2092 } 2202 } else if (tsx->method.id == PJSIP_INVITE_METHOD &&2203 event->type == PJSIP_EVENT_TX_MSG &&2204 event->body.tx_msg.tdata->msg->line.req.method.id==PJSIP_ACK_METHOD) {2205 2206 pj_status_t status;2207 2208 /* Set last transmitted message. */2209 if (tsx->last_tx != event->body.tx_msg.tdata) {2210 pjsip_tx_data_dec_ref( tsx->last_tx );2211 tsx->last_tx = event->body.tx_msg.tdata;2212 pjsip_tx_data_add_ref( tsx->last_tx );2213 }2214 2215 /* No state changed, but notify app.2216 * Must notify now, so app has chance to put SDP in outgoing ACK msg.2217 */2218 tsx_set_state( tsx, PJSIP_TSX_STATE_COMPLETED,2219 PJSIP_EVENT_TX_MSG, event->body.tx_msg.tdata );2220 2221 /* Send msg */2222 status = tsx_send_msg(tsx, event->body.tx_msg.tdata);2223 if (status != PJ_SUCCESS)2224 return status;2225 2093 2226 2094 } else { 2227 pj_assert( 0);2228 return PJ_E BUG;2095 pj_assert(!"Unexpected event"); 2096 return PJ_EINVALIDOP; 2229 2097 } 2230 2098 … … 2232 2100 } 2233 2101 2102 2234 2103 /* 2235 2104 * Handler for events in state Confirmed. 2236 2105 */ 2237 static pj_status_t pjsip_tsx_on_state_confirmed( pjsip_transaction *tsx,2238 2106 static pj_status_t tsx_on_state_confirmed( pjsip_transaction *tsx, 2107 pjsip_event *event) 2239 2108 { 2240 2109 pj_assert(tsx->state == PJSIP_TSX_STATE_CONFIRMED); … … 2247 2116 if (event->type == PJSIP_EVENT_RX_MSG) { 2248 2117 2249 pjsip_method_e method_id = 2250 event->body.rx_msg.rdata->msg_info.msg->line.req.method.id; 2251 2252 /* Must be a request message. */2253 pj_assert(event->body.rx_msg.rdata->msg_info.msg->type == PJSIP_REQUEST_MSG);2118 pjsip_msg *msg = event->body.rx_msg.rdata->msg_info.msg; 2119 2120 /* Only expecting request message. */ 2121 if (msg->type != PJSIP_REQUEST_MSG) 2122 return PJSIP_ENOTREQUESTMSG; 2254 2123 2255 2124 /* Must be an ACK request or a late INVITE retransmission. */ 2256 pj_assert(method_id == PJSIP_ACK_METHOD || 2257 method_id == PJSIP_INVITE_METHOD); 2258 2259 /* Just so that compiler won't complain about unused vars when 2260 * building release code. 2261 */ 2262 PJ_UNUSED_ARG(method_id); 2125 pj_assert(msg->line.req.method.id == PJSIP_ACK_METHOD || 2126 msg->line.req.method.id == PJSIP_INVITE_METHOD); 2263 2127 2264 2128 } else if (event->type == PJSIP_EVENT_TIMER) { … … 2271 2135 2272 2136 /* Transaction has been destroyed. */ 2273 return PJSIP_ETSXDESTROYED;2137 //return PJSIP_ETSXDESTROYED; 2274 2138 2275 2139 } else { 2276 pj_assert( 0);2140 pj_assert(!"Unexpected event"); 2277 2141 return PJ_EBUG; 2278 2142 } … … 2281 2145 } 2282 2146 2147 2283 2148 /* 2284 2149 * Handler for events in state Terminated. 2285 2150 */ 2286 static pj_status_t pjsip_tsx_on_state_terminated( pjsip_transaction *tsx,2287 2151 static pj_status_t tsx_on_state_terminated( pjsip_transaction *tsx, 2152 pjsip_event *event) 2288 2153 { 2289 2154 pj_assert(tsx->state == PJSIP_TSX_STATE_TERMINATED); 2290 2291 PJ_UNUSED_ARG(event); 2155 pj_assert(event->type == PJSIP_EVENT_TIMER); 2292 2156 2293 2157 /* Destroy this transaction */ … … 2299 2163 2300 2164 2301 static pj_status_t pjsip_tsx_on_state_destroyed(pjsip_transaction *tsx, 2302 pjsip_event *event) 2165 /* 2166 * Handler for events in state Destroyed. 2167 * Shouldn't happen! 2168 */ 2169 static pj_status_t tsx_on_state_destroyed(pjsip_transaction *tsx, 2170 pjsip_event *event) 2303 2171 { 2304 2172 PJ_UNUSED_ARG(tsx); 2305 2173 PJ_UNUSED_ARG(event); 2306 return PJ_SUCCESS; 2307 } 2308 2174 pj_assert(!"Not expecting any events!!"); 2175 return PJ_EBUG; 2176 } 2177
Note: See TracChangeset
for help on using the changeset viewer.