Ignore:
Timestamp:
Jan 5, 2006 11:35:46 PM (18 years ago)
Author:
bennylp
Message:

Added loop transport to test transaction

File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjsip/src/pjsip/sip_transaction.c

    r106 r107  
    1818 */ 
    1919#include <pjsip/sip_transaction.h> 
    20 #include <pjsip/sip_transport.h> 
    21 #include <pjsip/sip_config.h> 
    2220#include <pjsip/sip_util.h> 
    23 #include <pjsip/sip_event.h> 
     21#include <pjsip/sip_module.h> 
    2422#include <pjsip/sip_endpoint.h> 
    2523#include <pjsip/sip_errno.h> 
     24#include <pjsip/sip_event.h> 
     25#include <pj/hash.h> 
     26#include <pj/pool.h> 
     27#include <pj/os.h> 
     28#include <pj/string.h> 
     29#include <pj/assert.h> 
     30#include <pj/guid.h> 
    2631#include <pj/log.h> 
    27 #include <pj/string.h> 
    28 #include <pj/os.h> 
    29 #include <pj/guid.h> 
    30 #include <pj/pool.h> 
    31 #include <pj/assert.h> 
    32  
    33 #if 0   // XXX JUNK 
    34     /* Initialize TLS ID for transaction lock. */ 
    35     status = pj_thread_local_alloc(&pjsip_tsx_lock_tls_id); 
    36     if (status != PJ_SUCCESS) { 
    37         goto on_error; 
    38     } 
    39     pj_thread_local_set(pjsip_tsx_lock_tls_id, NULL); 
    40  
    41  
    42     /* Create hash table for transaction. */ 
    43     endpt->tsx_table = pj_hash_create( endpt->pool, PJSIP_MAX_TSX_COUNT ); 
    44     if (!endpt->tsx_table) { 
    45         status = PJ_ENOMEM; 
    46         goto on_error; 
    47     } 
    48  
    49  
    50 /* 
    51  * Create a new transaction. 
    52  * Endpoint must then initialize the new transaction as either UAS or UAC, and 
    53  * register it to the hash table. 
    54  */ 
    55 PJ_DEF(pj_status_t) pjsip_endpt_create_tsx(pjsip_endpoint *endpt, 
    56                                            pjsip_transaction **p_tsx) 
    57 { 
    58     pj_pool_t *pool; 
    59  
    60     PJ_ASSERT_RETURN(endpt && p_tsx, PJ_EINVAL); 
    61  
    62     PJ_LOG(5, (THIS_FILE, "pjsip_endpt_create_tsx()")); 
    63  
    64     /* Request one pool for the transaction. Mutex is locked there. */ 
    65     pool = pjsip_endpt_create_pool(endpt, "ptsx%p",  
    66                                       PJSIP_POOL_LEN_TSX, PJSIP_POOL_INC_TSX); 
    67     if (pool == NULL) { 
    68         return PJ_ENOMEM; 
    69     } 
    70  
    71     /* Create the transaction. */ 
    72     return pjsip_tsx_create(pool, endpt, p_tsx); 
    73 } 
    74  
    75  
    76 /* 
    77  * Register the transaction to the endpoint. 
    78  * This will put the transaction to the transaction hash table. Before calling 
    79  * this function, the transaction must be INITIALIZED as either UAS or UAC, so 
    80  * that the transaction key is built. 
    81  */ 
    82 PJ_DEF(void) pjsip_endpt_register_tsx( pjsip_endpoint *endpt, 
    83                                        pjsip_transaction *tsx) 
    84 { 
    85     PJ_LOG(5, (THIS_FILE, "pjsip_endpt_register_tsx(%s)", tsx->obj_name)); 
    86  
    87     pj_assert(tsx->transaction_key.slen != 0); 
    88     //pj_assert(tsx->state != PJSIP_TSX_STATE_NULL); 
    89  
    90     /* Lock hash table mutex. */ 
    91     pj_mutex_lock(endpt->tsx_table_mutex); 
    92  
    93     /* Register the transaction to the hash table. */ 
    94     pj_hash_set( tsx->pool, endpt->tsx_table, tsx->transaction_key.ptr, 
    95                  tsx->transaction_key.slen, tsx); 
    96  
    97     /* Unlock mutex. */ 
    98     pj_mutex_unlock(endpt->tsx_table_mutex); 
    99 } 
    100  
    101 /* 
    102  * Find transaction by the key. 
    103  */ 
    104 PJ_DEF(pjsip_transaction*) pjsip_endpt_find_tsx( pjsip_endpoint *endpt, 
    105                                                   const pj_str_t *key ) 
    106 { 
    107     pjsip_transaction *tsx; 
    108  
    109     PJ_LOG(5, (THIS_FILE, "pjsip_endpt_find_tsx()")); 
    110  
    111     /* Start lock mutex in the endpoint. */ 
    112     pj_mutex_lock(endpt->tsx_table_mutex); 
    113  
    114     /* Find the transaction in the hash table. */ 
    115     tsx = pj_hash_get( endpt->tsx_table, key->ptr, key->slen ); 
    116  
    117     /* Unlock mutex. */ 
    118     pj_mutex_unlock(endpt->tsx_table_mutex); 
    119  
    120     return tsx; 
    121 } 
    122  
    123 /* 
    124  * Create key. 
    125  */ 
    126 static void rdata_create_key( pjsip_rx_data *rdata) 
    127 { 
    128     pjsip_role_e role; 
    129     if (rdata->msg_info.msg->type == PJSIP_REQUEST_MSG) { 
    130         role = PJSIP_ROLE_UAS; 
    131     } else { 
    132         role = PJSIP_ROLE_UAC; 
    133     } 
    134     pjsip_tsx_create_key(rdata->tp_info.pool, &rdata->endpt_info.key, role, 
    135                          &rdata->msg_info.cseq->method, rdata); 
    136 } 
    137  
    138  
    139 /* 
    140  * This is the callback that is called by the transport manager when it  
    141  * receives a message from the network. 
    142  */ 
    143 static void endpt_transport_callback( pjsip_endpoint *endpt, 
    144                                       pj_status_t status, 
    145                                       pjsip_rx_data *rdata ) 
    146 { 
    147     pjsip_msg *msg = rdata->msg_info.msg; 
    148     pjsip_transaction *tsx; 
    149     pj_bool_t a_new_transaction_just_been_created = PJ_FALSE; 
    150  
    151     PJ_LOG(5, (THIS_FILE, "endpt_transport_callback(rdata=%p)", rdata)); 
    152  
    153     if (status != PJ_SUCCESS) { 
    154         const char *src_addr = rdata->pkt_info.src_name; 
    155         int port = rdata->pkt_info.src_port; 
    156         PJSIP_ENDPT_LOG_ERROR((endpt, "transport", status, 
    157                                "Src.addr=%s:%d, packet:--\n" 
    158                                "%s\n" 
    159                                "-- end of packet. Error", 
    160                                src_addr, port, rdata->msg_info.msg_buf)); 
    161         return; 
    162     } 
    163  
    164     /* For response, check that the value in Via sent-by match the transport. 
    165      * If not matched, silently drop the response. 
    166      * Ref: RFC3261 Section 18.1.2 Receiving Response 
    167      */ 
    168     if (msg->type == PJSIP_RESPONSE_MSG) { 
    169         const pj_str_t *addr_addr; 
    170         int port = rdata->msg_info.via->sent_by.port; 
    171         pj_bool_t mismatch = PJ_FALSE; 
    172         if (port == 0) { 
    173             int type; 
    174             type = rdata->tp_info.transport->key.type; 
    175             port = pjsip_transport_get_default_port_for_type(type); 
    176         } 
    177         addr_addr = &rdata->tp_info.transport->local_name.host; 
    178         if (pj_strcmp(&rdata->msg_info.via->sent_by.host, addr_addr) != 0) 
    179             mismatch = PJ_TRUE; 
    180         else if (port != rdata->tp_info.transport->local_name.port) { 
    181             /* Port or address mismatch, we should discard response */ 
    182             /* But we saw one implementation (we don't want to name it to  
    183              * protect the innocence) which put wrong sent-by port although 
    184              * the "rport" parameter is correct. 
    185              * So we discard the response only if the port doesn't match 
    186              * both the port in sent-by and rport. We try to be lenient here! 
    187              */ 
    188             if (rdata->msg_info.via->rport_param != rdata->tp_info.transport->local_name.port) 
    189                 mismatch = PJ_TRUE; 
    190             else { 
    191                 PJ_LOG(4,(THIS_FILE, "Response %p has mismatch port in sent-by" 
    192                                     " but the rport parameter is correct", 
    193                                     rdata)); 
    194             } 
    195         } 
    196  
    197         if (mismatch) { 
    198             pjsip_event e; 
    199  
    200             PJSIP_EVENT_INIT_DISCARD_MSG(e, rdata, PJSIP_EINVALIDVIA); 
    201             endpt_do_event( endpt, &e ); 
    202             return; 
    203         } 
    204     } 
    205  
    206     /* Create key for transaction lookup. */ 
    207     rdata_create_key( rdata); 
    208  
    209     /* Find the transaction for the received message. */ 
    210     PJ_LOG(5, (THIS_FILE, "finding tsx with key=%.*s",  
    211                          rdata->endpt_info.key.slen, rdata->endpt_info.key.ptr)); 
    212  
    213     /* Start lock mutex in the endpoint. */ 
    214     pj_mutex_lock(endpt->tsx_table_mutex); 
    215  
    216     /* Find the transaction in the hash table. */ 
    217     tsx = pj_hash_get( endpt->tsx_table, rdata->endpt_info.key.ptr, rdata->endpt_info.key.slen ); 
    218  
    219     /* Unlock mutex. */ 
    220     pj_mutex_unlock(endpt->tsx_table_mutex); 
    221  
    222     /* If the transaction is not found... */ 
    223     if (tsx == NULL || tsx->state == PJSIP_TSX_STATE_TERMINATED) { 
    224  
    225         /*  
    226          * For response message, discard the message, except if the response is 
    227          * an 2xx class response to INVITE, which in this case it must be 
    228          * passed to TU to be acked. 
    229          */ 
    230         if (msg->type == PJSIP_RESPONSE_MSG) { 
    231  
    232             /* Inform TU about the 200 message, only if it's INVITE. */ 
    233             if (PJSIP_IS_STATUS_IN_CLASS(msg->line.status.code, 200) && 
    234                 rdata->msg_info.cseq->method.id == PJSIP_INVITE_METHOD)  
    235             { 
    236                 pjsip_event e; 
    237  
    238                 /* Should not happen for UA. Tsx theoritically lives until 
    239                  * all responses are absorbed. 
    240                  */ 
    241                 pj_assert(0); 
    242  
    243                 PJSIP_EVENT_INIT_RX_200_MSG(e, rdata); 
    244                 endpt_do_event( endpt, &e ); 
    245  
    246             } else { 
    247                 /* Just discard the response, inform TU. */ 
    248                 pjsip_event e; 
    249  
    250                 PJSIP_EVENT_INIT_DISCARD_MSG(e, rdata,  
    251                     PJSIP_ERRNO_FROM_SIP_STATUS(PJSIP_SC_CALL_TSX_DOES_NOT_EXIST)); 
    252                 endpt_do_event( endpt, &e ); 
    253             } 
    254  
    255         /* 
    256          * For non-ACK request message, create a new transaction. 
    257          */ 
    258         } else if (rdata->msg_info.msg->line.req.method.id != PJSIP_ACK_METHOD) { 
    259  
    260             pj_status_t status; 
    261  
    262             /* Create transaction, mutex is locked there. */ 
    263             status = pjsip_endpt_create_tsx(endpt, &tsx); 
    264             if (status != PJ_SUCCESS) { 
    265                 PJSIP_ENDPT_LOG_ERROR((endpt, THIS_FILE, status, 
    266                                        "Unable to create transaction")); 
    267                 return; 
    268             } 
    269  
    270             /* Initialize transaction as UAS. */ 
    271             pjsip_tsx_init_uas( tsx, rdata ); 
    272  
    273             /* Register transaction, mutex is locked there. */ 
    274             pjsip_endpt_register_tsx( endpt, tsx ); 
    275  
    276             a_new_transaction_just_been_created = PJ_TRUE; 
    277         } 
    278     } 
    279  
    280     /* If transaction is found (or newly created), pass the message. 
    281      * Otherwise if it's an ACK request, pass directly to TU. 
    282      */ 
    283     if (tsx && tsx->state != PJSIP_TSX_STATE_TERMINATED) { 
    284         /* Dispatch message to transaction. */ 
    285         pjsip_tsx_on_rx_msg( tsx, rdata ); 
    286  
    287     } else if (rdata->msg_info.msg->line.req.method.id == PJSIP_ACK_METHOD) { 
    288         /* 
    289          * This is an ACK message, but the INVITE transaction could not 
    290          * be found (possibly because the branch parameter in Via in ACK msg 
    291          * is different than the branch in original INVITE). This happens with 
    292          * SER! 
    293          */ 
    294         pjsip_event event; 
    295  
    296         PJSIP_EVENT_INIT_RX_ACK_MSG(event,rdata); 
    297         endpt_do_event( endpt, &event ); 
    298     } 
    299  
    300     /* 
    301      * If a new request message has just been receieved, but no modules 
    302      * seem to be able to handle the request message, then terminate the 
    303      * transaction. 
    304      * 
    305      * Ideally for cases like "unsupported method", we should be able to 
    306      * answer the request statelessly. But we can not do that since the 
    307      * endpoint shoule be able to be used as both user agent and proxy stack, 
    308      * and a proxy stack should be able to handle arbitrary methods. 
    309      */ 
    310     if (a_new_transaction_just_been_created && tsx->status_code < 100) { 
    311         /* Certainly no modules has sent any response message. 
    312          * Check that any modules has attached a module data. 
    313          */ 
    314         int i; 
    315         for (i=0; i<PJSIP_MAX_MODULE; ++i) { 
    316             if (tsx->module_data[i] != NULL) { 
    317                 break; 
    318             } 
    319         } 
    320         if (i == PJSIP_MAX_MODULE) { 
    321             /* No modules have attached itself to the transaction.  
    322              * Terminate the transaction with 501/Not Implemented. 
    323              */ 
    324             pjsip_tx_data *tdata; 
    325             pj_status_t status; 
    326              
    327             if (tsx->method.id == PJSIP_OPTIONS_METHOD) { 
    328                 status = pjsip_endpt_create_response(endpt, rdata, 200,  
    329                                                      &tdata); 
    330             } else { 
    331                 status = pjsip_endpt_create_response(endpt, rdata,  
    332                                                      PJSIP_SC_METHOD_NOT_ALLOWED, 
    333                                                      &tdata); 
    334             } 
    335  
    336             if (status != PJ_SUCCESS) { 
    337                 PJSIP_ENDPT_LOG_ERROR((endpt, THIS_FILE, status, 
    338                                        "Unable to create response")); 
    339                 return; 
    340             } 
    341  
    342             if (endpt->allow_hdr) { 
    343                 pjsip_msg_add_hdr( tdata->msg,  
    344                                    pjsip_hdr_shallow_clone(tdata->pool, endpt->allow_hdr)); 
    345             } 
    346             pjsip_tsx_on_tx_msg( tsx, tdata ); 
    347  
    348         } else { 
    349             /* 
    350              * If a module has registered itself in the transaction but it 
    351              * hasn't responded the request, chances are the module wouldn't 
    352              * respond to the request at all. We terminate the request here 
    353              * with 500/Internal Server Error, to be safe. 
    354              */ 
    355             pjsip_tx_data *tdata; 
    356             pj_status_t status; 
    357  
    358             status = pjsip_endpt_create_response(endpt, rdata, 500, &tdata); 
    359             if (status != PJ_SUCCESS) { 
    360                 PJSIP_ENDPT_LOG_ERROR((endpt, THIS_FILE, status, 
    361                                        "Unable to create response")); 
    362                 return; 
    363             } 
    364  
    365             pjsip_tsx_on_tx_msg(tsx, tdata); 
    366         } 
    367     } 
    368 } 
    369  
    370  
    371  
    372     /* Transaction tables. */ 
    373     count = pj_hash_count(endpt->tsx_table); 
    374     PJ_LOG(3, (THIS_FILE, " Number of transactions: %u", count)); 
    375  
    376     if (count && detail) { 
    377         pj_hash_iterator_t it_val; 
    378         pj_hash_iterator_t *it; 
    379         pj_time_val now; 
    380  
    381         PJ_LOG(3, (THIS_FILE, " Dumping transaction tables:")); 
    382  
    383         pj_gettimeofday(&now); 
    384         it = pj_hash_first(endpt->tsx_table, &it_val); 
    385  
    386         while (it != NULL) { 
    387             int timeout_diff; 
    388  
    389             /* Get the transaction. No need to lock transaction's mutex 
    390              * since we already hold endpoint mutex, so that no transactions 
    391              * will be deleted. 
    392              */ 
    393             pjsip_transaction *tsx = pj_hash_this(endpt->tsx_table, it); 
    394  
    395             const char *role = (tsx->role == PJSIP_ROLE_UAS ? "UAS" : "UAC"); 
    396          
    397             if (tsx->timeout_timer._timer_id != -1) { 
    398                 if (tsx->timeout_timer._timer_value.sec > now.sec) { 
    399                     timeout_diff = tsx->timeout_timer._timer_value.sec - now.sec; 
    400                 } else { 
    401                     timeout_diff = now.sec - tsx->timeout_timer._timer_value.sec; 
    402                     timeout_diff = 0 - timeout_diff; 
    403                 } 
    404             } else { 
    405                 timeout_diff = -1; 
    406             } 
    407  
    408             PJ_LOG(3, (THIS_FILE, "  %s %s %10.*s %.9u %s t=%ds",  
    409                        tsx->obj_name, role,  
    410                        tsx->method.name.slen, tsx->method.name.ptr, 
    411                        tsx->cseq, 
    412                        pjsip_tsx_state_str(tsx->state), 
    413                        timeout_diff)); 
    414  
    415             it = pj_hash_next(endpt->tsx_table, it); 
    416         } 
    417     } 
    418  
    419  
    420  
    421 #endif  // XXX JUNK 
    422  
    423 /* Thread Local Storage ID for transaction lock (initialized by endpoint) */ 
    424 long pjsip_tsx_lock_tls_id; 
    425  
    426 /* State names */ 
     32 
     33/***************************************************************************** 
     34 ** 
     35 ** Declarations and static variable definitions section. 
     36 ** 
     37 ***************************************************************************** 
     38 
     39/* Prototypes. */ 
     40static pj_status_t mod_tsx_layer_load(pjsip_endpoint *endpt); 
     41static pj_status_t mod_tsx_layer_start(void); 
     42static pj_status_t mod_tsx_layer_stop(void); 
     43static pj_status_t mod_tsx_layer_unload(void); 
     44static pj_bool_t   mod_tsx_layer_on_rx_request(pjsip_rx_data *rdata); 
     45static pj_bool_t   mod_tsx_layer_on_rx_response(pjsip_rx_data *rdata); 
     46 
     47/* Transaction layer module definition. */ 
     48static struct mod_tsx_layer 
     49{ 
     50    struct pjsip_module  mod; 
     51    pj_pool_t           *pool; 
     52    pjsip_endpoint      *endpt; 
     53    pj_mutex_t          *mutex; 
     54    pj_hash_table_t     *htable; 
     55} mod_tsx_layer =  
     56{   { 
     57        NULL, NULL,                     /* List's prev and next.    */ 
     58        { "mod-tsx-layer", 13 },        /* Module name.             */ 
     59        -1,                             /* Module ID                */ 
     60        PJSIP_MOD_PRIORITY_TSX_LAYER,   /* Priority.                */ 
     61        NULL,                           /* User_data.               */ 
     62        0,                              /* Methods count.           */ 
     63        { NULL },                       /* Array of methods.        */ 
     64        mod_tsx_layer_load,             /* load().                  */ 
     65        mod_tsx_layer_start,            /* start()                  */ 
     66        mod_tsx_layer_stop,             /* stop()                   */ 
     67        mod_tsx_layer_unload,           /* unload()                 */ 
     68        mod_tsx_layer_on_rx_request,    /* on_rx_request()          */ 
     69        mod_tsx_layer_on_rx_response,   /* on_rx_response()         */ 
     70        NULL 
     71    } 
     72}; 
     73 
     74/* Thread Local Storage ID for transaction lock */ 
     75static long pjsip_tsx_lock_tls_id; 
     76 
     77/* Transaction state names */ 
    42778static const char *state_str[] =  
    42879{ 
     
    44091static const char *role_name[] =  
    44192{ 
    442     "Client", 
    443     "Server" 
     93    "UAC", 
     94    "UAS" 
     95}; 
     96 
     97/* Transport flag. */ 
     98enum 
     99{ 
     100    TSX_HAS_PENDING_TRANSPORT   = 1, 
     101    TSX_HAS_PENDING_RESCHED     = 2, 
     102    TSX_HAS_PENDING_SEND        = 4, 
     103    TSX_HAS_PENDING_DESTROY     = 8, 
    444104}; 
    445105 
     
    469129}; 
    470130 
    471 /* Function Prototypes */ 
    472 static pj_status_t pjsip_tsx_on_state_null(     pjsip_transaction *tsx,  
     131 
     132/* Prototypes. */ 
     133static void        lock_tsx(pjsip_transaction *tsx, struct tsx_lock_data *lck); 
     134static pj_status_t unlock_tsx( pjsip_transaction *tsx,  
     135                               struct tsx_lock_data *lck); 
     136static pj_status_t tsx_on_state_null(           pjsip_transaction *tsx,  
    473137                                                pjsip_event *event); 
    474 static pj_status_t pjsip_tsx_on_state_calling(  pjsip_transaction *tsx,  
     138static pj_status_t tsx_on_state_calling(        pjsip_transaction *tsx,  
    475139                                                pjsip_event *event); 
    476 static pj_status_t pjsip_tsx_on_state_trying(   pjsip_transaction *tsx,  
     140static pj_status_t tsx_on_state_trying(         pjsip_transaction *tsx,  
    477141                                                pjsip_event *event); 
    478 static pj_status_t pjsip_tsx_on_state_proceeding_uas( pjsip_transaction *tsx,  
     142static pj_status_t tsx_on_state_proceeding_uas( pjsip_transaction *tsx,  
    479143                                                pjsip_event *event); 
    480 static pj_status_t pjsip_tsx_on_state_proceeding_uac( pjsip_transaction *tsx, 
     144static pj_status_t tsx_on_state_proceeding_uac( pjsip_transaction *tsx, 
    481145                                                pjsip_event *event); 
    482 static pj_status_t pjsip_tsx_on_state_completed_uas( pjsip_transaction *tsx,  
     146static pj_status_t tsx_on_state_completed_uas(  pjsip_transaction *tsx,  
    483147                                                pjsip_event *event); 
    484 static pj_status_t pjsip_tsx_on_state_completed_uac( pjsip_transaction *tsx, 
     148static pj_status_t tsx_on_state_completed_uac(  pjsip_transaction *tsx, 
    485149                                                pjsip_event *event); 
    486 static pj_status_t pjsip_tsx_on_state_confirmed(pjsip_transaction *tsx,  
     150static pj_status_t tsx_on_state_confirmed(      pjsip_transaction *tsx,  
    487151                                                pjsip_event *event); 
    488 static pj_status_t pjsip_tsx_on_state_terminated(pjsip_transaction *tsx,  
     152static pj_status_t tsx_on_state_terminated(     pjsip_transaction *tsx,  
    489153                                                pjsip_event *event); 
    490 static pj_status_t pjsip_tsx_on_state_destroyed(pjsip_transaction *tsx,  
     154static pj_status_t tsx_on_state_destroyed(      pjsip_transaction *tsx,  
    491155                                                pjsip_event *event); 
    492  
    493 static void         tsx_timer_callback( pj_timer_heap_t *theap,  
    494                                         pj_timer_entry *entry); 
    495 static int          tsx_send_msg( pjsip_transaction *tsx,  
    496                                   pjsip_tx_data *tdata); 
    497 static void         lock_tsx( pjsip_transaction *tsx, struct  
    498                                tsx_lock_data *lck ); 
    499 static pj_status_t  unlock_tsx( pjsip_transaction *tsx,  
    500                                struct tsx_lock_data *lck ); 
     156static void        tsx_timer_callback( pj_timer_heap_t *theap,  
     157                                       pj_timer_entry *entry); 
     158static pj_status_t tsx_create( pjsip_module *tsx_user, 
     159                               pjsip_transaction **p_tsx); 
     160static void        tsx_destroy( pjsip_transaction *tsx ); 
     161static void        tsx_resched_retransmission( pjsip_transaction *tsx ); 
     162static pj_status_t tsx_retransmit( pjsip_transaction *tsx, int resched); 
     163static int         tsx_send_msg( pjsip_transaction *tsx,  
     164                                 pjsip_tx_data *tdata); 
     165static void        tsx_on_rx_msg( pjsip_transaction *tsx, 
     166                                  pjsip_rx_data *rdata ); 
     167 
    501168 
    502169/* State handlers for UAC, indexed by state */ 
     
    504171                                                          pjsip_event *) =  
    505172{ 
    506     &pjsip_tsx_on_state_null, 
    507     &pjsip_tsx_on_state_calling, 
    508     &pjsip_tsx_on_state_trying, 
    509     &pjsip_tsx_on_state_proceeding_uac, 
    510     &pjsip_tsx_on_state_completed_uac, 
    511     &pjsip_tsx_on_state_confirmed, 
    512     &pjsip_tsx_on_state_terminated, 
    513     &pjsip_tsx_on_state_destroyed, 
     173    &tsx_on_state_null, 
     174    &tsx_on_state_calling, 
     175    NULL, 
     176    &tsx_on_state_proceeding_uac, 
     177    &tsx_on_state_completed_uac, 
     178    &tsx_on_state_confirmed, 
     179    &tsx_on_state_terminated, 
     180    &tsx_on_state_destroyed, 
    514181}; 
    515182 
     
    518185                                                          pjsip_event *) =  
    519186{ 
    520     &pjsip_tsx_on_state_null, 
    521     &pjsip_tsx_on_state_calling, 
    522     &pjsip_tsx_on_state_trying, 
    523     &pjsip_tsx_on_state_proceeding_uas, 
    524     &pjsip_tsx_on_state_completed_uas, 
    525     &pjsip_tsx_on_state_confirmed, 
    526     &pjsip_tsx_on_state_terminated, 
    527     &pjsip_tsx_on_state_destroyed, 
     187    &tsx_on_state_null, 
     188    NULL, 
     189    &tsx_on_state_trying, 
     190    &tsx_on_state_proceeding_uas, 
     191    &tsx_on_state_completed_uas, 
     192    &tsx_on_state_confirmed, 
     193    &tsx_on_state_terminated, 
     194    &tsx_on_state_destroyed, 
    528195}; 
    529196 
     197/***************************************************************************** 
     198 ** 
     199 ** Utilities 
     200 ** 
     201 ***************************************************************************** 
     202 */ 
    530203/* 
    531204 * Get transaction state name. 
     
    543216    return role_name[role]; 
    544217} 
    545  
    546  
    547  
    548 /* 
    549  * Unregister the transaction from the hash table, and destroy the resources 
    550  * from the transaction. 
    551  */ 
    552 PJ_DEF(void) pjsip_endpt_destroy_tsx( pjsip_endpoint *endpt, 
    553                                       pjsip_transaction *tsx) 
    554 { 
    555     PJ_LOG(5, (THIS_FILE, "pjsip_endpt_destroy_tsx(%s)", tsx->obj_name)); 
    556  
    557     pj_assert(tsx->state == PJSIP_TSX_STATE_DESTROYED); 
    558  
    559     /* No need to lock transaction.  
    560      * This function typically is called from the transaction callback, which 
    561      * means that transaction mutex is being held. 
    562      */ 
    563     pj_assert( pj_mutex_is_locked(tsx->mutex) ); 
    564  
    565     /* Lock endpoint. */ 
    566     pj_mutex_lock( endpt->tsx_table_mutex ); 
    567  
    568     /* Unregister from the hash table. */ 
    569     pj_hash_set( NULL, endpt->tsx_table, tsx->transaction_key.ptr,  
    570                  tsx->transaction_key.slen, NULL); 
    571  
    572     /* Unlock endpoint mutex. */ 
    573     pj_mutex_unlock( endpt->tsx_table_mutex ); 
    574  
    575     /* Destroy transaction mutex. */ 
    576     pj_mutex_destroy( tsx->mutex ); 
    577  
    578     /* Release the pool for the transaction. */ 
    579     pj_pool_release(tsx->pool); 
    580  
    581     PJ_LOG(4, (THIS_FILE, "tsx%p destroyed", tsx)); 
    582 } 
    583  
    584218 
    585219 
     
    644278    *p++ = SEPARATOR; 
    645279 
    646     /* Add Request-URI */ 
    647     /* This is BUG! 
    648      * Response doesn't have Request-URI! 
    649      * 
    650     len = req_uri->vptr->print( PJSIP_URI_IN_REQ_URI, req_uri, p, end-p ); 
    651     p += len; 
    652     *p++ = SEPARATOR; 
    653      */ 
    654  
    655280    /* Add method, except when method is INVITE or ACK. */ 
    656281    if (method->id != PJSIP_INVITE_METHOD && method->id != PJSIP_ACK_METHOD) { 
     
    771396} 
    772397 
    773  
    774 /* 
    775  * Create new transaction. 
    776  */ 
    777 PJ_DEF(pj_status_t) pjsip_tsx_create( pj_pool_t *pool, 
    778                                       pjsip_endpoint *endpt, 
    779                                       pjsip_transaction **p_tsx) 
    780 { 
     398/***************************************************************************** 
     399 ** 
     400 ** Transaction layer module 
     401 ** 
     402 ***************************************************************************** 
     403 
     404/* 
     405 * Create transaction layer module and registers it to the endpoint. 
     406 */ 
     407PJ_DEF(pj_status_t) pjsip_tsx_layer_init(pjsip_endpoint *endpt) 
     408{ 
     409    pj_pool_t *pool; 
     410    pj_status_t status; 
     411 
     412 
     413    PJ_ASSERT_RETURN(mod_tsx_layer.endpt==NULL, PJ_EINVALIDOP); 
     414 
     415 
     416    /* Initialize TLS ID for transaction lock. */ 
     417    status = pj_thread_local_alloc(&pjsip_tsx_lock_tls_id); 
     418    if (status != PJ_SUCCESS) 
     419        return status; 
     420 
     421    pj_thread_local_set(pjsip_tsx_lock_tls_id, NULL); 
     422 
     423    /* 
     424     * Initialize transaction layer structure. 
     425     */ 
     426 
     427    /* Create pool for the module. */ 
     428    pool = pjsip_endpt_create_pool(endpt, "tsxlayer",  
     429                                   PJSIP_POOL_TSX_LAYER_LEN, 
     430                                   PJSIP_POOL_TSX_LAYER_INC ); 
     431    if (!pool) 
     432        return PJ_ENOMEM; 
     433 
     434     
     435    /* Initialize some attributes. */ 
     436    mod_tsx_layer.pool = pool; 
     437    mod_tsx_layer.endpt = endpt; 
     438 
     439 
     440    /* Create hash table. */ 
     441    mod_tsx_layer.htable = pj_hash_create( pool, PJSIP_MAX_TSX_COUNT ); 
     442    if (!mod_tsx_layer.htable) { 
     443        pjsip_endpt_release_pool(endpt, pool); 
     444        return PJ_ENOMEM; 
     445    } 
     446 
     447    /* Create mutex. */ 
     448    status = pj_mutex_create_recursive(pool, "tsxlayer", &mod_tsx_layer.mutex); 
     449    if (status != PJ_SUCCESS) { 
     450        pjsip_endpt_release_pool(endpt, pool); 
     451        return status; 
     452    } 
     453 
     454    /* 
     455     * Register transaction layer module to endpoint. 
     456     */ 
     457    status = pjsip_endpt_register_module( endpt, &mod_tsx_layer.mod ); 
     458    if (status != PJ_SUCCESS) { 
     459        pj_mutex_destroy(mod_tsx_layer.mutex); 
     460        pjsip_endpt_release_pool(endpt, pool); 
     461        return status; 
     462    } 
     463 
     464    return PJ_SUCCESS; 
     465} 
     466 
     467 
     468/* 
     469 * Get the instance of transaction layer module. 
     470 */ 
     471PJ_DEF(pjsip_module*) pjsip_tsx_layer_instance(void) 
     472{ 
     473    return &mod_tsx_layer.mod; 
     474} 
     475 
     476 
     477/* 
     478 * Unregister and destroy transaction layer module. 
     479 */ 
     480PJ_DEF(pj_status_t) pjsip_tsx_layer_destroy(void) 
     481{ 
     482    /* Are we registered? */ 
     483    PJ_ASSERT_RETURN(mod_tsx_layer.endpt!=NULL, PJ_EINVALIDOP); 
     484 
     485    /* Unregister from endpoint.  
     486     * Clean-ups will be done in the unload() module callback. 
     487     */ 
     488    return pjsip_endpt_unregister_module( mod_tsx_layer.endpt,  
     489                                          &mod_tsx_layer.mod); 
     490} 
     491 
     492 
     493/* 
     494 * Register the transaction to the hash table. 
     495 */ 
     496static void mod_tsx_layer_register_tsx( pjsip_transaction *tsx) 
     497{ 
     498    pj_assert(tsx->transaction_key.slen != 0); 
     499    //pj_assert(tsx->state != PJSIP_TSX_STATE_NULL); 
     500 
     501    /* Lock hash table mutex. */ 
     502    pj_mutex_lock(mod_tsx_layer.mutex); 
     503 
     504    /* Register the transaction to the hash table. */ 
     505    pj_hash_set( tsx->pool, mod_tsx_layer.htable, tsx->transaction_key.ptr, 
     506                 tsx->transaction_key.slen, tsx); 
     507 
     508    /* Unlock mutex. */ 
     509    pj_mutex_unlock(mod_tsx_layer.mutex); 
     510} 
     511 
     512 
     513/* 
     514 * Unregister the transaction from the hash table. 
     515 */ 
     516static void mod_tsx_layer_unregister_tsx( pjsip_transaction *tsx) 
     517{ 
     518    pj_assert(tsx->transaction_key.slen != 0); 
     519    //pj_assert(tsx->state != PJSIP_TSX_STATE_NULL); 
     520 
     521    /* Lock hash table mutex. */ 
     522    pj_mutex_lock(mod_tsx_layer.mutex); 
     523 
     524    /* Register the transaction to the hash table. */ 
     525    pj_hash_set( NULL, mod_tsx_layer.htable, tsx->transaction_key.ptr, 
     526                 tsx->transaction_key.slen, NULL); 
     527 
     528    /* Unlock mutex. */ 
     529    pj_mutex_unlock(mod_tsx_layer.mutex); 
     530} 
     531 
     532 
     533/* 
     534 * Find a transaction. 
     535 */ 
     536PJ_DEF(pjsip_transaction*) pjsip_tsx_layer_find_tsx( const pj_str_t *key, 
     537                                                     pj_bool_t lock ) 
     538{ 
     539    pjsip_transaction *tsx; 
     540 
     541    pj_mutex_lock(mod_tsx_layer.mutex); 
     542    tsx = pj_hash_get( mod_tsx_layer.htable, key->ptr, key->slen ); 
     543    pj_mutex_unlock(mod_tsx_layer.mutex); 
     544 
     545 
     546    /* Race condition! 
     547     * Transaction may gets deleted before we have chance to lock it. 
     548     */ 
     549    PJ_TODO(FIX_RACE_CONDITION_HERE); 
     550    if (tsx && lock) 
     551        pj_mutex_lock(tsx->mutex); 
     552 
     553    return tsx; 
     554} 
     555 
     556 
     557/* This module callback is called when module is being loaded by 
     558 * endpoint. It does nothing for this module. 
     559 */ 
     560static pj_status_t mod_tsx_layer_load(pjsip_endpoint *endpt) 
     561{ 
     562    PJ_UNUSED_ARG(endpt); 
     563    return PJ_SUCCESS; 
     564} 
     565 
     566 
     567/* This module callback is called when module is being started by 
     568 * endpoint. It does nothing for this module. 
     569 */ 
     570static pj_status_t mod_tsx_layer_start(void) 
     571{ 
     572    return PJ_SUCCESS; 
     573} 
     574 
     575 
     576/* This module callback is called when module is being stopped by 
     577 * endpoint.  
     578 */ 
     579static pj_status_t mod_tsx_layer_stop(void) 
     580{ 
     581    pj_hash_iterator_t it_buf, *it; 
     582 
     583    pj_mutex_lock(mod_tsx_layer.mutex); 
     584 
     585    /* Destroy all transactions. */ 
     586    it = pj_hash_first(mod_tsx_layer.htable, &it_buf); 
     587    while (it) { 
     588        pjsip_transaction *tsx = pj_hash_this(mod_tsx_layer.htable, it); 
     589        if (tsx) 
     590            tsx_destroy(tsx); 
     591        it = pj_hash_next(mod_tsx_layer.htable, it); 
     592    } 
     593 
     594    pj_mutex_unlock(mod_tsx_layer.mutex); 
     595    return PJ_SUCCESS; 
     596} 
     597 
     598 
     599/* This module callback is called when module is being unloaded by 
     600 * endpoint. 
     601 */ 
     602static pj_status_t mod_tsx_layer_unload(void) 
     603{ 
     604    /* Destroy mutex. */ 
     605    pj_mutex_destroy(mod_tsx_layer.mutex); 
     606 
     607    /* Release pool. */ 
     608    pjsip_endpt_release_pool(mod_tsx_layer.endpt, mod_tsx_layer.pool); 
     609 
     610    /* Mark as unregistered. */ 
     611    mod_tsx_layer.endpt = NULL; 
     612 
     613    return PJ_SUCCESS; 
     614} 
     615 
     616 
     617/* This module callback is called when endpoint has received an 
     618 * incoming request message. 
     619 */ 
     620static pj_bool_t mod_tsx_layer_on_rx_request(pjsip_rx_data *rdata) 
     621{ 
     622    pj_str_t key; 
     623    pjsip_transaction *tsx; 
     624 
     625    pjsip_tsx_create_key(rdata->tp_info.pool, &key, PJSIP_ROLE_UAS, 
     626                         &rdata->msg_info.cseq->method, rdata); 
     627 
     628    /* Find transaction. */ 
     629    pj_mutex_lock( mod_tsx_layer.mutex ); 
     630    tsx = pj_hash_get( mod_tsx_layer.htable, key.ptr, key.slen ); 
     631    if (tsx == NULL || tsx->state == PJSIP_TSX_STATE_TERMINATED) { 
     632        /* Transaction not found. 
     633         * Reject the request so that endpoint passes the request to 
     634         * upper layer modules. 
     635         */ 
     636        pj_mutex_unlock( mod_tsx_layer.mutex); 
     637        return PJ_FALSE; 
     638    } 
     639 
     640    /* Unlock hash table. */ 
     641    pj_mutex_unlock( mod_tsx_layer.mutex ); 
     642 
     643    /* Race condition! 
     644     * Transaction may gets deleted before we have chance to lock it 
     645     * in tsx_on_rx_msg(). 
     646     */ 
     647    PJ_TODO(FIX_RACE_CONDITION_HERE); 
     648 
     649    /* Pass the message to the transaction. */ 
     650    tsx_on_rx_msg(tsx, rdata ); 
     651 
     652    return PJ_TRUE; 
     653} 
     654 
     655 
     656/* This module callback is called when endpoint has received an 
     657 * incoming response message. 
     658 */ 
     659static pj_bool_t mod_tsx_layer_on_rx_response(pjsip_rx_data *rdata) 
     660{ 
     661    pj_str_t key; 
     662    pjsip_transaction *tsx; 
     663 
     664    pjsip_tsx_create_key(rdata->tp_info.pool, &key, PJSIP_ROLE_UAC, 
     665                         &rdata->msg_info.cseq->method, rdata); 
     666 
     667    /* Find transaction. */ 
     668    pj_mutex_lock( mod_tsx_layer.mutex ); 
     669    tsx = pj_hash_get( mod_tsx_layer.htable, key.ptr, key.slen ); 
     670    if (tsx == NULL || tsx->state == PJSIP_TSX_STATE_TERMINATED) { 
     671        /* Transaction not found. 
     672         * Reject the request so that endpoint passes the request to 
     673         * upper layer modules. 
     674         */ 
     675        pj_mutex_unlock( mod_tsx_layer.mutex); 
     676        return PJ_FALSE; 
     677    } 
     678 
     679    /* Unlock hash table. */ 
     680    pj_mutex_unlock( mod_tsx_layer.mutex ); 
     681 
     682    /* Race condition! 
     683     * Transaction may gets deleted before we have chance to lock it 
     684     * in tsx_on_rx_msg(). 
     685     */ 
     686    PJ_TODO(FIX_RACE_CONDITION_HERE); 
     687 
     688    /* Pass the message to the transaction. */ 
     689    tsx_on_rx_msg(tsx, rdata ); 
     690 
     691    return PJ_TRUE; 
     692} 
     693 
     694 
     695/* 
     696 * Get transaction instance in the rdata. 
     697 */ 
     698PJ_DEF(pjsip_transaction*) pjsip_rdata_get_tsx( pjsip_rx_data *rdata ) 
     699{ 
     700    return rdata->endpt_info.mod_data[mod_tsx_layer.mod.id]; 
     701} 
     702 
     703 
     704/***************************************************************************** 
     705 ** 
     706 ** Transaction 
     707 ** 
     708 ***************************************************************************** 
     709 
     710/* 
     711 * Lock transaction and set the value of Thread Local Storage. 
     712 */ 
     713static void lock_tsx(pjsip_transaction *tsx, struct tsx_lock_data *lck) 
     714{ 
     715    struct tsx_lock_data *prev_data; 
     716 
     717    pj_mutex_lock(tsx->mutex); 
     718    prev_data = (struct tsx_lock_data *)  
     719                    pj_thread_local_get(pjsip_tsx_lock_tls_id); 
     720    lck->prev = prev_data; 
     721    lck->tsx = tsx; 
     722    lck->is_alive = 1; 
     723    pj_thread_local_set(pjsip_tsx_lock_tls_id, lck); 
     724} 
     725 
     726 
     727/* 
     728 * Unlock transaction. 
     729 * This will selectively unlock the mutex ONLY IF the transaction has not been  
     730 * destroyed. The function knows whether the transaction has been destroyed 
     731 * because when transaction is destroyed the is_alive flag for the transaction 
     732 * will be set to zero. 
     733 */ 
     734static pj_status_t unlock_tsx( pjsip_transaction *tsx,  
     735                               struct tsx_lock_data *lck) 
     736{ 
     737    pj_assert( (void*)pj_thread_local_get(pjsip_tsx_lock_tls_id) == lck); 
     738    pj_assert( lck->tsx == tsx ); 
     739    pj_thread_local_set(pjsip_tsx_lock_tls_id, lck->prev); 
     740    if (lck->is_alive) 
     741        pj_mutex_unlock(tsx->mutex); 
     742 
     743    return lck->is_alive ? PJ_SUCCESS : PJSIP_ETSXDESTROYED; 
     744} 
     745 
     746 
     747/* Create and initialize basic transaction structure. 
     748 * This function is called by both UAC and UAS creation. 
     749 */ 
     750static pj_status_t tsx_create( pjsip_module *tsx_user, 
     751                               pjsip_transaction **p_tsx) 
     752{ 
     753    pj_pool_t *pool; 
    781754    pjsip_transaction *tsx; 
    782755    pj_status_t status; 
    783756 
    784     tsx = pj_pool_calloc(pool, 1, sizeof(pjsip_transaction)); 
    785  
     757    pool = pjsip_endpt_create_pool( mod_tsx_layer.endpt, "tsx",  
     758                                    PJSIP_POOL_TSX_LEN, PJSIP_POOL_TSX_INC ); 
     759    if (!pool) 
     760        return PJ_ENOMEM; 
     761 
     762    tsx = pj_pool_zalloc(pool, sizeof(pjsip_transaction)); 
    786763    tsx->pool = pool; 
    787     tsx->endpt = endpt; 
     764    tsx->tsx_user = tsx_user; 
     765    tsx->endpt = mod_tsx_layer.endpt; 
     766 
     767    pj_sprintf(tsx->obj_name, "tsx%p", tsx); 
     768 
     769    tsx->handle_200resp = 1; 
    788770    tsx->retransmit_timer.id = TSX_TIMER_RETRANSMISSION; 
    789771    tsx->retransmit_timer._timer_id = -1; 
     
    794776    tsx->timeout_timer.user_data = tsx; 
    795777    tsx->timeout_timer.cb = &tsx_timer_callback; 
    796     pj_sprintf(tsx->obj_name, "tsx%p", tsx); 
    797     status = pj_mutex_create_recursive(pool, "mtsx%p", &tsx->mutex); 
     778     
     779    status = pj_mutex_create_recursive(pool, "tsx%p", &tsx->mutex); 
    798780    if (status != PJ_SUCCESS) { 
     781        pjsip_endpt_release_pool(mod_tsx_layer.endpt, pool); 
    799782        return status; 
    800783    } 
     
    804787} 
    805788 
    806 /* 
    807  * Lock transaction and set the value of Thread Local Storage. 
    808  */ 
    809 static void lock_tsx(pjsip_transaction *tsx, struct tsx_lock_data *lck) 
    810 { 
    811     struct tsx_lock_data *prev_data; 
    812  
    813     pj_mutex_lock(tsx->mutex); 
    814     prev_data = (struct tsx_lock_data *)  
    815                     pj_thread_local_get(pjsip_tsx_lock_tls_id); 
    816     lck->prev = prev_data; 
    817     lck->tsx = tsx; 
    818     lck->is_alive = 1; 
    819     pj_thread_local_set(pjsip_tsx_lock_tls_id, lck); 
    820 } 
    821  
    822  
    823 /* 
    824  * Unlock transaction. 
    825  * This will selectively unlock the mutex ONLY IF the transaction has not been  
    826  * destroyed. The function knows whether the transaction has been destroyed 
    827  * because when transaction is destroyed the is_alive flag for the transaction 
    828  * will be set to zero. 
    829  */ 
    830 static pj_status_t unlock_tsx( pjsip_transaction *tsx,  
    831                                struct tsx_lock_data *lck) 
    832 { 
    833     pj_assert( (void*)pj_thread_local_get(pjsip_tsx_lock_tls_id) == lck); 
    834     pj_assert( lck->tsx == tsx ); 
    835     pj_thread_local_set(pjsip_tsx_lock_tls_id, lck->prev); 
    836     if (lck->is_alive) 
    837         pj_mutex_unlock(tsx->mutex); 
    838  
    839     return lck->is_alive ? PJ_SUCCESS : PJSIP_ETSXDESTROYED; 
    840 } 
     789 
     790/* Destroy transaction. */ 
     791static void tsx_destroy( pjsip_transaction *tsx ) 
     792{ 
     793    pj_mutex_destroy(tsx->mutex); 
     794    pjsip_endpt_release_pool(tsx->endpt, tsx->pool); 
     795} 
     796 
     797 
     798/* 
     799 * Callback when timer expires. 
     800 */ 
     801static void tsx_timer_callback( pj_timer_heap_t *theap, pj_timer_entry *entry) 
     802{ 
     803    pjsip_event event; 
     804    pjsip_transaction *tsx = entry->user_data; 
     805    struct tsx_lock_data lck; 
     806 
     807    PJ_UNUSED_ARG(theap); 
     808 
     809    PJ_LOG(5,(tsx->obj_name, "got timer event (%s timer)",  
     810             (entry->id==TSX_TIMER_RETRANSMISSION ? "Retransmit":"Timeout"))); 
     811 
     812 
     813    if (entry->id == TSX_TIMER_RETRANSMISSION) { 
     814        PJSIP_EVENT_INIT_TIMER(event, &tsx->retransmit_timer); 
     815    } else { 
     816        PJSIP_EVENT_INIT_TIMER(event, &tsx->timeout_timer); 
     817    } 
     818 
     819    /* Dispatch event to transaction. */ 
     820    lock_tsx(tsx, &lck); 
     821    (*tsx->state_handler)(tsx, &event); 
     822    unlock_tsx(tsx, &lck); 
     823} 
     824 
    841825 
    842826/* 
     
    848832                           void *event_src ) 
    849833{ 
    850     pjsip_event e; 
    851  
    852834    PJ_LOG(4, (tsx->obj_name, "STATE %s-->%s, cause = %s", 
    853835               state_str[tsx->state], state_str[state],  
     
    865847 
    866848    /* Inform TU */ 
    867     PJSIP_EVENT_INIT_TSX_STATE(e, tsx, event_src_type, event_src); 
    868     pjsip_endpt_send_tsx_event( tsx->endpt, &e  ); 
     849    if (tsx->tsx_user && tsx->tsx_user->on_tsx_state) { 
     850        pjsip_event e; 
     851        PJSIP_EVENT_INIT_TSX_STATE(e, tsx, event_src_type, event_src); 
     852        (*tsx->tsx_user->on_tsx_state)(tsx, &e); 
     853    } 
     854     
    869855 
    870856    /* When the transaction is terminated, release transport, and free the 
     
    872858     */ 
    873859    if (state == PJSIP_TSX_STATE_TERMINATED) { 
     860        pj_time_val timeout = {0, 0}; 
    874861 
    875862        /* Decrement transport reference counter. */ 
    876         if (tsx->transport &&  
    877             tsx->transport_state == PJSIP_TSX_TRANSPORT_STATE_FINAL)  
    878         { 
     863        if (tsx->transport) { 
    879864            pjsip_transport_dec_ref( tsx->transport ); 
    880865            tsx->transport = NULL; 
     
    896881        } 
    897882 
    898         /* If transport is not pending, reschedule timeout timer to 
    899          * destroy this transaction. 
    900          */ 
    901         if (tsx->transport_state == PJSIP_TSX_TRANSPORT_STATE_FINAL) { 
    902             pj_time_val timeout = {0, 0}; 
     883        /* Reschedule timeout timer to destroy this transaction. */ 
     884        if (tsx->transport_flag & TSX_HAS_PENDING_TRANSPORT) { 
     885            tsx->transport_flag |= TSX_HAS_PENDING_DESTROY; 
     886        } else { 
    903887            pjsip_endpt_schedule_timer( tsx->endpt, &tsx->timeout_timer,  
    904888                                        &timeout); 
    905889        } 
     890 
    906891 
    907892    } else if (state == PJSIP_TSX_STATE_DESTROYED) { 
     
    915900            lck = lck->prev; 
    916901        } 
    917     } 
    918 } 
    919  
    920 /* 
    921  * Look-up destination address and select which transport to be used to send 
    922  * the request message. The procedure used here follows the guidelines on  
    923  * sending the request in RFC3261 chapter 8.1.2. 
    924  * 
    925  * This function also modifies the message (request line and Route headers) 
    926  * accordingly. 
    927  */ 
    928 static pj_status_t tsx_process_route( pjsip_transaction *tsx, 
    929                                       pjsip_tx_data *tdata, 
    930                                       pjsip_host_info *send_addr ) 
    931 { 
    932     pjsip_route_hdr *route_hdr; 
    933      
    934     pj_assert(tdata->msg->type == PJSIP_REQUEST_MSG); 
    935  
    936     /* Get the first "Route" header from the message. If the message doesn't 
    937      * have any "Route" headers but the endpoint has, then copy the "Route" 
    938      * headers from the endpoint first. 
    939      */ 
    940     route_hdr = pjsip_msg_find_hdr(tdata->msg, PJSIP_H_ROUTE, NULL); 
    941     if (!route_hdr) { 
    942         const pjsip_route_hdr *hdr_list; 
    943         const pjsip_route_hdr *hdr; 
    944         hdr_list = (const pjsip_route_hdr*)pjsip_endpt_get_routing(tsx->endpt); 
    945         hdr = hdr_list->next; 
    946         while (hdr != hdr_list { 
    947             route_hdr = pjsip_hdr_shallow_clone(tdata->pool, hdr); 
    948             pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)route_hdr); 
    949             hdr = hdr->next; 
    950         } 
    951     } 
    952  
    953     return pjsip_get_request_addr(tdata, send_addr);   
    954 } 
    955  
    956  
    957 /* 
    958  * Callback from the transport job. 
    959  * This callback is called when asychronous transport connect() operation 
    960  * has completed, with or without error. 
    961  */ 
    962 static void tsx_transport_callback(pjsip_transport *tr,  
    963                                    void *token,  
    964                                    pj_status_t status) 
    965 { 
    966     char addr[PJ_MAX_HOSTNAME]; 
    967     pjsip_transaction *tsx = token; 
    968     struct tsx_lock_data lck; 
    969  
    970     pj_memcpy(addr, tsx->dest_name.addr.host.ptr, tsx->dest_name.addr.host.slen); 
    971     addr[tsx->dest_name.addr.host.slen] = '\0'; 
    972  
    973  
    974     if (status == PJ_SUCCESS) { 
    975         PJ_LOG(4, (tsx->obj_name, "%s connected to %s:%d", 
    976                                   tr->type_name, 
    977                                   addr, tsx->dest_name.addr.port)); 
    978     } else { 
    979         PJ_LOG(4, (tsx->obj_name, "%s unable to connect to %s:%d, status=%d",  
    980                                   tr->type_name, 
    981                                   addr, tsx->dest_name.addr.port, status)); 
    982     } 
    983  
    984     /* Lock transaction. */ 
    985     lock_tsx(tsx, &lck); 
    986  
    987     if (status != PJ_SUCCESS) { 
    988         tsx->transport_state = PJSIP_TSX_TRANSPORT_STATE_FINAL; 
    989         tsx->status_code = PJSIP_SC_TSX_TRANSPORT_ERROR; 
    990  
    991         tsx_set_state(tsx, PJSIP_TSX_STATE_TERMINATED, 
    992                       PJSIP_EVENT_TRANSPORT_ERROR, (void*)status); 
    993  
    994         /* Unlock transaction. */ 
    995         unlock_tsx(tsx, &lck); 
    996         return; 
    997     } 
    998  
    999     /* See if transaction has already been terminated.  
    1000      * If so, schedule to destroy the transaction. 
    1001      */ 
    1002     if (tsx->state == PJSIP_TSX_STATE_TERMINATED) { 
    1003         pj_time_val timeout = {0, 0}; 
    1004         pjsip_endpt_schedule_timer( tsx->endpt, &tsx->timeout_timer,  
    1005                                     &timeout); 
    1006  
    1007         /* Unlock transaction. */ 
    1008         unlock_tsx(tsx, &lck); 
    1009         return; 
    1010     } 
    1011  
    1012     /* Add reference counter to the transport. */ 
    1013     pjsip_transport_add_ref(tr); 
    1014  
    1015     /* Mark transport as ready. */ 
    1016     tsx->transport_state = PJSIP_TSX_TRANSPORT_STATE_FINAL; 
    1017     tsx->transport = tr; 
    1018  
    1019     /* If there's a pending message to send, send it now. */ 
    1020     if (tsx->has_unsent_msg) { 
    1021         tsx_send_msg( tsx, tsx->last_tx ); 
    1022     } 
    1023  
    1024     /* Unlock transaction. */ 
    1025     unlock_tsx(tsx, &lck); 
    1026 } 
    1027  
    1028 /* 
    1029  * Callback from the resolver job. 
    1030  */ 
    1031 static void tsx_resolver_callback(pj_status_t status, 
    1032                                   void *token, 
    1033                                   const struct pjsip_server_addresses *addr) 
    1034 { 
    1035     pjsip_transaction *tsx = token; 
    1036     struct tsx_lock_data lck; 
    1037     pjsip_transport *tp; 
    1038  
    1039     PJ_LOG(4, (tsx->obj_name, "resolver job complete, status=%d", status)); 
    1040  
    1041     if (status != PJ_SUCCESS || addr->count == 0) { 
    1042         lock_tsx(tsx, &lck); 
    1043         tsx->status_code = PJSIP_SC_TSX_RESOLVE_ERROR; 
    1044         tsx_set_state(tsx, PJSIP_TSX_STATE_TERMINATED,  
    1045                       PJSIP_EVENT_TRANSPORT_ERROR, (void*)status); 
    1046         unlock_tsx(tsx, &lck); 
    1047         return; 
    1048     } 
    1049  
    1050     /* Lock transaction. */ 
    1051     lock_tsx(tsx, &lck); 
    1052  
    1053     /* Copy server addresses. */ 
    1054     pj_memcpy(&tsx->remote_addr, addr, sizeof(*addr)); 
    1055  
    1056     /* Create/find the transport for the remote address. */ 
    1057     tsx->transport_state = PJSIP_TSX_TRANSPORT_STATE_CONNECTING; 
    1058     status = pjsip_endpt_alloc_transport( tsx->endpt, addr->entry[0].type, 
    1059                                           &addr->entry[0].addr, 
    1060                                           addr->entry[0].addr_len, 
    1061                                           &tp); 
    1062     tsx_transport_callback(tp, tsx, status); 
    1063  
    1064     /* Unlock transaction */ 
    1065     unlock_tsx(tsx, &lck); 
    1066  
    1067     /* There should be nothing to do after this point. 
    1068      * Execution for the transaction will resume when the callback for the  
    1069      * transport is called. 
    1070      */ 
    1071 } 
    1072  
    1073 /* 
    1074  * Initialize the transaction as UAC transaction. 
    1075  */ 
    1076 PJ_DEF(pj_status_t) pjsip_tsx_init_uac( pjsip_transaction *tsx,  
    1077                                         pjsip_tx_data *tdata) 
    1078 { 
     902 
     903        /* Unregister transaction. */ 
     904        mod_tsx_layer_unregister_tsx(tsx); 
     905 
     906        /* Destroy transaction. */ 
     907        tsx_destroy(tsx); 
     908    } 
     909} 
     910 
     911 
     912/* 
     913 * Create, initialize, and register UAC transaction. 
     914 */ 
     915PJ_DEF(pj_status_t) pjsip_tsx_create_uac( pjsip_module *tsx_user, 
     916                                          pjsip_tx_data *tdata, 
     917                                          pjsip_transaction **p_tsx) 
     918{ 
     919    pjsip_transaction *tsx; 
    1079920    pjsip_msg *msg; 
    1080921    pjsip_cseq_hdr *cseq; 
    1081922    pjsip_via_hdr *via; 
     923    struct tsx_lock_data lck; 
    1082924    pj_status_t status; 
    1083     struct tsx_lock_data lck; 
    1084  
    1085     PJ_LOG(4,(tsx->obj_name, "initializing tsx as UAC (tdata=%p)", tdata)); 
     925 
     926    PJ_ASSERT_RETURN(tdata!=NULL && p_tsx!=NULL, PJ_EINVAL); 
     927 
     928    /* Keep shortcut */ 
     929    msg = tdata->msg; 
     930 
     931    /* Make sure CSeq header is present. */ 
     932    cseq = pjsip_msg_find_hdr(msg, PJSIP_H_CSEQ, NULL); 
     933    if (!cseq) { 
     934        pj_assert(!"CSeq header not present in outgoing message!"); 
     935        return PJSIP_EMISSINGHDR; 
     936    } 
     937 
     938 
     939    /* Create transaction instance. */ 
     940    status = tsx_create( tsx_user, &tsx); 
     941    if (status != PJ_SUCCESS) 
     942        return status; 
     943 
    1086944 
    1087945    /* Lock transaction. */ 
    1088946    lock_tsx(tsx, &lck); 
    1089947 
    1090     /* Keep shortcut */ 
    1091     msg = tdata->msg; 
    1092  
    1093948    /* Role is UAC. */ 
    1094949    tsx->role = PJSIP_ROLE_UAC; 
     
    1096951    /* Save method. */ 
    1097952    pjsip_method_copy( tsx->pool, &tsx->method, &msg->line.req.method); 
     953 
     954    /* Save CSeq. */ 
     955    tsx->cseq = cseq->cseq; 
    1098956 
    1099957    /* Generate Via header if it doesn't exist. */ 
     
    1104962    } 
    1105963 
     964    /* Generate branch parameter if it doesn't exist. */ 
    1106965    if (via->branch_param.slen == 0) { 
    1107966        pj_str_t tmp; 
     
    1116975        /* Save branch parameter. */ 
    1117976        tsx->branch = via->branch_param; 
     977 
    1118978    } else { 
    1119979        /* Copy branch parameter. */ 
     
    1121981    } 
    1122982 
    1123  
    1124     /* Generate transaction key. */ 
    1125     status = create_tsx_key_3261( tsx->pool, &tsx->transaction_key, 
    1126                                   PJSIP_ROLE_UAC, &tsx->method,  
    1127                                   &via->branch_param); 
    1128     if (status != PJ_SUCCESS) { 
    1129         unlock_tsx(tsx, &lck); 
    1130         return status; 
    1131     } 
     983   /* Generate transaction key. */ 
     984    create_tsx_key_3261( tsx->pool, &tsx->transaction_key, 
     985                         PJSIP_ROLE_UAC, &tsx->method,  
     986                         &via->branch_param); 
    1132987 
    1133988    PJ_LOG(6, (tsx->obj_name, "tsx_key=%.*s", tsx->transaction_key.slen, 
    1134989               tsx->transaction_key.ptr)); 
    1135  
    1136     /* Save CSeq. */ 
    1137     cseq = pjsip_msg_find_hdr(msg, PJSIP_H_CSEQ, NULL); 
    1138     if (!cseq) { 
    1139         pj_assert(!"CSeq header not present in outgoing message!"); 
    1140         unlock_tsx(tsx, &lck); 
    1141         return PJSIP_EMISSINGHDR; 
    1142     } 
    1143     tsx->cseq = cseq->cseq; 
    1144  
    1145990 
    1146991    /* Begin with State_Null. 
     
    1148993     */ 
    1149994    tsx->state = PJSIP_TSX_STATE_NULL; 
    1150     tsx->state_handler = &pjsip_tsx_on_state_null; 
    1151  
    1152     /* Get destination name from the message. */ 
    1153     status = tsx_process_route(tsx, tdata, &tsx->dest_name); 
    1154     if (status != PJ_SUCCESS) { 
    1155         tsx->transport_state = PJSIP_TSX_TRANSPORT_STATE_FINAL; 
    1156         tsx->status_code = PJSIP_SC_TSX_TRANSPORT_ERROR; 
    1157         tsx_set_state(tsx, PJSIP_TSX_STATE_TERMINATED,  
    1158                       PJSIP_EVENT_TRANSPORT_ERROR, (void*)status); 
    1159         unlock_tsx(tsx, &lck); 
    1160         return status; 
    1161     } 
    1162  
    1163     /* Resolve destination. 
    1164      * This will start asynchronous resolver job, and when it finishes,  
    1165      * the callback will be called. 
    1166      */ 
    1167     PJ_LOG(5,(tsx->obj_name, "tsx resolving destination %.*s:%d", 
    1168                              tsx->dest_name.addr.host.slen,  
    1169                              tsx->dest_name.addr.host.ptr, 
    1170                              tsx->dest_name.addr.port)); 
    1171  
    1172     tsx->transport_state = PJSIP_TSX_TRANSPORT_STATE_RESOLVING; 
    1173     pjsip_endpt_resolve( tsx->endpt, tsx->pool, &tsx->dest_name,  
    1174                          tsx, &tsx_resolver_callback); 
    1175  
    1176     /* There should be nothing to do after this point.  
    1177      * Execution for the transaction will resume when the resolver callback is 
    1178      * called. 
    1179      */ 
    1180  
    1181     /* Unlock transaction and return. 
    1182      * If transaction has been destroyed WITHIN the current thread, the  
    1183      * unlock_tsx() function will return -1. 
    1184      */ 
    1185     return unlock_tsx(tsx, &lck); 
    1186 } 
    1187  
    1188  
    1189 /* 
    1190  * Initialize the transaction as UAS transaction. 
    1191  */ 
    1192 PJ_DEF(pj_status_t) pjsip_tsx_init_uas( pjsip_transaction *tsx,  
    1193                                         pjsip_rx_data *rdata) 
    1194 { 
    1195     pjsip_msg *msg = rdata->msg_info.msg; 
     995    tsx->state_handler = &tsx_on_state_null; 
     996 
     997    /* Save the message. */ 
     998    tsx->last_tx = tdata; 
     999    pjsip_tx_data_add_ref(tsx->last_tx); 
     1000 
     1001 
     1002    /* Register transaction to hash table. */ 
     1003    mod_tsx_layer_register_tsx(tsx); 
     1004 
     1005 
     1006    /* Unlock transaction and return. */ 
     1007    unlock_tsx(tsx, &lck); 
     1008 
     1009    *p_tsx = tsx; 
     1010    return PJ_SUCCESS; 
     1011} 
     1012 
     1013 
     1014/* 
     1015 * Create, initialize, and register UAS transaction. 
     1016 */ 
     1017PJ_DEF(pj_status_t) pjsip_tsx_create_uas( pjsip_module *tsx_user, 
     1018                                          pjsip_rx_data *rdata, 
     1019                                          pjsip_transaction **p_tsx) 
     1020{ 
     1021    pjsip_transaction *tsx; 
     1022    pjsip_msg *msg; 
    11961023    pj_str_t *branch; 
    11971024    pjsip_cseq_hdr *cseq; 
     
    11991026    struct tsx_lock_data lck; 
    12001027 
    1201     PJ_LOG(4,(tsx->obj_name, "initializing tsx as UAS (rdata=%p)", rdata)); 
     1028    PJ_ASSERT_RETURN(rdata!=NULL && p_tsx!=NULL, PJ_EINVAL); 
     1029 
     1030    /* Keep shortcut to message */ 
     1031    msg = rdata->msg_info.msg; 
     1032     
     1033    /* Make sure this is a request message. */ 
     1034    PJ_ASSERT_RETURN(msg->type == PJSIP_REQUEST_MSG, PJSIP_ENOTREQUESTMSG); 
     1035 
     1036    /* Make sure CSeq header is present. */ 
     1037    cseq = rdata->msg_info.cseq; 
     1038    if (!cseq) 
     1039        return PJSIP_EMISSINGHDR; 
     1040 
     1041    /* Make sure Via header is present. */ 
     1042    if (rdata->msg_info.via == NULL) 
     1043        return PJSIP_EMISSINGHDR; 
     1044 
     1045 
     1046    /*  
     1047     * Create transaction instance.  
     1048     */ 
     1049    status = tsx_create( tsx_user, &tsx); 
     1050    if (status != PJ_SUCCESS) 
     1051        return status; 
     1052 
    12021053 
    12031054    /* Lock transaction. */ 
    12041055    lock_tsx(tsx, &lck); 
    12051056 
    1206     /* Keep shortcut to message */ 
    1207     msg = rdata->msg_info.msg; 
    1208  
    12091057    /* Role is UAS */ 
    12101058    tsx->role = PJSIP_ROLE_UAS; 
     
    12121060    /* Save method. */ 
    12131061    pjsip_method_copy( tsx->pool, &tsx->method, &msg->line.req.method); 
     1062 
     1063    /* Save CSeq */ 
     1064    tsx->cseq = cseq->cseq; 
    12141065 
    12151066    /* Get transaction key either from branch for RFC3261 message, or 
     
    12191070                                  PJSIP_ROLE_UAS, &tsx->method, rdata); 
    12201071    if (status != PJ_SUCCESS) { 
    1221         unlock_tsx(tsx, &lck); 
     1072        tsx_destroy(tsx); 
    12221073        return status; 
    12231074    } 
     
    12301081               tsx->transaction_key.ptr)); 
    12311082 
    1232     /* Save CSeq */ 
    1233     cseq = rdata->msg_info.cseq; 
    1234     tsx->cseq = cseq->cseq; 
    1235  
    1236     /* Begin with state NULL 
     1083 
     1084    /* Begin with state TRYING. 
    12371085     * Manually set-up the state becase we don't want to call the callback. 
    12381086     */ 
    1239     tsx->state = PJSIP_TSX_STATE_NULL;  
    1240     tsx->state_handler = &pjsip_tsx_on_state_null; 
    1241  
    1242     /* Get the transport to send the response.  
    1243      * According to section 18.2.2 of RFC3261, if the transport is reliable 
    1244      * then the response must be sent using that transport. 
     1087    tsx->state = PJSIP_TSX_STATE_TRYING;  
     1088    tsx->state_handler = &tsx_on_state_trying; 
     1089 
     1090    /* Get response address. */ 
     1091    status = pjsip_get_response_addr( tsx->pool, rdata, &tsx->res_addr ); 
     1092    if (status != PJ_SUCCESS) { 
     1093        tsx_destroy(tsx); 
     1094        return status; 
     1095    } 
     1096 
     1097    /* If it's decided that we should use current transport, keep the 
     1098     * transport. 
    12451099     */ 
    1246     /* In addition, RFC 3581 says, if Via has "rport" parameter specified, 
    1247      * then return the response using the same transport. 
    1248      */ 
    1249     if (PJSIP_TRANSPORT_IS_RELIABLE(rdata->tp_info.transport) ||  
    1250         rdata->msg_info.via->rport_param >= 0)  
    1251     { 
    1252         tsx->transport = rdata->tp_info.transport; 
     1100    if (tsx->res_addr.transport) { 
     1101        tsx->transport = tsx->res_addr.transport; 
    12531102        pjsip_transport_add_ref(tsx->transport); 
    1254         tsx->transport_state = PJSIP_TSX_TRANSPORT_STATE_FINAL; 
    1255  
    1256         tsx->current_addr = 0; 
    1257         tsx->remote_addr.count = 1; 
    1258         tsx->remote_addr.entry[0].type = tsx->transport->key.type; 
    1259         pj_memcpy(&tsx->remote_addr.entry[0].addr,  
    1260                   &rdata->pkt_info.src_addr, rdata->pkt_info.src_addr_len); 
    1261          
    1262     } else { 
    1263         pj_status_t status; 
    1264  
    1265         status = pjsip_get_response_addr(tsx->pool, rdata->tp_info.transport, 
    1266                                          rdata->msg_info.via, &tsx->dest_name); 
    1267         if (status != PJ_SUCCESS) { 
    1268             tsx->transport_state = PJSIP_TSX_TRANSPORT_STATE_FINAL; 
    1269             tsx->status_code = PJSIP_SC_TSX_TRANSPORT_ERROR; 
    1270             tsx_set_state(tsx, PJSIP_TSX_STATE_TERMINATED,  
    1271                           PJSIP_EVENT_TRANSPORT_ERROR, (void*)status); 
    1272             unlock_tsx(tsx, &lck); 
    1273             return status; 
    1274         } 
    1275  
    1276         /* Resolve destination. 
    1277          * This will start asynchronous resolver job, and when it finishes,  
    1278          * the callback will be called. 
    1279          */ 
    1280         PJ_LOG(5,(tsx->obj_name, "tsx resolving destination %.*s:%d", 
    1281                                  tsx->dest_name.addr.host.slen,  
    1282                                  tsx->dest_name.addr.host.ptr, 
    1283                                  tsx->dest_name.addr.port)); 
    1284  
    1285         tsx->transport_state = PJSIP_TSX_TRANSPORT_STATE_RESOLVING; 
    1286         pjsip_endpt_resolve( tsx->endpt, tsx->pool, &tsx->dest_name,  
    1287                              tsx, &tsx_resolver_callback); 
    1288     } 
    1289      
    1290     /* There should be nothing to do after this point.  
    1291      * Execution for the transaction will resume when the resolver callback is 
    1292      * called. 
    1293      */ 
    1294  
    1295     /* Unlock transaction and return. 
    1296      * If transaction has been destroyed WITHIN the current thread, the  
    1297      * unlock_tsx() function will return -1. 
    1298      */ 
    1299     return unlock_tsx(tsx, &lck); 
    1300 } 
    1301  
    1302 /* 
    1303  * Callback when timer expires. 
    1304  */ 
    1305 static void tsx_timer_callback( pj_timer_heap_t *theap, pj_timer_entry *entry) 
    1306 { 
    1307     pjsip_event event; 
    1308     pjsip_transaction *tsx = entry->user_data; 
     1103        pj_memcpy(&tsx->addr, &tsx->res_addr.addr, tsx->res_addr.addr_len); 
     1104        tsx->addr_len = tsx->res_addr.addr_len; 
     1105    } 
     1106 
     1107 
     1108    /* Register the transaction. */ 
     1109    mod_tsx_layer_register_tsx(tsx); 
     1110 
     1111 
     1112    /* Unlock transaction and return. */ 
     1113    unlock_tsx(tsx, &lck); 
     1114 
     1115    *p_tsx = tsx; 
     1116    return PJ_SUCCESS; 
     1117} 
     1118 
     1119 
     1120/* 
     1121 * Forcely terminate transaction. 
     1122 */ 
     1123PJ_DEF(pj_status_t) pjsip_tsx_terminate( pjsip_transaction *tsx, int code ) 
     1124{ 
    13091125    struct tsx_lock_data lck; 
    13101126 
    1311     PJ_UNUSED_ARG(theap); 
    1312  
    1313     PJ_LOG(5,(tsx->obj_name, "got timer event (%s timer)",  
    1314              (entry->id==TSX_TIMER_RETRANSMISSION ? "Retransmit" : "Timeout"))); 
    1315  
    1316  
    1317     if (entry->id == TSX_TIMER_RETRANSMISSION) { 
    1318         PJSIP_EVENT_INIT_TIMER(event, &tsx->retransmit_timer); 
    1319     } else { 
    1320         PJSIP_EVENT_INIT_TIMER(event, &tsx->timeout_timer); 
    1321     } 
    1322  
    1323     /* Dispatch event to transaction. */ 
     1127    PJ_ASSERT_RETURN(tsx != NULL, PJ_EINVAL); 
     1128    PJ_ASSERT_RETURN(code >= 200, PJ_EINVAL); 
     1129 
    13241130    lock_tsx(tsx, &lck); 
    1325     (*tsx->state_handler)(tsx, &event); 
     1131    tsx->status_code = code; 
     1132    tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED, PJSIP_EVENT_USER, NULL); 
    13261133    unlock_tsx(tsx, &lck); 
    1327 } 
    1328  
    1329 /* 
    1330  * Transmit ACK message for 2xx/INVITE with this transaction. The ACK for 
    1331  * non-2xx/INVITE is automatically sent by the transaction. 
    1332  * This operation is only valid if the transaction is configured to handle ACK 
    1333  * (tsx->handle_ack is non-zero). If this attribute is not set, then the 
    1334  * transaction will comply with RFC-3261, i.e. it will set itself to  
    1335  * TERMINATED state when it receives 2xx/INVITE. 
    1336  */ 
    1337 PJ_DEF(void) pjsip_tsx_on_tx_ack( pjsip_transaction *tsx, pjsip_tx_data *tdata) 
    1338 { 
    1339     pjsip_msg *msg; 
    1340     pjsip_host_info dest_addr; 
    1341     pjsip_via_hdr *via; 
    1342     struct tsx_lock_data lck; 
    1343     pj_status_t status = PJ_SUCCESS; 
    1344  
    1345     /* Lock tsx. */ 
    1346     lock_tsx(tsx, &lck); 
    1347  
    1348     pj_assert(tsx->handle_ack != 0); 
    1349      
    1350     msg = tdata->msg; 
    1351  
    1352     /* Generate branch parameter if it doesn't exist. */ 
    1353     via = pjsip_msg_find_hdr(msg, PJSIP_H_VIA, NULL); 
    1354     if (via == NULL) { 
    1355         via = pjsip_via_hdr_create(tdata->pool); 
    1356         pjsip_msg_add_hdr(msg, (pjsip_hdr*) via); 
    1357     } 
    1358  
    1359     if (via->branch_param.slen == 0) { 
    1360         via->branch_param = tsx->branch; 
    1361     } else { 
    1362         pj_assert( pj_strcmp(&via->branch_param, &tsx->branch) == 0 ); 
    1363     } 
    1364  
    1365     /* Get destination name from the message. */ 
    1366     status = tsx_process_route(tsx, tdata, &dest_addr); 
    1367     if (status != 0){ 
    1368         goto on_error; 
    1369     } 
    1370  
    1371     /* Compare message's destination name with transaction's destination name. 
    1372      * If NOT equal, then we'll have to resolve the destination. 
    1373      */ 
    1374     if (dest_addr.type == tsx->dest_name.type && 
    1375         dest_addr.flag == tsx->dest_name.flag && 
    1376         dest_addr.addr.port == tsx->dest_name.addr.port && 
    1377         pj_stricmp(&dest_addr.addr.host, &tsx->dest_name.addr.host) == 0) 
    1378     { 
    1379         /* Equal destination. We can use current transport. */ 
    1380         pjsip_tsx_on_tx_msg(tsx, tdata); 
    1381         unlock_tsx(tsx, &lck); 
    1382         return; 
    1383  
    1384     } 
    1385  
    1386     /* New destination; we'll have to resolve host and create new transport. */ 
    1387     pj_memcpy(&tsx->dest_name, &dest_addr, sizeof(dest_addr)); 
    1388     pj_strdup(tsx->pool, &tsx->dest_name.addr.host, &dest_addr.addr.host); 
    1389  
    1390     PJ_LOG(5,(tsx->obj_name, "tsx resolving destination %.*s:%d", 
    1391                              tsx->dest_name.addr.host.slen,  
    1392                              tsx->dest_name.addr.host.ptr, 
    1393                              tsx->dest_name.addr.port)); 
    1394  
    1395     tsx->transport_state = PJSIP_TSX_TRANSPORT_STATE_RESOLVING; 
    1396     pjsip_transport_dec_ref(tsx->transport); 
    1397     tsx->transport = NULL; 
    1398  
    1399     /* Put the message in queue. */ 
    1400     pjsip_tsx_on_tx_msg(tsx, tdata); 
    1401  
    1402     /* This is a bug! 
    1403      * We shouldn't change transaction's state before actually sending the 
    1404      * message. Otherwise transaction will terminate before message is sent, 
    1405      * and timeout timer will be scheduled. 
    1406      */ 
    1407     PJ_TODO(TSX_DONT_CHANGE_STATE_BEFORE_SENDING_ACK) 
    1408  
    1409     /*  
    1410      * This will start asynchronous resolver job, and when it finishes,  
    1411      * the callback will be called. 
    1412      */ 
    1413  
    1414     tsx->transport_state = PJSIP_TSX_TRANSPORT_STATE_RESOLVING; 
    1415     pjsip_endpt_resolve( tsx->endpt, tsx->pool, &tsx->dest_name,  
    1416                          tsx, &tsx_resolver_callback); 
    1417  
    1418     unlock_tsx(tsx, &lck); 
    1419  
    1420     /* There should be nothing to do after this point.  
    1421      * Execution for the transaction will resume when the resolver callback is 
    1422      * called. 
    1423      */ 
    1424     return; 
    1425  
    1426 on_error: 
    1427     /* Failure condition.  
    1428      * Send TERMINATED event. 
    1429      */ 
    1430     tsx->status_code = PJSIP_SC_TSX_TRANSPORT_ERROR; 
    1431  
    1432     tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED,  
    1433                    PJSIP_EVENT_TRANSPORT_ERROR, (void*)status); 
    1434  
    1435     unlock_tsx(tsx, &lck); 
     1134 
     1135    return PJ_SUCCESS; 
    14361136} 
    14371137 
     
    14401140 * This function is called by TU to send a message. 
    14411141 */ 
    1442 PJ_DEF(void) pjsip_tsx_on_tx_msg( pjsip_transaction *tsx, 
    1443                                   pjsip_tx_data *tdata ) 
     1142PJ_DEF(pj_status_t) pjsip_tsx_send_msg( pjsip_transaction *tsx,  
     1143                                        pjsip_tx_data *tdata ) 
    14441144{ 
    14451145    pjsip_event event; 
    14461146    struct tsx_lock_data lck; 
    14471147    pj_status_t status; 
     1148 
     1149    if (tdata == NULL) 
     1150        tdata = tsx->last_tx; 
     1151 
     1152    PJ_ASSERT_RETURN(tdata != NULL, PJ_EINVALIDOP); 
    14481153 
    14491154    PJ_LOG(5,(tsx->obj_name, "Request to transmit msg on state %s (tdata=%p)", 
     
    14561161    status = (*tsx->state_handler)(tsx, &event); 
    14571162    unlock_tsx(tsx, &lck); 
    1458 } 
     1163 
     1164    return status; 
     1165} 
     1166 
    14591167 
    14601168/* 
     
    14621170 * transaction is received. 
    14631171 */ 
    1464 PJ_DEF(void) pjsip_tsx_on_rx_msg( pjsip_transaction *tsx, 
    1465                                   pjsip_rx_data *rdata) 
     1172static void tsx_on_rx_msg( pjsip_transaction *tsx, pjsip_rx_data *rdata) 
    14661173{ 
    14671174    pjsip_event event; 
     
    14721179              state_str[tsx->state], rdata)); 
    14731180 
     1181    /* Put the transaction in the rdata's mod_data. */ 
     1182    rdata->endpt_info.mod_data[mod_tsx_layer.mod.id] = tsx; 
     1183 
     1184    /* Init event. */ 
    14741185    PJSIP_EVENT_INIT_RX_MSG(event, tsx, rdata); 
    14751186 
     
    14801191} 
    14811192 
    1482 /* 
    1483  * Forcely terminate transaction. 
    1484  */ 
    1485 PJ_DEF(void) pjsip_tsx_terminate( pjsip_transaction *tsx, int code ) 
    1486 { 
     1193 
     1194/* Callback called by send message framework */ 
     1195static void send_msg_callback( pjsip_send_state *send_state, 
     1196                               pj_ssize_t sent, pj_bool_t *cont ) 
     1197{ 
     1198    pjsip_transaction *tsx = send_state->token; 
    14871199    struct tsx_lock_data lck; 
    14881200 
    14891201    lock_tsx(tsx, &lck); 
    1490     tsx->status_code = code; 
    1491     tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED,  
    1492                    PJSIP_EVENT_USER, NULL); 
     1202 
     1203    if (sent > 0) { 
     1204        /* Successfully sent! */ 
     1205        pj_assert(send_state->cur_transport != NULL); 
     1206 
     1207        if (tsx->transport != send_state->cur_transport) { 
     1208            if (tsx->transport) { 
     1209                pjsip_transport_dec_ref(tsx->transport); 
     1210                tsx->transport = NULL; 
     1211            } 
     1212            tsx->transport = send_state->cur_transport; 
     1213            pjsip_transport_add_ref(tsx->transport); 
     1214        } 
     1215 
     1216        /* Clear pending transport flag. */ 
     1217        tsx->transport_flag &= ~(TSX_HAS_PENDING_TRANSPORT); 
     1218 
     1219        /* Pending destroy? */ 
     1220        if (tsx->transport_flag & TSX_HAS_PENDING_DESTROY) { 
     1221            tsx_set_state( tsx, PJSIP_TSX_STATE_DESTROYED,  
     1222                           PJSIP_EVENT_UNKNOWN, NULL ); 
     1223            unlock_tsx(tsx, &lck); 
     1224            return; 
     1225        } 
     1226 
     1227        /* Need to transmit a message? */ 
     1228        if (tsx->transport_flag & TSX_HAS_PENDING_SEND) { 
     1229            tsx->transport_flag &= ~(TSX_HAS_PENDING_SEND); 
     1230            tsx_send_msg(tsx, tsx->last_tx); 
     1231        } 
     1232 
     1233        /* Need to reschedule retransmission? */ 
     1234        if (tsx->transport_flag & TSX_HAS_PENDING_RESCHED) { 
     1235            tsx->transport_flag &= ~(TSX_HAS_PENDING_RESCHED); 
     1236            tsx_resched_retransmission(tsx); 
     1237        } 
     1238 
     1239    } else { 
     1240        /* Failed to send! */ 
     1241        pj_assert(sent != 0); 
     1242 
     1243        /* If transaction is using the same transport as the failed one,  
     1244         * release the transport. 
     1245         */ 
     1246        if (send_state->cur_transport==tsx->transport && 
     1247            tsx->transport != NULL) 
     1248        { 
     1249            pjsip_transport_dec_ref(tsx->transport); 
     1250            tsx->transport = NULL; 
     1251        } 
     1252 
     1253        if (!*cont) { 
     1254            PJ_LOG(4,(tsx->obj_name, "Failed to send message! status=%d", 
     1255                      -sent)); 
     1256 
     1257            /* Clear pending transport flag. */ 
     1258            tsx->transport_flag &= ~(TSX_HAS_PENDING_TRANSPORT); 
     1259 
     1260            /* Terminate transaction. */ 
     1261            tsx->status_code = PJSIP_SC_TSX_TRANSPORT_ERROR; 
     1262            tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED,  
     1263                           PJSIP_EVENT_TRANSPORT_ERROR, send_state->tdata ); 
     1264        } 
     1265    } 
    14931266 
    14941267    unlock_tsx(tsx, &lck); 
    14951268} 
    14961269 
    1497 /* 
    1498  * Transport send completion callback. 
    1499  */ 
    1500 static void tsx_on_send_complete(void *token, pjsip_tx_data *tdata, 
    1501                                  pj_ssize_t bytes_sent) 
    1502 { 
    1503     PJ_UNUSED_ARG(token); 
    1504     PJ_UNUSED_ARG(tdata); 
    1505  
    1506     if (bytes_sent <= 0) { 
    1507         PJ_TODO(HANDLE_TRANSPORT_ERROR); 
    1508     } 
     1270 
     1271/* Transport callback. */ 
     1272static void transport_callback(void *token, pjsip_tx_data *tdata, 
     1273                               pj_ssize_t sent) 
     1274{ 
     1275    if (sent < 0) { 
     1276        pjsip_transaction *tsx = token; 
     1277        struct tsx_lock_data lck; 
     1278 
     1279        PJ_LOG(4,(tsx->obj_name, "Failed to send message! status=%d", 
     1280                  -sent)); 
     1281 
     1282        lock_tsx(tsx, &lck); 
     1283 
     1284        /* Dereference transport. */ 
     1285        pjsip_transport_dec_ref(tsx->transport); 
     1286        tsx->transport = NULL; 
     1287 
     1288        /* Terminate transaction. */ 
     1289        tsx->status_code = PJSIP_SC_TSX_TRANSPORT_ERROR; 
     1290        tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED,  
     1291                       PJSIP_EVENT_TRANSPORT_ERROR, tdata ); 
     1292 
     1293        unlock_tsx(tsx, &lck); 
     1294   } 
    15091295} 
    15101296 
    15111297/* 
    15121298 * Send message to the transport. 
    1513  * If transport is not yet available, then do nothing. The message will be 
    1514  * transmitted when transport connection completion callback is called. 
    15151299 */ 
    15161300static pj_status_t tsx_send_msg( pjsip_transaction *tsx,  
    15171301                                 pjsip_tx_data *tdata) 
    15181302{ 
    1519     pj_status_t status = PJ_SUCCESS; 
    1520  
    1521     PJ_LOG(5,(tsx->obj_name, "sending msg (tdata=%p)", tdata)); 
    1522  
    1523     if (tsx->transport_state == PJSIP_TSX_TRANSPORT_STATE_FINAL) { 
    1524         pjsip_event before_tx_event; 
    1525  
    1526         pj_assert(tsx->transport != NULL); 
    1527  
    1528         /* Make sure Via transport info is filled up properly for 
    1529          * requests.  
     1303    pj_status_t status = PJ_EBUG; 
     1304 
     1305    PJ_ASSERT_RETURN(tsx && tdata, PJ_EINVAL); 
     1306 
     1307    /* Send later if transport is still pending. */ 
     1308    if (tsx->transport_flag & TSX_HAS_PENDING_TRANSPORT) { 
     1309        tsx->transport_flag |= TSX_HAS_PENDING_SEND; 
     1310        return PJ_SUCCESS; 
     1311    } 
     1312 
     1313    if (tdata->msg->type == PJSIP_REQUEST_MSG) { 
     1314        /* If we have the transport, send the message using that transport. 
     1315         * Otherwise perform full transport resolution. 
    15301316         */ 
    1531         if (tdata->msg->type == PJSIP_REQUEST_MSG) { 
    1532             pjsip_via_hdr *via = (pjsip_via_hdr*)  
    1533                 pjsip_msg_find_hdr(tdata->msg, PJSIP_H_VIA, NULL); 
    1534  
    1535             /* For request message, set "rport" parameter by default. */ 
    1536             if (tdata->msg->type == PJSIP_REQUEST_MSG) 
    1537                 via->rport_param = 0; 
    1538  
    1539             /* Don't update Via sent-by on retransmission. */ 
    1540             if (via->sent_by.host.slen == 0) { 
    1541                 pj_strdup2(tdata->pool, &via->transport,  
    1542                            tsx->transport->type_name); 
    1543                 pj_strdup(tdata->pool, &via->sent_by.host,  
    1544                           &tsx->transport->local_name.host); 
    1545                 via->sent_by.port = tsx->transport->local_name.port; 
     1317        if (tsx->transport) { 
     1318            status = pjsip_transport_send( tsx->transport, tdata, &tsx->addr, 
     1319                                           tsx->addr_len, tsx,  
     1320                                           &transport_callback); 
     1321            if (status == PJ_EPENDING) 
     1322                status = PJ_SUCCESS; 
     1323 
     1324            if (status != PJ_SUCCESS) { 
     1325                /* On error, release transport to force using full transport 
     1326                 * resolution procedure. 
     1327                 */ 
     1328                if (tsx->transport) { 
     1329                    pjsip_transport_dec_ref(tsx->transport); 
     1330                    tsx->transport = NULL; 
     1331                } 
     1332                tsx->addr_len = 0; 
    15461333            } 
    15471334        } 
    1548  
    1549         /* Notify everybody we're about to send message. */ 
    1550         PJSIP_EVENT_INIT_PRE_TX_MSG(before_tx_event, tsx, tdata,  
    1551                                     tsx->retransmit_count); 
    1552         pjsip_endpt_send_tsx_event( tsx->endpt, &before_tx_event ); 
    1553  
    1554         tsx->has_unsent_msg = 0; 
    1555         status = pjsip_transport_send(tsx->transport, tdata, 
    1556                         &tsx->remote_addr.entry[tsx->current_addr].addr, 
    1557                         tsx->remote_addr.entry[tsx->current_addr].addr_len, 
    1558                         tsx, &tsx_on_send_complete); 
    1559         if (status != PJ_SUCCESS && status != PJ_EPENDING) { 
    1560             PJ_TODO(HANDLE_TRANSPORT_ERROR); 
    1561             goto on_error; 
    1562         } 
     1335         
     1336        if (!tsx->transport) { 
     1337            tsx->transport_flag |= TSX_HAS_PENDING_TRANSPORT; 
     1338            status = pjsip_endpt_send_request_stateless(tsx->endpt, tdata, tsx, 
     1339                                                        &send_msg_callback); 
     1340            if (status == PJ_EPENDING) 
     1341                status = PJ_SUCCESS; 
     1342        } 
     1343 
    15631344    } else { 
    1564         tsx->has_unsent_msg = 1; 
    1565     } 
    1566  
    1567     return 0; 
    1568  
    1569 on_error: 
    1570     tsx->status_code = PJSIP_SC_TSX_TRANSPORT_ERROR; 
    1571     tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED,  
    1572                    PJSIP_EVENT_TRANSPORT_ERROR, (void*)status); 
     1345        /* If we have the transport, send the message using that transport. 
     1346         * Otherwise perform full transport resolution. 
     1347         */ 
     1348        if (tsx->transport) { 
     1349            status = pjsip_transport_send( tsx->transport, tdata,  
     1350                                           &tsx->addr, tsx->addr_len, 
     1351                                           tsx, &transport_callback); 
     1352            if (status == PJ_EPENDING) 
     1353                status = PJ_SUCCESS; 
     1354 
     1355            if (status != PJ_SUCCESS) { 
     1356                if (tsx->transport) { 
     1357                    pjsip_transport_dec_ref(tsx->transport); 
     1358                    tsx->transport = NULL; 
     1359                } 
     1360                tsx->addr_len = 0; 
     1361                tsx->res_addr.transport = NULL; 
     1362                tsx->res_addr.addr_len = 0; 
     1363            } 
     1364 
     1365        }  
     1366 
     1367        if (!tsx->transport) { 
     1368            tsx->transport_flag |= TSX_HAS_PENDING_TRANSPORT; 
     1369            status = pjsip_endpt_send_response( tsx->endpt, &tsx->res_addr,  
     1370                                                tdata, tsx,  
     1371                                                &send_msg_callback); 
     1372            if (status == PJ_EPENDING) 
     1373                status = PJ_SUCCESS; 
     1374        } 
     1375    } 
     1376 
    15731377    return status; 
    15741378} 
    15751379 
     1380 
    15761381/* 
    15771382 * Retransmit last message sent. 
    15781383 */ 
    1579 static pj_status_t pjsip_tsx_retransmit( pjsip_transaction *tsx, 
    1580                                          int should_restart_timer) 
     1384static void tsx_resched_retransmission( pjsip_transaction *tsx ) 
     1385{ 
     1386    pj_time_val timeout; 
     1387    int msec_time; 
     1388 
     1389    pj_assert((tsx->transport_flag & TSX_HAS_PENDING_TRANSPORT) == 0); 
     1390 
     1391    msec_time = (1 << (tsx->retransmit_count)) * PJSIP_T1_TIMEOUT; 
     1392 
     1393    if (msec_time>PJSIP_T2_TIMEOUT && tsx->method.id!=PJSIP_INVITE_METHOD) 
     1394        msec_time = PJSIP_T2_TIMEOUT; 
     1395 
     1396    timeout.sec = msec_time / 1000; 
     1397    timeout.msec = msec_time % 1000; 
     1398    pjsip_endpt_schedule_timer( tsx->endpt, &tsx->retransmit_timer,  
     1399                                &timeout); 
     1400} 
     1401 
     1402/* 
     1403 * Retransmit last message sent. 
     1404 */ 
     1405static pj_status_t tsx_retransmit( pjsip_transaction *tsx, int resched) 
    15811406{ 
    15821407    pj_status_t status; 
    15831408 
     1409    PJ_ASSERT_RETURN(tsx->last_tx!=NULL, PJ_EBUG); 
     1410 
    15841411    PJ_LOG(4,(tsx->obj_name, "retransmiting (tdata=%p, count=%d, restart?=%d)",  
    1585               tsx->last_tx, tsx->retransmit_count, should_restart_timer)); 
    1586  
    1587     pj_assert(tsx->last_tx != NULL); 
     1412              tsx->last_tx, tsx->retransmit_count, resched)); 
    15881413 
    15891414    ++tsx->retransmit_count; 
    15901415 
    15911416    status = tsx_send_msg( tsx, tsx->last_tx); 
    1592     if (status != PJ_SUCCESS) { 
     1417    if (status != PJ_SUCCESS) 
    15931418        return status; 
    1594     } 
    15951419     
    15961420    /* Restart timer T1. */ 
    1597     if (should_restart_timer) { 
    1598         pj_time_val timeout; 
    1599         int msec_time = (1 << (tsx->retransmit_count)) * PJSIP_T1_TIMEOUT; 
    1600  
    1601         if (tsx->method.id!=PJSIP_INVITE_METHOD && msec_time>PJSIP_T2_TIMEOUT)  
    1602             msec_time = PJSIP_T2_TIMEOUT; 
    1603  
    1604         timeout.sec = msec_time / 1000; 
    1605         timeout.msec = msec_time % 1000; 
    1606         pjsip_endpt_schedule_timer( tsx->endpt, &tsx->retransmit_timer,  
    1607                                     &timeout); 
     1421    if (resched) { 
     1422        if (tsx->transport_flag & TSX_HAS_PENDING_TRANSPORT) { 
     1423            tsx->transport_flag |= TSX_HAS_PENDING_RESCHED; 
     1424        } else { 
     1425            tsx_resched_retransmission(tsx); 
     1426        } 
    16081427    } 
    16091428 
     
    16111430} 
    16121431 
     1432 
    16131433/* 
    16141434 * Handler for events in state Null. 
    16151435 */ 
    1616 static pj_status_t pjsip_tsx_on_state_null( pjsip_transaction *tsx,  
    1617                                             pjsip_event *event ) 
     1436static pj_status_t tsx_on_state_null( pjsip_transaction *tsx,  
     1437                                      pjsip_event *event ) 
    16181438{ 
    16191439    pj_status_t status; 
    16201440 
    1621     pj_assert( tsx->state == PJSIP_TSX_STATE_NULL); 
    1622     pj_assert( tsx->last_tx == NULL ); 
    1623     pj_assert( tsx->has_unsent_msg == 0); 
     1441    pj_assert(tsx->state == PJSIP_TSX_STATE_NULL); 
    16241442 
    16251443    if (tsx->role == PJSIP_ROLE_UAS) { 
    16261444 
    1627         /* Set state to Trying. */ 
    1628         pj_assert(event->type == PJSIP_EVENT_RX_MSG); 
    1629         tsx_set_state( tsx, PJSIP_TSX_STATE_TRYING,  
    1630                        PJSIP_EVENT_RX_MSG, event->body.rx_msg.rdata ); 
     1445        /* UAS doesn't have STATE_NULL. 
     1446         * State has moved from NULL after transaction is initialized. 
     1447         */ 
     1448        pj_assert(!"Bug bug bug!!"); 
     1449        return PJ_EBUG; 
    16311450 
    16321451    } else { 
    1633         pjsip_tx_data *tdata = event->body.tx_msg.tdata; 
     1452        pjsip_tx_data *tdata; 
     1453 
     1454        /* Must be transmit event. */ 
     1455        PJ_ASSERT_RETURN(event->type == PJSIP_EVENT_TX_MSG, PJ_EBUG); 
     1456 
     1457        /* Get the txdata */ 
     1458        tdata = event->body.tx_msg.tdata; 
    16341459 
    16351460        /* Save the message for retransmission. */ 
    1636         tsx->last_tx = tdata; 
    1637         pjsip_tx_data_add_ref(tdata); 
     1461        if (tsx->last_tx && tsx->last_tx != tdata) { 
     1462            pjsip_tx_data_dec_ref(tsx->last_tx); 
     1463            tsx->last_tx = NULL; 
     1464        } 
     1465        if (tsx->last_tx != tdata) { 
     1466            tsx->last_tx = tdata; 
     1467            pjsip_tx_data_add_ref(tdata); 
     1468        } 
    16381469 
    16391470        /* Send the message. */ 
     
    16521483         * transport is being used. 
    16531484         */ 
    1654         if (tsx->transport_state == PJSIP_TSX_TRANSPORT_STATE_FINAL && 
    1655             PJSIP_TRANSPORT_IS_RELIABLE(tsx->transport)==0)  
    1656         { 
    1657             pjsip_endpt_schedule_timer(tsx->endpt, &tsx->retransmit_timer,  
    1658                                        &t1_timer_val); 
     1485        if (!PJSIP_TRANSPORT_IS_RELIABLE(tsx->transport))  { 
    16591486            tsx->retransmit_count = 0; 
     1487            if (tsx->transport_flag & TSX_HAS_PENDING_TRANSPORT) { 
     1488                tsx->transport_flag |= TSX_HAS_PENDING_RESCHED; 
     1489            } else { 
     1490                pjsip_endpt_schedule_timer(tsx->endpt, &tsx->retransmit_timer, 
     1491                                           &t1_timer_val); 
     1492            } 
    16601493        } 
    16611494 
     
    16681501} 
    16691502 
     1503 
    16701504/* 
    16711505 * State Calling is for UAC after it sends request but before any responses 
    16721506 * is received. 
    16731507 */ 
    1674 static pj_status_t pjsip_tsx_on_state_calling( pjsip_transaction *tsx,  
    1675                                                pjsip_event *event ) 
     1508static pj_status_t tsx_on_state_calling( pjsip_transaction *tsx,  
     1509                                         pjsip_event *event ) 
    16761510{ 
    16771511    pj_assert(tsx->state == PJSIP_TSX_STATE_CALLING); 
     
    16841518 
    16851519        /* Retransmit the request. */ 
    1686         status = pjsip_tsx_retransmit( tsx, 1 ); 
     1520        status = tsx_retransmit( tsx, 1 ); 
    16871521        if (status != PJ_SUCCESS) { 
    16881522            return status; 
     
    17061540 
    17071541        /* Transaction is destroyed */ 
    1708         return PJSIP_ETSXDESTROYED; 
     1542        //return PJSIP_ETSXDESTROYED; 
    17091543 
    17101544    } else if (event->type == PJSIP_EVENT_RX_MSG) { 
    1711         int code; 
     1545        pjsip_msg *msg; 
     1546        //int code; 
     1547 
     1548        /* Get message instance */ 
     1549        msg = event->body.rx_msg.rdata->msg_info.msg; 
     1550 
     1551        /* Better be a response message. */ 
     1552        if (msg->type != PJSIP_RESPONSE_MSG) 
     1553            return PJSIP_ENOTRESPONSEMSG; 
    17121554 
    17131555        /* Cancel retransmission timer A. */ 
     
    17231565         */ 
    17241566        /* Keep last_tx for authorization. */ 
    1725         code = event->body.rx_msg.rdata->msg_info.msg->line.status.code; 
    1726         if (tsx->method.id != PJSIP_INVITE_METHOD && code!=401 && code!=407) { 
    1727             pjsip_tx_data_dec_ref(tsx->last_tx); 
    1728             tsx->last_tx = NULL; 
    1729         } 
     1567        //blp: always keep last_tx until transaction is destroyed 
     1568        //code = msg->line.status.code; 
     1569        //if (tsx->method.id != PJSIP_INVITE_METHOD && code!=401 && code!=407) { 
     1570        //    pjsip_tx_data_dec_ref(tsx->last_tx); 
     1571        //    tsx->last_tx = NULL; 
     1572        //} 
    17301573 
    17311574        /* Processing is similar to state Proceeding. */ 
    1732         pjsip_tsx_on_state_proceeding_uac( tsx, event); 
     1575        tsx_on_state_proceeding_uac( tsx, event); 
    17331576 
    17341577    } else { 
    1735         pj_assert(0); 
     1578        pj_assert(!"Unexpected event"); 
    17361579        return PJ_EBUG; 
    17371580    } 
     
    17391582    return PJ_SUCCESS; 
    17401583} 
     1584 
    17411585 
    17421586/* 
     
    17461590 *       non-INVITE client transaction (bug in RFC?). 
    17471591 */ 
    1748 static pj_status_t pjsip_tsx_on_state_trying( pjsip_transaction *tsx,  
    1749                                               pjsip_event *event) 
     1592static pj_status_t tsx_on_state_trying( pjsip_transaction *tsx,  
     1593                                        pjsip_event *event) 
    17501594{ 
    17511595    pj_status_t status; 
     
    17621606     * response because we haven't sent any!). 
    17631607     */ 
    1764     //pj_assert(event->type == PJSIP_EVENT_TX_MSG); 
    17651608    if (event->type != PJSIP_EVENT_TX_MSG) { 
    17661609        return PJ_SUCCESS; 
     
    17701613     * "Proceeding" state. 
    17711614     */ 
    1772     status = pjsip_tsx_on_state_proceeding_uas( tsx, event); 
     1615    status = tsx_on_state_proceeding_uas( tsx, event); 
    17731616 
    17741617    /* Inform the TU of the state transision if state is still State_Trying */ 
    17751618    if (status==PJ_SUCCESS && tsx->state == PJSIP_TSX_STATE_TRYING) { 
     1619 
    17761620        tsx_set_state( tsx, PJSIP_TSX_STATE_PROCEEDING,  
    17771621                       PJSIP_EVENT_TX_MSG, event->body.tx_msg.tdata); 
     1622 
    17781623    } 
    17791624 
    17801625    return status; 
    17811626} 
     1627 
    17821628 
    17831629/* 
     
    17851631 * This state happens after the TU sends provisional response. 
    17861632 */ 
    1787 static pj_status_t pjsip_tsx_on_state_proceeding_uas( pjsip_transaction *tsx, 
    1788                                                       pjsip_event *event) 
     1633static pj_status_t tsx_on_state_proceeding_uas( pjsip_transaction *tsx, 
     1634                                                pjsip_event *event) 
    17891635{ 
    17901636    pj_assert(tsx->state == PJSIP_TSX_STATE_PROCEEDING ||  
     
    17991645        pj_status_t status; 
    18001646 
    1801         /* Send last response. */ 
    1802         status = pjsip_tsx_retransmit( tsx, 0 ); 
    1803         if (status != PJ_SUCCESS) { 
    1804             return status; 
     1647        /* Must have last response sent. */ 
     1648        PJ_ASSERT_RETURN(tsx->last_tx != NULL, PJ_EBUG); 
     1649 
     1650        /* Send last response */ 
     1651        if (tsx->transport_flag & TSX_HAS_PENDING_TRANSPORT) { 
     1652            tsx->transport_flag |= TSX_HAS_PENDING_SEND; 
     1653        } else { 
     1654            status = tsx_send_msg(tsx, tsx->last_tx); 
     1655            if (status != PJ_SUCCESS) 
     1656                return status; 
    18051657        } 
    18061658         
     
    18161668 
    18171669        /* This can only be a response message. */ 
    1818         pj_assert(msg->type == PJSIP_RESPONSE_MSG); 
    1819  
    1820         /* Status code must be higher than last sent. */ 
    1821         pj_assert(msg->line.status.code >= tsx->status_code); 
     1670        PJ_ASSERT_RETURN(msg->type==PJSIP_RESPONSE_MSG, PJSIP_ENOTRESPONSEMSG); 
    18221671 
    18231672        /* Update last status */ 
     
    18481697                pjsip_tx_data_add_ref( tdata ); 
    18491698            } 
     1699 
    18501700            tsx_set_state( tsx, PJSIP_TSX_STATE_PROCEEDING,  
    18511701                           PJSIP_EVENT_TX_MSG, tdata ); 
     
    18531703        } else if (PJSIP_IS_STATUS_IN_CLASS(tsx->status_code, 200)) { 
    18541704 
    1855             if (tsx->method.id == PJSIP_INVITE_METHOD && tsx->handle_ack==0) { 
     1705            if (tsx->method.id == PJSIP_INVITE_METHOD && tsx->handle_200resp==0) { 
    18561706 
    18571707                /* 2xx class message is not saved, because retransmission  
     
    18621712 
    18631713                /* Transaction is destroyed. */ 
    1864                 return PJSIP_ETSXDESTROYED; 
     1714                //return PJSIP_ETSXDESTROYED; 
    18651715 
    18661716            } else { 
     
    18691719                if (tsx->method.id == PJSIP_INVITE_METHOD) { 
    18701720                    tsx->retransmit_count = 0; 
    1871                     pjsip_endpt_schedule_timer( tsx->endpt,  
    1872                                                 &tsx->retransmit_timer,  
    1873                                                 &t1_timer_val); 
     1721                    if (tsx->transport_flag & TSX_HAS_PENDING_TRANSPORT) { 
     1722                        tsx->transport_flag |= TSX_HAS_PENDING_RESCHED; 
     1723                    } else { 
     1724                        pjsip_endpt_schedule_timer( tsx->endpt,  
     1725                                                    &tsx->retransmit_timer, 
     1726                                                    &t1_timer_val); 
     1727                    } 
    18741728                } 
    18751729 
     
    18851739                 * reliable transport. 
    18861740                 */ 
    1887                 if (PJSIP_TRANSPORT_IS_RELIABLE(tsx->transport)==0) { 
     1741                if (!PJSIP_TRANSPORT_IS_RELIABLE(tsx->transport)) { 
    18881742                    timeout = timeout_timer_val; 
    18891743                } else { 
     
    19161770             * timer G will be scheduled (retransmission). 
    19171771             */ 
    1918             if (PJSIP_TRANSPORT_IS_RELIABLE(tsx->transport)==0) { 
     1772            if (!PJSIP_TRANSPORT_IS_RELIABLE(tsx->transport)) { 
    19191773                pjsip_cseq_hdr *cseq = pjsip_msg_find_hdr( msg, PJSIP_H_CSEQ, 
    19201774                                                           NULL); 
    19211775                if (cseq->method.id == PJSIP_INVITE_METHOD) { 
    19221776                    tsx->retransmit_count = 0; 
    1923                     pjsip_endpt_schedule_timer(tsx->endpt,  
    1924                                                &tsx->retransmit_timer,  
    1925                                                &t1_timer_val); 
     1777                    if (tsx->transport_flag & TSX_HAS_PENDING_TRANSPORT) { 
     1778                        tsx->transport_flag |= TSX_HAS_PENDING_RESCHED; 
     1779                    } else { 
     1780                        pjsip_endpt_schedule_timer(tsx->endpt,  
     1781                                                   &tsx->retransmit_timer,  
     1782                                                   &t1_timer_val); 
     1783                    } 
    19261784                } 
    19271785            } 
     
    19381796    } else if (event->type == PJSIP_EVENT_TIMER &&  
    19391797               event->body.timer.entry == &tsx->retransmit_timer) { 
     1798 
    19401799        /* Retransmission timer elapsed. */ 
    19411800        pj_status_t status; 
    19421801 
     1802        /* Must not be triggered while transport is pending. */ 
     1803        pj_assert((tsx->transport_flag & TSX_HAS_PENDING_TRANSPORT) == 0); 
     1804 
    19431805        /* Must have last response to retransmit. */ 
    19441806        pj_assert(tsx->last_tx != NULL); 
    19451807 
    19461808        /* Retransmit the last response. */ 
    1947         status = pjsip_tsx_retransmit( tsx, 1 ); 
     1809        status = tsx_retransmit( tsx, 1 ); 
    19481810        if (status != PJ_SUCCESS) { 
    19491811            return status; 
     
    19541816 
    19551817        /* Timeout timer. should not happen? */ 
    1956         pj_assert(0); 
     1818        pj_assert(!"Should not happen(?)"); 
    19571819 
    19581820        tsx->status_code = PJSIP_SC_TSX_TIMEOUT; 
     
    19641826 
    19651827    } else { 
    1966         pj_assert(0); 
     1828        pj_assert(!"Unexpected event"); 
    19671829        return PJ_EBUG; 
    19681830    } 
     
    19701832    return PJ_SUCCESS; 
    19711833} 
     1834 
    19721835 
    19731836/* 
     
    19761839 * UAS. 
    19771840 */ 
    1978 static pj_status_t pjsip_tsx_on_state_proceeding_uac(pjsip_transaction *tsx,  
    1979                                                      pjsip_event *event) 
     1841static pj_status_t tsx_on_state_proceeding_uac(pjsip_transaction *tsx,  
     1842                                               pjsip_event *event) 
    19801843{ 
    19811844 
     
    19841847 
    19851848    if (event->type != PJSIP_EVENT_TIMER) { 
     1849        pjsip_msg *msg; 
     1850 
    19861851        /* Must be incoming response, because we should not retransmit 
    19871852         * request once response has been received. 
     
    19921857        } 
    19931858 
    1994         tsx->status_code = event->body.rx_msg.rdata->msg_info.msg->line.status.code; 
     1859        msg = event->body.rx_msg.rdata->msg_info.msg; 
     1860 
     1861        /* Must be a response message. */ 
     1862        if (msg->type != PJSIP_RESPONSE_MSG) { 
     1863            pj_assert(!"Expecting response message!"); 
     1864            return PJSIP_ENOTRESPONSEMSG; 
     1865        } 
     1866 
     1867        tsx->status_code = msg->line.status.code; 
    19951868    } else { 
    19961869        tsx->status_code = PJSIP_SC_TSX_TIMEOUT; 
     
    20111884         * handled in TU). For non-INVITE, state moves to Completed. 
    20121885         */ 
    2013         if (tsx->method.id == PJSIP_INVITE_METHOD && tsx->handle_ack == 0) { 
     1886        if (tsx->method.id == PJSIP_INVITE_METHOD) { 
    20141887            tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED,  
    20151888                           PJSIP_EVENT_RX_MSG, event->body.rx_msg.rdata ); 
    2016             return PJSIP_ETSXDESTROYED; 
     1889            //return PJSIP_ETSXDESTROYED; 
    20171890 
    20181891        } else { 
     
    20471920        /* Generate and send ACK for INVITE. */ 
    20481921        if (tsx->method.id == PJSIP_INVITE_METHOD) { 
    2049             pjsip_endpt_create_ack( tsx->endpt, tsx->last_tx,  
    2050                                     event->body.rx_msg.rdata ); 
     1922            pjsip_tx_data *ack; 
     1923 
     1924            status = pjsip_endpt_create_ack( tsx->endpt, tsx->last_tx,  
     1925                                             event->body.rx_msg.rdata, 
     1926                                             &ack); 
     1927            if (status != PJ_SUCCESS) 
     1928                return status; 
     1929 
     1930            if (ack != tsx->last_tx) { 
     1931                pjsip_tx_data_dec_ref(tsx->last_tx); 
     1932                tsx->last_tx = ack; 
     1933            } 
     1934 
    20511935            status = tsx_send_msg( tsx, tsx->last_tx); 
    20521936            if (status != PJ_SUCCESS) { 
     
    20561940 
    20571941        /* Start Timer D with TD/T4 timer if unreliable transport is used. */ 
    2058         if (PJSIP_TRANSPORT_IS_RELIABLE(tsx->transport) == 0) { 
     1942        if (!PJSIP_TRANSPORT_IS_RELIABLE(tsx->transport)) { 
    20591943            if (tsx->method.id == PJSIP_INVITE_METHOD) { 
    20601944                timeout = td_timer_val; 
     
    20731957    } else { 
    20741958        // Shouldn't happen because there's no timer for this state. 
    2075         pj_assert(0); 
     1959        pj_assert(!"Unexpected event"); 
    20761960        return PJ_EBUG; 
    20771961    } 
     
    20801964} 
    20811965 
     1966 
    20821967/* 
    20831968 * Handler for events in Completed state for UAS 
    20841969 */ 
    2085 static pj_status_t pjsip_tsx_on_state_completed_uas( pjsip_transaction *tsx,  
    2086                                                      pjsip_event *event) 
     1970static pj_status_t tsx_on_state_completed_uas( pjsip_transaction *tsx,  
     1971                                               pjsip_event *event) 
    20871972{ 
    20881973    pj_assert(tsx->state == PJSIP_TSX_STATE_COMPLETED); 
     
    20901975    if (event->type == PJSIP_EVENT_RX_MSG) { 
    20911976        pjsip_msg *msg = event->body.rx_msg.rdata->msg_info.msg; 
    2092         pjsip_cseq_hdr *cseq = pjsip_msg_find_hdr( msg, PJSIP_H_CSEQ, NULL ); 
     1977 
     1978        /* This must be a request message retransmission. */ 
     1979        if (msg->type != PJSIP_REQUEST_MSG) 
     1980            return PJSIP_ENOTREQUESTMSG; 
    20931981 
    20941982        /* On receive request retransmission, retransmit last response. */ 
    2095         if (cseq->method.id != PJSIP_ACK_METHOD) { 
     1983        if (msg->line.req.method.id != PJSIP_ACK_METHOD) { 
    20961984            pj_status_t status; 
    20971985 
    2098             status = pjsip_tsx_retransmit( tsx, 0 ); 
     1986            status = tsx_retransmit( tsx, 0 ); 
    20991987            if (status != PJ_SUCCESS) { 
    21001988                return status; 
     
    21232011            pj_status_t status; 
    21242012 
    2125             status = pjsip_tsx_retransmit( tsx, 1 ); 
     2013            status = tsx_retransmit( tsx, 1 ); 
    21262014            if (status != PJ_SUCCESS) { 
    21272015                return status; 
     
    21402028                               PJSIP_EVENT_TIMER, &tsx->timeout_timer ); 
    21412029 
    2142                 return PJSIP_ETSXDESTROYED; 
     2030                //return PJSIP_ETSXDESTROYED; 
    21432031 
    21442032            } else { 
     
    21462034                tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED,  
    21472035                               PJSIP_EVENT_TIMER, &tsx->timeout_timer ); 
    2148                 return PJSIP_ETSXDESTROYED; 
     2036                //return PJSIP_ETSXDESTROYED; 
    21492037            } 
    21502038        } 
     
    21522040    } else { 
    21532041        /* Ignore request to transmit. */ 
    2154         pj_assert(event->body.tx_msg.tdata == tsx->last_tx); 
     2042        PJ_ASSERT_RETURN(event->type == PJSIP_EVENT_TX_MSG &&  
     2043                         event->body.tx_msg.tdata == tsx->last_tx,  
     2044                         PJ_EINVALIDOP); 
    21552045    } 
    21562046 
     
    21582048} 
    21592049 
     2050 
    21602051/* 
    21612052 * Handler for events in Completed state for UAC transaction. 
    21622053 */ 
    2163 static pj_status_t pjsip_tsx_on_state_completed_uac( pjsip_transaction *tsx, 
    2164                                                      pjsip_event *event) 
     2054static pj_status_t tsx_on_state_completed_uac( pjsip_transaction *tsx, 
     2055                                               pjsip_event *event) 
    21652056{ 
    21662057    pj_assert(tsx->state == PJSIP_TSX_STATE_COMPLETED); 
     
    21752066 
    21762067        /* Transaction has been destroyed. */ 
    2177         return PJSIP_ETSXDESTROYED; 
     2068        //return PJSIP_ETSXDESTROYED; 
    21782069 
    21792070    } else if (event->type == PJSIP_EVENT_RX_MSG) { 
     
    21892080                pj_status_t status; 
    21902081 
    2191                 status = pjsip_tsx_retransmit( tsx, 0 ); 
     2082                status = tsx_retransmit( tsx, 0 ); 
    21922083                if (status != PJ_SUCCESS) { 
    21932084                    return status; 
     
    22002091            /* Just drop the response. */ 
    22012092        } 
    2202     } else if (tsx->method.id == PJSIP_INVITE_METHOD && 
    2203                event->type == PJSIP_EVENT_TX_MSG && 
    2204                event->body.tx_msg.tdata->msg->line.req.method.id==PJSIP_ACK_METHOD) { 
    2205  
    2206         pj_status_t status; 
    2207  
    2208         /* Set last transmitted message. */ 
    2209         if (tsx->last_tx != event->body.tx_msg.tdata) { 
    2210             pjsip_tx_data_dec_ref( tsx->last_tx ); 
    2211             tsx->last_tx = event->body.tx_msg.tdata; 
    2212             pjsip_tx_data_add_ref( tsx->last_tx ); 
    2213         } 
    2214  
    2215         /* No state changed, but notify app.  
    2216          * Must notify now, so app has chance to put SDP in outgoing ACK msg. 
    2217          */ 
    2218         tsx_set_state( tsx, PJSIP_TSX_STATE_COMPLETED,  
    2219                        PJSIP_EVENT_TX_MSG, event->body.tx_msg.tdata ); 
    2220  
    2221         /* Send msg */ 
    2222         status = tsx_send_msg(tsx, event->body.tx_msg.tdata); 
    2223         if (status != PJ_SUCCESS) 
    2224             return status; 
    22252093 
    22262094    } else { 
    2227         pj_assert(0); 
    2228         return PJ_EBUG; 
     2095        pj_assert(!"Unexpected event"); 
     2096        return PJ_EINVALIDOP; 
    22292097    } 
    22302098 
     
    22322100} 
    22332101 
     2102 
    22342103/* 
    22352104 * Handler for events in state Confirmed. 
    22362105 */ 
    2237 static pj_status_t pjsip_tsx_on_state_confirmed( pjsip_transaction *tsx, 
    2238                                                  pjsip_event *event) 
     2106static pj_status_t tsx_on_state_confirmed( pjsip_transaction *tsx, 
     2107                                           pjsip_event *event) 
    22392108{ 
    22402109    pj_assert(tsx->state == PJSIP_TSX_STATE_CONFIRMED); 
     
    22472116    if (event->type == PJSIP_EVENT_RX_MSG) { 
    22482117 
    2249         pjsip_method_e method_id =  
    2250             event->body.rx_msg.rdata->msg_info.msg->line.req.method.id; 
    2251  
    2252         /* Must be a request message. */ 
    2253         pj_assert(event->body.rx_msg.rdata->msg_info.msg->type == PJSIP_REQUEST_MSG); 
     2118        pjsip_msg *msg = event->body.rx_msg.rdata->msg_info.msg; 
     2119 
     2120        /* Only expecting request message. */ 
     2121        if (msg->type != PJSIP_REQUEST_MSG) 
     2122            return PJSIP_ENOTREQUESTMSG; 
    22542123 
    22552124        /* Must be an ACK request or a late INVITE retransmission. */ 
    2256         pj_assert(method_id == PJSIP_ACK_METHOD || 
    2257                   method_id == PJSIP_INVITE_METHOD); 
    2258  
    2259         /* Just so that compiler won't complain about unused vars when 
    2260          * building release code. 
    2261          */ 
    2262         PJ_UNUSED_ARG(method_id); 
     2125        pj_assert(msg->line.req.method.id == PJSIP_ACK_METHOD ||  
     2126                  msg->line.req.method.id == PJSIP_INVITE_METHOD); 
    22632127 
    22642128    } else if (event->type == PJSIP_EVENT_TIMER) { 
     
    22712135 
    22722136        /* Transaction has been destroyed. */ 
    2273         return PJSIP_ETSXDESTROYED; 
     2137        //return PJSIP_ETSXDESTROYED; 
    22742138 
    22752139    } else { 
    2276         pj_assert(0); 
     2140        pj_assert(!"Unexpected event"); 
    22772141        return PJ_EBUG; 
    22782142    } 
     
    22812145} 
    22822146 
     2147 
    22832148/* 
    22842149 * Handler for events in state Terminated. 
    22852150 */ 
    2286 static pj_status_t pjsip_tsx_on_state_terminated( pjsip_transaction *tsx, 
    2287                                                   pjsip_event *event) 
     2151static pj_status_t tsx_on_state_terminated( pjsip_transaction *tsx, 
     2152                                            pjsip_event *event) 
    22882153{ 
    22892154    pj_assert(tsx->state == PJSIP_TSX_STATE_TERMINATED); 
    2290  
    2291     PJ_UNUSED_ARG(event); 
     2155    pj_assert(event->type == PJSIP_EVENT_TIMER); 
    22922156 
    22932157    /* Destroy this transaction */ 
     
    22992163 
    23002164 
    2301 static pj_status_t pjsip_tsx_on_state_destroyed(pjsip_transaction *tsx, 
    2302                                                 pjsip_event *event) 
     2165/* 
     2166 * Handler for events in state Destroyed. 
     2167 * Shouldn't happen! 
     2168 */ 
     2169static pj_status_t tsx_on_state_destroyed(pjsip_transaction *tsx, 
     2170                                          pjsip_event *event) 
    23032171{ 
    23042172    PJ_UNUSED_ARG(tsx); 
    23052173    PJ_UNUSED_ARG(event); 
    2306     return PJ_SUCCESS; 
    2307 } 
    2308  
     2174    pj_assert(!"Not expecting any events!!"); 
     2175    return PJ_EBUG; 
     2176} 
     2177 
Note: See TracChangeset for help on using the changeset viewer.