From 677cde6288a4574b8251a4a532b1d9e1594b09b2 Mon Sep 17 00:00:00 2001 From: Romain Forlot Date: Fri, 15 Sep 2017 16:29:17 +0200 Subject: Subscription by plugin to signals Change-Id: Icb923f87df2be8eb664106bc9077b3a8221dd3ce Signed-off-by: Romain Forlot --- .../signal-composer-binding.cpp | 21 +++++++----- signal-composer-binding/signal-composer.cpp | 37 ++++++++++++++------ signal-composer-binding/signal-composer.hpp | 6 ++-- signal-composer-binding/signal.cpp | 39 +++++++++++++++++++--- signal-composer-binding/signal.hpp | 7 ++-- signal-composer-binding/source.cpp | 26 +++++++++++++-- signal-composer-binding/source.hpp | 4 ++- 7 files changed, 106 insertions(+), 34 deletions(-) (limited to 'signal-composer-binding') diff --git a/signal-composer-binding/signal-composer-binding.cpp b/signal-composer-binding/signal-composer-binding.cpp index 860de07..5ff24b0 100644 --- a/signal-composer-binding/signal-composer-binding.cpp +++ b/signal-composer-binding/signal-composer-binding.cpp @@ -85,41 +85,44 @@ void get(afb_req request) int loadConf() { - int ret = 0; + int err = 0; const char* rootdir = strncat(GetBindingDirPath(), "/etc", sizeof(GetBindingDirPath()) - strlen(GetBindingDirPath()) -1); bindingApp& bApp = bindingApp::instance(); - ret = bApp.loadConfig(rootdir); + err = bApp.loadConfig(rootdir); #ifdef CONTROL_SUPPORT_LUA - ret += LuaConfigLoad(); + err += LuaConfigLoad(); #endif - return ret; + return err; } int execConf() { bindingApp& bApp = bindingApp::instance(); - int ret = CtlConfigExec(bApp.ctlConfig()); + int err = 0; + CtlConfigExec(bApp.ctlConfig()); std::vector> allSignals = bApp.getAllSignals(); ssize_t sigCount = allSignals.size(); for( std::shared_ptr& sig: allSignals) { - sig->attachToSources(bApp); + sig->attachToSourceSignals(bApp); } for(auto& sig: allSignals) { - if( (ret = sig->recursionCheck()) ) + if( (err += sig->recursionCheck()) ) { AFB_ERROR("There is an infinite recursion loop in your signals definition. Root coming from signal: %s", sig->id().c_str()); - return ret; + return err; } } + bApp.execSubscription(); + AFB_DEBUG("Signal Composer Control configuration Done.\n signals=%d", (int)sigCount); - return ret; + return err; } diff --git a/signal-composer-binding/signal-composer.cpp b/signal-composer-binding/signal-composer.cpp index a1300e3..3158797 100644 --- a/signal-composer-binding/signal-composer.cpp +++ b/signal-composer-binding/signal-composer.cpp @@ -114,7 +114,7 @@ CtlActionT* bindingApp::convert2Action(const std::string& name, json_object* act int bindingApp::loadOneSourceAPI(json_object* sourceJ) { json_object *initJ = nullptr, *getSignalJ = nullptr; - CtlActionT *initCtl, *getSignalCtl; + CtlActionT *initCtl = nullptr, *getSignalCtl = nullptr; const char *api, *info; int err = wrap_json_unpack(sourceJ, "{ss,s?s,s?o,s?o !}", @@ -205,7 +205,6 @@ int bindingApp::loadOneSignal(json_object* signalJ) } // Process sources JSON object - // TODO: claneys, really needs to factorize JSON array processing if (json_object_get_type(sourcesJ) == json_type_array) { int count = json_object_array_length(sourcesJ); @@ -251,19 +250,22 @@ int bindingApp::loadSignals(CtlSectionT* section, json_object *signalsJ) int err = 0; bindingApp& bApp = instance(); - if (json_object_get_type(signalsJ) == json_type_array) + if(signalsJ) { - int count = json_object_array_length(signalsJ); - - for (int idx = 0; idx < count; idx++) + if (json_object_get_type(signalsJ) == json_type_array) { - json_object *signalJ = json_object_array_get_idx(signalsJ, idx); - err = bApp.loadOneSignal(signalJ); - if (err) return err; + int count = json_object_array_length(signalsJ); + + for (int idx = 0; idx < count; idx++) + { + json_object *signalJ = json_object_array_get_idx(signalsJ, idx); + err = bApp.loadOneSignal(signalJ); + if (err) return err; + } } + else + {err = bApp.loadOneSignal(signalsJ);} } - else - {err = bApp.loadOneSignal(signalsJ);} return err; } @@ -306,3 +308,16 @@ CtlConfigT* bindingApp::ctlConfig() { return ctlConfig_; } + +int bindingApp::execSubscription() const +{ + int err = 0; + for(const SourceAPI& srcAPI: sourcesList_) + { + if (srcAPI.api() != std::string(ctlConfig_->api)) + { + err += srcAPI.makeSubscription(); + } + } + return err; +} diff --git a/signal-composer-binding/signal-composer.hpp b/signal-composer-binding/signal-composer.hpp index 8affc7a..2a79779 100644 --- a/signal-composer-binding/signal-composer.hpp +++ b/signal-composer-binding/signal-composer.hpp @@ -47,8 +47,10 @@ public: int loadConfig(const std::string& filepath); //void loadSignalsFile(std::string signalsFile); + CtlConfigT* ctlConfig(); + std::vector> getAllSignals(); SourceAPI* getSourceAPI(const std::string& api); std::shared_ptr searchSignal(const std::string& aName); - std::vector> getAllSignals(); - CtlConfigT* ctlConfig(); + + int execSubscription() const; }; diff --git a/signal-composer-binding/signal.cpp b/signal-composer-binding/signal.cpp index 0689a99..2dc517c 100644 --- a/signal-composer-binding/signal.cpp +++ b/signal-composer-binding/signal.cpp @@ -26,7 +26,7 @@ Signal::Signal(const std::string& id, double frequency, CtlActionT* onReceived) :id_(id), - sourcesSig_(sources), + signalSigList_(sources), frequency_(frequency), unit_(unit), onReceived_(onReceived) @@ -48,17 +48,46 @@ bool Signal::operator ==(const Signal& other) const bool Signal::operator==(const std::string& aName) const { if(id_ == aName) {return true;} - for( const std::string& src : sourcesSig_) + for( const std::string& src : signalSigList_) { if(src == aName) {return true;} } return false; } -std::string Signal::id() const +const std::string Signal::id() const { return id_; } + +json_object* Signal::toJSON() const +{ + json_object* queryJ = nullptr; + std::vector lowSignalName; + for (const std::string& src: signalSigList_ ) + { + ssize_t sep = src.find_first_of("/"); + if(sep != std::string::npos) + { + lowSignalName.push_back(src.substr(sep+1)); + } + } + json_object* nameArray = json_object_new_array(); + for (const std::string& lowSig: lowSignalName) + { + json_object_array_add(nameArray, json_object_new_string(lowSig.c_str())); + } + /*json_object_object_add(queryJ, "signal", nameArray); + json_object_object_add(queryJ, "unit", json_object_new_string(unit_.c_str())); + json_object_object_add(queryJ, "unit", json_object_new_double(frequency_));*/ + wrap_json_pack(&queryJ, "{so,ss*,sf*}", + "signal", nameArray, + "unit", unit_.c_str(), + "frequency", frequency_); + + return queryJ; +} + void update(double timestamp, double value) { AFB_NOTICE("Got an update from observed signal"); @@ -74,9 +103,9 @@ void Signal::attach(Signal* obs) Observers_.push_back(obs); } -void Signal::attachToSources(bindingApp& bApp) +void Signal::attachToSourceSignals(bindingApp& bApp) { - for (const std::string& srcSig: sourcesSig_) + for (const std::string& srcSig: signalSigList_) { if(srcSig.find("/") == std::string::npos) { diff --git a/signal-composer-binding/signal.hpp b/signal-composer-binding/signal.hpp index cb50c67..4d4c641 100644 --- a/signal-composer-binding/signal.hpp +++ b/signal-composer-binding/signal.hpp @@ -28,7 +28,7 @@ class Signal { private: std::string id_; - std::vector sourcesSig_; + std::vector signalSigList_; long long int timestamp_; double value_; std::map history_; ///< history_ - Hold signal value history in map with @@ -46,11 +46,12 @@ public: bool operator==(const Signal& other) const; bool operator==(const std::string& aName) const; - std::string id() const; + const std::string id() const; + json_object* toJSON() const; void update(long long int timestamp, double value); int onReceivedCB(json_object *queryJ); - void attachToSources(bindingApp& bApp); + void attachToSourceSignals(bindingApp& bApp); void notify(); //virtual double average() const; diff --git a/signal-composer-binding/source.cpp b/signal-composer-binding/source.cpp index 6e7fec2..80c59d6 100644 --- a/signal-composer-binding/source.cpp +++ b/signal-composer-binding/source.cpp @@ -33,19 +33,39 @@ void SourceAPI::addSignal(const std::string& id, std::vector& sourc { std::shared_ptr sig = std::make_shared(id, sources, unit, frequency, onReceived); - signals_.push_back(sig); + signalsList_.push_back(sig); } std::vector> SourceAPI::getSignals() const { - return signals_; + return signalsList_; } std::shared_ptr SourceAPI::searchSignal(const std::string& name) const { - for (auto& sig: signals_) + for (auto& sig: signalsList_) { if(*sig == name) {return sig;} } return nullptr; } + +int SourceAPI::makeSubscription() const +{ + int err = 0; + if(getSignal_) + { + for(std::shared_ptr sig: signalsList_) + { + json_object* lowSignalNameJ = sig->toJSON(); + if(!lowSignalNameJ) + { + AFB_ERROR("Error building JSON query object to subscribe to for signal %s", sig->id().c_str()); + return -1; + } + err += ActionExecOne(getSignal_, lowSignalNameJ); + } + } + + return err; +} diff --git a/signal-composer-binding/source.hpp b/signal-composer-binding/source.hpp index c1644c5..c295b6e 100644 --- a/signal-composer-binding/source.hpp +++ b/signal-composer-binding/source.hpp @@ -28,7 +28,7 @@ private: CtlActionT* init_; CtlActionT* getSignal_; - std::vector> signals_; + std::vector> signalsList_; public: SourceAPI(); @@ -39,4 +39,6 @@ public: std::vector> getSignals() const; std::shared_ptr searchSignal(const std::string& name) const; + + int makeSubscription() const; }; -- cgit 1.2.3-korg