1
0
Fork 0
mirror of https://git.rwth-aachen.de/acs/public/villas/node/ synced 2025-03-30 00:00:11 +01:00

first chunk of NGSI node type implementation

This commit is contained in:
Steffen Vogel 2015-09-19 18:54:27 +02:00
parent 006440567a
commit c63ad04400
5 changed files with 287 additions and 0 deletions

View file

@ -4,6 +4,7 @@
@subpage opal
@subpage file
@subpage socket
@subpage ngsi
Every server needs clients which act as sinks / sources for simulation data. In case of S2SS these clients are called _nodes_.
@ -13,5 +14,6 @@ Take a look at the `clients/` directory for them:
- RTDS via GTFPGA and PCIexpress
- OPAL via Asynchronous Process and UDP
- OPAL via Asynchronous Process and Shared memory
- NGSI 9/10 (FIRWARE context broker)
- Labview (*planned*)
- Simulink (*planned*)

View file

@ -111,6 +111,21 @@ nodes = {
id = "1ab8:4005", # The PCIe vendor:device ID (see third column in 'lspci -n' output)
rate = 1
},
ngsi_node = {
type = "ngsi",
### The following settings are specific to the gtfpga node-type!! ###
endpoint = "http://46.101.131.212:1026/v1", # The HTTP / REST endpoint of the FIRWARE context broker
mapping = [ # Format: "entityID(entityType).AttributeId(AttributeType)"
"rtds_sub1(voltage3).v1(float),
"rtds_sub1(voltage3).v2(float)",
"rtds_sub1(voltage3).v3(float)",
"rtds_sub2(power3).p1(float)",
"rtds_sub2(power3).p2(float)",
"rtds_sub2(power3).p3(float)"
]
}
};

86
server/include/ngsi.h Normal file
View file

@ -0,0 +1,86 @@
/** Node type: NGSI 9/10 (FIWARE context broker)
*
* This file implements the NGSI protocol as a node type.
*
* @see https://forge.fiware.org/plugins/mediawiki/wiki/fiware/index.php/FI-WARE_NGSI-10_Open_RESTful_API_Specification
* @file
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
* @copyright 2014-2015, Institute for Automation of Complex Power Systems, EONERC
* This file is part of S2SS. All Rights Reserved. Proprietary and confidential.
* Unauthorized copying of this file, via any medium is strictly prohibited.
*/
/**
* @addtogroup ngsi FIRWARE NGSI 9/10 RESTful HTTP API
* @ingroup node
* @{
**********************************************************************************/
#ifndef _NGSI_H_
#define _NGSI_H_
#include <curl/curl.h>
#include "list.h"
#include "config.h"
#include "msg.h"
#include "cfg.h"
#include "node.h"
struct node;
struct ngsi_attribute {
char *name;
char *type;
int index;
};
struct ngsi_entity {
char *name;
char *type;
struct list attributes;
struct list metadata;
};
struct ngsi {
char *endpoint;
char *token;
struct list entities;
struct curl_slist *headers;
CURL *curl;
};
/** Initialize global NGSI settings and maps shared memory regions.
*
* @see node_vtable::init
*/
int ngsi_init(int argc, char *argv[], struct settings *set);
/** Free global NGSI settings and unmaps shared memory regions.
*
* @see node_vtable::deinit
*/
int ngsi_deinit();
/** @see node_vtable::parse */
int ngsi_parse(config_setting_t *cfg, struct node *n);
/** @see node_vtable::print */
int ngsi_print(struct node *n, char *buf, int len);
/** @see node_vtable::open */
int ngsi_open(struct node *n);
/** @see node_vtable::close */
int ngsi_close(struct node *n);
/** @see node_vtable::read */
int ngsi_read(struct node *n, struct msg *pool, int poolsize, int first, int cnt);
/** @see node_vtable::write */
int ngsi_write(struct node *n, struct msg *pool, int poolsize, int first, int cnt);
#endif /** _NGSI_H_ @} */

179
server/src/ngsi.c Normal file
View file

