Changeset 109


Ignore:
Timestamp:
Jan 7, 2006 6:44:25 PM (18 years ago)
Author:
bennylp
Message:

Added test functions for UAC transaction

Location:
pjproject/trunk/pjsip
Files:
2 added
26 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjsip/build/pjsip_core.dsp

    r107 r109  
    128128!IF  "$(CFG)" == "pjsip_core - Win32 Release" 
    129129 
    130 # PROP Exclude_From_Build 1 
    131  
    132130!ELSEIF  "$(CFG)" == "pjsip_core - Win32 Debug" 
    133131 
  • pjproject/trunk/pjsip/build/test_pjsip.dsp

    r107 r109  
    9494# Begin Source File 
    9595 
     96SOURCE="..\src\test-pjsip\msg_logger.c" 
     97# End Source File 
     98# Begin Source File 
     99 
    96100SOURCE="..\src\test-pjsip\msg_test.c" 
    97101# End Source File 
     
    111115 
    112116SOURCE="..\src\test-pjsip\transport_udp_test.c" 
     117# End Source File 
     118# Begin Source File 
     119 
     120SOURCE="..\src\test-pjsip\tsx_basic_test.c" 
    113121# End Source File 
    114122# Begin Source File 
  • pjproject/trunk/pjsip/include/pjsip/sip_errno.h

    r107 r109  
    2424PJ_BEGIN_DECL 
    2525 
     26/** 
     27 * Guidelines on error message length. 
     28 */ 
     29#define PJSIP_ERR_MSG_SIZE  64 
     30 
    2631/* 
    2732 * PJSIP error codes occupies 170000 - 219000, and mapped as follows: 
     
    8792 */ 
    8893#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 */ 
    8999 
    90100 
  • pjproject/trunk/pjsip/include/pjsip/sip_module.h

    r106 r109  
    134134 
    135135    /** 
     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    /** 
    136158     * Called when this module is acting as transaction user for the specified 
    137159     * transaction, when the transaction's state has changed. 
     
    151173enum pjsip_module_priority 
    152174{ 
    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, 
    156179}; 
    157180 
  • pjproject/trunk/pjsip/include/pjsip/sip_msg.h

    r107 r109  
    377377 
    378378    PJSIP_SC_OK = 200, 
     379    PJSIP_SC_ACCEPTED = 202, 
    379380 
    380381    PJSIP_SC_MULTIPLE_CHOICES = 300, 
     
    400401    PJSIP_SC_BAD_EXTENSION = 420, 
    401402    PJSIP_SC_EXTENSION_REQUIRED = 421, 
     403    PJSIP_SC_SESSION_TIMER_TOO_SMALL = 422, 
    402404    PJSIP_SC_INTERVAL_TOO_BRIEF = 423, 
    403405    PJSIP_SC_TEMPORARILY_UNAVAILABLE = 480, 
     
    410412    PJSIP_SC_REQUEST_TERMINATED = 487, 
    411413    PJSIP_SC_NOT_ACCEPTABLE_HERE = 488, 
     414    PJSIP_SC_UNKNOWN_EVENT = 489, 
     415    PJSIP_SC_REQUEST_UPDATED = 490, 
    412416    PJSIP_SC_REQUEST_PENDING = 491, 
    413417    PJSIP_SC_UNDECIPHERABLE = 493, 
     
    420424    PJSIP_SC_VERSION_NOT_SUPPORTED = 505, 
    421425    PJSIP_SC_MESSAGE_TOO_LARGE = 513, 
     426    PJSIP_SC_PRECONDITION_FAILURE = 580, 
    422427 
    423428    PJSIP_SC_BUSY_EVERYWHERE = 600, 
     
    427432 
    428433    PJSIP_SC_TSX_TIMEOUT = 701, 
    429     PJSIP_SC_TSX_RESOLVE_ERROR = 702, 
     434    //PJSIP_SC_TSX_RESOLVE_ERROR = 702, 
    430435    PJSIP_SC_TSX_TRANSPORT_ERROR = 703, 
    431436 
  • pjproject/trunk/pjsip/include/pjsip/sip_transaction.h

    r107 r109  
    9393     */ 
    9494    pjsip_transport            *transport;      /**< Transport to use.      */ 
     95    pj_bool_t                   is_reliable;    /**< Transport is reliable. */ 
    9596    pj_sockaddr                 addr;           /**< Destination address.   */ 
    9697    int                         addr_len;       /**< Address length.        */ 
     
    190191/** 
    191192 * 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. 
    194198 * 
    195199 * @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. 
    197203 * 
    198204 * @return          PJ_SUCCESS if successfull. 
  • pjproject/trunk/pjsip/include/pjsip/sip_transport.h

    r107 r109  
    110110pjsip_transport_get_default_port_for_type(pjsip_transport_type_e type); 
    111111 
     112/** 
     113 * Get transport type name. 
     114 * 
     115 * @param t         Transport type. 
     116 * 
     117 * @return          Transport name. 
     118 */ 
     119PJ_DECL(const char*) pjsip_transport_get_type_name(pjsip_transport_type_e t); 
     120 
    112121 
    113122/***************************************************************************** 
     
    203212        /** The parsed message, if any. */ 
    204213        pjsip_msg               *msg; 
     214 
     215        /** Short description about the message.  
     216         *  Application should use #pjsip_rx_data_get_info() instead. 
     217         */ 
     218        char                    *info; 
    205219 
    206220        /** The Call-ID header as found in the message. */ 
     
    259273 
    260274}; 
     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 */ 
     283PJ_DECL(char*) pjsip_rx_data_get_info(pjsip_rx_data *rdata); 
    261284 
    262285 
     
    304327    char                 obj_name[PJ_MAX_OBJ_NAME]; 
    305328 
     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 
    306335    /** For response message, this contains the reference to timestamp when  
    307336     *  the original request message was received. The value of this field 
     
    340369    void                *token; 
    341370    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; 
    342383}; 
    343384 
     
    397438 */ 
    398439PJ_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 */ 
     449PJ_DECL(char*) pjsip_tx_data_get_info( pjsip_tx_data *tdata ); 
    399450 
    400451 
     
    594645 * @param pool      Pool. 
    595646 * @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. 
    597650 * @param p_mgr     Pointer to receive the new transport manager. 
    598651 * 
     
    601654PJ_DECL(pj_status_t) pjsip_tpmgr_create( pj_pool_t *pool, 
    602655                                         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*), 
    606661                                         pjsip_tpmgr **p_mgr); 
    607662 
  • pjproject/trunk/pjsip/include/pjsip/sip_transport_loop.h

    r107 r109  
    5959 * 
    6060 * @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 
    6465 *                      the packet. 
    6566 * @param prev_value    Optional argument to receive previous value of 
     
    7475 
    7576/** 
    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  
    7779 * control the delay for error notification callback. 
    7880 * 
     
    8486 * @return              PJ_SUCCESS on success. 
    8587 */ 
     88PJ_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 */ 
     104PJ_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 */ 
    86117PJ_DECL(pj_status_t) pjsip_loop_set_delay( pjsip_transport *tp, 
    87                                            unsigned delay, 
    88                                            unsigned *prev_value); 
     118                                           unsigned delay ); 
     119 
    89120 
    90121PJ_END_DECL 
  • pjproject/trunk/pjsip/src/pjsip/sip_endpoint.c

    r107 r109  
    3636 
    3737#define PJSIP_EX_NO_MEMORY  PJ_NO_MEMORY_EXCEPTION 
    38 #define THIS_FILE           "endpoint" 
     38#define THIS_FILE           "sip_endpoint.c" 
    3939 
    4040#define MAX_METHODS   32 
     
    9999 * Prototypes. 
    100100 */ 
    101 static void endpt_transport_callback(pjsip_endpoint*,  
    102                                      pj_status_t, pjsip_rx_data*); 
     101static void endpt_on_rx_msg( pjsip_endpoint*,  
     102                             pj_status_t, pjsip_rx_data*); 
     103static pj_status_t endpt_on_tx_msg( pjsip_endpoint *endpt, 
     104                                    pjsip_tx_data *tdata ); 
    103105 
    104106/* Defined in sip_parser.c */ 
     
    230232    pj_list_erase(mod); 
    231233 
     234    /* Set module Id to -1. */ 
     235    mod->id = -1; 
     236 
    232237    /* Done. */ 
    233238    status = PJ_SUCCESS; 
     
    313318    pj_lock_t *lock = NULL; 
    314319 
    315     PJ_LOG(5, (THIS_FILE, "pjsip_endpt_create()")); 
     320    PJ_LOG(5, (THIS_FILE, "Creating endpoint instance...")); 
    316321 
    317322    *p_endpt = NULL; 
     
    383388    /* Create transport manager. */ 
    384389    status = pjsip_tpmgr_create( endpt->pool, endpt, 
    385                                  &endpt_transport_callback, 
     390                                 &endpt_on_rx_msg, 
     391                                 &endpt_on_tx_msg, 
    386392                                 &endpt->transport_mgr); 
    387393    if (status != PJ_SUCCESS) { 
     
    392398    endpt->resolver = pjsip_resolver_create(endpt->pool); 
    393399    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")); 
    395401        goto on_error; 
    396402    } 
     
    426432    pj_pool_release( endpt->pool ); 
    427433 
    428     PJ_LOG(4, (THIS_FILE, "pjsip_endpt_init() failed")); 
     434    PJ_LOG(4, (THIS_FILE, "Error creating endpoint")); 
    429435    return status; 
    430436} 
     
    435441PJ_DEF(void) pjsip_endpt_destroy(pjsip_endpoint *endpt) 
    436442{ 
    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    } 
    438451 
    439452    /* Shutdown and destroy all transports. */ 
     
    445458    /* Finally destroy pool. */ 
    446459    pj_pool_release(endpt->pool); 
     460 
     461    PJ_LOG(4, (THIS_FILE, "Endpoint %p destroyed", endpt)); 
    447462} 
    448463 
     
    466481    pj_pool_t *pool; 
    467482 
    468     PJ_LOG(5, (THIS_FILE, "pjsip_endpt_create_pool()")); 
    469  
    470483    /* Lock endpoint mutex. */ 
    471484    pj_mutex_lock(endpt->mutex); 
     
    478491    pj_mutex_unlock(endpt->mutex); 
    479492 
    480     if (pool) { 
    481         PJ_LOG(5, (THIS_FILE, "   pool %s created", pj_pool_getobjname(pool))); 
    482     } else { 
     493    if (!pool) { 
    483494        PJ_LOG(4, (THIS_FILE, "Unable to create pool %s!", pool_name)); 
    484495    } 
     
    493504PJ_DEF(void) pjsip_endpt_release_pool( pjsip_endpoint *endpt, pj_pool_t *pool ) 
    494505{ 
    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))); 
    496507 
    497508    pj_mutex_lock(endpt->mutex); 
     
    509520    pj_time_val timeout = { 0, 0}; 
    510521 
    511     PJ_LOG(5, (THIS_FILE, "pjsip_endpt_handle_events()")); 
     522    PJ_LOG(6, (THIS_FILE, "pjsip_endpt_handle_events()")); 
    512523 
    513524    /* Poll the timer. The timer heap has its own mutex for better  
     
    535546                                                const pj_time_val *delay ) 
    536547{ 
    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)", 
    538549                         entry, delay->sec, delay->msec)); 
    539550    return pj_timer_heap_schedule( endpt->timer_heap, entry, delay ); 
     
    546557                                       pj_timer_entry *entry ) 
    547558{ 
    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)); 
    549560    pj_timer_heap_cancel( endpt->timer_heap, entry ); 
    550561} 
     
    554565 * receives a message from the network. 
    555566 */ 
    556 static void endpt_transport_callback( pjsip_endpoint *endpt, 
     567static void endpt_on_rx_msg( pjsip_endpoint *endpt, 
    557568                                      pj_status_t status, 
    558569                                      pjsip_rx_data *rdata ) 
    559570{ 
    560571    pjsip_msg *msg = rdata->msg_info.msg; 
    561  
    562     PJ_LOG(5, (THIS_FILE, "endpt_transport_callback(rdata=%p)", rdata)); 
    563572 
    564573    if (status != PJ_SUCCESS) { 
     
    572581        return; 
    573582    } 
     583 
     584    PJ_LOG(5, (THIS_FILE, "Processing incoming message: %s",  
     585               pjsip_rx_data_get_info(rdata))); 
    574586 
    575587    /* For response, check that the value in Via sent-by match the transport. 
     
    601613                mismatch = PJ_TRUE; 
    602614            else { 
    603                 PJ_LOG(4,(THIS_FILE, "Response %p from %s has mismatch port in " 
     615                PJ_LOG(4,(THIS_FILE, "Message %s from %s has mismatch port in " 
    604616                                     "sent-by but the rport parameter is " 
    605617                                     "correct", 
    606                                      rdata, rdata->pkt_info.src_name)); 
     618                                     pjsip_rx_data_get_info(rdata),  
     619                                     rdata->pkt_info.src_name)); 
    607620            } 
    608621        } 
     
    610623        if (mismatch) { 
    611624            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), 
    614628                                 rdata->pkt_info.src_name,  
    615629                                 rdata->pkt_info.src_port)); 
     
    619633 
    620634 
    621     /* Distribute to modules. */ 
     635    /* Distribute to modules, starting from modules with highest priority */ 
    622636    pj_rwmutex_lock_read(endpt->mod_mutex); 
    623637 
     
    638652        if (!handled) { 
    639653            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)); 
    642659        } 
    643660 
     
    656673 
    657674        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)); 
    660680        } 
    661681    } 
     
    663683    pj_rwmutex_unlock_read(endpt->mod_mutex); 
    664684} 
     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 */ 
     690static 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 
    665724 
    666725/* 
     
    670729                                               pjsip_tx_data **p_tdata) 
    671730{ 
    672     PJ_LOG(5, (THIS_FILE, "pjsip_endpt_create_tdata()")); 
    673731    return pjsip_tx_data_create(endpt->transport_mgr, p_tdata); 
    674732} 
     
    683741                                  pjsip_resolver_callback *cb) 
    684742{ 
    685     PJ_LOG(5, (THIS_FILE, "pjsip_endpt_resolve()")); 
    686743    pjsip_resolve( endpt->resolver, pool, target, token, cb); 
    687744} 
     
    712769                                                  pjsip_transport **transport) 
    713770{ 
    714     PJ_LOG(5, (THIS_FILE, "pjsip_endpt_acquire_transport()")); 
    715771    return pjsip_tpmgr_acquire_transport(endpt->transport_mgr, type,  
    716772                                         remote, addr_len, transport); 
  • pjproject/trunk/pjsip/src/pjsip/sip_errno.c

    r107 r109  
    3434    { PJSIP_EBUSY,              "Object is busy" }, 
    3535    { PJSIP_ETYPEEXISTS ,       "Object with the same type exists" }, 
     36    { PJSIP_ESHUTDOWN,          "SIP stack shutting down" }, 
    3637 
    3738    /* Messaging errors */ 
  • pjproject/trunk/pjsip/src/pjsip/sip_msg.c

    r107 r109  
    118118 
    119119    pj_strset2( &status_phrase[200], "OK"); 
     120    pj_strset2( &status_phrase[202], "Accepted"); 
    120121 
    121122    pj_strset2( &status_phrase[300], "Multiple Choices"); 
     
    141142    pj_strset2( &status_phrase[420], "Bad Extension"); 
    142143    pj_strset2( &status_phrase[421], "Extension Required"); 
     144    pj_strset2( &status_phrase[422], "Session Timer Too Small"); 
    143145    pj_strset2( &status_phrase[423], "Interval Too Brief"); 
    144146    pj_strset2( &status_phrase[480], "Temporarily Unavailable"); 
     
    151153    pj_strset2( &status_phrase[487], "Request Terminated"); 
    152154    pj_strset2( &status_phrase[488], "Not Acceptable Here"); 
     155    pj_strset2( &status_phrase[489], "Unknown Event"); 
     156    pj_strset2( &status_phrase[490], "Request Updated"); 
    153157    pj_strset2( &status_phrase[491], "Request Pending"); 
    154158    pj_strset2( &status_phrase[493], "Undecipherable"); 
     
    161165    pj_strset2( &status_phrase[505], "Version Not Supported"); 
    162166    pj_strset2( &status_phrase[513], "Message Too Large"); 
     167    pj_strset2( &status_phrase[580], "Precondition Failure"); 
    163168 
    164169    pj_strset2( &status_phrase[600], "Busy Everywhere"); 
  • pjproject/trunk/pjsip/src/pjsip/sip_resolve.c

    r105 r109  
    1919#include <pjsip/sip_resolve.h> 
    2020#include <pjsip/sip_transport.h> 
     21#include <pjsip/sip_errno.h> 
    2122#include <pj/pool.h> 
    2223#include <pj/ctype.h> 
    2324#include <pj/assert.h> 
     25#include <pj/log.h> 
     26 
     27#define THIS_FILE   "sip_resolve.c" 
    2428 
    2529struct pjsip_resolver_t 
     
    6872    PJ_UNUSED_ARG(resolver); 
    6973    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))); 
    7080 
    7181    /* We only do synchronous resolving at this moment. */ 
     
    117127                                      &target->addr.host,  
    118128                                     (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; 
    120140    } 
    121141 
    122142    /* 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))); 
    123153    svr_addr.count = (status == PJ_SUCCESS) ? 1 : 0; 
    124154    svr_addr.entry[0].type = type; 
  • pjproject/trunk/pjsip/src/pjsip/sip_transaction.c

    r107 r109  
    3030#include <pj/guid.h> 
    3131#include <pj/log.h> 
     32 
     33#define THIS_FILE   "sip_transaction.c" 
    3234 
    3335/***************************************************************************** 
     
    102104    TSX_HAS_PENDING_SEND        = 4, 
    103105    TSX_HAS_PENDING_DESTROY     = 8, 
     106    TSX_HAS_RESOLVED_SERVER     = 16, 
    104107}; 
    105108 
     
    413416    PJ_ASSERT_RETURN(mod_tsx_layer.endpt==NULL, PJ_EINVALIDOP); 
    414417 
     418    PJ_LOG(5,(THIS_FILE, "Initializing transaction layer module")); 
    415419 
    416420    /* Initialize TLS ID for transaction lock. */ 
     
    462466    } 
    463467 
     468    PJ_LOG(4,(THIS_FILE, "Transaction layer module initialized")); 
     469 
    464470    return PJ_SUCCESS; 
    465471} 
     
    581587    pj_hash_iterator_t it_buf, *it; 
    582588 
     589    PJ_LOG(4,(THIS_FILE, "Stopping transaction layer module")); 
     590 
    583591    pj_mutex_lock(mod_tsx_layer.mutex); 
    584592 
     
    587595    while (it) { 
    588596        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); 
    589598        if (tsx) 
    590599            tsx_destroy(tsx); 
    591         it = pj_hash_next(mod_tsx_layer.htable, it); 
     600        it = next; 
    592601    } 
    593602 
     
    611620    mod_tsx_layer.endpt = NULL; 
    612621 
     622    PJ_LOG(4,(THIS_FILE, "Transaction layer module destroyed")); 
     623 
    613624    return PJ_SUCCESS; 
    614625} 
     
    628639    /* Find transaction. */ 
    629640    pj_mutex_lock( mod_tsx_layer.mutex ); 
     641 
    630642    tsx = pj_hash_get( mod_tsx_layer.htable, key.ptr, key.slen ); 
     643 
    631644    if (tsx == NULL || tsx->state == PJSIP_TSX_STATE_TERMINATED) { 
    632645        /* Transaction not found. 
     
    667680    /* Find transaction. */ 
    668681    pj_mutex_lock( mod_tsx_layer.mutex ); 
     682 
    669683    tsx = pj_hash_get( mod_tsx_layer.htable, key.ptr, key.slen ); 
     684 
    670685    if (tsx == NULL || tsx->state == PJSIP_TSX_STATE_TERMINATED) { 
    671686        /* Transaction not found. 
     
    791806static void tsx_destroy( pjsip_transaction *tsx ) 
    792807{ 
     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 
    793851    pj_mutex_destroy(tsx->mutex); 
     852 
     853    PJ_LOG(5,(tsx->obj_name, "Transaction destroyed!")); 
     854 
    794855    pjsip_endpt_release_pool(tsx->endpt, tsx->pool); 
    795856} 
     
    807868    PJ_UNUSED_ARG(theap); 
    808869 
    809     PJ_LOG(5,(tsx->obj_name, "got timer event (%s timer)",  
     870    PJ_LOG(6,(tsx->obj_name, "%s timer event",  
    810871             (entry->id==TSX_TIMER_RETRANSMISSION ? "Retransmit":"Timeout"))); 
    811872 
     
    832893                           void *event_src ) 
    833894{ 
    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", 
    835896               state_str[tsx->state], state_str[state],  
    836897               pjsip_event_str(event_src_type))); 
     
    860921        pj_time_val timeout = {0, 0}; 
    861922 
    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  
    883923        /* Reschedule timeout timer to destroy this transaction. */ 
    884924        if (tsx->transport_flag & TSX_HAS_PENDING_TRANSPORT) { 
    885925            tsx->transport_flag |= TSX_HAS_PENDING_DESTROY; 
    886926        } 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 
    887933            pjsip_endpt_schedule_timer( tsx->endpt, &tsx->timeout_timer,  
    888934                                        &timeout); 
     
    891937 
    892938    } 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         } 
    902939 
    903940        /* Unregister transaction. */ 
     
    921958    pjsip_cseq_hdr *cseq; 
    922959    pjsip_via_hdr *via; 
     960    pjsip_host_info dst_info; 
    923961    struct tsx_lock_data lck; 
    924962    pj_status_t status; 
     
    9991037    pjsip_tx_data_add_ref(tsx->last_tx); 
    10001038 
     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); 
    10011048 
    10021049    /* Register transaction to hash table. */ 
     
    10061053    /* Unlock transaction and return. */ 
    10071054    unlock_tsx(tsx, &lck); 
     1055 
     1056    PJ_LOG(5,(tsx->obj_name, "Transaction created for %s", 
     1057              pjsip_tx_data_get_info(tdata))); 
    10081058 
    10091059    *p_tsx = tsx; 
     
    11131163    unlock_tsx(tsx, &lck); 
    11141164 
     1165 
     1166    PJ_LOG(5,(tsx->obj_name, "Transaction created for %s", 
     1167              pjsip_rx_data_get_info(rdata))); 
     1168 
     1169 
    11151170    *p_tsx = tsx; 
    11161171    return PJ_SUCCESS; 
     
    11271182    PJ_ASSERT_RETURN(tsx != NULL, PJ_EINVAL); 
    11281183    PJ_ASSERT_RETURN(code >= 200, PJ_EINVAL); 
     1184 
     1185    if (tsx->state == PJSIP_TSX_STATE_TERMINATED) 
     1186        return PJ_SUCCESS; 
    11291187 
    11301188    lock_tsx(tsx, &lck); 
     
    11521210    PJ_ASSERT_RETURN(tdata != NULL, PJ_EINVALIDOP); 
    11531211 
    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])); 
    11561215 
    11571216    PJSIP_EVENT_INIT_TX_MSG(event, tsx, tdata); 
     
    11621221    unlock_tsx(tsx, &lck); 
    11631222 
     1223    /* Will always decrement tdata reference counter 
     1224     * (consistent with other send functions. 
     1225     */ 
     1226    pjsip_tx_data_dec_ref(tdata); 
     1227 
    11641228    return status; 
    11651229} 
     
    11761240    pj_status_t status; 
    11771241 
    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])); 
    11801244 
    11811245    /* Put the transaction in the rdata's mod_data. */ 
     
    12061270 
    12071271        if (tsx->transport != send_state->cur_transport) { 
     1272            /* Update transport. */ 
    12081273            if (tsx->transport) { 
    12091274                pjsip_transport_dec_ref(tsx->transport); 
     
    12121277            tsx->transport = send_state->cur_transport; 
    12131278            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); 
    12141288        } 
    12151289 
    12161290        /* Clear pending transport flag. */ 
    12171291        tsx->transport_flag &= ~(TSX_HAS_PENDING_TRANSPORT); 
     1292 
     1293        /* Mark that we have resolved the addresses. */ 
     1294        tsx->transport_flag |= TSX_HAS_RESOLVED_SERVER; 
    12181295 
    12191296        /* Pending destroy? */ 
     
    12341311        if (tsx->transport_flag & TSX_HAS_PENDING_RESCHED) { 
    12351312            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            } 
    12371318        } 
    12381319 
     
    12521333 
    12531334        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)); 
    12561341 
    12571342            /* Clear pending transport flag. */ 
    12581343            tsx->transport_flag &= ~(TSX_HAS_PENDING_TRANSPORT); 
    12591344 
    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. */ 
    12611349            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)); 
    12641365        } 
    12651366    } 
     
    12761377        pjsip_transaction *tsx = token; 
    12771378        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)); 
    12811384 
    12821385        lock_tsx(tsx, &lck); 
     
    13011404                                 pjsip_tx_data *tdata) 
    13021405{ 
    1303     pj_status_t status = PJ_EBUG; 
     1406    pj_status_t status = PJ_SUCCESS; 
    13041407 
    13051408    PJ_ASSERT_RETURN(tsx && tdata, PJ_EINVAL); 
     
    13111414    } 
    13121415 
     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. */ 
    13131490    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); 
    13351499         
    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; 
    13431503 
    13441504    } 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 
    13761521 
    13771522    return status; 
     
    14091554    PJ_ASSERT_RETURN(tsx->last_tx!=NULL, PJ_EBUG); 
    14101555 
    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)); 
    14131559 
    14141560    ++tsx->retransmit_count; 
     
    14521598        pjsip_tx_data *tdata; 
    14531599 
    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         */ 
    14551605        PJ_ASSERT_RETURN(event->type == PJSIP_EVENT_TX_MSG, PJ_EBUG); 
    14561606 
     
    14831633         * transport is being used. 
    14841634         */ 
    1485         if (!PJSIP_TRANSPORT_IS_RELIABLE(tsx->transport))  { 
     1635        if (!tsx->is_reliable)  { 
    14861636            tsx->retransmit_count = 0; 
    14871637            if (tsx->transport_flag & TSX_HAS_PENDING_TRANSPORT) { 
     
    15281678 
    15291679        /* Cancel retransmission timer. */ 
    1530         if (PJSIP_TRANSPORT_IS_RELIABLE(tsx->transport)==0) { 
     1680        if (tsx->retransmit_timer._timer_id != -1) { 
    15311681            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); 
    15331685 
    15341686        /* Set status code */ 
     
    15541706 
    15551707        /* Cancel retransmission timer A. */ 
    1556         if (PJSIP_TRANSPORT_IS_RELIABLE(tsx->transport)==0) 
     1708        if (tsx->retransmit_timer._timer_id != -1) { 
    15571709            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 
    15581714 
    15591715        /* Cancel timer B (transaction timeout) */ 
     
    17391895                 * reliable transport. 
    17401896                 */ 
    1741                 if (!PJSIP_TRANSPORT_IS_RELIABLE(tsx->transport)) { 
     1897                if (!tsx->is_reliable) { 
    17421898                    timeout = timeout_timer_val; 
    17431899                } else { 
     
    17701926             * timer G will be scheduled (retransmission). 
    17711927             */ 
    1772             if (!PJSIP_TRANSPORT_IS_RELIABLE(tsx->transport)) { 
     1928            if (!tsx->is_reliable) { 
    17731929                pjsip_cseq_hdr *cseq = pjsip_msg_find_hdr( msg, PJSIP_H_CSEQ, 
    17741930                                                           NULL); 
     
    18942050            /* For unreliable transport, start timer D (for INVITE) or  
    18952051             * timer K for non-INVITE. */ 
    1896             if (PJSIP_TRANSPORT_IS_RELIABLE(tsx->transport) == 0) { 
     2052            if (!tsx->is_reliable) { 
    18972053                if (tsx->method.id == PJSIP_INVITE_METHOD) { 
    18982054                    timeout = td_timer_val; 
     
    19402096 
    19412097        /* 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) { 
    19432099            if (tsx->method.id == PJSIP_INVITE_METHOD) { 
    19442100                timeout = td_timer_val; 
     
    19932149 
    19942150            /* 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); 
    19962156 
    19972157            /* Start timer I in T4 interval (transaction termination). */ 
  • pjproject/trunk/pjsip/src/pjsip/sip_transport.c

    r107 r109  
    2323#include <pjsip/sip_private.h> 
    2424#include <pjsip/sip_errno.h> 
     25#include <pjsip/sip_module.h> 
    2526#include <pj/os.h> 
    2627#include <pj/log.h> 
     
    3334 
    3435 
    35 #define THIS_FILE    "transport" 
     36#define THIS_FILE    "sip_transport.c" 
     37 
     38/* Prototype. */ 
     39static 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 */ 
     44static 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}; 
    3663 
    3764/* 
     
    4774    pj_atomic_t     *tdata_counter; 
    4875#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*); 
    5078}; 
    5179 
     
    6795} transport_names[] =  
    6896{ 
    69     { PJSIP_TRANSPORT_UNSPECIFIED, 0, {NULL, 0}, 0}, 
     97    { PJSIP_TRANSPORT_UNSPECIFIED, 0, {"Unspecified", 11}, 0}, 
    7098    { PJSIP_TRANSPORT_UDP, 5060, {"UDP", 3}, PJSIP_TRANSPORT_DATAGRAM}, 
    7199    { PJSIP_TRANSPORT_TCP, 5060, {"TCP", 3}, PJSIP_TRANSPORT_RELIABLE}, 
     
    91119                     PJSIP_TRANSPORT_UDP, PJSIP_TRANSPORT_UNSPECIFIED); 
    92120 
     121    if (name->slen == 0) 
     122        return PJSIP_TRANSPORT_UNSPECIFIED; 
     123 
    93124    /* Get transport type from name. */ 
    94125    for (i=0; i<PJ_ARRAY_SIZE(transport_names); ++i) { 
     
    163194} 
    164195 
     196/* 
     197 * Get transport name. 
     198 */ 
     199PJ_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} 
    165213 
    166214/***************************************************************************** 
     
    181229 
    182230    PJ_ASSERT_RETURN(mgr && p_tdata, PJ_EINVAL); 
    183  
    184     PJ_LOG(5, ("", "pjsip_tx_data_create")); 
    185231 
    186232    pool = pjsip_endpt_create_pool( mgr->endpt, "tdta%p", 
     
    235281    pj_assert( pj_atomic_get(tdata->ref_cnt) > 0); 
    236282    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))); 
    238285#if defined(PJ_DEBUG) && PJ_DEBUG!=0 
    239286        pj_atomic_dec( tdata->mgr->tdata_counter ); 
     
    255302{ 
    256303    tdata->buf.cur = tdata->buf.start; 
     304    tdata->info = NULL; 
    257305} 
    258306 
     
    262310} 
    263311 
    264  
     312static 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 
     347PJ_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 
     362PJ_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} 
    265378 
    266379/***************************************************************************** 
     
    297410    /* Decrement reference count. */ 
    298411    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 */ 
     417static 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; 
    299441} 
    300442 
     
    321463    } 
    322464 
    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; 
    342487    } 
    343488 
     
    450595} 
    451596 
    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. */ 
     598static pj_status_t destroy_transport( pjsip_tpmgr *mgr, 
     599                                      pjsip_transport *tp ) 
    458600{ 
    459601    int key_len; 
    460  
    461     /* Must have no user. */ 
    462     PJ_ASSERT_RETURN(pj_atomic_get(tp->ref_cnt) == 0, PJSIP_EBUSY); 
    463602 
    464603    pj_lock_acquire(tp->lock); 
     
    484623    /* Destroy. */ 
    485624    return tp->destroy(tp); 
     625} 
     626 
     627/** 
     628 * Unregister transport. 
     629 */ 
     630PJ_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); 
    486638} 
    487639 
     
    557709PJ_DEF(pj_status_t) pjsip_tpmgr_create( pj_pool_t *pool, 
    558710                                        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*), 
    562716                                        pjsip_tpmgr **p_mgr) 
    563717{ 
     
    565719    pj_status_t status; 
    566720 
    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. */ 
    571729    mgr = pj_pool_zalloc(pool, sizeof(*mgr)); 
    572730    mgr->endpt = endpt; 
    573     mgr->msg_cb = cb; 
     731    mgr->on_rx_msg = rx_cb; 
     732    mgr->on_tx_msg = tx_cb; 
    574733    pj_list_init(&mgr->factory_list); 
    575734 
     
    588747#endif 
    589748 
     749    PJ_LOG(5, (THIS_FILE, "Transport manager created.")); 
     750 
    590751    *p_mgr = mgr; 
    591752    return PJ_SUCCESS; 
     
    601762    pj_hash_iterator_t itr_val; 
    602763    pj_hash_iterator_t *itr; 
     764    pjsip_endpoint *endpt = mgr->endpt; 
    603765     
    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")); 
    609767 
    610768    pj_lock_acquire(mgr->lock); 
     
    619777        next = pj_hash_next(mgr->table, itr); 
    620778 
    621         pj_atomic_set(transport->ref_cnt, 0); 
    622         pjsip_transport_unregister(mgr, transport); 
     779        destroy_transport(mgr, transport); 
    623780 
    624781        itr = next; 
     
    627784    pj_lock_release(mgr->lock); 
    628785    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 
    629799 
    630800    return PJ_SUCCESS; 
     
    686856            if (msg_status != PJ_SUCCESS) { 
    687857                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); 
    689859                    /* Exhaust all data. */ 
    690860                    return rdata->pkt_info.len; 
     
    703873            pjsip_parse_rdata( current_pkt, msg_fragment_size, rdata); 
    704874        if (msg == NULL) { 
    705             mgr->msg_cb(mgr->endpt, PJSIP_EINVALIDMSG, rdata); 
     875            mgr->on_rx_msg(mgr->endpt, PJSIP_EINVALIDMSG, rdata); 
    706876            goto finish_process_fragment; 
    707877        } 
     
    714884            rdata->msg_info.cseq == NULL)  
    715885        { 
    716             mgr->msg_cb(mgr->endpt, PJSIP_EMISSINGHDR, rdata); 
     886            mgr->on_rx_msg(mgr->endpt, PJSIP_EMISSINGHDR, rdata); 
    717887            goto finish_process_fragment; 
    718888        } 
     
    738908                hdr = pjsip_msg_find_hdr(msg, PJSIP_H_VIA, hdr); 
    739909                if (hdr) { 
    740                     mgr->msg_cb(mgr->endpt, PJSIP_EMULTIPLEVIA, rdata); 
     910                    mgr->on_rx_msg(mgr->endpt, PJSIP_EMULTIPLEVIA, rdata); 
    741911                    goto finish_process_fragment; 
    742912                } 
     
    746916        /* Call the transport manager's upstream message callback. 
    747917         */ 
    748         mgr->msg_cb(mgr->endpt, PJ_SUCCESS, rdata); 
     918        mgr->on_rx_msg(mgr->endpt, PJ_SUCCESS, rdata); 
    749919 
    750920 
     
    796966        const pj_sockaddr *remote_addr = (const pj_sockaddr*)remote; 
    797967 
    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) 
    802971        { 
    803972            pj_sockaddr_in *addr = (pj_sockaddr_in*)&key.addr; 
    804973 
    805974            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)); 
    806986            addr->sin_family = PJ_AF_INET; 
    807             addr->sin_addr.s_addr = 0; 
    808             addr->sin_port = 0; 
    809987 
    810988            key_len = sizeof(key.type) + sizeof(pj_sockaddr_in); 
  • pjproject/trunk/pjsip/src/pjsip/sip_transport_loop.c

    r107 r109  
    2828 
    2929 
    30 #define FAIL_IMMEDIATE  1 
    31 #define FAIL_CALLBACK   2 
    32  
    3330#define ADDR_LOOP       "128.0.0.1" 
    3431#define ADDR_LOOP_DGRAM "129.0.0.1" 
     
    6259    pj_bool_t                discard; 
    6360    int                      fail_mode; 
    64     unsigned                 delay; 
     61    unsigned                 recv_delay; 
     62    unsigned                 send_delay; 
    6563    struct recv_list         recv_list; 
    6664    struct send_list         send_list; 
     
    10199    /* When do we need to "deliver" this packet. */ 
    102100    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; 
    104102    pj_time_val_normalize(&pkt->rdata.pkt_info.timestamp); 
    105103 
     
    131129 
    132130    pj_gettimeofday(&sent_status->sent_time); 
    133     sent_status->sent_time.msec += loop->delay; 
     131    sent_status->sent_time.msec += loop->send_delay; 
    134132    pj_time_val_normalize(&sent_status->sent_time); 
    135133 
     
    161159 
    162160 
    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        } 
    174171    } 
    175172 
     
    184181 
    185182    /* If delay is not configured, deliver this packet now! */ 
    186     if (loop->delay == 0) { 
     183    if (loop->recv_delay == 0) { 
    187184        pj_ssize_t size_eaten; 
    188185 
     
    193190        pjsip_endpt_release_pool(loop->base.endpt,  
    194191                                 recv_pkt->rdata.tp_info.pool); 
    195         return PJ_SUCCESS; 
    196192 
    197193    } else { 
    198194        /* 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. 
    201196         */ 
    202         add_notification(loop, tdata, tdata->buf.cur - tdata->buf.start,  
    203                          token, cb); 
    204  
    205197        pj_lock_acquire(loop->base.lock); 
    206198        pj_list_push_back(&loop->recv_list, recv_pkt); 
    207199        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); 
    208205        return PJ_EPENDING; 
     206    } else { 
     207        return PJ_SUCCESS; 
    209208    } 
    210209} 
     
    224223    pj_thread_destroy(loop->thread); 
    225224 
     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.. */ 
    226245    pj_lock_destroy(loop->base.lock); 
    227246    pj_atomic_destroy(loop->base.ref_cnt); 
     
    239258        pj_time_val now; 
    240259 
    241         pj_thread_sleep(10); 
     260        pj_thread_sleep(1); 
    242261        pj_gettimeofday(&now); 
    243262 
     
    321340        goto on_error; 
    322341    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; 
    324343    loop->base.type_name = "LOOP-DGRAM"; 
    325344    loop->base.info = "LOOP-DGRAM"; 
     
    357376     */ 
    358377 
    359     *transport = &loop->base; 
     378    if (transport) 
     379        *transport = &loop->base; 
     380 
    360381    return PJ_SUCCESS; 
    361382 
     
    406427 
    407428 
    408 PJ_DEF(pj_status_t) pjsip_loop_set_delay( pjsip_transport *tp, 
    409                                           unsigned delay, 
    410                                           unsigned *prev_value) 
     429PJ_DEF(pj_status_t) pjsip_loop_set_recv_delay( pjsip_transport *tp, 
     430                                               unsigned delay, 
     431                                               unsigned *prev_value) 
    411432{ 
    412433    struct loop_transport *loop = (struct loop_transport*)tp; 
     
    416437 
    417438    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 
     445PJ_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 
     461PJ_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  
    5959 
    6060    /* Don't do anything if transport is closing. */ 
    61     if (tp->is_closing) 
     61    if (tp->is_closing) { 
     62        tp->is_closing++; 
    6263        return; 
     64    } 
    6365 
    6466    /* 
     
    229231 
    230232    /* 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     * 
    231239    for (i=0; i<tp->rdata_cnt; ++i) { 
    232240        pj_ioqueue_post_completion(tp->key,  
    233241                                   &tp->rdata[i]->tp_info.op_key.op_key, -1); 
    234242    } 
     243    */ 
    235244 
    236245    /* Unregister from ioqueue. */ 
     
    241250    if (tp->sock && tp->sock != PJ_INVALID_SOCKET) 
    242251        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    } 
    243266 
    244267    /* Destroy reference counter. */ 
  • pjproject/trunk/pjsip/src/pjsip/sip_util.c

    r107 r109  
    130130    } 
    131131 
    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))); 
    137134 
    138135} 
     
    162159    pj_status_t status; 
    163160    PJ_USE_EXCEPTION; 
    164  
    165     PJ_LOG(5,(THIS_FILE, "Entering pjsip_endpt_create_request()")); 
    166161 
    167162    status = pjsip_endpt_create_tdata(endpt, &tdata); 
     
    272267    pj_status_t status; 
    273268    PJ_USE_EXCEPTION; 
    274  
    275     PJ_LOG(5,(THIS_FILE, "Entering pjsip_endpt_create_request_from_hdr()")); 
    276269 
    277270    /* Check arguments. */ 
     
    344337    pj_assert(req_msg->type == PJSIP_REQUEST_MSG); 
    345338 
    346     /* Log this action. */ 
    347     PJ_LOG(5,(THIS_FILE, "pjsip_endpt_create_response(rdata=%p, code=%d)",  
    348                          rdata, st_code)); 
    349  
    350339    /* Create a new transmit buffer. */ 
    351340    status = pjsip_endpt_create_tdata( endpt, &tdata); 
     
    409398    /* All done. */ 
    410399    *p_tdata = tdata; 
     400 
     401    PJ_LOG(5,(THIS_FILE, "%s created", pjsip_tx_data_get_info(tdata))); 
    411402    return PJ_SUCCESS; 
    412403} 
     
    432423    pjsip_to_hdr *to; 
    433424    pj_status_t status; 
    434  
    435     /* Log this action. */ 
    436     PJ_LOG(5,(THIS_FILE, "pjsip_endpt_create_ack(rdata=%p)", rdata)); 
    437425 
    438426    /* rdata must be a final response. */ 
     
    525513    const pjsip_hdr *hdr; 
    526514    pj_status_t status; 
    527  
    528     /* Log this action. */ 
    529     PJ_LOG(5,(THIS_FILE, "pjsip_endpt_create_cancel(tdata=%p)", req_tdata)); 
    530515 
    531516    /* The transmit buffer must INVITE request. */ 
     
    703688        dest_info->type =  
    704689            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); 
    712692    } else { 
    713693        pj_assert(!"Unsupported URI scheme!"); 
  • pjproject/trunk/pjsip/src/test-pjsip/msg_test.c

    r107 r109  
    2424#define LOOP            10000 
    2525#define AVERAGE_MSG_LEN 800 
     26#define THIS_FILE       "msg_test.c" 
    2627 
    2728static pjsip_msg *create_msg0(pj_pool_t *pool); 
     
    143144    } 
    144145    if (msg_size != entry->len) { 
    145         PJ_LOG(3,("", "   error: size mismatch")); 
     146        PJ_LOG(3,(THIS_FILE, "   error: size mismatch")); 
    146147        return -6; 
    147148    } 
     
    163164            status = -10; 
    164165            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", 
    166167                              err_list.next->line, err_list.next->col)); 
    167168            } 
     
    208209    } else { 
    209210        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")); 
    211212            status = -32; 
    212213            goto on_return; 
     
    215216                      &ref_msg->line.status.reason) != 0)  
    216217        { 
    217             PJ_LOG(3,("", "   error: status text mismatch")); 
     218            PJ_LOG(3,(THIS_FILE, "   error: status text mismatch")); 
    218219            status = -33; 
    219220            goto on_return; 
     
    244245        if (pj_strcmp(&str1, &str2) != 0) { 
    245246            status = -60; 
    246             PJ_LOG(3,("", "   error: header string mismatch:\n" 
     247            PJ_LOG(3,(THIS_FILE, "   error: header string mismatch:\n" 
    247248                          "   h1='%s'\n" 
    248249                          "   h2='%s'\n", 
     
    684685    pj_highprec_t avg_detect, avg_parse, avg_print, kbytes; 
    685686 
    686     PJ_LOG(3,("", "  simple test..")); 
     687    PJ_LOG(3,(THIS_FILE, "  simple test..")); 
    687688    for (i=0; i<PJ_ARRAY_SIZE(test_array); ++i) { 
    688689        pool = pjsip_endpt_create_pool(endpt, NULL, POOL_SIZE, POOL_SIZE); 
     
    694695    } 
    695696 
    696     PJ_LOG(3,("", "  benchmarking..")); 
     697    PJ_LOG(3,(THIS_FILE, "  benchmarking..")); 
    697698    detect_len = parse_len = print_len = 0; 
    698699    zero.u64 = detect_time.u64 = parse_time.u64 = print_time.u64 = 0; 
     
    718719    avg_detect = 1000000 / avg_detect; 
    719720 
    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)); 
    724726 
    725727    kbytes = parse_len; 
     
    732734    avg_parse = 1000000 / avg_parse; 
    733735 
    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)); 
    738741 
    739742    kbytes = print_len; 
     
    746749    avg_print = 1000000 / avg_print; 
    747750 
    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)); 
    752756 
    753757    return status; 
  • pjproject/trunk/pjsip/src/test-pjsip/test.c

    r107 r109  
    2323#include <pjsip_core.h> 
    2424 
     25#define THIS_FILE   "test.c" 
     26 
    2527#define DO_TEST(test)   do { \ 
    26                             PJ_LOG(3, ("test", "Running %s...", #test));  \ 
     28                            PJ_LOG(3, (THIS_FILE, "Running %s...", #test));  \ 
    2729                            rc = test; \ 
    28                             PJ_LOG(3, ("test",  \ 
     30                            PJ_LOG(3, (THIS_FILE,  \ 
    2931                                       "%s(%d)",  \ 
    3032                                       (rc ? "..ERROR" : "..success"), rc)); \ 
     
    4345 
    4446    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)); 
    4648 
     49} 
     50 
     51void 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    } 
    4769} 
    4870 
     
    6082    int line; 
    6183 
    62     pj_log_set_level(3); 
     84    pj_log_set_level(5); 
     85    /* 
    6386    pj_log_set_decor(PJ_LOG_HAS_NEWLINE | PJ_LOG_HAS_TIME |  
    6487                     PJ_LOG_HAS_MICRO_SEC); 
     88     */ 
    6589 
    6690    if ((rc=pj_init()) != PJ_SUCCESS) { 
     
    80104    } 
    81105 
    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    } 
    83126 
    84127    //DO_TEST(uri_test()); 
     
    86129    //DO_TEST(txdata_test()); 
    87130    //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()); 
    90134 
    91135on_return: 
     
    94138    pj_caching_pool_destroy(&caching_pool); 
    95139 
    96     PJ_LOG(3,("test", "")); 
     140    PJ_LOG(3,(THIS_FILE, "")); 
    97141  
    98142    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",  
    100144                      pj_thread_get_stack_max_usage(pj_thread_this()), 
    101145                      filename, line)); 
    102146    if (rc == 0) 
    103         PJ_LOG(3,("test", "Looks like everything is okay!..")); 
     147        PJ_LOG(3,(THIS_FILE, "Looks like everything is okay!..")); 
    104148    else 
    105         PJ_LOG(3,("test", "Test completed with error(s)")); 
     149        PJ_LOG(3,(THIS_FILE, "Test completed with error(s)")); 
    106150 
    107151    return 0; 
  • pjproject/trunk/pjsip/src/test-pjsip/test.h

    r107 r109  
    3333int transport_udp_test(void); 
    3434int transport_loop_test(void); 
     35int tsx_basic_test(void); 
    3536int tsx_uac_test(void); 
    3637 
     
    4243int transport_rt_test( pjsip_transport_type_e tp_type, 
    4344                       pjsip_transport *ref_tp, 
    44                        char *target_url ); 
     45                       char *target_url, 
     46                       int *pkt_lost); 
    4547 
    4648/* Test main entry */ 
     
    4951/* Test utilities. */ 
    5052void app_perror(const char *msg, pj_status_t status); 
    51  
     53int init_msg_logger(void); 
     54int msg_logger_set_enabled(pj_bool_t enabled); 
     55void flush_events(unsigned duration); 
    5256 
    5357#endif  /* __TEST_H__ */ 
  • pjproject/trunk/pjsip/src/test-pjsip/transport_loop_test.c

    r107 r109  
    2222#include <pjlib.h> 
    2323 
     24#define THIS_FILE   "transport_loop_test.c" 
     25 
    2426static int datagram_loop_test() 
    2527{ 
    26     pjsip_transport *loop, *tp; 
    27     pj_str_t s; 
    28     int i, log_level; 
     28    pjsip_transport *loop; 
     29    int i, pkt_lost; 
    2930    pj_sockaddr_in addr; 
    3031    pj_status_t status; 
    3132 
    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")); 
    4434 
    4535    /* Test acquire transport. */ 
    4636    status = pjsip_endpt_acquire_transport( endpt, PJSIP_TRANSPORT_LOOP_DGRAM, 
    47                                             &addr, sizeof(addr), &tp); 
     37                                            &addr, sizeof(addr), &loop); 
    4838    if (status != PJ_SUCCESS) { 
    49         app_perror("   error: unable to acquire transport", status); 
     39        app_perror("   error: loop transport is not configured", status); 
    5040        return -20; 
    51     } 
    52  
    53     /* Check that this is the right transport. */ 
    54     if (tp != loop) { 
    55         return -30; 
    5641    } 
    5742 
     
    6954    } 
    7055 
    71     /* For multithreaded round-trip test to work, delay must be set 
    72      * (otherwise functions will be called recursively until no memory is 
    73      * left in the system) 
    74      */ 
    75  
    76     /* Put delay. */ 
    77     pjsip_loop_set_delay(loop, 1, NULL); 
    78  
    7956    /* 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); 
    8260    if (status != 0) 
    8361        return status; 
    8462 
     63    if (pkt_lost != 0) { 
     64        PJ_LOG(3,(THIS_FILE, "   error: %d packet(s) was lost", pkt_lost)); 
     65        return -40; 
     66    } 
    8567 
    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); 
    9771 
    9872    /* 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); 
    10176    if (status != 0) 
    10277        return status; 
    10378 
    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); 
    10686 
    10787    /* Check that reference counter is one. */ 
    10888    if (pj_atomic_get(loop->ref_cnt) != 1) { 
    109         return -30; 
     89        return -50; 
    11090    } 
    11191 
  • pjproject/trunk/pjsip/src/test-pjsip/transport_test.c

    r107 r109  
    2121#include <pjsip_core.h> 
    2222#include <pjlib.h> 
     23 
     24#define THIS_FILE   "transport_test.c" 
    2325 
    2426/////////////////////////////////////////////////////////////////////////////// 
     
    2931int generic_transport_test(pjsip_transport *tp) 
    3032{ 
    31     PJ_LOG(3,("", "  structure test...")); 
     33    PJ_LOG(3,(THIS_FILE, "  structure test...")); 
    3234 
    3335    /* Check that local address name is valid. */ 
     
    3840        if (pj_inet_aton(&tp->local_name.host, &addr) != 0) { 
    3941            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")); 
    4143                return -420; 
    4244            } 
     
    122124        pj_status_t status; 
    123125 
    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  
    131126        status = pjsip_endpt_create_response( endpt, rdata, 200, NULL, &tdata); 
    132127        if (status != PJ_SUCCESS) { 
     
    156151{ 
    157152    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  
    164153        pj_get_timestamp(&my_recv_time); 
    165154        recv_status = PJ_SUCCESS; 
     
    190179                              char *target_url ) 
    191180{ 
     181    pj_bool_t msg_log_enabled; 
    192182    pj_status_t status; 
    193183    pj_str_t target, from, to, contact, call_id, body; 
     
    196186    pj_time_val timeout; 
    197187 
    198     PJ_LOG(3,("", "  single message round-trip test...")); 
     188    PJ_LOG(3,(THIS_FILE, "  single message round-trip test...")); 
    199189 
    200190    /* Register out test module to receive the message (if necessary). */ 
     
    206196        } 
    207197    } 
     198 
     199    /* Disable message logging. */ 
     200    msg_log_enabled = msg_logger_set_enabled(0); 
    208201 
    209202    /* Create a request message. */ 
     
    250243        pj_gettimeofday(&now); 
    251244        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")); 
    253246            status = -540; 
    254247            goto on_return; 
     
    279272        unsigned usec_rt; 
    280273        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); 
    283279 
    284280    status = PJ_SUCCESS; 
     
    328324    int sent_request_count, recv_response_count; 
    329325    pj_str_t call_id; 
     326    pj_timer_entry timeout_timer; 
     327    pj_timer_entry tx_timer; 
     328    pj_mutex_t *mutex; 
    330329} rt_test_data[16]; 
    331330 
     
    372371    pj_str_t target, from, to, contact, call_id; 
    373372    pjsip_tx_data *tdata; 
     373    pj_time_val timeout_delay; 
     374 
     375    pj_mutex_lock(rt_test_data[thread_id].mutex); 
    374376 
    375377    /* Create a request message. */ 
     
    385387                                         NULL, &tdata ); 
    386388    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); 
    388391        return -610; 
    389392    } 
     
    396399    if (status != PJ_SUCCESS) { 
    397400        /* Immediate error! */ 
    398         app_perror("   error: send request", status); 
     401        app_perror("    error: send request", status); 
    399402        pjsip_tx_data_dec_ref(tdata); 
     403        pj_mutex_unlock(rt_test_data[thread_id].mutex); 
    400404        return -620; 
    401405    } 
     
    404408    rt_test_data[thread_id].sent_request_count++; 
    405409 
     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); 
    406420    return PJ_SUCCESS; 
    407421} 
     
    414428        pj_timestamp recv_time; 
    415429 
     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 
    416435        /* Update counter and end-time. */ 
    417436        rt_test_data[thread_id].recv_response_count++; 
     
    421440        pj_add_timestamp(&rt_test_data[thread_id].total_rt_time, &recv_time); 
    422441 
    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 
    425452        return PJ_TRUE; 
    426453    } 
     
    428455} 
    429456 
    430 static int rt_thread(void *arg) 
     457static 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 
     476static 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 
     490static int rt_worker_thread(void *arg) 
    431491{ 
    432492    int i, thread_id = (int)arg; 
     
    435495    /* Sleep to allow main threads to run. */ 
    436496    pj_thread_sleep(10); 
    437  
    438     /* Send the first request. */ 
    439     if (rt_send_request(thread_id) != PJ_SUCCESS) 
    440         return -1; 
    441497 
    442498    while (!rt_stop) { 
     
    453509int transport_rt_test( pjsip_transport_type_e tp_type, 
    454510                       pjsip_transport *ref_tp, 
    455                        char *target_url ) 
     511                       char *target_url, 
     512                       int *lost) 
    456513{ 
    457514    enum { THREADS = 4, INTERVAL = 10 }; 
     
    459516    pj_status_t status; 
    460517    pj_pool_t *pool; 
    461     pj_bool_t is_reliable; 
     518    pj_bool_t logger_enabled; 
    462519 
    463520    pj_timestamp zero_time, total_time; 
     
    467524 
    468525 
    469     PJ_LOG(3,("", "  multithreaded round-trip test (%d threads)...", 
     526    PJ_LOG(3,(THIS_FILE, "  multithreaded round-trip test (%d threads)...", 
    470527                  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); 
    474533 
    475534    /* Register module (if not yet registered) */ 
     
    498557 
    499558        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; 
    500565 
    501566        /* Generate Call-ID for each thread. */ 
     
    505570        pj_strcat(&rt_test_data[i].call_id, &str_id); 
    506571 
     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 
    507579        /* 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, 
    509581                                  PJ_THREAD_SUSPENDED, &rt_test_data[i].thread); 
    510582        if (status != PJ_SUCCESS) { 
     
    516588    /* Start threads! */ 
    517589    for (i=0; i<THREADS; ++i) { 
     590        pj_time_val delay = {0,0}; 
    518591        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); 
    519596    } 
    520597 
     
    529606        pj_thread_join(rt_test_data[i].thread); 
    530607        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); 
    531614    } 
    532615 
     
    547630        total_time.u64 = 0; 
    548631    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)); 
    556635 
    557636    pjsip_endpt_release_pool(endpt, pool); 
    558637 
    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 
    563646    return 0; 
    564647} 
  • pjproject/trunk/pjsip/src/test-pjsip/transport_udp_test.c

    r107 r109  
    2222#include <pjlib.h> 
    2323 
     24#define THIS_FILE   "transport_udp_test.c" 
     25 
    2426 
    2527/* 
     
    3335    pj_str_t s; 
    3436    pj_status_t status; 
    35     int i; 
     37    int i, pkt_lost; 
    3638 
    3739    pj_sockaddr_in_init(&addr, NULL, TEST_UDP_PORT); 
     
    8587    /* Multi-threaded round-trip test. */ 
    8688    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); 
    8891    if (status != 0) 
    8992        return status; 
     93 
     94    if (pkt_lost != 0) 
     95        PJ_LOG(3,(THIS_FILE, "   note: %d packet(s) was lost", pkt_lost)); 
    9096 
    9197    /* Check again that reference counter is 1. */ 
     
    101107        return -90; 
    102108 
     109    /* Flush events. */ 
     110    PJ_LOG(3,(THIS_FILE, "   Flushing events, 1 second...")); 
     111    flush_events(1000); 
    103112 
    104113    /* Done */ 
  • pjproject/trunk/pjsip/src/test-pjsip/tsx_uac_test.c

    r107 r109  
    2222#include <pjlib.h> 
    2323 
     24#define THIS_FILE   "tsx_uac_test.c" 
     25 
     26 
    2427/***************************************************************************** 
    2528 ** 
    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 **      
    3177 ***************************************************************************** 
    3278 */ 
    3379 
    34 static char *CALL_ID1 = "UAC-Tsx-Basic-Test1"; 
     80static char *TEST1_BRANCH_ID = PJSIP_RFC3261_BRANCH_ID "-Test1"; 
     81static char *TEST2_BRANCH_ID = PJSIP_RFC3261_BRANCH_ID "-Test2"; 
     82static char *TEST3_BRANCH_ID = PJSIP_RFC3261_BRANCH_ID "-Test3"; 
     83static char *TEST4_BRANCH_ID = PJSIP_RFC3261_BRANCH_ID "-Test4"; 
     84static char *TEST5_BRANCH_ID = PJSIP_RFC3261_BRANCH_ID "-Test5"; 
     85static char *TEST6_BRANCH_ID = PJSIP_RFC3261_BRANCH_ID "-Test6"; 
     86static char *TEST7_BRANCH_ID = PJSIP_RFC3261_BRANCH_ID "-Test7"; 
     87static char *TEST8_BRANCH_ID = PJSIP_RFC3261_BRANCH_ID "-Test8"; 
     88static 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 
    3595static void tsx_user_on_tsx_state(pjsip_transaction *tsx, pjsip_event *e); 
    3696static pj_bool_t msg_receiver_on_rx_request(pjsip_rx_data *rdata); 
     
    52112    NULL,                               /* on_rx_request()      */ 
    53113    NULL,                               /* on_rx_response()     */ 
     114    NULL,                               /* on_tx_request()      */ 
     115    NULL,                               /* on_tx_response()     */ 
    54116    &tsx_user_on_tsx_state,             /* on_tsx_state()       */ 
    55117}; 
     
    71133    &msg_receiver_on_rx_request,        /* on_rx_request()      */ 
    72134    NULL,                               /* on_rx_response()     */ 
     135    NULL,                               /* on_tx_request()      */ 
     136    NULL,                               /* on_tx_response()     */ 
    73137    NULL,                               /* on_tsx_state()       */ 
    74138}; 
    75139 
    76 /* Static vars. */ 
     140/* Static vars, which will be reset on each test. */ 
    77141static int recv_count; 
    78142static pj_time_val recv_last; 
    79143static pj_bool_t test_complete; 
    80144 
     145/* Loop transport instance. */ 
     146static 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 */ 
    81153static void tsx_user_on_tsx_state(pjsip_transaction *tsx, pjsip_event *e) 
    82154{ 
    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    } 
    85308} 
    86309 
    87310#define DIFF(a,b)   ((a<b) ? (b-a) : (a-b)) 
    88311 
     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 */ 
    89317static pj_bool_t msg_receiver_on_rx_request(pjsip_rx_data *rdata) 
    90318{ 
    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) { 
    92320        /* 
    93          * The CALL_ID1 test performs the verifications for transaction 
     321         * The TEST1_BRANCH_ID test performs the verifications for transaction 
    94322         * retransmission mechanism. It will not answer the incoming request 
    95323         * with any response. 
     
    97325        pjsip_msg *msg = rdata->msg_info.msg; 
    98326 
    99         PJ_LOG(4,("", "   received request")); 
     327        PJ_LOG(4,(THIS_FILE, "    received request")); 
    100328 
    101329        /* Only wants to take INVITE or OPTIONS method. */ 
     
    103331            msg->line.req.method.id != PJSIP_OPTIONS_METHOD) 
    104332        { 
    105             PJ_LOG(3,("", "   error: received unexpected method %.*s", 
     333            PJ_LOG(3,(THIS_FILE, "    error: received unexpected method %.*s", 
    106334                          msg->line.req.method.name.slen, 
    107335                          msg->line.req.method.name.ptr)); 
     
    112340        if (recv_count == 0) { 
    113341            recv_count++; 
    114             pj_gettimeofday(&recv_last); 
     342            //pj_gettimeofday(&recv_last); 
     343            recv_last = rdata->pkt_info.timestamp; 
    115344        } else { 
    116345            pj_time_val now; 
    117346            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; 
    120351            PJ_TIME_VAL_SUB(now, recv_last); 
    121352            msec_elapsed = now.sec*1000 + now.msec; 
     
    127358                if (msec_expected > PJSIP_T2_TIMEOUT) 
    128359                    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)); 
    135370                test_complete = -610; 
    136371            } 
    137372 
    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)); 
    141378                test_complete = -620; 
    142379            } 
    143380 
    144             pj_gettimeofday(&recv_last); 
     381            //pj_gettimeofday(&recv_last); 
     382            recv_last = rdata->pkt_info.timestamp; 
    145383        } 
    146384        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 
    148477    return PJ_FALSE; 
    149478} 
    150479 
    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 */ 
     483static int perform_tsx_test(int dummy, char *target_uri, char *from_uri,  
     484                            char *branch_param, int test_time,  
     485                            const pjsip_method *method) 
    162486{ 
    163487    pjsip_tx_data *tdata; 
    164488    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; 
    167491    pj_time_val timeout; 
    168492    pj_status_t status; 
    169493 
    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); 
    176505 
    177506    /* Create request. */ 
    178507    status = pjsip_endpt_create_request( endpt, method, &target, 
    179                                          &from, &target, NULL, &call_id, -1,  
     508                                         &from, &target, NULL, NULL, -1,  
    180509                                         NULL, &tdata); 
    181510    if (status != PJ_SUCCESS) { 
    182511        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); 
    185518 
    186519    /* Add additional reference to tdata to prevent transaction from 
     
    193526    if (status != PJ_SUCCESS) { 
    194527        app_perror("   Error: unable to create UAC transaction", status); 
    195         return -510; 
     528        pjsip_tx_data_dec_ref(tdata); 
     529        return -110; 
    196530    } 
    197531 
     
    201535    /* Send the message. */ 
    202536    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 
    207545 
    208546    /* Set test completion time. */ 
    209547    pj_gettimeofday(&timeout); 
    210     timeout.sec += 33; 
     548    timeout.sec += test_time; 
    211549 
    212550    /* Wait until test complete. */ 
    213551    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); 
    217555 
    218556        pj_gettimeofday(&now); 
    219557        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); 
    226566        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); 
    227582 
    228583    /* Make sure transaction has been destroyed. */ 
    229584    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; 
    232588    } 
    233589 
    234590    /* Check tdata reference counter. */ 
    235591    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", 
    237593                      pj_atomic_get(tdata->ref_cnt))); 
    238         return -550; 
     594        pjsip_tx_data_dec_ref(tdata); 
     595        return -150; 
    239596    } 
    240597 
     
    247604/***************************************************************************** 
    248605 ** 
     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 */ 
     614static 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 */ 
     679static 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 */ 
     730static 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 */ 
     762static 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 */ 
     809static 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 */ 
     832static 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 ** 
    249865 ** UAC Transaction Test. 
    250866 ** 
     
    254870{ 
    255871    pj_sockaddr_in addr; 
    256     pj_str_t tmp; 
    257     pjsip_transport *tp; 
    258872    pj_status_t status; 
    259873 
    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); 
    278877    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; 
    281880    } 
    282881 
     
    290889    if (status != PJ_SUCCESS) { 
    291890        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(); 
    297897    if (status != 0) 
    298898        return status; 
    299899 
    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(); 
    302902    if (status != 0) 
    303903        return status; 
    304904 
     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); 
    305928    return 0; 
    306929} 
     930 
  • pjproject/trunk/pjsip/src/test-pjsip/txdata_test.c

    r107 r109  
    2424#define HFIND(msg,h,H) ((pjsip_##h##_hdr*) pjsip_msg_find_hdr(msg, PJSIP_H_##H, NULL)) 
    2525 
     26#define THIS_FILE   "txdata_test.c" 
     27 
     28 
    2629/* 
    2730 * This tests various core message creation functions.  
     
    5154    /* Buffer must be invalid. */ 
    5255    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")); 
    5457        return -14; 
    5558    } 
    5659    /* Reference counter must be set to 1. */ 
    5760    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")); 
    5962        return -15; 
    6063    } 
     
    103106    /* Buffer must be invalid. */ 
    104107    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")); 
    106109        return -34; 
    107110    } 
    108111    /* Reference counter must be set to 1. */ 
    109112    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")); 
    111114        return -35; 
    112115    } 
     
    142145    /* Done checking invite2. We can delete this. */ 
    143146    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!")); 
    145148        return -49; 
    146149    } 
     
    173176    /* Buffer must be invalid. */ 
    174177    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")); 
    176179        return -54; 
    177180    } 
    178181    /* Check reference counter. */ 
    179182    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")); 
    181184        return -55; 
    182185    } 
     
    215218    /* Buffer must be invalid. */ 
    216219    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")); 
    218221        return -84; 
    219222    } 
    220223    /* Check reference counter. */ 
    221224    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")); 
    223226        return -85; 
    224227    } 
     
    248251    /* Done checking CANCEL request. */ 
    249252    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!")); 
    251254        return -99; 
    252255    } 
     
    260263    status = pjsip_endpt_create_ack( endpt, invite, &dummy_rdata, &ack ); 
    261264    if (status != PJ_SUCCESS) { 
    262         PJ_LOG(3,("", "   error: unable to create ACK")); 
     265        PJ_LOG(3,(THIS_FILE, "   error: unable to create ACK")); 
    263266        return -100; 
    264267    } 
    265268    /* Buffer must be invalid. */ 
    266269    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")); 
    268271        return -104; 
    269272    } 
    270273    /* Check reference counter. */ 
    271274    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")); 
    273276        return -105; 
    274277    } 
     
    299302    /* Done checking invite message. */ 
    300303    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!")); 
    302305        return -120; 
    303306    } 
     
    305308    /* Done checking response message. */ 
    306309    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!")); 
    308311        return -130; 
    309312    } 
     
    311314    /* Done checking ack message. */ 
    312315    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!")); 
    314317        return -140; 
    315318    } 
  • pjproject/trunk/pjsip/src/test-pjsip/uri_test.c

    r107 r109  
    2020#include <pjsip_core.h> 
    2121#include <pjlib.h> 
     22 
     23#define THIS_FILE   "uri_test.c" 
    2224 
    2325 
     
    693695        status = entry->status==ERR_SYNTAX_ERR ? PJ_SUCCESS : -10; 
    694696        if (status != 0) { 
    695             PJ_LOG(3,("", "   uri parse error!\n" 
    696                           "   uri='%s'\n", 
    697                           entry->str)); 
     697            PJ_LOG(3,(THIS_FILE, "   uri parse error!\n" 
     698                                "   uri='%s'\n", 
     699                                entry->str)); 
    698700        } 
    699701        goto on_return; 
     
    739741        status = entry->status==ERR_NOT_EQUAL ? PJ_SUCCESS : -40; 
    740742        if (status != 0) { 
    741             PJ_LOG(3,("", "   uri comparison mismatch, status=%d:\n" 
    742                           "    uri1='%s'\n" 
    743                           "    uri2='%s'", 
    744                           status, s1.ptr, s2.ptr)); 
     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)); 
    745747        } 
    746748        goto on_return; 
     
    763765        if (pj_strcmp2(&s1, entry->printed) != 0) { 
    764766            /* Not equal. */ 
    765             PJ_LOG(3,("", "   uri print mismatch:\n" 
    766                           "    printed='%s'\n" 
    767                           "    expectd='%s'", 
    768                           s1.ptr, entry->printed)); 
     767            PJ_LOG(3,(THIS_FILE, "   uri print mismatch:\n" 
     768                                "    printed='%s'\n" 
     769                                "    expectd='%s'", 
     770                                s1.ptr, entry->printed)); 
    769771            status = -60; 
    770772        } 
     
    772774        if (pj_strcmp(&s1, &s2) != 0) { 
    773775            /* Not equal. */ 
    774             PJ_LOG(3,("", "   uri print mismatch:\n" 
    775                           "    uri1='%s'\n" 
    776                           "    uri2='%s'", 
    777                           s1.ptr, s2.ptr)); 
     776            PJ_LOG(3,(THIS_FILE, "   uri print mismatch:\n" 
     777                                "    uri1='%s'\n" 
     778                                "    uri2='%s'", 
     779                                s1.ptr, s2.ptr)); 
    778780            status = -70; 
    779781        } 
     
    795797    zero.u32.hi = zero.u32.lo = 0; 
    796798 
    797     PJ_LOG(3,("", "  simple test")); 
     799    PJ_LOG(3,(THIS_FILE, "  simple test")); 
    798800    pool = pjsip_endpt_create_pool(endpt, "", POOL_SIZE, POOL_SIZE); 
    799801    for (i=0; i<PJ_ARRAY_SIZE(uri_test_array); ++i) { 
    800802        status = do_uri_test(pool, &uri_test_array[i]); 
    801803        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", 
    803805                      status, i)); 
    804806            goto on_return; 
     
    807809    pjsip_endpt_release_pool(endpt, pool); 
    808810 
    809     PJ_LOG(3,("", "  benchmarking...")); 
     811    PJ_LOG(3,(THIS_FILE, "  benchmarking...")); 
    810812    parse_len = print_len = cmp_len = 0; 
    811813    parse_time.u32.hi = parse_time.u32.lo = 0; 
     
    817819            status = do_uri_test(pool, &uri_test_array[i]); 
    818820            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", 
    820822                          status, i)); 
    821823                pjsip_endpt_release_pool(endpt, pool); 
     
    835837    avg_parse = 1000000 / avg_parse; 
    836838 
    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)); 
    841844 
    842845    kbytes = print_len; 
     
    849852    avg_print = 1000000 / avg_print; 
    850853 
    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)); 
    855859 
    856860    kbytes = cmp_len; 
     
    863867    avg_cmp = 1000000 / avg_cmp; 
    864868 
    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")); 
    871876 
    872877 
Note: See TracChangeset for help on using the changeset viewer.