Changeset 2362 for pjproject/trunk
- Timestamp:
- Oct 31, 2008 6:01:48 PM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjsip/src/pjsip-ua/sip_inv.c
r2306 r2362 143 143 struct tsx_inv_data 144 144 { 145 pjsip_inv_session *inv; 146 pj_bool_t sdp_done; 145 pjsip_inv_session *inv; /* The invite session */ 146 pj_bool_t sdp_done; /* SDP negotiation done for this tsx? */ 147 pj_str_t done_tag; /* To tag in RX response with answer */ 148 pj_bool_t done_early;/* Negotiation was done for early med? */ 147 149 }; 148 150 … … 1408 1410 pj_status_t status; 1409 1411 pjsip_msg *msg; 1410 pjmedia_sdp_session *sdp; 1412 pjmedia_sdp_session *rem_sdp; 1413 1414 /* Check if SDP is present in the message. */ 1415 1416 msg = rdata->msg_info.msg; 1417 if (msg->body == NULL) { 1418 /* Message doesn't have body. */ 1419 return PJ_SUCCESS; 1420 } 1421 1422 if (pj_stricmp(&msg->body->content_type.type, &str_application) || 1423 pj_stricmp(&msg->body->content_type.subtype, &str_sdp)) 1424 { 1425 /* Message body is not "application/sdp" */ 1426 return PJMEDIA_SDP_EINSDP; 1427 } 1411 1428 1412 1429 /* Get/attach invite session's transaction data */ … … 1418 1435 } 1419 1436 1420 /* MUST NOT do multiple SDP offer/answer in a single transaction. 1437 /* MUST NOT do multiple SDP offer/answer in a single transaction, 1438 * EXCEPT if: 1439 * - this is an initial UAC INVITE transaction (i.e. not re-INVITE), and 1440 * - the previous negotiation was done on an early media (18x) and 1441 * this response is a final/2xx response, and 1442 * - the 2xx response has different To tag than the 18x response 1443 * (i.e. the request has forked). 1444 * 1445 * The exception above is to add a rudimentary support for early media 1446 * forking (sample case: custom ringback). See this ticket for more 1447 * info: http://trac.pjsip.org/repos/ticket/657 1421 1448 */ 1422 1423 1449 if (tsx_inv_data->sdp_done) { 1424 if (rdata->msg_info.msg->body) { 1425 PJ_LOG(4,(inv->obj_name, "SDP negotiation done, message " 1426 "body is ignored")); 1427 } 1428 return PJ_SUCCESS; 1429 } 1430 1431 /* Check if SDP is present in the message. */ 1432 1433 msg = rdata->msg_info.msg; 1434 if (msg->body == NULL) { 1435 /* Message doesn't have body. */ 1436 return PJ_SUCCESS; 1437 } 1438 1439 if (pj_stricmp(&msg->body->content_type.type, &str_application) || 1440 pj_stricmp(&msg->body->content_type.subtype, &str_sdp)) 1441 { 1442 /* Message body is not "application/sdp" */ 1443 return PJMEDIA_SDP_EINSDP; 1450 pj_str_t res_tag; 1451 1452 res_tag = rdata->msg_info.to->tag; 1453 1454 /* Allow final response after SDP has been negotiated in early 1455 * media, IF this response is a final response with different 1456 * tag. 1457 */ 1458 if (tsx->role == PJSIP_ROLE_UAC && 1459 rdata->msg_info.msg->line.status.code/100 == 2 && 1460 tsx_inv_data->done_early && 1461 pj_strcmp(&tsx_inv_data->done_tag, &res_tag)) 1462 { 1463 const pjmedia_sdp_session *reoffer_sdp = NULL; 1464 1465 PJ_LOG(4,(inv->obj_name, "Received forked final response " 1466 "after SDP negotiation has been done in early " 1467 "media. Renegotiating SDP..")); 1468 1469 /* Retrieve original SDP offer from INVITE request */ 1470 reoffer_sdp = (const pjmedia_sdp_session*) 1471 tsx->last_tx->msg->body->data; 1472 1473 /* Feed the original offer to negotiator */ 1474 status = pjmedia_sdp_neg_modify_local_offer(inv->pool, inv->neg, 1475 reoffer_sdp); 1476 if (status != PJ_SUCCESS) { 1477 PJ_LOG(1,(inv->obj_name, "Error updating local offer for " 1478 "forked 2xx response (err=%d)", status)); 1479 return status; 1480 } 1481 1482 } else { 1483 1484 if (rdata->msg_info.msg->body) { 1485 PJ_LOG(4,(inv->obj_name, "SDP negotiation done, message " 1486 "body is ignored")); 1487 } 1488 return PJ_SUCCESS; 1489 } 1444 1490 } 1445 1491 … … 1448 1494 status = pjmedia_sdp_parse(rdata->tp_info.pool, 1449 1495 (char*)msg->body->data, 1450 msg->body->len, & sdp);1496 msg->body->len, &rem_sdp); 1451 1497 if (status == PJ_SUCCESS) 1452 status = pjmedia_sdp_validate( sdp);1498 status = pjmedia_sdp_validate(rem_sdp); 1453 1499 1454 1500 if (status != PJ_SUCCESS) { … … 1473 1519 if (inv->neg == NULL) { 1474 1520 status=pjmedia_sdp_neg_create_w_remote_offer(inv->pool, NULL, 1475 sdp, &inv->neg);1521 rem_sdp, &inv->neg); 1476 1522 } else { 1477 status=pjmedia_sdp_neg_set_remote_offer(inv->pool, inv->neg, sdp); 1523 status=pjmedia_sdp_neg_set_remote_offer(inv->pool, inv->neg, 1524 rem_sdp); 1478 1525 } 1479 1526 … … 1490 1537 if (mod_inv.cb.on_rx_offer && inv->notify) { 1491 1538 1492 (*mod_inv.cb.on_rx_offer)(inv, sdp);1539 (*mod_inv.cb.on_rx_offer)(inv, rem_sdp); 1493 1540 1494 1541 } … … 1497 1544 PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER) 1498 1545 { 1546 int status_code; 1499 1547 1500 1548 /* This is an answer. … … 1505 1553 pjsip_rx_data_get_info(rdata))); 1506 1554 1507 status = pjmedia_sdp_neg_set_remote_answer(inv->pool, inv->neg, sdp); 1555 status = pjmedia_sdp_neg_set_remote_answer(inv->pool, inv->neg, 1556 rem_sdp); 1508 1557 1509 1558 if (status != PJ_SUCCESS) { … … 1519 1568 inv_negotiate_sdp(inv); 1520 1569 1521 /* Mark this transaction has having SDP offer/answer done. */ 1570 /* Mark this transaction has having SDP offer/answer done, and 1571 * save the reference to the To tag 1572 */ 1522 1573 1523 1574 tsx_inv_data->sdp_done = 1; 1575 status_code = rdata->msg_info.msg->line.status.code; 1576 tsx_inv_data->done_early = (status_code/100==1); 1577 pj_strdup(tsx->pool, &tsx_inv_data->done_tag, 1578 &rdata->msg_info.to->tag); 1524 1579 1525 1580 } else {
Note: See TracChangeset
for help on using the changeset viewer.