@ -0,0 +1,179 @@
/** Node type: FIWARE NGSI 9/10
*
* This file implements the NGSI protocol as a node type.
*
* @see https://forge.fiware.org/plugins/mediawiki/wiki/fiware/index.php/FI-WARE_NGSI-10_Open_RESTful_API_Specification
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
* @copyright 2014-2015, Institute for Automation of Complex Power Systems, EONERC
* This file is part of S2SS. All Rights Reserved. Proprietary and confidential.
* Unauthorized copying of this file, via any medium is strictly prohibited.
**********************************************************************************/
#include <curl/curl.h>
#include <jansson.h>
#include "ngsi.h"
#include "utils.h"
/* NGSI Entity, Attribute & Metadata structure */
void ngsi_entity_dtor(void *ptr)
{
struct ngsi_entity *entity = ptr;
list_destroy(&entity->attributes);
list_destroy(&entity->metadata);
free(entity->name);
free(entity->type);
}
void ngsi_attribute_dtor(void *ptr)
{
struct ngsi_attribute *entity = ptr;
free(entity->name);
free(entity->type);
}
struct ngsi_entity * ngsi_entity()
{
struct ngsi_entity *entity = alloc(sizeof(struct ngsi_entity));
list_init(&entity->attributes, ngsi_attribute_dtor);
list_init(&entity->metadata, ngsi_attribute_dtor);
return entity;
}
/* Node type */
int ngsi_init(int argc, char *argv[], struct settings *set)
{
curl_global_init(CURL_GLOBAL_ALL);
}
int ngsi_deinit()
{
curl_global_cleanup();
}
int ngsi_parse(config_setting_t *cfg, struct node *n)
{
struct ngsi *i = n->ngsi;
config_setting_t *mapping = config_setting_get_member(cfg, "mapping");
if (!mapping || !config_setting_is_array(mapping))
cerror(cfg, "Missing entity.attribute mapping for node '%s", n->name);
for (int i = 0; i < config_setting_length(mapping); i++) {
const char *token = config_setting_get_string_elem(mapping, i);
if (token) {
if (sscanf(token, "%ms(%ms).%ms", &entity, &type, &attribue) != 2)
cerror(mapping, "Invalid entity.attribute token: '%s'", token);
}
cerror(mapping, "Invalid entity.attribute token");
}
}
int ngsi_print(struct node *n, char *buf, int len)
{
struct ngsi *i = n->ngsi;
return snprintf(buf, len, "endpoint=%s, token=%s, entities=%u",
i->endpoint, i->token, i->entities);
}
int ngsi_open(struct node *n)
{
char buf[128];
struct ngsi *i = n->ngsi;
i->curl = curl_easy_init();
i->headers = NULL:
if (i->token) {
snprintf(buf, sizeof(buf), "Auth-Token: %s", i->token);
i->headers = curl_slist_append(i->headers, buf);
}
i->headers = curl_slist_append(i->headers, "User-Agent: S2SS " VERSION);
i->headers = curl_slist_append(i->headers, "Content-Type: application/json");
snprintf(buf, sizeof(buf), "%s/v1/%s")
curl_easy_setopt(i->curl, CURLOPT_URL, url);
curl_easy_setopt(i->curl, CURLOPT_POSTFIELDSIZE, -1);
curl_easy_setopt(i->curl, CURLOPT_HTTPHEADER, i->headers);
/* Create entity */
char *post = ngsi_update_context(n, "APPEND");
return 0;
}
int ngsi_close(struct node *n)
{
struct ngsi *i = n->ngsi;
curl_easy_cleanup(i->curl);
curl_slist_free_all(i->headers);
return 0;
}
static int ngsi_query_context(struct node *n)
{
struct ngsi *i = n->ngsi;
return 0;
}
static char * ngsi_update_context(struct node *n, char *action)
{
struct ngsi *i = n->ngsi;
json_t *root = json_object();
json_t *elements = json_array();
for (int i = 0; i < i->entities; i++) {
json_t *entity = json_object();
json_t *attributes = json_object();
json_object_set(entity, "type", json_string("Room"));
json_object_set(entity, "isPattern", json_false());
json_object_set(entity, "id", json_string("Room1"));
}
json_object_set(root, "contextElements", conextElements);
json_object_set(root, "updateAction", json_string(action));
return json_dumps(root, JSON_COMPACT);
}
int ngsi_read(struct node *n, struct msg *pool, int poolsize, int first, int cnt)
{
struct ngsi *i = n->ngsi;
return -1; /** @todo not yet implemented */
}
int ngsi_write(struct node *n, struct msg *pool, int poolsize, int first, int cnt)
{
struct ngsi *i = n->ngsi;
long result;
char *post = ngsi_update_context(n, "UPDATE");
curl_easy_setopt(i->curl, CURLOPT_COPYPOSTFIELDS, post);
curl_easy_perform(i->curl);
curl_easy_getinfo(i->curl, CURLINFO_RESPONSE_CODE, &result);
return result == 200 ? 1 : 0
}
REGISTER_NODE_TYPE(NGSI, "ngsi", ngsi)

View file

@ -108,6 +108,11 @@ struct node * node_create()
void node_destroy(struct node *n)
{
switch (n->vt->type) {
#ifdef ENABLE_NGSI
case NGSI:
list_destroy(n->ngsi->entities);
break;
#endif
#ifdef ENABLE_SOCKET
case BSD_SOCKET:
rtnl_qdisc_put(n->socket->tc_qdisc);