- Timestamp:
- Jan 7, 2006 6:44:25 PM (19 years ago)
- Location:
- pjproject/trunk/pjsip
- Files:
-
- 2 added
- 26 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjsip/build/pjsip_core.dsp
r107 r109 128 128 !IF "$(CFG)" == "pjsip_core - Win32 Release" 129 129 130 # PROP Exclude_From_Build 1131 132 130 !ELSEIF "$(CFG)" == "pjsip_core - Win32 Debug" 133 131 -
pjproject/trunk/pjsip/build/test_pjsip.dsp
r107 r109 94 94 # Begin Source File 95 95 96 SOURCE="..\src\test-pjsip\msg_logger.c" 97 # End Source File 98 # Begin Source File 99 96 100 SOURCE="..\src\test-pjsip\msg_test.c" 97 101 # End Source File … … 111 115 112 116 SOURCE="..\src\test-pjsip\transport_udp_test.c" 117 # End Source File 118 # Begin Source File 119 120 SOURCE="..\src\test-pjsip\tsx_basic_test.c" 113 121 # End Source File 114 122 # Begin Source File -
pjproject/trunk/pjsip/include/pjsip/sip_errno.h
r107 r109 24 24 PJ_BEGIN_DECL 25 25 26 /** 27 * Guidelines on error message length. 28 */ 29 #define PJSIP_ERR_MSG_SIZE 64 30 26 31 /* 27 32 * PJSIP error codes occupies 170000 - 219000, and mapped as follows: … … 87 92 */ 88 93 #define PJSIP_ETYPEEXISTS (PJSIP_ERRNO_START_PJSIP + 2) /* 171002 */ 94 /** 95 * @hideinitializer 96 * SIP stack is shutting down. 97 */ 98 #define PJSIP_ESHUTDOWN (PJSIP_ERRNO_START_PJSIP + 3) /* 171003 */ 89 99 90 100 -
pjproject/trunk/pjsip/include/pjsip/sip_module.h
r106 r109 134 134 135 135 /** 136 * Called to process outgoing request. 137 * 138 * @param tdata The outgoing request message. 139 * 140 * @return Module should return PJ_SUCCESS in all cases. 141 * If non-zero (or PJ_FALSE) is returned, the message 142 * will not be sent. 143 */ 144 pj_status_t (*on_tx_request)(pjsip_tx_data *tdata); 145 146 /** 147 * Called to process outgoing response message. 148 * 149 * @param tdata The outgoing response message. 150 * 151 * @return Module should return PJ_SUCCESS in all cases. 152 * If non-zero (or PJ_FALSE) is returned, the message 153 * will not be sent. 154 */ 155 pj_status_t (*on_tx_response)(pjsip_tx_data *tdata); 156 157 /** 136 158 * Called when this module is acting as transaction user for the specified 137 159 * transaction, when the transaction's state has changed. … … 151 173 enum pjsip_module_priority 152 174 { 153 PJSIP_MOD_PRIORITY_TSX_LAYER = 4, 154 PJSIP_MOD_PRIORITY_UA_PROXY_LAYER = 16, 155 PJSIP_MOD_PRIORITY_APPLICATION = 32, 175 PJSIP_MOD_PRIORITY_TRANSPORT_LAYER = 8, 176 PJSIP_MOD_PRIORITY_TSX_LAYER = 16, 177 PJSIP_MOD_PRIORITY_UA_PROXY_LAYER = 32, 178 PJSIP_MOD_PRIORITY_APPLICATION = 64, 156 179 }; 157 180 -
pjproject/trunk/pjsip/include/pjsip/sip_msg.h
r107 r109 377 377 378 378 PJSIP_SC_OK = 200, 379 PJSIP_SC_ACCEPTED = 202, 379 380 380 381 PJSIP_SC_MULTIPLE_CHOICES = 300, … … 400 401 PJSIP_SC_BAD_EXTENSION = 420, 401 402 PJSIP_SC_EXTENSION_REQUIRED = 421, 403 PJSIP_SC_SESSION_TIMER_TOO_SMALL = 422, 402 404 PJSIP_SC_INTERVAL_TOO_BRIEF = 423, 403 405 PJSIP_SC_TEMPORARILY_UNAVAILABLE = 480, … … 410 412 PJSIP_SC_REQUEST_TERMINATED = 487, 411 413 PJSIP_SC_NOT_ACCEPTABLE_HERE = 488, 414 PJSIP_SC_UNKNOWN_EVENT = 489, 415 PJSIP_SC_REQUEST_UPDATED = 490, 412 416 PJSIP_SC_REQUEST_PENDING = 491, 413 417 PJSIP_SC_UNDECIPHERABLE = 493, … … 420 424 PJSIP_SC_VERSION_NOT_SUPPORTED = 505, 421 425 PJSIP_SC_MESSAGE_TOO_LARGE = 513, 426 PJSIP_SC_PRECONDITION_FAILURE = 580, 422 427 423 428 PJSIP_SC_BUSY_EVERYWHERE = 600, … … 427 432 428 433 PJSIP_SC_TSX_TIMEOUT = 701, 429 PJSIP_SC_TSX_RESOLVE_ERROR = 702,434 //PJSIP_SC_TSX_RESOLVE_ERROR = 702, 430 435 PJSIP_SC_TSX_TRANSPORT_ERROR = 703, 431 436 -
pjproject/trunk/pjsip/include/pjsip/sip_transaction.h
r107 r109 93 93 */ 94 94 pjsip_transport *transport; /**< Transport to use. */ 95 pj_bool_t is_reliable; /**< Transport is reliable. */ 95 96 pj_sockaddr addr; /**< Destination address. */ 96 97 int addr_len; /**< Address length. */ … … 190 191 /** 191 192 * Transmit message in tdata with this transaction. It is possible to 192 * pass NULL in tdata for UAC transaction, which in this case the request 193 * message which was specified in #pjsip_tsx_create_uac() will be sent. 193 * pass NULL in tdata for UAC transaction, which in this case the last message 194 * or the request message which was specified in #pjsip_tsx_create_uac() 195 * will be sent. 196 * 197 * This function decrements the reference counter of the transmit buffer. 194 198 * 195 199 * @param tsx The transaction. 196 * @param tdata The outgoing message. 200 * @param tdata The outgoing message. If NULL is specified, then the 201 * last message transmitted (or the message specified 202 * in UAC initialization) will be sent. 197 203 * 198 204 * @return PJ_SUCCESS if successfull. -
pjproject/trunk/pjsip/include/pjsip/sip_transport.h
r107 r109 110 110 pjsip_transport_get_default_port_for_type(pjsip_transport_type_e type); 111 111 112 /** 113 * Get transport type name. 114 * 115 * @param t Transport type. 116 * 117 * @return Transport name. 118 */ 119 PJ_DECL(const char*) pjsip_transport_get_type_name(pjsip_transport_type_e t); 120 112 121 113 122 /***************************************************************************** … … 203 212 /** The parsed message, if any. */ 204 213 pjsip_msg *msg; 214 215 /** Short description about the message. 216 * Application should use #pjsip_rx_data_get_info() instead. 217 */ 218 char *info; 205 219 206 220 /** The Call-ID header as found in the message. */ … … 259 273 260 274 }; 275 276 /** 277 * Get printable information about the message in the rdata. 278 * 279 * @param rdata The receive data buffer. 280 * 281 * @return Printable information. 282 */ 283 PJ_DECL(char*) pjsip_rx_data_get_info(pjsip_rx_data *rdata); 261 284 262 285 … … 304 327 char obj_name[PJ_MAX_OBJ_NAME]; 305 328 329 /** Short information describing this buffer and the message in it. 330 * Application should use #pjsip_tx_data_get_info() instead of 331 * directly accessing this member. 332 */ 333 char *info; 334 306 335 /** For response message, this contains the reference to timestamp when 307 336 * the original request message was received. The value of this field … … 340 369 void *token; 341 370 void (*cb)(void*, pjsip_tx_data*, pj_ssize_t); 371 372 /** Transport information, only valid during on_tx_request() and 373 * on_tx_response() callback. 374 */ 375 struct 376 { 377 pjsip_transport *transport; /**< Transport being used. */ 378 pj_sockaddr dst_addr; /**< Destination address. */ 379 int dst_addr_len; /**< Length of address. */ 380 char dst_name[16]; /**< Destination address. */ 381 int dst_port; /**< Destination port. */ 382 } tp_info; 342 383 }; 343 384 … … 397 438 */ 398 439 PJ_DECL(void) pjsip_tx_data_invalidate_msg( pjsip_tx_data *tdata ); 440 441 /** 442 * Get short printable info about the transmit data. This will normally return 443 * short information about the message. 444 * 445 * @param tdata The transmit buffer. 446 * 447 * @return Null terminated info string. 448 */ 449 PJ_DECL(char*) pjsip_tx_data_get_info( pjsip_tx_data *tdata ); 399 450 400 451 … … 594 645 * @param pool Pool. 595 646 * @param endpt Endpoint instance. 596 * @param cb Callback to receive incoming message. 647 * @param rx_cb Callback to receive incoming message. 648 * @param tx_cb Callback to be called before transport manager is sending 649 * outgoing message. 597 650 * @param p_mgr Pointer to receive the new transport manager. 598 651 * … … 601 654 PJ_DECL(pj_status_t) pjsip_tpmgr_create( pj_pool_t *pool, 602 655 pjsip_endpoint * endpt, 603 void (*cb)(pjsip_endpoint*, 604 pj_status_t, 605 pjsip_rx_data *), 656 void (*rx_cb)(pjsip_endpoint*, 657 pj_status_t, 658 pjsip_rx_data *), 659 pj_status_t (*tx_cb)(pjsip_endpoint*, 660 pjsip_tx_data*), 606 661 pjsip_tpmgr **p_mgr); 607 662 -
pjproject/trunk/pjsip/include/pjsip/sip_transport_loop.h
r107 r109 59 59 * 60 60 * @param tp The loop transport. 61 * @param fail_flag If set to 1, the transport will return immediate error. 62 * If set to 2, the transport will return error via 63 * callback. If zero, the transport will deliver 61 * @param fail_flag If set to 1, the transport will return fail to deliver 62 * the message. If delay is zero, failure will occur 63 * immediately; otherwise it will be reported in callback. 64 * If set to zero, the transport will successfully deliver 64 65 * the packet. 65 66 * @param prev_value Optional argument to receive previous value of … … 74 75 75 76 /** 76 * Set delay (in miliseconds) before packet is delivered. This will also 77 * Set delay (in miliseconds) before packet is received by the other end 78 * of the loop transport. This will also 77 79 * control the delay for error notification callback. 78 80 * … … 84 86 * @return PJ_SUCCESS on success. 85 87 */ 88 PJ_DECL(pj_status_t) pjsip_loop_set_recv_delay( pjsip_transport *tp, 89 unsigned delay, 90 unsigned *prev_value); 91 92 93 /** 94 * Set delay (in miliseconds) before send notification is delivered to sender. 95 * This will also control the delay for error notification callback. 96 * 97 * @param tp The loop transport. 98 * @param delay Delay, in miliseconds. 99 * @param prev_value Optional argument to receive previous value of the 100 * delay. 101 * 102 * @return PJ_SUCCESS on success. 103 */ 104 PJ_DECL(pj_status_t) pjsip_loop_set_send_callback_delay( pjsip_transport *tp, 105 unsigned delay, 106 unsigned *prev_value); 107 108 109 /** 110 * Set both receive and send notification delay. 111 * 112 * @param tp The loop transport. 113 * @param delay Delay, in miliseconds. 114 * 115 * @return PJ_SUCCESS on success. 116 */ 86 117 PJ_DECL(pj_status_t) pjsip_loop_set_delay( pjsip_transport *tp, 87 unsigned delay ,88 unsigned *prev_value); 118 unsigned delay ); 119 89 120 90 121 PJ_END_DECL -
pjproject/trunk/pjsip/src/pjsip/sip_endpoint.c
r107 r109 36 36 37 37 #define PJSIP_EX_NO_MEMORY PJ_NO_MEMORY_EXCEPTION 38 #define THIS_FILE " endpoint"38 #define THIS_FILE "sip_endpoint.c" 39 39 40 40 #define MAX_METHODS 32 … … 99 99 * Prototypes. 100 100 */ 101 static void endpt_transport_callback(pjsip_endpoint*, 102 pj_status_t, pjsip_rx_data*); 101 static void endpt_on_rx_msg( pjsip_endpoint*, 102 pj_status_t, pjsip_rx_data*); 103 static pj_status_t endpt_on_tx_msg( pjsip_endpoint *endpt, 104 pjsip_tx_data *tdata ); 103 105 104 106 /* Defined in sip_parser.c */ … … 230 232 pj_list_erase(mod); 231 233 234 /* Set module Id to -1. */ 235 mod->id = -1; 236 232 237 /* Done. */ 233 238 status = PJ_SUCCESS; … … 313 318 pj_lock_t *lock = NULL; 314 319 315 PJ_LOG(5, (THIS_FILE, " pjsip_endpt_create()"));320 PJ_LOG(5, (THIS_FILE, "Creating endpoint instance...")); 316 321 317 322 *p_endpt = NULL; … … 383 388 /* Create transport manager. */ 384 389 status = pjsip_tpmgr_create( endpt->pool, endpt, 385 &endpt_transport_callback, 390 &endpt_on_rx_msg, 391 &endpt_on_tx_msg, 386 392 &endpt->transport_mgr); 387 393 if (status != PJ_SUCCESS) { … … 392 398 endpt->resolver = pjsip_resolver_create(endpt->pool); 393 399 if (!endpt->resolver) { 394 PJ_LOG(4, (THIS_FILE, " pjsip_endpt_init(): error creating resolver"));400 PJ_LOG(4, (THIS_FILE, "Error creating resolver instance")); 395 401 goto on_error; 396 402 } … … 426 432 pj_pool_release( endpt->pool ); 427 433 428 PJ_LOG(4, (THIS_FILE, " pjsip_endpt_init() failed"));434 PJ_LOG(4, (THIS_FILE, "Error creating endpoint")); 429 435 return status; 430 436 } … … 435 441 PJ_DEF(void) pjsip_endpt_destroy(pjsip_endpoint *endpt) 436 442 { 437 PJ_LOG(5, (THIS_FILE, "pjsip_endpt_destroy()")); 443 pjsip_module *mod; 444 445 PJ_LOG(5, (THIS_FILE, "Destroying endpoing instance..")); 446 447 /* Unregister modules. */ 448 while ((mod=endpt->module_list.prev) != &endpt->module_list) { 449 pjsip_endpt_unregister_module(endpt, mod); 450 } 438 451 439 452 /* Shutdown and destroy all transports. */ … … 445 458 /* Finally destroy pool. */ 446 459 pj_pool_release(endpt->pool); 460 461 PJ_LOG(4, (THIS_FILE, "Endpoint %p destroyed", endpt)); 447 462 } 448 463 … … 466 481 pj_pool_t *pool; 467 482 468 PJ_LOG(5, (THIS_FILE, "pjsip_endpt_create_pool()"));469 470 483 /* Lock endpoint mutex. */ 471 484 pj_mutex_lock(endpt->mutex); … … 478 491 pj_mutex_unlock(endpt->mutex); 479 492 480 if (pool) { 481 PJ_LOG(5, (THIS_FILE, " pool %s created", pj_pool_getobjname(pool))); 482 } else { 493 if (!pool) { 483 494 PJ_LOG(4, (THIS_FILE, "Unable to create pool %s!", pool_name)); 484 495 } … … 493 504 PJ_DEF(void) pjsip_endpt_release_pool( pjsip_endpoint *endpt, pj_pool_t *pool ) 494 505 { 495 PJ_LOG( 5, (THIS_FILE, "pjsip_endpt_release_pool(%s)", pj_pool_getobjname(pool)));506 PJ_LOG(6, (THIS_FILE, "Releasing pool %s", pj_pool_getobjname(pool))); 496 507 497 508 pj_mutex_lock(endpt->mutex); … … 509 520 pj_time_val timeout = { 0, 0}; 510 521 511 PJ_LOG( 5, (THIS_FILE, "pjsip_endpt_handle_events()"));522 PJ_LOG(6, (THIS_FILE, "pjsip_endpt_handle_events()")); 512 523 513 524 /* Poll the timer. The timer heap has its own mutex for better … … 535 546 const pj_time_val *delay ) 536 547 { 537 PJ_LOG( 5, (THIS_FILE, "pjsip_endpt_schedule_timer(entry=%p, delay=%u.%u)",548 PJ_LOG(6, (THIS_FILE, "pjsip_endpt_schedule_timer(entry=%p, delay=%u.%u)", 538 549 entry, delay->sec, delay->msec)); 539 550 return pj_timer_heap_schedule( endpt->timer_heap, entry, delay ); … … 546 557 pj_timer_entry *entry ) 547 558 { 548 PJ_LOG( 5, (THIS_FILE, "pjsip_endpt_cancel_timer(entry=%p)", entry));559 PJ_LOG(6, (THIS_FILE, "pjsip_endpt_cancel_timer(entry=%p)", entry)); 549 560 pj_timer_heap_cancel( endpt->timer_heap, entry ); 550 561 } … … 554 565 * receives a message from the network. 555 566 */ 556 static void endpt_ transport_callback( pjsip_endpoint *endpt,567 static void endpt_on_rx_msg( pjsip_endpoint *endpt, 557 568 pj_status_t status, 558 569 pjsip_rx_data *rdata ) 559 570 { 560 571 pjsip_msg *msg = rdata->msg_info.msg; 561 562 PJ_LOG(5, (THIS_FILE, "endpt_transport_callback(rdata=%p)", rdata));563 572 564 573 if (status != PJ_SUCCESS) { … … 572 581 return; 573 582 } 583 584 PJ_LOG(5, (THIS_FILE, "Processing incoming message: %s", 585 pjsip_rx_data_get_info(rdata))); 574 586 575 587 /* For response, check that the value in Via sent-by match the transport. … … 601 613 mismatch = PJ_TRUE; 602 614 else { 603 PJ_LOG(4,(THIS_FILE, " Response %pfrom %s has mismatch port in "615 PJ_LOG(4,(THIS_FILE, "Message %s from %s has mismatch port in " 604 616 "sent-by but the rport parameter is " 605 617 "correct", 606 rdata, rdata->pkt_info.src_name)); 618 pjsip_rx_data_get_info(rdata), 619 rdata->pkt_info.src_name)); 607 620 } 608 621 } … … 610 623 if (mismatch) { 611 624 PJ_TODO(ENDPT_REPORT_WHEN_DROPPING_MESSAGE); 612 PJ_LOG(4,(THIS_FILE, "Dropping response from %s:%d because sent-by" 613 " is mismatch", 625 PJ_LOG(4,(THIS_FILE, "Dropping response %s from %s:%d because " 626 "sent-by is mismatch", 627 pjsip_rx_data_get_info(rdata), 614 628 rdata->pkt_info.src_name, 615 629 rdata->pkt_info.src_port)); … … 619 633 620 634 621 /* Distribute to modules .*/635 /* Distribute to modules, starting from modules with highest priority */ 622 636 pj_rwmutex_lock_read(endpt->mod_mutex); 623 637 … … 638 652 if (!handled) { 639 653 PJ_TODO(ENDPT_RESPOND_UNHANDLED_REQUEST); 640 PJ_LOG(4,(THIS_FILE, "Request from %s:%d was dropped/unhandled by" 641 " any modules")); 654 PJ_LOG(4,(THIS_FILE, "Message %s from %s:%d was dropped/unhandled by" 655 " any modules", 656 pjsip_rx_data_get_info(rdata), 657 rdata->pkt_info.src_name, 658 rdata->pkt_info.src_port)); 642 659 } 643 660 … … 656 673 657 674 if (!handled) { 658 PJ_LOG(4,(THIS_FILE, "Response from %s:%d was dropped/unhandled by" 659 " any modules")); 675 PJ_LOG(4,(THIS_FILE, "Message %s from %s:%d was dropped/unhandled" 676 " by any modules", 677 pjsip_rx_data_get_info(rdata), 678 rdata->pkt_info.src_name, 679 rdata->pkt_info.src_port)); 660 680 } 661 681 } … … 663 683 pj_rwmutex_unlock_read(endpt->mod_mutex); 664 684 } 685 686 /* 687 * This callback is called by transport manager before message is sent. 688 * Modules may inspect the message before it's actually sent. 689 */ 690 static pj_status_t endpt_on_tx_msg( pjsip_endpoint *endpt, 691 pjsip_tx_data *tdata ) 692 { 693 pj_status_t status = PJ_SUCCESS; 694 pjsip_module *mod; 695 696 /* Distribute to modules, starting from modules with LOWEST priority */ 697 pj_rwmutex_lock_read(endpt->mod_mutex); 698 699 mod = endpt->module_list.prev; 700 if (tdata->msg->type == PJSIP_REQUEST_MSG) { 701 while (mod != &endpt->module_list) { 702 if (mod->on_tx_request) 703 status = (*mod->on_tx_request)(tdata); 704 if (status != PJ_SUCCESS) 705 break; 706 mod = mod->prev; 707 } 708 709 } else { 710 while (mod != &endpt->module_list) { 711 if (mod->on_tx_response) 712 status = (*mod->on_tx_response)(tdata); 713 if (status != PJ_SUCCESS) 714 break; 715 mod = mod->prev; 716 } 717 } 718 719 pj_rwmutex_unlock_read(endpt->mod_mutex); 720 721 return status; 722 } 723 665 724 666 725 /* … … 670 729 pjsip_tx_data **p_tdata) 671 730 { 672 PJ_LOG(5, (THIS_FILE, "pjsip_endpt_create_tdata()"));673 731 return pjsip_tx_data_create(endpt->transport_mgr, p_tdata); 674 732 } … … 683 741 pjsip_resolver_callback *cb) 684 742 { 685 PJ_LOG(5, (THIS_FILE, "pjsip_endpt_resolve()"));686 743 pjsip_resolve( endpt->resolver, pool, target, token, cb); 687 744 } … … 712 769 pjsip_transport **transport) 713 770 { 714 PJ_LOG(5, (THIS_FILE, "pjsip_endpt_acquire_transport()"));715 771 return pjsip_tpmgr_acquire_transport(endpt->transport_mgr, type, 716 772 remote, addr_len, transport); -
pjproject/trunk/pjsip/src/pjsip/sip_errno.c
r107 r109 34 34 { PJSIP_EBUSY, "Object is busy" }, 35 35 { PJSIP_ETYPEEXISTS , "Object with the same type exists" }, 36 { PJSIP_ESHUTDOWN, "SIP stack shutting down" }, 36 37 37 38 /* Messaging errors */ -
pjproject/trunk/pjsip/src/pjsip/sip_msg.c
r107 r109 118 118 119 119 pj_strset2( &status_phrase[200], "OK"); 120 pj_strset2( &status_phrase[202], "Accepted"); 120 121 121 122 pj_strset2( &status_phrase[300], "Multiple Choices"); … … 141 142 pj_strset2( &status_phrase[420], "Bad Extension"); 142 143 pj_strset2( &status_phrase[421], "Extension Required"); 144 pj_strset2( &status_phrase[422], "Session Timer Too Small"); 143 145 pj_strset2( &status_phrase[423], "Interval Too Brief"); 144 146 pj_strset2( &status_phrase[480], "Temporarily Unavailable"); … … 151 153 pj_strset2( &status_phrase[487], "Request Terminated"); 152 154 pj_strset2( &status_phrase[488], "Not Acceptable Here"); 155 pj_strset2( &status_phrase[489], "Unknown Event"); 156 pj_strset2( &status_phrase[490], "Request Updated"); 153 157 pj_strset2( &status_phrase[491], "Request Pending"); 154 158 pj_strset2( &status_phrase[493], "Undecipherable"); … … 161 165 pj_strset2( &status_phrase[505], "Version Not Supported"); 162 166 pj_strset2( &status_phrase[513], "Message Too Large"); 167 pj_strset2( &status_phrase[580], "Precondition Failure"); 163 168 164 169 pj_strset2( &status_phrase[600], "Busy Everywhere"); -
pjproject/trunk/pjsip/src/pjsip/sip_resolve.c
r105 r109 19 19 #include <pjsip/sip_resolve.h> 20 20 #include <pjsip/sip_transport.h> 21 #include <pjsip/sip_errno.h> 21 22 #include <pj/pool.h> 22 23 #include <pj/ctype.h> 23 24 #include <pj/assert.h> 25 #include <pj/log.h> 26 27 #define THIS_FILE "sip_resolve.c" 24 28 25 29 struct pjsip_resolver_t … … 68 72 PJ_UNUSED_ARG(resolver); 69 73 PJ_UNUSED_ARG(pool); 74 75 PJ_LOG(5,(THIS_FILE, "Resolving server '%.*s:%d' type=%s", 76 target->addr.host.slen, 77 target->addr.host.ptr, 78 target->addr.port, 79 pjsip_transport_get_type_name(type))); 70 80 71 81 /* We only do synchronous resolving at this moment. */ … … 117 127 &target->addr.host, 118 128 (pj_uint16_t)target->addr.port); 119 pj_assert(status == PJ_SUCCESS); 129 } 130 131 if (status != PJ_SUCCESS) { 132 char errmsg[PJSIP_ERR_MSG_SIZE]; 133 PJ_LOG(4,(THIS_FILE, "Failed to resolve '%.*s'. Err=%d (%s)", 134 target->addr.host.slen, 135 target->addr.host.ptr, 136 status, 137 pjsip_strerror(status,errmsg,sizeof(errmsg)).ptr)); 138 (*cb)(status, token, &svr_addr); 139 return; 120 140 } 121 141 122 142 /* Call the callback. */ 143 PJ_LOG(5,(THIS_FILE, "Server resolved: '%.*s:%d' type=%s has %d entries, " 144 "entry[0]=%s:%d type=%s", 145 target->addr.host.slen, 146 target->addr.host.ptr, 147 target->addr.port, 148 pjsip_transport_get_type_name(type), 149 1, 150 pj_inet_ntoa(((pj_sockaddr_in*)&svr_addr.entry[0].addr)->sin_addr), 151 target->addr.port, 152 pjsip_transport_get_type_name(type))); 123 153 svr_addr.count = (status == PJ_SUCCESS) ? 1 : 0; 124 154 svr_addr.entry[0].type = type; -
pjproject/trunk/pjsip/src/pjsip/sip_transaction.c
r107 r109 30 30 #include <pj/guid.h> 31 31 #include <pj/log.h> 32 33 #define THIS_FILE "sip_transaction.c" 32 34 33 35 /***************************************************************************** … … 102 104 TSX_HAS_PENDING_SEND = 4, 103 105 TSX_HAS_PENDING_DESTROY = 8, 106 TSX_HAS_RESOLVED_SERVER = 16, 104 107 }; 105 108 … … 413 416 PJ_ASSERT_RETURN(mod_tsx_layer.endpt==NULL, PJ_EINVALIDOP); 414 417 418 PJ_LOG(5,(THIS_FILE, "Initializing transaction layer module")); 415 419 416 420 /* Initialize TLS ID for transaction lock. */ … … 462 466 } 463 467 468 PJ_LOG(4,(THIS_FILE, "Transaction layer module initialized")); 469 464 470 return PJ_SUCCESS; 465 471 } … … 581 587 pj_hash_iterator_t it_buf, *it; 582 588 589 PJ_LOG(4,(THIS_FILE, "Stopping transaction layer module")); 590 583 591 pj_mutex_lock(mod_tsx_layer.mutex); 584 592 … … 587 595 while (it) { 588 596 pjsip_transaction *tsx = pj_hash_this(mod_tsx_layer.htable, it); 597 pj_hash_iterator_t *next = pj_hash_next(mod_tsx_layer.htable, it); 589 598 if (tsx) 590 599 tsx_destroy(tsx); 591 it = pj_hash_next(mod_tsx_layer.htable, it);600 it = next; 592 601 } 593 602 … … 611 620 mod_tsx_layer.endpt = NULL; 612 621 622 PJ_LOG(4,(THIS_FILE, "Transaction layer module destroyed")); 623 613 624 return PJ_SUCCESS; 614 625 } … … 628 639 /* Find transaction. */ 629 640 pj_mutex_lock( mod_tsx_layer.mutex ); 641 630 642 tsx = pj_hash_get( mod_tsx_layer.htable, key.ptr, key.slen ); 643 631 644 if (tsx == NULL || tsx->state == PJSIP_TSX_STATE_TERMINATED) { 632 645 /* Transaction not found. … … 667 680 /* Find transaction. */ 668 681 pj_mutex_lock( mod_tsx_layer.mutex ); 682 669 683 tsx = pj_hash_get( mod_tsx_layer.htable, key.ptr, key.slen ); 684 670 685 if (tsx == NULL || tsx->state == PJSIP_TSX_STATE_TERMINATED) { 671 686 /* Transaction not found. … … 791 806 static void tsx_destroy( pjsip_transaction *tsx ) 792 807 { 808 struct tsx_lock_data *lck; 809 810 /* Decrement transport reference counter. */ 811 if (tsx->transport) { 812 pjsip_transport_dec_ref( tsx->transport ); 813 tsx->transport = NULL; 814 } 815 /* Free last transmitted message. */ 816 if (tsx->last_tx) { 817 pjsip_tx_data_dec_ref( tsx->last_tx ); 818 tsx->last_tx = NULL; 819 } 820 /* Cancel timeout timer. */ 821 if (tsx->timeout_timer._timer_id != -1) { 822 pjsip_endpt_cancel_timer(tsx->endpt, &tsx->timeout_timer); 823 tsx->timeout_timer._timer_id = -1; 824 } 825 /* Cancel retransmission timer. */ 826 if (tsx->retransmit_timer._timer_id != -1) { 827 pjsip_endpt_cancel_timer(tsx->endpt, &tsx->retransmit_timer); 828 tsx->retransmit_timer._timer_id = -1; 829 } 830 831 /* Clear some pending flags. */ 832 tsx->transport_flag &= ~(TSX_HAS_PENDING_RESCHED | TSX_HAS_PENDING_SEND); 833 834 /* Refuse to destroy transaction if it has pending resolving. */ 835 if (tsx->transport_flag & TSX_HAS_PENDING_TRANSPORT) { 836 tsx->transport_flag |= TSX_HAS_PENDING_DESTROY; 837 PJ_LOG(5,(tsx->obj_name, "Will destroy later because transport is " 838 "in progress")); 839 return; 840 } 841 842 /* Clear TLS, so that mutex will not be unlocked */ 843 lck = pj_thread_local_get(pjsip_tsx_lock_tls_id); 844 while (lck) { 845 if (lck->tsx == tsx) { 846 lck->is_alive = 0; 847 } 848 lck = lck->prev; 849 } 850 793 851 pj_mutex_destroy(tsx->mutex); 852 853 PJ_LOG(5,(tsx->obj_name, "Transaction destroyed!")); 854 794 855 pjsip_endpt_release_pool(tsx->endpt, tsx->pool); 795 856 } … … 807 868 PJ_UNUSED_ARG(theap); 808 869 809 PJ_LOG( 5,(tsx->obj_name, "got timer event (%s timer)",870 PJ_LOG(6,(tsx->obj_name, "%s timer event", 810 871 (entry->id==TSX_TIMER_RETRANSMISSION ? "Retransmit":"Timeout"))); 811 872 … … 832 893 void *event_src ) 833 894 { 834 PJ_LOG( 4, (tsx->obj_name, "STATE %s-->%s, cause =%s",895 PJ_LOG(5, (tsx->obj_name, "State changed from %s to %s, event=%s", 835 896 state_str[tsx->state], state_str[state], 836 897 pjsip_event_str(event_src_type))); … … 860 921 pj_time_val timeout = {0, 0}; 861 922 862 /* Decrement transport reference counter. */863 if (tsx->transport) {864 pjsip_transport_dec_ref( tsx->transport );865 tsx->transport = NULL;866 }867 /* Free last transmitted message. */868 if (tsx->last_tx) {869 pjsip_tx_data_dec_ref( tsx->last_tx );870 tsx->last_tx = NULL;871 }872 /* Cancel timeout timer. */873 if (tsx->timeout_timer._timer_id != -1) {874 pjsip_endpt_cancel_timer(tsx->endpt, &tsx->timeout_timer);875 tsx->timeout_timer._timer_id = -1;876 }877 /* Cancel retransmission timer. */878 if (tsx->retransmit_timer._timer_id != -1) {879 pjsip_endpt_cancel_timer(tsx->endpt, &tsx->retransmit_timer);880 tsx->retransmit_timer._timer_id = -1;881 }882 883 923 /* Reschedule timeout timer to destroy this transaction. */ 884 924 if (tsx->transport_flag & TSX_HAS_PENDING_TRANSPORT) { 885 925 tsx->transport_flag |= TSX_HAS_PENDING_DESTROY; 886 926 } else { 927 /* Cancel timeout timer. */ 928 if (tsx->timeout_timer._timer_id != -1) { 929 pjsip_endpt_cancel_timer(tsx->endpt, &tsx->timeout_timer); 930 tsx->timeout_timer._timer_id = -1; 931 } 932 887 933 pjsip_endpt_schedule_timer( tsx->endpt, &tsx->timeout_timer, 888 934 &timeout); … … 891 937 892 938 } else if (state == PJSIP_TSX_STATE_DESTROYED) { 893 894 /* Clear TLS, so that mutex will not be unlocked */895 struct tsx_lock_data *lck = pj_thread_local_get(pjsip_tsx_lock_tls_id);896 while (lck) {897 if (lck->tsx == tsx) {898 lck->is_alive = 0;899 }900 lck = lck->prev;901 }902 939 903 940 /* Unregister transaction. */ … … 921 958 pjsip_cseq_hdr *cseq; 922 959 pjsip_via_hdr *via; 960 pjsip_host_info dst_info; 923 961 struct tsx_lock_data lck; 924 962 pj_status_t status; … … 999 1037 pjsip_tx_data_add_ref(tsx->last_tx); 1000 1038 1039 /* Determine whether reliable transport should be used initially. 1040 * This will be updated whenever transport has changed. 1041 */ 1042 status = pjsip_get_request_addr(tdata, &dst_info); 1043 if (status != PJ_SUCCESS) { 1044 tsx_destroy(tsx); 1045 return status; 1046 } 1047 tsx->is_reliable = (dst_info.flag & PJSIP_TRANSPORT_RELIABLE); 1001 1048 1002 1049 /* Register transaction to hash table. */ … … 1006 1053 /* Unlock transaction and return. */ 1007 1054 unlock_tsx(tsx, &lck); 1055 1056 PJ_LOG(5,(tsx->obj_name, "Transaction created for %s", 1057 pjsip_tx_data_get_info(tdata))); 1008 1058 1009 1059 *p_tsx = tsx; … … 1113 1163 unlock_tsx(tsx, &lck); 1114 1164 1165 1166 PJ_LOG(5,(tsx->obj_name, "Transaction created for %s", 1167 pjsip_rx_data_get_info(rdata))); 1168 1169 1115 1170 *p_tsx = tsx; 1116 1171 return PJ_SUCCESS; … … 1127 1182 PJ_ASSERT_RETURN(tsx != NULL, PJ_EINVAL); 1128 1183 PJ_ASSERT_RETURN(code >= 200, PJ_EINVAL); 1184 1185 if (tsx->state == PJSIP_TSX_STATE_TERMINATED) 1186 return PJ_SUCCESS; 1129 1187 1130 1188 lock_tsx(tsx, &lck); … … 1152 1210 PJ_ASSERT_RETURN(tdata != NULL, PJ_EINVALIDOP); 1153 1211 1154 PJ_LOG(5,(tsx->obj_name, "Request to transmit msg on state %s (tdata=%p)", 1155 state_str[tsx->state], tdata)); 1212 PJ_LOG(5,(tsx->obj_name, "Sending %s in state %s", 1213 pjsip_tx_data_get_info(tdata), 1214 state_str[tsx->state])); 1156 1215 1157 1216 PJSIP_EVENT_INIT_TX_MSG(event, tsx, tdata); … … 1162 1221 unlock_tsx(tsx, &lck); 1163 1222 1223 /* Will always decrement tdata reference counter 1224 * (consistent with other send functions. 1225 */ 1226 pjsip_tx_data_dec_ref(tdata); 1227 1164 1228 return status; 1165 1229 } … … 1176 1240 pj_status_t status; 1177 1241 1178 PJ_LOG(5,(tsx->obj_name, "Incoming msg on state %s (rdata=%p)",1179 state_str[tsx->state], rdata));1242 PJ_LOG(5,(tsx->obj_name, "Incoming %s in state %s", 1243 pjsip_rx_data_get_info(rdata), state_str[tsx->state])); 1180 1244 1181 1245 /* Put the transaction in the rdata's mod_data. */ … … 1206 1270 1207 1271 if (tsx->transport != send_state->cur_transport) { 1272 /* Update transport. */ 1208 1273 if (tsx->transport) { 1209 1274 pjsip_transport_dec_ref(tsx->transport); … … 1212 1277 tsx->transport = send_state->cur_transport; 1213 1278 pjsip_transport_add_ref(tsx->transport); 1279 1280 /* Update remote address. */ 1281 tsx->addr_len = send_state->addr.entry[send_state->cur_addr].addr_len; 1282 pj_memcpy(&tsx->addr, 1283 &send_state->addr.entry[send_state->cur_addr].addr, 1284 tsx->addr_len); 1285 1286 /* Update is_reliable flag. */ 1287 tsx->is_reliable = PJSIP_TRANSPORT_IS_RELIABLE(tsx->transport); 1214 1288 } 1215 1289 1216 1290 /* Clear pending transport flag. */ 1217 1291 tsx->transport_flag &= ~(TSX_HAS_PENDING_TRANSPORT); 1292 1293 /* Mark that we have resolved the addresses. */ 1294 tsx->transport_flag |= TSX_HAS_RESOLVED_SERVER; 1218 1295 1219 1296 /* Pending destroy? */ … … 1234 1311 if (tsx->transport_flag & TSX_HAS_PENDING_RESCHED) { 1235 1312 tsx->transport_flag &= ~(TSX_HAS_PENDING_RESCHED); 1236 tsx_resched_retransmission(tsx); 1313 1314 /* Only update when transport turns out to be unreliable. */ 1315 if (!tsx->is_reliable) { 1316 tsx_resched_retransmission(tsx); 1317 } 1237 1318 } 1238 1319 … … 1252 1333 1253 1334 if (!*cont) { 1254 PJ_LOG(4,(tsx->obj_name, "Failed to send message! status=%d", 1255 -sent)); 1335 char errmsg[PJSIP_ERR_MSG_SIZE]; 1336 1337 PJ_LOG(4,(tsx->obj_name, 1338 "Failed to send %s! err=%d (%s)", 1339 pjsip_tx_data_get_info(send_state->tdata), -sent, 1340 pjsip_strerror(-sent, errmsg, sizeof(errmsg)).ptr)); 1256 1341 1257 1342 /* Clear pending transport flag. */ 1258 1343 tsx->transport_flag &= ~(TSX_HAS_PENDING_TRANSPORT); 1259 1344 1260 /* Terminate transaction. */ 1345 /* Mark that we have resolved the addresses. */ 1346 tsx->transport_flag |= TSX_HAS_RESOLVED_SERVER; 1347 1348 /* Terminate transaction, if it's not already terminated. */ 1261 1349 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 ); 1350 if (tsx->state != PJSIP_TSX_STATE_TERMINATED && 1351 tsx->state != PJSIP_TSX_STATE_DESTROYED) 1352 { 1353 tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED, 1354 PJSIP_EVENT_TRANSPORT_ERROR, send_state->tdata); 1355 } 1356 1357 } else { 1358 char errmsg[PJSIP_ERR_MSG_SIZE]; 1359 1360 PJ_LOG(4,(tsx->obj_name, 1361 "Temporary failure in sending %s, " 1362 "will try next server. Err=%d (%s)", 1363 pjsip_tx_data_get_info(send_state->tdata), -sent, 1364 pjsip_strerror(-sent, errmsg, sizeof(errmsg)).ptr)); 1264 1365 } 1265 1366 } … … 1276 1377 pjsip_transaction *tsx = token; 1277 1378 struct tsx_lock_data lck; 1278 1279 PJ_LOG(4,(tsx->obj_name, "Failed to send message! status=%d", 1280 -sent)); 1379 char errmsg[PJSIP_ERR_MSG_SIZE]; 1380 1381 PJ_LOG(4,(tsx->obj_name, "Transport failed to send %s! Err=%d (%s)", 1382 pjsip_tx_data_get_info(tdata), -sent, 1383 pjsip_strerror(-sent, errmsg, sizeof(errmsg)).ptr)); 1281 1384 1282 1385 lock_tsx(tsx, &lck); … … 1301 1404 pjsip_tx_data *tdata) 1302 1405 { 1303 pj_status_t status = PJ_ EBUG;1406 pj_status_t status = PJ_SUCCESS; 1304 1407 1305 1408 PJ_ASSERT_RETURN(tsx && tdata, PJ_EINVAL); … … 1311 1414 } 1312 1415 1416 /* If we have the transport, send the message using that transport. 1417 * Otherwise perform full transport resolution. 1418 */ 1419 if (tsx->transport) { 1420 status = pjsip_transport_send( tsx->transport, tdata, &tsx->addr, 1421 tsx->addr_len, tsx, 1422 &transport_callback); 1423 if (status == PJ_EPENDING) 1424 status = PJ_SUCCESS; 1425 1426 if (status != PJ_SUCCESS) { 1427 char errmsg[PJSIP_ERR_MSG_SIZE]; 1428 1429 PJ_LOG(4,(tsx->obj_name, 1430 "Error sending %s: Err=%d (%s)", 1431 pjsip_tx_data_get_info(tdata), status, 1432 pjsip_strerror(status, errmsg, sizeof(errmsg)).ptr)); 1433 1434 /* On error, release transport to force using full transport 1435 * resolution procedure. 1436 */ 1437 if (tsx->transport) { 1438 pjsip_transport_dec_ref(tsx->transport); 1439 tsx->transport = NULL; 1440 } 1441 tsx->addr_len = 0; 1442 tsx->res_addr.transport = NULL; 1443 tsx->res_addr.addr_len = 0; 1444 } else { 1445 return PJ_SUCCESS; 1446 } 1447 } 1448 1449 /* We are here because we don't have transport, or we failed to send 1450 * the message using existing transport. If we haven't resolved the 1451 * server before, then begin the long process of resolving the server 1452 * and send the message with possibly new server. 1453 */ 1454 pj_assert(status != PJ_SUCCESS || tsx->transport == NULL); 1455 1456 /* If we have resolved the server, we treat the error as permanent error. 1457 * Terminate transaction with transport error failure. 1458 */ 1459 if (tsx->transport_flag & TSX_HAS_RESOLVED_SERVER) { 1460 1461 char errmsg[PJSIP_ERR_MSG_SIZE]; 1462 1463 if (status == PJ_SUCCESS) { 1464 pj_assert(!"Unexpected status!"); 1465 status = PJ_EUNKNOWN; 1466 } 1467 1468 /* We have resolved the server!. 1469 * Treat this as permanent transport error. 1470 */ 1471 PJ_LOG(4,(tsx->obj_name, 1472 "Transport error, terminating transaction. " 1473 "Err=%d (%s)", 1474 status, 1475 pjsip_strerror(status, errmsg, sizeof(errmsg)).ptr)); 1476 1477 tsx->status_code = PJSIP_SC_TSX_TRANSPORT_ERROR; 1478 tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED, 1479 PJSIP_EVENT_TRANSPORT_ERROR, NULL ); 1480 1481 return status; 1482 } 1483 1484 /* Must add reference counter because the send request functions 1485 * decrement the reference counter. 1486 */ 1487 pjsip_tx_data_add_ref(tdata); 1488 1489 /* Begin resolving destination etc to send the message. */ 1313 1490 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. 1316 */ 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; 1333 } 1334 } 1491 1492 tsx->transport_flag |= TSX_HAS_PENDING_TRANSPORT; 1493 status = pjsip_endpt_send_request_stateless(tsx->endpt, tdata, tsx, 1494 &send_msg_callback); 1495 if (status == PJ_EPENDING) 1496 status = PJ_SUCCESS; 1497 if (status != PJ_SUCCESS) 1498 pjsip_tx_data_dec_ref(tdata); 1335 1499 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 } 1500 /* Check if transaction is terminated. */ 1501 if (status==PJ_SUCCESS && tsx->state == PJSIP_TSX_STATE_TERMINATED) 1502 status = PJSIP_ETSXDESTROYED; 1343 1503 1344 1504 } else { 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 } 1505 1506 tsx->transport_flag |= TSX_HAS_PENDING_TRANSPORT; 1507 status = pjsip_endpt_send_response( tsx->endpt, &tsx->res_addr, 1508 tdata, tsx, 1509 &send_msg_callback); 1510 if (status == PJ_EPENDING) 1511 status = PJ_SUCCESS; 1512 if (status != PJ_SUCCESS) 1513 pjsip_tx_data_dec_ref(tdata); 1514 1515 /* Check if transaction is terminated. */ 1516 if (status==PJ_SUCCESS && tsx->state == PJSIP_TSX_STATE_TERMINATED) 1517 status = PJSIP_ETSXDESTROYED; 1518 1519 } 1520 1376 1521 1377 1522 return status; … … 1409 1554 PJ_ASSERT_RETURN(tsx->last_tx!=NULL, PJ_EBUG); 1410 1555 1411 PJ_LOG(4,(tsx->obj_name, "retransmiting (tdata=%p, count=%d, restart?=%d)", 1412 tsx->last_tx, tsx->retransmit_count, resched)); 1556 PJ_LOG(5,(tsx->obj_name, "Retransmiting %s, count=%d, restart?=%d", 1557 pjsip_tx_data_get_info(tsx->last_tx), 1558 tsx->retransmit_count, resched)); 1413 1559 1414 1560 ++tsx->retransmit_count; … … 1452 1598 pjsip_tx_data *tdata; 1453 1599 1454 /* Must be transmit event. */ 1600 /* Must be transmit event. 1601 * You may got this assertion when using loop transport with delay 1602 * set to zero. That would cause on_rx_response() callback to be 1603 * called before tsx_send_msg() has completed. 1604 */ 1455 1605 PJ_ASSERT_RETURN(event->type == PJSIP_EVENT_TX_MSG, PJ_EBUG); 1456 1606 … … 1483 1633 * transport is being used. 1484 1634 */ 1485 if (! PJSIP_TRANSPORT_IS_RELIABLE(tsx->transport)) {1635 if (!tsx->is_reliable) { 1486 1636 tsx->retransmit_count = 0; 1487 1637 if (tsx->transport_flag & TSX_HAS_PENDING_TRANSPORT) { … … 1528 1678 1529 1679 /* Cancel retransmission timer. */ 1530 if ( PJSIP_TRANSPORT_IS_RELIABLE(tsx->transport)==0) {1680 if (tsx->retransmit_timer._timer_id != -1) { 1531 1681 pjsip_endpt_cancel_timer(tsx->endpt, &tsx->retransmit_timer); 1532 } 1682 tsx->retransmit_timer._timer_id = -1; 1683 } 1684 tsx->transport_flag &= ~(TSX_HAS_PENDING_RESCHED); 1533 1685 1534 1686 /* Set status code */ … … 1554 1706 1555 1707 /* Cancel retransmission timer A. */ 1556 if ( PJSIP_TRANSPORT_IS_RELIABLE(tsx->transport)==0)1708 if (tsx->retransmit_timer._timer_id != -1) { 1557 1709 pjsip_endpt_cancel_timer(tsx->endpt, &tsx->retransmit_timer); 1710 tsx->retransmit_timer._timer_id = -1; 1711 } 1712 tsx->transport_flag &= ~(TSX_HAS_PENDING_RESCHED); 1713 1558 1714 1559 1715 /* Cancel timer B (transaction timeout) */ … … 1739 1895 * reliable transport. 1740 1896 */ 1741 if (! PJSIP_TRANSPORT_IS_RELIABLE(tsx->transport)) {1897 if (!tsx->is_reliable) { 1742 1898 timeout = timeout_timer_val; 1743 1899 } else { … … 1770 1926 * timer G will be scheduled (retransmission). 1771 1927 */ 1772 if (! PJSIP_TRANSPORT_IS_RELIABLE(tsx->transport)) {1928 if (!tsx->is_reliable) { 1773 1929 pjsip_cseq_hdr *cseq = pjsip_msg_find_hdr( msg, PJSIP_H_CSEQ, 1774 1930 NULL); … … 1894 2050 /* For unreliable transport, start timer D (for INVITE) or 1895 2051 * timer K for non-INVITE. */ 1896 if ( PJSIP_TRANSPORT_IS_RELIABLE(tsx->transport) == 0) {2052 if (!tsx->is_reliable) { 1897 2053 if (tsx->method.id == PJSIP_INVITE_METHOD) { 1898 2054 timeout = td_timer_val; … … 1940 2096 1941 2097 /* Start Timer D with TD/T4 timer if unreliable transport is used. */ 1942 if (! PJSIP_TRANSPORT_IS_RELIABLE(tsx->transport)) {2098 if (!tsx->is_reliable) { 1943 2099 if (tsx->method.id == PJSIP_INVITE_METHOD) { 1944 2100 timeout = td_timer_val; … … 1993 2149 1994 2150 /* Cease retransmission. */ 1995 pjsip_endpt_cancel_timer( tsx->endpt, &tsx->retransmit_timer ); 2151 if (tsx->retransmit_timer._timer_id != -1) { 2152 pjsip_endpt_cancel_timer(tsx->endpt, &tsx->retransmit_timer); 2153 tsx->retransmit_timer._timer_id = -1; 2154 } 2155 tsx->transport_flag &= ~(TSX_HAS_PENDING_RESCHED); 1996 2156 1997 2157 /* Start timer I in T4 interval (transaction termination). */ -
pjproject/trunk/pjsip/src/pjsip/sip_transport.c
r107 r109 23 23 #include <pjsip/sip_private.h> 24 24 #include <pjsip/sip_errno.h> 25 #include <pjsip/sip_module.h> 25 26 #include <pj/os.h> 26 27 #include <pj/log.h> … … 33 34 34 35 35 #define THIS_FILE "transport" 36 #define THIS_FILE "sip_transport.c" 37 38 /* Prototype. */ 39 static pj_status_t mod_on_tx_msg(pjsip_tx_data *tdata); 40 41 /* This module has sole purpose to print transmit data to contigous buffer 42 * before actually transmitted to the wire. 43 */ 44 static pjsip_module mod_msg_print = 45 { 46 NULL, NULL, /* prev and next */ 47 { "mod-msg-print", 13}, /* Name. */ 48 -1, /* Id */ 49 PJSIP_MOD_PRIORITY_TRANSPORT_LAYER, /* Priority */ 50 NULL, /* User data. */ 51 0, /* Number of methods supported (=0). */ 52 { 0 }, /* Array of methods (none) */ 53 NULL, /* load() */ 54 NULL, /* start() */ 55 NULL, /* stop() */ 56 NULL, /* unload() */ 57 NULL, /* on_rx_request() */ 58 NULL, /* on_rx_response() */ 59 &mod_on_tx_msg, /* on_tx_request() */ 60 &mod_on_tx_msg, /* on_tx_response() */ 61 NULL, /* on_tsx_state() */ 62 }; 36 63 37 64 /* … … 47 74 pj_atomic_t *tdata_counter; 48 75 #endif 49 void (*msg_cb)(pjsip_endpoint*, pj_status_t, pjsip_rx_data*); 76 void (*on_rx_msg)(pjsip_endpoint*, pj_status_t, pjsip_rx_data*); 77 pj_status_t (*on_tx_msg)(pjsip_endpoint*, pjsip_tx_data*); 50 78 }; 51 79 … … 67 95 } transport_names[] = 68 96 { 69 { PJSIP_TRANSPORT_UNSPECIFIED, 0, { NULL, 0}, 0},97 { PJSIP_TRANSPORT_UNSPECIFIED, 0, {"Unspecified", 11}, 0}, 70 98 { PJSIP_TRANSPORT_UDP, 5060, {"UDP", 3}, PJSIP_TRANSPORT_DATAGRAM}, 71 99 { PJSIP_TRANSPORT_TCP, 5060, {"TCP", 3}, PJSIP_TRANSPORT_RELIABLE}, … … 91 119 PJSIP_TRANSPORT_UDP, PJSIP_TRANSPORT_UNSPECIFIED); 92 120 121 if (name->slen == 0) 122 return PJSIP_TRANSPORT_UNSPECIFIED; 123 93 124 /* Get transport type from name. */ 94 125 for (i=0; i<PJ_ARRAY_SIZE(transport_names); ++i) { … … 163 194 } 164 195 196 /* 197 * Get transport name. 198 */ 199 PJ_DEF(const char*) pjsip_transport_get_type_name(pjsip_transport_type_e type) 200 { 201 /* Sanity check. 202 * Check that transport_names[] are indexed on transport type. 203 */ 204 PJ_ASSERT_RETURN(transport_names[PJSIP_TRANSPORT_UDP].type == 205 PJSIP_TRANSPORT_UDP, "Unknown"); 206 207 /* Check that argument is valid. */ 208 PJ_ASSERT_RETURN(type < PJ_ARRAY_SIZE(transport_names), "Unknown"); 209 210 /* Return the port. */ 211 return transport_names[type].name.ptr; 212 } 165 213 166 214 /***************************************************************************** … … 181 229 182 230 PJ_ASSERT_RETURN(mgr && p_tdata, PJ_EINVAL); 183 184 PJ_LOG(5, ("", "pjsip_tx_data_create"));185 231 186 232 pool = pjsip_endpt_create_pool( mgr->endpt, "tdta%p", … … 235 281 pj_assert( pj_atomic_get(tdata->ref_cnt) > 0); 236 282 if (pj_atomic_dec_and_get(tdata->ref_cnt) <= 0) { 237 PJ_LOG(5,(tdata->obj_name, "destroying txdata")); 283 PJ_LOG(5,(tdata->obj_name, "Destroying txdata %s", 284 pjsip_tx_data_get_info(tdata))); 238 285 #if defined(PJ_DEBUG) && PJ_DEBUG!=0 239 286 pj_atomic_dec( tdata->mgr->tdata_counter ); … … 255 302 { 256 303 tdata->buf.cur = tdata->buf.start; 304 tdata->info = NULL; 257 305 } 258 306 … … 262 310 } 263 311 264 312 static char *get_msg_info(pj_pool_t *pool, const char *obj_name, 313 const pjsip_msg *msg) 314 { 315 char info_buf[128], *info; 316 const pjsip_cseq_hdr *cseq; 317 int len; 318 319 cseq = pjsip_msg_find_hdr(msg, PJSIP_H_CSEQ, NULL); 320 PJ_ASSERT_RETURN(cseq != NULL, "INVALID MSG"); 321 322 if (msg->type == PJSIP_REQUEST_MSG) { 323 len = pj_snprintf(info_buf, sizeof(info_buf), 324 "Request msg %.*s/cseq=%d (%s)", 325 msg->line.req.method.name.slen, 326 msg->line.req.method.name.ptr, 327 cseq->cseq, obj_name); 328 } else { 329 len = pj_snprintf(info_buf, sizeof(info_buf), 330 "Response msg %d/%.*s/cseq=%d (%s)", 331 msg->line.status.code, 332 cseq->method.name.slen, 333 cseq->method.name.ptr, 334 cseq->cseq, obj_name); 335 } 336 337 if (len < 1 || len >= sizeof(info_buf)) { 338 return (char*)obj_name; 339 } 340 341 info = pj_pool_alloc(pool, len+1); 342 pj_memcpy(info, info_buf, len+1); 343 344 return info; 345 } 346 347 PJ_DEF(char*) pjsip_tx_data_get_info( pjsip_tx_data *tdata ) 348 { 349 350 PJ_ASSERT_RETURN(tdata && tdata->msg, "INVALID MSG"); 351 352 if (tdata->info) 353 return tdata->info; 354 355 pj_lock_acquire(tdata->lock); 356 tdata->info = get_msg_info(tdata->pool, tdata->obj_name, tdata->msg); 357 pj_lock_release(tdata->lock); 358 359 return tdata->info; 360 } 361 362 PJ_DEF(char*) pjsip_rx_data_get_info(pjsip_rx_data *rdata) 363 { 364 char obj_name[16]; 365 366 PJ_ASSERT_RETURN(rdata->msg_info.msg, "INVALID MSG"); 367 368 if (rdata->msg_info.info) 369 return rdata->msg_info.info; 370 371 pj_native_strcpy(obj_name, "rdata"); 372 pj_sprintf(obj_name+5, "%p", rdata); 373 374 rdata->msg_info.info = get_msg_info(rdata->tp_info.pool, obj_name, 375 rdata->msg_info.msg); 376 return rdata->msg_info.info; 377 } 265 378 266 379 /***************************************************************************** … … 297 410 /* Decrement reference count. */ 298 411 pjsip_tx_data_dec_ref(tdata); 412 } 413 414 /* This function is called by endpoint for on_tx_request() and on_tx_response() 415 * notification. 416 */ 417 static pj_status_t mod_on_tx_msg(pjsip_tx_data *tdata) 418 { 419 /* Allocate buffer if necessary. */ 420 if (tdata->buf.start == NULL) { 421 tdata->buf.start = pj_pool_alloc( tdata->pool, PJSIP_MAX_PKT_LEN); 422 tdata->buf.cur = tdata->buf.start; 423 tdata->buf.end = tdata->buf.start + PJSIP_MAX_PKT_LEN; 424 } 425 426 /* Do we need to reprint? */ 427 if (!pjsip_tx_data_is_valid(tdata)) { 428 pj_ssize_t size; 429 430 size = pjsip_msg_print( tdata->msg, tdata->buf.start, 431 tdata->buf.end - tdata->buf.start); 432 if (size < 0) { 433 return PJSIP_EMSGTOOLONG; 434 } 435 pj_assert(size != 0); 436 tdata->buf.cur += size; 437 tdata->buf.cur[size] = '\0'; 438 } 439 440 return PJ_SUCCESS; 299 441 } 300 442 … … 321 463 } 322 464 323 /* Allocate buffer if necessary. */ 324 if (tdata->buf.start == NULL) { 325 tdata->buf.start = pj_pool_alloc( tdata->pool, PJSIP_MAX_PKT_LEN); 326 tdata->buf.cur = tdata->buf.start; 327 tdata->buf.end = tdata->buf.start + PJSIP_MAX_PKT_LEN; 328 } 329 330 /* Do we need to reprint? */ 331 if (!pjsip_tx_data_is_valid(tdata)) { 332 pj_ssize_t size; 333 334 size = pjsip_msg_print( tdata->msg, tdata->buf.start, 335 tdata->buf.end - tdata->buf.start); 336 if (size < 0) { 337 return PJSIP_EMSGTOOLONG; 338 } 339 pj_assert(size != 0); 340 tdata->buf.cur += size; 341 tdata->buf.cur[size] = '\0'; 465 /* Fill in tp_info. */ 466 tdata->tp_info.transport = tr; 467 pj_memcpy(&tdata->tp_info.dst_addr, addr, addr_len); 468 tdata->tp_info.dst_addr_len = addr_len; 469 if (addr->sa_family == PJ_AF_INET) { 470 const char *str_addr; 471 str_addr = pj_inet_ntoa(((pj_sockaddr_in*)addr)->sin_addr); 472 pj_native_strcpy(tdata->tp_info.dst_name, str_addr); 473 tdata->tp_info.dst_port = pj_ntohs(((pj_sockaddr_in*)addr)->sin_port); 474 } else { 475 pj_native_strcpy(tdata->tp_info.dst_name, "<unknown>"); 476 tdata->tp_info.dst_port = 0; 477 } 478 479 /* Distribute to modules. 480 * When the message reach mod_msg_print, the contents of the message will 481 * be "printed" to contiguous buffer. 482 */ 483 if (tr->tpmgr->on_tx_msg) { 484 status = (*tr->tpmgr->on_tx_msg)(tr->endpt, tdata); 485 if (status != PJ_SUCCESS) 486 return status; 342 487 } 343 488 … … 450 595 } 451 596 452 453 /** 454 * Unregister transport. 455 */ 456 PJ_DEF(pj_status_t) pjsip_transport_unregister( pjsip_tpmgr *mgr, 457 pjsip_transport *tp) 597 /* Force destroy transport (e.g. during transport manager shutdown. */ 598 static pj_status_t destroy_transport( pjsip_tpmgr *mgr, 599 pjsip_transport *tp ) 458 600 { 459 601 int key_len; 460 461 /* Must have no user. */462 PJ_ASSERT_RETURN(pj_atomic_get(tp->ref_cnt) == 0, PJSIP_EBUSY);463 602 464 603 pj_lock_acquire(tp->lock); … … 484 623 /* Destroy. */ 485 624 return tp->destroy(tp); 625 } 626 627 /** 628 * Unregister transport. 629 */ 630 PJ_DEF(pj_status_t) pjsip_transport_unregister( pjsip_tpmgr *mgr, 631 pjsip_transport *tp) 632 { 633 /* Must have no user. */ 634 PJ_ASSERT_RETURN(pj_atomic_get(tp->ref_cnt) == 0, PJSIP_EBUSY); 635 636 /* Destroy. */ 637 return destroy_transport(mgr, tp); 486 638 } 487 639 … … 557 709 PJ_DEF(pj_status_t) pjsip_tpmgr_create( pj_pool_t *pool, 558 710 pjsip_endpoint *endpt, 559 void (*cb)(pjsip_endpoint*, 560 pj_status_t, 561 pjsip_rx_data *), 711 void (*rx_cb)(pjsip_endpoint*, 712 pj_status_t, 713 pjsip_rx_data *), 714 pj_status_t (*tx_cb)(pjsip_endpoint*, 715 pjsip_tx_data*), 562 716 pjsip_tpmgr **p_mgr) 563 717 { … … 565 719 pj_status_t status; 566 720 567 PJ_ASSERT_RETURN(pool && endpt && cb && p_mgr, PJ_EINVAL); 568 569 PJ_LOG(5, (THIS_FILE, "pjsip_tpmgr_create()")); 570 721 PJ_ASSERT_RETURN(pool && endpt && rx_cb && p_mgr, PJ_EINVAL); 722 723 /* Register mod_msg_print module. */ 724 status = pjsip_endpt_register_module(endpt, &mod_msg_print); 725 if (status != PJ_SUCCESS) 726 return status; 727 728 /* Create and initialize transport manager. */ 571 729 mgr = pj_pool_zalloc(pool, sizeof(*mgr)); 572 730 mgr->endpt = endpt; 573 mgr->msg_cb = cb; 731 mgr->on_rx_msg = rx_cb; 732 mgr->on_tx_msg = tx_cb; 574 733 pj_list_init(&mgr->factory_list); 575 734 … … 588 747 #endif 589 748 749 PJ_LOG(5, (THIS_FILE, "Transport manager created.")); 750 590 751 *p_mgr = mgr; 591 752 return PJ_SUCCESS; … … 601 762 pj_hash_iterator_t itr_val; 602 763 pj_hash_iterator_t *itr; 764 pjsip_endpoint *endpt = mgr->endpt; 603 765 604 PJ_LOG(5, (THIS_FILE, "pjsip_tpmgr_destroy()")); 605 606 #if defined(PJ_DEBUG) && PJ_DEBUG!=0 607 pj_assert(pj_atomic_get(mgr->tdata_counter) == 0); 608 #endif 766 PJ_LOG(5, (THIS_FILE, "Destroying transport manager")); 609 767 610 768 pj_lock_acquire(mgr->lock); … … 619 777 next = pj_hash_next(mgr->table, itr); 620 778 621 pj_atomic_set(transport->ref_cnt, 0); 622 pjsip_transport_unregister(mgr, transport); 779 destroy_transport(mgr, transport); 623 780 624 781 itr = next; … … 627 784 pj_lock_release(mgr->lock); 628 785 pj_lock_destroy(mgr->lock); 786 787 /* Unregister mod_msg_print. */ 788 if (mod_msg_print.id != -1) { 789 pjsip_endpt_unregister_module(endpt, &mod_msg_print); 790 } 791 792 #if defined(PJ_DEBUG) && PJ_DEBUG!=0 793 /* If you encounter assert error on this line, it means there are 794 * leakings in transmit data (i.e. some transmit data have not been 795 * destroyed). 796 */ 797 pj_assert(pj_atomic_get(mgr->tdata_counter) == 0); 798 #endif 629 799 630 800 return PJ_SUCCESS; … … 686 856 if (msg_status != PJ_SUCCESS) { 687 857 if (remaining_len == PJSIP_MAX_PKT_LEN) { 688 mgr-> msg_cb(mgr->endpt, PJSIP_ERXOVERFLOW, rdata);858 mgr->on_rx_msg(mgr->endpt, PJSIP_ERXOVERFLOW, rdata); 689 859 /* Exhaust all data. */ 690 860 return rdata->pkt_info.len; … … 703 873 pjsip_parse_rdata( current_pkt, msg_fragment_size, rdata); 704 874 if (msg == NULL) { 705 mgr-> msg_cb(mgr->endpt, PJSIP_EINVALIDMSG, rdata);875 mgr->on_rx_msg(mgr->endpt, PJSIP_EINVALIDMSG, rdata); 706 876 goto finish_process_fragment; 707 877 } … … 714 884 rdata->msg_info.cseq == NULL) 715 885 { 716 mgr-> msg_cb(mgr->endpt, PJSIP_EMISSINGHDR, rdata);886 mgr->on_rx_msg(mgr->endpt, PJSIP_EMISSINGHDR, rdata); 717 887 goto finish_process_fragment; 718 888 } … … 738 908 hdr = pjsip_msg_find_hdr(msg, PJSIP_H_VIA, hdr); 739 909 if (hdr) { 740 mgr-> msg_cb(mgr->endpt, PJSIP_EMULTIPLEVIA, rdata);910 mgr->on_rx_msg(mgr->endpt, PJSIP_EMULTIPLEVIA, rdata); 741 911 goto finish_process_fragment; 742 912 } … … 746 916 /* Call the transport manager's upstream message callback. 747 917 */ 748 mgr-> msg_cb(mgr->endpt, PJ_SUCCESS, rdata);918 mgr->on_rx_msg(mgr->endpt, PJ_SUCCESS, rdata); 749 919 750 920 … … 796 966 const pj_sockaddr *remote_addr = (const pj_sockaddr*)remote; 797 967 798 /* For datagram transports, try lookup with zero address. 799 */ 800 if ( (flag & PJSIP_TRANSPORT_DATAGRAM) && 801 (remote_addr->sa_family == PJ_AF_INET)) 968 /* Ignore address for loop transports. */ 969 if (type == PJSIP_TRANSPORT_LOOP || 970 type == PJSIP_TRANSPORT_LOOP_DGRAM) 802 971 { 803 972 pj_sockaddr_in *addr = (pj_sockaddr_in*)&key.addr; 804 973 805 974 pj_memset(addr, 0, sizeof(pj_sockaddr_in)); 975 key_len = sizeof(key.type) + sizeof(pj_sockaddr_in); 976 transport = pj_hash_get(mgr->table, &key, key_len); 977 } 978 /* For datagram INET transports, try lookup with zero address. 979 */ 980 else if ((flag & PJSIP_TRANSPORT_DATAGRAM) && 981 (remote_addr->sa_family == PJ_AF_INET)) 982 { 983 pj_sockaddr_in *addr = (pj_sockaddr_in*)&key.addr; 984 985 pj_memset(addr, 0, sizeof(pj_sockaddr_in)); 806 986 addr->sin_family = PJ_AF_INET; 807 addr->sin_addr.s_addr = 0;808 addr->sin_port = 0;809 987 810 988 key_len = sizeof(key.type) + sizeof(pj_sockaddr_in); -
pjproject/trunk/pjsip/src/pjsip/sip_transport_loop.c
r107 r109 28 28 29 29 30 #define FAIL_IMMEDIATE 131 #define FAIL_CALLBACK 232 33 30 #define ADDR_LOOP "128.0.0.1" 34 31 #define ADDR_LOOP_DGRAM "129.0.0.1" … … 62 59 pj_bool_t discard; 63 60 int fail_mode; 64 unsigned delay; 61 unsigned recv_delay; 62 unsigned send_delay; 65 63 struct recv_list recv_list; 66 64 struct send_list send_list; … … 101 99 /* When do we need to "deliver" this packet. */ 102 100 pj_gettimeofday(&pkt->rdata.pkt_info.timestamp); 103 pkt->rdata.pkt_info.timestamp.msec += loop-> delay;101 pkt->rdata.pkt_info.timestamp.msec += loop->recv_delay; 104 102 pj_time_val_normalize(&pkt->rdata.pkt_info.timestamp); 105 103 … … 131 129 132 130 pj_gettimeofday(&sent_status->sent_time); 133 sent_status->sent_time.msec += loop-> delay;131 sent_status->sent_time.msec += loop->send_delay; 134 132 pj_time_val_normalize(&sent_status->sent_time); 135 133 … … 161 159 162 160 163 /* Need to send failure immediately? */ 164 if (loop->fail_mode == FAIL_IMMEDIATE) { 165 return PJ_STATUS_FROM_OS(OSERR_ECONNRESET); 166 167 /* Need to send failure later? */ 168 } else if (loop->fail_mode == FAIL_CALLBACK) { 169 170 add_notification(loop, tdata, -PJ_STATUS_FROM_OS(OSERR_ECONNRESET), 171 token, cb); 172 173 return PJ_EPENDING; 161 /* Need to send failure? */ 162 if (loop->fail_mode) { 163 if (loop->send_delay == 0) { 164 return PJ_STATUS_FROM_OS(OSERR_ECONNRESET); 165 } else { 166 add_notification(loop, tdata, -PJ_STATUS_FROM_OS(OSERR_ECONNRESET), 167 token, cb); 168 169 return PJ_EPENDING; 170 } 174 171 } 175 172 … … 184 181 185 182 /* If delay is not configured, deliver this packet now! */ 186 if (loop-> delay == 0) {183 if (loop->recv_delay == 0) { 187 184 pj_ssize_t size_eaten; 188 185 … … 193 190 pjsip_endpt_release_pool(loop->base.endpt, 194 191 recv_pkt->rdata.tp_info.pool); 195 return PJ_SUCCESS;196 192 197 193 } else { 198 194 /* Otherwise if delay is configured, add the "packet" to the 199 * receive list to be processed by worker thread, and add 200 * pending notification for calling the callback. 195 * receive list to be processed by worker thread. 201 196 */ 202 add_notification(loop, tdata, tdata->buf.cur - tdata->buf.start,203 token, cb);204 205 197 pj_lock_acquire(loop->base.lock); 206 198 pj_list_push_back(&loop->recv_list, recv_pkt); 207 199 pj_lock_release(loop->base.lock); 200 } 201 202 if (loop->send_delay != 0) { 203 add_notification(loop, tdata, tdata->buf.cur - tdata->buf.start, 204 token, cb); 208 205 return PJ_EPENDING; 206 } else { 207 return PJ_SUCCESS; 209 208 } 210 209 } … … 224 223 pj_thread_destroy(loop->thread); 225 224 225 /* Clear pending send notifications. */ 226 while (!pj_list_empty(&loop->send_list)) { 227 struct send_list *node = loop->send_list.next; 228 /* Notify callback. */ 229 if (node->callback) { 230 (*node->callback)(&loop->base, node->token, -PJSIP_ESHUTDOWN); 231 } 232 pj_list_erase(node); 233 pjsip_tx_data_dec_ref(node->tdata); 234 } 235 236 /* Clear "incoming" packets in the queue. */ 237 while (!pj_list_empty(&loop->recv_list)) { 238 struct recv_list *node = loop->recv_list.next; 239 pj_list_erase(node); 240 pjsip_endpt_release_pool(loop->base.endpt, 241 node->rdata.tp_info.pool); 242 } 243 244 /* Self destruct.. heheh.. */ 226 245 pj_lock_destroy(loop->base.lock); 227 246 pj_atomic_destroy(loop->base.ref_cnt); … … 239 258 pj_time_val now; 240 259 241 pj_thread_sleep(1 0);260 pj_thread_sleep(1); 242 261 pj_gettimeofday(&now); 243 262 … … 321 340 goto on_error; 322 341 loop->base.key.type = PJSIP_TRANSPORT_LOOP_DGRAM; 323 loop->base.key.rem_addr.sa_family = PJ_AF_INET;342 //loop->base.key.rem_addr.sa_family = PJ_AF_INET; 324 343 loop->base.type_name = "LOOP-DGRAM"; 325 344 loop->base.info = "LOOP-DGRAM"; … … 357 376 */ 358 377 359 *transport = &loop->base; 378 if (transport) 379 *transport = &loop->base; 380 360 381 return PJ_SUCCESS; 361 382 … … 406 427 407 428 408 PJ_DEF(pj_status_t) pjsip_loop_set_ delay( pjsip_transport *tp,409 unsigned delay,410 unsigned *prev_value)429 PJ_DEF(pj_status_t) pjsip_loop_set_recv_delay( pjsip_transport *tp, 430 unsigned delay, 431 unsigned *prev_value) 411 432 { 412 433 struct loop_transport *loop = (struct loop_transport*)tp; … … 416 437 417 438 if (prev_value) 418 *prev_value = loop->delay; 419 loop->delay = delay; 420 421 return PJ_SUCCESS; 422 } 423 439 *prev_value = loop->recv_delay; 440 loop->recv_delay = delay; 441 442 return PJ_SUCCESS; 443 } 444 445 PJ_DEF(pj_status_t) pjsip_loop_set_send_callback_delay( pjsip_transport *tp, 446 unsigned delay, 447 unsigned *prev_value) 448 { 449 struct loop_transport *loop = (struct loop_transport*)tp; 450 451 PJ_ASSERT_RETURN(tp && (tp->key.type == PJSIP_TRANSPORT_LOOP || 452 tp->key.type == PJSIP_TRANSPORT_LOOP_DGRAM), PJ_EINVAL); 453 454 if (prev_value) 455 *prev_value = loop->send_delay; 456 loop->send_delay = delay; 457 458 return PJ_SUCCESS; 459 } 460 461 PJ_DEF(pj_status_t) pjsip_loop_set_delay( pjsip_transport *tp, unsigned delay ) 462 { 463 struct loop_transport *loop = (struct loop_transport*)tp; 464 465 PJ_ASSERT_RETURN(tp && (tp->key.type == PJSIP_TRANSPORT_LOOP || 466 tp->key.type == PJSIP_TRANSPORT_LOOP_DGRAM), PJ_EINVAL); 467 468 loop->recv_delay = delay; 469 loop->send_delay = delay; 470 471 return PJ_SUCCESS; 472 } 473 -
pjproject/trunk/pjsip/src/pjsip/sip_transport_udp.c
r107 r109 59 59 60 60 /* Don't do anything if transport is closing. */ 61 if (tp->is_closing) 61 if (tp->is_closing) { 62 tp->is_closing++; 62 63 return; 64 } 63 65 64 66 /* … … 229 231 230 232 /* Cancel all pending operations. */ 233 /* blp: NO NO NO... 234 * No need to post queued completion as we poll the ioqueue until 235 * we've got events anyway. Posting completion will only cause 236 * callback to be called twice with IOCP: one for the post completion 237 * and another one for closing the socket. 238 * 231 239 for (i=0; i<tp->rdata_cnt; ++i) { 232 240 pj_ioqueue_post_completion(tp->key, 233 241 &tp->rdata[i]->tp_info.op_key.op_key, -1); 234 242 } 243 */ 235 244 236 245 /* Unregister from ioqueue. */ … … 241 250 if (tp->sock && tp->sock != PJ_INVALID_SOCKET) 242 251 pj_sock_close(tp->sock); 252 253 /* Must poll ioqueue because IOCP calls the callback when socket 254 * is closed. We poll the ioqueue until all pending callbacks 255 * have been called. 256 */ 257 for (i=0; i<50 && tp->is_closing < 1+tp->rdata_cnt; ++i) { 258 int cnt; 259 pj_time_val timeout = {0, 1}; 260 261 cnt = pj_ioqueue_poll(pjsip_endpt_get_ioqueue(transport->endpt), 262 &timeout); 263 if (cnt == 0) 264 break; 265 } 243 266 244 267 /* Destroy reference counter. */ -
pjproject/trunk/pjsip/src/pjsip/sip_util.c
r107 r109 130 130 } 131 131 132 PJ_LOG(4,(THIS_FILE, "Request %s (CSeq=%d/%.*s) created.", 133 tdata->obj_name, 134 param_cseq->cseq, 135 param_cseq->method.name.slen, 136 param_cseq->method.name.ptr)); 132 PJ_LOG(5,(THIS_FILE, "%s created.", 133 pjsip_tx_data_get_info(tdata))); 137 134 138 135 } … … 162 159 pj_status_t status; 163 160 PJ_USE_EXCEPTION; 164 165 PJ_LOG(5,(THIS_FILE, "Entering pjsip_endpt_create_request()"));166 161 167 162 status = pjsip_endpt_create_tdata(endpt, &tdata); … … 272 267 pj_status_t status; 273 268 PJ_USE_EXCEPTION; 274 275 PJ_LOG(5,(THIS_FILE, "Entering pjsip_endpt_create_request_from_hdr()"));276 269 277 270 /* Check arguments. */ … … 344 337 pj_assert(req_msg->type == PJSIP_REQUEST_MSG); 345 338 346 /* Log this action. */347 PJ_LOG(5,(THIS_FILE, "pjsip_endpt_create_response(rdata=%p, code=%d)",348 rdata, st_code));349 350 339 /* Create a new transmit buffer. */ 351 340 status = pjsip_endpt_create_tdata( endpt, &tdata); … … 409 398 /* All done. */ 410 399 *p_tdata = tdata; 400 401 PJ_LOG(5,(THIS_FILE, "%s created", pjsip_tx_data_get_info(tdata))); 411 402 return PJ_SUCCESS; 412 403 } … … 432 423 pjsip_to_hdr *to; 433 424 pj_status_t status; 434 435 /* Log this action. */436 PJ_LOG(5,(THIS_FILE, "pjsip_endpt_create_ack(rdata=%p)", rdata));437 425 438 426 /* rdata must be a final response. */ … … 525 513 const pjsip_hdr *hdr; 526 514 pj_status_t status; 527 528 /* Log this action. */529 PJ_LOG(5,(THIS_FILE, "pjsip_endpt_create_cancel(tdata=%p)", req_tdata));530 515 531 516 /* The transmit buffer must INVITE request. */ … … 703 688 dest_info->type = 704 689 pjsip_transport_get_type_from_name(&url->transport_param); 705 #if PJ_HAS_TCP 706 if (dest_info->type == PJSIP_TRANSPORT_TCP || 707 dest_info->type == PJSIP_TRANSPORT_SCTP) 708 { 709 dest_info->flag |= PJSIP_TRANSPORT_RELIABLE; 710 } 711 #endif 690 dest_info->flag = 691 pjsip_transport_get_flag_from_type(dest_info->type); 712 692 } else { 713 693 pj_assert(!"Unsupported URI scheme!"); -
pjproject/trunk/pjsip/src/test-pjsip/msg_test.c
r107 r109 24 24 #define LOOP 10000 25 25 #define AVERAGE_MSG_LEN 800 26 #define THIS_FILE "msg_test.c" 26 27 27 28 static pjsip_msg *create_msg0(pj_pool_t *pool); … … 143 144 } 144 145 if (msg_size != entry->len) { 145 PJ_LOG(3,( "", " error: size mismatch"));146 PJ_LOG(3,(THIS_FILE, " error: size mismatch")); 146 147 return -6; 147 148 } … … 163 164 status = -10; 164 165 if (err_list.next != &err_list) { 165 PJ_LOG(3,( "", " Syntax error in line %d col %d",166 PJ_LOG(3,(THIS_FILE, " Syntax error in line %d col %d", 166 167 err_list.next->line, err_list.next->col)); 167 168 } … … 208 209 } else { 209 210 if (parsed_msg->line.status.code != ref_msg->line.status.code) { 210 PJ_LOG(3,( "", " error: status code mismatch"));211 PJ_LOG(3,(THIS_FILE, " error: status code mismatch")); 211 212 status = -32; 212 213 goto on_return; … … 215 216 &ref_msg->line.status.reason) != 0) 216 217 { 217 PJ_LOG(3,( "", " error: status text mismatch"));218 PJ_LOG(3,(THIS_FILE, " error: status text mismatch")); 218 219 status = -33; 219 220 goto on_return; … … 244 245 if (pj_strcmp(&str1, &str2) != 0) { 245 246 status = -60; 246 PJ_LOG(3,( "", " error: header string mismatch:\n"247 PJ_LOG(3,(THIS_FILE, " error: header string mismatch:\n" 247 248 " h1='%s'\n" 248 249 " h2='%s'\n", … … 684 685 pj_highprec_t avg_detect, avg_parse, avg_print, kbytes; 685 686 686 PJ_LOG(3,( "", " simple test.."));687 PJ_LOG(3,(THIS_FILE, " simple test..")); 687 688 for (i=0; i<PJ_ARRAY_SIZE(test_array); ++i) { 688 689 pool = pjsip_endpt_create_pool(endpt, NULL, POOL_SIZE, POOL_SIZE); … … 694 695 } 695 696 696 PJ_LOG(3,( "", " benchmarking.."));697 PJ_LOG(3,(THIS_FILE, " benchmarking..")); 697 698 detect_len = parse_len = print_len = 0; 698 699 zero.u64 = detect_time.u64 = parse_time.u64 = print_time.u64 = 0; … … 718 719 avg_detect = 1000000 / avg_detect; 719 720 720 PJ_LOG(3,("", " %u.%u MB detected in %d.%03ds (avg=%d msg detection/sec)", 721 (unsigned)(detect_len/1000000), (unsigned)kbytes, 722 elapsed.sec, elapsed.msec, 723 (unsigned)avg_detect)); 721 PJ_LOG(3,(THIS_FILE, 722 " %u.%u MB detected in %d.%03ds (avg=%d msg detection/sec)", 723 (unsigned)(detect_len/1000000), (unsigned)kbytes, 724 elapsed.sec, elapsed.msec, 725 (unsigned)avg_detect)); 724 726 725 727 kbytes = parse_len; … … 732 734 avg_parse = 1000000 / avg_parse; 733 735 734 PJ_LOG(3,("", " %u.%u MB parsed in %d.%03ds (avg=%d msg parsing/sec)", 735 (unsigned)(parse_len/1000000), (unsigned)kbytes, 736 elapsed.sec, elapsed.msec, 737 (unsigned)avg_parse)); 736 PJ_LOG(3,(THIS_FILE, 737 " %u.%u MB parsed in %d.%03ds (avg=%d msg parsing/sec)", 738 (unsigned)(parse_len/1000000), (unsigned)kbytes, 739 elapsed.sec, elapsed.msec, 740 (unsigned)avg_parse)); 738 741 739 742 kbytes = print_len; … … 746 749 avg_print = 1000000 / avg_print; 747 750 748 PJ_LOG(3,("", " %u.%u MB printed in %d.%03ds (avg=%d msg print/sec)", 749 (unsigned)(print_len/1000000), (unsigned)kbytes, 750 elapsed.sec, elapsed.msec, 751 (unsigned)avg_print)); 751 PJ_LOG(3,(THIS_FILE, 752 " %u.%u MB printed in %d.%03ds (avg=%d msg print/sec)", 753 (unsigned)(print_len/1000000), (unsigned)kbytes, 754 elapsed.sec, elapsed.msec, 755 (unsigned)avg_print)); 752 756 753 757 return status; -
pjproject/trunk/pjsip/src/test-pjsip/test.c
r107 r109 23 23 #include <pjsip_core.h> 24 24 25 #define THIS_FILE "test.c" 26 25 27 #define DO_TEST(test) do { \ 26 PJ_LOG(3, ( "test", "Running %s...", #test)); \28 PJ_LOG(3, (THIS_FILE, "Running %s...", #test)); \ 27 29 rc = test; \ 28 PJ_LOG(3, ( "test", \30 PJ_LOG(3, (THIS_FILE, \ 29 31 "%s(%d)", \ 30 32 (rc ? "..ERROR" : "..success"), rc)); \ … … 43 45 44 46 pjsip_strerror(rc, errbuf, sizeof(errbuf)); 45 PJ_LOG(3,( "test", "%s: [pj_status_t=%d] %s", msg, rc, errbuf));47 PJ_LOG(3,(THIS_FILE, "%s: [pj_status_t=%d] %s", msg, rc, errbuf)); 46 48 49 } 50 51 void flush_events(unsigned duration) 52 { 53 pj_time_val stop_time; 54 55 pj_gettimeofday(&stop_time); 56 stop_time.msec += duration; 57 pj_time_val_normalize(&stop_time); 58 59 /* Process all events for the specified duration. */ 60 for (;;) { 61 pj_time_val timeout = {0, 1}, now; 62 63 pjsip_endpt_handle_events(endpt, &timeout); 64 65 pj_gettimeofday(&now); 66 if (PJ_TIME_VAL_GTE(now, stop_time)) 67 break; 68 } 47 69 } 48 70 … … 60 82 int line; 61 83 62 pj_log_set_level(3); 84 pj_log_set_level(5); 85 /* 63 86 pj_log_set_decor(PJ_LOG_HAS_NEWLINE | PJ_LOG_HAS_TIME | 64 87 PJ_LOG_HAS_MICRO_SEC); 88 */ 65 89 66 90 if ((rc=pj_init()) != PJ_SUCCESS) { … … 80 104 } 81 105 82 PJ_LOG(3,("","")); 106 PJ_LOG(3,(THIS_FILE,"")); 107 108 /* Init logger module. */ 109 init_msg_logger(); 110 msg_logger_set_enabled(1); 111 112 /* Start transaction layer module. */ 113 rc = pjsip_tsx_layer_init(endpt); 114 if (rc != PJ_SUCCESS) { 115 app_perror(" Error initializing transaction module", rc); 116 goto on_return; 117 } 118 119 /* Create loop transport. */ 120 rc = pjsip_loop_start(endpt, NULL); 121 if (rc != PJ_SUCCESS) { 122 app_perror(" error: unable to create datagram loop transport", 123 rc); 124 goto on_return; 125 } 83 126 84 127 //DO_TEST(uri_test()); … … 86 129 //DO_TEST(txdata_test()); 87 130 //DO_TEST(transport_udp_test()); 88 DO_TEST(transport_loop_test()); 89 //DO_TEST(tsx_uac_test()); 131 //DO_TEST(transport_loop_test()); 132 //DO_TEST(tsx_basic_test()); 133 DO_TEST(tsx_uac_test()); 90 134 91 135 on_return: … … 94 138 pj_caching_pool_destroy(&caching_pool); 95 139 96 PJ_LOG(3,( "test", ""));140 PJ_LOG(3,(THIS_FILE, "")); 97 141 98 142 pj_thread_get_stack_info(pj_thread_this(), &filename, &line); 99 PJ_LOG(3,( "test", "Stack max usage: %u, deepest: %s:%u",143 PJ_LOG(3,(THIS_FILE, "Stack max usage: %u, deepest: %s:%u", 100 144 pj_thread_get_stack_max_usage(pj_thread_this()), 101 145 filename, line)); 102 146 if (rc == 0) 103 PJ_LOG(3,( "test", "Looks like everything is okay!.."));147 PJ_LOG(3,(THIS_FILE, "Looks like everything is okay!..")); 104 148 else 105 PJ_LOG(3,( "test", "Test completed with error(s)"));149 PJ_LOG(3,(THIS_FILE, "Test completed with error(s)")); 106 150 107 151 return 0; -
pjproject/trunk/pjsip/src/test-pjsip/test.h
r107 r109 33 33 int transport_udp_test(void); 34 34 int transport_loop_test(void); 35 int tsx_basic_test(void); 35 36 int tsx_uac_test(void); 36 37 … … 42 43 int transport_rt_test( pjsip_transport_type_e tp_type, 43 44 pjsip_transport *ref_tp, 44 char *target_url ); 45 char *target_url, 46 int *pkt_lost); 45 47 46 48 /* Test main entry */ … … 49 51 /* Test utilities. */ 50 52 void app_perror(const char *msg, pj_status_t status); 51 53 int init_msg_logger(void); 54 int msg_logger_set_enabled(pj_bool_t enabled); 55 void flush_events(unsigned duration); 52 56 53 57 #endif /* __TEST_H__ */ -
pjproject/trunk/pjsip/src/test-pjsip/transport_loop_test.c
r107 r109 22 22 #include <pjlib.h> 23 23 24 #define THIS_FILE "transport_loop_test.c" 25 24 26 static int datagram_loop_test() 25 27 { 26 pjsip_transport *loop, *tp; 27 pj_str_t s; 28 int i, log_level; 28 pjsip_transport *loop; 29 int i, pkt_lost; 29 30 pj_sockaddr_in addr; 30 31 pj_status_t status; 31 32 32 PJ_LOG(3,("", "testing datagram loop transport")); 33 34 /* Create loop transport. */ 35 status = pjsip_loop_start(endpt, &loop); 36 if (status != PJ_SUCCESS) { 37 app_perror(" error: unable to create datagram loop transport", 38 status); 39 return -10; 40 } 41 42 /* Create dummy address. */ 43 pj_sockaddr_in_init(&addr, pj_cstr(&s, "130.0.0.1"), TEST_UDP_PORT); 33 PJ_LOG(3,(THIS_FILE, "testing datagram loop transport")); 44 34 45 35 /* Test acquire transport. */ 46 36 status = pjsip_endpt_acquire_transport( endpt, PJSIP_TRANSPORT_LOOP_DGRAM, 47 &addr, sizeof(addr), & tp);37 &addr, sizeof(addr), &loop); 48 38 if (status != PJ_SUCCESS) { 49 app_perror(" error: unable to acquire transport", status);39 app_perror(" error: loop transport is not configured", status); 50 40 return -20; 51 }52 53 /* Check that this is the right transport. */54 if (tp != loop) {55 return -30;56 41 } 57 42 … … 69 54 } 70 55 71 /* For multithreaded round-trip test to work, delay must be set72 * (otherwise functions will be called recursively until no memory is73 * left in the system)74 */75 76 /* Put delay. */77 pjsip_loop_set_delay(loop, 1, NULL);78 79 56 /* Multi-threaded round-trip test. */ 80 status = transport_rt_test(PJSIP_TRANSPORT_LOOP_DGRAM, tp, 81 "sip:bob@130.0.0.1;transport=loop-dgram"); 57 status = transport_rt_test(PJSIP_TRANSPORT_LOOP_DGRAM, loop, 58 "sip:bob@130.0.0.1;transport=loop-dgram", 59 &pkt_lost); 82 60 if (status != 0) 83 61 return status; 84 62 63 if (pkt_lost != 0) { 64 PJ_LOG(3,(THIS_FILE, " error: %d packet(s) was lost", pkt_lost)); 65 return -40; 66 } 85 67 86 /* Next test will test without delay. 87 * This will stress-test the system. 88 */ 89 PJ_LOG(3,(""," performing another multithreaded round-trip test...")); 90 91 /* Remove delay. */ 92 pjsip_loop_set_delay(loop, 0, NULL); 93 94 /* Ignore errors. */ 95 log_level = pj_log_get_level(); 96 pj_log_set_level(2); 68 /* Put delay. */ 69 PJ_LOG(3,(THIS_FILE," setting network delay to 10 ms")); 70 pjsip_loop_set_delay(loop, 10); 97 71 98 72 /* Multi-threaded round-trip test. */ 99 status = transport_rt_test(PJSIP_TRANSPORT_LOOP_DGRAM, tp, 100 "sip:bob@130.0.0.1;transport=loop-dgram"); 73 status = transport_rt_test(PJSIP_TRANSPORT_LOOP_DGRAM, loop, 74 "sip:bob@130.0.0.1;transport=loop-dgram", 75 &pkt_lost); 101 76 if (status != 0) 102 77 return status; 103 78 104 /* Restore log level. */ 105 pj_log_set_level(log_level); 79 if (pkt_lost != 0) { 80 PJ_LOG(3,(THIS_FILE, " error: %d packet(s) was lost", pkt_lost)); 81 return -50; 82 } 83 84 /* Restore delay. */ 85 pjsip_loop_set_delay(loop, 0); 106 86 107 87 /* Check that reference counter is one. */ 108 88 if (pj_atomic_get(loop->ref_cnt) != 1) { 109 return - 30;89 return -50; 110 90 } 111 91 -
pjproject/trunk/pjsip/src/test-pjsip/transport_test.c
r107 r109 21 21 #include <pjsip_core.h> 22 22 #include <pjlib.h> 23 24 #define THIS_FILE "transport_test.c" 23 25 24 26 /////////////////////////////////////////////////////////////////////////////// … … 29 31 int generic_transport_test(pjsip_transport *tp) 30 32 { 31 PJ_LOG(3,( "", " structure test..."));33 PJ_LOG(3,(THIS_FILE, " structure test...")); 32 34 33 35 /* Check that local address name is valid. */ … … 38 40 if (pj_inet_aton(&tp->local_name.host, &addr) != 0) { 39 41 if (addr.s_addr==PJ_INADDR_ANY || addr.s_addr==PJ_INADDR_NONE) { 40 PJ_LOG(3,( "", " Error: invalid address name"));42 PJ_LOG(3,(THIS_FILE, " Error: invalid address name")); 41 43 return -420; 42 44 } … … 122 124 pj_status_t status; 123 125 124 PJ_LOG(4,("test", "Received %d bytes request: --begin-\n"125 "%s\n"126 "--end--",127 rdata->msg_info.len,128 rdata->msg_info.msg_buf));129 130 131 126 status = pjsip_endpt_create_response( endpt, rdata, 200, NULL, &tdata); 132 127 if (status != PJ_SUCCESS) { … … 156 151 { 157 152 if (pj_strcmp2(&rdata->msg_info.call_id, CALL_ID_HDR) == 0) { 158 PJ_LOG(4,("test", "Received %d bytes response: --begin-\n"159 "%s\n"160 "--end--",161 rdata->msg_info.len,162 rdata->msg_info.msg_buf));163 164 153 pj_get_timestamp(&my_recv_time); 165 154 recv_status = PJ_SUCCESS; … … 190 179 char *target_url ) 191 180 { 181 pj_bool_t msg_log_enabled; 192 182 pj_status_t status; 193 183 pj_str_t target, from, to, contact, call_id, body; … … 196 186 pj_time_val timeout; 197 187 198 PJ_LOG(3,( "", " single message round-trip test..."));188 PJ_LOG(3,(THIS_FILE, " single message round-trip test...")); 199 189 200 190 /* Register out test module to receive the message (if necessary). */ … … 206 196 } 207 197 } 198 199 /* Disable message logging. */ 200 msg_log_enabled = msg_logger_set_enabled(0); 208 201 209 202 /* Create a request message. */ … … 250 243 pj_gettimeofday(&now); 251 244 if (PJ_TIME_VAL_GTE(now, timeout)) { 252 PJ_LOG(3,( "", " error: timeout in send/recv test"));245 PJ_LOG(3,(THIS_FILE, " error: timeout in send/recv test")); 253 246 status = -540; 254 247 goto on_return; … … 279 272 unsigned usec_rt; 280 273 usec_rt = pj_elapsed_usec(&my_send_time, &my_recv_time); 281 PJ_LOG(3,("", " round-trip = %d usec", usec_rt)); 282 } 274 PJ_LOG(3,(THIS_FILE, " round-trip = %d usec", usec_rt)); 275 } 276 277 /* Restore message logging. */ 278 msg_logger_set_enabled(msg_log_enabled); 283 279 284 280 status = PJ_SUCCESS; … … 328 324 int sent_request_count, recv_response_count; 329 325 pj_str_t call_id; 326 pj_timer_entry timeout_timer; 327 pj_timer_entry tx_timer; 328 pj_mutex_t *mutex; 330 329 } rt_test_data[16]; 331 330 … … 372 371 pj_str_t target, from, to, contact, call_id; 373 372 pjsip_tx_data *tdata; 373 pj_time_val timeout_delay; 374 375 pj_mutex_lock(rt_test_data[thread_id].mutex); 374 376 375 377 /* Create a request message. */ … … 385 387 NULL, &tdata ); 386 388 if (status != PJ_SUCCESS) { 387 app_perror(" error: unable to create request", status); 389 app_perror(" error: unable to create request", status); 390 pj_mutex_unlock(rt_test_data[thread_id].mutex); 388 391 return -610; 389 392 } … … 396 399 if (status != PJ_SUCCESS) { 397 400 /* Immediate error! */ 398 app_perror(" error: send request", status);401 app_perror(" error: send request", status); 399 402 pjsip_tx_data_dec_ref(tdata); 403 pj_mutex_unlock(rt_test_data[thread_id].mutex); 400 404 return -620; 401 405 } … … 404 408 rt_test_data[thread_id].sent_request_count++; 405 409 410 /* Set timeout timer. */ 411 if (rt_test_data[thread_id].timeout_timer.user_data != NULL) { 412 pjsip_endpt_cancel_timer(endpt, &rt_test_data[thread_id].timeout_timer); 413 } 414 timeout_delay.sec = 100; timeout_delay.msec = 0; 415 rt_test_data[thread_id].timeout_timer.user_data = (void*)1; 416 pjsip_endpt_schedule_timer(endpt, &rt_test_data[thread_id].timeout_timer, 417 &timeout_delay); 418 419 pj_mutex_unlock(rt_test_data[thread_id].mutex); 406 420 return PJ_SUCCESS; 407 421 } … … 414 428 pj_timestamp recv_time; 415 429 430 pj_mutex_lock(rt_test_data[thread_id].mutex); 431 432 /* Stop timer. */ 433 pjsip_endpt_cancel_timer(endpt, &rt_test_data[thread_id].timeout_timer); 434 416 435 /* Update counter and end-time. */ 417 436 rt_test_data[thread_id].recv_response_count++; … … 421 440 pj_add_timestamp(&rt_test_data[thread_id].total_rt_time, &recv_time); 422 441 423 if (!rt_stop) 424 rt_send_request(thread_id); 442 if (!rt_stop) { 443 pj_time_val tx_delay = { 0, 0 }; 444 pj_assert(rt_test_data[thread_id].tx_timer.user_data == NULL); 445 rt_test_data[thread_id].tx_timer.user_data = (void*)1; 446 pjsip_endpt_schedule_timer(endpt, &rt_test_data[thread_id].tx_timer, 447 &tx_delay); 448 } 449 450 pj_mutex_unlock(rt_test_data[thread_id].mutex); 451 425 452 return PJ_TRUE; 426 453 } … … 428 455 } 429 456 430 static int rt_thread(void *arg) 457 static void rt_timeout_timer( pj_timer_heap_t *timer_heap, 458 struct pj_timer_entry *entry ) 459 { 460 pj_mutex_lock(rt_test_data[entry->id].mutex); 461 462 PJ_UNUSED_ARG(timer_heap); 463 PJ_LOG(3,(THIS_FILE, " timeout waiting for response")); 464 rt_test_data[entry->id].timeout_timer.user_data = NULL; 465 466 if (rt_test_data[entry->id].tx_timer.user_data == NULL) { 467 pj_time_val delay = { 0, 0 }; 468 rt_test_data[entry->id].tx_timer.user_data = (void*)1; 469 pjsip_endpt_schedule_timer(endpt, &rt_test_data[entry->id].tx_timer, 470 &delay); 471 } 472 473 pj_mutex_unlock(rt_test_data[entry->id].mutex); 474 } 475 476 static void rt_tx_timer( pj_timer_heap_t *timer_heap, 477 struct pj_timer_entry *entry ) 478 { 479 pj_mutex_lock(rt_test_data[entry->id].mutex); 480 481 PJ_UNUSED_ARG(timer_heap); 482 pj_assert(rt_test_data[entry->id].tx_timer.user_data != NULL); 483 rt_test_data[entry->id].tx_timer.user_data = NULL; 484 rt_send_request(entry->id); 485 486 pj_mutex_unlock(rt_test_data[entry->id].mutex); 487 } 488 489 490 static int rt_worker_thread(void *arg) 431 491 { 432 492 int i, thread_id = (int)arg; … … 435 495 /* Sleep to allow main threads to run. */ 436 496 pj_thread_sleep(10); 437 438 /* Send the first request. */439 if (rt_send_request(thread_id) != PJ_SUCCESS)440 return -1;441 497 442 498 while (!rt_stop) { … … 453 509 int transport_rt_test( pjsip_transport_type_e tp_type, 454 510 pjsip_transport *ref_tp, 455 char *target_url ) 511 char *target_url, 512 int *lost) 456 513 { 457 514 enum { THREADS = 4, INTERVAL = 10 }; … … 459 516 pj_status_t status; 460 517 pj_pool_t *pool; 461 pj_bool_t is_reliable;518 pj_bool_t logger_enabled; 462 519 463 520 pj_timestamp zero_time, total_time; … … 467 524 468 525 469 PJ_LOG(3,( "", " multithreaded round-trip test (%d threads)...",526 PJ_LOG(3,(THIS_FILE, " multithreaded round-trip test (%d threads)...", 470 527 THREADS)); 471 PJ_LOG(3,("", " this will take approx %d seconds, please wait..", INTERVAL)); 472 473 is_reliable = (pjsip_transport_get_flag_from_type(tp_type) & PJSIP_TRANSPORT_RELIABLE); 528 PJ_LOG(3,(THIS_FILE, " this will take approx %d seconds, please wait..", 529 INTERVAL)); 530 531 /* Make sure msg logger is disabled. */ 532 logger_enabled = msg_logger_set_enabled(0); 474 533 475 534 /* Register module (if not yet registered) */ … … 498 557 499 558 pj_memset(&rt_test_data[i], 0, sizeof(rt_test_data[i])); 559 560 /* Init timer entry */ 561 rt_test_data[i].tx_timer.id = i; 562 rt_test_data[i].tx_timer.cb = &rt_tx_timer; 563 rt_test_data[i].timeout_timer.id = i; 564 rt_test_data[i].timeout_timer.cb = &rt_timeout_timer; 500 565 501 566 /* Generate Call-ID for each thread. */ … … 505 570 pj_strcat(&rt_test_data[i].call_id, &str_id); 506 571 572 /* Init mutex. */ 573 status = pj_mutex_create_recursive(pool, "rt", &rt_test_data[i].mutex); 574 if (status != PJ_SUCCESS) { 575 app_perror(" error: unable to create mutex", status); 576 return -615; 577 } 578 507 579 /* Create thread, suspended. */ 508 status = pj_thread_create(pool, "rttest%p", &rt_ thread, (void*)i, 0,580 status = pj_thread_create(pool, "rttest%p", &rt_worker_thread, (void*)i, 0, 509 581 PJ_THREAD_SUSPENDED, &rt_test_data[i].thread); 510 582 if (status != PJ_SUCCESS) { … … 516 588 /* Start threads! */ 517 589 for (i=0; i<THREADS; ++i) { 590 pj_time_val delay = {0,0}; 518 591 pj_thread_resume(rt_test_data[i].thread); 592 593 /* Schedule first message transmissions. */ 594 rt_test_data[i].tx_timer.user_data = (void*)1; 595 pjsip_endpt_schedule_timer(endpt, &rt_test_data[i].tx_timer, &delay); 519 596 } 520 597 … … 529 606 pj_thread_join(rt_test_data[i].thread); 530 607 pj_thread_destroy(rt_test_data[i].thread); 608 } 609 610 /* Destroy rt_test_data */ 611 for (i=0; i<THREADS; ++i) { 612 pj_mutex_destroy(rt_test_data[i].mutex); 613 pjsip_endpt_cancel_timer(endpt, &rt_test_data[i].timeout_timer); 531 614 } 532 615 … … 547 630 total_time.u64 = 0; 548 631 usec_rt = pj_elapsed_usec(&zero_time, &total_time); 549 PJ_LOG(3,("", " done.")); 550 PJ_LOG(3,("", " total %d messages sent", total_sent)); 551 if (total_sent-total_recv) 552 PJ_LOG(2,("", " total %d messages LOST", total_sent-total_recv)); 553 else 554 PJ_LOG(3,("", " no message was lost")); 555 PJ_LOG(3,("", " average round-trip=%d usec", usec_rt)); 632 PJ_LOG(3,(THIS_FILE, " done.")); 633 PJ_LOG(3,(THIS_FILE, " total %d messages sent", total_sent)); 634 PJ_LOG(3,(THIS_FILE, " average round-trip=%d usec", usec_rt)); 556 635 557 636 pjsip_endpt_release_pool(endpt, pool); 558 637 559 if (is_reliable && (total_sent != total_recv)) { 560 PJ_LOG(3,("", " error: %d messages lost", total_sent-total_recv)); 561 return -650; 562 } 638 *lost = total_sent-total_recv; 639 640 /* Flush events. */ 641 flush_events(500); 642 643 /* Restore msg logger. */ 644 msg_logger_set_enabled(logger_enabled); 645 563 646 return 0; 564 647 } -
pjproject/trunk/pjsip/src/test-pjsip/transport_udp_test.c
r107 r109 22 22 #include <pjlib.h> 23 23 24 #define THIS_FILE "transport_udp_test.c" 25 24 26 25 27 /* … … 33 35 pj_str_t s; 34 36 pj_status_t status; 35 int i ;37 int i, pkt_lost; 36 38 37 39 pj_sockaddr_in_init(&addr, NULL, TEST_UDP_PORT); … … 85 87 /* Multi-threaded round-trip test. */ 86 88 status = transport_rt_test(PJSIP_TRANSPORT_UDP, tp, 87 "sip:alice@127.0.0.1:"TEST_UDP_PORT_STR); 89 "sip:alice@127.0.0.1:"TEST_UDP_PORT_STR, 90 &pkt_lost); 88 91 if (status != 0) 89 92 return status; 93 94 if (pkt_lost != 0) 95 PJ_LOG(3,(THIS_FILE, " note: %d packet(s) was lost", pkt_lost)); 90 96 91 97 /* Check again that reference counter is 1. */ … … 101 107 return -90; 102 108 109 /* Flush events. */ 110 PJ_LOG(3,(THIS_FILE, " Flushing events, 1 second...")); 111 flush_events(1000); 103 112 104 113 /* Done */ -
pjproject/trunk/pjsip/src/test-pjsip/tsx_uac_test.c
r107 r109 22 22 #include <pjlib.h> 23 23 24 #define THIS_FILE "tsx_uac_test.c" 25 26 24 27 /***************************************************************************** 25 28 ** 26 ** UAC basic retransmission and timeout test. 27 ** 28 ** This will test the retransmission of the UAC transaction. Remote will not 29 ** answer the transaction, so the transaction should fail. 30 ** 29 ** UAC tests. 30 ** 31 ** This file performs various tests for UAC transactions. Each test will have 32 ** a different Via branch param so that message receiver module and 33 ** transaction user module can identify which test is being carried out. 34 ** 35 ** TEST1_BRANCH_ID 36 ** Perform basic retransmission and timeout test. Message receiver will 37 ** verify that retransmission is received at correct time. 38 ** This test verifies the following requirements: 39 ** - retransmit timer doubles for INVITE 40 ** - retransmit timer doubles and caps off for non-INVITE 41 ** - retransmit timer timer is precise 42 ** - correct timeout and retransmission count 43 ** Requirements not tested: 44 ** - retransmit timer only starts after resolving has completed. 45 ** 46 ** TEST2_BRANCH_ID 47 ** Test scenario where resolver is unable to resolve destination host. 48 ** 49 ** TEST3_BRANCH_ID 50 ** Test scenario where transaction is terminated while resolver is still 51 ** running. 52 ** 53 ** TEST4_BRANCH_ID 54 ** Test scenario where transport failed after several retransmissions. 55 ** 56 ** TEST5_BRANCH_ID 57 ** Test scenario where transaction is terminated by user after several 58 ** retransmissions. 59 ** 60 ** TEST6_BRANCH_ID 61 ** Test successfull non-INVITE transaction. 62 ** It tests the following requirements: 63 ** - transaction correctly moves to COMPLETED state. 64 ** - retransmission must cease. 65 ** - tx_data must be maintained until state is terminated. 66 ** 67 ** TEST7_BRANCH_ID 68 ** Test successfull non-INVITE transaction, with provisional response. 69 ** 70 ** TEST8_BRANCH_ID 71 ** Test failed INVITE transaction (e.g. ACK must be received) 72 ** 73 ** TEST9_BRANCH_ID 74 ** Test failed INVITE transaction with provisional response. 75 ** 76 ** 31 77 ***************************************************************************** 32 78 */ 33 79 34 static char *CALL_ID1 = "UAC-Tsx-Basic-Test1"; 80 static char *TEST1_BRANCH_ID = PJSIP_RFC3261_BRANCH_ID "-Test1"; 81 static char *TEST2_BRANCH_ID = PJSIP_RFC3261_BRANCH_ID "-Test2"; 82 static char *TEST3_BRANCH_ID = PJSIP_RFC3261_BRANCH_ID "-Test3"; 83 static char *TEST4_BRANCH_ID = PJSIP_RFC3261_BRANCH_ID "-Test4"; 84 static char *TEST5_BRANCH_ID = PJSIP_RFC3261_BRANCH_ID "-Test5"; 85 static char *TEST6_BRANCH_ID = PJSIP_RFC3261_BRANCH_ID "-Test6"; 86 static char *TEST7_BRANCH_ID = PJSIP_RFC3261_BRANCH_ID "-Test7"; 87 static char *TEST8_BRANCH_ID = PJSIP_RFC3261_BRANCH_ID "-Test8"; 88 static char *TEST9_BRANCH_ID = PJSIP_RFC3261_BRANCH_ID "-Test9"; 89 90 #define TEST1_ALLOWED_DIFF (150) 91 #define TEST4_RETRANSMIT_CNT 3 92 #define TEST5_RETRANSMIT_CNT 3 93 94 35 95 static void tsx_user_on_tsx_state(pjsip_transaction *tsx, pjsip_event *e); 36 96 static pj_bool_t msg_receiver_on_rx_request(pjsip_rx_data *rdata); … … 52 112 NULL, /* on_rx_request() */ 53 113 NULL, /* on_rx_response() */ 114 NULL, /* on_tx_request() */ 115 NULL, /* on_tx_response() */ 54 116 &tsx_user_on_tsx_state, /* on_tsx_state() */ 55 117 }; … … 71 133 &msg_receiver_on_rx_request, /* on_rx_request() */ 72 134 NULL, /* on_rx_response() */ 135 NULL, /* on_tx_request() */ 136 NULL, /* on_tx_response() */ 73 137 NULL, /* on_tsx_state() */ 74 138 }; 75 139 76 /* Static vars . */140 /* Static vars, which will be reset on each test. */ 77 141 static int recv_count; 78 142 static pj_time_val recv_last; 79 143 static pj_bool_t test_complete; 80 144 145 /* Loop transport instance. */ 146 static pjsip_transport *loop; 147 148 /* 149 * This is the handler to receive state changed notification from the 150 * transaction. It is used to verify that the transaction behaves according 151 * to the test scenario. 152 */ 81 153 static void tsx_user_on_tsx_state(pjsip_transaction *tsx, pjsip_event *e) 82 154 { 83 if (tsx->state == PJSIP_TSX_STATE_TERMINATED && test_complete==0) 84 test_complete = 1; 155 if (pj_strcmp2(&tsx->branch, TEST1_BRANCH_ID)==0) { 156 /* 157 * Transaction with TEST1_BRANCH_ID should terminate with transaction 158 * timeout status. 159 */ 160 if (tsx->state == PJSIP_TSX_STATE_TERMINATED) { 161 162 if (test_complete == 0) 163 test_complete = 1; 164 165 /* Test the status code. */ 166 if (tsx->status_code != PJSIP_SC_TSX_TIMEOUT) { 167 PJ_LOG(3,(THIS_FILE, 168 " error: status code is %d instead of %d", 169 tsx->status_code, PJSIP_SC_TSX_TIMEOUT)); 170 test_complete = -710; 171 } 172 } 173 174 } else if (pj_strcmp2(&tsx->branch, TEST2_BRANCH_ID)==0) { 175 /* 176 * Transaction with TEST2_BRANCH_ID should terminate with transport error. 177 */ 178 if (tsx->state == PJSIP_TSX_STATE_TERMINATED) { 179 180 /* Test the status code. */ 181 if (tsx->status_code != PJSIP_SC_TSX_TRANSPORT_ERROR) { 182 PJ_LOG(3,(THIS_FILE, 183 " error: status code is %d instead of %d", 184 tsx->status_code, PJSIP_SC_TSX_TRANSPORT_ERROR)); 185 test_complete = -720; 186 } 187 188 if (test_complete == 0) 189 test_complete = 1; 190 } 191 192 } else if (pj_strcmp2(&tsx->branch, TEST3_BRANCH_ID)==0) { 193 /* 194 * This test terminates the transaction while resolver is still 195 * running. 196 */ 197 if (tsx->state == PJSIP_TSX_STATE_CALLING) { 198 199 /* Terminate the transaction. */ 200 pjsip_tsx_terminate(tsx, PJSIP_SC_REQUEST_TERMINATED); 201 202 } else if (tsx->state == PJSIP_TSX_STATE_TERMINATED) { 203 204 /* Check if status code is correct. */ 205 if (tsx->status_code != PJSIP_SC_REQUEST_TERMINATED) { 206 PJ_LOG(3,(THIS_FILE, 207 " error: status code is %d instead of %d", 208 tsx->status_code, PJSIP_SC_REQUEST_TERMINATED)); 209 test_complete = -730; 210 } 211 212 if (test_complete == 0) 213 test_complete = 1; 214 215 } 216 217 } else if (pj_strcmp2(&tsx->branch, TEST4_BRANCH_ID)==0) { 218 /* 219 * This test simulates transport failure after several 220 * retransmissions. 221 */ 222 if (tsx->state == PJSIP_TSX_STATE_TERMINATED) { 223 224 /* Status code must be transport error. */ 225 if (tsx->status_code != PJSIP_SC_TSX_TRANSPORT_ERROR) { 226 PJ_LOG(3,(THIS_FILE, 227 " error: status code is %d instead of %d", 228 tsx->status_code, PJSIP_SC_TSX_TRANSPORT_ERROR)); 229 test_complete = -730; 230 } 231 232 /* Must have correct retransmission count. */ 233 if (tsx->retransmit_count != TEST4_RETRANSMIT_CNT) { 234 PJ_LOG(3,(THIS_FILE, 235 " error: retransmit cnt is %d instead of %d", 236 tsx->retransmit_count, TEST4_RETRANSMIT_CNT)); 237 test_complete = -731; 238 } 239 240 if (test_complete == 0) 241 test_complete = 1; 242 } 243 244 245 } else if (pj_strcmp2(&tsx->branch, TEST5_BRANCH_ID)==0) { 246 /* 247 * This test simulates transport failure after several 248 * retransmissions. 249 */ 250 if (tsx->state == PJSIP_TSX_STATE_TERMINATED) { 251 252 /* Status code must be PJSIP_SC_REQUEST_TERMINATED. */ 253 if (tsx->status_code != PJSIP_SC_REQUEST_TERMINATED) { 254 PJ_LOG(3,(THIS_FILE, 255 " error: status code is %d instead of %d", 256 tsx->status_code, PJSIP_SC_REQUEST_TERMINATED)); 257 test_complete = -733; 258 } 259 260 /* Must have correct retransmission count. */ 261 if (tsx->retransmit_count != TEST5_RETRANSMIT_CNT) { 262 PJ_LOG(3,(THIS_FILE, 263 " error: retransmit cnt is %d instead of %d", 264 tsx->retransmit_count, TEST5_RETRANSMIT_CNT)); 265 test_complete = -734; 266 } 267 268 if (test_complete == 0) 269 test_complete = 1; 270 } 271 272 273 } else if (pj_strcmp2(&tsx->branch, TEST6_BRANCH_ID)==0) { 274 /* 275 * Successfull non-INVITE transaction. 276 */ 277 if (tsx->state == PJSIP_TSX_STATE_COMPLETED) { 278 279 /* Status code must be 202. */ 280 if (tsx->status_code != 202) { 281 PJ_LOG(3,(THIS_FILE, 282 " error: status code is %d instead of %d", 283 tsx->status_code, 202)); 284 test_complete = -736; 285 } 286 287 /* Must have correct retransmission count. */ 288 if (tsx->retransmit_count != 0) { 289 PJ_LOG(3,(THIS_FILE, 290 " error: retransmit cnt is %d instead of %d", 291 tsx->retransmit_count, 0)); 292 test_complete = -737; 293 } 294 295 /* Must still keep last_tx */ 296 if (tsx->last_tx == NULL) { 297 PJ_LOG(3,(THIS_FILE, 298 " error: transaction lost last_tx")); 299 test_complete = -738; 300 } 301 302 if (test_complete == 0) { 303 test_complete = 1; 304 pjsip_tsx_terminate(tsx, 202); 305 } 306 } 307 } 85 308 } 86 309 87 310 #define DIFF(a,b) ((a<b) ? (b-a) : (a-b)) 88 311 312 /* 313 * This is the handler to receive message for this test. It is used to 314 * control and verify the behavior of the message transmitted by the 315 * transaction. 316 */ 89 317 static pj_bool_t msg_receiver_on_rx_request(pjsip_rx_data *rdata) 90 318 { 91 if (pj_strcmp2(&rdata->msg_info. call_id, CALL_ID1) == 0) {319 if (pj_strcmp2(&rdata->msg_info.via->branch_param, TEST1_BRANCH_ID) == 0) { 92 320 /* 93 * The CALL_ID1test performs the verifications for transaction321 * The TEST1_BRANCH_ID test performs the verifications for transaction 94 322 * retransmission mechanism. It will not answer the incoming request 95 323 * with any response. … … 97 325 pjsip_msg *msg = rdata->msg_info.msg; 98 326 99 PJ_LOG(4,( "", "received request"));327 PJ_LOG(4,(THIS_FILE, " received request")); 100 328 101 329 /* Only wants to take INVITE or OPTIONS method. */ … … 103 331 msg->line.req.method.id != PJSIP_OPTIONS_METHOD) 104 332 { 105 PJ_LOG(3,( "", "error: received unexpected method %.*s",333 PJ_LOG(3,(THIS_FILE, " error: received unexpected method %.*s", 106 334 msg->line.req.method.name.slen, 107 335 msg->line.req.method.name.ptr)); … … 112 340 if (recv_count == 0) { 113 341 recv_count++; 114 pj_gettimeofday(&recv_last); 342 //pj_gettimeofday(&recv_last); 343 recv_last = rdata->pkt_info.timestamp; 115 344 } else { 116 345 pj_time_val now; 117 346 unsigned msec_expected, msec_elapsed; 118 119 pj_gettimeofday(&now); 347 int max_received; 348 349 //pj_gettimeofday(&now); 350 now = rdata->pkt_info.timestamp; 120 351 PJ_TIME_VAL_SUB(now, recv_last); 121 352 msec_elapsed = now.sec*1000 + now.msec; … … 127 358 if (msec_expected > PJSIP_T2_TIMEOUT) 128 359 msec_expected = PJSIP_T2_TIMEOUT; 129 } 130 131 if (DIFF(msec_expected, msec_elapsed) > 100) { 132 PJ_LOG(3,(""," error: expecting %d-th retransmission in %d " 133 "ms, received in %d ms", 134 recv_count-1, msec_expected, msec_elapsed)); 360 max_received = 11; 361 } else { 362 max_received = 7; 363 } 364 365 if (DIFF(msec_expected, msec_elapsed) > TEST1_ALLOWED_DIFF) { 366 PJ_LOG(3,(THIS_FILE, 367 " error: expecting retransmission no. %d in %d " 368 "ms, received in %d ms", 369 recv_count-1, msec_expected, msec_elapsed)); 135 370 test_complete = -610; 136 371 } 137 372 138 if (recv_count > 7) { 139 PJ_LOG(3,("", " error: too many messages (%d) received", 140 recv_count)); 373 374 if (recv_count > max_received) { 375 PJ_LOG(3,(THIS_FILE, 376 " error: too many messages (%d) received", 377 recv_count)); 141 378 test_complete = -620; 142 379 } 143 380 144 pj_gettimeofday(&recv_last); 381 //pj_gettimeofday(&recv_last); 382 recv_last = rdata->pkt_info.timestamp; 145 383 } 146 384 return PJ_TRUE; 147 } 385 386 } else 387 if (pj_strcmp2(&rdata->msg_info.via->branch_param, TEST4_BRANCH_ID) == 0) { 388 /* 389 * The TEST4_BRANCH_ID test simulates transport failure after several 390 * retransmissions. 391 */ 392 recv_count++; 393 394 if (recv_count == TEST4_RETRANSMIT_CNT) { 395 /* Simulate transport failure. */ 396 pjsip_loop_set_failure(loop, 2, NULL); 397 398 } else if (recv_count > TEST4_RETRANSMIT_CNT) { 399 PJ_LOG(3,(THIS_FILE," error: not expecting %d-th packet!", 400 recv_count)); 401 test_complete = -631; 402 } 403 404 return PJ_TRUE; 405 406 407 } else 408 if (pj_strcmp2(&rdata->msg_info.via->branch_param, TEST5_BRANCH_ID) == 0) { 409 /* 410 * The TEST5_BRANCH_ID test simulates user terminating the transaction 411 * after several retransmissions. 412 */ 413 recv_count++; 414 415 if (recv_count == TEST5_RETRANSMIT_CNT+1) { 416 pj_str_t key; 417 pjsip_transaction *tsx; 418 419 pjsip_tsx_create_key( rdata->tp_info.pool, &key, PJSIP_ROLE_UAC, 420 &rdata->msg_info.msg->line.req.method, rdata); 421 tsx = pjsip_tsx_layer_find_tsx(&key, PJ_TRUE); 422 if (tsx) { 423 pjsip_tsx_terminate(tsx, PJSIP_SC_REQUEST_TERMINATED); 424 pj_mutex_unlock(tsx->mutex); 425 } else { 426 PJ_LOG(3,(THIS_FILE, " error: uac transaction not found!")); 427 test_complete = -633; 428 } 429 430 } else if (recv_count > TEST5_RETRANSMIT_CNT+1) { 431 PJ_LOG(3,(THIS_FILE," error: not expecting %d-th packet!", 432 recv_count)); 433 test_complete = -634; 434 } 435 436 return PJ_TRUE; 437 438 } else 439 if (pj_strcmp2(&rdata->msg_info.via->branch_param, TEST6_BRANCH_ID) == 0) { 440 /* 441 * The TEST5_BRANCH_ID test successfull non-INVITE transaction. 442 */ 443 pjsip_tx_data *tdata; 444 pjsip_response_addr res_addr; 445 pj_status_t status; 446 447 recv_count++; 448 449 if (recv_count > 1) { 450 PJ_LOG(3,(THIS_FILE," error: not expecting %d-th packet!", 451 recv_count)); 452 test_complete = -635; 453 } 454 455 status = pjsip_endpt_create_response(endpt, rdata, 202, NULL, &tdata); 456 if (status != PJ_SUCCESS) { 457 app_perror(" error: unable to create response", status); 458 test_complete = -636; 459 } 460 461 status = pjsip_get_response_addr(tdata->pool, rdata, &res_addr); 462 if (status != PJ_SUCCESS) { 463 app_perror(" error: unable to get response addr", status); 464 test_complete = -637; 465 } 466 467 status = pjsip_endpt_send_response(endpt, &res_addr, tdata, NULL,NULL); 468 if (status != PJ_SUCCESS) { 469 app_perror(" error: unable to send response", status); 470 test_complete = -638; 471 pjsip_tx_data_dec_ref(tdata); 472 } 473 474 return PJ_TRUE; 475 } 476 148 477 return PJ_FALSE; 149 478 } 150 479 151 /***************************************************************************** 152 ** 153 ** UAC basic retransmission and timeout test. 154 ** 155 ** This will test the retransmission of the UAC transaction. Remote will not 156 ** answer the transaction, so the transaction should fail. The Call-ID 157 ** CALL_ID1 will be used for this test. 158 ** 159 ***************************************************************************** 160 */ 161 static int tsx_uac_retransmit_test(const pjsip_method *method) 480 /* 481 * The generic test framework, used by most of the tests. 482 */ 483 static int perform_tsx_test(int dummy, char *target_uri, char *from_uri, 484 char *branch_param, int test_time, 485 const pjsip_method *method) 162 486 { 163 487 pjsip_tx_data *tdata; 164 488 pjsip_transaction *tsx; 165 char buf[80];166 pj _str_t target, from, call_id, tsx_key;489 pj_str_t target, from, tsx_key; 490 pjsip_via_hdr *via; 167 491 pj_time_val timeout; 168 492 pj_status_t status; 169 493 170 PJ_LOG(3,("", " basic uac retransmission and timeout test")); 171 172 pj_sprintf(buf, "sip:alice@127.0.0.1:%d", TEST_UDP_PORT); 173 target = pj_str(buf); 174 from = pj_str("sip:bob@127.0.0.1"); 175 call_id = pj_str(CALL_ID1); 494 PJ_LOG(3,(THIS_FILE, 495 " please standby, this will take at most %d seconds..", 496 test_time)); 497 498 /* Reset test. */ 499 recv_count = 0; 500 test_complete = 0; 501 502 /* Init headers. */ 503 target = pj_str(target_uri); 504 from = pj_str(from_uri); 176 505 177 506 /* Create request. */ 178 507 status = pjsip_endpt_create_request( endpt, method, &target, 179 &from, &target, NULL, &call_id, -1,508 &from, &target, NULL, NULL, -1, 180 509 NULL, &tdata); 181 510 if (status != PJ_SUCCESS) { 182 511 app_perror(" Error: unable to create request", status); 183 return -500; 184 } 512 return -100; 513 } 514 515 /* Set the branch param for test 1. */ 516 via = pjsip_msg_find_hdr(tdata->msg, PJSIP_H_VIA, NULL); 517 via->branch_param = pj_str(branch_param); 185 518 186 519 /* Add additional reference to tdata to prevent transaction from … … 193 526 if (status != PJ_SUCCESS) { 194 527 app_perror(" Error: unable to create UAC transaction", status); 195 return -510; 528 pjsip_tx_data_dec_ref(tdata); 529 return -110; 196 530 } 197 531 … … 201 535 /* Send the message. */ 202 536 status = pjsip_tsx_send_msg(tsx, NULL); 203 if (status != PJ_SUCCESS) { 204 app_perror(" Error: unable to send request", status); 205 return -520; 206 } 537 // Ignore send result. Some tests do deliberately triggers error 538 // when sending message. 539 //if (status != PJ_SUCCESS) { 540 // app_perror(" Error: unable to send request", status); 541 // pjsip_tx_data_dec_ref(tdata); 542 // return -120; 543 //} 544 207 545 208 546 /* Set test completion time. */ 209 547 pj_gettimeofday(&timeout); 210 timeout.sec += 33;548 timeout.sec += test_time; 211 549 212 550 /* Wait until test complete. */ 213 551 while (!test_complete) { 214 pj_time_val now ;215 216 pjsip_endpt_handle_events(endpt, NULL);552 pj_time_val now, poll_delay = {0, 10}; 553 554 pjsip_endpt_handle_events(endpt, &poll_delay); 217 555 218 556 pj_gettimeofday(&now); 219 557 if (now.sec > timeout.sec) { 220 PJ_LOG(3,("", " Error: test has timed out")); 221 return -530; 222 } 223 } 224 225 if (status < 0) 558 PJ_LOG(3,(THIS_FILE, " Error: test has timed out")); 559 pjsip_tx_data_dec_ref(tdata); 560 return -130; 561 } 562 } 563 564 if (status < 0) { 565 pjsip_tx_data_dec_ref(tdata); 226 566 return status; 567 } 568 569 if (test_complete < 0) { 570 tsx = pjsip_tsx_layer_find_tsx(&tsx_key, PJ_TRUE); 571 if (tsx) { 572 pjsip_tsx_terminate(tsx, PJSIP_SC_REQUEST_TERMINATED); 573 pj_mutex_unlock(tsx->mutex); 574 flush_events(1000); 575 } 576 pjsip_tx_data_dec_ref(tdata); 577 return test_complete; 578 } 579 580 /* Allow transaction to destroy itself */ 581 flush_events(500); 227 582 228 583 /* Make sure transaction has been destroyed. */ 229 584 if (pjsip_tsx_layer_find_tsx(&tsx_key, PJ_FALSE) != NULL) { 230 PJ_LOG(3,("", " Error: transaction has not been destroyed")); 231 return -540; 585 PJ_LOG(3,(THIS_FILE, " Error: transaction has not been destroyed")); 586 pjsip_tx_data_dec_ref(tdata); 587 return -140; 232 588 } 233 589 234 590 /* Check tdata reference counter. */ 235 591 if (pj_atomic_get(tdata->ref_cnt) != 1) { 236 PJ_LOG(3,( "", " Error: tdata reference counter is %d",592 PJ_LOG(3,(THIS_FILE, " Error: tdata reference counter is %d", 237 593 pj_atomic_get(tdata->ref_cnt))); 238 return -550; 594 pjsip_tx_data_dec_ref(tdata); 595 return -150; 239 596 } 240 597 … … 247 604 /***************************************************************************** 248 605 ** 606 ** TEST1_BRANCH_ID: UAC basic retransmission and timeout test. 607 ** 608 ** This will test the retransmission of the UAC transaction. Remote will not 609 ** answer the transaction, so the transaction should fail. The Via branch prm 610 ** TEST1_BRANCH_ID will be used for this test. 611 ** 612 ***************************************************************************** 613 */ 614 static int tsx_uac_retransmit_test(void) 615 { 616 int status, enabled; 617 int i; 618 struct { 619 const pjsip_method *method; 620 unsigned delay; 621 } sub_test[] = 622 { 623 { &pjsip_invite_method, 0}, 624 { &pjsip_invite_method, TEST1_ALLOWED_DIFF*2}, 625 { &pjsip_options_method, 0}, 626 { &pjsip_options_method, TEST1_ALLOWED_DIFF*2} 627 }; 628 629 PJ_LOG(3,(THIS_FILE, " test1: basic uac retransmit and timeout test")); 630 631 632 /* For this test. message printing shound be disabled because it makes 633 * incorrect timing. 634 */ 635 enabled = msg_logger_set_enabled(0); 636 637 for (i=0; i<PJ_ARRAY_SIZE(sub_test); ++i) { 638 639 PJ_LOG(3,(THIS_FILE, 640 " variant %c: %s with %d ms network delay", 641 ('a' + i), 642 sub_test[i].method->name.ptr, 643 sub_test[i].delay)); 644 645 /* Configure transport */ 646 pjsip_loop_set_failure(loop, 0, NULL); 647 pjsip_loop_set_recv_delay(loop, sub_test[i].delay, NULL); 648 649 /* Do the test. */ 650 status = perform_tsx_test(-500, "sip:bob@127.0.0.1;transport=loop-dgram", 651 "sip:alice@127.0.0.1;transport=loop-dgram", 652 TEST1_BRANCH_ID, 653 35, sub_test[i].method); 654 if (status != 0) 655 break; 656 } 657 658 /* Restore transport. */ 659 pjsip_loop_set_recv_delay(loop, 0, NULL); 660 661 /* Restore msg logger. */ 662 msg_logger_set_enabled(enabled); 663 664 /* Done. */ 665 return status; 666 } 667 668 /***************************************************************************** 669 ** 670 ** TEST2_BRANCH_ID: UAC resolve error test. 671 ** 672 ** Test the scenario where destination host is unresolvable. There are 673 ** two variants: 674 ** (a) resolver returns immediate error 675 ** (b) resolver returns error via the callback. 676 ** 677 ***************************************************************************** 678 */ 679 static int tsx_resolve_error_test(void) 680 { 681 int status; 682 683 PJ_LOG(3,(THIS_FILE, " test2: resolve error test")); 684 685 /* 686 * Variant (a): immediate resolve error. 687 */ 688 PJ_LOG(3,(THIS_FILE, " variant a: immediate resolving error")); 689 690 status = perform_tsx_test(-800, 691 "sip:bob@unresolved-host;transport=loop-dgram", 692 "sip:alice@127.0.0.1;transport=loop-dgram", 693 TEST2_BRANCH_ID, 10, 694 &pjsip_options_method); 695 if (status != 0) 696 return status; 697 698 /* 699 * Variant (b): error via callback. 700 */ 701 PJ_LOG(3,(THIS_FILE, " variant b: error via callback")); 702 703 /* Set loop transport to return delayed error. */ 704 pjsip_loop_set_failure(loop, 2, NULL); 705 pjsip_loop_set_send_callback_delay(loop, 10, NULL); 706 707 status = perform_tsx_test(-800, "sip:bob@127.0.0.1;transport=loop-dgram", 708 "sip:alice@127.0.0.1;transport=loop-dgram", 709 TEST2_BRANCH_ID, 2, 710 &pjsip_options_method); 711 if (status != 0) 712 return status; 713 714 /* Restore loop transport settings. */ 715 pjsip_loop_set_failure(loop, 0, NULL); 716 pjsip_loop_set_send_callback_delay(loop, 0, NULL); 717 718 return status; 719 } 720 721 722 /***************************************************************************** 723 ** 724 ** TEST3_BRANCH_ID: UAC terminate while resolving test. 725 ** 726 ** Terminate the transaction while resolver is still running. 727 ** 728 ***************************************************************************** 729 */ 730 static int tsx_terminate_resolving_test(void) 731 { 732 unsigned prev_delay; 733 pj_status_t status; 734 735 PJ_LOG(3,(THIS_FILE, " test3: terminate while resolving test")); 736 737 /* Configure transport delay. */ 738 pjsip_loop_set_send_callback_delay(loop, 100, &prev_delay); 739 740 /* Start the test. */ 741 status = perform_tsx_test(-900, "sip:127.0.0.1;transport=loop-dgram", 742 "sip:127.0.0.1;transport=loop-dgram", 743 TEST3_BRANCH_ID, 2, &pjsip_options_method); 744 745 /* Restore delay. */ 746 pjsip_loop_set_send_callback_delay(loop, prev_delay, NULL); 747 748 return status; 749 } 750 751 752 /***************************************************************************** 753 ** 754 ** TEST4_BRANCH_ID: Transport failed after several retransmissions 755 ** 756 ** There are two variants of this test: (a) failure occurs immediately when 757 ** transaction calls pjsip_transport_send() or (b) failure is reported via 758 ** transport callback. 759 ** 760 ***************************************************************************** 761 */ 762 static int tsx_retransmit_fail_test(void) 763 { 764 int i; 765 unsigned delay[] = {0, 10}; 766 pj_status_t status; 767 768 PJ_LOG(3,(THIS_FILE, 769 " test4: transport fails after several retransmissions test")); 770 771 772 for (i=0; i<PJ_ARRAY_SIZE(delay); ++i) { 773 774 PJ_LOG(3,(THIS_FILE, 775 " variant %c: transport delay %d ms", ('a'+i), delay[i])); 776 777 /* Configure transport delay. */ 778 pjsip_loop_set_send_callback_delay(loop, delay[i], NULL); 779 780 /* Restore transport failure mode. */ 781 pjsip_loop_set_failure(loop, 0, 0); 782 783 /* Start the test. */ 784 status = perform_tsx_test(-1000, "sip:127.0.0.1;transport=loop-dgram", 785 "sip:127.0.0.1;transport=loop-dgram", 786 TEST4_BRANCH_ID, 6, &pjsip_options_method); 787 788 if (status != 0) 789 break; 790 791 } 792 793 /* Restore delay. */ 794 pjsip_loop_set_send_callback_delay(loop, 0, NULL); 795 796 /* Restore transport failure mode. */ 797 pjsip_loop_set_failure(loop, 0, 0); 798 799 return status; 800 } 801 802 803 /***************************************************************************** 804 ** 805 ** TEST5_BRANCH_ID: Terminate transaction after several retransmissions 806 ** 807 ***************************************************************************** 808 */ 809 static int tsx_terminate_after_retransmit_test(void) 810 { 811 int status; 812 813 PJ_LOG(3,(THIS_FILE, " test5: terminate after retransmissions")); 814 815 /* Do the test. */ 816 status = perform_tsx_test(-1100, "sip:bob@127.0.0.1;transport=loop-dgram", 817 "sip:alice@127.0.0.1;transport=loop-dgram", 818 TEST5_BRANCH_ID, 819 6, &pjsip_options_method); 820 821 /* Done. */ 822 return status; 823 } 824 825 826 /***************************************************************************** 827 ** 828 ** TEST6_BRANCH_ID: Successfull non-invite transaction 829 ** 830 ***************************************************************************** 831 */ 832 static int tsx_successfull_non_invite_test(void) 833 { 834 int i, status; 835 unsigned delay[] = { 1, 200 }; 836 837 PJ_LOG(3,(THIS_FILE, " test6: successfull non-invite transaction")); 838 839 /* Do the test. */ 840 for (i=0; i<PJ_ARRAY_SIZE(delay); ++i) { 841 842 PJ_LOG(3,(THIS_FILE, " variant %c: with %d ms transport delay", 843 ('a'+i), delay[i])); 844 845 pjsip_loop_set_delay(loop, delay[i]); 846 847 status = perform_tsx_test(-1200, 848 "sip:bob@127.0.0.1;transport=loop-dgram", 849 "sip:alice@127.0.0.1;transport=loop-dgram", 850 TEST6_BRANCH_ID, 851 2, &pjsip_options_method); 852 if (status != 0) 853 return status; 854 } 855 856 pjsip_loop_set_delay(loop, 0); 857 858 /* Done. */ 859 return status; 860 } 861 862 863 /***************************************************************************** 864 ** 249 865 ** UAC Transaction Test. 250 866 ** … … 254 870 { 255 871 pj_sockaddr_in addr; 256 pj_str_t tmp;257 pjsip_transport *tp;258 872 pj_status_t status; 259 873 260 pj_sockaddr_in_init(&addr, pj_cstr(&tmp, "127.0.0.1"), TEST_UDP_PORT); 261 262 /* Start UDP transport if necessary. */ 263 if (pjsip_endpt_acquire_transport(endpt, PJSIP_TRANSPORT_UDP, &addr, 264 sizeof(addr), &tp) != PJ_SUCCESS) 265 { 266 addr.sin_addr.s_addr = 0; 267 status = pjsip_udp_transport_start( endpt, &addr, NULL, 1, NULL); 268 if (status != PJ_SUCCESS) { 269 app_perror(" Error: unable to start UDP transport", status); 270 return -10; 271 } 272 } else { 273 pjsip_transport_dec_ref(tp); 274 } 275 276 /* Start transaction layer module. */ 277 status = pjsip_tsx_layer_init(endpt); 874 /* Check if loop transport is configured. */ 875 status = pjsip_endpt_acquire_transport(endpt, PJSIP_TRANSPORT_LOOP_DGRAM, 876 &addr, sizeof(addr), &loop); 278 877 if (status != PJ_SUCCESS) { 279 app_perror(" Error initializing transaction module", status);280 return - 20;878 PJ_LOG(3,(THIS_FILE, " Error: loop transport is not configured!")); 879 return -10; 281 880 } 282 881 … … 290 889 if (status != PJ_SUCCESS) { 291 890 app_perror(" Error: unable to register module", status); 292 return -30; 293 } 294 295 /* Basic retransmit and timeout test for INVITE. */ 296 status = tsx_uac_retransmit_test(&pjsip_invite_method); 891 return -40; 892 } 893 894 #if 0 895 /* TEST1_BRANCH_ID: Basic retransmit and timeout test. */ 896 status = tsx_uac_retransmit_test(); 297 897 if (status != 0) 298 898 return status; 299 899 300 /* Basic retransmit and timeout test for non-INVITE. */301 status = tsx_ uac_retransmit_test(&pjsip_options_method);900 /* TEST2_BRANCH_ID: Resolve error test. */ 901 status = tsx_resolve_error_test(); 302 902 if (status != 0) 303 903 return status; 304 904 905 /* TEST3_BRANCH_ID: UAC terminate while resolving test. */ 906 status = tsx_terminate_resolving_test(); 907 if (status != 0) 908 return status; 909 910 /* TEST4_BRANCH_ID: Transport failed after several retransmissions */ 911 status = tsx_retransmit_fail_test(); 912 if (status != 0) 913 return status; 914 915 /* TEST5_BRANCH_ID: Terminate transaction after several retransmissions */ 916 status = tsx_terminate_after_retransmit_test(); 917 if (status != 0) 918 return status; 919 #endif 920 921 /* TEST6_BRANCH_ID: Successfull non-invite transaction */ 922 status = tsx_successfull_non_invite_test(); 923 if (status != 0) 924 return status; 925 926 927 pjsip_transport_dec_ref(loop); 305 928 return 0; 306 929 } 930 -
pjproject/trunk/pjsip/src/test-pjsip/txdata_test.c
r107 r109 24 24 #define HFIND(msg,h,H) ((pjsip_##h##_hdr*) pjsip_msg_find_hdr(msg, PJSIP_H_##H, NULL)) 25 25 26 #define THIS_FILE "txdata_test.c" 27 28 26 29 /* 27 30 * This tests various core message creation functions. … … 51 54 /* Buffer must be invalid. */ 52 55 if (pjsip_tx_data_is_valid(invite) != 0) { 53 PJ_LOG(3,( "", " error: buffer must be invalid"));56 PJ_LOG(3,(THIS_FILE, " error: buffer must be invalid")); 54 57 return -14; 55 58 } 56 59 /* Reference counter must be set to 1. */ 57 60 if (pj_atomic_get(invite->ref_cnt) != 1) { 58 PJ_LOG(3,( "", " error: invalid reference counter"));61 PJ_LOG(3,(THIS_FILE, " error: invalid reference counter")); 59 62 return -15; 60 63 } … … 103 106 /* Buffer must be invalid. */ 104 107 if (pjsip_tx_data_is_valid(invite2) != 0) { 105 PJ_LOG(3,( "", " error: buffer must be invalid"));108 PJ_LOG(3,(THIS_FILE, " error: buffer must be invalid")); 106 109 return -34; 107 110 } 108 111 /* Reference counter must be set to 1. */ 109 112 if (pj_atomic_get(invite2->ref_cnt) != 1) { 110 PJ_LOG(3,( "", " error: invalid reference counter"));113 PJ_LOG(3,(THIS_FILE, " error: invalid reference counter")); 111 114 return -35; 112 115 } … … 142 145 /* Done checking invite2. We can delete this. */ 143 146 if (pjsip_tx_data_dec_ref(invite2) != PJSIP_EBUFDESTROYED) { 144 PJ_LOG(3,( "", " error: request buffer not destroyed!"));147 PJ_LOG(3,(THIS_FILE, " error: request buffer not destroyed!")); 145 148 return -49; 146 149 } … … 173 176 /* Buffer must be invalid. */ 174 177 if (pjsip_tx_data_is_valid(response) != 0) { 175 PJ_LOG(3,( "", " error: buffer must be invalid"));178 PJ_LOG(3,(THIS_FILE, " error: buffer must be invalid")); 176 179 return -54; 177 180 } 178 181 /* Check reference counter. */ 179 182 if (pj_atomic_get(response->ref_cnt) != 1) { 180 PJ_LOG(3,( "", " error: invalid ref count in response"));183 PJ_LOG(3,(THIS_FILE, " error: invalid ref count in response")); 181 184 return -55; 182 185 } … … 215 218 /* Buffer must be invalid. */ 216 219 if (pjsip_tx_data_is_valid(cancel) != 0) { 217 PJ_LOG(3,( "", " error: buffer must be invalid"));220 PJ_LOG(3,(THIS_FILE, " error: buffer must be invalid")); 218 221 return -84; 219 222 } 220 223 /* Check reference counter. */ 221 224 if (pj_atomic_get(cancel->ref_cnt) != 1) { 222 PJ_LOG(3,( "", " error: invalid ref count in CANCEL request"));225 PJ_LOG(3,(THIS_FILE, " error: invalid ref count in CANCEL request")); 223 226 return -85; 224 227 } … … 248 251 /* Done checking CANCEL request. */ 249 252 if (pjsip_tx_data_dec_ref(cancel) != PJSIP_EBUFDESTROYED) { 250 PJ_LOG(3,( "", " error: response buffer not destroyed!"));253 PJ_LOG(3,(THIS_FILE, " error: response buffer not destroyed!")); 251 254 return -99; 252 255 } … … 260 263 status = pjsip_endpt_create_ack( endpt, invite, &dummy_rdata, &ack ); 261 264 if (status != PJ_SUCCESS) { 262 PJ_LOG(3,( "", " error: unable to create ACK"));265 PJ_LOG(3,(THIS_FILE, " error: unable to create ACK")); 263 266 return -100; 264 267 } 265 268 /* Buffer must be invalid. */ 266 269 if (pjsip_tx_data_is_valid(ack) != 0) { 267 PJ_LOG(3,( "", " error: buffer must be invalid"));270 PJ_LOG(3,(THIS_FILE, " error: buffer must be invalid")); 268 271 return -104; 269 272 } 270 273 /* Check reference counter. */ 271 274 if (pj_atomic_get(ack->ref_cnt) != 1) { 272 PJ_LOG(3,( "", " error: invalid ref count in ACK request"));275 PJ_LOG(3,(THIS_FILE, " error: invalid ref count in ACK request")); 273 276 return -105; 274 277 } … … 299 302 /* Done checking invite message. */ 300 303 if (pjsip_tx_data_dec_ref(invite) != PJSIP_EBUFDESTROYED) { 301 PJ_LOG(3,( "", " error: response buffer not destroyed!"));304 PJ_LOG(3,(THIS_FILE, " error: response buffer not destroyed!")); 302 305 return -120; 303 306 } … … 305 308 /* Done checking response message. */ 306 309 if (pjsip_tx_data_dec_ref(response) != PJSIP_EBUFDESTROYED) { 307 PJ_LOG(3,( "", " error: response buffer not destroyed!"));310 PJ_LOG(3,(THIS_FILE, " error: response buffer not destroyed!")); 308 311 return -130; 309 312 } … … 311 314 /* Done checking ack message. */ 312 315 if (pjsip_tx_data_dec_ref(ack) != PJSIP_EBUFDESTROYED) { 313 PJ_LOG(3,( "", " error: response buffer not destroyed!"));316 PJ_LOG(3,(THIS_FILE, " error: response buffer not destroyed!")); 314 317 return -140; 315 318 } -
pjproject/trunk/pjsip/src/test-pjsip/uri_test.c
r107 r109 20 20 #include <pjsip_core.h> 21 21 #include <pjlib.h> 22 23 #define THIS_FILE "uri_test.c" 22 24 23 25 … … 693 695 status = entry->status==ERR_SYNTAX_ERR ? PJ_SUCCESS : -10; 694 696 if (status != 0) { 695 PJ_LOG(3,( "", " uri parse error!\n"696 697 697 PJ_LOG(3,(THIS_FILE, " uri parse error!\n" 698 " uri='%s'\n", 699 entry->str)); 698 700 } 699 701 goto on_return; … … 739 741 status = entry->status==ERR_NOT_EQUAL ? PJ_SUCCESS : -40; 740 742 if (status != 0) { 741 PJ_LOG(3,( "", " uri comparison mismatch, status=%d:\n"742 743 744 743 PJ_LOG(3,(THIS_FILE, " uri comparison mismatch, status=%d:\n" 744 " uri1='%s'\n" 745 " uri2='%s'", 746 status, s1.ptr, s2.ptr)); 745 747 } 746 748 goto on_return; … … 763 765 if (pj_strcmp2(&s1, entry->printed) != 0) { 764 766 /* Not equal. */ 765 PJ_LOG(3,( "", " uri print mismatch:\n"766 767 768 767 PJ_LOG(3,(THIS_FILE, " uri print mismatch:\n" 768 " printed='%s'\n" 769 " expectd='%s'", 770 s1.ptr, entry->printed)); 769 771 status = -60; 770 772 } … … 772 774 if (pj_strcmp(&s1, &s2) != 0) { 773 775 /* Not equal. */ 774 PJ_LOG(3,( "", " uri print mismatch:\n"775 776 777 776 PJ_LOG(3,(THIS_FILE, " uri print mismatch:\n" 777 " uri1='%s'\n" 778 " uri2='%s'", 779 s1.ptr, s2.ptr)); 778 780 status = -70; 779 781 } … … 795 797 zero.u32.hi = zero.u32.lo = 0; 796 798 797 PJ_LOG(3,( "", " simple test"));799 PJ_LOG(3,(THIS_FILE, " simple test")); 798 800 pool = pjsip_endpt_create_pool(endpt, "", POOL_SIZE, POOL_SIZE); 799 801 for (i=0; i<PJ_ARRAY_SIZE(uri_test_array); ++i) { 800 802 status = do_uri_test(pool, &uri_test_array[i]); 801 803 if (status != PJ_SUCCESS) { 802 PJ_LOG(3,( "uri_test", " error %d when testing entry %d",804 PJ_LOG(3,(THIS_FILE, " error %d when testing entry %d", 803 805 status, i)); 804 806 goto on_return; … … 807 809 pjsip_endpt_release_pool(endpt, pool); 808 810 809 PJ_LOG(3,( "", " benchmarking..."));811 PJ_LOG(3,(THIS_FILE, " benchmarking...")); 810 812 parse_len = print_len = cmp_len = 0; 811 813 parse_time.u32.hi = parse_time.u32.lo = 0; … … 817 819 status = do_uri_test(pool, &uri_test_array[i]); 818 820 if (status != PJ_SUCCESS) { 819 PJ_LOG(3,( "uri_test", " error %d when testing entry %d",821 PJ_LOG(3,(THIS_FILE, " error %d when testing entry %d", 820 822 status, i)); 821 823 pjsip_endpt_release_pool(endpt, pool); … … 835 837 avg_parse = 1000000 / avg_parse; 836 838 837 PJ_LOG(3,("", " %u.%u MB of urls parsed in %d.%03ds (avg=%d urls/sec)", 838 (unsigned)(parse_len/1000000), (unsigned)kbytes, 839 elapsed.sec, elapsed.msec, 840 (unsigned)avg_parse)); 839 PJ_LOG(3,(THIS_FILE, 840 " %u.%u MB of urls parsed in %d.%03ds (avg=%d urls/sec)", 841 (unsigned)(parse_len/1000000), (unsigned)kbytes, 842 elapsed.sec, elapsed.msec, 843 (unsigned)avg_parse)); 841 844 842 845 kbytes = print_len; … … 849 852 avg_print = 1000000 / avg_print; 850 853 851 PJ_LOG(3,("", " %u.%u MB of urls printed in %d.%03ds (avg=%d urls/sec)", 852 (unsigned)(print_len/1000000), (unsigned)kbytes, 853 elapsed.sec, elapsed.msec, 854 (unsigned)avg_print)); 854 PJ_LOG(3,(THIS_FILE, 855 " %u.%u MB of urls printed in %d.%03ds (avg=%d urls/sec)", 856 (unsigned)(print_len/1000000), (unsigned)kbytes, 857 elapsed.sec, elapsed.msec, 858 (unsigned)avg_print)); 855 859 856 860 kbytes = cmp_len; … … 863 867 avg_cmp = 1000000 / avg_cmp; 864 868 865 PJ_LOG(3,("", " %u.%u MB of urls compared in %d.%03ds (avg=%d urls/sec)", 866 (unsigned)(cmp_len/1000000), (unsigned)kbytes, 867 elapsed.sec, elapsed.msec, 868 (unsigned)avg_cmp)); 869 870 PJ_LOG(3,("", " multithreaded test")); 869 PJ_LOG(3,(THIS_FILE, 870 " %u.%u MB of urls compared in %d.%03ds (avg=%d urls/sec)", 871 (unsigned)(cmp_len/1000000), (unsigned)kbytes, 872 elapsed.sec, elapsed.msec, 873 (unsigned)avg_cmp)); 874 875 PJ_LOG(3,(THIS_FILE, " multithreaded test")); 871 876 872 877
Note: See TracChangeset
for help on using the changeset viewer.