Changeset 3841 for pjproject/trunk/pjsip/src/pjsip-ua/sip_100rel.c
- Timestamp:
- Oct 24, 2011 9:28:13 AM (13 years ago)
- Location:
- pjproject/trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk
- Property svn:mergeinfo changed
-
pjproject/trunk/pjsip/src/pjsip-ua/sip_100rel.c
r3664 r3841 106 106 typedef struct uac_state_t 107 107 { 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 */ 110 112 } uac_state_t; 111 113 … … 116 118 pjsip_inv_session *inv; 117 119 uas_state_t *uas_state; 118 uac_state_t *uac_state ;120 uac_state_t *uac_state_list; 119 121 }; 120 122 … … 232 234 { 233 235 dlg_data *dd; 236 uac_state_t *uac_state = NULL; 237 const pj_str_t *to_tag = &rdata->msg_info.to->tag; 234 238 pjsip_transaction *tsx; 235 239 pjsip_msg *msg; … … 262 266 if (rseq_hdr == NULL) { 263 267 PJ_LOG(4,(dd->inv->dlg->obj_name, 264 "Ignoring provisional response with no RSeq header"));268 "Ignoring 100rel response with no RSeq header")); 265 269 return PJSIP_EMISSINGHDR; 266 270 } 267 271 rseq = (pj_uint32_t) pj_strtoul(&rseq_hdr->hvalue); 268 272 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 269 281 /* 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; 281 295 } 282 296 283 297 /* Ignore provisional response retransmission */ 284 if (rseq <= dd->uac_state->rseq) {298 if (rseq <= uac_state->rseq) { 285 299 /* This should have been handled before */ 286 300 return PJ_EIGNORED; 287 301 288 302 /* 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) { 290 304 PJ_LOG(4,(dd->inv->dlg->obj_name, 291 "Ignoring provisional response because RSeq jump "305 "Ignoring 100rel response because RSeq jump " 292 306 "(expecting %u, got %u)", 293 dd->uac_state->rseq+1, rseq));307 uac_state->rseq+1, rseq)); 294 308 return PJ_EIGNORED; 295 309 } 296 310 297 311 /* Update our RSeq */ 298 dd->uac_state->rseq = rseq;312 uac_state->rseq = rseq; 299 313 300 314 /* Create PRACK */ … … 303 317 if (status != PJ_SUCCESS) 304 318 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 } 305 339 306 340 /* Create RAck header */
Note: See TracChangeset
for help on using the changeset viewer.