aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRomain Forlot <romain.forlot@iot.bzh>2017-08-31 18:42:36 +0200
committerRomain Forlot <romain.forlot@iot.bzh>2017-09-02 12:18:23 +0200
commitad1c1d40d053f531f8c55238c24e2257e7f02814 (patch)
tree59741065191eabdd5f2995546df464c250fbaf01
parent0edcd87d090b85638519f854796ee25f13e55c5e (diff)
Retab
Change-Id: I42a8caa1431f7e44b1faecc8ade9a7f8e5c1c196 Signed-off-by: Romain Forlot <romain.forlot@iot.bzh>
-rw-r--r--high-viwi-binding/high-viwi-apidef.h156
-rw-r--r--high-viwi-binding/high-viwi-binding.cpp50
-rw-r--r--high-viwi-binding/high-viwi-binding.hpp10
-rw-r--r--high-viwi-binding/high.cpp690
-rw-r--r--high-viwi-binding/high.hpp46
5 files changed, 476 insertions, 476 deletions
diff --git a/high-viwi-binding/high-viwi-apidef.h b/high-viwi-binding/high-viwi-apidef.h
index fec9d26..e8dde84 100644
--- a/high-viwi-binding/high-viwi-apidef.h
+++ b/high-viwi-binding/high-viwi-apidef.h
@@ -1,41 +1,41 @@
static const char _afb_description_v2_high_viwi[] =
- "{\"openapi\":\"3.0.0\",\"$schema\":\"http:iot.bzh/download/openapi/schem"
- "a-3.0/default-schema.json\",\"info\":{\"description\":\"\",\"title\":\"h"
- "igh-level-viwi-service\",\"version\":\"4.0\",\"x-binding-c-generator\":{"
- "\"api\":\"high-viwi\",\"version\":2,\"prefix\":\"\",\"postfix\":\"\",\"s"
- "tart\":null,\"onevent\":\"onEvent\",\"init\":\"init_service\",\"scope\":"
- "\"\",\"private\":false}},\"servers\":[{\"url\":\"ws://{host}:{port}/api/"
- "monitor\",\"description\":\"High ViWi API connected to low level AGL ser"
- "vices\",\"variables\":{\"host\":{\"default\":\"localhost\"},\"port\":{\""
- "default\":\"1234\"}},\"x-afb-events\":[{\"$ref\":\"#/components/schemas/"
- "afb-event\"}]}],\"components\":{\"schemas\":{\"afb-reply\":{\"$ref\":\"#"
- "/components/schemas/afb-reply-v2\"},\"afb-event\":{\"$ref\":\"#/componen"
- "ts/schemas/afb-event-v2\"},\"afb-reply-v2\":{\"title\":\"Generic respons"
- "e.\",\"type\":\"object\",\"required\":[\"jtype\",\"request\"],\"properti"
- "es\":{\"jtype\":{\"type\":\"string\",\"const\":\"afb-reply\"},\"request\""
- ":{\"type\":\"object\",\"required\":[\"status\"],\"properties\":{\"status"
- "\":{\"type\":\"string\"},\"info\":{\"type\":\"string\"},\"token\":{\"typ"
- "e\":\"string\"},\"uuid\":{\"type\":\"string\"},\"reqid\":{\"type\":\"str"
- "ing\"}}},\"response\":{\"type\":\"object\"}}},\"afb-event-v2\":{\"type\""
- ":\"object\",\"required\":[\"jtype\",\"event\"],\"properties\":{\"jtype\""
- ":{\"type\":\"string\",\"const\":\"afb-event\"},\"event\":{\"type\":\"str"
- "ing\"},\"data\":{\"type\":\"object\"}}}},\"x-permissions\":{},\"response"
- "s\":{\"200\":{\"description\":\"A complex object array response\",\"cont"
- "ent\":{\"application/json\":{\"schema\":{\"$ref\":\"#/components/schemas"
- "/afb-reply\"}}}}}},\"paths\":{\"/subscribe\":{\"description\":\"Subscrib"
- "e to a ViWi object\",\"parameters\":[{\"in\":\"query\",\"name\":\"event\""
- ",\"required\":false,\"schema\":{\"type\":\"string\"}}],\"responses\":{\""
- "200\":{\"$ref\":\"#/components/responses/200\"}}},\"/unsubscribe\":{\"de"
- "scription\":\"Unsubscribe previously suscribed ViWi objects.\",\"paramet"
- "ers\":[{\"in\":\"query\",\"name\":\"event\",\"required\":false,\"schema\""
- ":{\"type\":\"string\"}}],\"responses\":{\"200\":{\"$ref\":\"#/components"
- "/responses/200\"}}},\"/get\":{\"description\":\"Get informations about a"
- " resource or element\",\"responses\":{\"200\":{\"$ref\":\"#/components/r"
- "esponses/200\"}}},\"/load\":{\"description\":\"Load config file in direc"
- "tory passed as argument\",\"parameters\":[{\"in\":\"query\",\"name\":\"p"
- "ath\",\"required\":true,\"schema\":{\"type\":\"string\"}}],\"responses\""
- ":{\"200\":{\"$ref\":\"#/components/responses/200\"}}}}}"
+ "{\"openapi\":\"3.0.0\",\"$schema\":\"http:iot.bzh/download/openapi/schem"
+ "a-3.0/default-schema.json\",\"info\":{\"description\":\"\",\"title\":\"h"
+ "igh-level-viwi-service\",\"version\":\"4.0\",\"x-binding-c-generator\":{"
+ "\"api\":\"high-viwi\",\"version\":2,\"prefix\":\"\",\"postfix\":\"\",\"s"
+ "tart\":null,\"onevent\":\"onEvent\",\"init\":\"init_service\",\"scope\":"
+ "\"\",\"private\":false}},\"servers\":[{\"url\":\"ws://{host}:{port}/api/"
+ "monitor\",\"description\":\"High ViWi API connected to low level AGL ser"
+ "vices\",\"variables\":{\"host\":{\"default\":\"localhost\"},\"port\":{\""
+ "default\":\"1234\"}},\"x-afb-events\":[{\"$ref\":\"#/components/schemas/"
+ "afb-event\"}]}],\"components\":{\"schemas\":{\"afb-reply\":{\"$ref\":\"#"
+ "/components/schemas/afb-reply-v2\"},\"afb-event\":{\"$ref\":\"#/componen"
+ "ts/schemas/afb-event-v2\"},\"afb-reply-v2\":{\"title\":\"Generic respons"
+ "e.\",\"type\":\"object\",\"required\":[\"jtype\",\"request\"],\"properti"
+ "es\":{\"jtype\":{\"type\":\"string\",\"const\":\"afb-reply\"},\"request\""
+ ":{\"type\":\"object\",\"required\":[\"status\"],\"properties\":{\"status"
+ "\":{\"type\":\"string\"},\"info\":{\"type\":\"string\"},\"token\":{\"typ"
+ "e\":\"string\"},\"uuid\":{\"type\":\"string\"},\"reqid\":{\"type\":\"str"
+ "ing\"}}},\"response\":{\"type\":\"object\"}}},\"afb-event-v2\":{\"type\""
+ ":\"object\",\"required\":[\"jtype\",\"event\"],\"properties\":{\"jtype\""
+ ":{\"type\":\"string\",\"const\":\"afb-event\"},\"event\":{\"type\":\"str"
+ "ing\"},\"data\":{\"type\":\"object\"}}}},\"x-permissions\":{},\"response"
+ "s\":{\"200\":{\"description\":\"A complex object array response\",\"cont"
+ "ent\":{\"application/json\":{\"schema\":{\"$ref\":\"#/components/schemas"
+ "/afb-reply\"}}}}}},\"paths\":{\"/subscribe\":{\"description\":\"Subscrib"
+ "e to a ViWi object\",\"parameters\":[{\"in\":\"query\",\"name\":\"event\""
+ ",\"required\":false,\"schema\":{\"type\":\"string\"}}],\"responses\":{\""
+ "200\":{\"$ref\":\"#/components/responses/200\"}}},\"/unsubscribe\":{\"de"
+ "scription\":\"Unsubscribe previously suscribed ViWi objects.\",\"paramet"
+ "ers\":[{\"in\":\"query\",\"name\":\"event\",\"required\":false,\"schema\""
+ ":{\"type\":\"string\"}}],\"responses\":{\"200\":{\"$ref\":\"#/components"
+ "/responses/200\"}}},\"/get\":{\"description\":\"Get informations about a"
+ " resource or element\",\"responses\":{\"200\":{\"$ref\":\"#/components/r"
+ "esponses/200\"}}},\"/load\":{\"description\":\"Load config file in direc"
+ "tory passed as argument\",\"parameters\":[{\"in\":\"query\",\"name\":\"p"
+ "ath\",\"required\":true,\"schema\":{\"type\":\"string\"}}],\"responses\""
+ ":{\"200\":{\"$ref\":\"#/components/responses/200\"}}}}}"
;
void subscribe(struct afb_req req);
@@ -44,51 +44,51 @@ static const char _afb_description_v2_high_viwi[] =
void load(struct afb_req req);
static const struct afb_verb_v2 _afb_verbs_v2_high_viwi[] = {
- {
- .verb = "subscribe",
- .callback = subscribe,
- .auth = NULL,
- .info = "Subscribe to a ViWi object",
- .session = AFB_SESSION_NONE_V2
- },
- {
- .verb = "unsubscribe",
- .callback = unsubscribe,
- .auth = NULL,
- .info = "Unsubscribe previously suscribed ViWi objects.",
- .session = AFB_SESSION_NONE_V2
- },
- {
- .verb = "get",
- .callback = get,
- .auth = NULL,
- .info = "Get informations about a resource or element",
- .session = AFB_SESSION_NONE_V2
- },
- {
- .verb = "load",
- .callback = load,
- .auth = NULL,
- .info = "Load config file in directory passed as argument",
- .session = AFB_SESSION_NONE_V2
- },
- {
- .verb = NULL,
- .callback = NULL,
- .auth = NULL,
- .info = NULL,
- .session = 0
+ {
+ .verb = "subscribe",
+ .callback = subscribe,
+ .auth = NULL,
+ .info = "Subscribe to a ViWi object",
+ .session = AFB_SESSION_NONE_V2
+ },
+ {
+ .verb = "unsubscribe",
+ .callback = unsubscribe,
+ .auth = NULL,
+ .info = "Unsubscribe previously suscribed ViWi objects.",
+ .session = AFB_SESSION_NONE_V2
+ },
+ {
+ .verb = "get",
+ .callback = get,
+ .auth = NULL,
+ .info = "Get informations about a resource or element",
+ .session = AFB_SESSION_NONE_V2
+ },
+ {
+ .verb = "load",
+ .callback = load,
+ .auth = NULL,
+ .info = "Load config file in directory passed as argument",
+ .session = AFB_SESSION_NONE_V2
+ },
+ {
+ .verb = NULL,
+ .callback = NULL,
+ .auth = NULL,
+ .info = NULL,
+ .session = 0
}
};
const struct afb_binding_v2 afbBindingV2 = {
- .api = "high-viwi",
- .specification = _afb_description_v2_high_viwi,
- .info = "",
- .verbs = _afb_verbs_v2_high_viwi,
- .preinit = NULL,
- .init = init_service,
- .onevent = onEvent,
- .noconcurrency = 0
+ .api = "high-viwi",
+ .specification = _afb_description_v2_high_viwi,
+ .info = "",
+ .verbs = _afb_verbs_v2_high_viwi,
+ .preinit = NULL,
+ .init = init_service,
+ .onevent = onEvent,
+ .noconcurrency = 0
};
diff --git a/high-viwi-binding/high-viwi-binding.cpp b/high-viwi-binding/high-viwi-binding.cpp
index f86fc67..e42a175 100644
--- a/high-viwi-binding/high-viwi-binding.cpp
+++ b/high-viwi-binding/high-viwi-binding.cpp
@@ -28,54 +28,54 @@ High high;
/// @brief callback for receiving message from low binding. Treatment itself is made in High class.
void onEvent(const char *event, json_object *object)
{
- high.treatMessage(object);
+ high.treatMessage(object);
}
/// @brief entry point for client subscription request. Treatment itself is made in High class.
void subscribe(afb_req request)
{
- if(high.subscribe(request))
- afb_req_success(request, NULL, NULL);
- else
- afb_req_fail(request, "error", NULL);
+ if(high.subscribe(request))
+ afb_req_success(request, NULL, NULL);
+ else
+ afb_req_fail(request, "error", NULL);
}
/// @brief entry point for client un-subscription request. Treatment itself is made in High class.
void unsubscribe(afb_req request)
{
- if(high.unsubscribe(request))
- afb_req_success(request, NULL, NULL);
- else
- afb_req_fail(request, "error", NULL);
+ if(high.unsubscribe(request))
+ afb_req_success(request, NULL, NULL);
+ else
+ afb_req_fail(request, "error", NULL);
}
/// @brief verb that loads JSON configuration (old high.json file now)
void load(afb_req request)
{
- json_object* args = afb_req_json(request);
- const char* confd;
+ json_object* args = afb_req_json(request);
+ const char* confd;
- wrap_json_unpack(args, "{s:s}", "path", &confd);
- high.parseConfigAndSubscribe(confd);
+ wrap_json_unpack(args, "{s:s}", "path", &confd);
+ high.parseConfigAndSubscribe(confd);
}
/// @brief entry point for get requests. Treatment itself is made in High class.
void get(afb_req request)
{
- json_object *jobj;
- if(high.get(request, &jobj))
- {
- afb_req_success(request, jobj, NULL);
- } else {
- afb_req_fail(request, "error", NULL);
- }
+ json_object *jobj;
+ if(high.get(request, &jobj))
+ {
+ afb_req_success(request, jobj, NULL);
+ } else {
+ afb_req_fail(request, "error", NULL);
+ }
}
/// @brief entry point for systemD timers. Treatment itself is made in High class.
/// @param[in] source: systemD timer, t: time of tick, data: interval (ms).
int ticked(sd_event_source *source, uint64_t t, void* data)
{
- high.tick(source, t, data);
- return 0;
+ high.tick(source, t, data);
+ return 0;
}
/// @brief Initialize the binding.
@@ -83,7 +83,7 @@ int ticked(sd_event_source *source, uint64_t t, void* data)
/// @return Exit code, zero if success.
int init_service()
{
- AFB_DEBUG("High level binding is initializing");
- AFB_NOTICE("High level binding is initialized and running");
- return 0;
+ AFB_DEBUG("High level binding is initializing");
+ AFB_NOTICE("High level binding is initialized and running");
+ return 0;
}
diff --git a/high-viwi-binding/high-viwi-binding.hpp b/high-viwi-binding/high-viwi-binding.hpp
index 711e531..5db5a4c 100644
--- a/high-viwi-binding/high-viwi-binding.hpp
+++ b/high-viwi-binding/high-viwi-binding.hpp
@@ -3,10 +3,10 @@
#include <systemd/sd-event.h>
extern "C"
{
- #define AFB_BINDING_VERSION 2
- #include <afb/afb-binding.h>
+ #define AFB_BINDING_VERSION 2
+ #include <afb/afb-binding.h>
};
- void onEvent(const char *event, struct json_object *object);
- int init_service();
- int ticked(sd_event_source *source, uint64_t t, void *data);
+ void onEvent(const char *event, struct json_object *object);
+ int init_service();
+ int ticked(sd_event_source *source, uint64_t t, void *data);
diff --git a/high-viwi-binding/high.cpp b/high-viwi-binding/high.cpp
index e0bdc3f..14e6ba6 100644
--- a/high-viwi-binding/high.cpp
+++ b/high-viwi-binding/high.cpp
@@ -32,19 +32,19 @@ using namespace std;
template<typename Out>
void split(const std::string &s, char delim, Out result)
{
- std::stringstream ss;
- ss.str(s);
- std::string item;
- while (std::getline(ss, item, delim))
- {
- *(result++) = item;
- }
+ std::stringstream ss;
+ ss.str(s);
+ std::string item;
+ while (std::getline(ss, item, delim))
+ {
+ *(result++) = item;
+ }
}
std::vector<std::string> split(const std::string &s, char delim)
{
- std::vector<std::string> elems;
- split(s, delim, std::back_inserter(elems));
- return elems;
+ std::vector<std::string> elems;
+ split(s, delim, std::back_inserter(elems));
+ return elems;
}
/// @brief Main high binding class: maintains resources status, subcriptions and timers
@@ -286,206 +286,206 @@ void High::parseConfigAndSubscribe(const std::string& confd)
///
void High::startTimer(const int &t)
{
- if(timers.find(t) != timers.end())
- return;
- struct timespec ts;
- clock_gettime(CLOCK_MONOTONIC, &ts);
- sd_event_add_time(afb_daemon_get_event_loop(), NULL, CLOCK_MONOTONIC, (ts.tv_sec + 1) * 1000000, 0, &ticked, new int(t));
+ if(timers.find(t) != timers.end())
+ return;
+ struct timespec ts;
+ clock_gettime(CLOCK_MONOTONIC, &ts);
+ sd_event_add_time(afb_daemon_get_event_loop(), NULL, CLOCK_MONOTONIC, (ts.tv_sec + 1) * 1000000, 0, &ticked, new int(t));
}
High::~High()
{
- timers.clear();
+ timers.clear();
}
/// @brief callback called after subscription to low-level binding.
///
void High::callBackFromSubscribe(void *handle, int iserror, json_object *result)
{
- AFB_NOTICE("high level callBackFromSubscribe method called %s", json_object_get_string(result));
+ AFB_NOTICE("high level callBackFromSubscribe method called %s", json_object_get_string(result));
}
/// @brief Entry point for all timer events. Treats all requests linked to the specific timer frequency.
-/// Restarts the timer, or cancels it if no requests are anymore linked to it.
+/// Restarts the timer, or cancels it if no requests are anymore linked to it.
///
/// @param[in] source: systemD timer, now: tick timestamp, interv: specific timer interval in ms.
///
void High::tick(sd_event_source *source, const long &now, void *interv)
{
- const int interval = *(int*)interv;
- AFB_NOTICE("tick! %d %ld", interval, now);
- bool hasEvents = false;
- if(timedEvents.find(interval) != timedEvents.end())
- {
- std::vector<TimedEvent> evts = timedEvents[interval];
- for(int i = (int)evts.size() - 1; i >= 0; --i)
- {
- const TimedEvent e = evts.at(i);
- std::map<std::string, json_object*> jsons;
- for(const auto &pp : registeredObjects)
- {
- if(startsWith(pp.first, e.name))
- {
- jsons[pp.first] = generateJson(pp.first);
- }
- }
- json_object *j = json_object_new_object();
- if(jsons.size() == 1)
- {
- j = jsons[0];
- } else if(jsons.size() > 1)
- {
- for(const auto &pp : jsons)
- json_object_object_add(j, pp.first.c_str(), pp.second);
- }
- const int nbSubscribers = afb_event_push(e.event, j);
- if(nbSubscribers == 0)
- {
- afb_event_drop(e.event);
- evts.erase(evts.begin() + i);
- timedEvents[interval] = evts;
- }
- //AFB_NOTICE("%s event pushed to %d subscribers", e.eventName.c_str(), nbSubscribers);
- }
- if(evts.size() > 0)
- hasEvents = true;
- }
- if(hasEvents)
- {
- sd_event_source_set_time(source, now + interval * 1000);
- sd_event_source_set_enabled(source, SD_EVENT_ON);
- } else {
- //AFB_NOTICE("timer removed %d", interval);
- delete (int*)interv;
- if(timers.find(interval) != timers.end())
- {
- timers.erase(interval);
- }
- sd_event_source_unref(source);
- }
+ const int interval = *(int*)interv;
+ AFB_NOTICE("tick! %d %ld", interval, now);
+ bool hasEvents = false;
+ if(timedEvents.find(interval) != timedEvents.end())
+ {
+ std::vector<TimedEvent> evts = timedEvents[interval];
+ for(int i = (int)evts.size() - 1; i >= 0; --i)
+ {
+ const TimedEvent e = evts.at(i);
+ std::map<std::string, json_object*> jsons;
+ for(const auto &pp : registeredObjects)
+ {
+ if(startsWith(pp.first, e.name))
+ {
+ jsons[pp.first] = generateJson(pp.first);
+ }
+ }
+ json_object *j = json_object_new_object();
+ if(jsons.size() == 1)
+ {
+ j = jsons[0];
+ } else if(jsons.size() > 1)
+ {
+ for(const auto &pp : jsons)
+ json_object_object_add(j, pp.first.c_str(), pp.second);
+ }
+ const int nbSubscribers = afb_event_push(e.event, j);
+ if(nbSubscribers == 0)
+ {
+ afb_event_drop(e.event);
+ evts.erase(evts.begin() + i);
+ timedEvents[interval] = evts;
+ }
+ //AFB_NOTICE("%s event pushed to %d subscribers", e.eventName.c_str(), nbSubscribers);
+ }
+ if(evts.size() > 0)
+ hasEvents = true;
+ }
+ if(hasEvents)
+ {
+ sd_event_source_set_time(source, now + interval * 1000);
+ sd_event_source_set_enabled(source, SD_EVENT_ON);
+ } else {
+ //AFB_NOTICE("timer removed %d", interval);
+ delete (int*)interv;
+ if(timers.find(interval) != timers.end())
+ {
+ timers.erase(interval);
+ }
+ sd_event_source_unref(source);
+ }
}
/// @brief Entry point for low-binding events. Updates all resources linked to this event and eventually
-/// sends back events to subscribers, if any.
+/// sends back events to subscribers, if any.
///
/// @param[in] message: json low-level message.
///
void High::treatMessage(json_object *message)
{
- json_object *nameJson, *jvalue;
- json_object_object_get_ex(message, "name", &nameJson);
- json_object_object_get_ex(message, "value", &jvalue);
- const std::string messageName(json_object_get_string(nameJson));
- if(lowMessagesToObjects.find(messageName) == lowMessagesToObjects.end())
- {
- AFB_ERROR("message not linked to any object %s", json_object_get_string(message));
- return;
- }
-// AFB_NOTICE("message received %s", json_object_get_string(message));
- const std::set<std::string> objects = lowMessagesToObjects.at(messageName);
- std::vector<std::string> candidateMessages;
- for(const std::string &uri : objects)
- {
- std::map<std::string, Property> properties = registeredObjects.at(uri);
- std::string foundProperty;
- for(const auto &p : properties)
- {
- if(p.second.lowMessageName != messageName)
- continue;
- foundProperty = p.first;
- candidateMessages.push_back(uri);
- break;
- }
+ json_object *nameJson, *jvalue;
+ json_object_object_get_ex(message, "name", &nameJson);
+ json_object_object_get_ex(message, "value", &jvalue);
+ const std::string messageName(json_object_get_string(nameJson));
+ if(lowMessagesToObjects.find(messageName) == lowMessagesToObjects.end())
+ {
+ AFB_ERROR("message not linked to any object %s", json_object_get_string(message));
+ return;
+ }
+// AFB_NOTICE("message received %s", json_object_get_string(message));
+ const std::set<std::string> objects = lowMessagesToObjects.at(messageName);
+ std::vector<std::string> candidateMessages;
+ for(const std::string &uri : objects)
+ {
+ std::map<std::string, Property> properties = registeredObjects.at(uri);
+ std::string foundProperty;
+ for(const auto &p : properties)
+ {
+ if(p.second.lowMessageName != messageName)
+ continue;
+ foundProperty = p.first;
+ candidateMessages.push_back(uri);
+ break;
+ }
- if(foundProperty.size() > 0)
- {
- Property property = properties.at(foundProperty);
- if(property.type == "boolean")
- property.value_bool = json_object_get_boolean(jvalue);
- else if(property.type == "string")
- property.value_string = std::string(json_object_get_string(jvalue));
- else if(property.type == "double")
- property.value_double = json_object_get_double(jvalue);
- else if(property.type == "int")
- property.value_int = json_object_get_int(jvalue);
- else
- AFB_ERROR("ERROR 3! unexpected type %s %s", property.description.c_str(), property.type.c_str());
- properties[foundProperty] = property;
- registeredObjects[uri] = properties;
- }
- }
+ if(foundProperty.size() > 0)
+ {
+ Property property = properties.at(foundProperty);
+ if(property.type == "boolean")
+ property.value_bool = json_object_get_boolean(jvalue);
+ else if(property.type == "string")
+ property.value_string = std::string(json_object_get_string(jvalue));
+ else if(property.type == "double")
+ property.value_double = json_object_get_double(jvalue);
+ else if(property.type == "int")
+ property.value_int = json_object_get_int(jvalue);
+ else
+ AFB_ERROR("ERROR 3! unexpected type %s %s", property.description.c_str(), property.type.c_str());
+ properties[foundProperty] = property;
+ registeredObjects[uri] = properties;
+ }
+ }
/** at that point all objects have been updated. Now lets see if we should also send back messages to our subscribers. */
- for(const std::string &m : candidateMessages)
- {
- for(const auto &p : events)
- {
- if(startsWith(m, p.first))
- {
- std::map<std::string, json_object*> jsons;
- for(const auto &pp : registeredObjects)
- {
- if(startsWith(pp.first, p.first))
- {
- jsons[pp.first] = generateJson(pp.first);
- }
- }
- json_object *j = json_object_new_object();
- if(jsons.size() == 1)
- {
- j = jsons[0];
- } else if(jsons.size() > 1)
- {
- for(const auto &pp : jsons)
- json_object_object_add(j, pp.first.c_str(), pp.second);
- }
- const int nbSubscribers = afb_event_push(p.second, j);
- if(nbSubscribers == 0)
- {
- afb_event_drop(p.second);
- events.erase(p.first);
- }
- }
- }
- }
+ for(const std::string &m : candidateMessages)
+ {
+ for(const auto &p : events)
+ {
+ if(startsWith(m, p.first))
+ {
+ std::map<std::string, json_object*> jsons;
+ for(const auto &pp : registeredObjects)
+ {
+ if(startsWith(pp.first, p.first))
+ {
+ jsons[pp.first] = generateJson(pp.first);
+ }
+ }
+ json_object *j = json_object_new_object();
+ if(jsons.size() == 1)
+ {
+ j = jsons[0];
+ } else if(jsons.size() > 1)
+ {
+ for(const auto &pp : jsons)
+ json_object_object_add(j, pp.first.c_str(), pp.second);
+ }
+ const int nbSubscribers = afb_event_push(p.second, j);
+ if(nbSubscribers == 0)
+ {
+ afb_event_drop(p.second);
+ events.erase(p.first);
+ }
+ }
+ }
+ }
}
/// @brief Generate json message for a resource, in ViWi format. Based on resource definition extracted from json
-/// configuration file. If vector "fields" is not empty, will included only properties present in the vector.
+/// configuration file. If vector "fields" is not empty, will included only properties present in the vector.
///
/// @param[in] messageObject: resource's name, fields: list of properties to be included (NULL = all).
///
/// @return jsonObject containing the resource status for this resource's name.
json_object *High::generateJson(const std::string &messageObject, std::vector<std::string> *fields)
{
- json_object *json = json_object_new_object();
- const std::map<std::string, Property> props = registeredObjects.at(messageObject);
- for(const auto &p : props)
- {
- if(fields && fields->size() > 0 && p.first != "id" && p.first != "uri" && p.first != "name")
- {
- if(std::find(fields->begin(), fields->end(), p.first) == fields->end())
- continue;
- }
- if(p.second.type == "string")
- {
- const std::string value = p.second.value_string;
- json_object_object_add(json, p.first.c_str(), json_object_new_string(value.c_str()));
- } else if(p.second.type == "boolean")
- {
- const bool value = p.second.value_bool;
- json_object_object_add(json, p.first.c_str(), json_object_new_boolean(value));
- } else if(p.second.type == "double")
- {
- const double value = p.second.value_double;
- json_object_object_add(json, p.first.c_str(), json_object_new_double(value));
- } else if(p.second.type == "int")
- {
- const int value = p.second.value_int;
- json_object_object_add(json, p.first.c_str(), json_object_new_int(value));
- } else {
- AFB_ERROR("ERROR 1! unexpected type %s %s %s", p.first.c_str(), p.second.description.c_str(), p.second.type.c_str());
- }
- }
- return json;
+ json_object *json = json_object_new_object();
+ const std::map<std::string, Property> props = registeredObjects.at(messageObject);
+ for(const auto &p : props)
+ {
+ if(fields && fields->size() > 0 && p.first != "id" && p.first != "uri" && p.first != "name")
+ {
+ if(std::find(fields->begin(), fields->end(), p.first) == fields->end())
+ continue;
+ }
+ if(p.second.type == "string")
+ {
+ const std::string value = p.second.value_string;
+ json_object_object_add(json, p.first.c_str(), json_object_new_string(value.c_str()));
+ } else if(p.second.type == "boolean")
+ {
+ const bool value = p.second.value_bool;
+ json_object_object_add(json, p.first.c_str(), json_object_new_boolean(value));
+ } else if(p.second.type == "double")
+ {
+ const double value = p.second.value_double;
+ json_object_object_add(json, p.first.c_str(), json_object_new_double(value));
+ } else if(p.second.type == "int")
+ {
+ const int value = p.second.value_int;
+ json_object_object_add(json, p.first.c_str(), json_object_new_int(value));
+ } else {
+ AFB_ERROR("ERROR 1! unexpected type %s %s %s", p.first.c_str(), p.second.description.c_str(), p.second.type.c_str());
+ }
+ }
+ return json;
}
/// @brief Generates a random UID
@@ -493,9 +493,9 @@ json_object *High::generateJson(const std::string &messageObject, std::vector<st
/// @return string containing the generated UID.
std::string High::generateId() const
{
- char id[50];
- sprintf(id, "%x-%x-%x-%x", (rand()%(int)1e7 + 1), (rand()%(int)1e7 + 1), (rand()%(int)1e7 + 1), (rand()%(int)1e7 + 1));
- return std::string(id);
+ char id[50];
+ sprintf(id, "%x-%x-%x-%x", (rand()%(int)1e7 + 1), (rand()%(int)1e7 + 1), (rand()%(int)1e7 + 1), (rand()%(int)1e7 + 1));
+ return std::string(id);
}
/// @brief Entry point for subscribing to a resource. Can optionnally include a time interval in ms.
@@ -505,95 +505,95 @@ std::string High::generateId() const
/// @return true if subscribed succeeded, false otherwise.
bool High::subscribe(afb_req request)
{
- /** /car/doors/3901a278-ba17-44d6-9aef-f7ca67c04840 */
- bool ok = false;
- json_object *args = afb_req_json(request);
- json_object *nameJson = NULL;
- json_object *intervalJson = NULL;
- if(!json_object_object_get_ex(args, "name", &nameJson))
- return false;
- json_object_object_get_ex(args, "interval", &intervalJson);
- int ms = -1;
- if(intervalJson)
- ms = json_object_get_int(intervalJson);
- std::string message(json_object_get_string(nameJson));
- if(message.size() == 0)
- return ok;
- for(const auto &p : registeredObjects)
- {
- if(startsWith(p.first, message))
- {
- afb_event event;
- if(ms <= 0)
- {
- if(events.find(message) != events.end())
- {
- event = events.at(message);
- } else {
- event = afb_daemon_make_event(p.first.c_str());
- events[message] = event;
- }
- if (afb_event_is_valid(event) && afb_req_subscribe(request, event) == 0)
- {
- ok = true;
- }
- } else {
- std::vector<TimedEvent> evts;
- if(timedEvents.find(ms) != timedEvents.end())
- evts = timedEvents.at(ms);
- afb_event afbEvent;
- bool found = false;
- for(const auto & e : evts)
- {
- if(e.name == message)
- {
- afbEvent = e.event;
- found = true;
- break;
- }
- }
- if(!found)
- {
- char ext[20];
- sprintf(ext, "_%d", ms);
- std::string messageName = message + std::string(ext);
- //AFB_NOTICE("subscribe with interval %s", messageName.c_str());
- afbEvent = afb_daemon_make_event(messageName.c_str());
- if (!afb_event_is_valid(afbEvent))
- {
- AFB_ERROR("unable to create event");
- return false;
- }
- TimedEvent e;
- e.name = message;
- e.eventName = messageName;
- e.event = afbEvent;
- e.interval = ms;
- evts.push_back(e);
- timedEvents[ms] = evts;
- }
- if(afb_req_subscribe(request, afbEvent) == 0)
- {
- ok = true;
- } else {
- if(!found)
- {
- evts.erase(evts.end() - 1);
- timedEvents[ms] = evts;
- }
- }
- if(timedEvents.size() == 0)
- {
- timers.clear();
- } else if(ok)
- {
- startTimer(ms);
- }
- }
- break;
- }
- }
- return ok;
+ /** /car/doors/3901a278-ba17-44d6-9aef-f7ca67c04840 */
+ bool ok = false;
+ json_object *args = afb_req_json(request);
+ json_object *nameJson = NULL;
+ json_object *intervalJson = NULL;
+ if(!json_object_object_get_ex(args, "name", &nameJson))
+ return false;
+ json_object_object_get_ex(args, "interval", &intervalJson);
+ int ms = -1;
+ if(intervalJson)
+ ms = json_object_get_int(intervalJson);
+ std::string message(json_object_get_string(nameJson));
+ if(message.size() == 0)
+ return ok;
+ for(const auto &p : registeredObjects)
+ {
+ if(startsWith(p.first, message))
+ {
+ afb_event event;
+ if(ms <= 0)
+ {
+ if(events.find(message) != events.end())
+ {
+ event = events.at(message);
+ } else {
+ event = afb_daemon_make_event(p.first.c_str());
+ events[message] = event;
+ }
+ if (afb_event_is_valid(event) && afb_req_subscribe(request, event) == 0)
+ {
+ ok = true;
+ }
+ } else {
+ std::vector<TimedEvent> evts;
+ if(timedEvents.find(ms) != timedEvents.end())
+ evts = timedEvents.at(ms);
+ afb_event afbEvent;
+ bool found = false;
+ for(const auto & e : evts)
+ {
+ if(e.name == message)
+ {
+ afbEvent = e.event;
+ found = true;
+ break;
+ }
+ }
+ if(!found)
+ {
+ char ext[20];
+ sprintf(ext, "_%d", ms);
+ std::string messageName = message + std::string(ext);
+ //AFB_NOTICE("subscribe with interval %s", messageName.c_str());
+ afbEvent = afb_daemon_make_event(messageName.c_str());
+ if (!afb_event_is_valid(afbEvent))
+ {
+ AFB_ERROR("unable to create event");
+ return false;
+ }
+ TimedEvent e;
+ e.name = message;
+ e.eventName = messageName;
+ e.event = afbEvent;
+ e.interval = ms;
+ evts.push_back(e);
+ timedEvents[ms] = evts;
+ }
+ if(afb_req_subscribe(request, afbEvent) == 0)
+ {
+ ok = true;
+ } else {
+ if(!found)
+ {
+ evts.erase(evts.end() - 1);
+ timedEvents[ms] = evts;
+ }
+ }
+ if(timedEvents.size() == 0)
+ {
+ timers.clear();
+ } else if(ok)
+ {
+ startTimer(ms);
+ }
+ }
+ break;
+ }
+ }
+ return ok;
}
/// @brief Entry point for unsubscribing to a resource. Can optionnally include a time interval in ms.
@@ -603,91 +603,91 @@ bool High::subscribe(afb_req request)
/// @return true if unsubscription succeeded, false otherwise.
bool High::unsubscribe(afb_req request)
{
- json_object *args = afb_req_json(request);
- json_object *nameJson = NULL;
- json_object *intervalJson = NULL;
- if(!json_object_object_get_ex(args, "name", &nameJson))
- return false;
- json_object_object_get_ex(args, "interval", &intervalJson);
- int ms = -1;
- if(intervalJson)
- ms = json_object_get_int(intervalJson);
- std::string message(json_object_get_string(nameJson));
- if(message.size() == 0)
- return false;
- if(ms <= 0)
- {
- if(events.find(message) != events.end())
- {
- if(afb_req_unsubscribe(request, events.at(message)) == 0)
- return true;
- }
- } else {
- if(timedEvents.find(ms) == timedEvents.end())
- return false;
- const auto evts = timedEvents.at(ms);
- afb_event afbEvent;
- bool found = false;
- for(const auto & e : evts)
- {
- if(e.name == message)
- {
- afbEvent = e.event;
- found = true;
- break;
- }
- }
- if(!found)
- return false;
- if(afb_req_unsubscribe(request, afbEvent) == 0)
- return true;
- }
- return false;
+ json_object *args = afb_req_json(request);
+ json_object *nameJson = NULL;
+ json_object *intervalJson = NULL;
+ if(!json_object_object_get_ex(args, "name", &nameJson))
+ return false;
+ json_object_object_get_ex(args, "interval", &intervalJson);
+ int ms = -1;
+ if(intervalJson)
+ ms = json_object_get_int(intervalJson);
+ std::string message(json_object_get_string(nameJson));
+ if(message.size() == 0)
+ return false;
+ if(ms <= 0)
+ {
+ if(events.find(message) != events.end())
+ {
+ if(afb_req_unsubscribe(request, events.at(message)) == 0)
+ return true;
+ }
+ } else {
+ if(timedEvents.find(ms) == timedEvents.end())
+ return false;
+ const auto evts = timedEvents.at(ms);
+ afb_event afbEvent;
+ bool found = false;
+ for(const auto & e : evts)
+ {
+ if(e.name == message)
+ {
+ afbEvent = e.event;
+ found = true;
+ break;
+ }
+ }
+ if(!found)
+ return false;
+ if(afb_req_unsubscribe(request, afbEvent) == 0)
+ return true;
+ }
+ return false;
}
/// @brief entry point for get requests. Accepts an optional list of properties to be included.
///
/// @param[in] request: afb-request containing a json request, for instance {"name":"/car/demoboard/", "fields":["vehicleSpeed"]},
-/// **json: a pointer to a json object to be used for the reply.
+/// **json: a pointer to a json object to be used for the reply.
///
/// @return true if get succeeded, false otherwise, and **json object generated with the reply.
bool High::get(afb_req request, json_object **json)
{
- json_object *args = afb_req_json(request);
- json_object *nameJson;
- json_object *fieldsJson;
- if(!json_object_object_get_ex(args, "name", &nameJson))
- return false;
- bool hasFields = json_object_object_get_ex(args, "fields", &fieldsJson);
- std::vector<std::string> fields;
- if(hasFields)
- {
- int arraylen = json_object_array_length(fieldsJson);
- json_object* jvalue;
- for(int i = 0; i < arraylen; ++i)
- {
- jvalue = json_object_array_get_idx(fieldsJson, i);
- fields.push_back(json_object_get_string(jvalue));
- }
- }
- const std::string name(json_object_get_string(nameJson));
- std::map<std::string, json_object*> jsons;
- for(const auto &p : registeredObjects)
- {
- if(startsWith(p.first, name))
- jsons[p.first] = generateJson(p.first, &fields);
- }
- if(jsons.size() == 0)
- {
- return false;
- }
- json_object *j = json_object_new_object();
- for(const auto &p : jsons)
- {
- json_object_object_add(j, p.first.c_str(), p.second);
- }
- *json = j;
- return true;
+ json_object *args = afb_req_json(request);
+ json_object *nameJson;
+ json_object *fieldsJson;
+ if(!json_object_object_get_ex(args, "name", &nameJson))
+ return false;
+ bool hasFields = json_object_object_get_ex(args, "fields", &fieldsJson);
+ std::vector<std::string> fields;
+ if(hasFields)
+ {
+ int arraylen = json_object_array_length(fieldsJson);
+ json_object* jvalue;
+ for(int i = 0; i < arraylen; ++i)
+ {
+ jvalue = json_object_array_get_idx(fieldsJson, i);
+ fields.push_back(json_object_get_string(jvalue));
+ }
+ }
+ const std::string name(json_object_get_string(nameJson));
+ std::map<std::string, json_object*> jsons;
+ for(const auto &p : registeredObjects)
+ {
+ if(startsWith(p.first, name))
+ jsons[p.first] = generateJson(p.first, &fields);
+ }
+ if(jsons.size() == 0)
+ {
+ return false;
+ }
+ json_object *j = json_object_new_object();
+ for(const auto &p : jsons)
+ {
+ json_object_object_add(j, p.first.c_str(), p.second);
+ }
+ *json = j;
+ return true;
}
/// @brief Sub-routine (static) to check whether a string starts with another string
@@ -697,7 +697,7 @@ bool High::get(afb_req request, json_object **json)
/// @return true if s starts with val, false otherwise.
bool High::startsWith(const std::string &s, const std::string &val)
{
- if(val.size() > s.size())
- return false;
- return s.substr(0, val.size()) == val;
+ if(val.size() > s.size())
+ return false;
+ return s.substr(0, val.size()) == val;
}
diff --git a/high-viwi-binding/high.hpp b/high-viwi-binding/high.hpp
index d021ce7..b0d8f23 100644
--- a/high-viwi-binding/high.hpp
+++ b/high-viwi-binding/high.hpp
@@ -9,15 +9,15 @@
#include <systemd/sd-event.h>
extern "C"
{
- #define AFB_BINDING_VERSION 2
- #include <afb/afb-binding.h>
+ #define AFB_BINDING_VERSION 2
+ #include <afb/afb-binding.h>
};
struct TimedEvent {
- int interval;
- afb_event event;
- std::string name;
- std::string eventName;
+ int interval;
+ afb_event event;
+ std::string name;
+ std::string eventName;
};
struct Property {
@@ -39,25 +39,25 @@ struct Property {
class High
{
public:
- High();
- void treatMessage(json_object *message);
- bool subscribe(afb_req request);
- bool unsubscribe(afb_req request);
- bool get(afb_req request, json_object **json);
- void tick(sd_event_source *source, const long &now, void *interv);
- void startTimer(const int &t);
- ~High();
- static bool startsWith(const std::string &s, const std::string &val);
- static void callBackFromSubscribe(void *handle, int iserror, json_object *result);
+ High();
+ void treatMessage(json_object *message);
+ bool subscribe(afb_req request);
+ bool unsubscribe(afb_req request);
+ bool get(afb_req request, json_object **json);
+ void tick(sd_event_source *source, const long &now, void *interv);
+ void startTimer(const int &t);
+ ~High();
void parseConfigAndSubscribe(const std::string& confd);
+ static bool startsWith(const std::string &s, const std::string &val);
+ static void callBackFromSubscribe(void *handle, int iserror, json_object *result);
private:
- std::map<std::string, afb_event> events;
- std::map<int, std::vector<TimedEvent>> timedEvents;
- std::map<std::string, std::map<std::string, Property>> registeredObjects;
- std::map<std::string, std::set<std::string>> lowMessagesToObjects;
- std::set<int> timers;
- std::string generateId() const;
- json_object *generateJson(const std::string &messageObject, std::vector<std::string> *fields = nullptr);
+ std::map<std::string, afb_event> events;
+ std::map<int, std::vector<TimedEvent>> timedEvents;
+ std::map<std::string, std::map<std::string, Property>> registeredObjects;
+ std::map<std::string, std::set<std::string>> lowMessagesToObjects;
+ std::set<int> timers;
+ std::string generateId() const;
+ json_object *generateJson(const std::string &messageObject, std::vector<std::string> *fields = nullptr);
void registerObjects(const std::string& uri, const std::map<std::string, Property>& properties);
std::map<std::string, std::map<std::string, Property>> loadDefinitions(json_object* definitionsJ) const;
void loadResources(json_object* resourcesJ);