зеркало из https://github.com/mozilla/gecko-dev.git
Bug 840344: Prevent multiple creations of local SDP r=ekr,jsmith
This commit is contained in:
Родитель
6755c6fcbc
Коммит
13614479ee
|
@ -32,6 +32,7 @@ MOCHITEST_FILES = \
|
|||
test_peerConnection_bug827843.html \
|
||||
test_peerConnection_bug825703.html \
|
||||
test_peerConnection_bug834153.html \
|
||||
test_peerConnection_bug840344.html \
|
||||
head.js \
|
||||
mediaStreamPlayback.js \
|
||||
pc.js \
|
||||
|
|
|
@ -0,0 +1,129 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=840344
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Bug 840344: Assertion failure</title>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
<script type="application/javascript" src="/MochiKit/MochiKit.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js">
|
||||
</script>
|
||||
<script type="application/javascript" src="head.js"></script>
|
||||
</meta>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=840344">
|
||||
Bug 840344</a>
|
||||
<p id="display"></p>
|
||||
<pre id="test">
|
||||
|
||||
<script class="testbody" type="application/javascript">
|
||||
|
||||
runTest(function () {
|
||||
var answerCount = 0;
|
||||
var setLocalCount = 0;
|
||||
|
||||
// SDP to stand in for an offer coming from a (theoretical) remote endpoint
|
||||
var offer = { sdp: "v=0\r\n"+
|
||||
"o=Mozilla-SIPUA 23597 0 IN IP4 0.0.0.0\r\n"+
|
||||
"s=SIP Call\r\n"+
|
||||
"t=0 0\r\n"+
|
||||
"a=ice-ufrag:f5fda439\r\n"+
|
||||
"a=ice-pwd:d0df8e2904bdbd29587966e797655970\r\n"+
|
||||
"a=fingerprint:sha-256 DF:69:78:20:8D:2E:08:CE:49:82:A3:11:79:1D:BF:"+
|
||||
"B5:49:49:2D:32:82:2F:0D:88:84:A7:C6:63:23:63:A9:0F\r\n"+
|
||||
"m=audio 52757 RTP/SAVPF 109 0 8 101\r\n"+
|
||||
"c=IN IP4 192.168.129.33\r\n"+
|
||||
"a=rtpmap:109 opus/48000/2\r\n"+
|
||||
"a=ptime:20\r\n"+
|
||||
"a=rtpmap:0 PCMU/8000\r\n"+
|
||||
"a=rtpmap:8 PCMA/8000\r\n"+
|
||||
"a=rtpmap:101 telephone-event/8000\r\n"+
|
||||
"a=fmtp:101 0-15\r\n"+
|
||||
"a=sendrecv\r\n"+
|
||||
"a=candidate:0 1 UDP 2113601791 192.168.129.33 52757 typ host\r\n"+
|
||||
"a=candidate:0 2 UDP 2113601790 192.168.129.33 59738 typ host\r\n"+
|
||||
"m=video 63901 RTP/SAVPF 120\r\n"+
|
||||
"c=IN IP4 192.168.129.33\r\n"+
|
||||
"a=rtpmap:120 VP8/90000\r\n"+
|
||||
"a=sendrecv\r\n"+
|
||||
"a=candidate:0 1 UDP 2113601791 192.168.129.33 63901 typ host\r\n"+
|
||||
"a=candidate:0 2 UDP 2113601790 192.168.129.33 54165 typ host\r\n"+
|
||||
"m=application 65080 SCTP/DTLS 5000 \r\n"+
|
||||
"c=IN IP4 192.168.129.33\r\n"+
|
||||
"a=fmtp:5000 protocol=webrtc-datachannel;streams=16\r\n"+
|
||||
"a=sendrecv\r\n"+
|
||||
"a=candidate:0 1 UDP 2113601791 192.168.129.33 65080 typ host\r\n"+
|
||||
"a=candidate:0 2 UDP 2113601790 192.168.129.33 62658 typ host\r\n",
|
||||
type: "offer" };
|
||||
|
||||
info("Step 0: Instantiate a Peer Connection");
|
||||
var pc = new mozRTCPeerConnection();
|
||||
|
||||
// First: Kick off the chain of events by asking for a mic and camera
|
||||
var start = function() {
|
||||
info("Step 1: Get User Media for Audio and Video");
|
||||
getUserMedia({audio:true, video:true},
|
||||
gumSuccess, unexpectedCallbackAndFinish);
|
||||
};
|
||||
|
||||
// Second: set the remote description
|
||||
var gumSuccess = function(x) {
|
||||
info("Step 2a: Add stream");
|
||||
pc.addStream(x);
|
||||
info("Step 2b: Create Session Description");
|
||||
var osd = new mozRTCSessionDescription(offer);
|
||||
info("Step 2c: Set Remote Description");
|
||||
pc.setRemoteDescription(osd,
|
||||
setRemoteSuccess,
|
||||
unexpectedCallbackAndFinish);
|
||||
};
|
||||
|
||||
// Third: Attempt to create an answer. Twice.
|
||||
var setRemoteSuccess = function() {
|
||||
info("Step 3a: Create answer #1");
|
||||
pc.createAnswer(answerSuccess, unexpectedCallbackAndFinish);
|
||||
info("Step 3b: Create answer #2");
|
||||
pc.createAnswer(answerSuccess, unexpectedCallbackAndFinish);
|
||||
};
|
||||
|
||||
// Fourth: Count the answers and push them into the local description
|
||||
var answerSuccess = function(answer) {
|
||||
answerCount++;
|
||||
ok (answerCount < 3, "Answer count is less than three.")
|
||||
info("got answer #" + answerCount);
|
||||
is(answer.type,'answer',"Answer is of type 'answer'");
|
||||
ok(answer.sdp.length > 10, "Answer has length " + answer.sdp.length);
|
||||
info("Step 4: Set local description");
|
||||
pc.setLocalDescription(answer,
|
||||
setLocalSuccess,
|
||||
unexpectedCallbackAndFinish);
|
||||
};
|
||||
|
||||
// Fifth: Once we have two successful rounds through here, we're done.
|
||||
var setLocalSuccess = function(x) {
|
||||
setLocalCount++;
|
||||
info("Set local description #" + setLocalCount);
|
||||
// Then shalt thou count to two, no more, no less. Two shall be the
|
||||
// number thou shalt count, and the number of the counting shall be
|
||||
// two. Three shalt thou not count, neither count thou one, excepting
|
||||
// that thou then proceed to two. Four is right out. Once the number two,
|
||||
// being the second number, be reached, then thou shalt declare success.
|
||||
ok (setLocalCount < 3, "Set local count is less than three.")
|
||||
if (setLocalCount === 2) {
|
||||
is (answerCount, 2, "Answer count is 2.")
|
||||
info("Step 5: Finished");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
};
|
||||
|
||||
start();
|
||||
|
||||
}, true);
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -1023,6 +1023,7 @@ fsmdef_init_dcb (fsmdef_dcb_t *dcb, callid_t call_id,
|
|||
|
||||
dcb->remote_sdp_present = FALSE;
|
||||
dcb->remote_sdp_in_ack = FALSE;
|
||||
dcb->local_sdp_complete = FALSE;
|
||||
|
||||
dcb->sdp = NULL;
|
||||
dcb->src_sdp_version = 0;
|
||||
|
@ -2865,6 +2866,8 @@ fsmdef_ev_createoffer (sm_event_t *event) {
|
|||
char *ice_pwd = NULL;
|
||||
short vcm_res;
|
||||
session_data_t *sess_data_p = NULL;
|
||||
char *local_sdp = NULL;
|
||||
uint32_t local_sdp_len = 0;
|
||||
|
||||
FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__));
|
||||
|
||||
|
@ -2878,6 +2881,29 @@ fsmdef_ev_createoffer (sm_event_t *event) {
|
|||
FSM_DEBUG_SM(DEB_F_PREFIX"dcb is NULL.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__));
|
||||
return SM_RC_CLEANUP;
|
||||
}
|
||||
|
||||
/* For now, if the local SDP has been set, we don't allow it to be set
|
||||
again. This will change when we allow renegotiation of ongoing
|
||||
sessions. See bug 840728. */
|
||||
if (dcb->local_sdp_complete) {
|
||||
FSM_DEBUG_SM(DEB_F_PREFIX"local SDP already created: returning "
|
||||
"prevously created SDP.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__));
|
||||
|
||||
local_sdp = sipsdp_write_to_buf(dcb->sdp->src_sdp, &local_sdp_len);
|
||||
if (!local_sdp) {
|
||||
ui_create_offer(evCreateOfferError, line, call_id,
|
||||
dcb->caller_id.call_instance_id, strlib_empty());
|
||||
FSM_DEBUG_SM(get_debug_string(FSM_DBG_SDP_BUILD_ERR));
|
||||
return (fsmdef_release(fcb, cause, FALSE));
|
||||
}
|
||||
|
||||
ui_create_offer(evCreateOffer, line, call_id,
|
||||
dcb->caller_id.call_instance_id,
|
||||
strlib_malloc(local_sdp,-1));
|
||||
free(local_sdp);
|
||||
return (SM_RC_END);
|
||||
}
|
||||
|
||||
dcb->inbound = FALSE;
|
||||
|
||||
if (msg->data.session.constraints) {
|
||||
|
@ -2935,6 +2961,8 @@ fsmdef_ev_createoffer (sm_event_t *event) {
|
|||
return (fsmdef_release(fcb, cause, FALSE));
|
||||
}
|
||||
|
||||
dcb->local_sdp_complete = TRUE;
|
||||
|
||||
/* Pass offer SDP back to UI */
|
||||
ui_create_offer(evCreateOffer, line, call_id,
|
||||
dcb->caller_id.call_instance_id,
|
||||
|
@ -2974,6 +3002,8 @@ fsmdef_ev_createanswer (sm_event_t *event) {
|
|||
boolean has_audio;
|
||||
boolean has_video;
|
||||
boolean has_data;
|
||||
char *local_sdp = NULL;
|
||||
uint32_t local_sdp_len = 0;
|
||||
|
||||
FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__));
|
||||
|
||||
|
@ -2986,6 +3016,29 @@ fsmdef_ev_createanswer (sm_event_t *event) {
|
|||
FSM_DEBUG_SM(DEB_F_PREFIX"dcb is NULL.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__));
|
||||
return SM_RC_CLEANUP;
|
||||
}
|
||||
|
||||
/* For now, if the local SDP has been set, we don't allow it to be set
|
||||
again. This will change when we allow renegotiation of ongoing
|
||||
sessions. See bug 840728. */
|
||||
if (dcb->local_sdp_complete) {
|
||||
FSM_DEBUG_SM(DEB_F_PREFIX"local SDP already created: returning "
|
||||
"prevously created SDP.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__));
|
||||
|
||||
local_sdp = sipsdp_write_to_buf(dcb->sdp->src_sdp, &local_sdp_len);
|
||||
if (!local_sdp) {
|
||||
ui_create_answer(evCreateAnswerError, line, call_id,
|
||||
dcb->caller_id.call_instance_id, strlib_empty());
|
||||
FSM_DEBUG_SM(get_debug_string(FSM_DBG_SDP_BUILD_ERR));
|
||||
return (fsmdef_release(fcb, cause, FALSE));
|
||||
}
|
||||
|
||||
ui_create_answer(evCreateAnswer, line, call_id,
|
||||
dcb->caller_id.call_instance_id,
|
||||
strlib_malloc(local_sdp,-1));
|
||||
free(local_sdp);
|
||||
return (SM_RC_END);
|
||||
}
|
||||
|
||||
dcb->inbound = TRUE;
|
||||
|
||||
if (msg->data.session.constraints) {
|
||||
|
@ -3069,6 +3122,8 @@ fsmdef_ev_createanswer (sm_event_t *event) {
|
|||
return (fsmdef_release(fcb, cause, FALSE));
|
||||
}
|
||||
|
||||
dcb->local_sdp_complete = TRUE;
|
||||
|
||||
/* Pass SDP back to UI */
|
||||
ui_create_answer(evCreateAnswer, line, call_id,
|
||||
dcb->caller_id.call_instance_id,
|
||||
|
@ -3096,7 +3151,7 @@ fsmdef_ev_setlocaldesc(sm_event_t *event) {
|
|||
callid_t call_id = msg->call_id;
|
||||
line_t line = msg->line;
|
||||
cc_causes_t lsm_rc;
|
||||
char *local_sdp = 0;
|
||||
char *local_sdp = NULL;
|
||||
uint32_t local_sdp_len = 0;
|
||||
|
||||
FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__));
|
||||
|
|
|
@ -293,6 +293,7 @@ typedef struct {
|
|||
*/
|
||||
boolean remote_sdp_present;
|
||||
boolean remote_sdp_in_ack;
|
||||
boolean local_sdp_complete;
|
||||
uint16_t src_sdp_version;
|
||||
cc_sdp_t *sdp;
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче