Ignore:
Timestamp:
Oct 24, 2011 9:28:13 AM (13 years ago)
Author:
ming
Message:

Re #1395: Backport of PJSIP 1.x branch into PJSIP 2.0 trunk

TODO: ticket #1268 (Option for automatic/manual sending of RTCP SDES/BYE for the stream) for video stream.

Location:
pjproject/trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk

  • pjproject/trunk/pjsip/src/pjsip-ua/sip_100rel.c

    r3664 r3841  
    106106typedef struct uac_state_t 
    107107{ 
    108         pj_int32_t      cseq; 
    109         pj_uint32_t     rseq;   /* Initialized to -1 */ 
     108    pj_str_t            tag;    /* To tag               */ 
     109    pj_int32_t          cseq; 
     110    pj_uint32_t         rseq;   /* Initialized to -1    */ 
     111    struct uac_state_t *next;   /* next call leg        */ 
    110112} uac_state_t; 
    111113 
     
    116118        pjsip_inv_session       *inv; 
    117119        uas_state_t             *uas_state; 
    118         uac_state_t             *uac_state; 
     120        uac_state_t             *uac_state_list; 
    119121}; 
    120122 
     
    232234{ 
    233235    dlg_data *dd; 
     236    uac_state_t *uac_state = NULL; 
     237    const pj_str_t *to_tag = &rdata->msg_info.to->tag; 
    234238    pjsip_transaction *tsx; 
    235239    pjsip_msg *msg; 
     
    262266    if (rseq_hdr == NULL) { 
    263267        PJ_LOG(4,(dd->inv->dlg->obj_name,  
    264                  "Ignoring provisional response with no RSeq header")); 
     268                 "Ignoring 100rel response with no RSeq header")); 
    265269        return PJSIP_EMISSINGHDR; 
    266270    } 
    267271    rseq = (pj_uint32_t) pj_strtoul(&rseq_hdr->hvalue); 
    268272 
     273    /* Find UAC state for the specified call leg */ 
     274    uac_state = dd->uac_state_list; 
     275    while (uac_state) { 
     276        if (pj_strcmp(&uac_state->tag, to_tag)==0) 
     277            break; 
     278        uac_state = uac_state->next; 
     279    } 
     280 
    269281    /* Create new UAC state if we don't have one */ 
    270     if (dd->uac_state == NULL) { 
    271         dd->uac_state = PJ_POOL_ZALLOC_T(dd->inv->dlg->pool, 
    272                                          uac_state_t); 
    273         dd->uac_state->cseq = rdata->msg_info.cseq->cseq; 
    274         dd->uac_state->rseq = rseq - 1; 
    275     } 
    276  
    277     /* If this is from new INVITE transaction, reset UAC state */ 
    278     if (rdata->msg_info.cseq->cseq != dd->uac_state->cseq) { 
    279         dd->uac_state->cseq = rdata->msg_info.cseq->cseq; 
    280         dd->uac_state->rseq = rseq - 1; 
     282    if (uac_state == NULL) { 
     283        uac_state = PJ_POOL_ZALLOC_T(dd->inv->dlg->pool, uac_state_t); 
     284        uac_state->cseq = rdata->msg_info.cseq->cseq; 
     285        uac_state->rseq = rseq - 1; 
     286        pj_strdup(dd->inv->dlg->pool, &uac_state->tag, to_tag); 
     287        uac_state->next = dd->uac_state_list; 
     288        dd->uac_state_list = uac_state; 
     289    } 
     290 
     291    /* If this is from new INVITE transaction, reset UAC state. */ 
     292    if (rdata->msg_info.cseq->cseq != uac_state->cseq) { 
     293        uac_state->cseq = rdata->msg_info.cseq->cseq; 
     294        uac_state->rseq = rseq - 1; 
    281295    } 
    282296 
    283297    /* Ignore provisional response retransmission */ 
    284     if (rseq <= dd->uac_state->rseq) { 
     298    if (rseq <= uac_state->rseq) { 
    285299        /* This should have been handled before */ 
    286300        return PJ_EIGNORED; 
    287301 
    288302    /* Ignore provisional response with out-of-order RSeq */ 
    289     } else if (rseq != dd->uac_state->rseq + 1) { 
     303    } else if (rseq != uac_state->rseq + 1) { 
    290304        PJ_LOG(4,(dd->inv->dlg->obj_name,  
    291                  "Ignoring provisional response because RSeq jump " 
     305                 "Ignoring 100rel response because RSeq jump " 
    292306                 "(expecting %u, got %u)", 
    293                  dd->uac_state->rseq+1, rseq)); 
     307                 uac_state->rseq+1, rseq)); 
    294308        return PJ_EIGNORED; 
    295309    } 
    296310 
    297311    /* Update our RSeq */ 
    298     dd->uac_state->rseq = rseq; 
     312    uac_state->rseq = rseq; 
    299313 
    300314    /* Create PRACK */ 
     
    303317    if (status != PJ_SUCCESS) 
    304318        return status; 
     319 
     320    /* If this response is a forked response from a different call-leg, 
     321     * update the req URI (https://trac.pjsip.org/repos/ticket/1364) 
     322     */ 
     323    if (pj_strcmp(&uac_state->tag, &dd->inv->dlg->remote.info->tag)) { 
     324        const pjsip_contact_hdr *mhdr; 
     325 
     326        mhdr = (const pjsip_contact_hdr*) 
     327               pjsip_msg_find_hdr(rdata->msg_info.msg, 
     328                                  PJSIP_H_CONTACT, NULL); 
     329        if (!mhdr || !mhdr->uri) { 
     330            PJ_LOG(4,(dd->inv->dlg->obj_name, 
     331                     "Ignoring 100rel response with no or " 
     332                     "invalid Contact header")); 
     333            pjsip_tx_data_dec_ref(tdata); 
     334            return PJ_EIGNORED; 
     335        } 
     336        tdata->msg->line.req.uri = (pjsip_uri*) 
     337                                   pjsip_uri_clone(tdata->pool, mhdr->uri); 
     338    } 
    305339 
    306340    /* Create RAck header */ 
Note: See TracChangeset for help on using the changeset viewer.