File: | media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp |
Location: | line 1147, column 3 |
Description: | Dereference of null pointer |
1 | /* This Source Code Form is subject to the terms of the Mozilla Public | ||||
2 | * License, v. 2.0. If a copy of the MPL was not distributed with this file, | ||||
3 | * You can obtain one at http://mozilla.org/MPL/2.0/. */ | ||||
4 | |||||
5 | #include <string> | ||||
6 | #include <iostream> | ||||
7 | |||||
8 | |||||
9 | #include "vcm.h" | ||||
10 | #include "CSFLog.h" | ||||
11 | #include "CSFLogStream.h" | ||||
12 | #include "ccapi_call_info.h" | ||||
13 | #include "CC_SIPCCCallInfo.h" | ||||
14 | #include "ccapi_device_info.h" | ||||
15 | #include "CC_SIPCCDeviceInfo.h" | ||||
16 | |||||
17 | #include "nspr.h" | ||||
18 | #include "nss.h" | ||||
19 | #include "pk11pub.h" | ||||
20 | |||||
21 | #include "nsNetCID.h" | ||||
22 | #include "nsIServiceManager.h" | ||||
23 | #include "nsServiceManagerUtils.h" | ||||
24 | #include "nsISocketTransportService.h" | ||||
25 | #include "nsThreadUtils.h" | ||||
26 | #include "nsProxyRelease.h" | ||||
27 | |||||
28 | #include "runnable_utils.h" | ||||
29 | #include "PeerConnectionCtx.h" | ||||
30 | #include "PeerConnectionImpl.h" | ||||
31 | |||||
32 | #include "nsPIDOMWindow.h" | ||||
33 | #include "nsDOMDataChannel.h" | ||||
34 | |||||
35 | #ifndef USE_FAKE_MEDIA_STREAMS | ||||
36 | #include "MediaSegment.h" | ||||
37 | #endif | ||||
38 | |||||
39 | using namespace mozilla; | ||||
40 | using namespace mozilla::dom; | ||||
41 | |||||
42 | namespace mozilla { | ||||
43 | class DataChannel; | ||||
44 | } | ||||
45 | |||||
46 | class nsIDOMDataChannel; | ||||
47 | |||||
48 | static const char* logTag = "PeerConnectionImpl"; | ||||
49 | static const mozilla::TrackID TRACK_AUDIO = 0; | ||||
50 | static const mozilla::TrackID TRACK_VIDEO = 1; | ||||
51 | static const int DTLS_FINGERPRINT_LENGTH = 64; | ||||
52 | static const int MEDIA_STREAM_MUTE = 0x80; | ||||
53 | |||||
54 | namespace sipcc { | ||||
55 | |||||
56 | typedef enum { | ||||
57 | PC_OBSERVER_CALLBACK, | ||||
58 | PC_OBSERVER_CONNECTION, | ||||
59 | PC_OBSERVER_CLOSEDCONNECTION, | ||||
60 | PC_OBSERVER_DATACHANNEL, | ||||
61 | PC_OBSERVER_ICE, | ||||
62 | PC_OBSERVER_READYSTATE | ||||
63 | } PeerConnectionObserverType; | ||||
64 | |||||
65 | // TODO: Refactor this. | ||||
66 | class PeerConnectionObserverDispatch : public nsRunnable { | ||||
67 | |||||
68 | public: | ||||
69 | PeerConnectionObserverDispatch(CSF::CC_CallInfoPtr aInfo, | ||||
70 | nsRefPtr<PeerConnectionImpl> aPC, | ||||
71 | IPeerConnectionObserver* aObserver) : | ||||
72 | mType(PC_OBSERVER_CALLBACK), mInfo(aInfo), mChannel(nullptr), mPC(aPC), mObserver(aObserver) {} | ||||
73 | |||||
74 | PeerConnectionObserverDispatch(PeerConnectionObserverType aType, | ||||
75 | nsRefPtr<nsIDOMDataChannel> aChannel, | ||||
76 | nsRefPtr<PeerConnectionImpl> aPC, | ||||
77 | IPeerConnectionObserver* aObserver) : | ||||
78 | mType(aType), mInfo(nullptr), mChannel(aChannel), mPC(aPC), mObserver(aObserver) {} | ||||
79 | |||||
80 | PeerConnectionObserverDispatch(PeerConnectionObserverType aType, | ||||
81 | nsRefPtr<PeerConnectionImpl> aPC, | ||||
82 | IPeerConnectionObserver* aObserver) : | ||||
83 | mType(aType), mInfo(nullptr), mPC(aPC), mObserver(aObserver) {} | ||||
84 | |||||
85 | ~PeerConnectionObserverDispatch(){} | ||||
86 | |||||
87 | NS_IMETHODvirtual __attribute__ ((visibility ("hidden"))) nsresult Run() | ||||
88 | { | ||||
89 | switch (mType) { | ||||
90 | case PC_OBSERVER_CALLBACK: | ||||
91 | { | ||||
92 | StatusCode code; | ||||
93 | std::string s_sdpstr; | ||||
94 | MediaStreamTable *streams = NULL__null; | ||||
95 | |||||
96 | cc_call_state_t state = mInfo->getCallState(); | ||||
97 | std::string statestr = mInfo->callStateToString(state); | ||||
98 | |||||
99 | nsDOMMediaStream* stream; | ||||
100 | uint32_t hint; | ||||
101 | |||||
102 | switch (state) { | ||||
103 | case CREATEOFFER: | ||||
104 | s_sdpstr = mInfo->getSDP(); | ||||
105 | mObserver->OnCreateOfferSuccess(s_sdpstr.c_str()); | ||||
106 | break; | ||||
107 | |||||
108 | case CREATEANSWER: | ||||
109 | s_sdpstr = mInfo->getSDP(); | ||||
110 | mObserver->OnCreateAnswerSuccess(s_sdpstr.c_str()); | ||||
111 | break; | ||||
112 | |||||
113 | case CREATEOFFERERROR: | ||||
114 | code = (StatusCode)mInfo->getStatusCode(); | ||||
115 | mObserver->OnCreateOfferError(code); | ||||
116 | break; | ||||
117 | |||||
118 | case CREATEANSWERERROR: | ||||
119 | code = (StatusCode)mInfo->getStatusCode(); | ||||
120 | mObserver->OnCreateAnswerError(code); | ||||
121 | break; | ||||
122 | |||||
123 | case SETLOCALDESC: | ||||
124 | code = (StatusCode)mInfo->getStatusCode(); | ||||
125 | mObserver->OnSetLocalDescriptionSuccess(code); | ||||
126 | break; | ||||
127 | |||||
128 | case SETREMOTEDESC: | ||||
129 | code = (StatusCode)mInfo->getStatusCode(); | ||||
130 | mObserver->OnSetRemoteDescriptionSuccess(code); | ||||
131 | break; | ||||
132 | |||||
133 | case SETLOCALDESCERROR: | ||||
134 | code = (StatusCode)mInfo->getStatusCode(); | ||||
135 | mObserver->OnSetLocalDescriptionError(code); | ||||
136 | break; | ||||
137 | |||||
138 | case SETREMOTEDESCERROR: | ||||
139 | code = (StatusCode)mInfo->getStatusCode(); | ||||
140 | mObserver->OnSetRemoteDescriptionError(code); | ||||
141 | break; | ||||
142 | |||||
143 | case REMOTESTREAMADD: | ||||
144 | { | ||||
145 | streams = mInfo->getMediaStreams(); | ||||
146 | nsRefPtr<RemoteSourceStreamInfo> remoteStream = mPC->GetRemoteStream(streams->media_stream_id); | ||||
147 | |||||
148 | MOZ_ASSERT(remoteStream)do { if (!(remoteStream)) { MOZ_ReportAssertionFailure("remoteStream" , "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 148); do { *((volatile int*) __null) = 123; ::abort(); } while (0); } } while (0); | ||||
149 | if (!remoteStream) | ||||
150 | { | ||||
151 | CSFLogErrorS(logTag, __FUNCTION__ << " GetRemoteStream returned NULL"){ std::ostringstream _oss; _oss << __FUNCTION__ << " GetRemoteStream returned NULL" << std::endl; CSFLog( CSF_LOG_ERROR, "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 151 , logTag, _oss.str().c_str()); }; | ||||
152 | } | ||||
153 | else | ||||
154 | { | ||||
155 | stream = remoteStream->GetMediaStream(); | ||||
156 | hint = stream->GetHintContents(); | ||||
157 | if (hint == nsDOMMediaStream::HINT_CONTENTS_AUDIO) { | ||||
158 | mObserver->OnAddStream(stream, "audio"); | ||||
159 | } else if (hint == nsDOMMediaStream::HINT_CONTENTS_VIDEO) { | ||||
160 | mObserver->OnAddStream(stream, "video"); | ||||
161 | } else { | ||||
162 | CSFLogErrorS(logTag, __FUNCTION__ << "Audio & Video not supported"){ std::ostringstream _oss; _oss << __FUNCTION__ << "Audio & Video not supported" << std::endl; CSFLog ( CSF_LOG_ERROR, "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 162 , logTag, _oss.str().c_str()); }; | ||||
163 | MOZ_ASSERT(PR_FALSE)do { if (!(0)) { MOZ_ReportAssertionFailure("0", "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 163); do { *((volatile int*) __null) = 123; ::abort(); } while (0); } } while (0); | ||||
164 | } | ||||
165 | } | ||||
166 | break; | ||||
167 | } | ||||
168 | default: | ||||
169 | CSFLogDebugS(logTag, ": **** UNHANDLED CALL STATE : " << statestr){ std::ostringstream _oss; _oss << ": **** UNHANDLED CALL STATE : " << statestr << std::endl; CSFLog( CSF_LOG_DEBUG, "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 169 , logTag, _oss.str().c_str()); }; | ||||
170 | break; | ||||
171 | } | ||||
172 | break; | ||||
173 | } | ||||
174 | case PC_OBSERVER_CONNECTION: | ||||
175 | CSFLogDebugS(logTag, __FUNCTION__ << ": Delivering PeerConnection onconnection"){ std::ostringstream _oss; _oss << __FUNCTION__ << ": Delivering PeerConnection onconnection" << std::endl ; CSFLog( CSF_LOG_DEBUG, "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 175 , logTag, _oss.str().c_str()); }; | ||||
176 | mObserver->NotifyConnection(); | ||||
177 | break; | ||||
178 | case PC_OBSERVER_CLOSEDCONNECTION: | ||||
179 | CSFLogDebugS(logTag, __FUNCTION__ << ": Delivering PeerConnection onclosedconnection"){ std::ostringstream _oss; _oss << __FUNCTION__ << ": Delivering PeerConnection onclosedconnection" << std ::endl; CSFLog( CSF_LOG_DEBUG, "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 179 , logTag, _oss.str().c_str()); }; | ||||
180 | mObserver->NotifyClosedConnection(); | ||||
181 | break; | ||||
182 | case PC_OBSERVER_DATACHANNEL: | ||||
183 | CSFLogDebugS(logTag, __FUNCTION__ << ": Delivering PeerConnection ondatachannel"){ std::ostringstream _oss; _oss << __FUNCTION__ << ": Delivering PeerConnection ondatachannel" << std::endl ; CSFLog( CSF_LOG_DEBUG, "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 183 , logTag, _oss.str().c_str()); }; | ||||
184 | mObserver->NotifyDataChannel(mChannel); | ||||
185 | #ifdef MOZILLA_INTERNAL_API1 | ||||
186 | NS_DataChannelAppReady(mChannel); | ||||
187 | #endif | ||||
188 | break; | ||||
189 | case PC_OBSERVER_ICE: | ||||
190 | CSFLogDebugS(logTag, __FUNCTION__ << ": Delivering PeerConnection ICE callback "){ std::ostringstream _oss; _oss << __FUNCTION__ << ": Delivering PeerConnection ICE callback " << std::endl ; CSFLog( CSF_LOG_DEBUG, "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 190 , logTag, _oss.str().c_str()); }; | ||||
191 | mObserver->OnStateChange(IPeerConnectionObserver::kIceState); | ||||
192 | break; | ||||
193 | case PC_OBSERVER_READYSTATE: | ||||
194 | CSFLogDebugS(logTag, __FUNCTION__ << ": Delivering PeerConnection Ready State callback "){ std::ostringstream _oss; _oss << __FUNCTION__ << ": Delivering PeerConnection Ready State callback " << std::endl; CSFLog( CSF_LOG_DEBUG, "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 194 , logTag, _oss.str().c_str()); }; | ||||
195 | mObserver->OnStateChange(IPeerConnectionObserver::kReadyState); | ||||
196 | } | ||||
197 | return NS_OK; | ||||
198 | } | ||||
199 | |||||
200 | private: | ||||
201 | PeerConnectionObserverType mType; | ||||
202 | CSF::CC_CallInfoPtr mInfo; | ||||
203 | nsRefPtr<nsIDOMDataChannel> mChannel; | ||||
204 | nsRefPtr<PeerConnectionImpl> mPC; | ||||
205 | nsCOMPtr<IPeerConnectionObserver> mObserver; | ||||
206 | }; | ||||
207 | |||||
208 | /* We get this callback in order to find out which tracks are audio and which | ||||
209 | * are video. We should get this callback right away for existing streams after | ||||
210 | * we add this class as a listener. | ||||
211 | */ | ||||
212 | void | ||||
213 | LocalSourceStreamInfo::NotifyQueuedTrackChanges( | ||||
214 | mozilla::MediaStreamGraph* aGraph, | ||||
215 | mozilla::TrackID aID, | ||||
216 | mozilla::TrackRate aTrackRate, | ||||
217 | mozilla::TrackTicks aTrackOffset, | ||||
218 | uint32_t aTrackEvents, | ||||
219 | const mozilla::MediaSegment& aQueuedMedia) | ||||
220 | { | ||||
221 | /* TODO: use this callback to keep track of changes to the MediaStream */ | ||||
222 | } | ||||
223 | |||||
224 | /* If the ExpectAudio hint is on we will add a track at the default first | ||||
225 | * audio track ID (0) | ||||
226 | * FIX - Do we need to iterate over the tracks instead of taking these hints? | ||||
227 | */ | ||||
228 | void | ||||
229 | LocalSourceStreamInfo::ExpectAudio(const mozilla::TrackID aID) | ||||
230 | { | ||||
231 | mAudioTracks.AppendElement(aID); | ||||
232 | } | ||||
233 | |||||
234 | // If the ExpectVideo hint is on we will add a track at the default first | ||||
235 | // video track ID (1). | ||||
236 | void | ||||
237 | LocalSourceStreamInfo::ExpectVideo(const mozilla::TrackID aID) | ||||
238 | { | ||||
239 | mVideoTracks.AppendElement(aID); | ||||
240 | } | ||||
241 | |||||
242 | unsigned | ||||
243 | LocalSourceStreamInfo::AudioTrackCount() | ||||
244 | { | ||||
245 | return mAudioTracks.Length(); | ||||
246 | } | ||||
247 | |||||
248 | unsigned | ||||
249 | LocalSourceStreamInfo::VideoTrackCount() | ||||
250 | { | ||||
251 | return mVideoTracks.Length(); | ||||
252 | } | ||||
253 | |||||
254 | PeerConnectionImpl* PeerConnectionImpl::CreatePeerConnection() | ||||
255 | { | ||||
256 | PeerConnectionImpl *pc = new PeerConnectionImpl(); | ||||
257 | |||||
258 | CSFLogDebugS(logTag, "Created PeerConnection: " << static_cast<void*>(pc)){ std::ostringstream _oss; _oss << "Created PeerConnection: " << static_cast<void*>(pc) << std::endl; CSFLog ( CSF_LOG_DEBUG, "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 258 , logTag, _oss.str().c_str()); }; | ||||
259 | |||||
260 | return pc; | ||||
261 | } | ||||
262 | |||||
263 | std::map<const std::string, PeerConnectionImpl *> | ||||
264 | PeerConnectionImpl::peerconnections; | ||||
265 | |||||
266 | NS_IMPL_THREADSAFE_ISUPPORTS1(PeerConnectionImpl, IPeerConnection)nsrefcnt PeerConnectionImpl::AddRef(void) { do { if (!(int32_t (mRefCnt) >= 0)) { NS_DebugBreak_P(NS_DEBUG_ASSERTION, "illegal refcnt" , "int32_t(mRefCnt) >= 0", "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 266); } } while(0); nsrefcnt count = NS_AtomicIncrementRefcnt (mRefCnt); NS_LogAddRef_P((this), (count), ("PeerConnectionImpl" ), (uint32_t) (sizeof(*this))); return (nsrefcnt) count; } nsrefcnt PeerConnectionImpl::Release(void) { do { if (!(0 != mRefCnt) ) { NS_DebugBreak_P(NS_DEBUG_ASSERTION, "dup release", "0 != mRefCnt" , "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 266); } } while(0); nsrefcnt count = NS_AtomicDecrementRefcnt (mRefCnt); NS_LogRelease_P((this), (count), ("PeerConnectionImpl" )); if (0 == count) { mRefCnt = 1; delete (this); return 0; } return count; } nsresult PeerConnectionImpl::QueryInterface( const nsIID& aIID, void** aInstancePtr) { do { if (!(aInstancePtr )) { NS_DebugBreak_P(NS_DEBUG_ASSERTION, "QueryInterface requires a non-NULL destination!" , "aInstancePtr", "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 266); } } while(0); nsresult rv = NS_ERROR_FAILURE; static const QITableEntry table[] = { { &IPeerConnection::COMTypeInfo <int>::kIID, int32_t(reinterpret_cast<char*>( static_cast <IPeerConnection*>((PeerConnectionImpl*) 0x1000)) - reinterpret_cast <char*>((PeerConnectionImpl*) 0x1000)) }, { &nsISupports ::COMTypeInfo<int>::kIID, int32_t(reinterpret_cast<char *>( static_cast<nsISupports*>( static_cast<IPeerConnection *>( (PeerConnectionImpl*) 0x1000))) - reinterpret_cast< char*>((PeerConnectionImpl*) 0x1000)) }, { nullptr, 0 } }; rv = NS_TableDrivenQI(static_cast<void*>(this), table, aIID, aInstancePtr); return rv; } | ||||
267 | |||||
268 | PeerConnectionImpl::PeerConnectionImpl() | ||||
269 | : mRole(kRoleUnknown) | ||||
270 | , mCall(NULL__null) | ||||
271 | , mReadyState(kNew) | ||||
272 | , mPCObserver(NULL__null) | ||||
273 | , mWindow(NULL__null) | ||||
274 | , mFingerprint("TempFingerprint") | ||||
275 | , mLocalSourceStreamsLock(PR_NewLock()) | ||||
276 | , mIceCtx(NULL__null) | ||||
277 | , mIceState(kIceGathering) | ||||
278 | , mIdentity(NULL__null) | ||||
279 | , mSTSThread(NULL__null) | ||||
280 | {} | ||||
281 | |||||
282 | PeerConnectionImpl::~PeerConnectionImpl() | ||||
283 | { | ||||
284 | peerconnections.erase(mHandle); | ||||
285 | Close(); | ||||
286 | PR_DestroyLock(mLocalSourceStreamsLock); | ||||
287 | |||||
288 | /* We should release mPCObserver on the main thread, but also prevent a double free. | ||||
289 | nsCOMPtr<nsIThread> mainThread; | ||||
290 | NS_GetMainThread(getter_AddRefs(mainThread)); | ||||
291 | NS_ProxyRelease(mainThread, mPCObserver); | ||||
292 | */ | ||||
293 | } | ||||
294 | |||||
295 | // One level of indirection so we can use WrapRunnable in CreateMediaStream. | ||||
296 | nsresult | ||||
297 | PeerConnectionImpl::MakeMediaStream(uint32_t aHint, nsIDOMMediaStream** aRetval) | ||||
298 | { | ||||
299 | MOZ_ASSERT(aRetval)do { if (!(aRetval)) { MOZ_ReportAssertionFailure("aRetval", "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 299); do { *((volatile int*) __null) = 123; ::abort(); } while (0); } } while (0); | ||||
300 | |||||
301 | nsRefPtr<nsDOMMediaStream> stream = nsDOMMediaStream::CreateInputStream(aHint); | ||||
302 | NS_ADDREF(*aRetval = stream)(*aRetval = stream)->AddRef(); | ||||
303 | |||||
304 | CSFLogDebugS(logTag, "PeerConnection " << static_cast<void*>(this){ std::ostringstream _oss; _oss << "PeerConnection " << static_cast<void*>(this) << ": Created media stream " << static_cast<void*>(stream) << " inner: " << static_cast<void*>(stream->GetStream()) << std::endl; CSFLog( CSF_LOG_DEBUG, "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 306 , logTag, _oss.str().c_str()); } | ||||
305 | << ": Created media stream " << static_cast<void*>(stream){ std::ostringstream _oss; _oss << "PeerConnection " << static_cast<void*>(this) << ": Created media stream " << static_cast<void*>(stream) << " inner: " << static_cast<void*>(stream->GetStream()) << std::endl; CSFLog( CSF_LOG_DEBUG, "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 306 , logTag, _oss.str().c_str()); } | ||||
306 | << " inner: " << static_cast<void*>(stream->GetStream())){ std::ostringstream _oss; _oss << "PeerConnection " << static_cast<void*>(this) << ": Created media stream " << static_cast<void*>(stream) << " inner: " << static_cast<void*>(stream->GetStream()) << std::endl; CSFLog( CSF_LOG_DEBUG, "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 306 , logTag, _oss.str().c_str()); }; | ||||
307 | |||||
308 | return NS_OK; | ||||
309 | } | ||||
310 | |||||
311 | nsresult | ||||
312 | PeerConnectionImpl::MakeRemoteSource(nsDOMMediaStream* aStream, RemoteSourceStreamInfo** aInfo) | ||||
313 | { | ||||
314 | MOZ_ASSERT(aInfo)do { if (!(aInfo)) { MOZ_ReportAssertionFailure("aInfo", "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 314); do { *((volatile int*) __null) = 123; ::abort(); } while (0); } } while (0); | ||||
315 | MOZ_ASSERT(aStream)do { if (!(aStream)) { MOZ_ReportAssertionFailure("aStream", "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 315); do { *((volatile int*) __null) = 123; ::abort(); } while (0); } } while (0); | ||||
316 | |||||
317 | // TODO(ekr@rtfm.com): Add the track info with the first segment | ||||
318 | nsRefPtr<RemoteSourceStreamInfo> remote = new RemoteSourceStreamInfo(aStream); | ||||
319 | NS_ADDREF(*aInfo = remote)(*aInfo = remote)->AddRef(); | ||||
320 | return NS_OK; | ||||
321 | } | ||||
322 | |||||
323 | nsresult | ||||
324 | PeerConnectionImpl::CreateRemoteSourceStreamInfo(uint32_t aHint, RemoteSourceStreamInfo** aInfo) | ||||
325 | { | ||||
326 | MOZ_ASSERT(aInfo)do { if (!(aInfo)) { MOZ_ReportAssertionFailure("aInfo", "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 326); do { *((volatile int*) __null) = 123; ::abort(); } while (0); } } while (0); | ||||
327 | |||||
328 | nsIDOMMediaStream* stream; | ||||
329 | |||||
330 | nsresult res; | ||||
331 | if (!mThread || NS_IsMainThreadNS_IsMainThread_P()) { | ||||
332 | res = MakeMediaStream(aHint, &stream); | ||||
333 | } else { | ||||
334 | mThread->Dispatch(WrapRunnableRet( | ||||
335 | this, &PeerConnectionImpl::MakeMediaStream, aHint, &stream, &res | ||||
336 | ), NS_DISPATCH_SYNCnsIEventTarget::DISPATCH_SYNC); | ||||
337 | } | ||||
338 | |||||
339 | if (NS_FAILED(res)) { | ||||
340 | return res; | ||||
341 | } | ||||
342 | |||||
343 | nsDOMMediaStream* comstream = static_cast<nsDOMMediaStream*>(stream); | ||||
344 | static_cast<mozilla::SourceMediaStream*>(comstream->GetStream())->SetPullEnabled(true); | ||||
345 | |||||
346 | nsRefPtr<RemoteSourceStreamInfo> remote; | ||||
347 | if (!mThread || NS_IsMainThreadNS_IsMainThread_P()) { | ||||
348 | remote = new RemoteSourceStreamInfo(comstream); | ||||
349 | NS_ADDREF(*aInfo = remote)(*aInfo = remote)->AddRef(); | ||||
350 | return NS_OK; | ||||
351 | } | ||||
352 | |||||
353 | mThread->Dispatch(WrapRunnableRet( | ||||
354 | this, &PeerConnectionImpl::MakeRemoteSource, comstream, aInfo, &res | ||||
355 | ), NS_DISPATCH_SYNCnsIEventTarget::DISPATCH_SYNC); | ||||
356 | |||||
357 | if (NS_FAILED(res)) { | ||||
358 | return res; | ||||
359 | } | ||||
360 | |||||
361 | return NS_OK; | ||||
362 | } | ||||
363 | |||||
364 | NS_IMETHODIMPnsresult | ||||
365 | PeerConnectionImpl::Initialize(IPeerConnectionObserver* aObserver, | ||||
366 | nsIDOMWindow* aWindow, | ||||
367 | nsIThread* aThread) { | ||||
368 | MOZ_ASSERT(aObserver)do { if (!(aObserver)) { MOZ_ReportAssertionFailure("aObserver" , "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 368); do { *((volatile int*) __null) = 123; ::abort(); } while (0); } } while (0); | ||||
369 | mPCObserver = aObserver; | ||||
370 | |||||
371 | #ifdef MOZILLA_INTERNAL_API1 | ||||
372 | // Currently no standalone unit tests for DataChannel, | ||||
373 | // which is the user of mWindow | ||||
374 | MOZ_ASSERT(aWindow)do { if (!(aWindow)) { MOZ_ReportAssertionFailure("aWindow", "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 374); do { *((volatile int*) __null) = 123; ::abort(); } while (0); } } while (0); | ||||
375 | mWindow = do_QueryInterface(aWindow); | ||||
376 | NS_ENSURE_STATE(mWindow)do { if ((__builtin_expect(!!(!(mWindow)), 0))) { NS_DebugBreak_P (NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "mWindow" ") failed", nullptr , "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 376); return NS_ERROR_UNEXPECTED; } } while(0); | ||||
377 | #endif | ||||
378 | |||||
379 | // The thread parameter can be passed in as NULL | ||||
380 | mThread = aThread; | ||||
381 | |||||
382 | PeerConnectionCtx *pcctx = PeerConnectionCtx::GetInstance(); | ||||
383 | MOZ_ASSERT(pcctx)do { if (!(pcctx)) { MOZ_ReportAssertionFailure("pcctx", "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 383); do { *((volatile int*) __null) = 123; ::abort(); } while (0); } } while (0); | ||||
384 | |||||
385 | mCall = pcctx->createCall(); | ||||
386 | if(!mCall.get()) { | ||||
387 | CSFLogErrorS(logTag, __FUNCTION__ << ": Couldn't Create Call Object"){ std::ostringstream _oss; _oss << __FUNCTION__ << ": Couldn't Create Call Object" << std::endl; CSFLog( CSF_LOG_ERROR , "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 387 , logTag, _oss.str().c_str()); }; | ||||
388 | return NS_ERROR_FAILURE; | ||||
389 | } | ||||
390 | |||||
391 | // Generate a random handle | ||||
392 | unsigned char handle_bin[8]; | ||||
393 | PK11_GenerateRandom(handle_bin, sizeof(handle_bin)); | ||||
394 | |||||
395 | char hex[17]; | ||||
396 | PR_snprintf(hex,sizeof(hex),"%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x", | ||||
397 | handle_bin[0], | ||||
398 | handle_bin[1], | ||||
399 | handle_bin[2], | ||||
400 | handle_bin[3], | ||||
401 | handle_bin[4], | ||||
402 | handle_bin[5], | ||||
403 | handle_bin[6], | ||||
404 | handle_bin[7]); | ||||
405 | |||||
406 | mHandle += hex; | ||||
407 | |||||
408 | |||||
409 | // TODO(ekr@rtfm.com): need some way to set not offerer later | ||||
410 | // Looks like a bug in the NrIceCtx API. | ||||
411 | mIceCtx = NrIceCtx::Create("PC:" + mHandle, true); | ||||
412 | if(!mIceCtx) { | ||||
413 | CSFLogErrorS(logTag, __FUNCTION__ << ": Failed to create Ice Context"){ std::ostringstream _oss; _oss << __FUNCTION__ << ": Failed to create Ice Context" << std::endl; CSFLog( CSF_LOG_ERROR, "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 413 , logTag, _oss.str().c_str()); }; | ||||
414 | return NS_ERROR_FAILURE; | ||||
415 | } | ||||
416 | |||||
417 | mIceCtx->SignalGatheringCompleted.connect(this, &PeerConnectionImpl::IceGatheringCompleted); | ||||
418 | mIceCtx->SignalCompleted.connect(this, &PeerConnectionImpl::IceCompleted); | ||||
419 | |||||
420 | // Create three streams to start with. | ||||
421 | // One each for audio, video and DataChannel | ||||
422 | // TODO: this will be re-visited | ||||
423 | RefPtr<NrIceMediaStream> audioStream = mIceCtx->CreateStream("stream1", 2); | ||||
424 | RefPtr<NrIceMediaStream> videoStream = mIceCtx->CreateStream("stream2", 2); | ||||
425 | RefPtr<NrIceMediaStream> dcStream = mIceCtx->CreateStream("stream3", 2); | ||||
426 | |||||
427 | if (!audioStream) { | ||||
428 | CSFLogErrorS(logTag, __FUNCTION__ << ": audio stream is NULL"){ std::ostringstream _oss; _oss << __FUNCTION__ << ": audio stream is NULL" << std::endl; CSFLog( CSF_LOG_ERROR , "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 428 , logTag, _oss.str().c_str()); }; | ||||
429 | return NS_ERROR_FAILURE; | ||||
430 | } else { | ||||
431 | mIceStreams.push_back(audioStream); | ||||
432 | } | ||||
433 | |||||
434 | if (!videoStream) { | ||||
435 | CSFLogErrorS(logTag, __FUNCTION__ << ": video stream is NULL"){ std::ostringstream _oss; _oss << __FUNCTION__ << ": video stream is NULL" << std::endl; CSFLog( CSF_LOG_ERROR , "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 435 , logTag, _oss.str().c_str()); }; | ||||
436 | return NS_ERROR_FAILURE; | ||||
437 | } else { | ||||
438 | mIceStreams.push_back(videoStream); | ||||
439 | } | ||||
440 | |||||
441 | if (!dcStream) { | ||||
442 | CSFLogErrorS(logTag, __FUNCTION__ << ": datachannel stream is NULL"){ std::ostringstream _oss; _oss << __FUNCTION__ << ": datachannel stream is NULL" << std::endl; CSFLog( CSF_LOG_ERROR , "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 442 , logTag, _oss.str().c_str()); }; | ||||
443 | return NS_ERROR_FAILURE; | ||||
444 | } else { | ||||
445 | mIceStreams.push_back(dcStream); | ||||
446 | } | ||||
447 | |||||
448 | for (std::size_t i=0; i<mIceStreams.size(); i++) { | ||||
449 | mIceStreams[i]->SignalReady.connect(this, &PeerConnectionImpl::IceStreamReady); | ||||
450 | } | ||||
451 | |||||
452 | // Start gathering | ||||
453 | nsresult res; | ||||
454 | mIceCtx->thread()->Dispatch(WrapRunnableRet( | ||||
455 | mIceCtx, &NrIceCtx::StartGathering, &res), NS_DISPATCH_SYNCnsIEventTarget::DISPATCH_SYNC | ||||
456 | ); | ||||
457 | |||||
458 | if (NS_FAILED(res)) { | ||||
459 | CSFLogErrorS(logTag, __FUNCTION__ << ": StartGathering failed: " << res){ std::ostringstream _oss; _oss << __FUNCTION__ << ": StartGathering failed: " << res << std::endl; CSFLog( CSF_LOG_ERROR, "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 459 , logTag, _oss.str().c_str()); }; | ||||
460 | return res; | ||||
461 | } | ||||
462 | |||||
463 | // Store under mHandle | ||||
464 | mCall->setPeerConnection(mHandle); | ||||
465 | peerconnections[mHandle] = this; | ||||
466 | |||||
467 | // Create the DTLS Identity | ||||
468 | mIdentity = DtlsIdentity::Generate(); | ||||
469 | |||||
470 | if (!mIdentity) { | ||||
471 | CSFLogErrorS(logTag, __FUNCTION__ << ": Generate returned NULL"){ std::ostringstream _oss; _oss << __FUNCTION__ << ": Generate returned NULL" << std::endl; CSFLog( CSF_LOG_ERROR , "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 471 , logTag, _oss.str().c_str()); }; | ||||
472 | return NS_ERROR_FAILURE; | ||||
473 | } | ||||
474 | |||||
475 | // Set the fingerprint. Right now assume we only have one | ||||
476 | // DTLS identity | ||||
477 | unsigned char fingerprint[DTLS_FINGERPRINT_LENGTH]; | ||||
478 | size_t fingerprint_length; | ||||
479 | res = mIdentity->ComputeFingerprint("sha-1", | ||||
480 | fingerprint, | ||||
481 | sizeof(fingerprint), | ||||
482 | &fingerprint_length); | ||||
483 | |||||
484 | if (NS_FAILED(res)) { | ||||
485 | CSFLogErrorS(logTag, __FUNCTION__ << ": ComputeFingerprint failed: " << res){ std::ostringstream _oss; _oss << __FUNCTION__ << ": ComputeFingerprint failed: " << res << std::endl ; CSFLog( CSF_LOG_ERROR, "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 485 , logTag, _oss.str().c_str()); }; | ||||
486 | return res; | ||||
487 | } | ||||
488 | |||||
489 | mFingerprint = "sha-1 " + mIdentity->FormatFingerprint(fingerprint, | ||||
490 | fingerprint_length); | ||||
491 | |||||
492 | // Find the STS thread | ||||
493 | mSTSThread = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID"@mozilla.org/network/socket-transport-service;1", &res); | ||||
494 | |||||
495 | if (NS_FAILED(res)) { | ||||
496 | CSFLogErrorS(logTag, __FUNCTION__ << ": do_GetService failed: " << res){ std::ostringstream _oss; _oss << __FUNCTION__ << ": do_GetService failed: " << res << std::endl; CSFLog ( CSF_LOG_ERROR, "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 496 , logTag, _oss.str().c_str()); }; | ||||
497 | return res; | ||||
498 | } | ||||
499 | |||||
500 | #ifndef MOZILLA_INTERNAL_API1 | ||||
501 | // Busy-wait until we are ready, for C++ unit tests. Remove when tests are fixed. | ||||
502 | CSFLogDebugS(logTag, __FUNCTION__ << ": Sleeping until kStarted"){ std::ostringstream _oss; _oss << __FUNCTION__ << ": Sleeping until kStarted" << std::endl; CSFLog( CSF_LOG_DEBUG , "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 502 , logTag, _oss.str().c_str()); }; | ||||
503 | while(PeerConnectionCtx::GetInstance()->sipcc_state() != kStarted) { | ||||
504 | PR_Sleep(100); | ||||
505 | } | ||||
506 | #endif | ||||
507 | |||||
508 | return NS_OK; | ||||
509 | } | ||||
510 | |||||
511 | nsresult | ||||
512 | PeerConnectionImpl::CreateFakeMediaStream(uint32_t aHint, nsIDOMMediaStream** aRetval) | ||||
513 | { | ||||
514 | MOZ_ASSERT(aRetval)do { if (!(aRetval)) { MOZ_ReportAssertionFailure("aRetval", "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 514); do { *((volatile int*) __null) = 123; ::abort(); } while (0); } } while (0); | ||||
515 | |||||
516 | bool mute = false; | ||||
517 | |||||
518 | // Hack to allow you to mute the stream | ||||
519 | if (aHint & MEDIA_STREAM_MUTE) { | ||||
520 | mute = true; | ||||
521 | aHint &= ~MEDIA_STREAM_MUTE; | ||||
522 | } | ||||
523 | |||||
524 | nsresult res; | ||||
525 | if (!mThread || NS_IsMainThreadNS_IsMainThread_P()) { | ||||
526 | res = MakeMediaStream(aHint, aRetval); | ||||
527 | } else { | ||||
528 | mThread->Dispatch(WrapRunnableRet( | ||||
529 | this, &PeerConnectionImpl::MakeMediaStream, aHint, aRetval, &res | ||||
530 | ), NS_DISPATCH_SYNCnsIEventTarget::DISPATCH_SYNC); | ||||
531 | } | ||||
532 | |||||
533 | if (NS_FAILED(res)) { | ||||
534 | return res; | ||||
535 | } | ||||
536 | |||||
537 | if (!mute) { | ||||
538 | if (aHint & nsDOMMediaStream::HINT_CONTENTS_AUDIO) { | ||||
539 | new Fake_AudioGenerator(static_cast<nsDOMMediaStream*>(*aRetval)); | ||||
540 | } else { | ||||
541 | #ifdef MOZILLA_INTERNAL_API1 | ||||
542 | new Fake_VideoGenerator(static_cast<nsDOMMediaStream*>(*aRetval)); | ||||
543 | #endif | ||||
544 | } | ||||
545 | } | ||||
546 | |||||
547 | return NS_OK; | ||||
548 | } | ||||
549 | |||||
550 | // Data channels won't work without a window, so in order for the C++ unit | ||||
551 | // tests to work (it doesn't have a window available) we ifdef the following | ||||
552 | // two implementations. | ||||
553 | NS_IMETHODIMPnsresult | ||||
554 | PeerConnectionImpl::ConnectDataConnection(uint16_t aLocalport, | ||||
555 | uint16_t aRemoteport, | ||||
556 | uint16_t aNumstreams) | ||||
557 | { | ||||
558 | #ifdef MOZILLA_INTERNAL_API1 | ||||
559 | mDataConnection = new mozilla::DataChannelConnection(this); | ||||
560 | NS_ENSURE_TRUE(mDataConnection,NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(mDataConnection)), 0))) { NS_DebugBreak_P (NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "mDataConnection" ") failed" , nullptr, "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 560); return NS_ERROR_FAILURE; } } while(0); | ||||
561 | if (!mDataConnection->Init(aLocalport, aNumstreams, true)) { | ||||
562 | CSFLogError(logTag,"%s DataConnection Init Failed",__FUNCTION__)CSFLog( CSF_LOG_ERROR, "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 562 , logTag , "%s DataConnection Init Failed" ,__FUNCTION__ ); | ||||
563 | return NS_ERROR_FAILURE; | ||||
564 | } | ||||
565 | // XXX Fix! Get the correct flow for DataChannel. Also error handling. | ||||
566 | nsRefPtr<TransportFlow> flow = GetTransportFlow(1,false).get(); | ||||
567 | CSFLogDebugS(logTag, "Transportflow[1] = " << flow.get()){ std::ostringstream _oss; _oss << "Transportflow[1] = " << flow.get() << std::endl; CSFLog( CSF_LOG_DEBUG , "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 567 , logTag, _oss.str().c_str()); }; | ||||
568 | if (!mDataConnection->ConnectDTLS(flow, aLocalport, aRemoteport)) { | ||||
569 | return NS_ERROR_FAILURE; | ||||
570 | } | ||||
571 | return NS_OK; | ||||
572 | #else | ||||
573 | return NS_ERROR_FAILURE; | ||||
574 | #endif | ||||
575 | } | ||||
576 | |||||
577 | NS_IMETHODIMPnsresult | ||||
578 | PeerConnectionImpl::CreateDataChannel(const nsACStringnsACString_internal& aLabel, | ||||
579 | uint16_t aType, | ||||
580 | bool outOfOrderAllowed, | ||||
581 | uint16_t aMaxTime, | ||||
582 | uint16_t aMaxNum, | ||||
583 | nsIDOMDataChannel** aRetval) | ||||
584 | { | ||||
585 | MOZ_ASSERT(aRetval)do { if (!(aRetval)) { MOZ_ReportAssertionFailure("aRetval", "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 585); do { *((volatile int*) __null) = 123; ::abort(); } while (0); } } while (0); | ||||
586 | |||||
587 | #ifdef MOZILLA_INTERNAL_API1 | ||||
588 | mozilla::DataChannel* dataChannel; | ||||
589 | mozilla::DataChannelConnection::Type theType = | ||||
590 | static_cast<mozilla::DataChannelConnection::Type>(aType); | ||||
591 | |||||
592 | if (!mDataConnection) { | ||||
593 | return NS_ERROR_FAILURE; | ||||
594 | } | ||||
595 | dataChannel = mDataConnection->Open( | ||||
596 | aLabel, theType, !outOfOrderAllowed, | ||||
597 | aType == mozilla::DataChannelConnection::PARTIAL_RELIABLE_REXMIT ? aMaxNum : | ||||
598 | (aType == mozilla::DataChannelConnection::PARTIAL_RELIABLE_TIMED ? aMaxTime : 0), | ||||
599 | nullptr, nullptr | ||||
600 | ); | ||||
601 | NS_ENSURE_TRUE(dataChannel,NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(dataChannel)), 0))) { NS_DebugBreak_P (NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "dataChannel" ") failed" , nullptr, "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 601); return NS_ERROR_FAILURE; } } while(0); | ||||
602 | |||||
603 | CSFLogDebugS(logTag, __FUNCTION__ << ": making DOMDataChannel"){ std::ostringstream _oss; _oss << __FUNCTION__ << ": making DOMDataChannel" << std::endl; CSFLog( CSF_LOG_DEBUG , "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 603 , logTag, _oss.str().c_str()); }; | ||||
604 | |||||
605 | return NS_NewDOMDataChannel(dataChannel, mWindow, aRetval); | ||||
606 | #else | ||||
607 | return NS_OK; | ||||
608 | #endif | ||||
609 | } | ||||
610 | |||||
611 | void | ||||
612 | PeerConnectionImpl::NotifyConnection() | ||||
613 | { | ||||
614 | MOZ_ASSERT(NS_IsMainThread())do { if (!(NS_IsMainThread_P())) { MOZ_ReportAssertionFailure ("NS_IsMainThread_P()", "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 614); do { *((volatile int*) __null) = 123; ::abort(); } while (0); } } while (0); | ||||
615 | |||||
616 | CSFLogDebugS(logTag, __FUNCTION__){ std::ostringstream _oss; _oss << __FUNCTION__ << std::endl; CSFLog( CSF_LOG_DEBUG, "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 616 , logTag, _oss.str().c_str()); }; | ||||
617 | |||||
618 | #ifdef MOZILLA_INTERNAL_API1 | ||||
619 | if (mPCObserver) { | ||||
620 | PeerConnectionObserverDispatch* runnable = | ||||
621 | new PeerConnectionObserverDispatch(PC_OBSERVER_CONNECTION, nullptr, | ||||
622 | this, mPCObserver); | ||||
623 | if (mThread) { | ||||
624 | mThread->Dispatch(runnable, NS_DISPATCH_NORMALnsIEventTarget::DISPATCH_NORMAL); | ||||
625 | return; | ||||
626 | } | ||||
627 | runnable->Run(); | ||||
628 | } | ||||
629 | #endif | ||||
630 | } | ||||
631 | |||||
632 | void | ||||
633 | PeerConnectionImpl::NotifyClosedConnection() | ||||
634 | { | ||||
635 | MOZ_ASSERT(NS_IsMainThread())do { if (!(NS_IsMainThread_P())) { MOZ_ReportAssertionFailure ("NS_IsMainThread_P()", "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 635); do { *((volatile int*) __null) = 123; ::abort(); } while (0); } } while (0); | ||||
636 | |||||
637 | CSFLogDebugS(logTag, __FUNCTION__){ std::ostringstream _oss; _oss << __FUNCTION__ << std::endl; CSFLog( CSF_LOG_DEBUG, "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 637 , logTag, _oss.str().c_str()); }; | ||||
638 | |||||
639 | #ifdef MOZILLA_INTERNAL_API1 | ||||
640 | if (mPCObserver) { | ||||
641 | PeerConnectionObserverDispatch* runnable = | ||||
642 | new PeerConnectionObserverDispatch(PC_OBSERVER_CLOSEDCONNECTION, nullptr, | ||||
643 | this, mPCObserver); | ||||
644 | if (mThread) { | ||||
645 | mThread->Dispatch(runnable, NS_DISPATCH_NORMALnsIEventTarget::DISPATCH_NORMAL); | ||||
646 | return; | ||||
647 | } | ||||
648 | runnable->Run(); | ||||
649 | } | ||||
650 | #endif | ||||
651 | } | ||||
652 | |||||
653 | void | ||||
654 | PeerConnectionImpl::NotifyDataChannel(mozilla::DataChannel *aChannel) | ||||
655 | { | ||||
656 | MOZ_ASSERT(NS_IsMainThread())do { if (!(NS_IsMainThread_P())) { MOZ_ReportAssertionFailure ("NS_IsMainThread_P()", "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 656); do { *((volatile int*) __null) = 123; ::abort(); } while (0); } } while (0); | ||||
657 | MOZ_ASSERT(aChannel)do { if (!(aChannel)) { MOZ_ReportAssertionFailure("aChannel" , "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 657); do { *((volatile int*) __null) = 123; ::abort(); } while (0); } } while (0); | ||||
658 | |||||
659 | CSFLogDebugS(logTag, __FUNCTION__ << ": channel: " << static_cast<void*>(aChannel)){ std::ostringstream _oss; _oss << __FUNCTION__ << ": channel: " << static_cast<void*>(aChannel) << std::endl; CSFLog( CSF_LOG_DEBUG, "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 659 , logTag, _oss.str().c_str()); }; | ||||
660 | |||||
661 | #ifdef MOZILLA_INTERNAL_API1 | ||||
662 | nsCOMPtr<nsIDOMDataChannel> domchannel; | ||||
663 | nsresult rv = NS_NewDOMDataChannel(aChannel, mWindow, | ||||
664 | getter_AddRefs(domchannel)); | ||||
665 | NS_ENSURE_SUCCESS(rv,)do { nsresult __rv = rv; if (NS_FAILED(__rv)) { char *msg = PR_smprintf ("NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%X", "rv" , "", __rv); NS_DebugBreak_P(NS_DEBUG_WARNING, msg, nullptr, "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 665); PR_smprintf_free(msg); return ; } } while(0); | ||||
666 | if (mPCObserver) { | ||||
667 | PeerConnectionObserverDispatch* runnable = | ||||
668 | new PeerConnectionObserverDispatch(PC_OBSERVER_DATACHANNEL, domchannel.get(), | ||||
669 | this, mPCObserver); | ||||
670 | if (mThread) { | ||||
671 | mThread->Dispatch(runnable, NS_DISPATCH_NORMALnsIEventTarget::DISPATCH_NORMAL); | ||||
672 | return; | ||||
673 | } | ||||
674 | runnable->Run(); | ||||
675 | } | ||||
676 | #endif | ||||
677 | } | ||||
678 | |||||
679 | /* | ||||
680 | * CC_SDP_DIRECTION_SENDRECV will not be used when Constraints are implemented | ||||
681 | */ | ||||
682 | NS_IMETHODIMPnsresult | ||||
683 | PeerConnectionImpl::CreateOffer(const char* aHints) { | ||||
684 | MOZ_ASSERT(aHints)do { if (!(aHints)) { MOZ_ReportAssertionFailure("aHints", "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 684); do { *((volatile int*) __null) = 123; ::abort(); } while (0); } } while (0); | ||||
685 | |||||
686 | CheckIceState(); | ||||
687 | mRole = kRoleOfferer; // TODO(ekr@rtfm.com): Interrogate SIPCC here? | ||||
688 | mCall->createOffer(aHints); | ||||
689 | return NS_OK; | ||||
690 | } | ||||
691 | |||||
692 | NS_IMETHODIMPnsresult | ||||
693 | PeerConnectionImpl::CreateAnswer(const char* aHints, const char* aOffer) { | ||||
694 | MOZ_ASSERT(aHints)do { if (!(aHints)) { MOZ_ReportAssertionFailure("aHints", "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 694); do { *((volatile int*) __null) = 123; ::abort(); } while (0); } } while (0); | ||||
695 | MOZ_ASSERT(aOffer)do { if (!(aOffer)) { MOZ_ReportAssertionFailure("aOffer", "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 695); do { *((volatile int*) __null) = 123; ::abort(); } while (0); } } while (0); | ||||
696 | |||||
697 | CheckIceState(); | ||||
698 | mRole = kRoleAnswerer; // TODO(ekr@rtfm.com): Interrogate SIPCC here? | ||||
699 | mCall->createAnswer(aHints, aOffer); | ||||
700 | return NS_OK; | ||||
701 | } | ||||
702 | |||||
703 | NS_IMETHODIMPnsresult | ||||
704 | PeerConnectionImpl::SetLocalDescription(int32_t aAction, const char* aSDP) { | ||||
705 | MOZ_ASSERT(aSDP)do { if (!(aSDP)) { MOZ_ReportAssertionFailure("aSDP", "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 705); do { *((volatile int*) __null) = 123; ::abort(); } while (0); } } while (0); | ||||
706 | |||||
707 | CheckIceState(); | ||||
708 | mLocalRequestedSDP = aSDP; | ||||
709 | mCall->setLocalDescription((cc_jsep_action_t)aAction, mLocalRequestedSDP); | ||||
710 | return NS_OK; | ||||
711 | } | ||||
712 | |||||
713 | NS_IMETHODIMPnsresult | ||||
714 | PeerConnectionImpl::SetRemoteDescription(int32_t action, const char* aSDP) { | ||||
715 | MOZ_ASSERT(aSDP)do { if (!(aSDP)) { MOZ_ReportAssertionFailure("aSDP", "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 715); do { *((volatile int*) __null) = 123; ::abort(); } while (0); } } while (0); | ||||
716 | |||||
717 | CheckIceState(); | ||||
718 | mRemoteRequestedSDP = aSDP; | ||||
719 | mCall->setRemoteDescription((cc_jsep_action_t)action, mRemoteRequestedSDP); | ||||
720 | return NS_OK; | ||||
721 | } | ||||
722 | |||||
723 | NS_IMETHODIMPnsresult | ||||
724 | PeerConnectionImpl::AddStream(nsIDOMMediaStream* aMediaStream) | ||||
725 | { | ||||
726 | MOZ_ASSERT(aMediaStream)do { if (!(aMediaStream)) { MOZ_ReportAssertionFailure("aMediaStream" , "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 726); do { *((volatile int*) __null) = 123; ::abort(); } while (0); } } while (0); | ||||
727 | |||||
728 | nsDOMMediaStream* stream = static_cast<nsDOMMediaStream*>(aMediaStream); | ||||
729 | |||||
730 | CSFLogDebugS(logTag, __FUNCTION__ << ": MediaStream: " << static_cast<void*>(aMediaStream)){ std::ostringstream _oss; _oss << __FUNCTION__ << ": MediaStream: " << static_cast<void*>(aMediaStream ) << std::endl; CSFLog( CSF_LOG_DEBUG, "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 730 , logTag, _oss.str().c_str()); }; | ||||
731 | |||||
732 | // TODO(ekr@rtfm.com): Remove these asserts? | ||||
733 | // Adding tracks here based on nsDOMMediaStream expectation settings | ||||
734 | uint32_t hints = stream->GetHintContents(); | ||||
735 | |||||
736 | if (!(hints & (nsDOMMediaStream::HINT_CONTENTS_AUDIO | | ||||
737 | nsDOMMediaStream::HINT_CONTENTS_VIDEO))) { | ||||
738 | CSFLogDebug(logTag, "Empty Stream !!")CSFLog(CSF_LOG_DEBUG, "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 738 , logTag , "Empty Stream !!" ); | ||||
739 | return NS_OK; | ||||
740 | } | ||||
741 | |||||
742 | // Now see if we already have a stream of this type, since we only | ||||
743 | // allow one of each. | ||||
744 | // TODO(ekr@rtfm.com): remove this when multiple of each stream | ||||
745 | // is allowed | ||||
746 | PR_Lock(mLocalSourceStreamsLock); | ||||
747 | for (uint32_t u = 0; u < mLocalSourceStreams.Length(); u++) { | ||||
748 | nsRefPtr<LocalSourceStreamInfo> localSourceStream = mLocalSourceStreams[u]; | ||||
749 | |||||
750 | if (localSourceStream->GetMediaStream()->GetHintContents() & hints) { | ||||
751 | CSFLogError(logTag, "Only one stream of any given type allowed")CSFLog( CSF_LOG_ERROR, "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 751 , logTag , "Only one stream of any given type allowed" ); | ||||
752 | PR_Unlock(mLocalSourceStreamsLock); | ||||
753 | return NS_ERROR_FAILURE; | ||||
754 | } | ||||
755 | } | ||||
756 | |||||
757 | // OK, we're good to add | ||||
758 | nsRefPtr<LocalSourceStreamInfo> localSourceStream = | ||||
759 | new LocalSourceStreamInfo(stream); | ||||
760 | cc_media_track_id_t media_stream_id = mLocalSourceStreams.Length(); | ||||
761 | |||||
762 | // TODO(ekr@rtfm.com): these integers should be the track IDs | ||||
763 | if (hints & nsDOMMediaStream::HINT_CONTENTS_AUDIO) { | ||||
764 | localSourceStream->ExpectAudio(TRACK_AUDIO); | ||||
765 | mCall->addStream(media_stream_id, 0, AUDIO); | ||||
766 | } | ||||
767 | |||||
768 | if (hints & nsDOMMediaStream::HINT_CONTENTS_VIDEO) { | ||||
769 | localSourceStream->ExpectVideo(TRACK_VIDEO); | ||||
770 | mCall->addStream(media_stream_id, 1, VIDEO); | ||||
771 | } | ||||
772 | |||||
773 | // Make it the listener for info from the MediaStream and add it to the list | ||||
774 | mozilla::MediaStream *plainMediaStream = stream->GetStream(); | ||||
775 | |||||
776 | if (plainMediaStream) { | ||||
777 | plainMediaStream->AddListener(localSourceStream); | ||||
778 | } | ||||
779 | |||||
780 | mLocalSourceStreams.AppendElement(localSourceStream); | ||||
781 | |||||
782 | PR_Unlock(mLocalSourceStreamsLock); | ||||
783 | return NS_OK; | ||||
784 | } | ||||
785 | |||||
786 | NS_IMETHODIMPnsresult | ||||
787 | PeerConnectionImpl::RemoveStream(nsIDOMMediaStream* aMediaStream) | ||||
788 | { | ||||
789 | MOZ_ASSERT(aMediaStream)do { if (!(aMediaStream)) { MOZ_ReportAssertionFailure("aMediaStream" , "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 789); do { *((volatile int*) __null) = 123; ::abort(); } while (0); } } while (0); | ||||
790 | |||||
791 | nsDOMMediaStream* stream = static_cast<nsDOMMediaStream*>(aMediaStream); | ||||
792 | |||||
793 | CSFLogDebugS(logTag, __FUNCTION__ << ": MediaStream: " << static_cast<void*>(aMediaStream)){ std::ostringstream _oss; _oss << __FUNCTION__ << ": MediaStream: " << static_cast<void*>(aMediaStream ) << std::endl; CSFLog( CSF_LOG_DEBUG, "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 793 , logTag, _oss.str().c_str()); }; | ||||
794 | |||||
795 | PR_Lock(mLocalSourceStreamsLock); | ||||
796 | for (uint32_t u = 0; u < mLocalSourceStreams.Length(); u++) { | ||||
797 | nsRefPtr<LocalSourceStreamInfo> localSourceStream = mLocalSourceStreams[u]; | ||||
798 | if (localSourceStream->GetMediaStream() == stream) { | ||||
799 | uint32_t hints = stream->GetHintContents(); | ||||
800 | if (hints & nsDOMMediaStream::HINT_CONTENTS_AUDIO) { | ||||
801 | // <emannion> This API will change when we implement multiple streams | ||||
802 | // It will only need the ID | ||||
803 | mCall->removeStream(u, 0, AUDIO); | ||||
804 | } | ||||
805 | if (hints & nsDOMMediaStream::HINT_CONTENTS_VIDEO) { | ||||
806 | mCall->removeStream(u, 1, VIDEO); | ||||
807 | } | ||||
808 | break; | ||||
809 | } | ||||
810 | } | ||||
811 | |||||
812 | PR_Unlock(mLocalSourceStreamsLock); | ||||
813 | return NS_OK; | ||||
814 | } | ||||
815 | |||||
816 | NS_IMETHODIMPnsresult | ||||
817 | PeerConnectionImpl::AddIceCandidate(const char* aCandidate, const char* aMid, unsigned short aLevel) { | ||||
818 | CheckIceState(); | ||||
819 | mCall->addICECandidate(aCandidate, aMid, aLevel); | ||||
820 | return NS_OK; | ||||
821 | } | ||||
822 | |||||
823 | NS_IMETHODIMPnsresult | ||||
824 | PeerConnectionImpl::CloseStreams() { | ||||
825 | if (mReadyState != PeerConnectionImpl::kClosed) { | ||||
826 | ChangeReadyState(PeerConnectionImpl::kClosing); | ||||
827 | } | ||||
828 | |||||
829 | mCall->endCall(); | ||||
830 | return NS_OK; | ||||
831 | } | ||||
832 | |||||
833 | /* | ||||
834 | NS_IMETHODIMP | ||||
835 | PeerConnectionImpl::SetRemoteFingerprint(const char* hash, const char* fingerprint) | ||||
836 | { | ||||
837 | MOZ_ASSERT(hash); | ||||
838 | MOZ_ASSERT(fingerprint); | ||||
839 | |||||
840 | if (fingerprint != NULL && (strcmp(hash, "sha-1") == 0)) { | ||||
841 | mRemoteFingerprint = std::string(fingerprint); | ||||
842 | CSFLogDebugS(logTag, "Setting remote fingerprint to " << mRemoteFingerprint); | ||||
843 | return NS_OK; | ||||
844 | } else { | ||||
845 | CSFLogError(logTag, "%s: Invalid Remote Finger Print", __FUNCTION__); | ||||
846 | return NS_ERROR_FAILURE; | ||||
847 | } | ||||
848 | } | ||||
849 | |||||
850 | NS_IMETHODIMP | ||||
851 | PeerConnectionImpl::GetFingerprint(char** fingerprint) | ||||
852 | { | ||||
853 | MOZ_ASSERT(fingerprint); | ||||
854 | |||||
855 | if (!mIdentity) { | ||||
856 | return NS_ERROR_FAILURE; | ||||
857 | } | ||||
858 | |||||
859 | char* tmp = new char[mFingerprint.size() + 1]; | ||||
860 | std::copy(mFingerprint.begin(), mFingerprint.end(), tmp); | ||||
861 | tmp[mFingerprint.size()] = '\0'; | ||||
862 | |||||
863 | *fingerprint = tmp; | ||||
864 | return NS_OK; | ||||
865 | } | ||||
866 | */ | ||||
867 | |||||
868 | NS_IMETHODIMPnsresult | ||||
869 | PeerConnectionImpl::GetLocalDescription(char** aSDP) | ||||
870 | { | ||||
871 | MOZ_ASSERT(aSDP)do { if (!(aSDP)) { MOZ_ReportAssertionFailure("aSDP", "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 871); do { *((volatile int*) __null) = 123; ::abort(); } while (0); } } while (0); | ||||
872 | |||||
873 | char* tmp = new char[mLocalSDP.size() + 1]; | ||||
874 | std::copy(mLocalSDP.begin(), mLocalSDP.end(), tmp); | ||||
875 | tmp[mLocalSDP.size()] = '\0'; | ||||
876 | |||||
877 | *aSDP = tmp; | ||||
878 | return NS_OK; | ||||
879 | } | ||||
880 | |||||
881 | NS_IMETHODIMPnsresult | ||||
882 | PeerConnectionImpl::GetRemoteDescription(char** aSDP) | ||||
883 | { | ||||
884 | MOZ_ASSERT(aSDP)do { if (!(aSDP)) { MOZ_ReportAssertionFailure("aSDP", "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 884); do { *((volatile int*) __null) = 123; ::abort(); } while (0); } } while (0); | ||||
885 | |||||
886 | char* tmp = new char[mRemoteSDP.size() + 1]; | ||||
887 | std::copy(mRemoteSDP.begin(), mRemoteSDP.end(), tmp); | ||||
888 | tmp[mRemoteSDP.size()] = '\0'; | ||||
889 | |||||
890 | *aSDP = tmp; | ||||
891 | return NS_OK; | ||||
892 | } | ||||
893 | |||||
894 | NS_IMETHODIMPnsresult | ||||
895 | PeerConnectionImpl::GetReadyState(uint32_t* aState) | ||||
896 | { | ||||
897 | MOZ_ASSERT(aState)do { if (!(aState)) { MOZ_ReportAssertionFailure("aState", "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 897); do { *((volatile int*) __null) = 123; ::abort(); } while (0); } } while (0); | ||||
898 | |||||
899 | *aState = mReadyState; | ||||
900 | return NS_OK; | ||||
901 | } | ||||
902 | |||||
903 | NS_IMETHODIMPnsresult | ||||
904 | PeerConnectionImpl::GetSipccState(uint32_t* aState) | ||||
905 | { | ||||
906 | MOZ_ASSERT(aState)do { if (!(aState)) { MOZ_ReportAssertionFailure("aState", "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 906); do { *((volatile int*) __null) = 123; ::abort(); } while (0); } } while (0); | ||||
907 | |||||
908 | PeerConnectionCtx* pcctx = PeerConnectionCtx::GetInstance(); | ||||
909 | *aState = pcctx ? pcctx->sipcc_state() : kIdle; | ||||
910 | return NS_OK; | ||||
911 | } | ||||
912 | |||||
913 | NS_IMETHODIMPnsresult | ||||
914 | PeerConnectionImpl::GetIceState(uint32_t* aState) | ||||
915 | { | ||||
916 | MOZ_ASSERT(aState)do { if (!(aState)) { MOZ_ReportAssertionFailure("aState", "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 916); do { *((volatile int*) __null) = 123; ::abort(); } while (0); } } while (0); | ||||
917 | |||||
918 | *aState = mIceState; | ||||
919 | return NS_OK; | ||||
920 | } | ||||
921 | |||||
922 | NS_IMETHODIMPnsresult | ||||
923 | PeerConnectionImpl::Close() | ||||
924 | { | ||||
925 | if (mCall != NULL__null) | ||||
926 | mCall->endCall(); | ||||
927 | #ifdef MOZILLA_INTERNAL_API1 | ||||
928 | if (mDataConnection != NULL__null) | ||||
929 | mDataConnection->CloseAll(); | ||||
930 | #endif | ||||
931 | |||||
932 | ShutdownMedia(); | ||||
933 | |||||
934 | // DataConnection will need to stay alive until all threads/runnables exit | ||||
935 | |||||
936 | return NS_OK; | ||||
937 | } | ||||
938 | |||||
939 | void | ||||
940 | PeerConnectionImpl::ShutdownMedia() | ||||
941 | { | ||||
942 | CSFLogDebugS(logTag, __FUNCTION__ << " Disconnecting media streams from PC"){ std::ostringstream _oss; _oss << __FUNCTION__ << " Disconnecting media streams from PC" << std::endl; CSFLog ( CSF_LOG_DEBUG, "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 942 , logTag, _oss.str().c_str()); }; | ||||
943 | // Disconnect ourselves from the DOM Media Streams | ||||
944 | RUN_ON_THREAD(mThread, WrapRunnable(this,((mThread && (mThread != nsRefPtr<nsIThread>(do_GetCurrentThread ()))) ? mThread->Dispatch(WrapRunnable(this, &PeerConnectionImpl ::DisconnectMediaStreams), nsIEventTarget::DISPATCH_SYNC) : WrapRunnable (this, &PeerConnectionImpl::DisconnectMediaStreams)->Run ()) | ||||
945 | &PeerConnectionImpl::DisconnectMediaStreams), NS_DISPATCH_SYNC)((mThread && (mThread != nsRefPtr<nsIThread>(do_GetCurrentThread ()))) ? mThread->Dispatch(WrapRunnable(this, &PeerConnectionImpl ::DisconnectMediaStreams), nsIEventTarget::DISPATCH_SYNC) : WrapRunnable (this, &PeerConnectionImpl::DisconnectMediaStreams)->Run ()); | ||||
946 | |||||
947 | CSFLogDebugS(logTag, __FUNCTION__ << " Disconnecting transport"){ std::ostringstream _oss; _oss << __FUNCTION__ << " Disconnecting transport" << std::endl; CSFLog( CSF_LOG_DEBUG , "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 947 , logTag, _oss.str().c_str()); }; | ||||
948 | // Shutdown the transport. | ||||
949 | RUN_ON_THREAD(mSTSThread, WrapRunnable(((mSTSThread && (mSTSThread != nsRefPtr<nsIThread> (do_GetCurrentThread()))) ? mSTSThread->Dispatch(WrapRunnable ( this, &PeerConnectionImpl::ShutdownMediaTransport), nsIEventTarget ::DISPATCH_SYNC) : WrapRunnable( this, &PeerConnectionImpl ::ShutdownMediaTransport)->Run()) | ||||
950 | this, &PeerConnectionImpl::ShutdownMediaTransport), NS_DISPATCH_SYNC)((mSTSThread && (mSTSThread != nsRefPtr<nsIThread> (do_GetCurrentThread()))) ? mSTSThread->Dispatch(WrapRunnable ( this, &PeerConnectionImpl::ShutdownMediaTransport), nsIEventTarget ::DISPATCH_SYNC) : WrapRunnable( this, &PeerConnectionImpl ::ShutdownMediaTransport)->Run()); | ||||
951 | |||||
952 | CSFLogDebugS(logTag, __FUNCTION__ << " Media shut down"){ std::ostringstream _oss; _oss << __FUNCTION__ << " Media shut down" << std::endl; CSFLog( CSF_LOG_DEBUG , "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 952 , logTag, _oss.str().c_str()); }; | ||||
953 | } | ||||
954 | |||||
955 | void | ||||
956 | PeerConnectionImpl::DisconnectMediaStreams() | ||||
957 | { | ||||
958 | // TODO(ekr@rtfm.com): Lock | ||||
959 | for (uint32_t i=0; i < mLocalSourceStreams.Length(); ++i) { | ||||
960 | mLocalSourceStreams[i]->Detach(); | ||||
961 | } | ||||
962 | |||||
963 | for (uint32_t i=0; i < mRemoteSourceStreams.Length(); ++i) { | ||||
964 | mRemoteSourceStreams[i]->Detach(); | ||||
965 | } | ||||
966 | |||||
967 | mLocalSourceStreams.Clear(); | ||||
968 | mRemoteSourceStreams.Clear(); | ||||
969 | } | ||||
970 | |||||
971 | void | ||||
972 | PeerConnectionImpl::ShutdownMediaTransport() | ||||
973 | { | ||||
974 | mTransportFlows.clear(); | ||||
975 | mIceStreams.clear(); | ||||
976 | mIceCtx = NULL__null; | ||||
977 | } | ||||
978 | |||||
979 | void | ||||
980 | PeerConnectionImpl::Shutdown() | ||||
981 | { | ||||
982 | PeerConnectionCtx::Destroy(); | ||||
983 | } | ||||
984 | |||||
985 | void | ||||
986 | PeerConnectionImpl::onCallEvent(ccapi_call_event_e aCallEvent, | ||||
987 | CSF::CC_CallPtr aCall, CSF::CC_CallInfoPtr aInfo) | ||||
988 | { | ||||
989 | MOZ_ASSERT(aCall.get())do { if (!(aCall.get())) { MOZ_ReportAssertionFailure("aCall.get()" , "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 989); do { *((volatile int*) __null) = 123; ::abort(); } while (0); } } while (0); | ||||
990 | MOZ_ASSERT(aInfo.get())do { if (!(aInfo.get())) { MOZ_ReportAssertionFailure("aInfo.get()" , "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 990); do { *((volatile int*) __null) = 123; ::abort(); } while (0); } } while (0); | ||||
991 | |||||
992 | cc_call_state_t event = aInfo->getCallState(); | ||||
993 | std::string statestr = aInfo->callStateToString(event); | ||||
994 | |||||
995 | if (CCAPI_CALL_EV_CREATED != aCallEvent && CCAPI_CALL_EV_STATE != aCallEvent) { | ||||
996 | CSFLogDebugS(logTag, ": **** CALL HANDLE IS: " << mHandle <<{ std::ostringstream _oss; _oss << ": **** CALL HANDLE IS: " << mHandle << ": **** CALL STATE IS: " << statestr << std::endl; CSFLog( CSF_LOG_DEBUG, "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 997 , logTag, _oss.str().c_str()); } | ||||
997 | ": **** CALL STATE IS: " << statestr){ std::ostringstream _oss; _oss << ": **** CALL HANDLE IS: " << mHandle << ": **** CALL STATE IS: " << statestr << std::endl; CSFLog( CSF_LOG_DEBUG, "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 997 , logTag, _oss.str().c_str()); }; | ||||
998 | return; | ||||
999 | } | ||||
1000 | |||||
1001 | switch (event) { | ||||
1002 | case SETLOCALDESC: | ||||
1003 | mLocalSDP = mLocalRequestedSDP; | ||||
1004 | break; | ||||
1005 | case SETREMOTEDESC: | ||||
1006 | mRemoteSDP = mRemoteRequestedSDP; | ||||
1007 | break; | ||||
1008 | case CONNECTED: | ||||
1009 | CSFLogDebugS(logTag, "Setting PeerConnnection state to kActive"){ std::ostringstream _oss; _oss << "Setting PeerConnnection state to kActive" << std::endl; CSFLog( CSF_LOG_DEBUG, "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 1009 , logTag, _oss.str().c_str()); }; | ||||
1010 | ChangeReadyState(kActive); | ||||
1011 | break; | ||||
1012 | default: | ||||
1013 | break; | ||||
1014 | } | ||||
1015 | |||||
1016 | if (mPCObserver) { | ||||
1017 | PeerConnectionObserverDispatch* runnable = | ||||
1018 | new PeerConnectionObserverDispatch(aInfo, this, mPCObserver); | ||||
1019 | |||||
1020 | if (mThread) { | ||||
1021 | mThread->Dispatch(runnable, NS_DISPATCH_NORMALnsIEventTarget::DISPATCH_NORMAL); | ||||
1022 | return; | ||||
1023 | } | ||||
1024 | runnable->Run(); | ||||
1025 | } | ||||
1026 | } | ||||
1027 | |||||
1028 | void | ||||
1029 | PeerConnectionImpl::ChangeReadyState(PeerConnectionImpl::ReadyState aReadyState) | ||||
1030 | { | ||||
1031 | mReadyState = aReadyState; | ||||
1032 | // FIXME: Dispatch on main thread. | ||||
1033 | if (mPCObserver) { | ||||
1034 | PeerConnectionObserverDispatch* runnable = | ||||
1035 | new PeerConnectionObserverDispatch(PC_OBSERVER_READYSTATE, this, mPCObserver); | ||||
1036 | |||||
1037 | if (mThread) { | ||||
1038 | mThread->Dispatch(runnable, NS_DISPATCH_NORMALnsIEventTarget::DISPATCH_NORMAL); | ||||
1039 | return; | ||||
1040 | } | ||||
1041 | runnable->Run(); | ||||
1042 | } | ||||
1043 | } | ||||
1044 | |||||
1045 | PeerConnectionWrapper *PeerConnectionImpl::AcquireInstance(const std::string& aHandle) | ||||
1046 | { | ||||
1047 | if (peerconnections.find(aHandle) == peerconnections.end()) { | ||||
1048 | return NULL__null; | ||||
1049 | } | ||||
1050 | |||||
1051 | PeerConnectionImpl *impl = peerconnections[aHandle]; | ||||
1052 | impl->AddRef(); | ||||
1053 | |||||
1054 | return new PeerConnectionWrapper(impl); | ||||
1055 | } | ||||
1056 | |||||
1057 | void | ||||
1058 | PeerConnectionImpl::ReleaseInstance() | ||||
1059 | { | ||||
1060 | Release(); | ||||
1061 | } | ||||
1062 | |||||
1063 | const std::string& | ||||
1064 | PeerConnectionImpl::GetHandle() | ||||
1065 | { | ||||
1066 | return mHandle; | ||||
1067 | } | ||||
1068 | |||||
1069 | void | ||||
1070 | PeerConnectionImpl::IceGatheringCompleted(NrIceCtx *aCtx) | ||||
1071 | { | ||||
1072 | MOZ_ASSERT(aCtx)do { if (!(aCtx)) { MOZ_ReportAssertionFailure("aCtx", "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 1072); do { *((volatile int*) __null) = 123; ::abort(); } while (0); } } while (0); | ||||
1073 | |||||
1074 | CSFLogDebugS(logTag, __FUNCTION__ << ": ctx: " << static_cast<void*>(aCtx)){ std::ostringstream _oss; _oss << __FUNCTION__ << ": ctx: " << static_cast<void*>(aCtx) << std ::endl; CSFLog( CSF_LOG_DEBUG, "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 1074 , logTag, _oss.str().c_str()); }; | ||||
1075 | |||||
1076 | mIceState = kIceWaiting; | ||||
1077 | |||||
1078 | #ifdef MOZILLA_INTERNAL_API1 | ||||
1079 | if (mPCObserver) { | ||||
1080 | PeerConnectionObserverDispatch* runnable = | ||||
1081 | new PeerConnectionObserverDispatch(PC_OBSERVER_ICE, this, mPCObserver); | ||||
1082 | if (mThread) { | ||||
1083 | mThread->Dispatch(runnable, NS_DISPATCH_NORMALnsIEventTarget::DISPATCH_NORMAL); | ||||
1084 | return; | ||||
1085 | } | ||||
1086 | runnable->Run(); | ||||
1087 | } | ||||
1088 | #endif | ||||
1089 | } | ||||
1090 | |||||
1091 | void | ||||
1092 | PeerConnectionImpl::IceCompleted(NrIceCtx *aCtx) | ||||
1093 | { | ||||
1094 | MOZ_ASSERT(aCtx)do { if (!(aCtx)) { MOZ_ReportAssertionFailure("aCtx", "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 1094); do { *((volatile int*) __null) = 123; ::abort(); } while (0); } } while (0); | ||||
1095 | |||||
1096 | CSFLogDebugS(logTag, __FUNCTION__ << ": ctx: " << static_cast<void*>(aCtx)){ std::ostringstream _oss; _oss << __FUNCTION__ << ": ctx: " << static_cast<void*>(aCtx) << std ::endl; CSFLog( CSF_LOG_DEBUG, "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 1096 , logTag, _oss.str().c_str()); }; | ||||
1097 | |||||
1098 | mIceState = kIceConnected; | ||||
1099 | |||||
1100 | #ifdef MOZILLA_INTERNAL_API1 | ||||
1101 | if (mPCObserver) { | ||||
1102 | PeerConnectionObserverDispatch* runnable = | ||||
1103 | new PeerConnectionObserverDispatch(PC_OBSERVER_ICE, this, mPCObserver); | ||||
1104 | if (mThread) { | ||||
1105 | mThread->Dispatch(runnable, NS_DISPATCH_NORMALnsIEventTarget::DISPATCH_NORMAL); | ||||
1106 | return; | ||||
1107 | } | ||||
1108 | runnable->Run(); | ||||
1109 | } | ||||
1110 | #endif | ||||
1111 | } | ||||
1112 | |||||
1113 | void | ||||
1114 | PeerConnectionImpl::IceStreamReady(NrIceMediaStream *aStream) | ||||
1115 | { | ||||
1116 | MOZ_ASSERT(aStream)do { if (!(aStream)) { MOZ_ReportAssertionFailure("aStream", "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 1116); do { *((volatile int*) __null) = 123; ::abort(); } while (0); } } while (0); | ||||
1117 | |||||
1118 | CSFLogDebugS(logTag, __FUNCTION__ << ": " << aStream->name().c_str()){ std::ostringstream _oss; _oss << __FUNCTION__ << ": " << aStream->name().c_str() << std::endl; CSFLog( CSF_LOG_DEBUG, "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 1118 , logTag, _oss.str().c_str()); }; | ||||
1119 | } | ||||
1120 | |||||
1121 | nsRefPtr<LocalSourceStreamInfo> | ||||
1122 | PeerConnectionImpl::GetLocalStream(int aIndex) | ||||
1123 | { | ||||
1124 | if(aIndex < 0 || aIndex >= (int) mLocalSourceStreams.Length()) { | ||||
1125 | return NULL__null; | ||||
1126 | } | ||||
1127 | |||||
1128 | MOZ_ASSERT(mLocalSourceStreams[aIndex])do { if (!(mLocalSourceStreams[aIndex])) { MOZ_ReportAssertionFailure ("mLocalSourceStreams[aIndex]", "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 1128); do { *((volatile int*) __null) = 123; ::abort(); } while (0); } } while (0); | ||||
1129 | return mLocalSourceStreams[aIndex]; | ||||
1130 | } | ||||
1131 | |||||
1132 | nsRefPtr<RemoteSourceStreamInfo> | ||||
1133 | PeerConnectionImpl::GetRemoteStream(int aIndex) | ||||
1134 | { | ||||
1135 | if(aIndex < 0 || aIndex >= (int) mRemoteSourceStreams.Length()) { | ||||
1136 | return NULL__null; | ||||
1137 | } | ||||
1138 | |||||
1139 | MOZ_ASSERT(mRemoteSourceStreams[aIndex])do { if (!(mRemoteSourceStreams[aIndex])) { MOZ_ReportAssertionFailure ("mRemoteSourceStreams[aIndex]", "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 1139); do { *((volatile int*) __null) = 123; ::abort(); } while (0); } } while (0); | ||||
1140 | return mRemoteSourceStreams[aIndex]; | ||||
1141 | } | ||||
1142 | |||||
1143 | nsresult | ||||
1144 | PeerConnectionImpl::AddRemoteStream(nsRefPtr<RemoteSourceStreamInfo> aInfo, | ||||
1145 | int *aIndex) | ||||
1146 | { | ||||
1147 | MOZ_ASSERT(aIndex)do { if (!(aIndex)) { MOZ_ReportAssertionFailure("aIndex", "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 1147); do { *((volatile int*) __null) = 123; ::abort(); } while (0); } } while (0); | ||||
Within the expansion of the macro 'MOZ_ASSERT':
| |||||
1148 | |||||
1149 | *aIndex = mRemoteSourceStreams.Length(); | ||||
1150 | |||||
1151 | mRemoteSourceStreams.AppendElement(aInfo); | ||||
1152 | |||||
1153 | return NS_OK; | ||||
1154 | } | ||||
1155 | |||||
1156 | void | ||||
1157 | LocalSourceStreamInfo::StorePipeline(int aTrack, | ||||
1158 | mozilla::RefPtr<mozilla::MediaPipeline> aPipeline) | ||||
1159 | { | ||||
1160 | MOZ_ASSERT(mPipelines.find(aTrack) == mPipelines.end())do { if (!(mPipelines.find(aTrack) == mPipelines.end())) { MOZ_ReportAssertionFailure ("mPipelines.find(aTrack) == mPipelines.end()", "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 1160); do { *((volatile int*) __null) = 123; ::abort(); } while (0); } } while (0); | ||||
1161 | if (mPipelines.find(aTrack) != mPipelines.end()) { | ||||
1162 | CSFLogErrorS(logTag, __FUNCTION__ << ": Storing duplicate track"){ std::ostringstream _oss; _oss << __FUNCTION__ << ": Storing duplicate track" << std::endl; CSFLog( CSF_LOG_ERROR , "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 1162 , logTag, _oss.str().c_str()); }; | ||||
1163 | return; | ||||
1164 | } | ||||
1165 | //TODO: Revisit once we start supporting multiple streams or multiple tracks | ||||
1166 | // of same type | ||||
1167 | mPipelines[aTrack] = aPipeline; | ||||
1168 | } | ||||
1169 | |||||
1170 | void | ||||
1171 | RemoteSourceStreamInfo::StorePipeline(int aTrack, | ||||
1172 | mozilla::RefPtr<mozilla::MediaPipeline> aPipeline) | ||||
1173 | { | ||||
1174 | MOZ_ASSERT(mPipelines.find(aTrack) == mPipelines.end())do { if (!(mPipelines.find(aTrack) == mPipelines.end())) { MOZ_ReportAssertionFailure ("mPipelines.find(aTrack) == mPipelines.end()", "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 1174); do { *((volatile int*) __null) = 123; ::abort(); } while (0); } } while (0); | ||||
1175 | if (mPipelines.find(aTrack) != mPipelines.end()) { | ||||
1176 | CSFLogErrorS(logTag, __FUNCTION__ << ": Storing duplicate track"){ std::ostringstream _oss; _oss << __FUNCTION__ << ": Storing duplicate track" << std::endl; CSFLog( CSF_LOG_ERROR , "/srv/repos/browser/mozilla-central/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp" , 1176 , logTag, _oss.str().c_str()); }; | ||||
1177 | return; | ||||
1178 | } | ||||
1179 | //TODO: Revisit once we start supporting multiple streams or multiple tracks | ||||
1180 | // of same type | ||||
1181 | mPipelines[aTrack] = aPipeline; | ||||
1182 | } | ||||
1183 | |||||
1184 | } // end sipcc namespace |