- Timestamp:
- Sep 8, 2011 4:37:43 AM (13 years ago)
- Location:
- pjproject/branches/1.x
- Files:
-
- 1 added
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/branches/1.x/pjsip/src/pjsip-ua/sip_100rel.c
r3553 r3743 105 105 typedef struct uac_state_t 106 106 { 107 pj_int32_t cseq; 108 pj_uint32_t rseq; /* Initialized to -1 */ 107 pj_str_t tag; /* To tag */ 108 pj_int32_t cseq; 109 pj_uint32_t rseq; /* Initialized to -1 */ 110 struct uac_state_t *next; /* next call leg */ 109 111 } uac_state_t; 110 112 … … 115 117 pjsip_inv_session *inv; 116 118 uas_state_t *uas_state; 117 uac_state_t *uac_state ;119 uac_state_t *uac_state_list; 118 120 }; 119 121 … … 231 233 { 232 234 dlg_data *dd; 235 uac_state_t *uac_state = NULL; 236 const pj_str_t *to_tag = &rdata->msg_info.to->tag; 233 237 pjsip_transaction *tsx; 234 238 pjsip_msg *msg; … … 261 265 if (rseq_hdr == NULL) { 262 266 PJ_LOG(4,(dd->inv->dlg->obj_name, 263 "Ignoring provisional response with no RSeq header"));267 "Ignoring 100rel response with no RSeq header")); 264 268 return PJSIP_EMISSINGHDR; 265 269 } 266 270 rseq = (pj_uint32_t) pj_strtoul(&rseq_hdr->hvalue); 267 271 272 /* Find UAC state for the specified call leg */ 273 uac_state = dd->uac_state_list; 274 while (uac_state) { 275 if (pj_strcmp(&uac_state->tag, to_tag)==0) 276 break; 277 uac_state = uac_state->next; 278 } 279 268 280 /* Create new UAC state if we don't have one */ 269 if (dd->uac_state == NULL) { 270 dd->uac_state = PJ_POOL_ZALLOC_T(dd->inv->dlg->pool, 271 uac_state_t); 272 dd->uac_state->cseq = rdata->msg_info.cseq->cseq; 273 dd->uac_state->rseq = rseq - 1; 274 } 275 276 /* If this is from new INVITE transaction, reset UAC state */ 277 if (rdata->msg_info.cseq->cseq != dd->uac_state->cseq) { 278 dd->uac_state->cseq = rdata->msg_info.cseq->cseq; 279 dd->uac_state->rseq = rseq - 1; 281 if (uac_state == NULL) { 282 uac_state = PJ_POOL_ZALLOC_T(dd->inv->dlg->pool, uac_state_t); 283 uac_state->cseq = rdata->msg_info.cseq->cseq; 284 uac_state->rseq = rseq - 1; 285 pj_strdup(dd->inv->dlg->pool, &uac_state->tag, to_tag); 286 uac_state->next = dd->uac_state_list; 287 dd->uac_state_list = uac_state; 288 } 289 290 /* If this is from new INVITE transaction, reset UAC state. */ 291 if (rdata->msg_info.cseq->cseq != uac_state->cseq) { 292 uac_state->cseq = rdata->msg_info.cseq->cseq; 293 uac_state->rseq = rseq - 1; 280 294 } 281 295 282 296 /* Ignore provisional response retransmission */ 283 if (rseq <= dd->uac_state->rseq) {297 if (rseq <= uac_state->rseq) { 284 298 /* This should have been handled before */ 285 299 return PJ_EIGNORED; 286 300 287 301 /* Ignore provisional response with out-of-order RSeq */ 288 } else if (rseq != dd->uac_state->rseq + 1) {302 } else if (rseq != uac_state->rseq + 1) { 289 303 PJ_LOG(4,(dd->inv->dlg->obj_name, 290 "Ignoring provisional response because RSeq jump "304 "Ignoring 100rel response because RSeq jump " 291 305 "(expecting %u, got %u)", 292 dd->uac_state->rseq+1, rseq));306 uac_state->rseq+1, rseq)); 293 307 return PJ_EIGNORED; 294 308 } 295 309 296 310 /* Update our RSeq */ 297 dd->uac_state->rseq = rseq;311 uac_state->rseq = rseq; 298 312 299 313 /* Create PRACK */ … … 302 316 if (status != PJ_SUCCESS) 303 317 return status; 318 319 /* If this response is a forked response from a different call-leg, 320 * update the req URI (https://trac.pjsip.org/repos/ticket/1364) 321 */ 322 if (pj_strcmp(&uac_state->tag, &dd->inv->dlg->remote.info->tag)) { 323 const pjsip_contact_hdr *mhdr; 324 325 mhdr = (const pjsip_contact_hdr*) 326 pjsip_msg_find_hdr(rdata->msg_info.msg, 327 PJSIP_H_CONTACT, NULL); 328 if (!mhdr || !mhdr->uri) { 329 PJ_LOG(4,(dd->inv->dlg->obj_name, 330 "Ignoring 100rel response with no or " 331 "invalid Contact header")); 332 pjsip_tx_data_dec_ref(tdata); 333 return PJ_EIGNORED; 334 } 335 tdata->msg->line.req.uri = pjsip_uri_clone(tdata->pool, mhdr->uri); 336 } 304 337 305 338 /* Create RAck header */
Note: See TracChangeset
for help on using the changeset viewer.