Bug 694807: Implement PeerConnection C++ module; r=jst,jesup,ekr

This commit is contained in:
Anant Narayanan 2012-10-07 01:34:30 -04:00
parent 892bf6da06
commit e61ba69837
9 changed files with 208 additions and 162 deletions

View File

@ -5250,8 +5250,8 @@ dnl enable once Signaling lands
MOZ_WEBRTC_IN_LIBXUL=1
fi
dnl enable once PeerConnection lands
dnl MOZ_PEERCONNECTION=1
dnl AC_DEFINE(MOZ_PEERCONNECTION)
MOZ_PEERCONNECTION=1
AC_DEFINE(MOZ_PEERCONNECTION)
MOZ_SCTP=1
MOZ_SRTP=1
AC_DEFINE(MOZ_SCTP)

View File

@ -43,9 +43,10 @@ nsDOMMediaStream::GetCurrentTime(double *aCurrentTime)
}
already_AddRefed<nsDOMMediaStream>
nsDOMMediaStream::CreateInputStream()
nsDOMMediaStream::CreateInputStream(PRUint32 aHintContents)
{
nsRefPtr<nsDOMMediaStream> stream = new nsDOMMediaStream();
stream->SetHintContents(aHintContents);
MediaStreamGraph* gm = MediaStreamGraph::GetInstance();
stream->mStream = gm->CreateInputStream(stream);
return stream.forget();

View File

@ -38,6 +38,7 @@ ifdef MOZ_WEBRTC
LOCAL_INCLUDES += \
-I$(topsrcdir)/media/webrtc/trunk/src \
$(NULL)
DIRS += bridge
endif
include $(topsrcdir)/config/config.mk

View File

@ -0,0 +1,97 @@
#include "nsIThread.idl"
#include "nsIDOMWindow.idl"
interface nsIDOMMediaStream;
/* Do not confuse with nsIDOMRTCPeerConnection. This interface is purely for
* communication between the PeerConnection JS DOM binding and the C++
* implementation in SIPCC.
*
* See media/webrtc/signaling/include/PeerConnectionImpl.h
*/
[scriptable, uuid(84efc76f-41d9-496a-9444-2965d179d419)]
interface IPeerConnectionObserver : nsISupports
{
/* Constants */
const long kReadyState = 0x1;
const long kIceState = 0x2;
const long kSdpState = 0x3;
const long kSipccState = 0x4;
/* JSEP callbacks */
void onCreateOfferSuccess(in string offer);
void onCreateOfferError(in unsigned long code);
void onCreateAnswerSuccess(in string answer);
void onCreateAnswerError(in unsigned long code);
void onSetLocalDescriptionSuccess(in unsigned long code);
void onSetRemoteDescriptionSuccess(in unsigned long code);
void onSetLocalDescriptionError(in unsigned long code);
void onSetRemoteDescriptionError(in unsigned long code);
/* Notification of one of several types of state changed */
void onStateChange(in unsigned long state);
/* Changes to MediaStreams */
void onAddStream(in nsIDOMMediaStream stream, in string type);
void onRemoveStream();
void onAddTrack();
void onRemoveTrack();
/* When SDP is parsed and a candidate line is found this method is called.
* It should hook back into the media transport to notify it of ICE candidates
* listed in the SDP PeerConnectionImpl does not parse ICE candidates, just
* pulls them out of the SDP.
*/
void foundIceCandidate(in string candidate);
};
[scriptable, uuid(942366a9-80fe-4cac-ac97-4fbca45bcbff)]
interface IPeerConnection : nsISupports
{
const unsigned long kHintAudio = 0x00000001;
const unsigned long kHintVideo = 0x00000002;
const long kActionNone = -1;
const long kActionOffer = 0;
const long kActionAnswer = 1;
const long kActionPRAnswer = 2;
const long kIceGathering = 0;
const long kIceWaiting = 1;
const long kIceChecking = 2;
const long kIceConnected = 3;
const long kIceFailed = 4;
/* Must be called first. Observer events will be dispatched on the thread provided */
void initialize(in IPeerConnectionObserver observer, in nsIDOMWindow window,
[optional] in nsIThread thread);
/* JSEP calls */
void createOffer(in string hints);
void createAnswer(in string hints, in string offer);
void setLocalDescription(in long action, in string sdp);
void setRemoteDescription(in long action, in string sdp);
/* Adds the stream created by GetUserMedia */
void addStream(in nsIDOMMediaStream stream);
void removeStream(in nsIDOMMediaStream stream);
void closeStreams();
/* As the ICE candidates roll in this one should be called each time
* in order to keep the candidate list up-to-date for the next SDP-related
* call PeerConnectionImpl does not parse ICE candidates, just sticks them
* into the SDP.
*/
void addIceCandidate(in string candidate, in string mid, in unsigned short level);
/* Puts the SIPCC engine back to 'kIdle', shuts down threads, deletes state */
void close();
/* Attributes */
readonly attribute string localDescription;
readonly attribute string remoteDescription;
readonly attribute unsigned long iceState;
readonly attribute unsigned long readyState;
readonly attribute unsigned long sipccState;
};

View File

@ -0,0 +1,37 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
DEPTH = ../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = peerconnection
XPIDL_MODULE = peerconnection
LIBRARY_NAME = peerconnection
MODULE_NAME = peerconnection
IS_COMPONENT = 1
EXPORT_LIBRARY = 1
LIBXUL_LIBRARY = 1
XPIDLSRCS = IPeerConnection.idl
CPPSRCS = \
MediaModule.cpp \
$(NULL)
LOCAL_INCLUDES += \
-I$(topsrcdir)/media/mtransport \
-I$(topsrcdir)/media/webrtc/signaling/include \
-I$(topsrcdir)/media/webrtc/signaling/src/sipcc/include \
-I$(topsrcdir)/media/webrtc/signaling/src/peerconnection \
-I$(topsrcdir)/media/webrtc/signaling/src/mediapipeline \
-I$(topsrcdir)/media/webrtc/signaling/src/media-conduit \
-I$(topsrcdir)/ipc/chromium/src \
$(NULL)
include $(topsrcdir)/config/rules.mk

View File

@ -0,0 +1,46 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "base/linked_ptr.h"
#include "mozilla/ModuleUtils.h"
#include "nsIClassInfoImpl.h"
#ifdef MOZ_WEBRTC
#include "PeerConnectionImpl.h"
#define PEERCONNECTION_CID \
{0xb93af7a1, 0x3411, 0x44a8, {0xbd, 0x0a, 0x8a, 0xf3, 0xdd, 0xe4, 0xd8, 0xd8}}
#define PEERCONNECTION_CONTRACTID "@mozilla.org/peerconnection;1"
namespace sipcc
{
// Factory defined in sipcc::, defines sipcc::PeerConnectionImplConstructor
NS_GENERIC_FACTORY_CONSTRUCTOR(PeerConnectionImpl)
}
// Defines kPEERCONNECTION_CID
NS_DEFINE_NAMED_CID(PEERCONNECTION_CID);
static const mozilla::Module::CIDEntry kCIDs[] = {
{ &kPEERCONNECTION_CID, false, NULL, sipcc::PeerConnectionImplConstructor },
{ NULL }
};
static const mozilla::Module::ContractIDEntry kContracts[] = {
{ PEERCONNECTION_CONTRACTID, &kPEERCONNECTION_CID },
{ NULL }
};
static const mozilla::Module kModule = {
mozilla::Module::kVersion,
kCIDs,
kContracts
};
NSMODULE_DEFN(peerconnection) = &kModule;
#endif

View File

@ -3,6 +3,8 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <string>
#include <iostream>
#include "vcm.h"
#include "CSFLog.h"
@ -171,15 +173,15 @@ public:
}
case PC_OBSERVER_CONNECTION:
CSFLogDebugS(logTag, __FUNCTION__ << ": Delivering PeerConnection onconnection");
mObserver->NotifyConnection();
//mObserver->NotifyConnection();
break;
case PC_OBSERVER_CLOSEDCONNECTION:
CSFLogDebugS(logTag, __FUNCTION__ << ": Delivering PeerConnection onclosedconnection");
mObserver->NotifyClosedConnection();
//mObserver->NotifyClosedConnection();
break;
case PC_OBSERVER_DATACHANNEL:
CSFLogDebugS(logTag, __FUNCTION__ << ": Delivering PeerConnection ondatachannel");
mObserver->NotifyDataChannel(mChannel);
//mObserver->NotifyDataChannel(mChannel);
#ifdef MOZILLA_INTERNAL_API
NS_DataChannelAppReady(mChannel);
#endif
@ -474,7 +476,7 @@ PeerConnectionImpl::Initialize(IPeerConnectionObserver* observer,
// DTLS identity
unsigned char fingerprint[DTLS_FINGERPRINT_LENGTH];
size_t fingerprint_length;
res = mIdentity->ComputeFingerprint("sha-256",
res = mIdentity->ComputeFingerprint("sha-1",
fingerprint,
sizeof(fingerprint),
&fingerprint_length);
@ -484,7 +486,7 @@ PeerConnectionImpl::Initialize(IPeerConnectionObserver* observer,
return res;
}
mFingerprint = "sha-256 " + mIdentity->FormatFingerprint(fingerprint,
mFingerprint = "sha-1 " + mIdentity->FormatFingerprint(fingerprint,
fingerprint_length);
// Find the STS thread
@ -506,7 +508,7 @@ PeerConnectionImpl::Initialize(IPeerConnectionObserver* observer,
return NS_OK;
}
NS_IMETHODIMP
nsresult
PeerConnectionImpl::CreateFakeMediaStream(PRUint32 hint, nsIDOMMediaStream** retval)
{
MOZ_ASSERT(retval);
@ -545,153 +547,6 @@ PeerConnectionImpl::CreateFakeMediaStream(PRUint32 hint, nsIDOMMediaStream** ret
return NS_OK;
}
NS_IMETHODIMP
PeerConnectionImpl::ConnectDataConnection(PRUint16 localport, PRUint16 remoteport, PRUint16 numstreams)
{
#ifdef MOZILLA_INTERNAL_API
mDataConnection = new mozilla::DataChannelConnection(this);
NS_ENSURE_TRUE(mDataConnection,NS_ERROR_FAILURE);
if(!mDataConnection->Init(localport, numstreams, true))
{
CSFLogError(logTag,"%s DataConnection Init Failed",__FUNCTION__);
return NS_ERROR_FAILURE;
}
// XXX errors?
// XXX Fix! get the correct flow for DataChannel
nsRefPtr<TransportFlow> flow = GetTransportFlow(2,false).get();
CSFLogDebugS(logTag, "Transportflow[2] = " << flow.get());
if(!mDataConnection->ConnectDTLS(flow, localport, remoteport))
{
return NS_ERROR_FAILURE;
}
// XXX errors?
return NS_OK;
#else
return NS_ERROR_FAILURE;
#endif
}
NS_IMETHODIMP
PeerConnectionImpl::CreateDataChannel(const nsACString& label,
PRUint16 type,
bool outOfOrderAllowed,
PRUint16 maxTime,
PRUint16 maxNum,
nsIDOMDataChannel** aRetval)
{
MOZ_ASSERT(aRetval);
#ifdef MOZILLA_INTERNAL_API
mozilla::DataChannel *aDataChannel;
mozilla::DataChannelConnection::Type theType = (mozilla::DataChannelConnection::Type) type;
if (!mDataConnection) {
return NS_ERROR_FAILURE;
}
aDataChannel = mDataConnection->Open(label,
theType, !outOfOrderAllowed,
type == mozilla::DataChannelConnection::PARTIAL_RELIABLE_REXMIT ? maxNum :
(type == mozilla::DataChannelConnection::PARTIAL_RELIABLE_TIMED ? maxTime : 0),
NULL, NULL);
NS_ENSURE_TRUE(aDataChannel,NS_ERROR_FAILURE);
CSFLogDebugS(logTag, __FUNCTION__ << ": making DOMDataChannel");
return NS_NewDOMDataChannel(aDataChannel,
mWindow,
aRetval);
#else
return NS_OK;
#endif
}
// XXX Temporary - remove
NS_IMETHODIMP
PeerConnectionImpl::Listen(unsigned short port, PRUint16 numstreams)
{
CSFLogDebugS(logTag, __FUNCTION__ << ": port: " << port << ", numstreams: " << numstreams);
#ifdef MOZILLA_INTERNAL_API
if (!mDataConnection) {
mDataConnection = new mozilla::DataChannelConnection(this);
if(!mDataConnection->Init(port, numstreams, false)) {
CSFLogError(logTag,"%s DataConnection Init Failed",__FUNCTION__);
return NS_ERROR_FAILURE;
}
}
listenPort = port;
PR_CreateThread(
PR_SYSTEM_THREAD,
PeerConnectionImpl::ListenThread, this,
PR_PRIORITY_NORMAL,
PR_GLOBAL_THREAD,
PR_JOINABLE_THREAD, 0
);
CSFLogDebugS(logTag, __FUNCTION__ << ": returned");;
#endif
return NS_OK;
}
// XXX Temporary - remove
void
PeerConnectionImpl::ListenThread(void *aData)
{
MOZ_ASSERT(aData);
#ifdef MOZILLA_INTERNAL_API
sipcc::PeerConnectionImpl *ctx = static_cast<sipcc::PeerConnectionImpl*>(aData);
ctx->mDataConnection->Listen(ctx->listenPort);
#endif
CSFLogDebugS(logTag, __FUNCTION__ << ": finished");
}
// XXX Temporary - remove
NS_IMETHODIMP
PeerConnectionImpl::Connect(const nsAString &addr, PRUint16 localport, PRUint16 remoteport, PRUint16 numstreams)
{
CSFLogDebugS(logTag, __FUNCTION__);
#ifdef MOZILLA_INTERNAL_API
char *s = ToNewCString(addr);
if (!mDataConnection) {
mDataConnection = new mozilla::DataChannelConnection(this);
if(!mDataConnection->Init(localport, numstreams, false))
{
CSFLogError(logTag,"%s DataConnection Init Failed",__FUNCTION__);
return NS_ERROR_FAILURE;
}
}
connectStr = s;
connectPort = remoteport;
PR_CreateThread(
PR_SYSTEM_THREAD,
PeerConnectionImpl::ConnectThread, this,
PR_PRIORITY_NORMAL,
PR_GLOBAL_THREAD,
PR_JOINABLE_THREAD, 0
);
CSFLogDebugS(logTag, __FUNCTION__ << ": returned");;
#endif
return NS_OK;
}
// XXX Temporary - remove
void
PeerConnectionImpl::ConnectThread(void *aData)
{
MOZ_ASSERT(aData);
#ifdef MOZILLA_INTERNAL_API
sipcc::PeerConnectionImpl *ctx = static_cast<sipcc::PeerConnectionImpl*>(aData);
ctx->mDataConnection->Connect(ctx->connectStr,ctx->connectPort);
#endif
CSFLogDebugS(logTag, __FUNCTION__ << ": finished");
}
void
PeerConnectionImpl::NotifyConnection()
{
@ -746,7 +601,7 @@ PeerConnectionImpl::NotifyDataChannel(mozilla::DataChannel *aChannel)
nsCOMPtr<nsIDOMDataChannel> domchannel;
nsresult rv = NS_NewDOMDataChannel(aChannel, mWindow,
getter_AddRefs(domchannel));
NS_ENSURE_SUCCESS(rv,/**/);
NS_ENSURE_SUCCESS(rv,);
if (mPCObserver) {
PeerConnectionObserverDispatch* runnable =
new PeerConnectionObserverDispatch(PC_OBSERVER_DATACHANNEL, domchannel.get(),
@ -914,13 +769,14 @@ PeerConnectionImpl::CloseStreams() {
return NS_OK;
}
/*
NS_IMETHODIMP
PeerConnectionImpl::SetRemoteFingerprint(const char* hash, const char* fingerprint)
{
MOZ_ASSERT(hash);
MOZ_ASSERT(fingerprint);
if (fingerprint != NULL && (strcmp(hash, "sha-256") == 0)) {
if (fingerprint != NULL && (strcmp(hash, "sha-1") == 0)) {
mRemoteFingerprint = std::string(fingerprint);
CSFLogDebugS(logTag, "Setting remote fingerprint to " << mRemoteFingerprint);
return NS_OK;
@ -930,10 +786,6 @@ PeerConnectionImpl::SetRemoteFingerprint(const char* hash, const char* fingerpri
}
}
/**
* @fingerprint[out]: Ownership of this parameter
* is responsibility of the caller.
*/
NS_IMETHODIMP
PeerConnectionImpl::GetFingerprint(char** fingerprint)
{
@ -950,6 +802,7 @@ PeerConnectionImpl::GetFingerprint(char** fingerprint)
*fingerprint = tmp;
return NS_OK;
}
*/
NS_IMETHODIMP
PeerConnectionImpl::GetLocalDescription(char** sdp)

View File

@ -6,6 +6,7 @@
#define _PEER_CONNECTION_IMPL_H_
#include <string>
#include <iostream>
#include <vector>
#include <map>
#include <cmath>
@ -366,6 +367,9 @@ public:
// Get the DTLS identity
mozilla::RefPtr<DtlsIdentity> const GetIdentity() { return mIdentity; }
// Create a fake media stream
nsresult CreateFakeMediaStream(PRUint32 hint, nsIDOMMediaStream** retval);
private:
PeerConnectionImpl(const PeerConnectionImpl&rhs);
PeerConnectionImpl& operator=(PeerConnectionImpl);

View File

@ -164,6 +164,12 @@
#define PROFILER_MODULE
#endif
#if defined(MOZ_WEBRTC)
#define PEERCONNECTION_MODULE MODULE(peerconnection)
#else
#define PEERCONNECTION_MODULE
#endif
#define XUL_MODULES \
MODULE(nsUConvModule) \
MODULE(nsI18nModule) \
@ -221,6 +227,7 @@
MODULE(nsTelemetryModule) \
MODULE(jsinspector) \
MODULE(jsdebugger) \
PEERCONNECTION_MODULE \
/* end of list */
#define MODULE(_name) \