Ignore:
Timestamp:
Dec 30, 2005 11:50:15 PM (18 years ago)
Author:
bennylp
Message:

Basic module, transport, and sending messages

File:
1 edited

Legend:

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

    r105 r106  
    2424#include <pjsip/sip_transaction.h> 
    2525#include <pjsip/sip_module.h> 
     26#include <pjsip/sip_errno.h> 
    2627#include <pj/log.h> 
    2728#include <pj/string.h> 
     
    5253static pj_str_t str_TEXT = { "text", 4}, 
    5354                str_PLAIN = { "plain", 5 }; 
    54 static int aux_mod_id; 
    55  
    56 struct aux_tsx_data 
    57 { 
    58     void *token; 
    59     void (*cb)(void*,pjsip_event*); 
    60 }; 
    61  
    62 static pj_status_t aux_tsx_init( pjsip_endpoint *endpt, 
    63                                  struct pjsip_module *mod, pj_uint32_t id ) 
    64 { 
    65     PJ_UNUSED_ARG(endpt); 
    66     PJ_UNUSED_ARG(mod); 
    67  
    68     aux_mod_id = id; 
    69     return 0; 
    70 } 
    71  
    72 static void aux_tsx_handler( struct pjsip_module *mod, pjsip_event *event ) 
    73 { 
    74     pjsip_transaction *tsx; 
    75     struct aux_tsx_data *tsx_data; 
    76  
    77     PJ_UNUSED_ARG(mod); 
    78  
    79     if (event->type != PJSIP_EVENT_TSX_STATE) 
    80         return; 
    81  
    82     pj_assert(event->body.tsx_state.tsx != NULL); 
    83     tsx = event->body.tsx_state.tsx; 
    84     if (tsx == NULL) 
    85         return; 
    86     if (tsx->module_data[aux_mod_id] == NULL) 
    87         return; 
    88     if (tsx->status_code < 200) 
    89         return; 
    90  
    91     /* Call the callback, if any, and prevent the callback to be called again 
    92      * by clearing the transaction's module_data. 
    93      */ 
    94     tsx_data = tsx->module_data[aux_mod_id]; 
    95     tsx->module_data[aux_mod_id] = NULL; 
    96  
    97     if (tsx_data->cb) { 
    98         (*tsx_data->cb)(tsx_data->token, event); 
    99     } 
    100 } 
    101  
    102 pjsip_module aux_tsx_module =  
    103 { 
    104     { "Aux-Tsx", 7},        /* Name.            */ 
    105     0,                      /* Flag             */ 
    106     128,                    /* Priority         */ 
    107     NULL,                   /* Arbitrary data.  */ 
    108     0,                      /* Number of methods supported (none). */ 
    109     { 0 },                  /* Array of methods (none) */ 
    110     &aux_tsx_init,          /* init_module()    */ 
    111     NULL,                   /* start_module()   */ 
    112     NULL,                   /* deinit_module()  */ 
    113     &aux_tsx_handler,       /* tsx_handler()    */ 
    114 }; 
    115  
    116 PJ_DEF(pj_status_t) pjsip_endpt_send_request(  pjsip_endpoint *endpt, 
    117                                                pjsip_tx_data *tdata, 
    118                                                int timeout, 
    119                                                void *token, 
    120                                                void (*cb)(void*,pjsip_event*)) 
    121 { 
    122     pjsip_transaction *tsx; 
    123     struct aux_tsx_data *tsx_data; 
    124     pj_status_t status; 
    125  
    126     status = pjsip_endpt_create_tsx(endpt, &tsx); 
    127     if (!tsx) { 
    128         pjsip_tx_data_dec_ref(tdata); 
    129         return -1; 
    130     } 
    131  
    132     tsx_data = pj_pool_alloc(tsx->pool, sizeof(struct aux_tsx_data)); 
    133     tsx_data->token = token; 
    134     tsx_data->cb = cb; 
    135     tsx->module_data[aux_mod_id] = tsx_data; 
    136  
    137     if (pjsip_tsx_init_uac(tsx, tdata) != 0) { 
    138         pjsip_endpt_destroy_tsx(endpt, tsx); 
    139         pjsip_tx_data_dec_ref(tdata); 
    140         return -1; 
    141     } 
    142  
    143     pjsip_endpt_register_tsx(endpt, tsx); 
    144     pjsip_tx_data_invalidate_msg(tdata); 
    145     pjsip_tsx_on_tx_msg(tsx, tdata); 
    146     pjsip_tx_data_dec_ref(tdata); 
    147     return 0; 
    148 } 
    14955 
    15056/* 
     
    17076    pjsip_msg *msg; 
    17177    pjsip_msg_body *body; 
     78    pjsip_via_hdr *via; 
    17279    const pjsip_hdr *endpt_hdr; 
    17380 
     
    205112    /* Add CSeq header. */ 
    206113    pjsip_msg_add_hdr(msg, (void*)param_cseq); 
     114 
     115    /* Add a blank Via header. */ 
     116    via = pjsip_via_hdr_create(tdata->pool); 
     117    via->rport_param = 0; 
     118    pjsip_msg_insert_first_hdr(msg, (void*)via); 
    207119 
    208120    /* Create message body. */ 
     
    217129        msg->body = body; 
    218130    } 
     131 
     132    PJ_LOG(4,(THIS_FILE, "Request %s (CSeq=%d/%.*s) created.",  
     133                         tdata->obj_name,  
     134                         param_cseq->cseq,  
     135                         param_cseq->method.name.slen, 
     136                         param_cseq->method.name.ptr)); 
     137 
    219138} 
    220139 
     
    329248    PJ_END 
    330249 
    331     PJ_LOG(4,(THIS_FILE, "Request %s (%d %.*s) created.",  
    332                         tdata->obj_name,  
    333                         cseq->cseq,  
    334                         cseq->method.name.slen, 
    335                         cseq->method.name.ptr)); 
    336  
    337250    *p_tdata = tdata; 
    338251    return PJ_SUCCESS; 
     
    367280    PJ_LOG(5,(THIS_FILE, "Entering pjsip_endpt_create_request_from_hdr()")); 
    368281 
     282    /* Check arguments. */ 
     283    PJ_ASSERT_RETURN(endpt && method && param_target && param_from && 
     284                     param_to && p_tdata, PJ_EINVAL); 
     285 
     286    /* Create new transmit data. */ 
    369287    status = pjsip_endpt_create_tdata(endpt, &tdata); 
    370288    if (status != PJ_SUCCESS) 
    371289        return status; 
    372290 
     291    /* Set initial reference counter to 1. */ 
    373292    pjsip_tx_data_add_ref(tdata); 
    374293 
    375294    PJ_TRY { 
     295        /* Duplicate target URI and headers. */ 
    376296        target = pjsip_uri_clone(tdata->pool, param_target); 
    377         from = pjsip_hdr_shallow_clone(tdata->pool, param_from); 
     297        from = pjsip_hdr_clone(tdata->pool, param_from); 
    378298        pjsip_fromto_set_from(from); 
    379         to = pjsip_hdr_shallow_clone(tdata->pool, param_to); 
     299        to = pjsip_hdr_clone(tdata->pool, param_to); 
    380300        pjsip_fromto_set_to(to); 
    381301        if (param_contact) 
    382             contact = pjsip_hdr_shallow_clone(tdata->pool, param_contact); 
     302            contact = pjsip_hdr_clone(tdata->pool, param_contact); 
    383303        else 
    384304            contact = NULL; 
    385         call_id = pjsip_hdr_shallow_clone(tdata->pool, param_call_id); 
     305        call_id = pjsip_hdr_clone(tdata->pool, param_call_id); 
    386306        cseq = pjsip_cseq_hdr_create(tdata->pool); 
    387307        if (param_cseq >= 0) 
     
    391311        pjsip_method_copy(tdata->pool, &cseq->method, method); 
    392312 
     313        /* Copy headers to the request. */ 
    393314        init_request_throw(endpt, tdata, &cseq->method, target, from, to,  
    394315                           contact, call_id, cseq, param_text); 
     
    400321    PJ_END; 
    401322 
    402     PJ_LOG(4,(THIS_FILE, "Request %s (%d %.*s) created.",  
    403                         tdata->obj_name,  
    404                         cseq->cseq,  
    405                         cseq->method.name.slen, 
    406                         cseq->method.name.ptr)); 
    407  
    408323    *p_tdata = tdata; 
    409324    return PJ_SUCCESS; 
     
    419334PJ_DEF(pj_status_t) pjsip_endpt_create_response( pjsip_endpoint *endpt, 
    420335                                                 const pjsip_rx_data *rdata, 
    421                                                  int code, 
     336                                                 int st_code, 
     337                                                 const pj_str_t *st_text, 
    422338                                                 pjsip_tx_data **p_tdata) 
    423339{ 
     
    435351    /* Log this action. */ 
    436352    PJ_LOG(5,(THIS_FILE, "pjsip_endpt_create_response(rdata=%p, code=%d)",  
    437                          rdata, code)); 
     353                         rdata, st_code)); 
    438354 
    439355    /* Create a new transmit buffer. */ 
     
    442358        return status; 
    443359 
     360    /* Set initial reference count to 1. */ 
     361    pjsip_tx_data_add_ref(tdata); 
     362 
    444363    /* Create new response message. */ 
    445364    tdata->msg = msg = pjsip_msg_create(tdata->pool, PJSIP_RESPONSE_MSG); 
    446365 
    447366    /* Set status code and reason text. */ 
    448     msg->line.status.code = code; 
    449     msg->line.status.reason = *pjsip_get_status_text(code); 
     367    msg->line.status.code = st_code; 
     368    if (st_text) 
     369        pj_strdup(tdata->pool, &msg->line.status.reason, st_text); 
     370    else 
     371        msg->line.status.reason = *pjsip_get_status_text(st_code); 
    450372 
    451373    /* Set TX data attributes. */ 
     
    501423 * and one must not use this function to generate such ACK. 
    502424 */ 
    503 PJ_DEF(void) pjsip_endpt_create_ack(pjsip_endpoint *endpt, 
    504                                     pjsip_tx_data *tdata, 
    505                                     const pjsip_rx_data *rdata ) 
    506 { 
    507     pjsip_msg *ack_msg, *invite_msg; 
     425PJ_DEF(pj_status_t) pjsip_endpt_create_ack( pjsip_endpoint *endpt, 
     426                                            const pjsip_tx_data *tdata, 
     427                                            const pjsip_rx_data *rdata, 
     428                                            pjsip_tx_data **ack_tdata) 
     429{ 
     430    pjsip_tx_data *ack = NULL; 
     431    const pjsip_msg *invite_msg; 
     432    const pjsip_from_hdr *from_hdr; 
     433    const pjsip_to_hdr *to_hdr; 
     434    const pjsip_cid_hdr *cid_hdr; 
     435    const pjsip_cseq_hdr *cseq_hdr; 
     436    const pjsip_hdr *hdr; 
    508437    pjsip_to_hdr *to; 
    509     pjsip_from_hdr *from; 
    510     pjsip_cseq_hdr *cseq; 
    511     pjsip_hdr *hdr; 
    512  
    513     /* Make compiler happy. */ 
    514     PJ_UNUSED_ARG(endpt); 
     438    pj_status_t status; 
     439 
     440    /* Log this action. */ 
     441    PJ_LOG(5,(THIS_FILE, "pjsip_endpt_create_ack(rdata=%p)", rdata)); 
    515442 
    516443    /* rdata must be a final response. */ 
     
    518445              rdata->msg_info.msg->line.status.code >= 300); 
    519446 
    520     /* Log this action. */ 
    521     PJ_LOG(5,(THIS_FILE, "pjsip_endpt_create_ack(rdata=%p)", rdata)); 
    522  
    523     /* Create new request message. */ 
    524     ack_msg = pjsip_msg_create(tdata->pool, PJSIP_REQUEST_MSG); 
    525     pjsip_method_set( &ack_msg->line.req.method, PJSIP_ACK_METHOD ); 
     447    /* Initialize return value to NULL. */ 
     448    *ack_tdata = NULL; 
    526449 
    527450    /* The original INVITE message. */ 
    528451    invite_msg = tdata->msg; 
    529452 
    530     /* Copy Request-Uri from the original INVITE. */ 
    531     ack_msg->line.req.uri = invite_msg->line.req.uri; 
    532      
    533     /* Copy Call-ID from the original INVITE */ 
    534     hdr = pjsip_msg_find_remove_hdr( invite_msg, PJSIP_H_CALL_ID, NULL); 
    535     pjsip_msg_add_hdr( ack_msg, hdr ); 
    536  
    537     /* Copy From header from the original INVITE. */ 
    538     from = (pjsip_from_hdr*)pjsip_msg_find_remove_hdr(invite_msg,  
    539                                                       PJSIP_H_FROM, NULL); 
    540     pjsip_msg_add_hdr( ack_msg, (pjsip_hdr*)from ); 
    541  
    542     /* Copy To header from the original INVITE. */ 
    543     to = (pjsip_to_hdr*)pjsip_msg_find_remove_hdr( invite_msg,  
    544                                                    PJSIP_H_TO, NULL); 
    545     pj_strdup(tdata->pool, &to->tag, &rdata->msg_info.to->tag); 
    546     pjsip_msg_add_hdr( ack_msg, (pjsip_hdr*)to ); 
     453    /* Get the headers from original INVITE request. */ 
     454#   define FIND_HDR(m,HNAME) pjsip_msg_find_hdr(m, PJSIP_H_##HNAME, NULL) 
     455 
     456    from_hdr = (const pjsip_from_hdr*) FIND_HDR(invite_msg, FROM); 
     457    PJ_ASSERT_ON_FAIL(from_hdr != NULL, goto on_missing_hdr); 
     458 
     459    to_hdr = (const pjsip_to_hdr*) FIND_HDR(invite_msg, TO); 
     460    PJ_ASSERT_ON_FAIL(to_hdr != NULL, goto on_missing_hdr); 
     461 
     462    cid_hdr = (const pjsip_cid_hdr*) FIND_HDR(invite_msg, CALL_ID); 
     463    PJ_ASSERT_ON_FAIL(to_hdr != NULL, goto on_missing_hdr); 
     464 
     465    cseq_hdr = (const pjsip_cseq_hdr*) FIND_HDR(invite_msg, CSEQ); 
     466    PJ_ASSERT_ON_FAIL(to_hdr != NULL, goto on_missing_hdr); 
     467 
     468#   undef FIND_HDR 
     469 
     470    /* Create new request message from the headers. */ 
     471    status = pjsip_endpt_create_request_from_hdr(endpt,  
     472                                                 &pjsip_ack_method, 
     473                                                 tdata->msg->line.req.uri, 
     474                                                 from_hdr, to_hdr, 
     475                                                 NULL, cid_hdr, 
     476                                                 cseq_hdr->cseq, NULL, 
     477                                                 &ack); 
     478 
     479    if (status != PJ_SUCCESS) 
     480        return status; 
     481 
     482    /* Update tag in To header with the one from the response (if any). */ 
     483    to = (pjsip_to_hdr*) pjsip_msg_find_hdr(ack->msg, PJSIP_H_TO, NULL); 
     484    pj_strdup(ack->pool, &to->tag, &rdata->msg_info.to->tag); 
    547485 
    548486    /* Must contain single Via, just as the original INVITE. */ 
    549     hdr = pjsip_msg_find_remove_hdr( invite_msg, PJSIP_H_VIA, NULL); 
    550     pjsip_msg_insert_first_hdr( ack_msg, hdr ); 
    551  
    552     /* Must have the same CSeq value as the original INVITE, but method  
    553      * changed to ACK  
    554      */ 
    555     cseq = (pjsip_cseq_hdr*) pjsip_msg_find_remove_hdr( invite_msg,  
    556                                                         PJSIP_H_CSEQ, NULL); 
    557     pjsip_method_set( &cseq->method, PJSIP_ACK_METHOD ); 
    558     pjsip_msg_add_hdr( ack_msg, (pjsip_hdr*) cseq ); 
     487    hdr = pjsip_msg_find_hdr( invite_msg, PJSIP_H_VIA, NULL); 
     488    if (hdr) { 
     489        pjsip_msg_insert_first_hdr( ack->msg, pjsip_hdr_clone(ack->pool,hdr) ); 
     490    } 
    559491 
    560492    /* If the original INVITE has Route headers, those header fields MUST  
    561493     * appear in the ACK. 
    562494     */ 
    563     hdr = pjsip_msg_find_remove_hdr( invite_msg, PJSIP_H_ROUTE, NULL); 
     495    hdr = pjsip_msg_find_hdr( invite_msg, PJSIP_H_ROUTE, NULL); 
    564496    while (hdr != NULL) { 
    565         pjsip_msg_add_hdr( ack_msg, hdr ); 
    566         hdr = pjsip_msg_find_remove_hdr( invite_msg, PJSIP_H_ROUTE, NULL); 
    567     } 
    568  
    569     /* Set the message in the "tdata" to point to the ACK message. */ 
    570     tdata->msg = ack_msg; 
    571  
    572     /* Reset transmit packet buffer, to force 're-printing' of message. */ 
    573     tdata->buf.cur = tdata->buf.start; 
     497        pjsip_msg_add_hdr( ack->msg, pjsip_hdr_clone(ack->pool, hdr) ); 
     498        hdr = hdr->next; 
     499        if (hdr == &invite_msg->hdr) 
     500            break; 
     501        hdr = pjsip_msg_find_hdr( invite_msg, PJSIP_H_ROUTE, hdr); 
     502    } 
    574503 
    575504    /* We're done. 
    576505     * "tdata" parameter now contains the ACK message. 
    577506     */ 
     507    *ack_tdata = ack; 
     508    return PJ_SUCCESS; 
     509 
     510on_missing_hdr: 
     511    if (ack) 
     512        pjsip_tx_data_dec_ref(ack); 
     513    return PJSIP_EMISSINGHDR; 
    578514} 
    579515 
     
    584520 */ 
    585521PJ_DEF(pj_status_t) pjsip_endpt_create_cancel( pjsip_endpoint *endpt, 
    586                                                pjsip_tx_data *req_tdata, 
     522                                               const pjsip_tx_data *req_tdata, 
    587523                                               pjsip_tx_data **p_tdata) 
    588524{ 
    589     pjsip_msg *req_msg; /* the original request. */ 
    590     pjsip_tx_data *cancel_tdata; 
    591     pjsip_msg *cancel_msg; 
    592     pjsip_hdr *hdr; 
    593     pjsip_cseq_hdr *req_cseq, *cseq; 
    594     pjsip_uri *req_uri; 
     525    pjsip_tx_data *cancel_tdata = NULL; 
     526    const pjsip_from_hdr *from_hdr; 
     527    const pjsip_to_hdr *to_hdr; 
     528    const pjsip_cid_hdr *cid_hdr; 
     529    const pjsip_cseq_hdr *cseq_hdr; 
     530    const pjsip_hdr *hdr; 
    595531    pj_status_t status; 
    596532 
     
    598534    PJ_LOG(5,(THIS_FILE, "pjsip_endpt_create_cancel(tdata=%p)", req_tdata)); 
    599535 
    600     /* Get the original request. */ 
    601     req_msg = req_tdata->msg; 
    602  
    603536    /* The transmit buffer must INVITE request. */ 
    604     PJ_ASSERT_RETURN(req_msg->type == PJSIP_REQUEST_MSG && 
    605                      req_msg->line.req.method.id == PJSIP_INVITE_METHOD, 
     537    PJ_ASSERT_RETURN(req_tdata->msg->type == PJSIP_REQUEST_MSG && 
     538                     req_tdata->msg->line.req.method.id == PJSIP_INVITE_METHOD, 
    606539                     PJ_EINVAL); 
    607540 
    608     /* Create new transmit buffer. */ 
    609     status = pjsip_endpt_create_tdata( endpt, &cancel_tdata); 
    610     if (status != PJ_SUCCESS) { 
     541    /* Get the headers from original INVITE request. */ 
     542#   define FIND_HDR(m,HNAME) pjsip_msg_find_hdr(m, PJSIP_H_##HNAME, NULL) 
     543 
     544    from_hdr = (const pjsip_from_hdr*) FIND_HDR(req_tdata->msg, FROM); 
     545    PJ_ASSERT_ON_FAIL(from_hdr != NULL, goto on_missing_hdr); 
     546 
     547    to_hdr = (const pjsip_to_hdr*) FIND_HDR(req_tdata->msg, TO); 
     548    PJ_ASSERT_ON_FAIL(to_hdr != NULL, goto on_missing_hdr); 
     549 
     550    cid_hdr = (const pjsip_cid_hdr*) FIND_HDR(req_tdata->msg, CALL_ID); 
     551    PJ_ASSERT_ON_FAIL(to_hdr != NULL, goto on_missing_hdr); 
     552 
     553    cseq_hdr = (const pjsip_cseq_hdr*) FIND_HDR(req_tdata->msg, CSEQ); 
     554    PJ_ASSERT_ON_FAIL(to_hdr != NULL, goto on_missing_hdr); 
     555 
     556#   undef FIND_HDR 
     557 
     558    /* Create new request message from the headers. */ 
     559    status = pjsip_endpt_create_request_from_hdr(endpt,  
     560                                                 &pjsip_cancel_method, 
     561                                                 req_tdata->msg->line.req.uri, 
     562                                                 from_hdr, to_hdr, 
     563                                                 NULL, cid_hdr, 
     564                                                 cseq_hdr->cseq, NULL, 
     565                                                 &cancel_tdata); 
     566 
     567    if (status != PJ_SUCCESS) 
    611568        return status; 
    612     } 
    613  
    614     /* Create CANCEL request message. */ 
    615     cancel_msg = pjsip_msg_create(cancel_tdata->pool, PJSIP_REQUEST_MSG); 
    616     cancel_tdata->msg = cancel_msg; 
    617  
    618     /* Request-URI, Call-ID, From, To, and the numeric part of the CSeq are 
    619      * copied from the original request. 
    620      */ 
    621     /* Set request line. */ 
    622     pjsip_method_set(&cancel_msg->line.req.method, PJSIP_CANCEL_METHOD); 
    623     req_uri = req_msg->line.req.uri; 
    624     cancel_msg->line.req.uri = pjsip_uri_clone(cancel_tdata->pool, req_uri); 
    625  
    626     /* Copy Call-ID */ 
    627     hdr = pjsip_msg_find_hdr(req_msg, PJSIP_H_CALL_ID, NULL); 
    628     pjsip_msg_add_hdr(cancel_msg, pjsip_hdr_clone(cancel_tdata->pool, hdr)); 
    629  
    630     /* Copy From header. */ 
    631     hdr = pjsip_msg_find_hdr(req_msg, PJSIP_H_FROM, NULL); 
    632     pjsip_msg_add_hdr(cancel_msg, pjsip_hdr_clone(cancel_tdata->pool, hdr)); 
    633  
    634     /* Copy To header. */ 
    635     hdr = pjsip_msg_find_hdr(req_msg, PJSIP_H_TO, NULL); 
    636     pjsip_msg_add_hdr(cancel_msg, pjsip_hdr_clone(cancel_tdata->pool, hdr)); 
    637  
    638     /* Create new CSeq with equal number, but method set to CANCEL. */ 
    639     req_cseq = (pjsip_cseq_hdr*) pjsip_msg_find_hdr(req_msg, PJSIP_H_CSEQ, NULL); 
    640     cseq = pjsip_cseq_hdr_create(cancel_tdata->pool); 
    641     cseq->cseq = req_cseq->cseq; 
    642     pjsip_method_set(&cseq->method, PJSIP_CANCEL_METHOD); 
    643     pjsip_msg_add_hdr(cancel_msg, (pjsip_hdr*)cseq); 
    644569 
    645570    /* Must only have single Via which matches the top-most Via in the  
    646571     * request being cancelled.  
    647572     */ 
    648     hdr = pjsip_msg_find_hdr(req_msg, PJSIP_H_VIA, NULL); 
    649     pjsip_msg_insert_first_hdr(cancel_msg,  
    650                                pjsip_hdr_clone(cancel_tdata->pool, hdr)); 
     573    hdr = pjsip_msg_find_hdr(req_tdata->msg, PJSIP_H_VIA, NULL); 
     574    if (hdr) { 
     575        pjsip_msg_insert_first_hdr(cancel_tdata->msg,  
     576                                   pjsip_hdr_clone(cancel_tdata->pool, hdr)); 
     577    } 
    651578 
    652579    /* If the original request has Route header, the CANCEL request must also 
     
    654581     * Copy "Route" header from the request. 
    655582     */ 
    656     hdr = pjsip_msg_find_hdr(req_msg, PJSIP_H_ROUTE, NULL); 
     583    hdr = pjsip_msg_find_hdr(req_tdata->msg, PJSIP_H_ROUTE, NULL); 
    657584    while (hdr != NULL) { 
    658         pjsip_msg_add_hdr(cancel_msg, pjsip_hdr_clone(cancel_tdata->pool, hdr)); 
     585        pjsip_msg_add_hdr(cancel_tdata->msg,  
     586                          pjsip_hdr_clone(cancel_tdata->pool, hdr)); 
    659587        hdr = hdr->next; 
    660         if (hdr != &cancel_msg->hdr) 
    661             hdr = pjsip_msg_find_hdr(req_msg, PJSIP_H_ROUTE, hdr); 
     588        if (hdr != &cancel_tdata->msg->hdr) 
     589            hdr = pjsip_msg_find_hdr(cancel_tdata->msg, PJSIP_H_ROUTE, hdr); 
    662590        else 
    663591            break; 
     
    669597    *p_tdata = cancel_tdata; 
    670598    return PJ_SUCCESS; 
    671 } 
    672  
    673 /* Get the address parameters (host, port, flag, TTL, etc) to send the 
    674  * response. 
    675  */ 
    676 PJ_DEF(pj_status_t) pjsip_get_response_addr(pj_pool_t *pool, 
    677                                             const pjsip_transport *req_transport, 
    678                                             const pjsip_via_hdr *via, 
    679                                             pjsip_host_info *send_addr) 
    680 { 
    681     /* Determine the destination address (section 18.2.2): 
    682      * - for TCP, SCTP, or TLS, send the response using the transport where 
    683      *   the request was received. 
    684      * - if maddr parameter is present, send to this address using the port 
    685      *   in sent-by or 5060. If multicast is used, the TTL in the Via must 
    686      *   be used, or 1 if ttl parameter is not present. 
    687      * - otherwise if received parameter is present, set to this address. 
    688      * - otherwise send to the address in sent-by. 
     599 
     600on_missing_hdr: 
     601    if (cancel_tdata) 
     602        pjsip_tx_data_dec_ref(cancel_tdata); 
     603    return PJSIP_EMISSINGHDR; 
     604} 
     605 
     606 
     607/* 
     608 * Find which destination to be used to send the request message, based 
     609 * on the request URI and Route headers in the message. The procedure 
     610 * used here follows the guidelines on sending the request in RFC 3261 
     611 * chapter 8.1.2. 
     612 */ 
     613PJ_DEF(pj_status_t) pjsip_get_request_addr( pjsip_tx_data *tdata, 
     614                                            pjsip_host_info *dest_info ) 
     615{ 
     616    const pjsip_uri *new_request_uri, *target_uri; 
     617    const pjsip_name_addr *topmost_route_uri; 
     618    pjsip_route_hdr *first_route_hdr, *last_route_hdr; 
     619     
     620    PJ_ASSERT_RETURN(tdata->msg->type == PJSIP_REQUEST_MSG,  
     621                     PJSIP_ENOTREQUESTMSG); 
     622    PJ_ASSERT_RETURN(dest_info != NULL, PJ_EINVAL); 
     623 
     624    /* Get the first "Route" header from the message. If the message doesn't 
     625     * have any "Route" headers but the endpoint has, then copy the "Route" 
     626     * headers from the endpoint first. 
    689627     */ 
    690     send_addr->flag = req_transport->flag; 
    691     send_addr->type = req_transport->key.type; 
    692  
    693     if (PJSIP_TRANSPORT_IS_RELIABLE(req_transport)) { 
    694         pj_strdup( pool, &send_addr->addr.host,  
    695                    &req_transport->remote_name.host); 
    696         send_addr->addr.port = req_transport->remote_name.port; 
    697  
     628    last_route_hdr = first_route_hdr =  
     629        pjsip_msg_find_hdr(tdata->msg, PJSIP_H_ROUTE, NULL); 
     630    if (first_route_hdr) { 
     631        topmost_route_uri = &first_route_hdr->name_addr; 
     632        while (last_route_hdr->next != (void*)&tdata->msg->hdr) { 
     633            pjsip_route_hdr *hdr; 
     634            hdr = pjsip_msg_find_hdr(tdata->msg, PJSIP_H_ROUTE,  
     635                                     last_route_hdr->next); 
     636            if (!hdr) 
     637                break; 
     638            last_route_hdr = hdr; 
     639        } 
    698640    } else { 
    699         /* Set the host part */ 
    700         if (via->maddr_param.slen) { 
    701             pj_strdup(pool, &send_addr->addr.host, &via->maddr_param); 
    702         } else if (via->recvd_param.slen) { 
    703             pj_strdup(pool, &send_addr->addr.host, &via->recvd_param); 
     641        topmost_route_uri = NULL; 
     642    } 
     643 
     644    /* If Route headers exist, and the first element indicates loose-route, 
     645     * the URI is taken from the Request-URI, and we keep all existing Route 
     646     * headers intact. 
     647     * If Route headers exist, and the first element DOESN'T indicate loose 
     648     * route, the URI is taken from the first Route header, and remove the 
     649     * first Route header from the message. 
     650     * Otherwise if there's no Route headers, the URI is taken from the 
     651     * Request-URI. 
     652     */ 
     653    if (topmost_route_uri) { 
     654        pj_bool_t has_lr_param; 
     655 
     656        if (PJSIP_URI_SCHEME_IS_SIP(topmost_route_uri) || 
     657            PJSIP_URI_SCHEME_IS_SIPS(topmost_route_uri)) 
     658        { 
     659            const pjsip_url *url = pjsip_uri_get_uri((void*)topmost_route_uri); 
     660            has_lr_param = url->lr_param; 
    704661        } else { 
    705             pj_strdup(pool, &send_addr->addr.host, &via->sent_by.host); 
    706         } 
    707  
    708         /* Set the port */ 
    709         send_addr->addr.port = via->sent_by.port; 
    710     } 
    711  
     662            has_lr_param = 0; 
     663        } 
     664 
     665        if (has_lr_param) { 
     666            new_request_uri = tdata->msg->line.req.uri; 
     667            /* We shouldn't need to delete topmost Route if it has lr param. 
     668             * But seems like it breaks some proxy implementation, so we 
     669             * delete it anyway. 
     670             */ 
     671            /* 
     672            pj_list_erase(first_route_hdr); 
     673            if (first_route_hdr == last_route_hdr) 
     674                last_route_hdr = NULL; 
     675            */ 
     676        } else { 
     677            new_request_uri = pjsip_uri_get_uri((void*)topmost_route_uri); 
     678            pj_list_erase(first_route_hdr); 
     679            if (first_route_hdr == last_route_hdr) 
     680                last_route_hdr = NULL; 
     681        } 
     682 
     683        target_uri = (pjsip_uri*)topmost_route_uri; 
     684 
     685    } else { 
     686        target_uri = new_request_uri = tdata->msg->line.req.uri; 
     687    } 
     688 
     689    /* The target URI must be a SIP/SIPS URL so we can resolve it's address. 
     690     * Otherwise we're in trouble (i.e. there's no host part in tel: URL). 
     691     */ 
     692    pj_memset(dest_info, 0, sizeof(*dest_info)); 
     693 
     694    if (PJSIP_URI_SCHEME_IS_SIPS(target_uri)) { 
     695        pjsip_uri *uri = (pjsip_uri*) target_uri; 
     696        const pjsip_url *url = (const pjsip_url*)pjsip_uri_get_uri(uri); 
     697        dest_info->flag |= (PJSIP_TRANSPORT_SECURE | PJSIP_TRANSPORT_RELIABLE); 
     698        pj_strdup(tdata->pool, &dest_info->addr.host, &url->host); 
     699        dest_info->addr.port = url->port; 
     700        dest_info->type =  
     701            pjsip_transport_get_type_from_name(&url->transport_param); 
     702 
     703    } else if (PJSIP_URI_SCHEME_IS_SIP(target_uri)) { 
     704        pjsip_uri *uri = (pjsip_uri*) target_uri; 
     705        const pjsip_url *url = (const pjsip_url*)pjsip_uri_get_uri(uri); 
     706        pj_strdup(tdata->pool, &dest_info->addr.host, &url->host); 
     707        dest_info->addr.port = url->port; 
     708        dest_info->type =  
     709            pjsip_transport_get_type_from_name(&url->transport_param); 
     710#if PJ_HAS_TCP 
     711        if (dest_info->type == PJSIP_TRANSPORT_TCP ||  
     712            dest_info->type == PJSIP_TRANSPORT_SCTP)  
     713        { 
     714            dest_info->flag |= PJSIP_TRANSPORT_RELIABLE; 
     715        } 
     716#endif 
     717    } else { 
     718        pj_assert(!"Unsupported URI scheme!"); 
     719        PJ_TODO(SUPPORT_REQUEST_ADDR_RESOLUTION_FOR_TEL_URI); 
     720        return PJSIP_EINVALIDSCHEME; 
     721    } 
     722 
     723    /* If target URI is different than request URI, replace  
     724     * request URI add put the original URI in the last Route header. 
     725     */ 
     726    if (new_request_uri && new_request_uri!=tdata->msg->line.req.uri) { 
     727        pjsip_route_hdr *route = pjsip_route_hdr_create(tdata->pool); 
     728        route->name_addr.uri = tdata->msg->line.req.uri; 
     729        if (last_route_hdr) 
     730            pj_list_insert_after(last_route_hdr, route); 
     731        else 
     732            pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)route); 
     733        tdata->msg->line.req.uri = (pjsip_uri*)new_request_uri; 
     734    } 
     735 
     736    /* Success. */ 
     737    return PJ_SUCCESS;   
     738} 
     739 
     740 
     741/* Transport callback for sending stateless request.  
     742 * This is one of the most bizzare function in pjsip, so 
     743 * good luck if you happen to debug this function!! 
     744 */ 
     745static void stateless_send_transport_cb( void *token, 
     746                                         pjsip_tx_data *tdata, 
     747                                         pj_ssize_t sent ) 
     748{ 
     749    pjsip_send_state *stateless_data = token; 
     750 
     751    PJ_UNUSED_ARG(tdata); 
     752    pj_assert(tdata == stateless_data->tdata); 
     753 
     754    for (;;) { 
     755        pj_status_t status; 
     756        pj_bool_t cont; 
     757 
     758        pj_sockaddr_t *cur_addr; 
     759        pjsip_transport_type_e cur_addr_type; 
     760        int cur_addr_len; 
     761 
     762        pjsip_via_hdr *via; 
     763 
     764        if (sent == -PJ_EPENDING) { 
     765            /* This is the initial process. 
     766             * When the process started, this function will be called by 
     767             * stateless_send_resolver_callback() with sent argument set to 
     768             * -PJ_EPENDING. 
     769             */ 
     770            cont = PJ_TRUE; 
     771        } else { 
     772            /* There are two conditions here: 
     773             * (1) Message is sent (i.e. sent > 0), 
     774             * (2) Failure (i.e. sent <= 0) 
     775             */ 
     776            cont = (sent > 0) ? PJ_FALSE : 
     777                   (stateless_data->cur_addr<stateless_data->addr.count-1); 
     778            if (stateless_data->app_cb) { 
     779                (*stateless_data->app_cb)(stateless_data, sent, &cont); 
     780            } else { 
     781                /* Doesn't have application callback. 
     782                 * Terminate the process. 
     783                 */ 
     784                cont = PJ_FALSE; 
     785            } 
     786        } 
     787 
     788        /* Finished with this transport. */ 
     789        if (stateless_data->cur_transport) { 
     790            pjsip_transport_dec_ref(stateless_data->cur_transport); 
     791            stateless_data->cur_transport = NULL; 
     792        } 
     793 
     794        /* Done if application doesn't want to continue. */ 
     795        if (sent > 0 || !cont) { 
     796            pjsip_tx_data_dec_ref(tdata); 
     797            return; 
     798        } 
     799 
     800        /* Try next address, if any, and only when this is not the  
     801         * first invocation.  
     802         */ 
     803        if (sent != -PJ_EPENDING) { 
     804            stateless_data->cur_addr++; 
     805        } 
     806 
     807        /* Have next address? */ 
     808        if (stateless_data->cur_addr >= stateless_data->addr.count) { 
     809            /* This only happens when a rather buggy application has 
     810             * sent 'cont' to PJ_TRUE when the initial value was PJ_FALSE. 
     811             * In this case just stop the processing; we don't need to 
     812             * call the callback again as application has been informed 
     813             * before. 
     814             */ 
     815            pjsip_tx_data_dec_ref(tdata); 
     816            return; 
     817        } 
     818 
     819        /* Keep current server address information handy. */ 
     820        cur_addr = &stateless_data->addr.entry[stateless_data->cur_addr].addr; 
     821        cur_addr_type = stateless_data->addr.entry[stateless_data->cur_addr].type; 
     822        cur_addr_len = stateless_data->addr.entry[stateless_data->cur_addr].addr_len; 
     823 
     824        /* Acquire transport. */ 
     825        status = pjsip_endpt_acquire_transport( stateless_data->endpt, 
     826                                                cur_addr_type, 
     827                                                cur_addr, 
     828                                                cur_addr_len, 
     829                                                &stateless_data->cur_transport); 
     830        if (status != PJ_SUCCESS) { 
     831            sent = -status; 
     832            continue; 
     833        } 
     834 
     835        /* Modify Via header. */ 
     836        via = (pjsip_via_hdr*) pjsip_msg_find_hdr( tdata->msg, 
     837                                                   PJSIP_H_VIA, NULL); 
     838        if (!via) { 
     839            /* Shouldn't happen if request was created with PJSIP API!  
     840             * But we handle the case anyway for robustness. 
     841             */ 
     842            pj_assert(!"Via header not found!"); 
     843            via = pjsip_via_hdr_create(tdata->pool); 
     844            pjsip_msg_insert_first_hdr(tdata->msg, (pjsip_hdr*)via); 
     845        } 
     846 
     847        if (via->branch_param.slen == 0) { 
     848            pj_str_t tmp; 
     849            via->branch_param.ptr = pj_pool_alloc(tdata->pool, 
     850                                                  PJSIP_MAX_BRANCH_LEN); 
     851            via->branch_param.slen = PJSIP_MAX_BRANCH_LEN; 
     852            pj_memcpy(via->branch_param.ptr, PJSIP_RFC3261_BRANCH_ID, 
     853                      PJSIP_RFC3261_BRANCH_LEN); 
     854            tmp.ptr = via->branch_param.ptr + PJSIP_RFC3261_BRANCH_LEN; 
     855            pj_generate_unique_string(&tmp); 
     856        } 
     857 
     858        via->transport = pj_str(stateless_data->cur_transport->type_name); 
     859        via->sent_by = stateless_data->cur_transport->local_name; 
     860        via->rport_param = 0; 
     861 
     862        /* Send message using this transport. */ 
     863        status = pjsip_transport_send( stateless_data->cur_transport, 
     864                                       tdata, 
     865                                       cur_addr, 
     866                                       cur_addr_len, 
     867                                       stateless_data, 
     868                                       &stateless_send_transport_cb); 
     869        if (status == PJ_SUCCESS) { 
     870            /* Recursively call this function. */ 
     871            sent = tdata->buf.cur - tdata->buf.start; 
     872            stateless_send_transport_cb( stateless_data, tdata, sent ); 
     873            return; 
     874        } else if (status == PJ_EPENDING) { 
     875            /* This callback will be called later. */ 
     876            return; 
     877        } else { 
     878            /* Recursively call this function. */ 
     879            sent = -status; 
     880            stateless_send_transport_cb( stateless_data, tdata, sent ); 
     881            return; 
     882        } 
     883    } 
     884 
     885} 
     886 
     887/* Resolver callback for sending stateless request. */ 
     888static void  
     889stateless_send_resolver_callback( pj_status_t status, 
     890                                  void *token, 
     891                                  const struct pjsip_server_addresses *addr) 
     892{ 
     893    pjsip_send_state *stateless_data = token; 
     894 
     895    /* Fail on server resolution. */ 
     896    if (status != PJ_SUCCESS) { 
     897        if (stateless_data->app_cb) { 
     898            pj_bool_t cont = PJ_FALSE; 
     899            (*stateless_data->app_cb)(stateless_data, -status, &cont); 
     900        } 
     901        pjsip_tx_data_dec_ref(stateless_data->tdata); 
     902        return; 
     903    } 
     904 
     905    /* Copy server addresses */ 
     906    pj_memcpy( &stateless_data->addr, addr, sizeof(pjsip_server_addresses)); 
     907 
     908    /* Process the addresses. */ 
     909    stateless_send_transport_cb( stateless_data, stateless_data->tdata, 
     910                                 -PJ_EPENDING); 
     911} 
     912 
     913/* 
     914 * Send stateless request. 
     915 * The sending process consists of several stages: 
     916 *  - determine which host to contact (#pjsip_get_request_addr). 
     917 *  - resolve the host (#pjsip_endpt_resolve) 
     918 *  - establish transport (#pjsip_endpt_acquire_transport) 
     919 *  - send the message (#pjsip_transport_send) 
     920 */ 
     921PJ_DEF(pj_status_t)  
     922pjsip_endpt_send_request_stateless(pjsip_endpoint *endpt,  
     923                                   pjsip_tx_data *tdata, 
     924                                   void *token, 
     925                                   void (*cb)(pjsip_send_state*, 
     926                                              pj_ssize_t sent, 
     927                                              pj_bool_t *cont)) 
     928{ 
     929    pjsip_host_info dest_info; 
     930    pjsip_send_state *stateless_data; 
     931    pj_status_t status; 
     932 
     933    PJ_ASSERT_RETURN(endpt && tdata, PJ_EINVAL); 
     934 
     935    /* Get destination name to contact. */ 
     936    status = pjsip_get_request_addr(tdata, &dest_info); 
     937    if (status != PJ_SUCCESS) 
     938        return status; 
     939 
     940    /* Keep stateless data. */ 
     941    stateless_data = pj_pool_zalloc(tdata->pool, sizeof(pjsip_send_state)); 
     942    stateless_data->token = token; 
     943    stateless_data->endpt = endpt; 
     944    stateless_data->tdata = tdata; 
     945    stateless_data->app_cb = cb; 
     946 
     947    /* Resolve destination host. 
     948     * The processing then resumed when the resolving callback is called. 
     949     */ 
     950    pjsip_endpt_resolve( endpt, tdata->pool, &dest_info, stateless_data, 
     951                         &stateless_send_resolver_callback); 
    712952    return PJ_SUCCESS; 
    713953} 
     954 
     955/* 
     956 * Determine which address (and transport) to use to send response message 
     957 * based on the received request. This function follows the specification 
     958 * in section 18.2.2 of RFC 3261 and RFC 3581 for calculating the destination 
     959 * address and transport. 
     960 */ 
     961PJ_DEF(pj_status_t) pjsip_get_response_addr( pj_pool_t *pool, 
     962                                             pjsip_rx_data *rdata, 
     963                                             pjsip_response_addr *res_addr ) 
     964{ 
     965    pjsip_transport *src_transport = rdata->tp_info.transport; 
     966 
     967    /* Check arguments. */ 
     968    PJ_ASSERT_RETURN(pool && rdata && res_addr, PJ_EINVAL); 
     969 
     970    /* All requests must have "received" parameter. 
     971     * This must always be done in transport layer. 
     972     */ 
     973    pj_assert(rdata->msg_info.via->recvd_param.slen != 0); 
     974 
     975    /* Do the calculation based on RFC 3261 Section 18.2.2 and RFC 3581 */ 
     976 
     977    if (PJSIP_TRANSPORT_IS_RELIABLE(src_transport)) { 
     978        /* For reliable protocol such as TCP or SCTP, or TLS over those, the 
     979         * response MUST be sent using the existing connection to the source 
     980         * of the original request that created the transaction, if that  
     981         * connection is still open.  
     982         * If that connection is no longer open, the server SHOULD open a  
     983         * connection to the IP address in the received parameter, if present, 
     984         * using the port in the sent-by value, or the default port for that  
     985         * transport, if no port is specified.  
     986         * If that connection attempt fails, the server SHOULD use the  
     987         * procedures in [4] for servers in order to determine the IP address 
     988         * and port to open the connection and send the response to. 
     989         */ 
     990        res_addr->transport = rdata->tp_info.transport; 
     991        pj_memcpy(&res_addr->addr, &rdata->pkt_info.src_addr, 
     992                  rdata->pkt_info.src_addr_len); 
     993        res_addr->addr_len = rdata->pkt_info.src_addr_len; 
     994        res_addr->dst_host.type = src_transport->key.type; 
     995        res_addr->dst_host.flag = src_transport->flag; 
     996        pj_strdup( pool, &res_addr->dst_host.addr.host,  
     997                   &rdata->msg_info.via->recvd_param); 
     998        res_addr->dst_host.addr.port = rdata->msg_info.via->sent_by.port; 
     999        if (res_addr->dst_host.addr.port == 0) { 
     1000            res_addr->dst_host.addr.port =  
     1001                pjsip_transport_get_default_port_for_type(res_addr->dst_host.type); 
     1002        } 
     1003 
     1004    } else if (rdata->msg_info.via->maddr_param.slen) { 
     1005        /* Otherwise, if the Via header field value contains a maddr parameter, 
     1006         * the response MUST be forwarded to the address listed there, using  
     1007         * the port indicated in sent-by, or port 5060 if none is present.  
     1008         * If the address is a multicast address, the response SHOULD be sent  
     1009         * using the TTL indicated in the ttl parameter, or with a TTL of 1 if 
     1010         * that parameter is not present.  
     1011         */ 
     1012        res_addr->transport = NULL; 
     1013        res_addr->dst_host.type = src_transport->key.type; 
     1014        res_addr->dst_host.flag = src_transport->flag; 
     1015        pj_strdup( pool, &res_addr->dst_host.addr.host,  
     1016                   &rdata->msg_info.via->maddr_param); 
     1017        res_addr->dst_host.addr.port = rdata->msg_info.via->sent_by.port; 
     1018        if (res_addr->dst_host.addr.port == 0) 
     1019            res_addr->dst_host.addr.port = 5060; 
     1020 
     1021    } else if (rdata->msg_info.via->rport_param >= 0) { 
     1022        /* There is both a "received" parameter and an "rport" parameter,  
     1023         * the response MUST be sent to the IP address listed in the "received" 
     1024         * parameter, and the port in the "rport" parameter.  
     1025         * The response MUST be sent from the same address and port that the  
     1026         * corresponding request was received on. 
     1027         */ 
     1028        res_addr->transport = rdata->tp_info.transport; 
     1029        pj_memcpy(&res_addr->addr, &rdata->pkt_info.src_addr, 
     1030                  rdata->pkt_info.src_addr_len); 
     1031        res_addr->addr_len = rdata->pkt_info.src_addr_len; 
     1032        res_addr->dst_host.type = src_transport->key.type; 
     1033        res_addr->dst_host.flag = src_transport->flag; 
     1034        pj_strdup( pool, &res_addr->dst_host.addr.host,  
     1035                   &rdata->msg_info.via->recvd_param); 
     1036        res_addr->dst_host.addr.port = rdata->msg_info.via->sent_by.port; 
     1037        if (res_addr->dst_host.addr.port == 0) { 
     1038            res_addr->dst_host.addr.port =  
     1039                pjsip_transport_get_default_port_for_type(res_addr->dst_host.type); 
     1040        } 
     1041 
     1042    } else { 
     1043        res_addr->transport = NULL; 
     1044        res_addr->dst_host.type = src_transport->key.type; 
     1045        res_addr->dst_host.flag = src_transport->flag; 
     1046        pj_strdup( pool, &res_addr->dst_host.addr.host,  
     1047                   &rdata->msg_info.via->recvd_param); 
     1048        res_addr->dst_host.addr.port = rdata->msg_info.via->sent_by.port; 
     1049        if (res_addr->dst_host.addr.port == 0) { 
     1050            res_addr->dst_host.addr.port =  
     1051                pjsip_transport_get_default_port_for_type(res_addr->dst_host.type); 
     1052        } 
     1053    } 
     1054 
     1055    return PJ_SUCCESS; 
     1056} 
     1057 
     1058/* 
     1059 * Callback called by transport during send_response. 
     1060 */ 
     1061static void send_response_transport_cb(void *token, pjsip_tx_data *tdata, 
     1062                                       pj_ssize_t sent) 
     1063{ 
     1064    pjsip_send_state *send_state = token; 
     1065    pj_bool_t cont = PJ_FALSE; 
     1066 
     1067    /* Call callback, if any. */ 
     1068    if (send_state->app_cb) 
     1069        (*send_state->app_cb)(send_state, sent, &cont); 
     1070 
     1071    /* Decrement transport reference counter. */ 
     1072    pjsip_transport_dec_ref(send_state->cur_transport); 
     1073 
     1074    /* Decrement transmit data ref counter. */ 
     1075    pjsip_tx_data_dec_ref(tdata); 
     1076} 
     1077 
     1078/* 
     1079 * Resolver calback during send_response. 
     1080 */ 
     1081static void send_response_resolver_cb( pj_status_t status, void *token, 
     1082                                       const pjsip_server_addresses *addr ) 
     1083{ 
     1084    pjsip_send_state *send_state = token; 
     1085 
     1086    if (status != PJ_SUCCESS) { 
     1087        if (send_state->app_cb) { 
     1088            pj_bool_t cont = PJ_FALSE; 
     1089            (*send_state->app_cb)(send_state, -status, &cont); 
     1090        } 
     1091        pjsip_tx_data_dec_ref(send_state->tdata); 
     1092        return; 
     1093    } 
     1094 
     1095    /* Only handle the first address resolved. */ 
     1096 
     1097    /* Acquire transport. */ 
     1098    status = pjsip_endpt_acquire_transport( send_state->endpt,  
     1099                                            addr->entry[0].type, 
     1100                                            &addr->entry[0].addr, 
     1101                                            addr->entry[0].addr_len, 
     1102                                            &send_state->cur_transport); 
     1103    if (status != PJ_SUCCESS) { 
     1104        if (send_state->app_cb) { 
     1105            pj_bool_t cont = PJ_FALSE; 
     1106            (*send_state->app_cb)(send_state, -status, &cont); 
     1107        } 
     1108        pjsip_tx_data_dec_ref(send_state->tdata); 
     1109        return; 
     1110    } 
     1111 
     1112    /* Send response using the transoprt. */ 
     1113    status = pjsip_transport_send( send_state->cur_transport,  
     1114                                   send_state->tdata, 
     1115                                   &addr->entry[0].addr, 
     1116                                   addr->entry[0].addr_len, 
     1117                                   send_state, 
     1118                                   &send_response_transport_cb); 
     1119    if (status == PJ_SUCCESS) { 
     1120        pj_ssize_t sent = send_state->tdata->buf.cur -  
     1121                          send_state->tdata->buf.start; 
     1122        send_response_transport_cb(send_state, send_state->tdata, sent); 
     1123 
     1124    } else if (status == PJ_EPENDING) { 
     1125        /* Transport callback will be called later. */ 
     1126    } else { 
     1127        send_response_transport_cb(send_state, send_state->tdata, -status); 
     1128    } 
     1129} 
     1130 
     1131/* 
     1132 * Send response. 
     1133 */ 
     1134PJ_DEF(pj_status_t) pjsip_endpt_send_response( pjsip_endpoint *endpt, 
     1135                                               pjsip_response_addr *res_addr, 
     1136                                               pjsip_tx_data *tdata, 
     1137                                               void *token, 
     1138                                               void (*cb)(pjsip_send_state*, 
     1139                                                          pj_ssize_t sent, 
     1140                                                          pj_bool_t *cont)) 
     1141{ 
     1142    /* Determine which transports and addresses to send the response, 
     1143     * based on Section 18.2.2 of RFC 3261. 
     1144     */ 
     1145    pjsip_send_state *send_state; 
     1146    pj_status_t status; 
     1147 
     1148    /* Create structure to keep the sending state. */ 
     1149    send_state = pj_pool_zalloc(tdata->pool, sizeof(pjsip_send_state)); 
     1150    send_state->endpt = endpt; 
     1151    send_state->tdata = tdata; 
     1152    send_state->token = token; 
     1153    send_state->app_cb = cb; 
     1154 
     1155    if (res_addr->transport != NULL) { 
     1156        send_state->cur_transport = res_addr->transport; 
     1157        pjsip_transport_add_ref(send_state->cur_transport); 
     1158 
     1159        status = pjsip_transport_send( send_state->cur_transport, tdata,  
     1160                                       &res_addr->addr, 
     1161                                       res_addr->addr_len, 
     1162                                       send_state, 
     1163                                       &send_response_transport_cb ); 
     1164        if (status == PJ_SUCCESS) { 
     1165            pj_ssize_t sent = tdata->buf.cur - tdata->buf.start; 
     1166            send_response_transport_cb(send_state, tdata, sent); 
     1167            return PJ_SUCCESS; 
     1168        } else if (status == PJ_EPENDING) { 
     1169            /* Callback will be called later. */ 
     1170            return PJ_SUCCESS; 
     1171        } else { 
     1172            send_response_transport_cb(send_state, tdata, -status); 
     1173            return status; 
     1174        } 
     1175    } else { 
     1176        pjsip_endpt_resolve(endpt, tdata->pool, &res_addr->dst_host,  
     1177                            send_state, &send_response_resolver_cb); 
     1178        return PJ_SUCCESS; 
     1179    } 
     1180} 
     1181 
    7141182 
    7151183/* 
Note: See TracChangeset for help on using the changeset viewer.