diff --git a/bin/nodejs/Makefile.am b/bin/nodejs/Makefile.am index 612dfc70ee1fe6e34f763bd274851799f546e7ae..d4d85728aec2205743d633fe211b93ec233ffa2e 100644 --- a/bin/nodejs/Makefile.am +++ b/bin/nodejs/Makefile.am @@ -5,8 +5,11 @@ BUILT_SOURCES= \ build/Makefile \ build/Release/obj.target/dring.node -ring_wrapper.cpp: jni_interface.i configurationmanager.i managerimpl.i - $(SWIG) -v -c++ -javascript -node -o ring_wrapper.cpp jni_interface.i +ring_wrapper.cpp: nodejs_interface.i configurationmanager.i managerimpl.i + $(SWIG) -v -c++ -javascript -node -o ring_wrapper.cpp nodejs_interface.i + sed -i 's/_wrap_setAccountsChangedCb)/setAccountsChangedCb)/g' ring_wrapper.cpp + sed -i 's/_wrap_setRegistrationStateChangedCb)/setRegistrationStateChangedCb)/g' ring_wrapper.cpp + build/Makefile: ring_wrapper.cpp binding.gyp node-gyp configure diff --git a/bin/nodejs/callback.h b/bin/nodejs/callback.h new file mode 100644 index 0000000000000000000000000000000000000000..e19d22e63288f4445f9b47b398ca7b2901e99595 --- /dev/null +++ b/bin/nodejs/callback.h @@ -0,0 +1,53 @@ +v8::Persistent<v8::Function> accountsChangedCb; +v8::Persistent<v8::Function> registrationStateChangedCb; + +static void setAccountsChangedCb(const SwigV8Arguments &args) { + SWIGV8_HANDLESCOPE(); + if (args[0]->IsObject()) { + if (args[0]->IsFunction()){ + v8::Local<v8::Function> func = v8::Local<v8::Function>::Cast(args[0]); + accountsChangedCb.Reset(v8::Isolate::GetCurrent(), func); + } else { + accountsChangedCb.Reset(); + } + } +} + + +void accountsChanged(){ + SWIGV8_HANDLESCOPE(); + + v8::Local<v8::Function> func = v8::Local<v8::Function>::New(v8::Isolate::GetCurrent(), accountsChangedCb); + if (!func.IsEmpty()) { + printf("accountsChanged Called | C++\n" ); + v8::Local<v8::Value> callback_args[] = { }; + v8::Handle<v8::Value> js_result = func->Call(SWIGV8_CURRENT_CONTEXT()->Global(), 0, callback_args); + } +} + + +static void setRegistrationStateChangedCb(const SwigV8Arguments &args) { + SWIGV8_HANDLESCOPE(); + + if (args[0]->IsObject()) { + if (args[0]->IsFunction()){ + v8::Local<v8::Function> func = v8::Local<v8::Function>::Cast(args[0]); + registrationStateChangedCb.Reset(v8::Isolate::GetCurrent(), func); + } else { + registrationStateChangedCb.Reset(); + } + } +} + +void registrationStateChanged(const std::string& account_id,const std::string& state,int code,const std::string& detail_str){ + SWIGV8_HANDLESCOPE(); + + v8::Local<v8::Function> func = v8::Local<v8::Function>::New(v8::Isolate::GetCurrent(), registrationStateChangedCb); + if (!func.IsEmpty()) { + printf("registrationStateChanged Called | C++\n" ); + v8::Local<v8::Value> callback_args[] = { SWIGV8_STRING_NEW(account_id.c_str()),SWIGV8_STRING_NEW(state.c_str()), + SWIGV8_INTEGER_NEW(code),SWIGV8_STRING_NEW(detail_str.c_str()) }; + + v8::Handle<v8::Value> js_result = func->Call(SWIGV8_CURRENT_CONTEXT()->Global(), 4, callback_args); + } +} \ No newline at end of file diff --git a/bin/nodejs/callback.i b/bin/nodejs/callback.i new file mode 100644 index 0000000000000000000000000000000000000000..3799c1774ed6f8b202487cf8bf1111a34b219db8 --- /dev/null +++ b/bin/nodejs/callback.i @@ -0,0 +1,3 @@ +static void setAccountsChangedCb(const SwigV8Arguments &args); + +static void setRegistrationStateChangedCb(const SwigV8Arguments &args); \ No newline at end of file diff --git a/bin/nodejs/index.js b/bin/nodejs/index.js index 6a0e4fc3ac5dc6e28935055011cff266035dabfe..77950e755d473d23a8ec14184f58f9e6bce0ef02 100644 --- a/bin/nodejs/index.js +++ b/bin/nodejs/index.js @@ -2,6 +2,7 @@ * Copyright (c) 2017 Savoir-faire Linux Inc. * * Author: Adrien BĂ©raud <adrien.beraud@savoirfairelinux.com> + * Author: Asad Salman <me@asad.co> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,6 +17,26 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see <https://www.gnu.org/licenses/>. */ -'use strict'; +"use strict"; +const dring = require("./build/Release/dring"); -require("./build/Release/dring") +dring.setAccountsChangedCb(function () { + console.log("accountsChanged Called | JavaScript"); +}); + +dring.setRegistrationStateChangedCb(function (account_id, state, code, detail_str) { + console.log("registrationStateChanged Called | JavaScript"); + console.log(account_id + "|" + state + "|" + code + "|" + detail_str); +}); + +dring.init(); + +var params = new dring.StringMap(); +params.set("Account.type", "RING"); +params.set("Account.alias", "RingAccount"); +dring.addAccount(params); + +setInterval(function () { + dring.pollEvents(); + //console.log("Polling..."); +}, 10); diff --git a/bin/nodejs/jni_interface.i b/bin/nodejs/jni_interface.i deleted file mode 100644 index d927ad6f13d2e2f9462aa29844585deb8630e19d..0000000000000000000000000000000000000000 --- a/bin/nodejs/jni_interface.i +++ /dev/null @@ -1,275 +0,0 @@ -/* - * Copyright (C) 2004-2016 Savoir-faire Linux Inc. - * - * Author: Emeric Vigier <emeric.vigier@savoirfairelinux.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -/* File : jni_interface.i */ -%module (directors="1") Ringservice - -#define SWIG_JAVA_ATTACH_CURRENT_THREAD_AS_DAEMON -%include "typemaps.i" -%include "std_string.i" /* std::string typemaps */ -%include "arrays_javascript.i"; -%include "carrays.i"; -%include "std_map.i"; -%include "std_vector.i"; -%include "stdint.i"; - -/* void* shall be handled as byte arrays */ -%typemap(jni) void * "void *" -%typemap(jtype) void * "byte[]" -%typemap(jstype) void * "byte[]" -%typemap(javain) void * "$javainput" -%typemap(in) void * %{ - $1 = (void*)$input; -%} -%typemap(javadirectorin) void * "$jniinput" -%typemap(out) void * %{ - $result = $1; -%} -%typemap(javaout) void * { - return $jnicall; -} - -/* Avoid uint64_t to be converted to BigInteger */ -%apply int64_t { uint64_t }; - -namespace std { - -%typemap(javacode) map<string, string> %{ - public static $javaclassname toSwig(java.util.Map<String,String> in) { - $javaclassname n = new $javaclassname(); - for (java.util.Map.Entry<String, String> entry : in.entrySet()) { - if (entry.getValue() != null) { - n.set(entry.getKey(), entry.getValue()); - } - } - return n; - } - public java.util.HashMap<String,String> toNative() { - java.util.HashMap<String,String> out = new java.util.HashMap<>((int)size()); - StringVect keys = keys(); - for (String s : keys) { - out.put(s, get(s)); - } - return out; - } - public java.util.HashMap<String,String> toNativeFromUtf8() { - java.util.HashMap<String,String> out = new java.util.HashMap<>((int)size()); - StringVect keys = keys(); - for (String s : keys) { - out.put(s, getRaw(s).toJavaString()); - } - return out; - } -%} -%extend map<string, string> { - std::vector<std::string> keys() const { - std::vector<std::string> k; - k.reserve($self->size()); - for (const auto& i : *$self) { - k.push_back(i.first); - } - return k; - } - void setRaw(std::string key, const vector<uint8_t>& value) { - (*$self)[key] = std::string(value.data(), value.data()+value.size()); - } - std::vector<uint8_t> getRaw(std::string key) { - auto& v = $self->at(key); - return {v.begin(), v.end()}; - } -} -%template(StringMap) map<string, string>; - -%typemap(javabase) vector<string> "java.util.AbstractList<String>" -%typemap(javainterface) vector<string> "java.util.RandomAccess" -%extend vector<string> { - value_type set(int i, const value_type& in) throw (std::out_of_range) { - const std::string old = $self->at(i); - $self->at(i) = in; - return old; - } - bool add(const value_type& in) { - $self->push_back(in); - return true; - } - int32_t size() const { - return $self->size(); - } -} -%template(StringVect) vector<string>; - -%typemap(javacode) vector< map<string,string> > %{ - public java.util.ArrayList<java.util.Map<String, String>> toNative() { - java.util.ArrayList<java.util.Map<String, String>> out = new java.util.ArrayList<>(); - for (int i = 0; i < size(); ++i) { - out.add(get(i).toNative()); - } - return out; - } -%} -%template(VectMap) vector< map<string,string> >; -%template(IntegerMap) map<string,int>; -%template(IntVect) vector<int32_t>; -%template(UintVect) vector<uint32_t>; - -%typemap(javacode) vector<uint8_t> %{ - public static Blob fromString(String in) { - byte[] dat; - try { - dat = in.getBytes("UTF-8"); - } catch (java.io.UnsupportedEncodingException e) { - dat = in.getBytes(); - } - Blob n = new Blob(dat.length); - for (int i=0; i<dat.length; i++) { - n.set(i, dat[i]); - } - return n; - } - public String toJavaString() { - byte[] dat = new byte[(int)size()]; - for (int i=0; i<dat.length; i++) { - dat[i] = (byte)get(i); - } - try { - return new String(dat, "utf-8"); - } catch (java.io.UnsupportedEncodingException e) { - return ""; - } - } -%} -%template(Blob) vector<uint8_t>; -%template(FloatVect) vector<float>; -} - -/* not parsed by SWIG but needed by generated C files */ -%header %{ - -#include <functional> - -%} - -/* parsed by SWIG to generate all the glue */ -/* %include "../managerimpl.h" */ -/* %include <client/callmanager.h> */ - -%include "managerimpl.i" -%include "callmanager.i" -%include "configurationmanager.i" -%include "presencemanager.i" -%include "videomanager.i" - -#include "dring/callmanager_interface.h" - -%inline %{ -/* some functions that need to be declared in *_wrap.cpp - * that are not declared elsewhere in the c++ code - */ - -void init(ConfigurationCallback* confM, Callback* callM, PresenceCallback* presM, VideoCallback* videoM) { - using namespace std::placeholders; - - using std::bind; - using DRing::exportable_callback; - using DRing::CallSignal; - using DRing::ConfigurationSignal; - using DRing::PresenceSignal; - using DRing::VideoSignal; - - using SharedCallback = std::shared_ptr<DRing::CallbackWrapperBase>; - - // Call event handlers - const std::map<std::string, SharedCallback> callEvHandlers = { - exportable_callback<CallSignal::StateChange>(bind(&Callback::callStateChanged, callM, _1, _2, _3)), - exportable_callback<CallSignal::TransferFailed>(bind(&Callback::transferFailed, callM)), - exportable_callback<CallSignal::TransferSucceeded>(bind(&Callback::transferSucceeded, callM)), - exportable_callback<CallSignal::RecordPlaybackStopped>(bind(&Callback::recordPlaybackStopped, callM, _1)), - exportable_callback<CallSignal::VoiceMailNotify>(bind(&Callback::voiceMailNotify, callM, _1, _2)), - exportable_callback<CallSignal::IncomingMessage>(bind(&Callback::incomingMessage, callM, _1, _2, _3)), - exportable_callback<CallSignal::IncomingCall>(bind(&Callback::incomingCall, callM, _1, _2, _3)), - exportable_callback<CallSignal::RecordPlaybackFilepath>(bind(&Callback::recordPlaybackFilepath, callM, _1, _2)), - exportable_callback<CallSignal::ConferenceCreated>(bind(&Callback::conferenceCreated, callM, _1)), - exportable_callback<CallSignal::ConferenceChanged>(bind(&Callback::conferenceChanged, callM, _1, _2)), - exportable_callback<CallSignal::UpdatePlaybackScale>(bind(&Callback::updatePlaybackScale, callM, _1, _2, _3)), - exportable_callback<CallSignal::ConferenceRemoved>(bind(&Callback::conferenceRemoved, callM, _1)), - exportable_callback<CallSignal::NewCallCreated>(bind(&Callback::newCallCreated, callM, _1, _2, _3)), - exportable_callback<CallSignal::RecordingStateChanged>(bind(&Callback::recordingStateChanged, callM, _1, _2)), - exportable_callback<CallSignal::RtcpReportReceived>(bind(&Callback::onRtcpReportReceived, callM, _1, _2)), - exportable_callback<CallSignal::PeerHold>(bind(&Callback::peerHold, callM, _1, _2)) - }; - - // Configuration event handlers - const std::map<std::string, SharedCallback> configEvHandlers = { - exportable_callback<ConfigurationSignal::VolumeChanged>(bind(&ConfigurationCallback::volumeChanged, confM, _1, _2)), - exportable_callback<ConfigurationSignal::AccountsChanged>(bind(&ConfigurationCallback::accountsChanged, confM)), - exportable_callback<ConfigurationSignal::StunStatusFailed>(bind(&ConfigurationCallback::stunStatusFailure, confM, _1)), - exportable_callback<ConfigurationSignal::RegistrationStateChanged>(bind(&ConfigurationCallback::registrationStateChanged, confM, _1, _2, _3, _4)), - exportable_callback<ConfigurationSignal::VolatileDetailsChanged>(bind(&ConfigurationCallback::volatileAccountDetailsChanged, confM, _1, _2)), - exportable_callback<ConfigurationSignal::KnownDevicesChanged>(bind(&ConfigurationCallback::knownDevicesChanged, confM, _1, _2)), - exportable_callback<ConfigurationSignal::ExportOnRingEnded>(bind(&ConfigurationCallback::exportOnRingEnded, confM, _1, _2, _3)), - exportable_callback<ConfigurationSignal::Error>(bind(&ConfigurationCallback::errorAlert, confM, _1)), - exportable_callback<ConfigurationSignal::IncomingAccountMessage>(bind(&ConfigurationCallback::incomingAccountMessage, confM, _1, _2, _3 )), - exportable_callback<ConfigurationSignal::AccountMessageStatusChanged>(bind(&ConfigurationCallback::accountMessageStatusChanged, confM, _1, _2, _3, _4 )), - exportable_callback<ConfigurationSignal::IncomingTrustRequest>(bind(&ConfigurationCallback::incomingTrustRequest, confM, _1, _2, _3, _4 )), - exportable_callback<ConfigurationSignal::ContactAdded>(bind(&ConfigurationCallback::contactAdded, confM, _1, _2, _3 )), - exportable_callback<ConfigurationSignal::ContactRemoved>(bind(&ConfigurationCallback::contactRemoved, confM, _1, _2, _3 )), - exportable_callback<ConfigurationSignal::CertificatePinned>(bind(&ConfigurationCallback::certificatePinned, confM, _1 )), - exportable_callback<ConfigurationSignal::CertificatePathPinned>(bind(&ConfigurationCallback::certificatePathPinned, confM, _1, _2 )), - exportable_callback<ConfigurationSignal::CertificateExpired>(bind(&ConfigurationCallback::certificateExpired, confM, _1 )), - exportable_callback<ConfigurationSignal::CertificateStateChanged>(bind(&ConfigurationCallback::certificateStateChanged, confM, _1, _2, _3 )), - exportable_callback<ConfigurationSignal::RegisteredNameFound>(bind(&ConfigurationCallback::registeredNameFound, confM, _1, _2, _3, _4 )), - exportable_callback<ConfigurationSignal::NameRegistrationEnded>(bind(&ConfigurationCallback::nameRegistrationEnded, confM, _1, _2, _3 )), - exportable_callback<ConfigurationSignal::MigrationEnded>(bind(&ConfigurationCallback::migrationEnded, confM, _1, _2)), - exportable_callback<ConfigurationSignal::DeviceRevocationEnded>(bind(&ConfigurationCallback::deviceRevocationEnded, confM, _1, _2, _3)) - }; - - // Presence event handlers - const std::map<std::string, SharedCallback> presenceEvHandlers = { - exportable_callback<PresenceSignal::NewServerSubscriptionRequest>(bind(&PresenceCallback::newServerSubscriptionRequest, presM, _1 )), - exportable_callback<PresenceSignal::ServerError>(bind(&PresenceCallback::serverError, presM, _1, _2, _3 )), - exportable_callback<PresenceSignal::NewBuddyNotification>(bind(&PresenceCallback::newBuddyNotification, presM, _1, _2, _3, _4 )), - exportable_callback<PresenceSignal::SubscriptionStateChanged>(bind(&PresenceCallback::subscriptionStateChanged, presM, _1, _2, _3 )) - }; - - /*const std::map<std::string, SharedCallback> videoEvHandlers = { - exportable_callback<VideoSignal::GetCameraInfo>(bind(&VideoCallback::getCameraInfo, videoM, _1, _2, _3, _4)), - exportable_callback<VideoSignal::SetParameters>(bind(&VideoCallback::setParameters, videoM, _1, _2, _3, _4, _5)), - exportable_callback<VideoSignal::StartCapture>(bind(&VideoCallback::startCapture, videoM, _1)), - exportable_callback<VideoSignal::StopCapture>(bind(&VideoCallback::stopCapture, videoM)), - exportable_callback<VideoSignal::DecodingStarted>(bind(&VideoCallback::decodingStarted, videoM, _1, _2, _3, _4, _5)), - exportable_callback<VideoSignal::DecodingStopped>(bind(&VideoCallback::decodingStopped, videoM, _1, _2, _3)), - };*/ - - if (!DRing::init(static_cast<DRing::InitFlag>(DRing::DRING_FLAG_DEBUG))) - return; - - registerCallHandlers(callEvHandlers); - registerConfHandlers(configEvHandlers); - registerPresHandlers(presenceEvHandlers); - //registerVideoHandlers(videoEvHandlers); - - DRing::start(); -} - - -%} -#ifndef SWIG -/* some bad declarations */ -#endif diff --git a/bin/nodejs/nodejs_interface.i b/bin/nodejs/nodejs_interface.i new file mode 100644 index 0000000000000000000000000000000000000000..6e172560af54b520c25f77ecc213dafcb1605a30 --- /dev/null +++ b/bin/nodejs/nodejs_interface.i @@ -0,0 +1,140 @@ +/* + * Copyright (C) 2004-2016 Savoir-faire Linux Inc. + * + * Author: Emeric Vigier <emeric.vigier@savoirfairelinux.com> + * Author: Asad Salman <me@asad.co> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* File : nodejs_interface.i */ +%module (directors="1") Ringservice + +#define SWIG_JAVA_ATTACH_CURRENT_THREAD_AS_DAEMON +%include "typemaps.i" +%include "std_string.i" /* std::string typemaps */ +%include "arrays_javascript.i"; +%include "carrays.i"; +%include "std_map.i"; +%include "std_vector.i"; +%include "stdint.i"; + + +/* Avoid uint64_t to be converted to BigInteger */ +%apply int64_t { uint64_t }; + +namespace std { + +%extend map<string, string> { + std::vector<std::string> keys() const { + std::vector<std::string> k; + k.reserve($self->size()); + for (const auto& i : *$self) { + k.push_back(i.first); + } + return k; + } + void setRaw(std::string key, const vector<uint8_t>& value) { + (*$self)[key] = std::string(value.data(), value.data()+value.size()); + } + std::vector<uint8_t> getRaw(std::string key) { + auto& v = $self->at(key); + return {v.begin(), v.end()}; + } +} +%template(StringMap) map<string, string>; + + +%extend vector<string> { + value_type set(int i, const value_type& in) throw (std::out_of_range) { + const std::string old = $self->at(i); + $self->at(i) = in; + return old; + } + bool add(const value_type& in) { + $self->push_back(in); + return true; + } + int32_t size() const { + return $self->size(); + } +} +%template(StringVect) vector<string>; + + +%template(VectMap) vector< map<string,string> >; +%template(IntegerMap) map<string,int>; +%template(IntVect) vector<int32_t>; +%template(UintVect) vector<uint32_t>; + + +%template(Blob) vector<uint8_t>; +%template(FloatVect) vector<float>; +} + +/* not parsed by SWIG but needed by generated C files */ +%header %{ +#include <functional> +%} + +/* parsed by SWIG to generate all the glue */ +/* %include "../managerimpl.h" */ +/* %include <client/callmanager.h> */ + +%include "managerimpl.i" +%include "callmanager.i" +%include "configurationmanager.i" +%include "presencemanager.i" +%include "videomanager.i" +%include "callback.i" + +#include "dring/callmanager_interface.h" + +%header %{ + +#include "callback.h" +%} + +%inline %{ +/* some functions that need to be declared in *_wrap.cpp + * that are not declared elsewhere in the c++ code + */ + +void init(){ + using namespace std::placeholders; + + using std::bind; + using DRing::exportable_callback; + using DRing::ConfigurationSignal; + using SharedCallback = std::shared_ptr<DRing::CallbackWrapperBase>; + + const std::map<std::string, SharedCallback> configEvHandlers = { + exportable_callback<ConfigurationSignal::AccountsChanged>(bind(&accountsChanged)), + exportable_callback<ConfigurationSignal::RegistrationStateChanged>(bind(®istrationStateChanged, _1, _2, _3, _4)) + }; + + if (!DRing::init(static_cast<DRing::InitFlag>(DRing::DRING_FLAG_DEBUG))) + return; + + registerConfHandlers(configEvHandlers); + + DRing::start(); +} + + +%} +#ifndef SWIG +/* some bad declarations */ +#endif