diff options
Diffstat (limited to 'signal-composer-binding')
-rw-r--r-- | signal-composer-binding/CMakeLists.txt | 1 | ||||
-rw-r--r-- | signal-composer-binding/signal-composer-binding.cpp | 3 | ||||
-rw-r--r-- | signal-composer-binding/signal-composer.cpp | 80 | ||||
-rw-r--r-- | signal-composer-binding/signal-composer.hpp | 2 | ||||
-rw-r--r-- | signal-composer-binding/signal.cpp | 52 | ||||
-rw-r--r-- | signal-composer-binding/signal.hpp | 20 | ||||
-rw-r--r-- | signal-composer-binding/source.cpp | 14 |
7 files changed, 125 insertions, 47 deletions
diff --git a/signal-composer-binding/CMakeLists.txt b/signal-composer-binding/CMakeLists.txt index 5255e21..c4eebfd 100644 --- a/signal-composer-binding/CMakeLists.txt +++ b/signal-composer-binding/CMakeLists.txt @@ -37,7 +37,6 @@ PROJECT_TARGET_ADD(signal-composer) # Library dependencies (include updates automatically) TARGET_LINK_LIBRARIES(${TARGET_NAME} - afb-utilities afb-controller ${link_libraries} ) diff --git a/signal-composer-binding/signal-composer-binding.cpp b/signal-composer-binding/signal-composer-binding.cpp index 92bd0cc..5d2667d 100644 --- a/signal-composer-binding/signal-composer-binding.cpp +++ b/signal-composer-binding/signal-composer-binding.cpp @@ -228,8 +228,7 @@ int loadConf() std::string bindingDirPath = GetBindingDirPath(); std::string rootdir = bindingDirPath + "/etc"; - Composer& composer = Composer::instance(); - err = composer.loadConfig(rootdir.c_str()); + err = Composer::instance().loadConfig(rootdir.c_str()); return err; } diff --git a/signal-composer-binding/signal-composer.cpp b/signal-composer-binding/signal-composer.cpp index 4218bae..2a689f8 100644 --- a/signal-composer-binding/signal-composer.cpp +++ b/signal-composer-binding/signal-composer.cpp @@ -21,7 +21,7 @@ #include "clientApp.hpp" -extern "C" void setSignalValueHandle(const char* aName, uint64_t timestamp, struct signalValue value) +extern "C" void searchNsetSignalValueHandle(const char* aName, uint64_t timestamp, struct signalValue value) { std::vector<std::shared_ptr<Signal>> signals = Composer::instance().searchSignals(aName); if(!signals.empty()) @@ -31,6 +31,12 @@ extern "C" void setSignalValueHandle(const char* aName, uint64_t timestamp, stru } } +extern "C" void setSignalValueHandle(void* aSignal, uint64_t timestamp, struct signalValue value) +{ + Signal* sig = static_cast<Signal*>(aSignal); + sig->set(timestamp, value); +} + bool startsWith(const std::string& str, const std::string& pattern) { size_t sep; @@ -39,13 +45,16 @@ bool startsWith(const std::string& str, const std::string& pattern) return false; } +// aSignal member value will be initialized in sourceAPI->addSignal() static struct signalCBT pluginHandle = { + .searchNsetSignalValue = searchNsetSignalValueHandle, .setSignalValue = setSignalValueHandle, + .aSignal = nullptr, }; CtlSectionT Composer::ctlSections_[] = { [0]={.key="plugins" , .label = "plugins", .info=nullptr, - .loadCB=PluginConfig, + .loadCB=pluginsLoad, .handle=&pluginHandle}, [1]={.key="sources" , .label = "sources", .info=nullptr, .loadCB=loadSourcesAPI, @@ -126,23 +135,17 @@ CtlActionT* Composer::convert2Action(const std::string& name, json_object* actio else if(startsWith(function, "builtin://")) { std::string uri = std::string(function).substr(10); - char b[8] = "builtin"; - char* label = strncat(b , name.c_str(), name.size()); std::vector<std::string> uriV = Composer::parseURI(uri); if(uriV.size() > 1) {AFB_WARNING("Too many thing specified. Uri has to be like: builtin://<builtin-function-name>");} - return new CtlActionT { - CTL_TYPE_CB, - nullptr, - uriV[0].c_str(), - functionArgsJ, - Signal::defaultOnReceivedCB, - CtlSourceT{ - label, - nullptr, - {nullptr, nullptr}, - nullptr, - } - }; + + json_object *callbackJ = nullptr; + wrap_json_pack(&callbackJ, "{ss,ss,so*}", + "plugin", "builtin", + "function", uriV[0].c_str(), + "args", functionArgsJ); + wrap_json_pack(&action, "{ss,so}", + "label", name.c_str(), + "callback", callbackJ); } else { @@ -154,6 +157,42 @@ CtlActionT* Composer::convert2Action(const std::string& name, json_object* actio return nullptr; } +/// @brief Add the builtin plugin in the default plugins section definition +/// +/// @param[in] section - Control Section structure +/// @param[in] pluginsJ - JSON object containing all plugins definition made in +/// JSON configuration file. +/// +/// @return 0 if OK, other if not. +int Composer::pluginsLoad(CtlSectionT *section, json_object *pluginsJ) +{ + json_object* builtinJ = nullptr, * completePluginsJ = nullptr; + + if(pluginsJ) + { + wrap_json_pack(&builtinJ, "{ss,ss,ss,ss,s[s]}", + "label", "builtin", + "version", "4.99", + "info", "Builtin routine for onReceived or getSignals routines", + "basename", "builtin", + "lua2c", "setSignalValueWrap"); + + if (json_object_get_type(pluginsJ) == json_type_array) + { + json_object_array_add(pluginsJ, builtinJ); + completePluginsJ = pluginsJ; + } + else + { + completePluginsJ = json_object_new_array(); + json_object_array_add(completePluginsJ, pluginsJ); + json_object_array_add(completePluginsJ, builtinJ); + } + } + + return PluginConfig(section, completePluginsJ); +} + int Composer::loadOneSourceAPI(json_object* sourceJ) { json_object *initJ = nullptr, @@ -335,13 +374,18 @@ int Composer::loadOneSignal(json_object* signalJ) unit = !unit ? "" : unit; // Set default onReceived action if not specified + char* label = strndup("onReceived_", 11); + label = strncat(label, id, strlen(id)); if(!onReceivedJ) { onReceivedCtl = src->signalsDefault().onReceived ? src->signalsDefault().onReceived : nullptr; + // Overwrite label to the signal one instead of the default + if(onReceivedCtl) + {onReceivedCtl->source.label = label;} } - else {onReceivedCtl = convert2Action("onReceived", onReceivedJ);} + else {onReceivedCtl = convert2Action(label, onReceivedJ);} if(src != nullptr) {src->addSignal(id, event, dependsV, retention, unit, frequency, onReceivedCtl, getSignalsArgs);} diff --git a/signal-composer-binding/signal-composer.hpp b/signal-composer-binding/signal-composer.hpp index f472c4f..024336b 100644 --- a/signal-composer-binding/signal-composer.hpp +++ b/signal-composer-binding/signal-composer.hpp @@ -16,7 +16,6 @@ */ #pragma once - #include <vector> #include <string> @@ -35,6 +34,7 @@ private: ~Composer(); CtlActionT* convert2Action(const std::string& name, json_object* action); + static int pluginsLoad(CtlSectionT *section, json_object *pluginsJ); int loadOneSourceAPI(json_object* sourcesJ); static int loadSourcesAPI(CtlSectionT* section, json_object *signalsJ); diff --git a/signal-composer-binding/signal.cpp b/signal-composer-binding/signal.cpp index 019cbe7..df0ca00 100644 --- a/signal-composer-binding/signal.cpp +++ b/signal-composer-binding/signal.cpp @@ -28,7 +28,7 @@ Signal::Signal() event_(""), dependsSigV_(), timestamp_(0.0), - value_({0,0,0,0,0,""}), + value_(), retention_(0), frequency_(0), unit_(""), @@ -42,7 +42,7 @@ Signal::Signal(const std::string& id, const std::string& event, std::vector<std: event_(event), dependsSigV_(depends), timestamp_(0.0), - value_({0,0,0,0,0,""}), + value_(), retention_(retention), frequency_(frequency), unit_(unit), @@ -61,7 +61,7 @@ Signal::Signal(const std::string& id, event_(), dependsSigV_(depends), timestamp_(0.0), - value_({0,0,0,0,0,""}), + value_(), retention_(retention), frequency_(frequency), unit_(unit), @@ -70,6 +70,11 @@ Signal::Signal(const std::string& id, subscribed_(false) {} +Signal::~Signal() +{ + free(onReceived_); +} + Signal::operator bool() const { if(id_.empty()) @@ -168,15 +173,15 @@ void Signal::update(Signal* sig) /// @brief /// -/// @param[in] queryJ - json_object containing event data to process +/// @param[in] eventJ - json_object containing event data to process /// /// @return 0 if ok, -1 or others if not -int Signal::defaultReceivedCB(json_object *queryJ) +int Signal::defaultReceivedCB(json_object *eventJ) { uint64_t ts = 0; - struct signalValue sv = {0,0,0,0,0,""}; - json_object_iterator iter = json_object_iter_begin(queryJ); - json_object_iterator iterEnd = json_object_iter_end(queryJ); + struct signalValue sv; + json_object_iterator iter = json_object_iter_begin(eventJ); + json_object_iterator iterEnd = json_object_iter_end(eventJ); while(!json_object_iter_equal(&iter, &iterEnd)) { std::string name = json_object_iter_peek_name(&iter); @@ -185,11 +190,11 @@ int Signal::defaultReceivedCB(json_object *queryJ) if (name.find("value") || name.find(id_)) { if(json_object_is_type(value, json_type_double)) - {sv = {0,0,true,json_object_get_double(value),0,""};} + {sv = json_object_get_double(value);} else if(json_object_is_type(value, json_type_boolean)) - {sv = {true,json_object_get_int(value),0,0,0,""};} + {sv = json_object_get_int(value);} else if(json_object_is_type(value, json_type_string)) - {sv = {0,0,0,0,true,json_object_get_string(value)};} + {sv = json_object_get_string(value);} } else if (name.find("timestamp")) { @@ -200,7 +205,7 @@ int Signal::defaultReceivedCB(json_object *queryJ) if(!sv.hasBool && !sv.hasNum && !sv.hasStr) { - AFB_ERROR("No data found to set signal %s in %s", id_.c_str(), json_object_to_json_string(queryJ)); + AFB_ERROR("No data found to set signal %s in %s", id_.c_str(), json_object_to_json_string(eventJ)); return -1; } else if(ts == 0) @@ -217,15 +222,15 @@ int Signal::defaultReceivedCB(json_object *queryJ) /// @brief Notify observers that there is a change and execute callback defined /// when signal is received /// -/// @param[in] queryJ - JSON query object to transmit to callback function +/// @param[in] eventJ - JSON query object to transmit to callback function /// /// @return 0 if OK, -1 or other if not. -int Signal::onReceivedCB(json_object *queryJ) +int Signal::onReceivedCB(json_object *eventJ) { if(onReceived_ && onReceived_->type == CTL_TYPE_LUA) { - json_object_iterator iter = json_object_iter_begin(queryJ); - json_object_iterator iterEnd = json_object_iter_end(queryJ); + json_object_iterator iter = json_object_iter_begin(eventJ); + json_object_iterator iterEnd = json_object_iter_end(eventJ); while(!json_object_iter_equal(&iter, &iterEnd)) { const char *name = ::strdup(json_object_iter_peek_name(&iter)); @@ -234,15 +239,14 @@ int Signal::onReceivedCB(json_object *queryJ) { int64_t newVal = json_object_get_int64(value); newVal = newVal > USEC_TIMESTAMP_FLAG ? newVal/MICRO:newVal; - json_object_object_del(queryJ, name); + json_object_object_del(eventJ, name); json_object* luaVal = json_object_new_int64(newVal); - json_object_object_add(queryJ, name, luaVal); + json_object_object_add(eventJ, name, luaVal); } json_object_iter_next(&iter); } } - AFB_NOTICE("JSON %s", json_object_to_json_string(queryJ)); - int err = onReceived_ ? ActionExecOne(onReceived_, queryJ) : defaultReceivedCB(queryJ); + int err = onReceived_ ? ActionExecOne(onReceived_, eventJ) : defaultReceivedCB(eventJ); notify(); return err; } @@ -277,7 +281,7 @@ void Signal::attachToSourceSignals(Composer& composer) double Signal::average(int seconds) const { uint64_t begin = history_.begin()->first; - uint64_t end = !seconds ? + uint64_t end = seconds ? begin+(seconds*MICRO) : history_.rbegin()->first; double total = 0.0; @@ -314,7 +318,7 @@ double Signal::average(int seconds) const double Signal::minimum(int seconds) const { uint64_t begin = history_.begin()->first; - uint64_t end = !seconds ? + uint64_t end = seconds ? begin+(seconds*MICRO) : history_.rbegin()->first; @@ -346,7 +350,7 @@ double Signal::minimum(int seconds) const double Signal::maximum(int seconds) const { uint64_t begin = history_.begin()->first; - uint64_t end = !seconds ? + uint64_t end = seconds ? begin+(seconds*MICRO) : history_.rbegin()->first; @@ -375,7 +379,7 @@ double Signal::maximum(int seconds) const /// @return Last value struct signalValue Signal::last() const { - if(history_.empty()) {return signalValue({0,0,0,0,0,""});} + if(history_.empty()) {return signalValue();} return history_.rbegin()->second; } diff --git a/signal-composer-binding/signal.hpp b/signal-composer-binding/signal.hpp index 3d373fa..ba3e8c7 100644 --- a/signal-composer-binding/signal.hpp +++ b/signal-composer-binding/signal.hpp @@ -40,6 +40,17 @@ struct signalValue { double numVal; bool hasStr; std::string strVal; + + signalValue(): + hasBool(false), boolVal(false), hasNum(false), numVal(0), hasStr(false), strVal("") {}; + signalValue(bool b): + hasBool(true), boolVal(b), hasNum(false), numVal(0), hasStr(false), strVal("") {}; + signalValue(int b): + hasBool(true), boolVal(b), hasNum(false), numVal(0), hasStr(false), strVal("") {}; + signalValue(double d): + hasBool(false), boolVal(false), hasNum(true), numVal(d), hasStr(false), strVal("") {}; + signalValue(const std::string& s): + hasBool(false), boolVal(false), hasNum(false), numVal(0), hasStr(true), strVal(s) {}; }; /// @brief Holds a signal (raw or virtual) definition. Value could be of @@ -68,6 +79,7 @@ public: Signal(); Signal(const std::string& id, const std::string& event, std::vector<std::string>& depends, const std::string& unit, int retention, double frequency, CtlActionT* onReceived, json_object* getSignalsArgs); Signal(const std::string& id, std::vector<std::string>& depends, const std::string& unit, int retention, double frequency, CtlActionT* onReceived); + ~Signal(); explicit operator bool() const; bool operator==(const Signal& other) const; @@ -92,7 +104,13 @@ public: int recursionCheck(Signal* obs); }; +extern "C" void searchNsetSignalValueHandle(const char* aName, uint64_t timestamp, struct signalValue value); +extern "C" void setSignalValueHandle(void* aSignal, uint64_t timestamp, struct signalValue value); + +/// @brief Holds composer callbacks and obj to manipulate struct signalCBT { - void (*setSignalValue)(const char* aName, uint64_t timestamp, struct signalValue value); + void (*searchNsetSignalValue)(const char* aName, uint64_t timestamp, struct signalValue value); + void (*setSignalValue)(void* aSignal, uint64_t timestamp, struct signalValue value); + void* aSignal; }; diff --git a/signal-composer-binding/source.cpp b/signal-composer-binding/source.cpp index d1b2120..4511fa7 100644 --- a/signal-composer-binding/source.cpp +++ b/signal-composer-binding/source.cpp @@ -52,6 +52,20 @@ void SourceAPI::addSignal(const std::string& id, const std::string& event, std:: { std::shared_ptr<Signal> sig = std::make_shared<Signal>(id, event, depends, unit, retention, frequency, onReceived, getSignalsArgs); + if(onReceived) + { + struct signalCBT* ctx = onReceived->source.context ? + (struct signalCBT*)onReceived->source.context : + (struct signalCBT*)calloc (1, sizeof(struct signalCBT)); + if(!ctx->searchNsetSignalValue) + {ctx->searchNsetSignalValue = searchNsetSignalValueHandle;} + if(!ctx->setSignalValue) + {ctx->setSignalValue = setSignalValueHandle;} + + ctx->aSignal = (void*)sig.get(); + onReceived->source.context = (void*)ctx; + } + signalsMap_[id] = sig; } |