From de86c1406568fc193511a5569a59aec550158d9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Charmet?= Date: Mon, 13 Mar 2017 14:10:47 +0100 Subject: [PATCH 01/20] WIP --- src/rtcpeerconnection.cc | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/src/rtcpeerconnection.cc b/src/rtcpeerconnection.cc index 2209cf4..e49e4a8 100644 --- a/src/rtcpeerconnection.cc +++ b/src/rtcpeerconnection.cc @@ -130,16 +130,31 @@ RTCPeerConnection::~RTCPeerConnection() { } NAN_METHOD(RTCPeerConnection::New) { + CONSTRUCTOR_HEADER("RTCPeerConnection") webrtc::FakeConstraints constraints; - webrtc::PeerConnectionInterface::RTCConfiguration config; + webrtc::PeerConnectionInterface::RTCConfiguration _config; webrtc::PeerConnectionInterface::IceServer server; - server.uri = "stun:stun.l.google.com:19302"; - config.servers.push_back(server); + //server.uri = "stun:stun.l.google.com:19302"; + //config.servers.push_back(server); + + if (info.Length() > 0) { + ASSERT_OBJECT_ARGUMENT(0, config); + + DECLARE_OBJECT_PROPERTY(config, "iceServer", iceServerVal); + Local iceServer = iceServerVal->ToObject(); + + DECLARE_OBJECT_PROPERTY(iceServer, "url", iceServerUrlVal); + ASSERT_PROPERTY_STRING("iceServer.url", iceServerUrlVal, iceServerUrl); + + webrtc::PeerConnectionInterface::IceServer server; + server.uri = *iceServerUrl; + _config.servers.push_back(server); + } constraints.AddOptional(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, "true"); - RTCPeerConnection *rtcPeerConnection = new RTCPeerConnection(config, + RTCPeerConnection *rtcPeerConnection = new RTCPeerConnection(_config, constraints); rtcPeerConnection->Wrap(info.This()); From f1033fedd866e12591244a7e6f10332453242bc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Charmet?= Date: Mon, 13 Mar 2017 16:27:49 +0100 Subject: [PATCH 02/20] [PeerConnection] added `iceServers.urls` and `certificates` in config --- src/common.h | 23 +++++++++++++++++++++ src/rtccertificate.h | 5 ++--- src/rtcpeerconnection.cc | 44 +++++++++++++++++++++++++++++++--------- 3 files changed, 59 insertions(+), 13 deletions(-) diff --git a/src/common.h b/src/common.h index 9f5fe8c..e96793f 100644 --- a/src/common.h +++ b/src/common.h @@ -44,6 +44,12 @@ #define ERROR_PROPERTY_NOT_BOOLEAN(NAME) \ "The '" << NAME << "' property is not a boolean." +#define ERROR_PROPERTY_NOT_OBJECT(NAME) \ + "The '" << NAME << "' property is not an object." + +#define ERROR_PROPERTY_NOT_ARRAY(NAME) \ + "The '" << NAME << "' property is not an object." + #define ERROR_PROPERTY_NOT_UINT8ARRAY(NAME) \ "The '" << NAME << "' property is not a Uint8Array." @@ -168,6 +174,23 @@ \ Local S(V->ToBoolean()); +#define ASSERT_PROPERTY_OBJECT(N, V, S) \ + if (!V->IsObject()) { \ + errorStream << ERROR_PROPERTY_NOT_OBJECT(N); \ + return Nan::ThrowTypeError(errorStream.str().c_str()); \ + } \ + \ + Local S(V->ToObject()); + +#define ASSERT_PROPERTY_ARRAY(N, V, S) \ + if (!V->IsArray()) { \ + errorStream << ERROR_PROPERTY_NOT_ARRAY(N); \ + return Nan::ThrowTypeError(errorStream.str().c_str()); \ + } \ + \ + Local S = Local::Cast(V); + + #define ASSERT_REJECT_PROPERTY_BOOLEAN(N, V, S) \ if (!V->IsBoolean()) { \ errorStream << ERROR_PROPERTY_NOT_BOOLEAN(N); \ diff --git a/src/rtccertificate.h b/src/rtccertificate.h index eacfd84..e44a41a 100644 --- a/src/rtccertificate.h +++ b/src/rtccertificate.h @@ -41,15 +41,14 @@ class RTCCertificate : public Nan::ObjectWrap { return _constructor; } + const rtc::scoped_refptr _certificate; + private: explicit RTCCertificate( const rtc::scoped_refptr& certificate); ~RTCCertificate(); static NAN_METHOD(New); - - protected: - const rtc::scoped_refptr _certificate; }; #endif // RTCCERTIFICATE_H_ diff --git a/src/rtcpeerconnection.cc b/src/rtcpeerconnection.cc index e49e4a8..9a1ad3d 100644 --- a/src/rtcpeerconnection.cc +++ b/src/rtcpeerconnection.cc @@ -32,6 +32,10 @@ static const char sRTCPeerConnection[] = "RTCPeerConnection"; static const char kCreateOffer[] = "createOffer"; static const char kGenerateCertificate[] = "generateCertificate"; +static const char kIceServers[] = "iceServers"; +static const char kIceServerUrls[] = "urls"; +static const char kCertificates[] = "certificates"; + static const char kName[] = "name"; static const char kRSA[] = "RSASSA-PKCS1-v1_5"; static const char kHash[] = "hash"; @@ -134,21 +138,41 @@ NAN_METHOD(RTCPeerConnection::New) { webrtc::FakeConstraints constraints; webrtc::PeerConnectionInterface::RTCConfiguration _config; webrtc::PeerConnectionInterface::IceServer server; - //server.uri = "stun:stun.l.google.com:19302"; - //config.servers.push_back(server); - + if (info.Length() > 0) { ASSERT_OBJECT_ARGUMENT(0, config); - DECLARE_OBJECT_PROPERTY(config, "iceServer", iceServerVal); - Local iceServer = iceServerVal->ToObject(); + DECLARE_OBJECT_PROPERTY(config, kIceServers, iceServersVal); + ASSERT_PROPERTY_ARRAY(kIceServers, iceServersVal, iceServers); + + for(unsigned int i = 0; i < iceServers->Length(); i = i + 1) { + Local iceServerVal = iceServers->Get(i); + ASSERT_PROPERTY_OBJECT(kIceServers, iceServerVal, iceServer); + + webrtc::PeerConnectionInterface::IceServer server; + + DECLARE_OBJECT_PROPERTY(iceServer, kIceServerUrls, iceServerUrlsVal); + ASSERT_PROPERTY_ARRAY(kIceServerUrls, iceServerUrlsVal, iceServerUrls); - DECLARE_OBJECT_PROPERTY(iceServer, "url", iceServerUrlVal); - ASSERT_PROPERTY_STRING("iceServer.url", iceServerUrlVal, iceServerUrl); + for(unsigned int j = 0; j < iceServerUrls->Length(); j = j + 1) { + Local iceServerUrlVal = iceServerUrls->Get(j); + ASSERT_PROPERTY_STRING(kIceServerUrls, iceServerUrlVal, iceServerUrl); + server.urls.push_back(*iceServerUrl); + } - webrtc::PeerConnectionInterface::IceServer server; - server.uri = *iceServerUrl; - _config.servers.push_back(server); + _config.servers.push_back(server); + } + + DECLARE_OBJECT_PROPERTY(config, kCertificates, certificatesVal); + ASSERT_PROPERTY_ARRAY(kCertificates, certificatesVal, certificates); + + for(unsigned int i = 0; i < certificates->Length(); i = i + 1) { + Local certificateVal = certificates->Get(i); + ASSERT_PROPERTY_OBJECT(kCertificates, certificateVal, certificate); + // FIXME: validate it's a RTCCertificate object + RTCCertificate* _certificate = Nan::ObjectWrap::Unwrap(certificate); + _config.certificates.push_back(_certificate->_certificate); + } } constraints.AddOptional(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, From fea2009a8bcc0be47037628225f7c72917371c68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Charmet?= Date: Mon, 13 Mar 2017 18:33:34 +0100 Subject: [PATCH 03/20] WIP setLocalDescription + createDataChannel --- binding.gyp | 2 + src/common.h | 8 ++ src/event/setsessiondescriptionevent.cc | 88 +++++++++++++++++++ src/event/setsessiondescriptionevent.h | 45 ++++++++++ .../createsessiondescriptionobserver.h | 2 +- src/observer/setsessiondescriptionobserver.cc | 58 ++++++++++++ src/observer/setsessiondescriptionobserver.h | 50 +++++++++++ src/rtcpeerconnection.cc | 39 +++++++- src/rtcpeerconnection.h | 2 + src/rtcsessiondescription.h | 5 +- 10 files changed, 294 insertions(+), 5 deletions(-) create mode 100644 src/event/setsessiondescriptionevent.cc create mode 100644 src/event/setsessiondescriptionevent.h create mode 100644 src/observer/setsessiondescriptionobserver.cc create mode 100644 src/observer/setsessiondescriptionobserver.h diff --git a/binding.gyp b/binding.gyp index d941c67..57fb628 100644 --- a/binding.gyp +++ b/binding.gyp @@ -4,10 +4,12 @@ 'target_name': 'webrtc', 'sources': [ 'src/event/createsessiondescriptionevent.cc', + 'src/event/setsessiondescriptionevent.cc', 'src/event/eventqueue.cc', 'src/globals.cc', 'src/module.cc', 'src/observer/createsessiondescriptionobserver.cc', + 'src/observer/setsessiondescriptionobserver.cc', 'src/observer/peerconnectionobserver.cc', 'src/rtccertificate.cc', 'src/rtcicecandidate.cc', diff --git a/src/common.h b/src/common.h index e96793f..a6a00ca 100644 --- a/src/common.h +++ b/src/common.h @@ -122,6 +122,14 @@ \ Local N = info[I].As(); +#define ASSERT_STRING_ARGUMENT(I, N) \ + if (!info[I]->IsString()) { \ + errorStream << ERROR_ARGUMENT_NOT_FUNCTION(I + 1, #N); \ + return Nan::ThrowTypeError(errorStream.str().c_str()); \ + } \ + \ + String::Utf8Value N(info[I]->ToString()); + #define ASSERT_REJECT_OBJECT_ARGUMENT(I, N) \ if (!info[I]->IsObject()) { \ errorStream << ERROR_ARGUMENT_NOT_OBJECT(I + 1, #N); \ diff --git a/src/event/setsessiondescriptionevent.cc b/src/event/setsessiondescriptionevent.cc new file mode 100644 index 0000000..4f7253e --- /dev/null +++ b/src/event/setsessiondescriptionevent.cc @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2017 Axel Isouard + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "common.h" +#include "setsessiondescriptionevent.h" +#include "rtcsessiondescription.h" + +using namespace v8; + +SetSessionDescriptionEvent::SetSessionDescriptionEvent( + Persistent *successCallback, + Persistent *failureCallback) : + _resolver(NULL), + _successCallback(successCallback), + _failureCallback(failureCallback) { +} + +SetSessionDescriptionEvent::SetSessionDescriptionEvent( + Persistent *resolver) : + _resolver(resolver), + _successCallback(NULL), + _failureCallback(NULL) { +} + +void SetSessionDescriptionEvent::Handle() { + Nan::HandleScope scope; + + if (_resolver) { + Local resolver = Nan::New(*_resolver); + + if (_succeeded) { + resolver->Resolve(Nan::Undefined()); + } else { + resolver->Reject(Nan::Error(_errorMessage.c_str())); + } + + Isolate::GetCurrent()->RunMicrotasks(); + _resolver->Reset(); + delete _resolver; + return; + } + + if (_succeeded && _successCallback) { + Local successCallback = Nan::New(*_successCallback); + Nan::Callback cb(successCallback); + + const int argc = 0; + Local argv[0] = {}; + + cb.Call(argc, argv); + } else if (!_succeeded && _failureCallback) { + Local failureCallback = Nan::New(*_failureCallback); + Nan::Callback cb(failureCallback); + + const int argc = 1; + Local argv[1] = { Nan::Error(_errorMessage.c_str()) }; + + cb.Call(argc, argv); + } + + _successCallback->Reset(); + _failureCallback->Reset(); + + delete _successCallback; + delete _failureCallback; +} + +void SetSessionDescriptionEvent::SetSucceeded(bool succeeded) { + _succeeded = succeeded; +} + +void SetSessionDescriptionEvent::SetErrorMessage( + const std::string &errorMessage) { + _errorMessage = errorMessage; +} diff --git a/src/event/setsessiondescriptionevent.h b/src/event/setsessiondescriptionevent.h new file mode 100644 index 0000000..ad185a5 --- /dev/null +++ b/src/event/setsessiondescriptionevent.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2017 Axel Isouard + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef EVENT_SETSESSIONDESCRIPTIONEVENT_H_ +#define EVENT_SETSESSIONDESCRIPTIONEVENT_H_ + +#include +#include +#include "event.h" + +using namespace v8; + +class SetSessionDescriptionEvent : public Event { + public: + explicit SetSessionDescriptionEvent( + Persistent *resolver); + SetSessionDescriptionEvent(Persistent *successCallback, + Persistent *failureCallback); + + void Handle(); + void SetSucceeded(bool succeeded); + void SetErrorMessage(const std::string& errorMessage); + + private: + Persistent *_resolver; + Persistent *_successCallback; + Persistent *_failureCallback; + bool _succeeded; + std::string _errorMessage; +}; + +#endif // EVENT_SETSESSIONDESCRIPTIONEVENT_H_ diff --git a/src/observer/createsessiondescriptionobserver.h b/src/observer/createsessiondescriptionobserver.h index 287c51b..feda2a2 100644 --- a/src/observer/createsessiondescriptionobserver.h +++ b/src/observer/createsessiondescriptionobserver.h @@ -47,4 +47,4 @@ class CreateSessionDescriptionObserver : Persistent *failureCallback); }; -#endif // OBSERVER_CREATESESSIONDESCRIPTIONOBSERVER_H_ +#endif // OBSERVER_SETSESSIONDESCRIPTIONOBSERVER_H_ diff --git a/src/observer/setsessiondescriptionobserver.cc b/src/observer/setsessiondescriptionobserver.cc new file mode 100644 index 0000000..b3fb589 --- /dev/null +++ b/src/observer/setsessiondescriptionobserver.cc @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2017 Axel Isouard + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include "common.h" +#include "setsessiondescriptionobserver.h" +#include "event/setsessiondescriptionevent.h" +#include "globals.h" + +using namespace v8; + +SetSessionDescriptionObserver::SetSessionDescriptionObserver( + Persistent *resolver) { + _event = new SetSessionDescriptionEvent(resolver); +} + +SetSessionDescriptionObserver::SetSessionDescriptionObserver( + Persistent *successCallback, + Persistent *failureCallback) { + _event = new SetSessionDescriptionEvent(successCallback, failureCallback); +} + +SetSessionDescriptionObserver *SetSessionDescriptionObserver:: + Create(Persistent *successCallback, + Persistent *failureCallback) { + return new rtc::RefCountedObject + (successCallback, failureCallback); +} + +SetSessionDescriptionObserver *SetSessionDescriptionObserver:: + Create(Persistent *resolver) { + return new rtc::RefCountedObject + (resolver); +} + +void SetSessionDescriptionObserver::OnSuccess() { + _event->SetSucceeded(true); + Globals::GetEventQueue()->PushEvent(_event); +} + +void SetSessionDescriptionObserver::OnFailure(const std::string &error) { + _event->SetSucceeded(false); + _event->SetErrorMessage(error); + Globals::GetEventQueue()->PushEvent(_event); +} diff --git a/src/observer/setsessiondescriptionobserver.h b/src/observer/setsessiondescriptionobserver.h new file mode 100644 index 0000000..75a53af --- /dev/null +++ b/src/observer/setsessiondescriptionobserver.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2017 Axel Isouard + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OBSERVER_SETSESSIONDESCRIPTIONOBSERVER_H_ +#define OBSERVER_SETSESSIONDESCRIPTIONOBSERVER_H_ + +#include +#include +#include + +using namespace v8; + +class SetSessionDescriptionEvent; +class SetSessionDescriptionObserver : + public webrtc::SetSessionDescriptionObserver { + public: + static SetSessionDescriptionObserver *Create( + Persistent *resolver); + static SetSessionDescriptionObserver *Create( + Persistent *successCallback, + Persistent *failureCallback); + + void OnSuccess(); + void OnFailure(const std::string& error); + + private: + SetSessionDescriptionEvent *_event; + + protected: + explicit SetSessionDescriptionObserver( + Persistent *resolver); + + SetSessionDescriptionObserver(Persistent *successCallback, + Persistent *failureCallback); +}; + +#endif // OBSERVER_SETSESSIONDESCRIPTIONOBSERVER_H_ diff --git a/src/rtcpeerconnection.cc b/src/rtcpeerconnection.cc index 9a1ad3d..17dcd83 100644 --- a/src/rtcpeerconnection.cc +++ b/src/rtcpeerconnection.cc @@ -21,15 +21,19 @@ #include "common.h" #include "globals.h" #include "observer/createsessiondescriptionobserver.h" +#include "observer/setsessiondescriptionobserver.h" #include "observer/peerconnectionobserver.h" #include "rtccertificate.h" #include "rtcpeerconnection.h" +#include "rtcsessiondescription.h" Nan::Persistent RTCPeerConnection::constructor; static const char sRTCPeerConnection[] = "RTCPeerConnection"; static const char kCreateOffer[] = "createOffer"; +static const char kSetLocalDescription[] = "setLocalDescription"; +static const char kCreateDataChannel[] = "createDataChannel"; static const char kGenerateCertificate[] = "generateCertificate"; static const char kIceServers[] = "iceServers"; @@ -90,6 +94,8 @@ NAN_MODULE_INIT(RTCPeerConnection::Init) { Local prototype = ctor->InstanceTemplate(); Nan::SetMethod(prototype, kCreateOffer, CreateOffer); + Nan::SetMethod(prototype, kSetLocalDescription, SetLocalDescription); + Nan::SetMethod(prototype, kCreateDataChannel, CreateDataChannel); Local tpl = ctor->InstanceTemplate(); Nan::SetAccessor(tpl, LOCAL_STRING(kConnectionState), @@ -137,7 +143,6 @@ NAN_METHOD(RTCPeerConnection::New) { CONSTRUCTOR_HEADER("RTCPeerConnection") webrtc::FakeConstraints constraints; webrtc::PeerConnectionInterface::RTCConfiguration _config; - webrtc::PeerConnectionInterface::IceServer server; if (info.Length() > 0) { ASSERT_OBJECT_ARGUMENT(0, config); @@ -228,6 +233,38 @@ NAN_METHOD(RTCPeerConnection::CreateOffer) { object->_peerConnection->CreateOffer(observer, &constraints); } +NAN_METHOD(RTCPeerConnection::SetLocalDescription) { + METHOD_HEADER("RTCPeerConnection", "setLocalDescription"); + UNWRAP_OBJECT(RTCPeerConnection, object); + + rtc::scoped_refptr observer; + + // FIXME: Promise implementation only + DECLARE_PROMISE_RESOLVER; + ASSERT_REJECT_OBJECT_ARGUMENT(0, sessionDescription); + + // FIXME: validate it's a RTCSessionDescription object + RTCSessionDescription* _sessionDescription = Nan::ObjectWrap::Unwrap(sessionDescription); + + observer = SetSessionDescriptionObserver::Create( + new Nan::Persistent(resolver)); + + object->_peerConnection->SetLocalDescription(observer, _sessionDescription->_sessionDescription); + +} + +NAN_METHOD(RTCPeerConnection::CreateDataChannel) { + METHOD_HEADER("RTCPeerConnection", "setLocalDescription"); + UNWRAP_OBJECT(RTCPeerConnection, object); + + ASSERT_STRING_ARGUMENT(0, name); + + const webrtc::DataChannelInit init; + + object->_peerConnection->CreateDataChannel(*name, &init); + +} + NAN_GETTER(RTCPeerConnection::GetConnectionState) { info.GetReturnValue().Set(LOCAL_STRING("new")); } diff --git a/src/rtcpeerconnection.h b/src/rtcpeerconnection.h index 9bb302e..3d82c04 100644 --- a/src/rtcpeerconnection.h +++ b/src/rtcpeerconnection.h @@ -36,6 +36,8 @@ class RTCPeerConnection : public Nan::ObjectWrap { static NAN_METHOD(New); static NAN_METHOD(CreateOffer); + static NAN_METHOD(SetLocalDescription); + static NAN_METHOD(CreateDataChannel); static NAN_METHOD(GenerateCertificate); static NAN_GETTER(GetConnectionState); diff --git a/src/rtcsessiondescription.h b/src/rtcsessiondescription.h index c941a5a..334099f 100644 --- a/src/rtcsessiondescription.h +++ b/src/rtcsessiondescription.h @@ -42,6 +42,8 @@ class RTCSessionDescription : public Nan::ObjectWrap { static const char kPranswer[]; static const char kRollback[]; + webrtc::SessionDescriptionInterface *_sessionDescription; + private: explicit RTCSessionDescription( webrtc::SessionDescriptionInterface *sessionDescription); @@ -51,9 +53,6 @@ class RTCSessionDescription : public Nan::ObjectWrap { static NAN_GETTER(GetType); static NAN_GETTER(GetSdp); - - protected: - webrtc::SessionDescriptionInterface *_sessionDescription; }; #endif // RTCSESSIONDESCRIPTION_H_ From 9a3c88d7f01156171afb93694a1fd9ab3028419c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Charmet?= Date: Tue, 14 Mar 2017 16:44:57 +0100 Subject: [PATCH 04/20] added createAnswer, setRemoteDescription, datachannel --- binding.gyp | 1 + src/common.h | 5 ++- src/module.cc | 2 ++ src/rtcdatachannel.cc | 76 ++++++++++++++++++++++++++++++++++++++++ src/rtcdatachannel.h | 53 ++++++++++++++++++++++++++++ src/rtcpeerconnection.cc | 61 ++++++++++++++++++++++++++++++-- src/rtcpeerconnection.h | 2 ++ 7 files changed, 196 insertions(+), 4 deletions(-) create mode 100644 src/rtcdatachannel.cc create mode 100644 src/rtcdatachannel.h diff --git a/binding.gyp b/binding.gyp index 57fb628..9e95758 100644 --- a/binding.gyp +++ b/binding.gyp @@ -15,6 +15,7 @@ 'src/rtcicecandidate.cc', 'src/rtcpeerconnection.cc', 'src/rtcsessiondescription.cc', + 'src/rtcdatachannel.cc', ], 'include_dirs' : [ 'build/include', diff --git a/src/common.h b/src/common.h index a6a00ca..89d4b6f 100644 --- a/src/common.h +++ b/src/common.h @@ -62,6 +62,9 @@ #define ERROR_ARGUMENT_NOT_FUNCTION(INDEX, NAME) \ "parameter " << INDEX << " ('" << NAME << "') is not a function." +#define ERROR_ARGUMENT_NOT_STRING(INDEX, NAME) \ + "parameter " << INDEX << " ('" << NAME << "') is not a string." + #ifdef DEBUG #define CONSTRUCTOR_HEADER(NAME) \ LOG(LS_INFO) << __PRETTY_FUNCTION__; \ @@ -124,7 +127,7 @@ #define ASSERT_STRING_ARGUMENT(I, N) \ if (!info[I]->IsString()) { \ - errorStream << ERROR_ARGUMENT_NOT_FUNCTION(I + 1, #N); \ + errorStream << ERROR_ARGUMENT_NOT_STRING(I + 1, #N); \ return Nan::ThrowTypeError(errorStream.str().c_str()); \ } \ \ diff --git a/src/module.cc b/src/module.cc index 1526da6..1ec0930 100644 --- a/src/module.cc +++ b/src/module.cc @@ -21,6 +21,7 @@ #include "rtcicecandidate.h" #include "rtcpeerconnection.h" #include "rtcsessiondescription.h" +#include "rtcdatachannel.h" NAN_MODULE_INIT(Init) { if (!Globals::Init()) { @@ -31,6 +32,7 @@ NAN_MODULE_INIT(Init) { RTCIceCandidate::Init(target); RTCPeerConnection::Init(target); RTCSessionDescription::Init(target); + RTCDataChannel::Init(target); node::AtExit(Globals::Cleanup); } diff --git a/src/rtcdatachannel.cc b/src/rtcdatachannel.cc new file mode 100644 index 0000000..f1c2899 --- /dev/null +++ b/src/rtcdatachannel.cc @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2017 Axel Isouard + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include "rtcdatachannel.h" +#include "common.h" + +static const char sRTCDataChannel[] = "RTCDataChannel"; + +static const char kLabel[] = "label"; +static const char kOrdered[] = "ordered"; +static const char kReadyState[] = "readyState"; + +NAN_MODULE_INIT(RTCDataChannel::Init) { + Local ctor = Nan::New(New); + ctor->SetClassName(LOCAL_STRING(sRTCDataChannel)); + ctor->InstanceTemplate()->SetInternalFieldCount(1); + + Local prototype = ctor->PrototypeTemplate(); + Nan::SetAccessor(prototype, LOCAL_STRING(kLabel), GetLabel); + Nan::SetAccessor(prototype, LOCAL_STRING(kOrdered), GetOrdered); + Nan::SetAccessor(prototype, LOCAL_STRING(kReadyState), GetReadyState); + + constructor().Reset(Nan::GetFunction(ctor).ToLocalChecked()); +} + +RTCDataChannel::RTCDataChannel( + const rtc::scoped_refptr &datachannel) + : _datachannel(datachannel) { +} + +RTCDataChannel::~RTCDataChannel() {} + +Local RTCDataChannel::Create( + const rtc::scoped_refptr &datachannel) { + Local cons = Nan::New(RTCDataChannel::constructor()); + Local instance = Nan::NewInstance(cons, 0, NULL).ToLocalChecked(); + + RTCDataChannel *_datachannel = new RTCDataChannel(datachannel); + _datachannel->Wrap(instance); + + return instance; +} + +NAN_METHOD(RTCDataChannel::New) { +} + +NAN_GETTER(RTCDataChannel::GetLabel) { + UNWRAP_OBJECT(RTCDataChannel, object); + info.GetReturnValue().Set(LOCAL_STRING(object->_datachannel->label())); +} + +NAN_GETTER(RTCDataChannel::GetOrdered) { + UNWRAP_OBJECT(RTCDataChannel, object); + info.GetReturnValue().Set(object->_datachannel->ordered()); +} + +NAN_GETTER(RTCDataChannel::GetReadyState) { + UNWRAP_OBJECT(RTCDataChannel, object); + const char* readyState = webrtc::DataChannelInterface::DataStateString(object->_datachannel->state()); + info.GetReturnValue().Set(LOCAL_STRING(readyState)); +} diff --git a/src/rtcdatachannel.h b/src/rtcdatachannel.h new file mode 100644 index 0000000..09c6307 --- /dev/null +++ b/src/rtcdatachannel.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2017 Axel Isouard + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef RTCDATACHANNEL_H_ +#define RTCDATACHANNEL_H_ + +#include +#include +#include + +using namespace v8; + +class RTCDataChannel : public Nan::ObjectWrap { + public: + static NAN_MODULE_INIT(Init); + + static NAN_GETTER(GetLabel); + static NAN_GETTER(GetOrdered); + static NAN_GETTER(GetReadyState); + + static Local Create( + const rtc::scoped_refptr& datachannel); + + static inline Nan::Persistent& constructor() { + static Nan::Persistent _constructor; + return _constructor; + } + + const rtc::scoped_refptr _datachannel; + + private: + explicit RTCDataChannel( + const rtc::scoped_refptr& datachannel); + ~RTCDataChannel(); + + static NAN_METHOD(New); + +}; + +#endif // RTCDATACHANNEL_H_ diff --git a/src/rtcpeerconnection.cc b/src/rtcpeerconnection.cc index 17dcd83..bad2aaa 100644 --- a/src/rtcpeerconnection.cc +++ b/src/rtcpeerconnection.cc @@ -26,13 +26,16 @@ #include "rtccertificate.h" #include "rtcpeerconnection.h" #include "rtcsessiondescription.h" +#include "rtcdatachannel.h" Nan::Persistent RTCPeerConnection::constructor; static const char sRTCPeerConnection[] = "RTCPeerConnection"; static const char kCreateOffer[] = "createOffer"; +static const char kCreateAnswer[] = "createAnswer"; static const char kSetLocalDescription[] = "setLocalDescription"; +static const char kSetRemoteDescription[] = "setRemoteDescription"; static const char kCreateDataChannel[] = "createDataChannel"; static const char kGenerateCertificate[] = "generateCertificate"; @@ -94,7 +97,9 @@ NAN_MODULE_INIT(RTCPeerConnection::Init) { Local prototype = ctor->InstanceTemplate(); Nan::SetMethod(prototype, kCreateOffer, CreateOffer); + Nan::SetMethod(prototype, kCreateAnswer, CreateAnswer); Nan::SetMethod(prototype, kSetLocalDescription, SetLocalDescription); + Nan::SetMethod(prototype, kSetRemoteDescription, SetRemoteDescription); Nan::SetMethod(prototype, kCreateDataChannel, CreateDataChannel); Local tpl = ctor->InstanceTemplate(); @@ -164,7 +169,6 @@ NAN_METHOD(RTCPeerConnection::New) { ASSERT_PROPERTY_STRING(kIceServerUrls, iceServerUrlVal, iceServerUrl); server.urls.push_back(*iceServerUrl); } - _config.servers.push_back(server); } @@ -233,6 +237,35 @@ NAN_METHOD(RTCPeerConnection::CreateOffer) { object->_peerConnection->CreateOffer(observer, &constraints); } +NAN_METHOD(RTCPeerConnection::CreateAnswer) { + METHOD_HEADER("RTCPeerConnection", "createAnswer"); + UNWRAP_OBJECT(RTCPeerConnection, object); + + unsigned char start = 0; + rtc::scoped_refptr observer; + + if (info.Length() < 2) { + DECLARE_PROMISE_RESOLVER; + + observer = CreateSessionDescriptionObserver::Create( + new Nan::Persistent(resolver)); + } else if (info.Length() > 1) { + if (info.Length() > 2) { + start = 1; + } + + ASSERT_FUNCTION_ARGUMENT(start, successCallback); + ASSERT_FUNCTION_ARGUMENT(start + 1, failureCallback); + + observer = CreateSessionDescriptionObserver::Create( + new Nan::Persistent(successCallback), + new Nan::Persistent(failureCallback)); + } + + webrtc::FakeConstraints constraints; + object->_peerConnection->CreateAnswer(observer, &constraints); +} + NAN_METHOD(RTCPeerConnection::SetLocalDescription) { METHOD_HEADER("RTCPeerConnection", "setLocalDescription"); UNWRAP_OBJECT(RTCPeerConnection, object); @@ -250,19 +283,41 @@ NAN_METHOD(RTCPeerConnection::SetLocalDescription) { new Nan::Persistent(resolver)); object->_peerConnection->SetLocalDescription(observer, _sessionDescription->_sessionDescription); +} + +NAN_METHOD(RTCPeerConnection::SetRemoteDescription) { + METHOD_HEADER("RTCPeerConnection", "setRemoteDescription"); + UNWRAP_OBJECT(RTCPeerConnection, object); + + rtc::scoped_refptr observer; + + // FIXME: Promise implementation only + DECLARE_PROMISE_RESOLVER; + ASSERT_REJECT_OBJECT_ARGUMENT(0, sessionDescription); + + // FIXME: validate it's a RTCSessionDescription object + RTCSessionDescription* _sessionDescription = Nan::ObjectWrap::Unwrap(sessionDescription); + observer = SetSessionDescriptionObserver::Create( + new Nan::Persistent(resolver)); + + object->_peerConnection->SetRemoteDescription(observer, _sessionDescription->_sessionDescription); } NAN_METHOD(RTCPeerConnection::CreateDataChannel) { - METHOD_HEADER("RTCPeerConnection", "setLocalDescription"); + METHOD_HEADER("RTCPeerConnection", "createDataChannel"); UNWRAP_OBJECT(RTCPeerConnection, object); ASSERT_STRING_ARGUMENT(0, name); + // FIXME: add init options const webrtc::DataChannelInit init; - object->_peerConnection->CreateDataChannel(*name, &init); + rtc::scoped_refptr _channel = object->_peerConnection->CreateDataChannel(*name, &init); + + Local datachannel = RTCDataChannel::Create(_channel); + info.GetReturnValue().Set(datachannel); } NAN_GETTER(RTCPeerConnection::GetConnectionState) { diff --git a/src/rtcpeerconnection.h b/src/rtcpeerconnection.h index 3d82c04..d41d84f 100644 --- a/src/rtcpeerconnection.h +++ b/src/rtcpeerconnection.h @@ -36,7 +36,9 @@ class RTCPeerConnection : public Nan::ObjectWrap { static NAN_METHOD(New); static NAN_METHOD(CreateOffer); + static NAN_METHOD(CreateAnswer); static NAN_METHOD(SetLocalDescription); + static NAN_METHOD(SetRemoteDescription); static NAN_METHOD(CreateDataChannel); static NAN_METHOD(GenerateCertificate); From 9351fa40dd7dcee80260cf4720d3941442f6d290 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Charmet?= Date: Thu, 16 Mar 2017 11:32:45 +0100 Subject: [PATCH 05/20] added localDescription / remoteDescription --- src/rtcpeerconnection.cc | 36 ++++++++++++++++++++++++++++++++++++ src/rtcpeerconnection.h | 4 +++- 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/src/rtcpeerconnection.cc b/src/rtcpeerconnection.cc index bad2aaa..289e28a 100644 --- a/src/rtcpeerconnection.cc +++ b/src/rtcpeerconnection.cc @@ -56,6 +56,8 @@ static const char kP256[] = "P-256"; static const char kConnectionState[] = "connectionState"; static const char kCurrentLocalDescription[] = "currentLocalDescription"; static const char kCurrentRemoteDescription[] = "currentRemoteDescription"; +static const char kLocalDescription[] = "localDescription"; +static const char kRemoteDescription[] = "remoteDescription"; static const char kIceConnectionState[] = "iceConnectionState"; static const char kIceGatheringState[] = "iceGatheringState"; static const char kPendingLocalDescription[] = "pendingLocalDescription"; @@ -109,6 +111,10 @@ NAN_MODULE_INIT(RTCPeerConnection::Init) { GetCurrentLocalDescription); Nan::SetAccessor(tpl, LOCAL_STRING(kCurrentRemoteDescription), GetCurrentRemoteDescription); + Nan::SetAccessor(tpl, LOCAL_STRING(kLocalDescription), + GetLocalDescription); + Nan::SetAccessor(tpl, LOCAL_STRING(kRemoteDescription), + GetRemoteDescription); Nan::SetAccessor(tpl, LOCAL_STRING(kIceConnectionState), GetIceConnectionState); Nan::SetAccessor(tpl, LOCAL_STRING(kIceGatheringState), @@ -328,6 +334,36 @@ NAN_GETTER(RTCPeerConnection::GetCurrentLocalDescription) { info.GetReturnValue().Set(Nan::Null()); } +NAN_GETTER(RTCPeerConnection::GetLocalDescription) { + METHOD_HEADER("RTCPeerConnection", "getLocalDescription"); + UNWRAP_OBJECT(RTCPeerConnection, object); + + const webrtc::SessionDescriptionInterface *session = object->_peerConnection->local_description(); + + const std::string type = session->type(); + std::string sdp; + session->ToString(&sdp); + + Local desc = RTCSessionDescription::Create( type, sdp ); + + info.GetReturnValue().Set(desc); +} + +NAN_GETTER(RTCPeerConnection::GetRemoteDescription) { + METHOD_HEADER("RTCPeerConnection", "getRemoteDescription"); + UNWRAP_OBJECT(RTCPeerConnection, object); + + const webrtc::SessionDescriptionInterface *session = object->_peerConnection->remote_description(); + + const std::string type = session->type(); + std::string sdp; + session->ToString(&sdp); + + Local desc = RTCSessionDescription::Create( type, sdp ); + + info.GetReturnValue().Set(desc); +} + NAN_GETTER(RTCPeerConnection::GetCurrentRemoteDescription) { info.GetReturnValue().Set(Nan::Null()); } diff --git a/src/rtcpeerconnection.h b/src/rtcpeerconnection.h index d41d84f..20430d8 100644 --- a/src/rtcpeerconnection.h +++ b/src/rtcpeerconnection.h @@ -44,7 +44,9 @@ class RTCPeerConnection : public Nan::ObjectWrap { static NAN_GETTER(GetConnectionState); static NAN_GETTER(GetCurrentLocalDescription); - static NAN_GETTER(GetCurrentRemoteDescription); + static NAN_GETTER(GetCurrentRemoteDescription); + static NAN_GETTER(GetLocalDescription); + static NAN_GETTER(GetRemoteDescription); static NAN_GETTER(GetIceConnectionState); static NAN_GETTER(GetIceGatheringState); static NAN_GETTER(GetPendingLocalDescription); From eebe11302d5cc43fa5f2c3ce5623f68b7482191c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Charmet?= Date: Thu, 16 Mar 2017 17:36:57 +0100 Subject: [PATCH 06/20] expose datachannel and make it extend EventEmitter --- index.js | 19 ++++++++++++++++++- src/rtcdatachannel.cc | 2 ++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/index.js b/index.js index 9a28268..f167d55 100644 --- a/index.js +++ b/index.js @@ -1,3 +1,20 @@ 'use strict'; -module.exports = require('bindings')('webrtc'); +const EventEmitter = require('events').EventEmitter; +const webrtc = require('bindings')('webrtc'); + +function inherit(cl,parent) { + for( var k in parent.prototype ) { + cl.prototype[k] = parent.prototype[k]; + } +} + +var EventTarget = function(){}; +inherit(EventTarget, EventEmitter); +EventTarget.prototype.addEventListener = EventEmitter.prototype.on; + +[webrtc.RTCPeerConnection, webrtc.RTCDataChannel].map((cl)=>{ + inherit(cl, EventTarget); +}); + +module.exports = webrtc; \ No newline at end of file diff --git a/src/rtcdatachannel.cc b/src/rtcdatachannel.cc index f1c2899..16e2ae5 100644 --- a/src/rtcdatachannel.cc +++ b/src/rtcdatachannel.cc @@ -36,6 +36,8 @@ NAN_MODULE_INIT(RTCDataChannel::Init) { Nan::SetAccessor(prototype, LOCAL_STRING(kReadyState), GetReadyState); constructor().Reset(Nan::GetFunction(ctor).ToLocalChecked()); + + Nan::Set(target, LOCAL_STRING(sRTCDataChannel), ctor->GetFunction()); } RTCDataChannel::RTCDataChannel( From e623bf53d05005a0dd66a08e60a5de88be2e11fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Charmet?= Date: Mon, 20 Mar 2017 18:10:56 +0100 Subject: [PATCH 07/20] wip peer connection events --- binding.gyp | 2 ++ src/event/peerconnectionevent.cc | 40 +++++++++++++++++++++++++ src/event/peerconnectionevent.h | 41 ++++++++++++++++++++++++++ src/eventemitter.cc | 39 ++++++++++++++++++++++++ src/eventemitter.h | 36 ++++++++++++++++++++++ src/observer/peerconnectionobserver.cc | 18 +++++++++-- src/observer/peerconnectionobserver.h | 16 ++++++++-- src/rtcpeerconnection.cc | 31 ++++++++++++++++++- src/rtcpeerconnection.h | 8 ++++- 9 files changed, 225 insertions(+), 6 deletions(-) create mode 100644 src/event/peerconnectionevent.cc create mode 100644 src/event/peerconnectionevent.h create mode 100644 src/eventemitter.cc create mode 100644 src/eventemitter.h diff --git a/binding.gyp b/binding.gyp index 9e95758..98e3f0d 100644 --- a/binding.gyp +++ b/binding.gyp @@ -5,9 +5,11 @@ 'sources': [ 'src/event/createsessiondescriptionevent.cc', 'src/event/setsessiondescriptionevent.cc', + 'src/event/peerconnectionevent.cc', 'src/event/eventqueue.cc', 'src/globals.cc', 'src/module.cc', + 'src/eventemitter.cc', 'src/observer/createsessiondescriptionobserver.cc', 'src/observer/setsessiondescriptionobserver.cc', 'src/observer/peerconnectionobserver.cc', diff --git a/src/event/peerconnectionevent.cc b/src/event/peerconnectionevent.cc new file mode 100644 index 0000000..961eeb1 --- /dev/null +++ b/src/event/peerconnectionevent.cc @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2017 Axel Isouard + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "common.h" +#include "peerconnectionevent.h" +#include + +using namespace v8; + +PeerConnectionEvent::PeerConnectionEvent( EventEmitter *eventEmitter ) : + _eventEmitter(eventEmitter) { +} + +void PeerConnectionEvent::Handle() { + Nan::HandleScope scope; + + _eventEmitter->Emit(LOCAL_STRING("test"), LOCAL_STRING("test")); +} + +void PeerConnectionEvent::SetSucceeded(bool succeeded) { + _succeeded = succeeded; +} + +void PeerConnectionEvent::SetErrorMessage( + const std::string &errorMessage) { + _errorMessage = errorMessage; +} diff --git a/src/event/peerconnectionevent.h b/src/event/peerconnectionevent.h new file mode 100644 index 0000000..c32d2e6 --- /dev/null +++ b/src/event/peerconnectionevent.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2017 Axel Isouard + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef EVENT_PEERCONNECTIONEVENT_H_ +#define EVENT_PEERCONNECTIONEVENT_H_ + +#include +#include +#include "event.h" +#include "eventemitter.h" + +using namespace v8; + +class PeerConnectionEvent : public Event { + public: + explicit PeerConnectionEvent( EventEmitter *eventEmitter ); + + void Handle(); + void SetSucceeded(bool succeeded); + void SetErrorMessage(const std::string& errorMessage); + + private: + bool _succeeded; + std::string _errorMessage; + EventEmitter *_eventEmitter; +}; + +#endif // EVENT_PEERCONNECTIONEVENT_H_ diff --git a/src/eventemitter.cc b/src/eventemitter.cc new file mode 100644 index 0000000..dbea924 --- /dev/null +++ b/src/eventemitter.cc @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2017 Axel Isouard + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "eventemitter.h" +#include +#include +#include +#include "common.h" + +using namespace v8; + +EventEmitter::EventEmitter(){}; + +void EventEmitter::Wrap( Local obj ){ + Nan::ObjectWrap::Wrap( obj ); + _emit = new Nan::Persistent(v8::Local::Cast(handle()->Get(Nan::New("emit").ToLocalChecked()))); +} + +void EventEmitter::Emit( Local type, Local data ){ + Nan::HandleScope scope; + Local argv[] = { type, data }; + Local emit = Nan::New(*_emit); + emit->Call(handle(), 2, argv); +} + + diff --git a/src/eventemitter.h b/src/eventemitter.h new file mode 100644 index 0000000..4e6d973 --- /dev/null +++ b/src/eventemitter.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2017 Axel Isouard + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef EVENTEMITTER_H_ +#define EVENTEMITTER_H_ + +#include +#include +#include + +using namespace v8; + +class EventEmitter : public Nan::ObjectWrap { + public: + explicit EventEmitter(); + Persistent* _emit = nullptr; + + void Wrap( Local obj ); + void Emit( Local type, Local data ); + +}; + +#endif // EVENTEMITTER_H_ diff --git a/src/observer/peerconnectionobserver.cc b/src/observer/peerconnectionobserver.cc index 7d52f7a..3376d71 100644 --- a/src/observer/peerconnectionobserver.cc +++ b/src/observer/peerconnectionobserver.cc @@ -16,6 +16,8 @@ #include #include "peerconnectionobserver.h" +#include "event/peerconnectionevent.h" +#include "globals.h" PeerConnectionObserver::PeerConnectionObserver() { } @@ -26,7 +28,9 @@ PeerConnectionObserver::~PeerConnectionObserver() { void PeerConnectionObserver::OnSignalingChange( webrtc::PeerConnectionInterface::SignalingState new_state) { - std::cout << "OnSignalingChange" << std::endl; + PeerConnectionEvent* _event = new PeerConnectionEvent(_eventEmitter); + Globals::GetEventQueue()->PushEvent(_event); + } void PeerConnectionObserver::OnAddStream( @@ -77,6 +81,16 @@ PeerConnectionObserver *PeerConnectionObserver::Create() { } void PeerConnectionObserver::SetPeerConnection( - rtc::scoped_refptr peerConnection) { + RTCPeerConnection* peerConnection) { _peerConnection = peerConnection; } + +void PeerConnectionObserver::SetEventEmitter( + EventEmitter* eventEmitter) { + _eventEmitter = eventEmitter; +} + +// void PeerConnectionObserver::SetEmit( +// Persistent* emit) { +// _emit = emit; +// } diff --git a/src/observer/peerconnectionobserver.h b/src/observer/peerconnectionobserver.h index 8d52e59..e343d8c 100644 --- a/src/observer/peerconnectionobserver.h +++ b/src/observer/peerconnectionobserver.h @@ -18,6 +18,10 @@ #define OBSERVER_PEERCONNECTIONOBSERVER_H_ #include +#include +#include + +using namespace v8; class PeerConnectionObserver : public rtc::RefCountInterface, public webrtc::PeerConnectionObserver { @@ -25,7 +29,13 @@ class PeerConnectionObserver : public rtc::RefCountInterface, static PeerConnectionObserver *Create(); void SetPeerConnection( - rtc::scoped_refptr peerConnection); + RTCPeerConnection* peerConnection); + + // void SetEmit( + // Persistent* emit); + + void SetEventEmitter( + EventEmitter* eventEmitter); // Triggered when the SignalingState changed. void OnSignalingChange( @@ -66,7 +76,9 @@ class PeerConnectionObserver : public rtc::RefCountInterface, void OnIceConnectionReceivingChange(bool receiving); private: - rtc::scoped_refptr _peerConnection; + RTCPeerConnection* _peerConnection; + //Persistent* _emit; + EventEmitter* _eventEmitter; protected: PeerConnectionObserver(); diff --git a/src/rtcpeerconnection.cc b/src/rtcpeerconnection.cc index 289e28a..bf0617a 100644 --- a/src/rtcpeerconnection.cc +++ b/src/rtcpeerconnection.cc @@ -141,7 +141,7 @@ RTCPeerConnection::RTCPeerConnection( _peerConnectionObserver = PeerConnectionObserver::Create(); _peerConnection = _peerConnectionFactory->CreatePeerConnection( config, &constraints, NULL, NULL, _peerConnectionObserver); - _peerConnectionObserver->SetPeerConnection(_peerConnection); + //_peerConnectionObserver->SetPeerConnection(_peerConnection); } RTCPeerConnection::~RTCPeerConnection() { @@ -197,6 +197,17 @@ NAN_METHOD(RTCPeerConnection::New) { constraints); rtcPeerConnection->Wrap(info.This()); + // "access" emit function inherited from EventEmitter + //rtcPeerConnection->emit = new Nan::Persistent(v8::Local::Cast(rtcPeerConnection->handle()->Get(Nan::New("emit2").ToLocalChecked()))); + // v8::Local::Cast(rtcPeerConnection->handle()->Get(Nan::New("emit").ToLocalChecked()))); + + //rtcPeerConnection->_peerConnectionObserver->SetEmit(rtcPeerConnection->emit); + rtcPeerConnection->_peerConnectionObserver->SetEventEmitter(rtcPeerConnection); + // rtcPeerConnection->_peerConnectionObserver->SetEmit( + // new Nan::Persistent() + // ); + + info.GetReturnValue().Set(info.This()); } @@ -272,12 +283,30 @@ NAN_METHOD(RTCPeerConnection::CreateAnswer) { object->_peerConnection->CreateAnswer(observer, &constraints); } +void RTCPeerConnection::Test(){ + std::cout << "TEST TEST" << std::endl; +} + +NAN_METHOD(RTCPeerConnection::TestEmit) { + METHOD_HEADER("RTCPeerConnection", "testEmit"); + // UNWRAP_OBJECT(RTCPeerConnection, object); + + // Local argv[] = { Nan::New("test").ToLocalChecked() }; + // Nan::New(*object->emit)->Call(object->handle(), 1, argv); + + info.GetReturnValue().Set(Nan::Null()); +} + NAN_METHOD(RTCPeerConnection::SetLocalDescription) { METHOD_HEADER("RTCPeerConnection", "setLocalDescription"); UNWRAP_OBJECT(RTCPeerConnection, object); rtc::scoped_refptr observer; + // Local emit = Nan::New(*object->emit); + // Local argv[] = { Nan::New("test").ToLocalChecked() }; + // emit->Call( object->handle(), 1 , argv ); + // FIXME: Promise implementation only DECLARE_PROMISE_RESOLVER; ASSERT_REJECT_OBJECT_ARGUMENT(0, sessionDescription); diff --git a/src/rtcpeerconnection.h b/src/rtcpeerconnection.h index 20430d8..fba1fca 100644 --- a/src/rtcpeerconnection.h +++ b/src/rtcpeerconnection.h @@ -20,14 +20,19 @@ #include #include #include +#include "eventemitter.h" using namespace v8; class PeerConnectionObserver; -class RTCPeerConnection : public Nan::ObjectWrap { +class RTCPeerConnection : public EventEmitter { public: static NAN_MODULE_INIT(Init); + //Persistent* emit = nullptr; + //void TestEmit(); + void Test(); + private: explicit RTCPeerConnection( const webrtc::PeerConnectionInterface::RTCConfiguration& config, @@ -41,6 +46,7 @@ class RTCPeerConnection : public Nan::ObjectWrap { static NAN_METHOD(SetRemoteDescription); static NAN_METHOD(CreateDataChannel); static NAN_METHOD(GenerateCertificate); + static NAN_METHOD(TestEmit); static NAN_GETTER(GetConnectionState); static NAN_GETTER(GetCurrentLocalDescription); From 9853c4e67f071f2cc4e26db4f00ec9b05815103f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Charmet?= Date: Tue, 21 Mar 2017 18:05:52 +0100 Subject: [PATCH 08/20] peer connection events more or less work --- binding.gyp | 3 +- ...peerconnectionevent.cc => emitterevent.cc} | 22 ++++------ .../{peerconnectionevent.h => emitterevent.h} | 21 ++++------ src/event/peerconnectioniceevent.cc | 41 +++++++++++++++++++ src/event/peerconnectioniceevent.h | 38 +++++++++++++++++ src/eventemitter.cc | 17 +++++--- src/eventemitter.h | 4 +- src/observer/peerconnectionobserver.cc | 38 +++++++++++++---- src/observer/peerconnectionobserver.h | 3 +- src/rtcicecandidate.cc | 24 +++++++++-- src/rtcicecandidate.h | 10 +++-- src/rtcpeerconnection.cc | 4 -- src/rtcpeerconnection.h | 4 -- 13 files changed, 172 insertions(+), 57 deletions(-) rename src/event/{peerconnectionevent.cc => emitterevent.cc} (62%) rename src/event/{peerconnectionevent.h => emitterevent.h} (64%) create mode 100644 src/event/peerconnectioniceevent.cc create mode 100644 src/event/peerconnectioniceevent.h diff --git a/binding.gyp b/binding.gyp index 98e3f0d..3d3bb57 100644 --- a/binding.gyp +++ b/binding.gyp @@ -5,7 +5,8 @@ 'sources': [ 'src/event/createsessiondescriptionevent.cc', 'src/event/setsessiondescriptionevent.cc', - 'src/event/peerconnectionevent.cc', + 'src/event/emitterevent.cc', + 'src/event/peerconnectioniceevent.cc', 'src/event/eventqueue.cc', 'src/globals.cc', 'src/module.cc', diff --git a/src/event/peerconnectionevent.cc b/src/event/emitterevent.cc similarity index 62% rename from src/event/peerconnectionevent.cc rename to src/event/emitterevent.cc index 961eeb1..215b66b 100644 --- a/src/event/peerconnectionevent.cc +++ b/src/event/emitterevent.cc @@ -15,26 +15,20 @@ */ #include "common.h" -#include "peerconnectionevent.h" -#include +#include "emitterevent.h" using namespace v8; -PeerConnectionEvent::PeerConnectionEvent( EventEmitter *eventEmitter ) : +EmitterEvent::EmitterEvent( EventEmitter *eventEmitter ) : _eventEmitter(eventEmitter) { } -void PeerConnectionEvent::Handle() { +void EmitterEvent::Handle() { Nan::HandleScope scope; - - _eventEmitter->Emit(LOCAL_STRING("test"), LOCAL_STRING("test")); -} - -void PeerConnectionEvent::SetSucceeded(bool succeeded) { - _succeeded = succeeded; + _eventEmitter->Emit(LOCAL_STRING(_type)); } -void PeerConnectionEvent::SetErrorMessage( - const std::string &errorMessage) { - _errorMessage = errorMessage; -} +void EmitterEvent::SetType( + const std::string &type) { + _type = type; +} \ No newline at end of file diff --git a/src/event/peerconnectionevent.h b/src/event/emitterevent.h similarity index 64% rename from src/event/peerconnectionevent.h rename to src/event/emitterevent.h index c32d2e6..daf8df1 100644 --- a/src/event/peerconnectionevent.h +++ b/src/event/emitterevent.h @@ -14,28 +14,25 @@ * limitations under the License. */ -#ifndef EVENT_PEERCONNECTIONEVENT_H_ -#define EVENT_PEERCONNECTIONEVENT_H_ +#ifndef EVENT_EMITTEREVENT_H_ +#define EVENT_EMITTEREVENT_H_ -#include -#include #include "event.h" #include "eventemitter.h" using namespace v8; -class PeerConnectionEvent : public Event { +class EmitterEvent : public Event { public: - explicit PeerConnectionEvent( EventEmitter *eventEmitter ); + explicit EmitterEvent( EventEmitter *eventEmitter ); void Handle(); - void SetSucceeded(bool succeeded); - void SetErrorMessage(const std::string& errorMessage); + void SetType(const std::string& type); - private: - bool _succeeded; - std::string _errorMessage; + protected: EventEmitter *_eventEmitter; + std::string _type; + }; -#endif // EVENT_PEERCONNECTIONEVENT_H_ +#endif // EVENT_EMITTEREVENT_H_ diff --git a/src/event/peerconnectioniceevent.cc b/src/event/peerconnectioniceevent.cc new file mode 100644 index 0000000..a475929 --- /dev/null +++ b/src/event/peerconnectioniceevent.cc @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2017 Axel Isouard + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "common.h" +#include "peerconnectioniceevent.h" +#include "eventemitter.h" +#include "rtcicecandidate.h" + +#include +#include + +using namespace v8; + +PeerConnectionIceEvent::PeerConnectionIceEvent(EventEmitter *eventEmitter) + : EmitterEvent(eventEmitter) { +} + +void PeerConnectionIceEvent::Handle() { + Nan::HandleScope scope; + + _eventEmitter->Emit(LOCAL_STRING(_type)); +} + +void PeerConnectionIceEvent::SetCandidate(const webrtc::IceCandidateInterface* candidate) { + + // FIXME: needs to serialize here... + _candidate = candidate; +} diff --git a/src/event/peerconnectioniceevent.h b/src/event/peerconnectioniceevent.h new file mode 100644 index 0000000..4705c0c --- /dev/null +++ b/src/event/peerconnectioniceevent.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2017 Axel Isouard + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef EVENT_PEERCONNECTIONICEEVENT_H_ +#define EVENT_PEERCONNECTIONICEEVENT_H_ + +#include "emitterevent.h" +#include "eventemitter.h" +#include + +using namespace v8; + +class PeerConnectionIceEvent : public EmitterEvent { + public: + explicit PeerConnectionIceEvent(EventEmitter *eventEmitter); + + void Handle(); + void SetCandidate(const webrtc::IceCandidateInterface* candidate); + + private: + const webrtc::IceCandidateInterface *_candidate; + +}; + +#endif // EVENT_PEERCONNECTIONICEEVENT_H_ diff --git a/src/eventemitter.cc b/src/eventemitter.cc index dbea924..26f6365 100644 --- a/src/eventemitter.cc +++ b/src/eventemitter.cc @@ -15,21 +15,28 @@ */ #include "eventemitter.h" -#include -#include -#include #include "common.h" using namespace v8; +static const char kEmit[] = "emit"; + EventEmitter::EventEmitter(){}; void EventEmitter::Wrap( Local obj ){ Nan::ObjectWrap::Wrap( obj ); - _emit = new Nan::Persistent(v8::Local::Cast(handle()->Get(Nan::New("emit").ToLocalChecked()))); + _emit = new Nan::Persistent( + Local::Cast(handle()->Get(Nan::New(kEmit).ToLocalChecked()))); +} + +void EventEmitter::Emit( Local type ){ + Nan::HandleScope scope; + Local argv[] = { type }; + Local emit = Nan::New(*_emit); + emit->Call(handle(), 1, argv); } -void EventEmitter::Emit( Local type, Local data ){ +void EventEmitter::EmitData( Local type, Local data ){ Nan::HandleScope scope; Local argv[] = { type, data }; Local emit = Nan::New(*_emit); diff --git a/src/eventemitter.h b/src/eventemitter.h index 4e6d973..5ef06ed 100644 --- a/src/eventemitter.h +++ b/src/eventemitter.h @@ -18,7 +18,6 @@ #define EVENTEMITTER_H_ #include -#include #include using namespace v8; @@ -29,7 +28,8 @@ class EventEmitter : public Nan::ObjectWrap { Persistent* _emit = nullptr; void Wrap( Local obj ); - void Emit( Local type, Local data ); + void Emit( Local type ); + void EmitData( Local type, Local data ); }; diff --git a/src/observer/peerconnectionobserver.cc b/src/observer/peerconnectionobserver.cc index 3376d71..106b4a9 100644 --- a/src/observer/peerconnectionobserver.cc +++ b/src/observer/peerconnectionobserver.cc @@ -16,9 +16,15 @@ #include #include "peerconnectionobserver.h" -#include "event/peerconnectionevent.h" #include "globals.h" +static const char kSignalingStateChange[] = "signalingstatechange"; +static const char kIceConnectionStateChange[] = "iceconnectionstatechange"; +static const char kIceGatheringStateChange[] = "icegatheringstatechange"; +static const char kNegociationNeeded[] = "negotiationneeded"; +static const char kDataChannel[] = "datachannel"; +static const char kIceCandidate[] = "icecandidate"; + PeerConnectionObserver::PeerConnectionObserver() { } @@ -27,10 +33,10 @@ PeerConnectionObserver::~PeerConnectionObserver() { } void PeerConnectionObserver::OnSignalingChange( - webrtc::PeerConnectionInterface::SignalingState new_state) { - PeerConnectionEvent* _event = new PeerConnectionEvent(_eventEmitter); + webrtc::PeerConnectionInterface::SignalingState new_state) { + EmitterEvent* _event = new EmitterEvent(_eventEmitter); + _event->SetType(kSignalingStateChange); Globals::GetEventQueue()->PushEvent(_event); - } void PeerConnectionObserver::OnAddStream( @@ -49,22 +55,38 @@ void PeerConnectionObserver::OnDataChannel( } void PeerConnectionObserver::OnRenegotiationNeeded() { - std::cout << "OnRenegotiationNeeded" << std::endl; + EmitterEvent* _event = new EmitterEvent(_eventEmitter); + _event->SetType(kNegociationNeeded); + Globals::GetEventQueue()->PushEvent(_event); } void PeerConnectionObserver::OnIceConnectionChange( webrtc::PeerConnectionInterface::IceConnectionState new_state) { - std::cout << "OnIceConnectionChange" << std::endl; + EmitterEvent* _event = new EmitterEvent(_eventEmitter); + _event->SetType(kIceConnectionStateChange); + Globals::GetEventQueue()->PushEvent(_event); } void PeerConnectionObserver::OnIceGatheringChange( webrtc::PeerConnectionInterface::IceGatheringState new_state) { - std::cout << "OnIceGatheringChange" << std::endl; + EmitterEvent* _event = new EmitterEvent(_eventEmitter); + _event->SetType(kIceGatheringStateChange); + Globals::GetEventQueue()->PushEvent(_event); } void PeerConnectionObserver::OnIceCandidate( const webrtc::IceCandidateInterface *candidate) { - std::cout << "OnIceCandidate" << std::endl; + + std::string candidateValue; + candidate->ToString(&candidateValue); + + std::cout << candidateValue << std::endl; + + PeerConnectionIceEvent* _event = new PeerConnectionIceEvent(_eventEmitter); + _event->SetType(kIceCandidate); + _event->SetCandidate(candidate); + Globals::GetEventQueue()->PushEvent(_event); + } void PeerConnectionObserver::OnIceCandidatesRemoved( diff --git a/src/observer/peerconnectionobserver.h b/src/observer/peerconnectionobserver.h index e343d8c..6f2ea62 100644 --- a/src/observer/peerconnectionobserver.h +++ b/src/observer/peerconnectionobserver.h @@ -19,7 +19,8 @@ #include #include -#include +#include "event/emitterevent.h" +#include "event/peerconnectioniceevent.h" using namespace v8; diff --git a/src/rtcicecandidate.cc b/src/rtcicecandidate.cc index c60a1e5..fd73e11 100644 --- a/src/rtcicecandidate.cc +++ b/src/rtcicecandidate.cc @@ -23,7 +23,7 @@ #include "common.h" #include "rtcicecandidate.h" -Nan::Persistent RTCIceCandidate::constructor; +//Nan::Persistent RTCIceCandidate::constructor; static const char sRTCIceCandidate[] = "RTCIceCandidate"; @@ -67,12 +67,13 @@ NAN_MODULE_INIT(RTCIceCandidate::Init) { Nan::SetAccessor(prototype, LOCAL_STRING(kRelatedAddress), GetRelatedAddress); Nan::SetAccessor(prototype, LOCAL_STRING(kRelatedPort), GetRelatedPort); - constructor.Reset(ctor); + constructor().Reset(Nan::GetFunction(ctor).ToLocalChecked()); + Nan::Set(target, LOCAL_STRING(sRTCIceCandidate), ctor->GetFunction()); } -RTCIceCandidate::RTCIceCandidate(webrtc::IceCandidateInterface *iceCandidate) +RTCIceCandidate::RTCIceCandidate(const webrtc::IceCandidateInterface *iceCandidate) : _iceCandidate(iceCandidate) { } @@ -80,6 +81,23 @@ RTCIceCandidate::~RTCIceCandidate() { delete _iceCandidate; } +Local RTCIceCandidate::Create(const webrtc::IceCandidateInterface *iceCandidate) { + Local cons = Nan::New(RTCIceCandidate::constructor()); + + // FIXME: broken, need to serialize / deserialize all in PeerConnectionIceEvent + Local candidateInitDict = Nan::New(); + + const int argc = 1; + Local argv[1] = { candidateInitDict }; + + Local instance = Nan::NewInstance(cons, argc, argv).ToLocalChecked(); + + RTCIceCandidate *_candidate = new RTCIceCandidate(iceCandidate); + _candidate->Wrap(instance); + + return instance; +} + NAN_METHOD(RTCIceCandidate::New) { CONSTRUCTOR_HEADER("RTCIceCandidate") diff --git a/src/rtcicecandidate.h b/src/rtcicecandidate.h index 907195f..a4ef7dc 100644 --- a/src/rtcicecandidate.h +++ b/src/rtcicecandidate.h @@ -25,9 +25,10 @@ using namespace v8; class RTCIceCandidate : public Nan::ObjectWrap { public: static NAN_MODULE_INIT(Init); + static Local Create(const webrtc::IceCandidateInterface *_iceCandidate); private: - explicit RTCIceCandidate(webrtc::IceCandidateInterface *iceCandidate); + explicit RTCIceCandidate(const webrtc::IceCandidateInterface *iceCandidate); ~RTCIceCandidate(); static NAN_METHOD(New); @@ -46,10 +47,13 @@ class RTCIceCandidate : public Nan::ObjectWrap { static NAN_GETTER(GetRelatedAddress); static NAN_GETTER(GetRelatedPort); - static Nan::Persistent constructor; + static inline Nan::Persistent& constructor() { + static Nan::Persistent _constructor; + return _constructor; + } protected: - webrtc::IceCandidateInterface *_iceCandidate; + const webrtc::IceCandidateInterface *_iceCandidate; }; #endif // RTCICECANDIDATE_H_ diff --git a/src/rtcpeerconnection.cc b/src/rtcpeerconnection.cc index bf0617a..8eace1f 100644 --- a/src/rtcpeerconnection.cc +++ b/src/rtcpeerconnection.cc @@ -283,10 +283,6 @@ NAN_METHOD(RTCPeerConnection::CreateAnswer) { object->_peerConnection->CreateAnswer(observer, &constraints); } -void RTCPeerConnection::Test(){ - std::cout << "TEST TEST" << std::endl; -} - NAN_METHOD(RTCPeerConnection::TestEmit) { METHOD_HEADER("RTCPeerConnection", "testEmit"); // UNWRAP_OBJECT(RTCPeerConnection, object); diff --git a/src/rtcpeerconnection.h b/src/rtcpeerconnection.h index fba1fca..faa9fc2 100644 --- a/src/rtcpeerconnection.h +++ b/src/rtcpeerconnection.h @@ -29,10 +29,6 @@ class RTCPeerConnection : public EventEmitter { public: static NAN_MODULE_INIT(Init); - //Persistent* emit = nullptr; - //void TestEmit(); - void Test(); - private: explicit RTCPeerConnection( const webrtc::PeerConnectionInterface::RTCConfiguration& config, From ae9f9aba27c76bb707e7d1cad87abb991c91854e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Charmet?= Date: Wed, 22 Mar 2017 11:29:17 +0100 Subject: [PATCH 09/20] got onicecandidate working --- src/event/peerconnectioniceevent.cc | 15 +++++++++++---- src/event/peerconnectioniceevent.h | 5 ++++- src/observer/peerconnectionobserver.cc | 6 ------ src/rtcicecandidate.cc | 10 ++++------ src/rtcicecandidate.h | 2 +- 5 files changed, 20 insertions(+), 18 deletions(-) diff --git a/src/event/peerconnectioniceevent.cc b/src/event/peerconnectioniceevent.cc index a475929..2b236e0 100644 --- a/src/event/peerconnectioniceevent.cc +++ b/src/event/peerconnectioniceevent.cc @@ -24,6 +24,8 @@ using namespace v8; +static const char kCandidate[] = "candidate"; + PeerConnectionIceEvent::PeerConnectionIceEvent(EventEmitter *eventEmitter) : EmitterEvent(eventEmitter) { } @@ -31,11 +33,16 @@ PeerConnectionIceEvent::PeerConnectionIceEvent(EventEmitter *eventEmitter) void PeerConnectionIceEvent::Handle() { Nan::HandleScope scope; - _eventEmitter->Emit(LOCAL_STRING(_type)); + // FIXME: make proper PeerConnectionIceEvent ? + Local e = Nan::New(); + e->Set(LOCAL_STRING(kCandidate), + RTCIceCandidate::Create(_sdpMid, _sdpMLineIndex, _candidate)); + + _eventEmitter->EmitData(LOCAL_STRING(_type),e); } void PeerConnectionIceEvent::SetCandidate(const webrtc::IceCandidateInterface* candidate) { - - // FIXME: needs to serialize here... - _candidate = candidate; + candidate->ToString(&_candidate); + _sdpMid = candidate->sdp_mid(); + _sdpMLineIndex = candidate->sdp_mline_index(); } diff --git a/src/event/peerconnectioniceevent.h b/src/event/peerconnectioniceevent.h index 4705c0c..9489c3b 100644 --- a/src/event/peerconnectioniceevent.h +++ b/src/event/peerconnectioniceevent.h @@ -31,7 +31,10 @@ class PeerConnectionIceEvent : public EmitterEvent { void SetCandidate(const webrtc::IceCandidateInterface* candidate); private: - const webrtc::IceCandidateInterface *_candidate; + std::string _candidate = ""; + std::string _sdpMid = ""; + int _sdpMLineIndex = 0; + //std::string _ufrag; }; diff --git a/src/observer/peerconnectionobserver.cc b/src/observer/peerconnectionobserver.cc index 106b4a9..2e52214 100644 --- a/src/observer/peerconnectionobserver.cc +++ b/src/observer/peerconnectionobserver.cc @@ -76,12 +76,6 @@ void PeerConnectionObserver::OnIceGatheringChange( void PeerConnectionObserver::OnIceCandidate( const webrtc::IceCandidateInterface *candidate) { - - std::string candidateValue; - candidate->ToString(&candidateValue); - - std::cout << candidateValue << std::endl; - PeerConnectionIceEvent* _event = new PeerConnectionIceEvent(_eventEmitter); _event->SetType(kIceCandidate); _event->SetCandidate(candidate); diff --git a/src/rtcicecandidate.cc b/src/rtcicecandidate.cc index fd73e11..ba08508 100644 --- a/src/rtcicecandidate.cc +++ b/src/rtcicecandidate.cc @@ -81,20 +81,18 @@ RTCIceCandidate::~RTCIceCandidate() { delete _iceCandidate; } -Local RTCIceCandidate::Create(const webrtc::IceCandidateInterface *iceCandidate) { +Local RTCIceCandidate::Create(std::string sdpMid, int sdpMLineIndex, std::string candidate) { Local cons = Nan::New(RTCIceCandidate::constructor()); - // FIXME: broken, need to serialize / deserialize all in PeerConnectionIceEvent Local candidateInitDict = Nan::New(); + candidateInitDict->Set(LOCAL_STRING(kSdpMid), LOCAL_STRING(sdpMid)); + candidateInitDict->Set(LOCAL_STRING(kSdpMLineIndex), Nan::New(sdpMLineIndex)); + candidateInitDict->Set(LOCAL_STRING(kCandidate), LOCAL_STRING(candidate)); const int argc = 1; Local argv[1] = { candidateInitDict }; - Local instance = Nan::NewInstance(cons, argc, argv).ToLocalChecked(); - RTCIceCandidate *_candidate = new RTCIceCandidate(iceCandidate); - _candidate->Wrap(instance); - return instance; } diff --git a/src/rtcicecandidate.h b/src/rtcicecandidate.h index a4ef7dc..061e9d8 100644 --- a/src/rtcicecandidate.h +++ b/src/rtcicecandidate.h @@ -25,7 +25,7 @@ using namespace v8; class RTCIceCandidate : public Nan::ObjectWrap { public: static NAN_MODULE_INIT(Init); - static Local Create(const webrtc::IceCandidateInterface *_iceCandidate); + static Local Create(std::string sdpMid, int sdpMLineIndex, std::string candidate); private: explicit RTCIceCandidate(const webrtc::IceCandidateInterface *iceCandidate); From f349537260bfc42a3b5f29381888e5cebf41d8c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Charmet?= Date: Wed, 22 Mar 2017 12:01:05 +0100 Subject: [PATCH 10/20] added onchannel event, untested --- binding.gyp | 1 + src/event/datachannelevent.cc | 40 ++++++++++++++++++++++++++ src/event/datachannelevent.h | 39 +++++++++++++++++++++++++ src/observer/peerconnectionobserver.cc | 4 ++- src/observer/peerconnectionobserver.h | 4 +-- 5 files changed, 84 insertions(+), 4 deletions(-) create mode 100644 src/event/datachannelevent.cc create mode 100644 src/event/datachannelevent.h diff --git a/binding.gyp b/binding.gyp index 3d3bb57..6077186 100644 --- a/binding.gyp +++ b/binding.gyp @@ -7,6 +7,7 @@ 'src/event/setsessiondescriptionevent.cc', 'src/event/emitterevent.cc', 'src/event/peerconnectioniceevent.cc', + 'src/event/datachannelevent.cc', 'src/event/eventqueue.cc', 'src/globals.cc', 'src/module.cc', diff --git a/src/event/datachannelevent.cc b/src/event/datachannelevent.cc new file mode 100644 index 0000000..1b6cffd --- /dev/null +++ b/src/event/datachannelevent.cc @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2017 Axel Isouard + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "common.h" +#include "datachannelevent.h" +#include "eventemitter.h" +#include "rtcdatachannel.h" + +using namespace v8; + +static const char kChannel[] = "channel"; + +DataChannelEvent::DataChannelEvent(EventEmitter *eventEmitter, + const rtc::scoped_refptr &datachannel) + : EmitterEvent(eventEmitter), _channel(datachannel) { +} + +void DataChannelEvent::Handle() { + Nan::HandleScope scope; + + // FIXME: make proper DataChannelEvent ? + Local e = Nan::New(); + e->Set(LOCAL_STRING(kChannel), + RTCDataChannel::Create(_channel)); + + _eventEmitter->EmitData(LOCAL_STRING(_type),e); +} diff --git a/src/event/datachannelevent.h b/src/event/datachannelevent.h new file mode 100644 index 0000000..4f68696 --- /dev/null +++ b/src/event/datachannelevent.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2017 Axel Isouard + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef EVENT_DATACHANNELEVENT_H_ +#define EVENT_DATACHANNELEVENT_H_ + +#include "emitterevent.h" +#include "eventemitter.h" +#include +#include + +using namespace v8; + +class DataChannelEvent : public EmitterEvent { + public: + explicit DataChannelEvent(EventEmitter *eventEmitter, + const rtc::scoped_refptr& datachannel); + + void Handle(); + + private: + const rtc::scoped_refptr _channel; + +}; + +#endif // EVENT_DATACHANNELEVENT_H_ diff --git a/src/observer/peerconnectionobserver.cc b/src/observer/peerconnectionobserver.cc index 2e52214..b484478 100644 --- a/src/observer/peerconnectionobserver.cc +++ b/src/observer/peerconnectionobserver.cc @@ -51,7 +51,9 @@ void PeerConnectionObserver::OnRemoveStream( void PeerConnectionObserver::OnDataChannel( rtc::scoped_refptr data_channel) { - std::cout << "OnDataChannel" << std::endl; + DataChannelEvent* _event = new DataChannelEvent(_eventEmitter, data_channel); + _event->SetType(kDataChannel); + Globals::GetEventQueue()->PushEvent(_event); } void PeerConnectionObserver::OnRenegotiationNeeded() { diff --git a/src/observer/peerconnectionobserver.h b/src/observer/peerconnectionobserver.h index 6f2ea62..47ca802 100644 --- a/src/observer/peerconnectionobserver.h +++ b/src/observer/peerconnectionobserver.h @@ -21,6 +21,7 @@ #include #include "event/emitterevent.h" #include "event/peerconnectioniceevent.h" +#include "event/datachannelevent.h" using namespace v8; @@ -32,9 +33,6 @@ class PeerConnectionObserver : public rtc::RefCountInterface, void SetPeerConnection( RTCPeerConnection* peerConnection); - // void SetEmit( - // Persistent* emit); - void SetEventEmitter( EventEmitter* eventEmitter); From 392f8b1399c9299e02a5deaefa0e515e1130e616 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Charmet?= Date: Wed, 22 Mar 2017 15:13:04 +0100 Subject: [PATCH 11/20] clean --- src/observer/peerconnectionobserver.cc | 12 +----------- src/observer/peerconnectionobserver.h | 5 ----- 2 files changed, 1 insertion(+), 16 deletions(-) diff --git a/src/observer/peerconnectionobserver.cc b/src/observer/peerconnectionobserver.cc index b484478..e252caf 100644 --- a/src/observer/peerconnectionobserver.cc +++ b/src/observer/peerconnectionobserver.cc @@ -29,7 +29,7 @@ PeerConnectionObserver::PeerConnectionObserver() { } PeerConnectionObserver::~PeerConnectionObserver() { - _peerConnection = NULL; + _eventEmitter = NULL; } void PeerConnectionObserver::OnSignalingChange( @@ -98,17 +98,7 @@ PeerConnectionObserver *PeerConnectionObserver::Create() { return new rtc::RefCountedObject(); } -void PeerConnectionObserver::SetPeerConnection( - RTCPeerConnection* peerConnection) { - _peerConnection = peerConnection; -} - void PeerConnectionObserver::SetEventEmitter( EventEmitter* eventEmitter) { _eventEmitter = eventEmitter; } - -// void PeerConnectionObserver::SetEmit( -// Persistent* emit) { -// _emit = emit; -// } diff --git a/src/observer/peerconnectionobserver.h b/src/observer/peerconnectionobserver.h index 47ca802..2be6e4d 100644 --- a/src/observer/peerconnectionobserver.h +++ b/src/observer/peerconnectionobserver.h @@ -30,9 +30,6 @@ class PeerConnectionObserver : public rtc::RefCountInterface, public: static PeerConnectionObserver *Create(); - void SetPeerConnection( - RTCPeerConnection* peerConnection); - void SetEventEmitter( EventEmitter* eventEmitter); @@ -75,8 +72,6 @@ class PeerConnectionObserver : public rtc::RefCountInterface, void OnIceConnectionReceivingChange(bool receiving); private: - RTCPeerConnection* _peerConnection; - //Persistent* _emit; EventEmitter* _eventEmitter; protected: From 4420c1e0f25a48041ed0ff1042507b5dbf72b860 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Charmet?= Date: Fri, 24 Mar 2017 16:29:18 +0100 Subject: [PATCH 12/20] added datachannel.send, emit empty icecandidate on gathering complete, clean --- src/event/peerconnectioniceevent.cc | 7 ++- src/event/peerconnectioniceevent.h | 4 +- src/event/setsessiondescriptionevent.cc | 1 + src/module.cc | 4 ++ src/observer/peerconnectionobserver.cc | 26 +++++++++++ src/rtcdatachannel.cc | 16 +++++++ src/rtcdatachannel.h | 5 ++- src/rtcpeerconnection.cc | 60 ++++++++++++++----------- src/rtcpeerconnection.h | 3 +- 9 files changed, 93 insertions(+), 33 deletions(-) diff --git a/src/event/peerconnectioniceevent.cc b/src/event/peerconnectioniceevent.cc index 2b236e0..5c35940 100644 --- a/src/event/peerconnectioniceevent.cc +++ b/src/event/peerconnectioniceevent.cc @@ -35,8 +35,13 @@ void PeerConnectionIceEvent::Handle() { // FIXME: make proper PeerConnectionIceEvent ? Local e = Nan::New(); - e->Set(LOCAL_STRING(kCandidate), + + if(_candidate.length() && _sdpMid.length()) { + e->Set(LOCAL_STRING(kCandidate), RTCIceCandidate::Create(_sdpMid, _sdpMLineIndex, _candidate)); + } else { + e->Set(LOCAL_STRING(kCandidate), Nan::Null()); + } _eventEmitter->EmitData(LOCAL_STRING(_type),e); } diff --git a/src/event/peerconnectioniceevent.h b/src/event/peerconnectioniceevent.h index 9489c3b..65bd86e 100644 --- a/src/event/peerconnectioniceevent.h +++ b/src/event/peerconnectioniceevent.h @@ -31,8 +31,8 @@ class PeerConnectionIceEvent : public EmitterEvent { void SetCandidate(const webrtc::IceCandidateInterface* candidate); private: - std::string _candidate = ""; - std::string _sdpMid = ""; + std::string _candidate; + std::string _sdpMid; int _sdpMLineIndex = 0; //std::string _ufrag; diff --git a/src/event/setsessiondescriptionevent.cc b/src/event/setsessiondescriptionevent.cc index 4f7253e..23638e4 100644 --- a/src/event/setsessiondescriptionevent.cc +++ b/src/event/setsessiondescriptionevent.cc @@ -17,6 +17,7 @@ #include "common.h" #include "setsessiondescriptionevent.h" #include "rtcsessiondescription.h" +#include using namespace v8; diff --git a/src/module.cc b/src/module.cc index 1ec0930..2628c96 100644 --- a/src/module.cc +++ b/src/module.cc @@ -22,12 +22,16 @@ #include "rtcpeerconnection.h" #include "rtcsessiondescription.h" #include "rtcdatachannel.h" +#include NAN_MODULE_INIT(Init) { if (!Globals::Init()) { return; } + rtc::LogMessage::LogToDebug(rtc::LS_NONE); + //rtc::LogMessage::LogToDebug(rtc::LS_VERBOSE); + RTCCertificate::Init(target); RTCIceCandidate::Init(target); RTCPeerConnection::Init(target); diff --git a/src/observer/peerconnectionobserver.cc b/src/observer/peerconnectionobserver.cc index e252caf..c433afe 100644 --- a/src/observer/peerconnectionobserver.cc +++ b/src/observer/peerconnectionobserver.cc @@ -34,6 +34,7 @@ PeerConnectionObserver::~PeerConnectionObserver() { void PeerConnectionObserver::OnSignalingChange( webrtc::PeerConnectionInterface::SignalingState new_state) { + //std::cout << "OnSignalingChange" << std::endl; EmitterEvent* _event = new EmitterEvent(_eventEmitter); _event->SetType(kSignalingStateChange); Globals::GetEventQueue()->PushEvent(_event); @@ -51,12 +52,14 @@ void PeerConnectionObserver::OnRemoveStream( void PeerConnectionObserver::OnDataChannel( rtc::scoped_refptr data_channel) { + //std::cout << "OnDataChannel" << std::endl; DataChannelEvent* _event = new DataChannelEvent(_eventEmitter, data_channel); _event->SetType(kDataChannel); Globals::GetEventQueue()->PushEvent(_event); } void PeerConnectionObserver::OnRenegotiationNeeded() { + std::cout << "OnRenegotiationNeeded" << std::endl; EmitterEvent* _event = new EmitterEvent(_eventEmitter); _event->SetType(kNegociationNeeded); Globals::GetEventQueue()->PushEvent(_event); @@ -64,6 +67,7 @@ void PeerConnectionObserver::OnRenegotiationNeeded() { void PeerConnectionObserver::OnIceConnectionChange( webrtc::PeerConnectionInterface::IceConnectionState new_state) { + //std::cout << "OnIceConnectionChange" << std::endl; EmitterEvent* _event = new EmitterEvent(_eventEmitter); _event->SetType(kIceConnectionStateChange); Globals::GetEventQueue()->PushEvent(_event); @@ -71,6 +75,27 @@ void PeerConnectionObserver::OnIceConnectionChange( void PeerConnectionObserver::OnIceGatheringChange( webrtc::PeerConnectionInterface::IceGatheringState new_state) { + //std::cout << "OnAddStream" << std::endl; + switch (new_state) { + case webrtc::PeerConnectionInterface::kIceGatheringNew: + break; + + case webrtc::PeerConnectionInterface::kIceGatheringGathering: + break; + + case webrtc::PeerConnectionInterface::kIceGatheringComplete: + { + // emit null ice candidate as per https://www.w3.org/TR/webrtc/#dom-rtcpeerconnectioniceevent + PeerConnectionIceEvent* _iceEvent = new PeerConnectionIceEvent(_eventEmitter); + _iceEvent->SetType(kIceCandidate); + Globals::GetEventQueue()->PushEvent(_iceEvent); + break; + } + + default: + break; + } + EmitterEvent* _event = new EmitterEvent(_eventEmitter); _event->SetType(kIceGatheringStateChange); Globals::GetEventQueue()->PushEvent(_event); @@ -78,6 +103,7 @@ void PeerConnectionObserver::OnIceGatheringChange( void PeerConnectionObserver::OnIceCandidate( const webrtc::IceCandidateInterface *candidate) { + //std::cout << "OnIceCandidate" << std::endl; PeerConnectionIceEvent* _event = new PeerConnectionIceEvent(_eventEmitter); _event->SetType(kIceCandidate); _event->SetCandidate(candidate); diff --git a/src/rtcdatachannel.cc b/src/rtcdatachannel.cc index 16e2ae5..26b83f7 100644 --- a/src/rtcdatachannel.cc +++ b/src/rtcdatachannel.cc @@ -24,6 +24,7 @@ static const char sRTCDataChannel[] = "RTCDataChannel"; static const char kLabel[] = "label"; static const char kOrdered[] = "ordered"; static const char kReadyState[] = "readyState"; +static const char kSend[] = "send"; NAN_MODULE_INIT(RTCDataChannel::Init) { Local ctor = Nan::New(New); @@ -34,6 +35,8 @@ NAN_MODULE_INIT(RTCDataChannel::Init) { Nan::SetAccessor(prototype, LOCAL_STRING(kLabel), GetLabel); Nan::SetAccessor(prototype, LOCAL_STRING(kOrdered), GetOrdered); Nan::SetAccessor(prototype, LOCAL_STRING(kReadyState), GetReadyState); + + Nan::SetMethod(prototype, kSend, Send); constructor().Reset(Nan::GetFunction(ctor).ToLocalChecked()); @@ -76,3 +79,16 @@ NAN_GETTER(RTCDataChannel::GetReadyState) { const char* readyState = webrtc::DataChannelInterface::DataStateString(object->_datachannel->state()); info.GetReturnValue().Set(LOCAL_STRING(readyState)); } + +NAN_METHOD(RTCDataChannel::Send) { + METHOD_HEADER("RTCDataChannel", "send"); + UNWRAP_OBJECT(RTCDataChannel, object); + + // FIXME: implement for ArrayBuffer, others? + ASSERT_STRING_ARGUMENT(0, data); + + webrtc::DataBuffer _buffer(*data); + object->_datachannel->Send(_buffer); + + info.GetReturnValue().Set(Nan::Null()); +} diff --git a/src/rtcdatachannel.h b/src/rtcdatachannel.h index 09c6307..cd13520 100644 --- a/src/rtcdatachannel.h +++ b/src/rtcdatachannel.h @@ -20,10 +20,11 @@ #include #include #include +#include "eventemitter.h" using namespace v8; -class RTCDataChannel : public Nan::ObjectWrap { +class RTCDataChannel : public EventEmitter { public: static NAN_MODULE_INIT(Init); @@ -31,6 +32,8 @@ class RTCDataChannel : public Nan::ObjectWrap { static NAN_GETTER(GetOrdered); static NAN_GETTER(GetReadyState); + static NAN_METHOD(Send); + static Local Create( const rtc::scoped_refptr& datachannel); diff --git a/src/rtcpeerconnection.cc b/src/rtcpeerconnection.cc index 8eace1f..0cc8e3d 100644 --- a/src/rtcpeerconnection.cc +++ b/src/rtcpeerconnection.cc @@ -141,7 +141,6 @@ RTCPeerConnection::RTCPeerConnection( _peerConnectionObserver = PeerConnectionObserver::Create(); _peerConnection = _peerConnectionFactory->CreatePeerConnection( config, &constraints, NULL, NULL, _peerConnectionObserver); - //_peerConnectionObserver->SetPeerConnection(_peerConnection); } RTCPeerConnection::~RTCPeerConnection() { @@ -196,18 +195,9 @@ NAN_METHOD(RTCPeerConnection::New) { RTCPeerConnection *rtcPeerConnection = new RTCPeerConnection(_config, constraints); rtcPeerConnection->Wrap(info.This()); - - // "access" emit function inherited from EventEmitter - //rtcPeerConnection->emit = new Nan::Persistent(v8::Local::Cast(rtcPeerConnection->handle()->Get(Nan::New("emit2").ToLocalChecked()))); - // v8::Local::Cast(rtcPeerConnection->handle()->Get(Nan::New("emit").ToLocalChecked()))); - - //rtcPeerConnection->_peerConnectionObserver->SetEmit(rtcPeerConnection->emit); + rtcPeerConnection->_peerConnectionObserver->SetEventEmitter(rtcPeerConnection); - // rtcPeerConnection->_peerConnectionObserver->SetEmit( - // new Nan::Persistent() - // ); - - + info.GetReturnValue().Set(info.This()); } @@ -283,15 +273,7 @@ NAN_METHOD(RTCPeerConnection::CreateAnswer) { object->_peerConnection->CreateAnswer(observer, &constraints); } -NAN_METHOD(RTCPeerConnection::TestEmit) { - METHOD_HEADER("RTCPeerConnection", "testEmit"); - // UNWRAP_OBJECT(RTCPeerConnection, object); - - // Local argv[] = { Nan::New("test").ToLocalChecked() }; - // Nan::New(*object->emit)->Call(object->handle(), 1, argv); - - info.GetReturnValue().Set(Nan::Null()); -} +// FIXME: factorize SetLocalDescription and SetRemoteDescription NAN_METHOD(RTCPeerConnection::SetLocalDescription) { METHOD_HEADER("RTCPeerConnection", "setLocalDescription"); @@ -299,10 +281,6 @@ NAN_METHOD(RTCPeerConnection::SetLocalDescription) { rtc::scoped_refptr observer; - // Local emit = Nan::New(*object->emit); - // Local argv[] = { Nan::New("test").ToLocalChecked() }; - // emit->Call( object->handle(), 1 , argv ); - // FIXME: Promise implementation only DECLARE_PROMISE_RESOLVER; ASSERT_REJECT_OBJECT_ARGUMENT(0, sessionDescription); @@ -313,7 +291,20 @@ NAN_METHOD(RTCPeerConnection::SetLocalDescription) { observer = SetSessionDescriptionObserver::Create( new Nan::Persistent(resolver)); - object->_peerConnection->SetLocalDescription(observer, _sessionDescription->_sessionDescription); + std::string sdp; + _sessionDescription->_sessionDescription->ToString(&sdp); + std::string type = _sessionDescription->_sessionDescription->type(); + + webrtc::SdpParseError error; + webrtc::SessionDescriptionInterface *desc; + desc = webrtc::CreateSessionDescription(type, sdp, &error); + + if (!desc) { + errorStream << error.description; + return Nan::ThrowTypeError(errorStream.str().c_str()); + } + + object->_peerConnection->SetLocalDescription(observer, desc); } NAN_METHOD(RTCPeerConnection::SetRemoteDescription) { @@ -332,7 +323,21 @@ NAN_METHOD(RTCPeerConnection::SetRemoteDescription) { observer = SetSessionDescriptionObserver::Create( new Nan::Persistent(resolver)); - object->_peerConnection->SetRemoteDescription(observer, _sessionDescription->_sessionDescription); + std::string sdp; + _sessionDescription->_sessionDescription->ToString(&sdp); + std::string type = _sessionDescription->_sessionDescription->type(); + + webrtc::SdpParseError error; + webrtc::SessionDescriptionInterface *desc; + desc = webrtc::CreateSessionDescription(type, sdp, &error); + + if (!desc) { + errorStream << error.description; + return Nan::ThrowTypeError(errorStream.str().c_str()); + } + + object->_peerConnection->SetRemoteDescription(observer, desc); + } NAN_METHOD(RTCPeerConnection::CreateDataChannel) { @@ -352,6 +357,7 @@ NAN_METHOD(RTCPeerConnection::CreateDataChannel) { } NAN_GETTER(RTCPeerConnection::GetConnectionState) { + // FIXME: implement info.GetReturnValue().Set(LOCAL_STRING("new")); } diff --git a/src/rtcpeerconnection.h b/src/rtcpeerconnection.h index faa9fc2..43ddce8 100644 --- a/src/rtcpeerconnection.h +++ b/src/rtcpeerconnection.h @@ -42,8 +42,7 @@ class RTCPeerConnection : public EventEmitter { static NAN_METHOD(SetRemoteDescription); static NAN_METHOD(CreateDataChannel); static NAN_METHOD(GenerateCertificate); - static NAN_METHOD(TestEmit); - + static NAN_GETTER(GetConnectionState); static NAN_GETTER(GetCurrentLocalDescription); static NAN_GETTER(GetCurrentRemoteDescription); From e87ea2a367f1b6ed5baa0a53493fd61212dde435 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Charmet?= Date: Fri, 24 Mar 2017 16:48:36 +0100 Subject: [PATCH 13/20] reworked fix on session descriptions --- src/rtcpeerconnection.cc | 37 ++++++------------------------------ src/rtcsessiondescription.cc | 10 ++++++++++ src/rtcsessiondescription.h | 8 +++++--- 3 files changed, 21 insertions(+), 34 deletions(-) diff --git a/src/rtcpeerconnection.cc b/src/rtcpeerconnection.cc index 0cc8e3d..0ba220c 100644 --- a/src/rtcpeerconnection.cc +++ b/src/rtcpeerconnection.cc @@ -286,25 +286,13 @@ NAN_METHOD(RTCPeerConnection::SetLocalDescription) { ASSERT_REJECT_OBJECT_ARGUMENT(0, sessionDescription); // FIXME: validate it's a RTCSessionDescription object - RTCSessionDescription* _sessionDescription = Nan::ObjectWrap::Unwrap(sessionDescription); + RTCSessionDescription* _sessionDescription; + _sessionDescription = Nan::ObjectWrap::Unwrap(sessionDescription); observer = SetSessionDescriptionObserver::Create( new Nan::Persistent(resolver)); - std::string sdp; - _sessionDescription->_sessionDescription->ToString(&sdp); - std::string type = _sessionDescription->_sessionDescription->type(); - - webrtc::SdpParseError error; - webrtc::SessionDescriptionInterface *desc; - desc = webrtc::CreateSessionDescription(type, sdp, &error); - - if (!desc) { - errorStream << error.description; - return Nan::ThrowTypeError(errorStream.str().c_str()); - } - - object->_peerConnection->SetLocalDescription(observer, desc); + object->_peerConnection->SetLocalDescription(observer, _sessionDescription->session_description()); } NAN_METHOD(RTCPeerConnection::SetRemoteDescription) { @@ -318,26 +306,13 @@ NAN_METHOD(RTCPeerConnection::SetRemoteDescription) { ASSERT_REJECT_OBJECT_ARGUMENT(0, sessionDescription); // FIXME: validate it's a RTCSessionDescription object - RTCSessionDescription* _sessionDescription = Nan::ObjectWrap::Unwrap(sessionDescription); + RTCSessionDescription* _sessionDescription; + _sessionDescription = Nan::ObjectWrap::Unwrap(sessionDescription); observer = SetSessionDescriptionObserver::Create( new Nan::Persistent(resolver)); - std::string sdp; - _sessionDescription->_sessionDescription->ToString(&sdp); - std::string type = _sessionDescription->_sessionDescription->type(); - - webrtc::SdpParseError error; - webrtc::SessionDescriptionInterface *desc; - desc = webrtc::CreateSessionDescription(type, sdp, &error); - - if (!desc) { - errorStream << error.description; - return Nan::ThrowTypeError(errorStream.str().c_str()); - } - - object->_peerConnection->SetRemoteDescription(observer, desc); - + object->_peerConnection->SetRemoteDescription(observer, _sessionDescription->session_description()); } NAN_METHOD(RTCPeerConnection::CreateDataChannel) { diff --git a/src/rtcsessiondescription.cc b/src/rtcsessiondescription.cc index d0bb36f..bbcc346 100644 --- a/src/rtcsessiondescription.cc +++ b/src/rtcsessiondescription.cc @@ -52,6 +52,16 @@ RTCSessionDescription::~RTCSessionDescription() { delete _sessionDescription; } +webrtc::SessionDescriptionInterface* RTCSessionDescription::session_description() { + std::string sdp; + _sessionDescription->ToString(&sdp); + std::string type = _sessionDescription->type(); + + // FIXME: handle error... + webrtc::SdpParseError error; + return webrtc::CreateSessionDescription(type, sdp, &error); +} + Local RTCSessionDescription::Create(const std::string &type, const std::string &sdp) { Local cons = Nan::New(RTCSessionDescription::constructor()); diff --git a/src/rtcsessiondescription.h b/src/rtcsessiondescription.h index 334099f..8842572 100644 --- a/src/rtcsessiondescription.h +++ b/src/rtcsessiondescription.h @@ -28,7 +28,7 @@ class RTCSessionDescription : public Nan::ObjectWrap { static NAN_MODULE_INIT(Init); static Local Create(const std::string& type, const std::string &sdp); - + static inline Nan::Persistent& constructor() { static Nan::Persistent _constructor; return _constructor; @@ -42,13 +42,15 @@ class RTCSessionDescription : public Nan::ObjectWrap { static const char kPranswer[]; static const char kRollback[]; - webrtc::SessionDescriptionInterface *_sessionDescription; + webrtc::SessionDescriptionInterface* session_description(); private: explicit RTCSessionDescription( - webrtc::SessionDescriptionInterface *sessionDescription); + webrtc::SessionDescriptionInterface* sessionDescription); ~RTCSessionDescription(); + webrtc::SessionDescriptionInterface* _sessionDescription; + static NAN_METHOD(New); static NAN_GETTER(GetType); From 7b0c71545190aa139c65553ada53c668f251ea8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Charmet?= Date: Thu, 11 May 2017 15:06:17 +0200 Subject: [PATCH 14/20] attempt at datachannelobserver --- binding.gyp | 2 + src/event/messageevent.cc | 40 +++++++++++++++++ src/event/messageevent.h | 38 ++++++++++++++++ src/observer/datachannelobserver.cc | 65 +++++++++++++++++++++++++++ src/observer/datachannelobserver.h | 50 +++++++++++++++++++++ src/observer/peerconnectionobserver.h | 1 - src/rtcdatachannel.cc | 8 +++- src/rtcdatachannel.h | 6 ++- src/rtcpeerconnection.cc | 4 +- 9 files changed, 209 insertions(+), 5 deletions(-) create mode 100644 src/event/messageevent.cc create mode 100644 src/event/messageevent.h create mode 100644 src/observer/datachannelobserver.cc create mode 100644 src/observer/datachannelobserver.h diff --git a/binding.gyp b/binding.gyp index 6077186..8e6afa5 100644 --- a/binding.gyp +++ b/binding.gyp @@ -8,6 +8,7 @@ 'src/event/emitterevent.cc', 'src/event/peerconnectioniceevent.cc', 'src/event/datachannelevent.cc', + 'src/event/messageevent.cc', 'src/event/eventqueue.cc', 'src/globals.cc', 'src/module.cc', @@ -15,6 +16,7 @@ 'src/observer/createsessiondescriptionobserver.cc', 'src/observer/setsessiondescriptionobserver.cc', 'src/observer/peerconnectionobserver.cc', + 'src/observer/datachannelobserver.cc', 'src/rtccertificate.cc', 'src/rtcicecandidate.cc', 'src/rtcpeerconnection.cc', diff --git a/src/event/messageevent.cc b/src/event/messageevent.cc new file mode 100644 index 0000000..b43b350 --- /dev/null +++ b/src/event/messageevent.cc @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2017 Axel Isouard + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "common.h" +#include "messageevent.h" +#include "eventemitter.h" + +using namespace v8; + +static const char kData[] = "data"; + +MessageEvent::MessageEvent(EventEmitter *eventEmitter) + : EmitterEvent(eventEmitter){ +} + +void MessageEvent::Handle() { + Nan::HandleScope scope; + + // FIXME: make proper MessageData ? + Local e = Nan::New(); + e->Set(LOCAL_STRING(kData), LOCAL_STRING(_data)); + _eventEmitter->EmitData(LOCAL_STRING(_type),e); +} + +void MessageEvent::SetData(const std::string& data) { + _data = data; +} diff --git a/src/event/messageevent.h b/src/event/messageevent.h new file mode 100644 index 0000000..a342029 --- /dev/null +++ b/src/event/messageevent.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2017 Axel Isouard + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef EVENT_MESSAGEEVENT_H_ +#define EVENT_MESSAGEEVENT_H_ + +#include "emitterevent.h" +#include "eventemitter.h" +#include + +using namespace v8; + +class MessageEvent : public EmitterEvent { + public: + explicit MessageEvent(EventEmitter *eventEmitter); + + void Handle(); + void SetData(const std::string& data); + + private: + std::string _data; + +}; + +#endif // EVENT_MESSAGEEVENT_H_ diff --git a/src/observer/datachannelobserver.cc b/src/observer/datachannelobserver.cc new file mode 100644 index 0000000..447230d --- /dev/null +++ b/src/observer/datachannelobserver.cc @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2017 Axel Isouard + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include "datachannelobserver.h" +#include "event/messageevent.h" +#include "globals.h" + +static const char kMessage[] = "message"; + +DataChannelObserver::DataChannelObserver() { +} + +DataChannelObserver::~DataChannelObserver() { + _eventEmitter = NULL; +} + +void DataChannelObserver::OnStateChange() { + std::cout << "DataChannel OnStateChange" << std::endl; + // TODO +} + +void DataChannelObserver::OnMessage(const webrtc::DataBuffer& buffer){ + std::cout << "DataChannel OnMessage" << std::endl; + + MessageEvent* _event = new MessageEvent(_eventEmitter); + _event->SetType(kMessage); + + rtc::CopyOnWriteBuffer data = buffer.data; + std::string _data((char *)data.data());; + + std::cout << "message : " << _data << std::endl; + + _event->SetData(_data); + Globals::GetEventQueue()->PushEvent(_event); + // TODO +} + +void DataChannelObserver::OnBufferedAmountChange(uint64_t previous_amount){ + std::cout << "DataChannel OnBufferedAmountChange" << std::endl; + // TODO +} + +DataChannelObserver *DataChannelObserver::Create() { + return new rtc::RefCountedObject(); +} + +void DataChannelObserver::SetEventEmitter( + EventEmitter* eventEmitter) { + _eventEmitter = eventEmitter; +} diff --git a/src/observer/datachannelobserver.h b/src/observer/datachannelobserver.h new file mode 100644 index 0000000..f8a3a14 --- /dev/null +++ b/src/observer/datachannelobserver.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2017 Axel Isouard + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OBSERVER_DATACHANNELOBSERVER_H_ +#define OBSERVER_DATACHANNELOBSERVER_H_ + +#include +#include "event/emitterevent.h" + +using namespace v8; + +class DataChannelObserver : public rtc::RefCountInterface, + public webrtc::DataChannelObserver { + public: + static DataChannelObserver *Create(); + + void SetEventEmitter( + EventEmitter* eventEmitter); + + // The data channel state have changed. + void OnStateChange(); + + // A data buffer was successfully received. + void OnMessage(const webrtc::DataBuffer& buffer); + + // The data channel's buffered_amount has changed. + void OnBufferedAmountChange(uint64_t previous_amount); + + private: + EventEmitter* _eventEmitter; + + protected: + DataChannelObserver(); + ~DataChannelObserver(); +}; + +#endif // OBSERVER_DATACHANNELOBSERVER_H_ diff --git a/src/observer/peerconnectionobserver.h b/src/observer/peerconnectionobserver.h index 2be6e4d..c848be5 100644 --- a/src/observer/peerconnectionobserver.h +++ b/src/observer/peerconnectionobserver.h @@ -18,7 +18,6 @@ #define OBSERVER_PEERCONNECTIONOBSERVER_H_ #include -#include #include "event/emitterevent.h" #include "event/peerconnectioniceevent.h" #include "event/datachannelevent.h" diff --git a/src/rtcdatachannel.cc b/src/rtcdatachannel.cc index 26b83f7..849ea3e 100644 --- a/src/rtcdatachannel.cc +++ b/src/rtcdatachannel.cc @@ -16,6 +16,7 @@ #include #include +#include "observer/datachannelobserver.h" #include "rtcdatachannel.h" #include "common.h" @@ -46,6 +47,10 @@ NAN_MODULE_INIT(RTCDataChannel::Init) { RTCDataChannel::RTCDataChannel( const rtc::scoped_refptr &datachannel) : _datachannel(datachannel) { + + _datachannelObserver = DataChannelObserver::Create(); + datachannel->RegisterObserver(_datachannelObserver); + } RTCDataChannel::~RTCDataChannel() {} @@ -57,7 +62,8 @@ Local RTCDataChannel::Create( RTCDataChannel *_datachannel = new RTCDataChannel(datachannel); _datachannel->Wrap(instance); - + _datachannel->_datachannelObserver->SetEventEmitter(_datachannel); + return instance; } diff --git a/src/rtcdatachannel.h b/src/rtcdatachannel.h index cd13520..f87700d 100644 --- a/src/rtcdatachannel.h +++ b/src/rtcdatachannel.h @@ -21,6 +21,7 @@ #include #include #include "eventemitter.h" +#include "observer/datachannelobserver.h" using namespace v8; @@ -43,7 +44,7 @@ class RTCDataChannel : public EventEmitter { } const rtc::scoped_refptr _datachannel; - + private: explicit RTCDataChannel( const rtc::scoped_refptr& datachannel); @@ -51,6 +52,9 @@ class RTCDataChannel : public EventEmitter { static NAN_METHOD(New); + protected: + rtc::scoped_refptr _datachannelObserver; + }; #endif // RTCDATACHANNEL_H_ diff --git a/src/rtcpeerconnection.cc b/src/rtcpeerconnection.cc index 0ba220c..e65e940 100644 --- a/src/rtcpeerconnection.cc +++ b/src/rtcpeerconnection.cc @@ -323,9 +323,9 @@ NAN_METHOD(RTCPeerConnection::CreateDataChannel) { // FIXME: add init options const webrtc::DataChannelInit init; - + rtc::scoped_refptr _channel = object->_peerConnection->CreateDataChannel(*name, &init); - + Local datachannel = RTCDataChannel::Create(_channel); info.GetReturnValue().Set(datachannel); From cc98332ac060c9190869021ccd4cc8825573a9bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Charmet?= Date: Thu, 11 May 2017 16:21:06 +0200 Subject: [PATCH 15/20] fixed bug with remote DataChannel + message buffer --- src/event/datachannelevent.cc | 5 +++-- src/observer/datachannelobserver.cc | 6 +----- src/rtcdatachannel.cc | 7 +++++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/event/datachannelevent.cc b/src/event/datachannelevent.cc index 1b6cffd..4ffa209 100644 --- a/src/event/datachannelevent.cc +++ b/src/event/datachannelevent.cc @@ -33,8 +33,9 @@ void DataChannelEvent::Handle() { // FIXME: make proper DataChannelEvent ? Local e = Nan::New(); - e->Set(LOCAL_STRING(kChannel), - RTCDataChannel::Create(_channel)); + // FIXME: move to observer ? + Nan::Persistent channel(RTCDataChannel::Create(_channel)); + e->Set(LOCAL_STRING(kChannel), Nan::New(channel)); _eventEmitter->EmitData(LOCAL_STRING(_type),e); } diff --git a/src/observer/datachannelobserver.cc b/src/observer/datachannelobserver.cc index 447230d..d44413b 100644 --- a/src/observer/datachannelobserver.cc +++ b/src/observer/datachannelobserver.cc @@ -35,16 +35,12 @@ void DataChannelObserver::OnStateChange() { } void DataChannelObserver::OnMessage(const webrtc::DataBuffer& buffer){ - std::cout << "DataChannel OnMessage" << std::endl; - MessageEvent* _event = new MessageEvent(_eventEmitter); _event->SetType(kMessage); rtc::CopyOnWriteBuffer data = buffer.data; - std::string _data((char *)data.data());; + std::string _data((char *)data.data(), data.size());; - std::cout << "message : " << _data << std::endl; - _event->SetData(_data); Globals::GetEventQueue()->PushEvent(_event); // TODO diff --git a/src/rtcdatachannel.cc b/src/rtcdatachannel.cc index 849ea3e..2d472b9 100644 --- a/src/rtcdatachannel.cc +++ b/src/rtcdatachannel.cc @@ -49,11 +49,14 @@ RTCDataChannel::RTCDataChannel( : _datachannel(datachannel) { _datachannelObserver = DataChannelObserver::Create(); - datachannel->RegisterObserver(_datachannelObserver); + _datachannel->RegisterObserver(_datachannelObserver); } -RTCDataChannel::~RTCDataChannel() {} +RTCDataChannel::~RTCDataChannel() { + _datachannel->UnregisterObserver(); + _datachannelObserver = NULL; +} Local RTCDataChannel::Create( const rtc::scoped_refptr &datachannel) { From b0e4cb796b394dc75441eaaeaa7c60f81477b88c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Charmet?= Date: Thu, 11 May 2017 17:26:25 +0200 Subject: [PATCH 16/20] lint --- src/event/datachannelevent.cc | 8 +-- src/event/datachannelevent.h | 7 ++- src/event/emitterevent.cc | 10 ++-- src/event/emitterevent.h | 7 ++- src/event/messageevent.cc | 7 ++- src/event/messageevent.h | 5 +- src/event/peerconnectioniceevent.cc | 15 +++--- src/event/peerconnectioniceevent.h | 6 +-- src/event/setsessiondescriptionevent.cc | 2 +- src/event/setsessiondescriptionevent.h | 2 +- src/eventemitter.cc | 10 ++-- src/eventemitter.h | 9 ++-- src/module.cc | 2 +- .../createsessiondescriptionobserver.h | 2 +- src/observer/datachannelobserver.cc | 9 ++-- src/observer/datachannelobserver.h | 2 +- src/observer/peerconnectionobserver.cc | 13 ++--- src/rtccertificate.h | 2 +- src/rtcdatachannel.cc | 8 +-- src/rtcdatachannel.h | 3 +- src/rtcicecandidate.cc | 23 ++++---- src/rtcicecandidate.h | 4 +- src/rtcpeerconnection.cc | 52 +++++++++++-------- src/rtcpeerconnection.h | 4 +- src/rtcsessiondescription.cc | 5 +- src/rtcsessiondescription.h | 2 +- 26 files changed, 109 insertions(+), 110 deletions(-) diff --git a/src/event/datachannelevent.cc b/src/event/datachannelevent.cc index 4ffa209..1beecfd 100644 --- a/src/event/datachannelevent.cc +++ b/src/event/datachannelevent.cc @@ -23,8 +23,8 @@ using namespace v8; static const char kChannel[] = "channel"; -DataChannelEvent::DataChannelEvent(EventEmitter *eventEmitter, - const rtc::scoped_refptr &datachannel) +DataChannelEvent::DataChannelEvent(EventEmitter *eventEmitter, + const rtc::scoped_refptr &datachannel) : EmitterEvent(eventEmitter), _channel(datachannel) { } @@ -36,6 +36,6 @@ void DataChannelEvent::Handle() { // FIXME: move to observer ? Nan::Persistent channel(RTCDataChannel::Create(_channel)); e->Set(LOCAL_STRING(kChannel), Nan::New(channel)); - - _eventEmitter->EmitData(LOCAL_STRING(_type),e); + + _eventEmitter->EmitData(LOCAL_STRING(_type), e); } diff --git a/src/event/datachannelevent.h b/src/event/datachannelevent.h index 4f68696..7780d06 100644 --- a/src/event/datachannelevent.h +++ b/src/event/datachannelevent.h @@ -26,14 +26,13 @@ using namespace v8; class DataChannelEvent : public EmitterEvent { public: - explicit DataChannelEvent(EventEmitter *eventEmitter, + explicit DataChannelEvent(EventEmitter *eventEmitter, const rtc::scoped_refptr& datachannel); - + void Handle(); - + private: const rtc::scoped_refptr _channel; - }; #endif // EVENT_DATACHANNELEVENT_H_ diff --git a/src/event/emitterevent.cc b/src/event/emitterevent.cc index 215b66b..737ac41 100644 --- a/src/event/emitterevent.cc +++ b/src/event/emitterevent.cc @@ -19,16 +19,14 @@ using namespace v8; -EmitterEvent::EmitterEvent( EventEmitter *eventEmitter ) : - _eventEmitter(eventEmitter) { -} +EmitterEvent::EmitterEvent(EventEmitter *eventEmitter) + : _eventEmitter(eventEmitter) {} void EmitterEvent::Handle() { Nan::HandleScope scope; _eventEmitter->Emit(LOCAL_STRING(_type)); } -void EmitterEvent::SetType( - const std::string &type) { +void EmitterEvent::SetType(const std::string &type) { _type = type; -} \ No newline at end of file +} diff --git a/src/event/emitterevent.h b/src/event/emitterevent.h index daf8df1..acc735a 100644 --- a/src/event/emitterevent.h +++ b/src/event/emitterevent.h @@ -24,15 +24,14 @@ using namespace v8; class EmitterEvent : public Event { public: - explicit EmitterEvent( EventEmitter *eventEmitter ); - + explicit EmitterEvent(EventEmitter *eventEmitter); + void Handle(); void SetType(const std::string& type); - + protected: EventEmitter *_eventEmitter; std::string _type; - }; #endif // EVENT_EMITTEREVENT_H_ diff --git a/src/event/messageevent.cc b/src/event/messageevent.cc index b43b350..16f88fe 100644 --- a/src/event/messageevent.cc +++ b/src/event/messageevent.cc @@ -22,9 +22,8 @@ using namespace v8; static const char kData[] = "data"; -MessageEvent::MessageEvent(EventEmitter *eventEmitter) - : EmitterEvent(eventEmitter){ -} +MessageEvent::MessageEvent(EventEmitter *eventEmitter) + : EmitterEvent(eventEmitter) {} void MessageEvent::Handle() { Nan::HandleScope scope; @@ -32,7 +31,7 @@ void MessageEvent::Handle() { // FIXME: make proper MessageData ? Local e = Nan::New(); e->Set(LOCAL_STRING(kData), LOCAL_STRING(_data)); - _eventEmitter->EmitData(LOCAL_STRING(_type),e); + _eventEmitter->EmitData(LOCAL_STRING(_type), e); } void MessageEvent::SetData(const std::string& data) { diff --git a/src/event/messageevent.h b/src/event/messageevent.h index a342029..f8f1d04 100644 --- a/src/event/messageevent.h +++ b/src/event/messageevent.h @@ -26,13 +26,12 @@ using namespace v8; class MessageEvent : public EmitterEvent { public: explicit MessageEvent(EventEmitter *eventEmitter); - + void Handle(); void SetData(const std::string& data); - + private: std::string _data; - }; #endif // EVENT_MESSAGEEVENT_H_ diff --git a/src/event/peerconnectioniceevent.cc b/src/event/peerconnectioniceevent.cc index 5c35940..db3e2ac 100644 --- a/src/event/peerconnectioniceevent.cc +++ b/src/event/peerconnectioniceevent.cc @@ -26,7 +26,7 @@ using namespace v8; static const char kCandidate[] = "candidate"; -PeerConnectionIceEvent::PeerConnectionIceEvent(EventEmitter *eventEmitter) +PeerConnectionIceEvent::PeerConnectionIceEvent(EventEmitter *eventEmitter) : EmitterEvent(eventEmitter) { } @@ -35,18 +35,19 @@ void PeerConnectionIceEvent::Handle() { // FIXME: make proper PeerConnectionIceEvent ? Local e = Nan::New(); - - if(_candidate.length() && _sdpMid.length()) { - e->Set(LOCAL_STRING(kCandidate), + + if (_candidate.length() && _sdpMid.length()) { + e->Set(LOCAL_STRING(kCandidate), RTCIceCandidate::Create(_sdpMid, _sdpMLineIndex, _candidate)); } else { e->Set(LOCAL_STRING(kCandidate), Nan::Null()); } - - _eventEmitter->EmitData(LOCAL_STRING(_type),e); + + _eventEmitter->EmitData(LOCAL_STRING(_type), e); } -void PeerConnectionIceEvent::SetCandidate(const webrtc::IceCandidateInterface* candidate) { +void PeerConnectionIceEvent::SetCandidate( + const webrtc::IceCandidateInterface* candidate) { candidate->ToString(&_candidate); _sdpMid = candidate->sdp_mid(); _sdpMLineIndex = candidate->sdp_mline_index(); diff --git a/src/event/peerconnectioniceevent.h b/src/event/peerconnectioniceevent.h index 65bd86e..72c134c 100644 --- a/src/event/peerconnectioniceevent.h +++ b/src/event/peerconnectioniceevent.h @@ -26,16 +26,14 @@ using namespace v8; class PeerConnectionIceEvent : public EmitterEvent { public: explicit PeerConnectionIceEvent(EventEmitter *eventEmitter); - + void Handle(); void SetCandidate(const webrtc::IceCandidateInterface* candidate); - + private: std::string _candidate; std::string _sdpMid; int _sdpMLineIndex = 0; - //std::string _ufrag; - }; #endif // EVENT_PEERCONNECTIONICEEVENT_H_ diff --git a/src/event/setsessiondescriptionevent.cc b/src/event/setsessiondescriptionevent.cc index 23638e4..4c909ed 100644 --- a/src/event/setsessiondescriptionevent.cc +++ b/src/event/setsessiondescriptionevent.cc @@ -57,7 +57,7 @@ void SetSessionDescriptionEvent::Handle() { if (_succeeded && _successCallback) { Local successCallback = Nan::New(*_successCallback); Nan::Callback cb(successCallback); - + const int argc = 0; Local argv[0] = {}; diff --git a/src/event/setsessiondescriptionevent.h b/src/event/setsessiondescriptionevent.h index ad185a5..88fb615 100644 --- a/src/event/setsessiondescriptionevent.h +++ b/src/event/setsessiondescriptionevent.h @@ -33,7 +33,7 @@ class SetSessionDescriptionEvent : public Event { void Handle(); void SetSucceeded(bool succeeded); void SetErrorMessage(const std::string& errorMessage); - + private: Persistent *_resolver; Persistent *_successCallback; diff --git a/src/eventemitter.cc b/src/eventemitter.cc index 26f6365..1e462e4 100644 --- a/src/eventemitter.cc +++ b/src/eventemitter.cc @@ -21,22 +21,22 @@ using namespace v8; static const char kEmit[] = "emit"; -EventEmitter::EventEmitter(){}; +EventEmitter::EventEmitter() {} -void EventEmitter::Wrap( Local obj ){ - Nan::ObjectWrap::Wrap( obj ); +void EventEmitter::Wrap(Local obj) { + Nan::ObjectWrap::Wrap(obj); _emit = new Nan::Persistent( Local::Cast(handle()->Get(Nan::New(kEmit).ToLocalChecked()))); } -void EventEmitter::Emit( Local type ){ +void EventEmitter::Emit(Local type) { Nan::HandleScope scope; Local argv[] = { type }; Local emit = Nan::New(*_emit); emit->Call(handle(), 1, argv); } -void EventEmitter::EmitData( Local type, Local data ){ +void EventEmitter::EmitData(Local type, Local data) { Nan::HandleScope scope; Local argv[] = { type, data }; Local emit = Nan::New(*_emit); diff --git a/src/eventemitter.h b/src/eventemitter.h index 5ef06ed..174c84c 100644 --- a/src/eventemitter.h +++ b/src/eventemitter.h @@ -24,13 +24,12 @@ using namespace v8; class EventEmitter : public Nan::ObjectWrap { public: - explicit EventEmitter(); + EventEmitter(); Persistent* _emit = nullptr; - void Wrap( Local obj ); - void Emit( Local type ); - void EmitData( Local type, Local data ); - + void Wrap(Local obj); + void Emit(Local type); + void EmitData(Local type, Local data); }; #endif // EVENTEMITTER_H_ diff --git a/src/module.cc b/src/module.cc index 2628c96..b726e2c 100644 --- a/src/module.cc +++ b/src/module.cc @@ -30,7 +30,7 @@ NAN_MODULE_INIT(Init) { } rtc::LogMessage::LogToDebug(rtc::LS_NONE); - //rtc::LogMessage::LogToDebug(rtc::LS_VERBOSE); + // rtc::LogMessage::LogToDebug(rtc::LS_VERBOSE); RTCCertificate::Init(target); RTCIceCandidate::Init(target); diff --git a/src/observer/createsessiondescriptionobserver.h b/src/observer/createsessiondescriptionobserver.h index feda2a2..287c51b 100644 --- a/src/observer/createsessiondescriptionobserver.h +++ b/src/observer/createsessiondescriptionobserver.h @@ -47,4 +47,4 @@ class CreateSessionDescriptionObserver : Persistent *failureCallback); }; -#endif // OBSERVER_SETSESSIONDESCRIPTIONOBSERVER_H_ +#endif // OBSERVER_CREATESESSIONDESCRIPTIONOBSERVER_H_ diff --git a/src/observer/datachannelobserver.cc b/src/observer/datachannelobserver.cc index d44413b..011977d 100644 --- a/src/observer/datachannelobserver.cc +++ b/src/observer/datachannelobserver.cc @@ -31,24 +31,21 @@ DataChannelObserver::~DataChannelObserver() { void DataChannelObserver::OnStateChange() { std::cout << "DataChannel OnStateChange" << std::endl; - // TODO } -void DataChannelObserver::OnMessage(const webrtc::DataBuffer& buffer){ +void DataChannelObserver::OnMessage(const webrtc::DataBuffer& buffer) { MessageEvent* _event = new MessageEvent(_eventEmitter); _event->SetType(kMessage); rtc::CopyOnWriteBuffer data = buffer.data; - std::string _data((char *)data.data(), data.size());; + std::string _data(reinterpret_cast(data.data()), data.size());; _event->SetData(_data); Globals::GetEventQueue()->PushEvent(_event); - // TODO } -void DataChannelObserver::OnBufferedAmountChange(uint64_t previous_amount){ +void DataChannelObserver::OnBufferedAmountChange(uint64_t previous_amount) { std::cout << "DataChannel OnBufferedAmountChange" << std::endl; - // TODO } DataChannelObserver *DataChannelObserver::Create() { diff --git a/src/observer/datachannelobserver.h b/src/observer/datachannelobserver.h index f8a3a14..8a4df6d 100644 --- a/src/observer/datachannelobserver.h +++ b/src/observer/datachannelobserver.h @@ -35,7 +35,7 @@ class DataChannelObserver : public rtc::RefCountInterface, // A data buffer was successfully received. void OnMessage(const webrtc::DataBuffer& buffer); - + // The data channel's buffered_amount has changed. void OnBufferedAmountChange(uint64_t previous_amount); diff --git a/src/observer/peerconnectionobserver.cc b/src/observer/peerconnectionobserver.cc index c433afe..d1cdaaa 100644 --- a/src/observer/peerconnectionobserver.cc +++ b/src/observer/peerconnectionobserver.cc @@ -34,7 +34,6 @@ PeerConnectionObserver::~PeerConnectionObserver() { void PeerConnectionObserver::OnSignalingChange( webrtc::PeerConnectionInterface::SignalingState new_state) { - //std::cout << "OnSignalingChange" << std::endl; EmitterEvent* _event = new EmitterEvent(_eventEmitter); _event->SetType(kSignalingStateChange); Globals::GetEventQueue()->PushEvent(_event); @@ -52,14 +51,12 @@ void PeerConnectionObserver::OnRemoveStream( void PeerConnectionObserver::OnDataChannel( rtc::scoped_refptr data_channel) { - //std::cout << "OnDataChannel" << std::endl; DataChannelEvent* _event = new DataChannelEvent(_eventEmitter, data_channel); _event->SetType(kDataChannel); Globals::GetEventQueue()->PushEvent(_event); } void PeerConnectionObserver::OnRenegotiationNeeded() { - std::cout << "OnRenegotiationNeeded" << std::endl; EmitterEvent* _event = new EmitterEvent(_eventEmitter); _event->SetType(kNegociationNeeded); Globals::GetEventQueue()->PushEvent(_event); @@ -67,7 +64,6 @@ void PeerConnectionObserver::OnRenegotiationNeeded() { void PeerConnectionObserver::OnIceConnectionChange( webrtc::PeerConnectionInterface::IceConnectionState new_state) { - //std::cout << "OnIceConnectionChange" << std::endl; EmitterEvent* _event = new EmitterEvent(_eventEmitter); _event->SetType(kIceConnectionStateChange); Globals::GetEventQueue()->PushEvent(_event); @@ -75,7 +71,6 @@ void PeerConnectionObserver::OnIceConnectionChange( void PeerConnectionObserver::OnIceGatheringChange( webrtc::PeerConnectionInterface::IceGatheringState new_state) { - //std::cout << "OnAddStream" << std::endl; switch (new_state) { case webrtc::PeerConnectionInterface::kIceGatheringNew: break; @@ -85,8 +80,10 @@ void PeerConnectionObserver::OnIceGatheringChange( case webrtc::PeerConnectionInterface::kIceGatheringComplete: { - // emit null ice candidate as per https://www.w3.org/TR/webrtc/#dom-rtcpeerconnectioniceevent - PeerConnectionIceEvent* _iceEvent = new PeerConnectionIceEvent(_eventEmitter); + // emit null ice candidate + // as per https://www.w3.org/TR/webrtc/#dom-rtcpeerconnectioniceevent + PeerConnectionIceEvent* _iceEvent + = new PeerConnectionIceEvent(_eventEmitter); _iceEvent->SetType(kIceCandidate); Globals::GetEventQueue()->PushEvent(_iceEvent); break; @@ -103,12 +100,10 @@ void PeerConnectionObserver::OnIceGatheringChange( void PeerConnectionObserver::OnIceCandidate( const webrtc::IceCandidateInterface *candidate) { - //std::cout << "OnIceCandidate" << std::endl; PeerConnectionIceEvent* _event = new PeerConnectionIceEvent(_eventEmitter); _event->SetType(kIceCandidate); _event->SetCandidate(candidate); Globals::GetEventQueue()->PushEvent(_event); - } void PeerConnectionObserver::OnIceCandidatesRemoved( diff --git a/src/rtccertificate.h b/src/rtccertificate.h index e44a41a..8197475 100644 --- a/src/rtccertificate.h +++ b/src/rtccertificate.h @@ -45,7 +45,7 @@ class RTCCertificate : public Nan::ObjectWrap { private: explicit RTCCertificate( - const rtc::scoped_refptr& certificate); + const rtc::scoped_refptr& certificate); ~RTCCertificate(); static NAN_METHOD(New); diff --git a/src/rtcdatachannel.cc b/src/rtcdatachannel.cc index 2d472b9..928822c 100644 --- a/src/rtcdatachannel.cc +++ b/src/rtcdatachannel.cc @@ -38,7 +38,7 @@ NAN_MODULE_INIT(RTCDataChannel::Init) { Nan::SetAccessor(prototype, LOCAL_STRING(kReadyState), GetReadyState); Nan::SetMethod(prototype, kSend, Send); - + constructor().Reset(Nan::GetFunction(ctor).ToLocalChecked()); Nan::Set(target, LOCAL_STRING(sRTCDataChannel), ctor->GetFunction()); @@ -50,7 +50,6 @@ RTCDataChannel::RTCDataChannel( _datachannelObserver = DataChannelObserver::Create(); _datachannel->RegisterObserver(_datachannelObserver); - } RTCDataChannel::~RTCDataChannel() { @@ -66,7 +65,7 @@ Local RTCDataChannel::Create( RTCDataChannel *_datachannel = new RTCDataChannel(datachannel); _datachannel->Wrap(instance); _datachannel->_datachannelObserver->SetEventEmitter(_datachannel); - + return instance; } @@ -85,7 +84,8 @@ NAN_GETTER(RTCDataChannel::GetOrdered) { NAN_GETTER(RTCDataChannel::GetReadyState) { UNWRAP_OBJECT(RTCDataChannel, object); - const char* readyState = webrtc::DataChannelInterface::DataStateString(object->_datachannel->state()); + const char* readyState = webrtc::DataChannelInterface::DataStateString( + object->_datachannel->state()); info.GetReturnValue().Set(LOCAL_STRING(readyState)); } diff --git a/src/rtcdatachannel.h b/src/rtcdatachannel.h index f87700d..518c8eb 100644 --- a/src/rtcdatachannel.h +++ b/src/rtcdatachannel.h @@ -44,7 +44,7 @@ class RTCDataChannel : public EventEmitter { } const rtc::scoped_refptr _datachannel; - + private: explicit RTCDataChannel( const rtc::scoped_refptr& datachannel); @@ -54,7 +54,6 @@ class RTCDataChannel : public EventEmitter { protected: rtc::scoped_refptr _datachannelObserver; - }; #endif // RTCDATACHANNEL_H_ diff --git a/src/rtcicecandidate.cc b/src/rtcicecandidate.cc index ba08508..136fb56 100644 --- a/src/rtcicecandidate.cc +++ b/src/rtcicecandidate.cc @@ -23,8 +23,6 @@ #include "common.h" #include "rtcicecandidate.h" -//Nan::Persistent RTCIceCandidate::constructor; - static const char sRTCIceCandidate[] = "RTCIceCandidate"; static const char kCandidate[] = "candidate"; @@ -73,22 +71,27 @@ NAN_MODULE_INIT(RTCIceCandidate::Init) { ctor->GetFunction()); } -RTCIceCandidate::RTCIceCandidate(const webrtc::IceCandidateInterface *iceCandidate) - : _iceCandidate(iceCandidate) { +RTCIceCandidate::RTCIceCandidate( + const webrtc::IceCandidateInterface *iceCandidate) + : _iceCandidate(iceCandidate) { } RTCIceCandidate::~RTCIceCandidate() { delete _iceCandidate; } -Local RTCIceCandidate::Create(std::string sdpMid, int sdpMLineIndex, std::string candidate) { +Local RTCIceCandidate::Create( + std::string sdpMid, int sdpMLineIndex, std::string candidate) { Local cons = Nan::New(RTCIceCandidate::constructor()); - + Local candidateInitDict = Nan::New(); - candidateInitDict->Set(LOCAL_STRING(kSdpMid), LOCAL_STRING(sdpMid)); - candidateInitDict->Set(LOCAL_STRING(kSdpMLineIndex), Nan::New(sdpMLineIndex)); - candidateInitDict->Set(LOCAL_STRING(kCandidate), LOCAL_STRING(candidate)); - + candidateInitDict->Set(LOCAL_STRING(kSdpMid), + LOCAL_STRING(sdpMid)); + candidateInitDict->Set(LOCAL_STRING(kSdpMLineIndex), + Nan::New(sdpMLineIndex)); + candidateInitDict->Set(LOCAL_STRING(kCandidate), + LOCAL_STRING(candidate)); + const int argc = 1; Local argv[1] = { candidateInitDict }; Local instance = Nan::NewInstance(cons, argc, argv).ToLocalChecked(); diff --git a/src/rtcicecandidate.h b/src/rtcicecandidate.h index 061e9d8..c113c15 100644 --- a/src/rtcicecandidate.h +++ b/src/rtcicecandidate.h @@ -25,7 +25,9 @@ using namespace v8; class RTCIceCandidate : public Nan::ObjectWrap { public: static NAN_MODULE_INIT(Init); - static Local Create(std::string sdpMid, int sdpMLineIndex, std::string candidate); + static Local Create(std::string sdpMid, + int sdpMLineIndex, + std::string candidate); private: explicit RTCIceCandidate(const webrtc::IceCandidateInterface *iceCandidate); diff --git a/src/rtcpeerconnection.cc b/src/rtcpeerconnection.cc index e65e940..2432967 100644 --- a/src/rtcpeerconnection.cc +++ b/src/rtcpeerconnection.cc @@ -153,14 +153,14 @@ NAN_METHOD(RTCPeerConnection::New) { CONSTRUCTOR_HEADER("RTCPeerConnection") webrtc::FakeConstraints constraints; webrtc::PeerConnectionInterface::RTCConfiguration _config; - + if (info.Length() > 0) { ASSERT_OBJECT_ARGUMENT(0, config); DECLARE_OBJECT_PROPERTY(config, kIceServers, iceServersVal); ASSERT_PROPERTY_ARRAY(kIceServers, iceServersVal, iceServers); - for(unsigned int i = 0; i < iceServers->Length(); i = i + 1) { + for (unsigned int i = 0; i < iceServers->Length(); i = i + 1) { Local iceServerVal = iceServers->Get(i); ASSERT_PROPERTY_OBJECT(kIceServers, iceServerVal, iceServer); @@ -169,7 +169,7 @@ NAN_METHOD(RTCPeerConnection::New) { DECLARE_OBJECT_PROPERTY(iceServer, kIceServerUrls, iceServerUrlsVal); ASSERT_PROPERTY_ARRAY(kIceServerUrls, iceServerUrlsVal, iceServerUrls); - for(unsigned int j = 0; j < iceServerUrls->Length(); j = j + 1) { + for (unsigned int j = 0; j < iceServerUrls->Length(); j = j + 1) { Local iceServerUrlVal = iceServerUrls->Get(j); ASSERT_PROPERTY_STRING(kIceServerUrls, iceServerUrlVal, iceServerUrl); server.urls.push_back(*iceServerUrl); @@ -180,11 +180,13 @@ NAN_METHOD(RTCPeerConnection::New) { DECLARE_OBJECT_PROPERTY(config, kCertificates, certificatesVal); ASSERT_PROPERTY_ARRAY(kCertificates, certificatesVal, certificates); - for(unsigned int i = 0; i < certificates->Length(); i = i + 1) { + for (unsigned int i = 0; i < certificates->Length(); i = i + 1) { Local certificateVal = certificates->Get(i); ASSERT_PROPERTY_OBJECT(kCertificates, certificateVal, certificate); // FIXME: validate it's a RTCCertificate object - RTCCertificate* _certificate = Nan::ObjectWrap::Unwrap(certificate); + RTCCertificate* _certificate + = Nan::ObjectWrap::Unwrap(certificate); + _config.certificates.push_back(_certificate->_certificate); } } @@ -195,9 +197,10 @@ NAN_METHOD(RTCPeerConnection::New) { RTCPeerConnection *rtcPeerConnection = new RTCPeerConnection(_config, constraints); rtcPeerConnection->Wrap(info.This()); - - rtcPeerConnection->_peerConnectionObserver->SetEventEmitter(rtcPeerConnection); - + + rtcPeerConnection->_peerConnectionObserver->SetEventEmitter( + rtcPeerConnection); + info.GetReturnValue().Set(info.This()); } @@ -287,12 +290,14 @@ NAN_METHOD(RTCPeerConnection::SetLocalDescription) { // FIXME: validate it's a RTCSessionDescription object RTCSessionDescription* _sessionDescription; - _sessionDescription = Nan::ObjectWrap::Unwrap(sessionDescription); + _sessionDescription = Nan::ObjectWrap::Unwrap( + sessionDescription); observer = SetSessionDescriptionObserver::Create( - new Nan::Persistent(resolver)); + new Nan::Persistent(resolver)); - object->_peerConnection->SetLocalDescription(observer, _sessionDescription->session_description()); + object->_peerConnection->SetLocalDescription(observer, + _sessionDescription->session_description()); } NAN_METHOD(RTCPeerConnection::SetRemoteDescription) { @@ -307,12 +312,14 @@ NAN_METHOD(RTCPeerConnection::SetRemoteDescription) { // FIXME: validate it's a RTCSessionDescription object RTCSessionDescription* _sessionDescription; - _sessionDescription = Nan::ObjectWrap::Unwrap(sessionDescription); + _sessionDescription = Nan::ObjectWrap::Unwrap( + sessionDescription); observer = SetSessionDescriptionObserver::Create( - new Nan::Persistent(resolver)); + new Nan::Persistent(resolver)); - object->_peerConnection->SetRemoteDescription(observer, _sessionDescription->session_description()); + object->_peerConnection->SetRemoteDescription(observer, + _sessionDescription->session_description()); } NAN_METHOD(RTCPeerConnection::CreateDataChannel) { @@ -323,9 +330,10 @@ NAN_METHOD(RTCPeerConnection::CreateDataChannel) { // FIXME: add init options const webrtc::DataChannelInit init; - - rtc::scoped_refptr _channel = object->_peerConnection->CreateDataChannel(*name, &init); - + + rtc::scoped_refptr _channel + = object->_peerConnection->CreateDataChannel(*name, &init); + Local datachannel = RTCDataChannel::Create(_channel); info.GetReturnValue().Set(datachannel); @@ -344,13 +352,14 @@ NAN_GETTER(RTCPeerConnection::GetLocalDescription) { METHOD_HEADER("RTCPeerConnection", "getLocalDescription"); UNWRAP_OBJECT(RTCPeerConnection, object); - const webrtc::SessionDescriptionInterface *session = object->_peerConnection->local_description(); + const webrtc::SessionDescriptionInterface *session + = object->_peerConnection->local_description(); const std::string type = session->type(); std::string sdp; session->ToString(&sdp); - Local desc = RTCSessionDescription::Create( type, sdp ); + Local desc = RTCSessionDescription::Create(type, sdp); info.GetReturnValue().Set(desc); } @@ -359,13 +368,14 @@ NAN_GETTER(RTCPeerConnection::GetRemoteDescription) { METHOD_HEADER("RTCPeerConnection", "getRemoteDescription"); UNWRAP_OBJECT(RTCPeerConnection, object); - const webrtc::SessionDescriptionInterface *session = object->_peerConnection->remote_description(); + const webrtc::SessionDescriptionInterface *session + = object->_peerConnection->remote_description(); const std::string type = session->type(); std::string sdp; session->ToString(&sdp); - Local desc = RTCSessionDescription::Create( type, sdp ); + Local desc = RTCSessionDescription::Create(type, sdp); info.GetReturnValue().Set(desc); } diff --git a/src/rtcpeerconnection.h b/src/rtcpeerconnection.h index 43ddce8..c23fda9 100644 --- a/src/rtcpeerconnection.h +++ b/src/rtcpeerconnection.h @@ -42,10 +42,10 @@ class RTCPeerConnection : public EventEmitter { static NAN_METHOD(SetRemoteDescription); static NAN_METHOD(CreateDataChannel); static NAN_METHOD(GenerateCertificate); - + static NAN_GETTER(GetConnectionState); static NAN_GETTER(GetCurrentLocalDescription); - static NAN_GETTER(GetCurrentRemoteDescription); + static NAN_GETTER(GetCurrentRemoteDescription); static NAN_GETTER(GetLocalDescription); static NAN_GETTER(GetRemoteDescription); static NAN_GETTER(GetIceConnectionState); diff --git a/src/rtcsessiondescription.cc b/src/rtcsessiondescription.cc index bbcc346..c5eeaaa 100644 --- a/src/rtcsessiondescription.cc +++ b/src/rtcsessiondescription.cc @@ -52,11 +52,12 @@ RTCSessionDescription::~RTCSessionDescription() { delete _sessionDescription; } -webrtc::SessionDescriptionInterface* RTCSessionDescription::session_description() { +webrtc::SessionDescriptionInterface* +RTCSessionDescription::session_description() { std::string sdp; _sessionDescription->ToString(&sdp); std::string type = _sessionDescription->type(); - + // FIXME: handle error... webrtc::SdpParseError error; return webrtc::CreateSessionDescription(type, sdp, &error); diff --git a/src/rtcsessiondescription.h b/src/rtcsessiondescription.h index 8842572..98b8b03 100644 --- a/src/rtcsessiondescription.h +++ b/src/rtcsessiondescription.h @@ -28,7 +28,7 @@ class RTCSessionDescription : public Nan::ObjectWrap { static NAN_MODULE_INIT(Init); static Local Create(const std::string& type, const std::string &sdp); - + static inline Nan::Persistent& constructor() { static Nan::Persistent _constructor; return _constructor; From f8c46300c556bd677cd2dd138305f8959e901dac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Charmet?= Date: Mon, 22 May 2017 16:11:19 +0200 Subject: [PATCH 17/20] removed (fake) constraints (deprecated?) + make PC configuration fields optional --- src/rtcpeerconnection.cc | 69 +++++++++++++++++++++++----------------- src/rtcpeerconnection.h | 3 +- 2 files changed, 41 insertions(+), 31 deletions(-) diff --git a/src/rtcpeerconnection.cc b/src/rtcpeerconnection.cc index 2432967..79ea549 100644 --- a/src/rtcpeerconnection.cc +++ b/src/rtcpeerconnection.cc @@ -88,7 +88,10 @@ static const char eUnsupported[] = "The 1st argument provided is an " "AlgorithmIdentifier with a supported algorithm name, but the parameters " "are not supported."; -static const char eFailure[] = "Failed to generate the certificate."; +static const char eGenerateCertificateFailure[] = + "Failed to generate the certificate."; +static const char eConstructorFailure[] = + "Failed to construct 'RTCPeerConnection'"; NAN_MODULE_INIT(RTCPeerConnection::Init) { Local ctor = Nan::New(New); @@ -131,8 +134,7 @@ NAN_MODULE_INIT(RTCPeerConnection::Init) { } RTCPeerConnection::RTCPeerConnection( - const webrtc::PeerConnectionInterface::RTCConfiguration& config, - const webrtc::MediaConstraintsInterface& constraints) { + const webrtc::PeerConnectionInterface::RTCConfiguration& config) { _peerConnectionFactory = webrtc::CreatePeerConnectionFactory( Globals::GetSignalingThread(), Globals::GetWorkerThread(), @@ -140,7 +142,7 @@ RTCPeerConnection::RTCPeerConnection( _peerConnectionObserver = PeerConnectionObserver::Create(); _peerConnection = _peerConnectionFactory->CreatePeerConnection( - config, &constraints, NULL, NULL, _peerConnectionObserver); + config, NULL, NULL, _peerConnectionObserver); } RTCPeerConnection::~RTCPeerConnection() { @@ -158,44 +160,53 @@ NAN_METHOD(RTCPeerConnection::New) { ASSERT_OBJECT_ARGUMENT(0, config); DECLARE_OBJECT_PROPERTY(config, kIceServers, iceServersVal); - ASSERT_PROPERTY_ARRAY(kIceServers, iceServersVal, iceServers); - for (unsigned int i = 0; i < iceServers->Length(); i = i + 1) { - Local iceServerVal = iceServers->Get(i); - ASSERT_PROPERTY_OBJECT(kIceServers, iceServerVal, iceServer); + if (!iceServersVal->IsNull() && !iceServersVal->IsUndefined()) { + ASSERT_PROPERTY_ARRAY(kIceServers, iceServersVal, iceServers); - webrtc::PeerConnectionInterface::IceServer server; + for (unsigned int i = 0; i < iceServers->Length(); i = i + 1) { + Local iceServerVal = iceServers->Get(i); + ASSERT_PROPERTY_OBJECT(kIceServers, iceServerVal, iceServer); - DECLARE_OBJECT_PROPERTY(iceServer, kIceServerUrls, iceServerUrlsVal); - ASSERT_PROPERTY_ARRAY(kIceServerUrls, iceServerUrlsVal, iceServerUrls); + webrtc::PeerConnectionInterface::IceServer server; - for (unsigned int j = 0; j < iceServerUrls->Length(); j = j + 1) { - Local iceServerUrlVal = iceServerUrls->Get(j); - ASSERT_PROPERTY_STRING(kIceServerUrls, iceServerUrlVal, iceServerUrl); - server.urls.push_back(*iceServerUrl); + DECLARE_OBJECT_PROPERTY(iceServer, kIceServerUrls, iceServerUrlsVal); + ASSERT_PROPERTY_ARRAY(kIceServerUrls, iceServerUrlsVal, iceServerUrls); + + for (unsigned int j = 0; j < iceServerUrls->Length(); j = j + 1) { + Local iceServerUrlVal = iceServerUrls->Get(j); + // FIXME: validate URL + ASSERT_PROPERTY_STRING(kIceServerUrls, iceServerUrlVal, iceServerUrl); + server.urls.push_back(*iceServerUrl); + // FIXME: add username / password for TURN servers + } + _config.servers.push_back(server); } - _config.servers.push_back(server); } DECLARE_OBJECT_PROPERTY(config, kCertificates, certificatesVal); - ASSERT_PROPERTY_ARRAY(kCertificates, certificatesVal, certificates); - for (unsigned int i = 0; i < certificates->Length(); i = i + 1) { - Local certificateVal = certificates->Get(i); - ASSERT_PROPERTY_OBJECT(kCertificates, certificateVal, certificate); - // FIXME: validate it's a RTCCertificate object - RTCCertificate* _certificate - = Nan::ObjectWrap::Unwrap(certificate); + if (!certificatesVal->IsNull() && !certificatesVal->IsUndefined()) { + ASSERT_PROPERTY_ARRAY(kCertificates, certificatesVal, certificates); + + for (unsigned int i = 0; i < certificates->Length(); i = i + 1) { + Local certificateVal = certificates->Get(i); + ASSERT_PROPERTY_OBJECT(kCertificates, certificateVal, certificate); + // FIXME: validate it's a RTCCertificate object + RTCCertificate* _certificate + = Nan::ObjectWrap::Unwrap(certificate); - _config.certificates.push_back(_certificate->_certificate); + _config.certificates.push_back(_certificate->_certificate); + } } } - constraints.AddOptional(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, - "true"); + RTCPeerConnection *rtcPeerConnection = new RTCPeerConnection(_config); + + if (!rtcPeerConnection->_peerConnection) { + return Nan::ThrowError(eConstructorFailure); + } - RTCPeerConnection *rtcPeerConnection = new RTCPeerConnection(_config, - constraints); rtcPeerConnection->Wrap(info.This()); rtcPeerConnection->_peerConnectionObserver->SetEventEmitter( @@ -519,7 +530,7 @@ void RTCPeerConnection::GenerateCertificateWorker::WorkComplete() { if (!_certificate.get()) { std::stringstream errorStream; - errorStream << eFailure; + errorStream << eGenerateCertificateFailure; resolver->Reject(Nan::TypeError(errorStream.str().c_str())); } else { resolver->Resolve(RTCCertificate::Create(_certificate)); diff --git a/src/rtcpeerconnection.h b/src/rtcpeerconnection.h index c23fda9..9c77767 100644 --- a/src/rtcpeerconnection.h +++ b/src/rtcpeerconnection.h @@ -31,8 +31,7 @@ class RTCPeerConnection : public EventEmitter { private: explicit RTCPeerConnection( - const webrtc::PeerConnectionInterface::RTCConfiguration& config, - const webrtc::MediaConstraintsInterface& constraints); + const webrtc::PeerConnectionInterface::RTCConfiguration& config); ~RTCPeerConnection(); static NAN_METHOD(New); From ce6693fc03bc3137d15fef4c79774b1d42bc9b93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Charmet?= Date: Mon, 22 May 2017 17:38:58 +0200 Subject: [PATCH 18/20] added datachannel.close --- src/rtcdatachannel.cc | 11 +++++++++++ src/rtcdatachannel.h | 1 + 2 files changed, 12 insertions(+) diff --git a/src/rtcdatachannel.cc b/src/rtcdatachannel.cc index 928822c..e0df156 100644 --- a/src/rtcdatachannel.cc +++ b/src/rtcdatachannel.cc @@ -26,6 +26,7 @@ static const char kLabel[] = "label"; static const char kOrdered[] = "ordered"; static const char kReadyState[] = "readyState"; static const char kSend[] = "send"; +static const char kClose[] = "close"; NAN_MODULE_INIT(RTCDataChannel::Init) { Local ctor = Nan::New(New); @@ -38,6 +39,7 @@ NAN_MODULE_INIT(RTCDataChannel::Init) { Nan::SetAccessor(prototype, LOCAL_STRING(kReadyState), GetReadyState); Nan::SetMethod(prototype, kSend, Send); + Nan::SetMethod(prototype, kClose, Close); constructor().Reset(Nan::GetFunction(ctor).ToLocalChecked()); @@ -101,3 +103,12 @@ NAN_METHOD(RTCDataChannel::Send) { info.GetReturnValue().Set(Nan::Null()); } + +NAN_METHOD(RTCDataChannel::Close) { + METHOD_HEADER("RTCDataChannel", "close"); + UNWRAP_OBJECT(RTCDataChannel, object); + + object->_datachannel->Close(); + + info.GetReturnValue().Set(Nan::Null()); +} diff --git a/src/rtcdatachannel.h b/src/rtcdatachannel.h index 518c8eb..2ee4330 100644 --- a/src/rtcdatachannel.h +++ b/src/rtcdatachannel.h @@ -34,6 +34,7 @@ class RTCDataChannel : public EventEmitter { static NAN_GETTER(GetReadyState); static NAN_METHOD(Send); + static NAN_METHOD(Close); static Local Create( const rtc::scoped_refptr& datachannel); From 2e0154ae26949742f8bf9b69d975c23ab349f099 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Charmet?= Date: Tue, 23 May 2017 17:15:46 +0200 Subject: [PATCH 19/20] started mediastream api --- binding.gyp | 2 + src/event/mediastreamevent.cc | 41 ++++++++++++++++ src/event/mediastreamevent.h | 38 ++++++++++++++ src/observer/peerconnectionobserver.cc | 9 ++++ src/observer/peerconnectionobserver.h | 1 + src/rtcmediastream.cc | 68 ++++++++++++++++++++++++++ src/rtcmediastream.h | 59 ++++++++++++++++++++++ 7 files changed, 218 insertions(+) create mode 100644 src/event/mediastreamevent.cc create mode 100644 src/event/mediastreamevent.h create mode 100644 src/rtcmediastream.cc create mode 100644 src/rtcmediastream.h diff --git a/binding.gyp b/binding.gyp index 8e6afa5..aba4881 100644 --- a/binding.gyp +++ b/binding.gyp @@ -8,6 +8,7 @@ 'src/event/emitterevent.cc', 'src/event/peerconnectioniceevent.cc', 'src/event/datachannelevent.cc', + 'src/event/mediastreamevent.cc', 'src/event/messageevent.cc', 'src/event/eventqueue.cc', 'src/globals.cc', @@ -22,6 +23,7 @@ 'src/rtcpeerconnection.cc', 'src/rtcsessiondescription.cc', 'src/rtcdatachannel.cc', + 'src/rtcmediastream.cc', ], 'include_dirs' : [ 'build/include', diff --git a/src/event/mediastreamevent.cc b/src/event/mediastreamevent.cc new file mode 100644 index 0000000..c6c3548 --- /dev/null +++ b/src/event/mediastreamevent.cc @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2017 Axel Isouard + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "common.h" +#include "mediastreamevent.h" +#include "eventemitter.h" +#include "rtcmediastream.h" + +using namespace v8; + +static const char kStream[] = "stream"; + +MediaStreamEvent::MediaStreamEvent(EventEmitter *eventEmitter, + const rtc::scoped_refptr &mediastream) + : EmitterEvent(eventEmitter), _mediastream(mediastream) { +} + +void MediaStreamEvent::Handle() { + Nan::HandleScope scope; + + // FIXME: make proper MediaStreamEvent ? + Local e = Nan::New(); + // FIXME: move to observer ? + Nan::Persistent mediastream(RTCMediaStream::Create(_mediastream)); + e->Set(LOCAL_STRING(kStream), Nan::New(mediastream)); + + _eventEmitter->EmitData(LOCAL_STRING(_type), e); +} diff --git a/src/event/mediastreamevent.h b/src/event/mediastreamevent.h new file mode 100644 index 0000000..155af71 --- /dev/null +++ b/src/event/mediastreamevent.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2017 Axel Isouard + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef EVENT_MEDIASTREAMEVENT_H_ +#define EVENT_MEDIASTREAMEVENT_H_ + +#include "emitterevent.h" +#include "eventemitter.h" +#include +#include + +using namespace v8; + +class MediaStreamEvent : public EmitterEvent { + public: + explicit MediaStreamEvent(EventEmitter *eventEmitter, + const rtc::scoped_refptr& datachannel); + + void Handle(); + + private: + const rtc::scoped_refptr _mediastream; +}; + +#endif // EVENT_MEDIASTREAMEVENT_H_ diff --git a/src/observer/peerconnectionobserver.cc b/src/observer/peerconnectionobserver.cc index d1cdaaa..53ebddd 100644 --- a/src/observer/peerconnectionobserver.cc +++ b/src/observer/peerconnectionobserver.cc @@ -24,6 +24,9 @@ static const char kIceGatheringStateChange[] = "icegatheringstatechange"; static const char kNegociationNeeded[] = "negotiationneeded"; static const char kDataChannel[] = "datachannel"; static const char kIceCandidate[] = "icecandidate"; +// FIXME: not part of W3C spec ? +static const char kAddStream[] = "addstream"; +static const char kRemoveStream[] = "removestream"; PeerConnectionObserver::PeerConnectionObserver() { } @@ -42,11 +45,17 @@ void PeerConnectionObserver::OnSignalingChange( void PeerConnectionObserver::OnAddStream( rtc::scoped_refptr stream) { std::cout << "OnAddStream" << std::endl; + MediaStreamEvent* _event = new MediaStreamEvent(_eventEmitter, stream); + _event->SetType(kAddStream); + Globals::GetEventQueue()->PushEvent(_event); } void PeerConnectionObserver::OnRemoveStream( rtc::scoped_refptr stream) { std::cout << "OnRemoveStream" << std::endl; + MediaStreamEvent* _event = new MediaStreamEvent(_eventEmitter, stream); + _event->SetType(kRemoveStream); + Globals::GetEventQueue()->PushEvent(_event); } void PeerConnectionObserver::OnDataChannel( diff --git a/src/observer/peerconnectionobserver.h b/src/observer/peerconnectionobserver.h index c848be5..0af3771 100644 --- a/src/observer/peerconnectionobserver.h +++ b/src/observer/peerconnectionobserver.h @@ -21,6 +21,7 @@ #include "event/emitterevent.h" #include "event/peerconnectioniceevent.h" #include "event/datachannelevent.h" +#include "event/mediastreamevent.h" using namespace v8; diff --git a/src/rtcmediastream.cc b/src/rtcmediastream.cc new file mode 100644 index 0000000..257d88c --- /dev/null +++ b/src/rtcmediastream.cc @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2017 Axel Isouard + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include "rtcmediastream.h" +#include "common.h" + +static const char sRTCMediaStream[] = "RTCMediaStream"; + +NAN_MODULE_INIT(RTCMediaStream::Init) { + Local ctor = Nan::New(New); + ctor->SetClassName(LOCAL_STRING(sRTCMediaStream)); + ctor->InstanceTemplate()->SetInternalFieldCount(1); + + Local prototype = ctor->PrototypeTemplate(); + // Nan::SetAccessor(prototype, LOCAL_STRING(kLabel), GetLabel); + // Nan::SetAccessor(prototype, LOCAL_STRING(kOrdered), GetOrdered); + // Nan::SetAccessor(prototype, LOCAL_STRING(kReadyState), GetReadyState); + + // Nan::SetMethod(prototype, kSend, Send); + // Nan::SetMethod(prototype, kClose, Close); + + constructor().Reset(Nan::GetFunction(ctor).ToLocalChecked()); + + Nan::Set(target, LOCAL_STRING(sRTCMediaStream), ctor->GetFunction()); +} + +RTCMediaStream::RTCMediaStream( + const rtc::scoped_refptr &mediastream) + : _mediastream(mediastream) { + + //_mediastreamObserver = DataChannelObserver::Create(); + //_mediastream->RegisterObserver(_mediastreamObserver); +} + +RTCMediaStream::~RTCMediaStream() { + //_mediastream->UnregisterObserver(); + //_mediastreamObserver = NULL; +} + +Local RTCMediaStream::Create( + const rtc::scoped_refptr &mediastream) { + Local cons = Nan::New(RTCMediaStream::constructor()); + Local instance = Nan::NewInstance(cons, 0, NULL).ToLocalChecked(); + + RTCMediaStream *_mediastream = new RTCMediaStream(mediastream); + _mediastream->Wrap(instance); + //_mediastream->_mediastreamObserver->SetEventEmitter(_mediastream); + + return instance; +} + +NAN_METHOD(RTCMediaStream::New) { +} diff --git a/src/rtcmediastream.h b/src/rtcmediastream.h new file mode 100644 index 0000000..a5850a6 --- /dev/null +++ b/src/rtcmediastream.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2017 Axel Isouard + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef RTCMEDIASTREAM_H_ +#define RTCMEDIASTREAM_H_ + +#include +#include +#include +#include "eventemitter.h" + +using namespace v8; + +class RTCMediaStream : public EventEmitter { + public: + static NAN_MODULE_INIT(Init); + + // static NAN_GETTER(GetLabel); + // static NAN_GETTER(GetOrdered); + // static NAN_GETTER(GetReadyState); + + // static NAN_METHOD(Send); + // static NAN_METHOD(Close); + + static Local Create( + const rtc::scoped_refptr& mediastream); + + static inline Nan::Persistent& constructor() { + static Nan::Persistent _constructor; + return _constructor; + } + + const rtc::scoped_refptr _mediastream; + + private: + explicit RTCMediaStream( + const rtc::scoped_refptr& mediastream); + ~RTCMediaStream(); + + static NAN_METHOD(New); + + protected: + // rtc::scoped_refptr _datachannelObserver; +}; + +#endif // RTCMEDIASTREAM_H_ From 5d1882f2962af2d0c0537555e5b4f334a6ecab5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Charmet?= Date: Tue, 23 May 2017 18:23:52 +0200 Subject: [PATCH 20/20] [peerconnection] addstream --- src/module.cc | 2 ++ src/rtcmediastream.cc | 3 ++- src/rtcpeerconnection.cc | 24 ++++++++++++++++++++++++ src/rtcpeerconnection.h | 1 + 4 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/module.cc b/src/module.cc index b726e2c..711cd92 100644 --- a/src/module.cc +++ b/src/module.cc @@ -22,6 +22,7 @@ #include "rtcpeerconnection.h" #include "rtcsessiondescription.h" #include "rtcdatachannel.h" +#include "rtcmediastream.h" #include NAN_MODULE_INIT(Init) { @@ -37,6 +38,7 @@ NAN_MODULE_INIT(Init) { RTCPeerConnection::Init(target); RTCSessionDescription::Init(target); RTCDataChannel::Init(target); + RTCMediaStream::Init(target); node::AtExit(Globals::Cleanup); } diff --git a/src/rtcmediastream.cc b/src/rtcmediastream.cc index 257d88c..0d18c7f 100644 --- a/src/rtcmediastream.cc +++ b/src/rtcmediastream.cc @@ -26,7 +26,7 @@ NAN_MODULE_INIT(RTCMediaStream::Init) { ctor->SetClassName(LOCAL_STRING(sRTCMediaStream)); ctor->InstanceTemplate()->SetInternalFieldCount(1); - Local prototype = ctor->PrototypeTemplate(); + // Local prototype = ctor->PrototypeTemplate(); // Nan::SetAccessor(prototype, LOCAL_STRING(kLabel), GetLabel); // Nan::SetAccessor(prototype, LOCAL_STRING(kOrdered), GetOrdered); // Nan::SetAccessor(prototype, LOCAL_STRING(kReadyState), GetReadyState); @@ -54,6 +54,7 @@ RTCMediaStream::~RTCMediaStream() { Local RTCMediaStream::Create( const rtc::scoped_refptr &mediastream) { + Local cons = Nan::New(RTCMediaStream::constructor()); Local instance = Nan::NewInstance(cons, 0, NULL).ToLocalChecked(); diff --git a/src/rtcpeerconnection.cc b/src/rtcpeerconnection.cc index 79ea549..1c646fa 100644 --- a/src/rtcpeerconnection.cc +++ b/src/rtcpeerconnection.cc @@ -27,6 +27,7 @@ #include "rtcpeerconnection.h" #include "rtcsessiondescription.h" #include "rtcdatachannel.h" +#include "rtcmediastream.h" Nan::Persistent RTCPeerConnection::constructor; @@ -37,6 +38,7 @@ static const char kCreateAnswer[] = "createAnswer"; static const char kSetLocalDescription[] = "setLocalDescription"; static const char kSetRemoteDescription[] = "setRemoteDescription"; static const char kCreateDataChannel[] = "createDataChannel"; +static const char kAddStream[] = "addStream"; static const char kGenerateCertificate[] = "generateCertificate"; static const char kIceServers[] = "iceServers"; @@ -106,6 +108,7 @@ NAN_MODULE_INIT(RTCPeerConnection::Init) { Nan::SetMethod(prototype, kSetLocalDescription, SetLocalDescription); Nan::SetMethod(prototype, kSetRemoteDescription, SetRemoteDescription); Nan::SetMethod(prototype, kCreateDataChannel, CreateDataChannel); + Nan::SetMethod(prototype, kAddStream, AddStream); Local tpl = ctor->InstanceTemplate(); Nan::SetAccessor(tpl, LOCAL_STRING(kConnectionState), @@ -350,6 +353,27 @@ NAN_METHOD(RTCPeerConnection::CreateDataChannel) { info.GetReturnValue().Set(datachannel); } +NAN_METHOD(RTCPeerConnection::AddStream) { + METHOD_HEADER("RTCPeerConnection", "addStream"); + UNWRAP_OBJECT(RTCPeerConnection, object); + + ASSERT_OBJECT_ARGUMENT(0, stream); + + // FIXME: validate... + RTCMediaStream* _stream = Nan::ObjectWrap::Unwrap( + stream); + + std::cout << "ADDING STREAM" << std::endl; + bool ok = object->_peerConnection->AddStream(_stream->_mediastream); + if(ok) { + std::cout << "stream added" << std::endl; + }else{ + std::cout << "stream NOT added" << std::endl; + } + + info.GetReturnValue().Set(Nan::Null()); +} + NAN_GETTER(RTCPeerConnection::GetConnectionState) { // FIXME: implement info.GetReturnValue().Set(LOCAL_STRING("new")); diff --git a/src/rtcpeerconnection.h b/src/rtcpeerconnection.h index 9c77767..60236cf 100644 --- a/src/rtcpeerconnection.h +++ b/src/rtcpeerconnection.h @@ -41,6 +41,7 @@ class RTCPeerConnection : public EventEmitter { static NAN_METHOD(SetRemoteDescription); static NAN_METHOD(CreateDataChannel); static NAN_METHOD(GenerateCertificate); + static NAN_METHOD(AddStream); static NAN_GETTER(GetConnectionState); static NAN_GETTER(GetCurrentLocalDescription);