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

Added test functions for UAC transaction

File:
1 edited

Legend:

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

    r107 r109  
    2323#include <pjsip/sip_private.h> 
    2424#include <pjsip/sip_errno.h> 
     25#include <pjsip/sip_module.h> 
    2526#include <pj/os.h> 
    2627#include <pj/log.h> 
     
    3334 
    3435 
    35 #define THIS_FILE    "transport" 
     36#define THIS_FILE    "sip_transport.c" 
     37 
     38/* Prototype. */ 
     39static pj_status_t mod_on_tx_msg(pjsip_tx_data *tdata); 
     40 
     41/* This module has sole purpose to print transmit data to contigous buffer 
     42 * before actually transmitted to the wire.  
     43 */ 
     44static pjsip_module mod_msg_print =  
     45{ 
     46    NULL, NULL,                         /* prev and next        */ 
     47    { "mod-msg-print", 13},             /* Name.                */ 
     48    -1,                                 /* Id                   */ 
     49    PJSIP_MOD_PRIORITY_TRANSPORT_LAYER, /* Priority             */ 
     50    NULL,                               /* User data.           */ 
     51    0,                                  /* Number of methods supported (=0). */ 
     52    { 0 },                              /* Array of methods (none) */ 
     53    NULL,                               /* load()               */ 
     54    NULL,                               /* start()              */ 
     55    NULL,                               /* stop()               */ 
     56    NULL,                               /* unload()             */ 
     57    NULL,                               /* on_rx_request()      */ 
     58    NULL,                               /* on_rx_response()     */ 
     59    &mod_on_tx_msg,                     /* on_tx_request()      */ 
     60    &mod_on_tx_msg,                     /* on_tx_response()     */ 
     61    NULL,                               /* on_tsx_state()       */ 
     62}; 
    3663 
    3764/* 
     
    4774    pj_atomic_t     *tdata_counter; 
    4875#endif 
    49     void           (*msg_cb)(pjsip_endpoint*, pj_status_t, pjsip_rx_data*); 
     76    void           (*on_rx_msg)(pjsip_endpoint*, pj_status_t, pjsip_rx_data*); 
     77    pj_status_t    (*on_tx_msg)(pjsip_endpoint*, pjsip_tx_data*); 
    5078}; 
    5179 
     
    6795} transport_names[] =  
    6896{ 
    69     { PJSIP_TRANSPORT_UNSPECIFIED, 0, {NULL, 0}, 0}, 
     97    { PJSIP_TRANSPORT_UNSPECIFIED, 0, {"Unspecified", 11}, 0}, 
    7098    { PJSIP_TRANSPORT_UDP, 5060, {"UDP", 3}, PJSIP_TRANSPORT_DATAGRAM}, 
    7199    { PJSIP_TRANSPORT_TCP, 5060, {"TCP", 3}, PJSIP_TRANSPORT_RELIABLE}, 
     
    91119                     PJSIP_TRANSPORT_UDP, PJSIP_TRANSPORT_UNSPECIFIED); 
    92120 
     121    if (name->slen == 0) 
     122        return PJSIP_TRANSPORT_UNSPECIFIED; 
     123 
    93124    /* Get transport type from name. */ 
    94125    for (i=0; i<PJ_ARRAY_SIZE(transport_names); ++i) { 
     
    163194} 
    164195 
     196/* 
     197 * Get transport name. 
     198 */ 
     199PJ_DEF(const char*) pjsip_transport_get_type_name(pjsip_transport_type_e type) 
     200{ 
     201    /* Sanity check.  
     202     * Check that transport_names[] are indexed on transport type.  
     203     */ 
     204    PJ_ASSERT_RETURN(transport_names[PJSIP_TRANSPORT_UDP].type == 
     205                     PJSIP_TRANSPORT_UDP, "Unknown"); 
     206 
     207    /* Check that argument is valid. */ 
     208    PJ_ASSERT_RETURN(type < PJ_ARRAY_SIZE(transport_names), "Unknown"); 
     209 
     210    /* Return the port. */ 
     211    return transport_names[type].name.ptr; 
     212} 
    165213 
    166214/***************************************************************************** 
     
    181229 
    182230    PJ_ASSERT_RETURN(mgr && p_tdata, PJ_EINVAL); 
    183  
    184     PJ_LOG(5, ("", "pjsip_tx_data_create")); 
    185231 
    186232    pool = pjsip_endpt_create_pool( mgr->endpt, "tdta%p", 
     
    235281    pj_assert( pj_atomic_get(tdata->ref_cnt) > 0); 
    236282    if (pj_atomic_dec_and_get(tdata->ref_cnt) <= 0) { 
    237         PJ_LOG(5,(tdata->obj_name, "destroying txdata")); 
     283        PJ_LOG(5,(tdata->obj_name, "Destroying txdata %s", 
     284                  pjsip_tx_data_get_info(tdata))); 
    238285#if defined(PJ_DEBUG) && PJ_DEBUG!=0 
    239286        pj_atomic_dec( tdata->mgr->tdata_counter ); 
     
    255302{ 
    256303    tdata->buf.cur = tdata->buf.start; 
     304    tdata->info = NULL; 
    257305} 
    258306 
     
    262310} 
    263311 
    264  
     312static char *get_msg_info(pj_pool_t *pool, const char *obj_name, 
     313                          const pjsip_msg *msg) 
     314{ 
     315    char info_buf[128], *info; 
     316    const pjsip_cseq_hdr *cseq; 
     317    int len; 
     318 
     319    cseq = pjsip_msg_find_hdr(msg, PJSIP_H_CSEQ, NULL); 
     320    PJ_ASSERT_RETURN(cseq != NULL, "INVALID MSG"); 
     321 
     322    if (msg->type == PJSIP_REQUEST_MSG) { 
     323        len = pj_snprintf(info_buf, sizeof(info_buf),  
     324                          "Request msg %.*s/cseq=%d (%s)", 
     325                          msg->line.req.method.name.slen, 
     326                          msg->line.req.method.name.ptr, 
     327                          cseq->cseq, obj_name); 
     328    } else { 
     329        len = pj_snprintf(info_buf, sizeof(info_buf), 
     330                          "Response msg %d/%.*s/cseq=%d (%s)", 
     331                          msg->line.status.code, 
     332                          cseq->method.name.slen, 
     333                          cseq->method.name.ptr, 
     334                          cseq->cseq, obj_name); 
     335    } 
     336 
     337    if (len < 1 || len >= sizeof(info_buf)) { 
     338        return (char*)obj_name; 
     339    } 
     340 
     341    info = pj_pool_alloc(pool, len+1); 
     342    pj_memcpy(info, info_buf, len+1); 
     343 
     344    return info; 
     345} 
     346 
     347PJ_DEF(char*) pjsip_tx_data_get_info( pjsip_tx_data *tdata ) 
     348{ 
     349 
     350    PJ_ASSERT_RETURN(tdata && tdata->msg, "INVALID MSG"); 
     351 
     352    if (tdata->info) 
     353        return tdata->info; 
     354 
     355    pj_lock_acquire(tdata->lock); 
     356    tdata->info = get_msg_info(tdata->pool, tdata->obj_name, tdata->msg); 
     357    pj_lock_release(tdata->lock); 
     358 
     359    return tdata->info; 
     360} 
     361 
     362PJ_DEF(char*) pjsip_rx_data_get_info(pjsip_rx_data *rdata) 
     363{ 
     364    char obj_name[16]; 
     365 
     366    PJ_ASSERT_RETURN(rdata->msg_info.msg, "INVALID MSG"); 
     367 
     368    if (rdata->msg_info.info) 
     369        return rdata->msg_info.info; 
     370 
     371    pj_native_strcpy(obj_name, "rdata"); 
     372    pj_sprintf(obj_name+5, "%p", rdata); 
     373 
     374    rdata->msg_info.info = get_msg_info(rdata->tp_info.pool, obj_name, 
     375                                        rdata->msg_info.msg); 
     376    return rdata->msg_info.info; 
     377} 
    265378 
    266379/***************************************************************************** 
     
    297410    /* Decrement reference count. */ 
    298411    pjsip_tx_data_dec_ref(tdata); 
     412} 
     413 
     414/* This function is called by endpoint for on_tx_request() and on_tx_response() 
     415 * notification. 
     416 */ 
     417static pj_status_t mod_on_tx_msg(pjsip_tx_data *tdata) 
     418{ 
     419    /* Allocate buffer if necessary. */ 
     420    if (tdata->buf.start == NULL) { 
     421        tdata->buf.start = pj_pool_alloc( tdata->pool, PJSIP_MAX_PKT_LEN); 
     422        tdata->buf.cur = tdata->buf.start; 
     423        tdata->buf.end = tdata->buf.start + PJSIP_MAX_PKT_LEN; 
     424    } 
     425 
     426    /* Do we need to reprint? */ 
     427    if (!pjsip_tx_data_is_valid(tdata)) { 
     428        pj_ssize_t size; 
     429 
     430        size = pjsip_msg_print( tdata->msg, tdata->buf.start,  
     431                                tdata->buf.end - tdata->buf.start); 
     432        if (size < 0) { 
     433            return PJSIP_EMSGTOOLONG; 
     434        } 
     435        pj_assert(size != 0); 
     436        tdata->buf.cur += size; 
     437        tdata->buf.cur[size] = '\0'; 
     438    } 
     439 
     440    return PJ_SUCCESS; 
    299441} 
    300442 
     
    321463    } 
    322464 
    323     /* Allocate buffer if necessary. */ 
    324     if (tdata->buf.start == NULL) { 
    325         tdata->buf.start = pj_pool_alloc( tdata->pool, PJSIP_MAX_PKT_LEN); 
    326         tdata->buf.cur = tdata->buf.start; 
    327         tdata->buf.end = tdata->buf.start + PJSIP_MAX_PKT_LEN; 
    328     } 
    329  
    330     /* Do we need to reprint? */ 
    331     if (!pjsip_tx_data_is_valid(tdata)) { 
    332         pj_ssize_t size; 
    333  
    334         size = pjsip_msg_print( tdata->msg, tdata->buf.start,  
    335                                 tdata->buf.end - tdata->buf.start); 
    336         if (size < 0) { 
    337             return PJSIP_EMSGTOOLONG; 
    338         } 
    339         pj_assert(size != 0); 
    340         tdata->buf.cur += size; 
    341         tdata->buf.cur[size] = '\0'; 
     465    /* Fill in tp_info. */ 
     466    tdata->tp_info.transport = tr; 
     467    pj_memcpy(&tdata->tp_info.dst_addr, addr, addr_len); 
     468    tdata->tp_info.dst_addr_len = addr_len; 
     469    if (addr->sa_family == PJ_AF_INET) { 
     470        const char *str_addr; 
     471        str_addr = pj_inet_ntoa(((pj_sockaddr_in*)addr)->sin_addr); 
     472        pj_native_strcpy(tdata->tp_info.dst_name, str_addr); 
     473        tdata->tp_info.dst_port = pj_ntohs(((pj_sockaddr_in*)addr)->sin_port); 
     474    } else { 
     475        pj_native_strcpy(tdata->tp_info.dst_name, "<unknown>"); 
     476        tdata->tp_info.dst_port = 0; 
     477    } 
     478 
     479    /* Distribute to modules.  
     480     * When the message reach mod_msg_print, the contents of the message will 
     481     * be "printed" to contiguous buffer. 
     482     */ 
     483    if (tr->tpmgr->on_tx_msg) { 
     484        status = (*tr->tpmgr->on_tx_msg)(tr->endpt, tdata); 
     485        if (status != PJ_SUCCESS) 
     486            return status; 
    342487    } 
    343488 
     
    450595} 
    451596 
    452  
    453 /** 
    454  * Unregister transport. 
    455  */ 
    456 PJ_DEF(pj_status_t) pjsip_transport_unregister( pjsip_tpmgr *mgr, 
    457                                                 pjsip_transport *tp) 
     597/* Force destroy transport (e.g. during transport manager shutdown. */ 
     598static pj_status_t destroy_transport( pjsip_tpmgr *mgr, 
     599                                      pjsip_transport *tp ) 
    458600{ 
    459601    int key_len; 
    460  
    461     /* Must have no user. */ 
    462     PJ_ASSERT_RETURN(pj_atomic_get(tp->ref_cnt) == 0, PJSIP_EBUSY); 
    463602 
    464603    pj_lock_acquire(tp->lock); 
     
    484623    /* Destroy. */ 
    485624    return tp->destroy(tp); 
     625} 
     626 
     627/** 
     628 * Unregister transport. 
     629 */ 
     630PJ_DEF(pj_status_t) pjsip_transport_unregister( pjsip_tpmgr *mgr, 
     631                                                pjsip_transport *tp) 
     632{ 
     633    /* Must have no user. */ 
     634    PJ_ASSERT_RETURN(pj_atomic_get(tp->ref_cnt) == 0, PJSIP_EBUSY); 
     635 
     636    /* Destroy. */ 
     637    return destroy_transport(mgr, tp); 
    486638} 
    487639 
     
    557709PJ_DEF(pj_status_t) pjsip_tpmgr_create( pj_pool_t *pool, 
    558710                                        pjsip_endpoint *endpt, 
    559                                         void (*cb)(pjsip_endpoint*, 
    560                                                    pj_status_t, 
    561                                                    pjsip_rx_data *), 
     711                                        void (*rx_cb)(pjsip_endpoint*, 
     712                                                      pj_status_t, 
     713                                                      pjsip_rx_data *), 
     714                                        pj_status_t (*tx_cb)(pjsip_endpoint*, 
     715                                                             pjsip_tx_data*), 
    562716                                        pjsip_tpmgr **p_mgr) 
    563717{ 
     
    565719    pj_status_t status; 
    566720 
    567     PJ_ASSERT_RETURN(pool && endpt && cb && p_mgr, PJ_EINVAL); 
    568  
    569     PJ_LOG(5, (THIS_FILE, "pjsip_tpmgr_create()")); 
    570  
     721    PJ_ASSERT_RETURN(pool && endpt && rx_cb && p_mgr, PJ_EINVAL); 
     722 
     723    /* Register mod_msg_print module. */ 
     724    status = pjsip_endpt_register_module(endpt, &mod_msg_print); 
     725    if (status != PJ_SUCCESS) 
     726        return status; 
     727 
     728    /* Create and initialize transport manager. */ 
    571729    mgr = pj_pool_zalloc(pool, sizeof(*mgr)); 
    572730    mgr->endpt = endpt; 
    573     mgr->msg_cb = cb; 
     731    mgr->on_rx_msg = rx_cb; 
     732    mgr->on_tx_msg = tx_cb; 
    574733    pj_list_init(&mgr->factory_list); 
    575734 
     
    588747#endif 
    589748 
     749    PJ_LOG(5, (THIS_FILE, "Transport manager created.")); 
     750 
    590751    *p_mgr = mgr; 
    591752    return PJ_SUCCESS; 
     
    601762    pj_hash_iterator_t itr_val; 
    602763    pj_hash_iterator_t *itr; 
     764    pjsip_endpoint *endpt = mgr->endpt; 
    603765     
    604     PJ_LOG(5, (THIS_FILE, "pjsip_tpmgr_destroy()")); 
    605  
    606 #if defined(PJ_DEBUG) && PJ_DEBUG!=0 
    607     pj_assert(pj_atomic_get(mgr->tdata_counter) == 0); 
    608 #endif 
     766    PJ_LOG(5, (THIS_FILE, "Destroying transport manager")); 
    609767 
    610768    pj_lock_acquire(mgr->lock); 
     
    619777        next = pj_hash_next(mgr->table, itr); 
    620778 
    621         pj_atomic_set(transport->ref_cnt, 0); 
    622         pjsip_transport_unregister(mgr, transport); 
     779        destroy_transport(mgr, transport); 
    623780 
    624781        itr = next; 
     
    627784    pj_lock_release(mgr->lock); 
    628785    pj_lock_destroy(mgr->lock); 
     786 
     787    /* Unregister mod_msg_print. */ 
     788    if (mod_msg_print.id != -1) { 
     789        pjsip_endpt_unregister_module(endpt, &mod_msg_print); 
     790    } 
     791 
     792#if defined(PJ_DEBUG) && PJ_DEBUG!=0 
     793    /* If you encounter assert error on this line, it means there are 
     794     * leakings in transmit data (i.e. some transmit data have not been 
     795     * destroyed). 
     796     */ 
     797    pj_assert(pj_atomic_get(mgr->tdata_counter) == 0); 
     798#endif 
    629799 
    630800    return PJ_SUCCESS; 
     
    686856            if (msg_status != PJ_SUCCESS) { 
    687857                if (remaining_len == PJSIP_MAX_PKT_LEN) { 
    688                     mgr->msg_cb(mgr->endpt, PJSIP_ERXOVERFLOW, rdata); 
     858                    mgr->on_rx_msg(mgr->endpt, PJSIP_ERXOVERFLOW, rdata); 
    689859                    /* Exhaust all data. */ 
    690860                    return rdata->pkt_info.len; 
     
    703873            pjsip_parse_rdata( current_pkt, msg_fragment_size, rdata); 
    704874        if (msg == NULL) { 
    705             mgr->msg_cb(mgr->endpt, PJSIP_EINVALIDMSG, rdata); 
     875            mgr->on_rx_msg(mgr->endpt, PJSIP_EINVALIDMSG, rdata); 
    706876            goto finish_process_fragment; 
    707877        } 
     
    714884            rdata->msg_info.cseq == NULL)  
    715885        { 
    716             mgr->msg_cb(mgr->endpt, PJSIP_EMISSINGHDR, rdata); 
     886            mgr->on_rx_msg(mgr->endpt, PJSIP_EMISSINGHDR, rdata); 
    717887            goto finish_process_fragment; 
    718888        } 
     
    738908                hdr = pjsip_msg_find_hdr(msg, PJSIP_H_VIA, hdr); 
    739909                if (hdr) { 
    740                     mgr->msg_cb(mgr->endpt, PJSIP_EMULTIPLEVIA, rdata); 
     910                    mgr->on_rx_msg(mgr->endpt, PJSIP_EMULTIPLEVIA, rdata); 
    741911                    goto finish_process_fragment; 
    742912                } 
     
    746916        /* Call the transport manager's upstream message callback. 
    747917         */ 
    748         mgr->msg_cb(mgr->endpt, PJ_SUCCESS, rdata); 
     918        mgr->on_rx_msg(mgr->endpt, PJ_SUCCESS, rdata); 
    749919 
    750920 
     
    796966        const pj_sockaddr *remote_addr = (const pj_sockaddr*)remote; 
    797967 
    798         /* For datagram transports, try lookup with zero address.  
    799          */ 
    800         if ( (flag & PJSIP_TRANSPORT_DATAGRAM) &&  
    801              (remote_addr->sa_family == PJ_AF_INET))  
     968        /* Ignore address for loop transports. */ 
     969        if (type == PJSIP_TRANSPORT_LOOP || 
     970                 type == PJSIP_TRANSPORT_LOOP_DGRAM) 
    802971        { 
    803972            pj_sockaddr_in *addr = (pj_sockaddr_in*)&key.addr; 
    804973 
    805974            pj_memset(addr, 0, sizeof(pj_sockaddr_in)); 
     975            key_len = sizeof(key.type) + sizeof(pj_sockaddr_in); 
     976            transport = pj_hash_get(mgr->table, &key, key_len); 
     977        } 
     978        /* For datagram INET transports, try lookup with zero address. 
     979         */ 
     980        else if ((flag & PJSIP_TRANSPORT_DATAGRAM) &&  
     981                 (remote_addr->sa_family == PJ_AF_INET))  
     982        { 
     983            pj_sockaddr_in *addr = (pj_sockaddr_in*)&key.addr; 
     984 
     985            pj_memset(addr, 0, sizeof(pj_sockaddr_in)); 
    806986            addr->sin_family = PJ_AF_INET; 
    807             addr->sin_addr.s_addr = 0; 
    808             addr->sin_port = 0; 
    809987 
    810988            key_len = sizeof(key.type) + sizeof(pj_sockaddr_in); 
Note: See TracChangeset for help on using the changeset viewer.