aboutsummaryrefslogtreecommitdiffstats
path: root/signal-composer-binding
diff options
context:
space:
mode:
authorRomain Forlot <romain.forlot@iot.bzh>2017-10-05 01:38:18 +0200
committerRomain Forlot <romain.forlot@iot.bzh>2017-12-14 11:00:25 +0100
commit8df3e437f941912067231250ff5695b8a3a7fd92 (patch)
treec812fb252ad0f8a48041aff28b7fc60a75f245d1 /signal-composer-binding
parent8364673ab93eb484e25c7c4776e5d705b73330b4 (diff)
LUA lib and bin embedded in project
Change-Id: I1a61b49f55e4daa305800e754a14b6041aa81b34 Signed-off-by: Romain Forlot <romain.forlot@iot.bzh>
Diffstat (limited to 'signal-composer-binding')
-rw-r--r--signal-composer-binding/CMakeLists.txt1
-rw-r--r--signal-composer-binding/signal-composer-binding.cpp3
-rw-r--r--signal-composer-binding/signal-composer.cpp80
-rw-r--r--signal-composer-binding/signal-composer.hpp2
-rw-r--r--signal-composer-binding/signal.cpp52
-rw-r--r--signal-composer-binding/signal.hpp20
-rw-r--r--signal-composer-binding/source.cpp14
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;
}