diff --git a/bin/Makefile.am b/bin/Makefile.am index bbe9d273e158ac60280bc5990c50412094a2a8c6..c833d0746a3a4e787c470b2ec7645da8fc535866 100644 --- a/bin/Makefile.am +++ b/bin/Makefile.am @@ -18,8 +18,10 @@ ringcli_CXXFLAGS = -I$(top_srcdir)/src \ ringcli_LDADD = $(top_builddir)/src/libring.la endif +SUBDIRS= + if RING_DBUS -SUBDIRS=dbus +SUBDIRS+=dbus ringlib_PROGRAMS = dring @@ -32,8 +34,12 @@ dring_CXXFLAGS= -I$(top_srcdir)/src ${DBUSCPP_CFLAGS} \ dring_LDADD = dbus/libclient_dbus.la ${DBUSCPP_LIBS} $(top_builddir)/src/libring.la endif +if RING_NODEJS +SUBDIRS+=nodejs +endif + if RING_RESTCPP -SUBDIRS=restcpp +SUBDIRS+=restcpp sbin_PROGRAMS = restdring diff --git a/bin/nodejs/Makefile.am b/bin/nodejs/Makefile.am new file mode 100644 index 0000000000000000000000000000000000000000..bc18443eb5f502e447b1d0378ee7035babd4f5f2 --- /dev/null +++ b/bin/nodejs/Makefile.am @@ -0,0 +1,19 @@ +include $(top_srcdir)/globals.mk + +BUILT_SOURCES= \ + ring_wrapper.cpp \ + build/Makefile \ + build/Release/obj.target/dring.node + +ring_wrapper.cpp: nodejs_interface.i configurationmanager.i managerimpl.i + $(SWIG) -v -c++ -javascript -node -o ring_wrapper.cpp nodejs_interface.i + +build/Makefile: ring_wrapper.cpp binding.gyp + node-gyp configure + +build/Release/obj.target/dring.node: build/Makefile ring_wrapper.cpp callback.h + node-gyp build + +CLEANFILES= \ + $(BUILT_SOURCES) \ + build/Release/dring.node diff --git a/bin/nodejs/binding.gyp b/bin/nodejs/binding.gyp new file mode 100644 index 0000000000000000000000000000000000000000..dcdb13ebc411ed51fccb53a97865d64396ad5a9f --- /dev/null +++ b/bin/nodejs/binding.gyp @@ -0,0 +1,12 @@ +{ + "targets": [ + { + "target_name": "dring", + "sources": [ "ring_wrapper.cpp" ], + 'include_dirs': ['../../src/'], + 'libraries': ['-L<(module_root_dir)/../../src/.libs/', '-lring'], + 'cflags!': [ '-fno-exceptions' ], + 'cflags_cc!': [ '-fno-exceptions' ] + } + ] +} \ No newline at end of file diff --git a/bin/nodejs/callback.h b/bin/nodejs/callback.h new file mode 100755 index 0000000000000000000000000000000000000000..823f908ab322b72d577f1e70c52e22100ae52fbe --- /dev/null +++ b/bin/nodejs/callback.h @@ -0,0 +1,344 @@ +#pragma once + +#define V8_STRING_NEW(str) v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), str.data(), v8::String::kNormalString, str.size()) + +#include <uv.h> +#include <queue> +#include <functional> +#include <mutex> + +using namespace v8; + +Persistent<Function> accountsChangedCb; +Persistent<Function> registrationStateChangedCb; +Persistent<Function> volatileDetailsChangedCb; +Persistent<Function> incomingAccountMessageCb; +Persistent<Function> accountMessageStatusChangedCb; +Persistent<Function> incomingTrustRequestCb; +Persistent<Function> contactAddedCb; +Persistent<Function> contactRemovedCb; +Persistent<Function> exportOnRingEndedCb; +Persistent<Function> nameRegistrationEndedCb; +Persistent<Function> knownDevicesChangedCb; +Persistent<Function> registeredNameFoundCb; +Persistent<Function> callStateChangedCb; +Persistent<Function> incomingMessageCb; +Persistent<Function> incomingCallCb; +Persistent<Function> newCallCreatedCb; + +std::queue<std::function<void() >> pendingSignals; +std::mutex pendingSignalsLock; + +uv_async_t signalAsync; + +Persistent<Function>* getPresistentCb(const std::string &signal) { + if (signal == "AccountsChanged") + return &accountsChangedCb; + else if (signal == "RegistrationStateChanged") + return ®istrationStateChangedCb; + else if (signal == "VolatileDetailsChanged") + return &volatileDetailsChangedCb; + else if (signal == "IncomingAccountMessage") + return &incomingAccountMessageCb; + else if (signal == "AccountMessageStatusChanged") + return &accountMessageStatusChangedCb; + else if (signal == "IncomingTrustRequest") + return &incomingTrustRequestCb; + else if (signal == "ContactAdded") + return &contactAddedCb; + else if (signal == "ContactRemoved") + return &contactRemovedCb; + else if (signal == "ExportOnRingEnded") + return &exportOnRingEndedCb; + else if (signal == "NameRegistrationEnded") + return &nameRegistrationEndedCb; + else if (signal == "KnownDevicesChanged") + return &knownDevicesChangedCb; + else if (signal == "RegisteredNameFound") + return ®isteredNameFoundCb; + else if (signal == "CallStateChanged") + return &callStateChangedCb; + else if (signal == "IncomingMessage") + return &incomingMessageCb; + else if (signal == "IncomingCall") + return &incomingCallCb; + else if (signal == "NewCallCreated") + return &newCallCreatedCb; + else return nullptr; +} + +void intVectToJsArray(const std::vector<uint8_t>& intVect, const Local<Array>& jsArray) { + for (unsigned int i = 0; i < intVect.size(); i++) + jsArray->Set(SWIGV8_INTEGER_NEW_UNS(i), SWIGV8_INTEGER_NEW(intVect[i])); +} + +void stringMapToJsMap(const std::map<std::string, std::string>& strmap, const Local<Object> &jsMap) { + for (auto& kvpair : strmap) + jsMap->Set(V8_STRING_NEW(std::get<0>(kvpair)), V8_STRING_NEW(std::get<1>(kvpair))); +} + +void setCallback(const std::string& signal, Local<Function>& func) { + if (auto* presistentCb = getPresistentCb(signal)) { + if (func->IsObject() && func->IsFunction()) { + presistentCb->Reset(Isolate::GetCurrent(), func); + } else { + presistentCb->Reset(); + } + } else { + printf("No Signal Associated with Event \'%s\'\n", signal.c_str()); + } +} + +void parseCbMap(const Local<Value>& callbackMap) { + Local<Object> cbAssocArray = callbackMap->ToObject(); + Local<Array> props = cbAssocArray->GetOwnPropertyNames(); + for (uint32_t i = 0; i < props->Length(); ++i) { + const Local<Value> key_local = props->Get(i); + std::string key = *String::Utf8Value(key_local); + Handle<Object> buffer = cbAssocArray->Get(V8_STRING_NEW(key))->ToObject(); + Local<Function> func = Local<Function>::Cast(buffer); + setCallback(key, func); + } +} + +void handlePendingSignals(uv_async_t* async_data) { + SWIGV8_HANDLESCOPE(); + std::lock_guard<std::mutex> lock(pendingSignalsLock); + while (not pendingSignals.empty()) { + pendingSignals.front()(); + pendingSignals.pop(); + } +} + +void registrationStateChanged(const std::string& account_id, const std::string& state, int code, const std::string& detail_str) { + + std::lock_guard<std::mutex> lock(pendingSignalsLock); + pendingSignals.emplace([account_id, state, code, detail_str]() { + Local<Function> func = Local<Function>::New(Isolate::GetCurrent(), registrationStateChangedCb); + if (!func.IsEmpty()) { + Local<Value> callback_args[] = {V8_STRING_NEW(account_id), V8_STRING_NEW(state), SWIGV8_INTEGER_NEW(code), V8_STRING_NEW(detail_str)}; + func->Call(SWIGV8_CURRENT_CONTEXT()->Global(), 4, callback_args); + } + }); + + uv_async_send(&signalAsync); +} + +void volatileDetailsChanged(const std::string& account_id, const std::map<std::string, std::string>& details) { + + std::lock_guard<std::mutex> lock(pendingSignalsLock); + pendingSignals.emplace([account_id, details]() { + Local<Function> func = Local<Function>::New(Isolate::GetCurrent(), volatileDetailsChangedCb); + if (!func.IsEmpty()) { + Local<Object> jsMap = SWIGV8_OBJECT_NEW(); + stringMapToJsMap(details, jsMap); + Local<Value> callback_args[] = {V8_STRING_NEW(account_id), jsMap}; + func->Call(SWIGV8_CURRENT_CONTEXT()->Global(), 2, callback_args); + } + }); + + uv_async_send(&signalAsync); +} + +void accountsChanged() { + + std::lock_guard<std::mutex> lock(pendingSignalsLock); + pendingSignals.emplace([]() { + Local<Function> func = Local<Function>::New(Isolate::GetCurrent(), accountsChangedCb); + if (!func.IsEmpty()) { + Local<Value> callback_args[] = {}; + func->Call(SWIGV8_CURRENT_CONTEXT()->Global(), 0, callback_args); + } + }); + + uv_async_send(&signalAsync); +} + +void contactAdded(const std::string& account_id, const std::string& uri, bool confirmed) { + + std::lock_guard<std::mutex> lock(pendingSignalsLock); + pendingSignals.emplace([account_id, uri, confirmed]() { + Local<Function> func = Local<Function>::New(Isolate::GetCurrent(), contactAddedCb); + if (!func.IsEmpty()) { + Local<Value> callback_args[] = {V8_STRING_NEW(account_id), V8_STRING_NEW(uri), SWIGV8_BOOLEAN_NEW(confirmed)}; + func->Call(SWIGV8_CURRENT_CONTEXT()->Global(), 3, callback_args); + } + }); + + uv_async_send(&signalAsync); +} + +void contactRemoved(const std::string& account_id, const std::string& uri, bool banned) { + + std::lock_guard<std::mutex> lock(pendingSignalsLock); + pendingSignals.emplace([account_id, uri, banned]() { + Local<Function> func = Local<Function>::New(Isolate::GetCurrent(), contactRemovedCb); + if (!func.IsEmpty()) { + Local<Value> callback_args[] = {V8_STRING_NEW(account_id), V8_STRING_NEW(uri), SWIGV8_BOOLEAN_NEW(banned)}; + func->Call(SWIGV8_CURRENT_CONTEXT()->Global(), 3, callback_args); + } + }); + + uv_async_send(&signalAsync); +} + +void exportOnRingEnded(const std::string& account_id, int state, const std::string& pin) { + + std::lock_guard<std::mutex> lock(pendingSignalsLock); + pendingSignals.emplace([account_id, state, pin]() { + Local<Function> func = Local<Function>::New(Isolate::GetCurrent(), exportOnRingEndedCb); + if (!func.IsEmpty()) { + Local<Value> callback_args[] = {V8_STRING_NEW(account_id), SWIGV8_INTEGER_NEW(state), V8_STRING_NEW(pin)}; + func->Call(SWIGV8_CURRENT_CONTEXT()->Global(), 3, callback_args); + } + }); + + uv_async_send(&signalAsync); +} + +void nameRegistrationEnded(const std::string& account_id, int state, const std::string& name) { + + std::lock_guard<std::mutex> lock(pendingSignalsLock); + pendingSignals.emplace([account_id, state, name]() { + Local<Function> func = Local<Function>::New(Isolate::GetCurrent(), nameRegistrationEndedCb); + if (!func.IsEmpty()) { + Local<Value> callback_args[] = {V8_STRING_NEW(account_id), SWIGV8_INTEGER_NEW(state), V8_STRING_NEW(name)}; + func->Call(SWIGV8_CURRENT_CONTEXT()->Global(), 3, callback_args); + } + }); + + uv_async_send(&signalAsync); +} + +void registeredNameFound(const std::string& account_id, int state, const std::string& address, const std::string& name) { + + std::lock_guard<std::mutex> lock(pendingSignalsLock); + pendingSignals.emplace([account_id, state, address, name]() { + Local<Function> func = Local<Function>::New(Isolate::GetCurrent(), registeredNameFoundCb); + if (!func.IsEmpty()) { + Local<Value> callback_args[] = {V8_STRING_NEW(account_id), SWIGV8_INTEGER_NEW(state), V8_STRING_NEW(address), V8_STRING_NEW(name)}; + func->Call(SWIGV8_CURRENT_CONTEXT()->Global(), 4, callback_args); + } + }); + + uv_async_send(&signalAsync); +} + +void accountMessageStatusChanged(const std::string& account_id, uint64_t message_id, const std::string& to, int state) { + + std::lock_guard<std::mutex> lock(pendingSignalsLock); + pendingSignals.emplace([account_id, message_id, to, state]() { + Local<Function> func = Local<Function>::New(Isolate::GetCurrent(), accountMessageStatusChangedCb); + if (!func.IsEmpty()) { + Local<Value> callback_args[] = {V8_STRING_NEW(account_id), SWIGV8_INTEGER_NEW_UNS(message_id), V8_STRING_NEW(to), SWIGV8_INTEGER_NEW(state)}; + func->Call(SWIGV8_CURRENT_CONTEXT()->Global(), 4, callback_args); + } + }); + + uv_async_send(&signalAsync); +} + +void incomingAccountMessage(const std::string& account_id, const std::string& from, const std::map<std::string, std::string>& payloads) { + + std::lock_guard<std::mutex> lock(pendingSignalsLock); + pendingSignals.emplace([account_id, from, payloads]() { + Local<Function> func = Local<Function>::New(Isolate::GetCurrent(), incomingAccountMessageCb); + if (!func.IsEmpty()) { + Local<Object> jsMap = SWIGV8_OBJECT_NEW(); + stringMapToJsMap(payloads, jsMap); + Local<Value> callback_args[] = {V8_STRING_NEW(account_id), V8_STRING_NEW(from), jsMap}; + func->Call(SWIGV8_CURRENT_CONTEXT()->Global(), 3, callback_args); + } + }); + + uv_async_send(&signalAsync); +} + +void knownDevicesChanged(const std::string& account_id, const std::map<std::string, std::string>& devices) { + + std::lock_guard<std::mutex> lock(pendingSignalsLock); + pendingSignals.emplace([account_id, devices]() { + Local<Function> func = Local<Function>::New(Isolate::GetCurrent(), knownDevicesChangedCb); + if (!func.IsEmpty()) { + Local<Object> jsMap = SWIGV8_OBJECT_NEW(); + stringMapToJsMap(devices, jsMap); + Local<Value> callback_args[] = {V8_STRING_NEW(account_id), jsMap}; + func->Call(SWIGV8_CURRENT_CONTEXT()->Global(), 2, callback_args); + } + }); + + uv_async_send(&signalAsync); +} + +void incomingTrustRequest(const std::string& account_id, const std::string& from, const std::vector<uint8_t>& payload, time_t received) { + + + std::lock_guard<std::mutex> lock(pendingSignalsLock); + pendingSignals.emplace([account_id, from, payload, received]() { + Local<Function> func = Local<Function>::New(Isolate::GetCurrent(), incomingTrustRequestCb); + if (!func.IsEmpty()) { + Local<Array> jsArray = SWIGV8_ARRAY_NEW(); + intVectToJsArray(payload, jsArray); + Local<Value> callback_args[] = {V8_STRING_NEW(account_id), V8_STRING_NEW(from), jsArray, SWIGV8_NUMBER_NEW(received)}; + func->Call(SWIGV8_CURRENT_CONTEXT()->Global(), 4, callback_args); + } + }); + uv_async_send(&signalAsync); +} + +void callStateChanged(const std::string& call_id, const std::string& state, int detail_code) { + + std::lock_guard<std::mutex> lock(pendingSignalsLock); + pendingSignals.emplace([call_id, state, detail_code]() { + Local<Function> func = Local<Function>::New(Isolate::GetCurrent(), callStateChangedCb); + if (!func.IsEmpty()) { + Local<Value> callback_args[] = {V8_STRING_NEW(call_id), V8_STRING_NEW(state), SWIGV8_INTEGER_NEW(detail_code)}; + func->Call(SWIGV8_CURRENT_CONTEXT()->Global(), 3, callback_args); + } + }); + + uv_async_send(&signalAsync); +} + +void incomingMessage(const std::string& id, const std::string& from, const std::map<std::string, std::string>& messages) { + + std::lock_guard<std::mutex> lock(pendingSignalsLock); + pendingSignals.emplace([id, from, messages]() { + Local<Function> func = Local<Function>::New(Isolate::GetCurrent(), incomingMessageCb); + if (!func.IsEmpty()) { + Local<Object> jsMap = SWIGV8_OBJECT_NEW(); + stringMapToJsMap(messages, jsMap); + Local<Value> callback_args[] = {V8_STRING_NEW(id), V8_STRING_NEW(from), jsMap}; + func->Call(SWIGV8_CURRENT_CONTEXT()->Global(), 4, callback_args); + } + }); + + uv_async_send(&signalAsync); +} + +void incomingCall(const std::string& account_id, const std::string& call_id, const std::string& from) { + + std::lock_guard<std::mutex> lock(pendingSignalsLock); + pendingSignals.emplace([account_id, call_id, from]() { + Local<Function> func = Local<Function>::New(Isolate::GetCurrent(), incomingCallCb); + if (!func.IsEmpty()) { + Local<Value> callback_args[] = {V8_STRING_NEW(account_id), V8_STRING_NEW(call_id), V8_STRING_NEW(from)}; + func->Call(SWIGV8_CURRENT_CONTEXT()->Global(), 3, callback_args); + } + }); + + uv_async_send(&signalAsync); +} +void newCallCreated(const std::string& account_id, const std::string& call_id, const std::string& to_uri) { + + std::lock_guard<std::mutex> lock(pendingSignalsLock); + pendingSignals.emplace([account_id, call_id, to_uri]() { + Local<Function> func = Local<Function>::New(Isolate::GetCurrent(), newCallCreatedCb); + if (!func.IsEmpty()) { + Local<Value> callback_args[] = {V8_STRING_NEW(account_id), V8_STRING_NEW(call_id), V8_STRING_NEW(to_uri)}; + func->Call(SWIGV8_CURRENT_CONTEXT()->Global(), 3, callback_args); + } + }); + + uv_async_send(&signalAsync); +} \ No newline at end of file diff --git a/bin/nodejs/callmanager.i b/bin/nodejs/callmanager.i new file mode 100644 index 0000000000000000000000000000000000000000..39c1bf09df42bd23e6ab0a2b57cf8166377d8616 --- /dev/null +++ b/bin/nodejs/callmanager.i @@ -0,0 +1,137 @@ +/* + * Copyright (C) 2004-2016 Savoir-faire Linux Inc. + * + * Author: Emeric Vigier <emeric.vigier@savoirfairelinux.com> + * Alexandre Lision <alexnadre.L@savoirfairelinux.com> + * Adrien Béraud <adrien.beraud@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. + */ + +%header %{ + +#include "dring/dring.h" +#include "dring/callmanager_interface.h" + +class Callback { +public: + virtual ~Callback() {} + virtual void callStateChanged(const std::string& call_id, const std::string& state, int detail_code){} + virtual void transferFailed(void){} + virtual void transferSucceeded(void){} + virtual void recordPlaybackStopped(const std::string& path){} + virtual void voiceMailNotify(const std::string& call_id, int nd_msg){} + virtual void incomingMessage(const std::string& id, const std::string& from, const std::map<std::string, std::string>& messages){} + virtual void incomingCall(const std::string& account_id, const std::string& call_id, const std::string& from){} + virtual void recordPlaybackFilepath(const std::string& id, const std::string& filename){} + virtual void conferenceCreated(const std::string& conf_id){} + virtual void conferenceChanged(const std::string& conf_id, const std::string& state){} + virtual void conferenceRemoved(const std::string& conf_id){} + virtual void newCallCreated(const std::string& call_id, const std::string&, const std::string&){} + virtual void updatePlaybackScale(const std::string& filepath, int position, int scale){} + virtual void conferenceRemove(const std::string& conf_id){} + virtual void newCall(const std::string& account_id, const std::string& call_id, const std::string& to){} + virtual void sipCallStateChange(const std::string& call_id, const std::string& state, int code){} + virtual void recordingStateChanged(const std::string& call_id, int code){} + virtual void recordStateChange(const std::string& call_id, int state){} + virtual void onRtcpReportReceived(const std::string& call_id, const std::map<std::string, int>& stats){} + virtual void peerHold(const std::string& call_id, bool holding){} +}; + + +%} + +%feature("director") Callback; + +namespace DRing { + +/* Call related methods */ +std::string placeCall(const std::string& accountID, const std::string& to); + +bool refuse(const std::string& callID); +bool accept(const std::string& callID); +bool hangUp(const std::string& callID); +bool hold(const std::string& callID); +bool unhold(const std::string& callID); +bool muteLocalMedia(const std::string& callid, const std::string& mediaType, bool mute); +bool transfer(const std::string& callID, const std::string& to); +bool attendedTransfer(const std::string& transferID, const std::string& targetID); +std::map<std::string, std::string> getCallDetails(const std::string& callID); +std::vector<std::string> getCallList(); + +/* Conference related methods */ +void removeConference(const std::string& conference_id); +bool joinParticipant(const std::string& sel_callID, const std::string& drag_callID); +void createConfFromParticipantList(const std::vector<std::string>& participants); +bool isConferenceParticipant(const std::string& call_id); +bool addParticipant(const std::string& callID, const std::string& confID); +bool addMainParticipant(const std::string& confID); +bool detachParticipant(const std::string& callID); +bool joinConference(const std::string& sel_confID, const std::string& drag_confID); +bool hangUpConference(const std::string& confID); +bool holdConference(const std::string& confID); +bool unholdConference(const std::string& confID); +std::vector<std::string> getConferenceList(); +std::vector<std::string> getParticipantList(const std::string& confID); +std::vector<std::string> getDisplayNames(const std::string& confID); +std::string getConferenceId(const std::string& callID); +std::map<std::string, std::string> getConferenceDetails(const std::string& callID); + +/* File Playback methods */ +bool startRecordedFilePlayback(const std::string& filepath); +void stopRecordedFilePlayback(const std::string& filepath); + +/* General audio methods */ +bool toggleRecording(const std::string& callID); +/* DEPRECATED */ +void setRecording(const std::string& callID); + +void recordPlaybackSeek(double value); +bool getIsRecording(const std::string& callID); +std::string getCurrentAudioCodecName(const std::string& callID); +void playDTMF(const std::string& key); +void startTone(int32_t start, int32_t type); + +bool switchInput(const std::string& callID, const std::string& resource); + +/* Instant messaging */ +void sendTextMessage(const std::string& callID, const std::map<std::string, std::string>& messages, const std::string& from, const bool& isMixed); + +} + +class Callback { +public: + virtual ~Callback() {} + virtual void callStateChanged(const std::string& call_id, const std::string& state, int detail_code){} + virtual void transferFailed(void){} + virtual void transferSucceeded(void){} + virtual void recordPlaybackStopped(const std::string& path){} + virtual void voiceMailNotify(const std::string& call_id, int nd_msg){} + virtual void incomingMessage(const std::string& id, const std::string& from, const std::map<std::string, std::string>& messages){} + virtual void incomingCall(const std::string& account_id, const std::string& call_id, const std::string& from){} + virtual void recordPlaybackFilepath(const std::string& id, const std::string& filename){} + virtual void conferenceCreated(const std::string& conf_id){} + virtual void conferenceChanged(const std::string& conf_id, const std::string& state){} + virtual void conferenceRemoved(const std::string& conf_id){} + virtual void newCallCreated(const std::string& call_id, const std::string&, const std::string&){} + virtual void updatePlaybackScale(const std::string& filepath, int position, int scale){} + virtual void conferenceRemove(const std::string& conf_id){} + virtual void newCall(const std::string& account_id, const std::string& call_id, const std::string& to){} + virtual void sipCallStateChange(const std::string& call_id, const std::string& state, int code){} + virtual void recordingStateChanged(const std::string& call_id, int code){} + virtual void recordStateChange(const std::string& call_id, int state){} + virtual void onRtcpReportReceived(const std::string& call_id, const std::map<std::string, int>& stats){} + virtual void peerHold(const std::string& call_id, bool holding){} +}; diff --git a/bin/nodejs/configurationmanager.i b/bin/nodejs/configurationmanager.i new file mode 100644 index 0000000000000000000000000000000000000000..4124e9c0264a7ec62a47b759520a9852742a02b5 --- /dev/null +++ b/bin/nodejs/configurationmanager.i @@ -0,0 +1,226 @@ +/* + * Copyright (C) 2004-2016 Savoir-faire Linux Inc. + * + * Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com> + * Author: Adrien Béraud <adrien.beraud@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. + */ + +%header %{ +#include "dring/dring.h" +#include "dring/configurationmanager_interface.h" + +class ConfigurationCallback { +public: + virtual ~ConfigurationCallback(){} + virtual void volumeChanged(const std::string& device, int value){} + virtual void accountsChanged(void){} + virtual void historyChanged(void){} + virtual void stunStatusFailure(const std::string& account_id){} + virtual void registrationStateChanged(const std::string& account_id, const std::string& state, int code, const std::string& detail_str){} + virtual void volatileAccountDetailsChanged(const std::string& account_id, const std::map<std::string, std::string>& details){} + virtual void incomingAccountMessage(const std::string& /*account_id*/, const std::string& /*from*/, const std::map<std::string, std::string>& /*payload*/){} + virtual void accountMessageStatusChanged(const std::string& /*account_id*/, uint64_t /*message_id*/, const std::string& /*to*/, int /*state*/){} + virtual void knownDevicesChanged(const std::string& /*account_id*/, const std::map<std::string, std::string>& /*devices*/){} + virtual void exportOnRingEnded(const std::string& /*account_id*/, int /*state*/, const std::string& /*pin*/){} + + virtual void incomingTrustRequest(const std::string& /*account_id*/, const std::string& /*from*/, const std::vector<uint8_t>& /*payload*/, time_t received){} + virtual void contactAdded(const std::string& /*account_id*/, const std::string& /*uri*/, bool confirmed){} + virtual void contactRemoved(const std::string& /*account_id*/, const std::string& /*uri*/, bool banned){} + + virtual void certificatePinned(const std::string& /*certId*/){} + virtual void certificatePathPinned(const std::string& /*path*/, const std::vector<std::string>& /*certId*/){} + virtual void certificateExpired(const std::string& /*certId*/){} + virtual void certificateStateChanged(const std::string& /*account_id*/, const std::string& /*certId*/, const std::string& /*state*/){} + + virtual void errorAlert(int alert){} + + virtual void nameRegistrationEnded(const std::string& /*account_id*/, int state, const std::string& /*name*/){} + virtual void registeredNameFound(const std::string& /*account_id*/, int state, const std::string& /*address*/, const std::string& /*name*/){} + + virtual void migrationEnded(const std::string& /*accountId*/, const std::string& /*state*/){} + virtual void deviceRevocationEnded(const std::string& /*accountId*/, const std::string& /*device*/, int /*status*/){} +}; +%} + +%feature("director") ConfigurationCallback; + +namespace DRing { + +std::map<std::string, std::string> getAccountDetails(const std::string& accountID); +std::map<std::string, std::string> getVolatileAccountDetails(const std::string& accountID); +void setAccountDetails(const std::string& accountID, const std::map<std::string, std::string>& details); +void setAccountActive(const std::string& accountID, bool active); +std::map<std::string, std::string> getAccountTemplate(const std::string& accountType); +std::string addAccount(const std::map<std::string, std::string>& details); +void removeAccount(const std::string& accountID); +std::vector<std::string> getAccountList(); +void sendRegister(const std::string& accountID, bool enable); +void registerAllAccounts(void); +uint64_t sendAccountTextMessage(const std::string& accountID, const std::string& to, const std::map<std::string, std::string>& message); +int getMessageStatus(uint64_t id); + +bool lookupName(const std::string& account, const std::string& nameserver, const std::string& name); +bool lookupAddress(const std::string& account, const std::string& nameserver, const std::string& address); +bool registerName(const std::string& account, const std::string& password, const std::string& name); + +std::map<std::string, std::string> getTlsDefaultSettings(); + +std::vector<unsigned> getCodecList(); +std::vector<std::string> getSupportedTlsMethod(); +std::vector<std::string> getSupportedCiphers(const std::string& accountID); +std::map<std::string, std::string> getCodecDetails(const std::string& accountID, const unsigned& codecId); +bool setCodecDetails(const std::string& accountID, const unsigned& codecId, const std::map<std::string, std::string>& details); +std::vector<unsigned> getActiveCodecList(const std::string& accountID); +std::string exportOnRing(const std::string& accountID, const std::string& password); + +std::map<std::string, std::string> getKnownRingDevices(const std::string& accountID); +bool revokeDevice(const std::string& accountID, const std::string& password, const std::string& deviceID); + +void setActiveCodecList(const std::string& accountID, const std::vector<unsigned>& list); + +std::vector<std::string> getAudioPluginList(); +void setAudioPlugin(const std::string& audioPlugin); +std::vector<std::string> getAudioOutputDeviceList(); +void setAudioOutputDevice(int32_t index); +void setAudioInputDevice(int32_t index); +void setAudioRingtoneDevice(int32_t index); +std::vector<std::string> getAudioInputDeviceList(); +std::vector<std::string> getCurrentAudioDevicesIndex(); +int32_t getAudioInputDeviceIndex(const std::string& name); +int32_t getAudioOutputDeviceIndex(const std::string& name); +std::string getCurrentAudioOutputPlugin(); +bool getNoiseSuppressState(); +void setNoiseSuppressState(bool state); + +bool isAgcEnabled(); +void setAgcState(bool enabled); + +void muteDtmf(bool mute); +bool isDtmfMuted(); + +bool isCaptureMuted(); +void muteCapture(bool mute); +bool isPlaybackMuted(); +void mutePlayback(bool mute); +bool isRingtoneMuted(); +void muteRingtone(bool mute); + +std::string getAudioManager(); +bool setAudioManager(const std::string& api); + +std::string getRecordPath(); +void setRecordPath(const std::string& recPath); +bool getIsAlwaysRecording(); +void setIsAlwaysRecording(bool rec); + +void setHistoryLimit(int32_t days); +int32_t getHistoryLimit(); + +void setAccountsOrder(const std::string& order); + +std::map<std::string, std::string> getHookSettings(); +void setHookSettings(const std::map<std::string, std::string>& settings); + +std::vector<std::map<std::string, std::string> > getCredentials(const std::string& accountID); +void setCredentials(const std::string& accountID, const std::vector<std::map<std::string, std::string> >& details); + +std::string getAddrFromInterfaceName(const std::string& interface); + +std::vector<std::string> getAllIpInterface(); +std::vector<std::string> getAllIpInterfaceByName(); + +std::map<std::string, std::string> getShortcuts(); +void setShortcuts(const std::map<std::string, std::string> &shortcutsMap); + +void setVolume(const std::string& device, double value); +double getVolume(const std::string& device); + +/* + * Security + */ +std::map<std::string, std::string> validateCertificatePath(const std::string& accountId, + const std::string& certificate, + const std::string& privateKey, + const std::string& privateKeyPassword, + const std::string& caList); + +std::map<std::string, std::string> validateCertificate(const std::string& accountId, const std::string& certificate); + +std::map<std::string, std::string> getCertificateDetails(const std::string& certificate); +std::map<std::string, std::string> getCertificateDetailsPath(const std::string& certificate, const std::string& privateKey, const std::string& privateKeyPass); + +std::vector<std::string> getPinnedCertificates(); + +std::vector<std::string> pinCertificate(const std::vector<uint8_t>& certificate, bool local); +bool unpinCertificate(const std::string& certId); + +void pinCertificatePath(const std::string& path); +unsigned unpinCertificatePath(const std::string& path); + +bool pinRemoteCertificate(const std::string& accountId, const std::string& certId); +bool setCertificateStatus(const std::string& account, const std::string& certId, const std::string& status); +std::vector<std::string> getCertificatesByStatus(const std::string& account, const std::string& status); + +/* contact requests */ +std::vector<std::map<std::string, std::string>> getTrustRequests(const std::string& accountId); +bool acceptTrustRequest(const std::string& accountId, const std::string& from); +bool discardTrustRequest(const std::string& accountId, const std::string& from); +void sendTrustRequest(const std::string& accountId, const std::string& to, const std::vector<uint8_t>& payload); + +/* Contacts */ + +void addContact(const std::string& accountId, const std::string& uri); +void removeContact(const std::string& accountId, const std::string& uri, const bool& ban); +std::vector<std::map<std::string, std::string>> getContacts(const std::string& accountId); + +int exportAccounts(std::vector<std::string> accountIDs, std::string toDir, std::string password); +int importAccounts(std::string archivePath, std::string password); + +void connectivityChanged(); +} + +class ConfigurationCallback { +public: + virtual ~ConfigurationCallback(){} + virtual void volumeChanged(const std::string& device, int value){} + virtual void accountsChanged(void){} + virtual void historyChanged(void){} + virtual void stunStatusFailure(const std::string& account_id){} + virtual void registrationStateChanged(const std::string& account_id, const std::string& state, int code, const std::string& detail_str){} + virtual void volatileAccountDetailsChanged(const std::string& account_id, const std::map<std::string, std::string>& details){} + virtual void incomingAccountMessage(const std::string& /*account_id*/, const std::string& /*from*/, const std::map<std::string, std::string>& /*payload*/){} + virtual void accountMessageStatusChanged(const std::string& /*account_id*/, uint64_t /*message_id*/, const std::string& /*to*/, int /*state*/){} + virtual void knownDevicesChanged(const std::string& /*account_id*/, const std::map<std::string, std::string>& /*devices*/){} + virtual void exportOnRingEnded(const std::string& /*account_id*/, int /*state*/, const std::string& /*pin*/){} + + virtual void incomingTrustRequest(const std::string& /*account_id*/, const std::string& /*from*/, const std::vector<uint8_t>& /*payload*/, time_t received){} + virtual void contactAdded(const std::string& /*account_id*/, const std::string& /*uri*/, bool confirmed){} + virtual void contactRemoved(const std::string& /*account_id*/, const std::string& /*uri*/, bool banned){} + + virtual void certificatePinned(const std::string& /*certId*/){} + virtual void certificatePathPinned(const std::string& /*path*/, const std::vector<std::string>& /*certId*/){} + virtual void certificateExpired(const std::string& /*certId*/){} + virtual void certificateStateChanged(const std::string& /*account_id*/, const std::string& /*certId*/, const std::string& /*state*/){} + + virtual void errorAlert(int alert){} + + virtual void nameRegistrationEnded(const std::string& /*account_id*/, int state, const std::string& /*name*/){} + virtual void registeredNameFound(const std::string& /*account_id*/, int state, const std::string& /*address*/, const std::string& /*name*/){} + + virtual void migrationEnded(const std::string& /*accountId*/, const std::string& /*state*/){} + virtual void deviceRevocationEnded(const std::string& /*accountId*/, const std::string& /*device*/, int /*status*/){} +}; diff --git a/bin/nodejs/index.js b/bin/nodejs/index.js new file mode 100755 index 0000000000000000000000000000000000000000..5c9ea4eba3c0c15942ff31cea159d30d8220b190 --- /dev/null +++ b/bin/nodejs/index.js @@ -0,0 +1,124 @@ +/* + * 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 + * 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, see <https://www.gnu.org/licenses/>. + */ + + +"use strict"; +class RingDaemon{ + constructor(callbackMap) { + if(callbackMap){ + this.dring = require("./build/Release/dring"); + this.dring.init(callbackMap); + var that = this; + this.pollIntervalId = setInterval(function () { + that.dring.pollEvents(); + //console.log("Polling..."); + }, 10); + } + } + + boolToStr(bool){ + if(bool) + return "TRUE"; + else + return "FALSE"; + } + + addAccount(account) { + var params = new this.dring.StringMap(); + params.set("Account.type", "RING"); + if(account.archivePassword){ + params.set("Account.archivePassword", account.archivePassword); + } else { + console.log("archivePassword required"); + return; + } + if(account.alias) + params.set("Account.alias", account.alias); + if(account.displayName) + params.set("Account.displayName", account.displayName); + if(account.enable) + params.set("Account.enable", this.boolToStr(account.enable)); + if(account.autoAnswer) + params.set("Account.autoAnswer", this.boolToStr(account.autoAnswer)); + if(account.ringtonePath) + params.set("Account.ringtonePath", account.ringtonePath); + if(account.ringtoneEnabled) + params.set("Account.ringtoneEnabled", this.boolToStr(account.ringtoneEnabled)); + if(account.videoEnabled) + params.set("Account.videoEnabled", this.boolToStr(account.videoEnabled)); + if(account.useragent){ + params.set("Account.useragent", account.useragent); + params.set("Account.hasCustomUserAgent","TRUE"); + } else { + params.set("Account.hasCustomUserAgent","FALSE"); + } + if(account.audioPortMin) + params.set("Account.audioPortMin", account.audioPortMin); + if(account.audioPortMax) + params.set("Account.audioPortMax", account.audioPortMax); + if(account.videoPortMin) + params.set("Account.videoPortMin", account.videoPortMin); + if(account.videoPortMax) + params.set("Account.videoPortMax", account.videoPortMax); + if(account.localInterface) + params.set("Account.localInterface", account.localInterface); + if(account.publishedSameAsLocal) + params.set("Account.publishedSameAsLocal", this.boolToStr(account.publishedSameAsLocal)); + if(account.localPort) + params.set("Account.localPort", account.localPort); + if(account.publishedPort) + params.set("Account.publishedPort", account.publishedPort); + if(account.publishedAddress) + params.set("Account.publishedAddress", account.publishedAddress); + if(account.upnpEnabled) + params.set("Account.upnpEnabled", this.boolToStr(account.upnpEnabled)); + + this.dring.addAccount(params); + } + + getAudioOutputDeviceList() { + var devicesVect = this.dring.getAudioOutputDeviceList(); + var outputDevices = []; + for(var i=0; i<devicesVect.size(); i++) + outputDevices.push(devicesVect.get(i)); + + return outputDevices; + } + + getVolume(deviceName) { + return this.dring.getVolume(deviceName); + } + + setVolume(deviceName, volume) { + return this.dring.setVolume(deviceName,volume); + } + + stop() { + clearInterval(this.pollIntervalId); + this.dring.fini(); + } +} + +var f = function(){ + console.log("RegistrationStateChanged JS"); +}; + +var daemon = new RingDaemon({"RegistrationStateChanged": f}); +//daemon.stop(); \ No newline at end of file diff --git a/bin/nodejs/managerimpl.i b/bin/nodejs/managerimpl.i new file mode 100644 index 0000000000000000000000000000000000000000..d24a42572156b4c93ab576390d24b9d11c28fbff --- /dev/null +++ b/bin/nodejs/managerimpl.i @@ -0,0 +1,39 @@ +/* + * 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. + */ + +/* %nodefaultctor ManagerImpl; +%nodefaultdtor ManagerImpl; */ +%header %{ +#include "dring/dring.h" +%} + +namespace DRing { + +/** + * Finalizes libsflphone, freeing any resource allocated by the library. + */ +void fini(void); + +/** + * Poll for events + */ +void pollEvents(void); + +} diff --git a/bin/nodejs/nodejs_interface.i b/bin/nodejs/nodejs_interface.i new file mode 100644 index 0000000000000000000000000000000000000000..85d4c60118534164da3488ec5e8797e9730435f6 --- /dev/null +++ b/bin/nodejs/nodejs_interface.i @@ -0,0 +1,167 @@ +/* + * 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 "callmanager.i" +%include "videomanager.i" +//#include "dring/callmanager_interface.h" + +%header %{ +#include "callback.h" +%} + +//typemap for passing Callbacks +%typemap(in) v8::Local<v8::Function> { + $1 = v8::Local<v8::Function>::Cast($input); +} + +//typemap for handling map of functions +%typemap(in) const v8::Handle<v8::Value> { + $1 = $input; +} + + +%inline %{ +/* some functions that need to be declared in *_wrap.cpp + * that are not declared elsewhere in the c++ code + */ + +void init(const v8::Handle<v8::Value> &funcMap){ + parseCbMap(funcMap); + uv_async_init(uv_default_loop(), &signalAsync, handlePendingSignals); + + using namespace std::placeholders; + using std::bind; + using DRing::exportable_callback; + using DRing::ConfigurationSignal; + using DRing::CallSignal; + using SharedCallback = std::shared_ptr<DRing::CallbackWrapperBase>; + const std::map<std::string, SharedCallback> callEvHandlers = { + exportable_callback<CallSignal::StateChange>(bind(&callStateChanged, _1, _2, _3)), + exportable_callback<CallSignal::IncomingMessage>(bind(&incomingMessage, _1, _2, _3)), + exportable_callback<CallSignal::IncomingCall>(bind(&incomingCall, _1, _2, _3)), + exportable_callback<CallSignal::NewCallCreated>(bind(&newCallCreated, _1, _2, _3)) + }; + + const std::map<std::string, SharedCallback> configEvHandlers = { + exportable_callback<ConfigurationSignal::AccountsChanged>(bind(&accountsChanged)), + exportable_callback<ConfigurationSignal::RegistrationStateChanged>(bind(®istrationStateChanged, _1, _2, _3, _4)), + exportable_callback<ConfigurationSignal::ContactAdded>(bind(&contactAdded, _1, _2, _3 )), + exportable_callback<ConfigurationSignal::ContactRemoved>(bind(&contactRemoved, _1, _2, _3 )), + exportable_callback<ConfigurationSignal::ExportOnRingEnded>(bind(&exportOnRingEnded, _1, _2, _3 )), + exportable_callback<ConfigurationSignal::NameRegistrationEnded>(bind(&nameRegistrationEnded, _1, _2, _3 )), + exportable_callback<ConfigurationSignal::RegisteredNameFound>(bind(®isteredNameFound, _1, _2, _3, _4 )), + exportable_callback<ConfigurationSignal::VolatileDetailsChanged>(bind(&volatileDetailsChanged, _1, _2)), + exportable_callback<ConfigurationSignal::KnownDevicesChanged>(bind(&knownDevicesChanged, _1, _2 )), + exportable_callback<ConfigurationSignal::IncomingAccountMessage>(bind(&incomingAccountMessage, _1, _2, _3 )), + exportable_callback<ConfigurationSignal::AccountMessageStatusChanged>(bind(&accountMessageStatusChanged, _1, _2, _3, _4 )), + exportable_callback<ConfigurationSignal::IncomingTrustRequest>(bind(&incomingTrustRequest, _1, _2, _3, _4 )), + }; + + if (!DRing::init(static_cast<DRing::InitFlag>(DRing::DRING_FLAG_DEBUG))) + return; + + registerConfHandlers(configEvHandlers); + registerCallHandlers(callEvHandlers); + + DRing::start(); +} +%} +#ifndef SWIG +/* some bad declarations */ +#endif \ No newline at end of file diff --git a/bin/nodejs/presencemanager.i b/bin/nodejs/presencemanager.i new file mode 100644 index 0000000000000000000000000000000000000000..5fe2302e6c47b26ca03b3b14e14fd440158c4a5e --- /dev/null +++ b/bin/nodejs/presencemanager.i @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2017 Savoir-faire Linux Inc. + * + * Author: Aline Bonnet <aline.bonnet@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, see <http://www.gnu.org/licenses/>. + */ + +%header %{ + +#include "dring/dring.h" +#include "dring/presencemanager_interface.h" + +class PresenceCallback { +public: + virtual ~PresenceCallback(){} + virtual void newServerSubscriptionRequest(const std::string& /*remote*/){} + virtual void serverError(const std::string& /*account_id*/, const std::string& /*error*/, const std::string& /*msg*/){} + virtual void newBuddyNotification(const std::string& /*account_id*/, const std::string& /*buddy_uri*/, int /*status*/, const std::string& /*line_status*/){} + virtual void subscriptionStateChanged(const std::string& /*account_id*/, const std::string& /*buddy_uri*/, int /*state*/){} +}; +%} + +%feature("director") PresenceCallback; + +namespace DRing { + +/* Presence subscription/Notification. */ +void publish(const std::string& accountID, bool status, const std::string& note); +void answerServerRequest(const std::string& uri, bool flag); +void subscribeBuddy(const std::string& accountID, const std::string& uri, bool flag); +std::vector<std::map<std::string, std::string>> getSubscriptions(const std::string& accountID); +void setSubscriptions(const std::string& accountID, const std::vector<std::string>& uris); +} + +class PresenceCallback { +public: + virtual ~PresenceCallback(){} + virtual void newServerSubscriptionRequest(const std::string& /*remote*/){} + virtual void serverError(const std::string& /*account_id*/, const std::string& /*error*/, const std::string& /*msg*/){} + virtual void newBuddyNotification(const std::string& /*account_id*/, const std::string& /*buddy_uri*/, int /*status*/, const std::string& /*line_status*/){} + virtual void subscriptionStateChanged(const std::string& /*account_id*/, const std::string& /*buddy_uri*/, int /*state*/){} +}; \ No newline at end of file diff --git a/bin/nodejs/videomanager.i b/bin/nodejs/videomanager.i new file mode 100644 index 0000000000000000000000000000000000000000..87a0cc4267ae73169819a19967d88d7e218fecb7 --- /dev/null +++ b/bin/nodejs/videomanager.i @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2015-2016 Savoir-faire Linux Inc. + * + * Authors: Damien Riegel <damien.riegel@savoirfairelinux.com> + * Adrien Béraud <adrien.beraud@savoirfairelinux.com> + * Ciro Santilli <ciro.santilli@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, see <http://www.gnu.org/licenses/>. + */ + +%header %{ +#include <functional> +#include <list> +#include <mutex> + +#include "dring/dring.h" +#include "dring/videomanager_interface.h" + +class VideoCallback { +public: + virtual ~VideoCallback(){} + virtual void getCameraInfo(const std::string& device, std::vector<int> *formats, std::vector<unsigned> *sizes, std::vector<unsigned> *rates) {} + virtual void setParameters(const std::string, const int format, const int width, const int height, const int rate) {} + virtual void startCapture(const std::string& camid) {} + virtual void stopCapture() {} + virtual void decodingStarted(const std::string& id, const std::string& shm_path, int w, int h, bool is_mixer) {} + virtual void decodingStopped(const std::string& id, const std::string& shm_path, bool is_mixer) {} +}; +%} + +%feature("director") VideoCallback; + +namespace DRing { + +void setDefaultDevice(const std::string& name); +std::string getDefaultDevice(); + +void startCamera(); +void stopCamera(); +bool hasCameraStarted(); +bool switchInput(const std::string& resource); +bool switchToCamera(); +std::map<std::string, std::string> getSettings(const std::string& name); +void applySettings(const std::string& name, const std::map<std::string, std::string>& settings); + +void registerSinkTarget(const std::string& sinkId, const DRing::SinkTarget& target); +} + +class VideoCallback { +public: + virtual ~VideoCallback(){} + virtual void getCameraInfo(const std::string& device, std::vector<int> *formats, std::vector<unsigned> *sizes, std::vector<unsigned> *rates){} + virtual void setParameters(const std::string, const int format, const int width, const int height, const int rate) {} + virtual void startCapture(const std::string& camid) {} + virtual void stopCapture() {} + virtual void decodingStarted(const std::string& id, const std::string& shm_path, int w, int h, bool is_mixer) {} + virtual void decodingStopped(const std::string& id, const std::string& shm_path, bool is_mixer) {} +}; diff --git a/configure.ac b/configure.ac index 3ee14ce5bb71621d6d98855855e78f4f710b4a73..a10c41b35d32b9b8b5c7ad420c6b1765799dc3a7 100644 --- a/configure.ac +++ b/configure.ac @@ -390,6 +390,20 @@ AC_ARG_ENABLE([ringns], AS_HELP_STRING([--disable-ringns], [Enable Ring Name Ser AM_CONDITIONAL([RINGNS], test "x$enable_ringns" != "xno", [Define if you use the Ring Name Service]) AC_DEFINE_UNQUOTED([HAVE_RINGNS], `if test "x$enable_ringns" != "xno"; then echo 1; else echo 0; fi`, [Define if you use the Ring Name Service]) +dnl Ring nodejs module +AC_ARG_WITH([nodejs], AS_HELP_STRING([--with-nodejs], [Enable Ring NodeJS module])) +AM_CONDITIONAL([RING_NODEJS], test "x$enable_nodejs" != "xno", [Define if you use the Ring NodeJS module]) +AC_DEFINE_UNQUOTED([HAVE_NODEJS], `if test "x$enable_ringns" != "xno"; then echo 1; else echo 0; fi`, [Define if you use the Ring NodeJS module]) +AS_IF([test "x$with_nodejs" = "xyes"], [ + AC_PATH_PROG(SWIG, swig, "") + AS_AC_EXPAND(SBINDIR, $sbindir) + AC_SUBST(SBINDIR) + AC_CONFIG_FILES([bin/nodejs/Makefile]) + AM_CONDITIONAL(RING_NODEJS, true) + ], + AM_CONDITIONAL(RING_NODEJS, false) +); + # Rest C++ with restbed AC_ARG_WITH([restcpp], AS_HELP_STRING([--with-restcpp], [enable rest support with C++]))