From e93cb3415e883bbd73528ca6a08e53e854f7bee0 Mon Sep 17 00:00:00 2001 From: Romain Forlot Date: Thu, 21 Sep 2017 08:50:38 +0200 Subject: Find all signals that matches the searched pattern Change-Id: Ia562fbd90aaeaa57c1c731d0f66dd31865db7e71 Signed-off-by: Romain Forlot --- .../signal-composer-binding.cpp | 43 +++++++++- signal-composer-binding/signal-composer.cpp | 96 +++++++++++++--------- signal-composer-binding/signal-composer.hpp | 3 +- signal-composer-binding/signal.cpp | 10 +-- signal-composer-binding/source.cpp | 8 +- signal-composer-binding/source.hpp | 2 +- 6 files changed, 109 insertions(+), 53 deletions(-) diff --git a/signal-composer-binding/signal-composer-binding.cpp b/signal-composer-binding/signal-composer-binding.cpp index 269eaba..5dcb53f 100644 --- a/signal-composer-binding/signal-composer-binding.cpp +++ b/signal-composer-binding/signal-composer-binding.cpp @@ -35,16 +35,53 @@ void onEvent(const char *event, json_object *object) AFB_DEBUG("Received event json: %s", json_object_to_json_string(object)); bindingApp& bApp = bindingApp::instance(); - std::shared_ptr sig = bApp.searchSignal(event); - if(sig != nullptr) + std::vector> signals = bApp.searchSignals(event); + if(!signals.empty()) { - sig->onReceivedCB(object); + for(auto& sig: signals) + { + sig->onReceivedCB(object); + } } } +static int one_subscribe_unsubscribe(struct afb_req request, + bool subscribe, + const std::string& tag, + json_object* args) +{ + return 1; +} + /// @brief entry point for client subscription request. void subscribe(afb_req request) { + int rc,rc2,n; + json_object *event, *args = afb_req_json(request); + if (args == NULL || + !json_object_object_get_ex(args, "event", &event) || + !json_object_object_get_ex(args, "events", &event) || + !json_object_object_get_ex(args, "signal", &event) || + !json_object_object_get_ex(args, "signals", &event)) + { + rc = one_subscribe_unsubscribe(request, subscribe, "*", args); + } + else if (json_object_get_type(event) != json_type_array) + { + rc = one_subscribe_unsubscribe(request, subscribe, json_object_get_string(event), args); + } + else + { + rc = 0; + n = json_object_array_length(event); + for (int i = 0 ; i < n ; i++) + { + json_object *x = json_object_array_get_idx(event, i); + rc2 = one_subscribe_unsubscribe(request, subscribe, json_object_get_string(x), args); + if (rc >= 0) + rc = rc2 >= 0 ? rc + rc2 : rc2; + } + } if(true) afb_req_success(request, NULL, NULL); else diff --git a/signal-composer-binding/signal-composer.cpp b/signal-composer-binding/signal-composer.cpp index 2e4f221..0eba8a2 100644 --- a/signal-composer-binding/signal-composer.cpp +++ b/signal-composer-binding/signal-composer.cpp @@ -22,9 +22,14 @@ extern "C" void setSignalValueHandle(const char* aName, long long int timestamp, struct SignalValue value) { - std::shared_ptr sig = bindingApp::instance().searchSignal(aName); - if(sig) - {sig->set(timestamp, value);} + std::vector> signals = bindingApp::instance().searchSignals(aName); + if(!signals.empty()) + { + for(auto& sig: signals) + { + sig->set(timestamp, value); + } + } } bool startsWith(const std::string& str, const std::string& pattern) @@ -376,15 +381,16 @@ int bindingApp::loadSignals(json_object* signalsJ) return loadSignals(nullptr, signalsJ); } -std::shared_ptr bindingApp::searchSignal(const std::string& aName) +std::vector> bindingApp::searchSignals(const std::string& aName) { std::string api; + std::vector> signals; size_t sep = aName.find_first_of("/"); if(sep != std::string::npos) { api = aName.substr(0, sep); SourceAPI* source = getSourceAPI(api); - return source->searchSignal(aName); + return source->searchSignals(aName); } else { @@ -392,10 +398,10 @@ std::shared_ptr bindingApp::searchSignal(const std::string& aName) for (std::shared_ptr& sig : allSignals) { if(*sig == aName) - {return sig;} + {signals.emplace_back(sig);} } } - return nullptr; + return signals; } std::vector> bindingApp::getAllSignals() @@ -428,48 +434,36 @@ int bindingApp::execSubscription() return err; } -json_object* bindingApp::getSignalValue(const std::string& sig, json_object* options) +void bindingApp::processOptions(const char** opts, std::shared_ptr sig, json_object* response) const { - const char **opts = nullptr; - json_object *response = nullptr; - - wrap_json_unpack(options, "{s?s?s?s?!}", - &opts[0], - &opts[1], - &opts[2], - &opts[3]); - - std::shared_ptr sigP = searchSignal(sig); - wrap_json_pack(&response, "{ss}", - "signal", sigP->id().c_str()); for(int idx=0; idx < sizeof(opts); idx++) { bool avg = false, min = false, max = false, last = false; if (strcasestr(opts[idx], "average") && !avg) { avg = true; - double value = sigP->average(); + double value = sig->average(); json_object_object_add(response, "average", json_object_new_double(value)); } if (strcasestr(opts[idx], "min") && !min) { min = true; - double value = sigP->minimum(); + double value = sig->minimum(); json_object_object_add(response, "min", json_object_new_double(value)); } if (strcasestr(opts[idx], "max") && !max) { max = true; - double value = sigP->maximum(); + double value = sig->maximum(); json_object_object_add(response, "max", json_object_new_double(value)); } if (strcasestr(opts[idx], "last") && !last) { last = true; - struct SignalValue value = sigP->last(); + struct SignalValue value = sig->last(); if(value.hasBool) { json_object_object_add(response, "last", @@ -487,24 +481,48 @@ json_object* bindingApp::getSignalValue(const std::string& sig, json_object* opt } } } +} +json_object* bindingApp::getSignalValue(const std::string& sig, json_object* options) +{ + const char **opts = nullptr; + json_object *response = nullptr, *finalResponse = json_object_new_array(); - if (!opts) + wrap_json_unpack(options, "{s?s?s?s?!}", + &opts[0], + &opts[1], + &opts[2], + &opts[3]); + + + std::vector> sigP = searchSignals(sig); + if(!sigP.empty()) { - struct SignalValue value = sigP->last(); - if(value.hasBool) - { - json_object_object_add(response, "last", - json_object_new_boolean(value.boolVal)); - } - if(value.hasNum) - { - json_object_object_add(response, "last", - json_object_new_double(value.numVal)); - } - if(value.hasStr) + for(auto& sig: sigP) { - json_object_object_add(response, "last", - json_object_new_string(value.strVal.c_str())); + wrap_json_pack(&response, "{ss}", + "signal", sig->id().c_str()); + if (!opts) + { + struct SignalValue value = sig->last(); + if(value.hasBool) + { + json_object_object_add(response, "last", + json_object_new_boolean(value.boolVal)); + } + if(value.hasNum) + { + json_object_object_add(response, "last", + json_object_new_double(value.numVal)); + } + if(value.hasStr) + { + json_object_object_add(response, "last", + json_object_new_string(value.strVal.c_str())); + } + } + else + {processOptions(opts, sig, response);} + json_object_array_add(finalResponse, response); } } diff --git a/signal-composer-binding/signal-composer.hpp b/signal-composer-binding/signal-composer.hpp index 689f107..5cf5858 100644 --- a/signal-composer-binding/signal-composer.hpp +++ b/signal-composer-binding/signal-composer.hpp @@ -52,8 +52,9 @@ public: int initSourcesAPI(); std::vector> getAllSignals(); SourceAPI* getSourceAPI(const std::string& api); - std::shared_ptr searchSignal(const std::string& aName); + std::vector> searchSignals(const std::string& aName); json_object* getSignalValue(const std::string& sig, json_object* options); + void processOptions(const char** opts, std::shared_ptr sig, json_object* response) const; int execSubscription(); }; diff --git a/signal-composer-binding/signal.cpp b/signal-composer-binding/signal.cpp index 309a156..a9a18b0 100644 --- a/signal-composer-binding/signal.cpp +++ b/signal-composer-binding/signal.cpp @@ -16,8 +16,6 @@ */ #include -#include -#include #include "signal.hpp" #include "signal-composer.hpp" @@ -67,7 +65,7 @@ bool Signal::operator ==(const Signal& other) const bool Signal::operator ==(const std::string& aName) const { - if(! fnmatch(aName.c_str(), id_.c_str(), FNM_CASEFOLD)) {return true;} + if(id_.find(aName) != std::string::npos) {return true;} if(event_.find(aName) != std::string::npos) {return true;} return false; @@ -168,11 +166,11 @@ void Signal::attachToSourceSignals(bindingApp& bApp) { if(srcSig.find("/") == std::string::npos) { - std::shared_ptr sig = bApp.searchSignal(srcSig); - if(sig) + std::vector> sig = bApp.searchSignals(srcSig); + if(sig[0]) { AFB_NOTICE("Attaching %s to %s", id_.c_str(), srcSig.c_str()); - sig->attach(this); + sig[0]->attach(this); continue; } AFB_WARNING("Can't attach. Is %s exists ?", srcSig.c_str()); diff --git a/signal-composer-binding/source.cpp b/signal-composer-binding/source.cpp index 2f4ab03..8481740 100644 --- a/signal-composer-binding/source.cpp +++ b/signal-composer-binding/source.cpp @@ -59,13 +59,15 @@ std::vector> SourceAPI::getSignals() const return signals; } -std::shared_ptr SourceAPI::searchSignal(const std::string& name) const +std::vector> SourceAPI::searchSignals(const std::string& name) const { + std::vector> signals; for (auto& sig: signalsMap_) { - if(*sig.first == name) {return sig.first;} + if(*sig.first == name) + {signals.emplace_back(sig.first);} } - return nullptr; + return signals; } int SourceAPI::makeSubscription() diff --git a/signal-composer-binding/source.hpp b/signal-composer-binding/source.hpp index a995b07..0885bf0 100644 --- a/signal-composer-binding/source.hpp +++ b/signal-composer-binding/source.hpp @@ -39,7 +39,7 @@ public: void addSignal(const std::string& id, const std::string& event, std::vector& sources, const std::string& sClass, const std::string& unit, double frequency, CtlActionT* onReceived, json_object* getSignalsArgs); std::vector> getSignals() const; - std::shared_ptr searchSignal(const std::string& name) const; + std::vector> searchSignals(const std::string& name) const; int makeSubscription(); }; -- cgit 1.2.3-korg