SOIL C++
C++ Unified Device Interface
Variable.h
Go to the documentation of this file.
1#pragma once
2#include "constants.h"
3#include "Types.h"
4#include "Element.h"
5#include "Container.h"
6#include "Range.h"
7#include "Figure.h"
8#include "SIGN/Signer.h"
9#include "SIGN/Hasher.h"
10#include "MQTT/Publisher.h"
11#include <boost/algorithm/string/join.hpp>
12
13
14namespace SOIL
15{
40 template <typename T, int x = -1, int y = -1>
41 class Variable : public Figure<T, x, y>
42 {
43 protected:
44
51 std::string nonce;
52
61 std::vector<unsigned char> hash;
62
75
83 virtual void read(void);
84
92 virtual void write(void);
93
94 public:
109 Variable(std::shared_ptr<Element> parent, std::string uuid, std::string name, std::string description, std::string unit, std::string ontology = "", Range<T> range = Range<T>(), TIME time = TIME(), std::string nonce = "");
110
116 ~Variable();
117
133 static std::shared_ptr<Variable> create(std::shared_ptr<Element> parent, std::string uuid, std::string name, std::string description, std::string unit, std::string ontology = "", Range<T> range = Range<T>(), TIME time = TIME(), std::string nonce = "");
134
147
157 HTTP::Json wjson(void) override;
158
173 HTTP::Response handle_get(HTTP::Request message, std::smatch match = std::smatch()) override;
174
187 HTTP::Response handle_options(HTTP::Request message, std::smatch match = std::smatch()) override;
188
199 void update(const Container<T, x, y>& value, TIME time, std::string nonce = "");
200
212
229 std::vector <unsigned char> bytes(void);
230
239 std::vector <unsigned char> sha256(void);
240
255 std::vector <unsigned char> sign(std::shared_ptr<SIGN::Signer> signer = NULL);
256
268 std::vector <unsigned char> fingerprint(std::shared_ptr<SIGN::Signer> signer);
269
270
277 inline std::shared_ptr<Variable> ptr(void)
278 {
279 return std::dynamic_pointer_cast<Variable>(Element::self);
280 }
281
303 bool mqtt(std::shared_ptr<MQTT::Publisher> publisher, int qos = 0, bool retain = false);
304 };
305
306
307}
308
309
310
311template<typename T, int x, int y>
312SOIL::Variable<T, x, y>::Variable(std::shared_ptr<Element> parent, std::string uuid, std::string name, std::string description, std::string unit, std::string ontology, Range<T> range, TIME time, std::string nonce) : SOIL::Figure<T, x, y>(parent, uuid, name, description, unit, ontology, range, time)
313{
314 if (uuid.substr(0, 3) != "VAR")
315 {
316 throw std::logic_error("UUIDs for Variables must start with VAR!");
317 }
318
319 HTTP::Resource::allowed_methods = { HTTP::Methods::GET, HTTP::Methods::GET, HTTP::Methods::OPTIONS, HTTP::Methods::HEAD};
320}
321
322template<typename T, int x, int y>
324{
325}
326
327template<typename T, int x, int y>
328inline std::shared_ptr<SOIL::Variable<T,x,y> > SOIL::Variable<T, x, y>::create(std::shared_ptr<Element> parent, std::string uuid, std::string name, std::string description, std::string unit, std::string ontology, Range<T> range, TIME time, std::string nonce)
329{
330 Variable<T, x, y>* variable = new Variable<T, x, y>(parent, uuid, name, description, unit, ontology, range, time, nonce);
331 return variable->ptr();
332}
333
334template<typename T, int x, int y>
336{
338 return *this;
339}
340
341
342template<typename T, int x, int y>
344{
345 std::unique_lock<std::recursive_mutex> lock(Element::mutex);
347
348
349 std::ostringstream buffer;
350
351 for (std::string::size_type i = 0; i < hash.size();i++)
352 {
353 buffer << std::hex << std::setfill('0') << std::setw(2) << std::uppercase << (int)hash[i];
354 if (i != hash.size() - 1)
355 {
356 buffer << std::setw(1) << " ";
357 }
358 }
359
360 std::string readable_hash = buffer.str();
361
362 json_root[U("nonce")] = (nonce == "") ? HTTP::Json::null() : SOIL::to_json(nonce);
363 json_root[U("hash")] = (readable_hash == "") ? HTTP::Json::null() : SOIL::to_json(readable_hash);
364 json_root[U("covariance")] = covariance.wjson()[U("value")];
365
366 return json_root;
367}
368
369template<typename T, int x, int y>
371{
372}
373
374template<typename T, int x, int y>
376{
377}
378
379template<typename T, int x, int y>
381{
382 std::unique_lock<std::recursive_mutex> lock(Element::mutex);
383 this->covariance = covariance;
384}
385
386template<typename T, int x, int y>
387inline std::vector<unsigned char> SOIL::Variable<T, x, y>::bytes(void)
388{
389 std::unique_lock<std::recursive_mutex> lock(Element::mutex);
390 std::vector<unsigned char> result;
391 std::vector<unsigned char> bytes_dimension = Figure<T, x, y>::value.serialize_dimensions();
392 std::vector<unsigned char> bytes_value = Figure<T, x, y>::value.serialize_value();
393 std::vector<unsigned char> bytes_covariance = covariance.serialize_value();
394 std::vector<unsigned char> bytes_unit(3, ' ');
395 std::vector<unsigned char> bytes_time = Figure<T,x,y>::time.serialize();
396 std::vector<unsigned char> bytes_nonce;
397 for (int i = 0; i < static_cast<int>(std::min(static_cast<size_t>(3), Figure<T,x,y>::unit.length())); i++)
398 {
399 bytes_unit.at(i) = Figure<T, x, y>::unit.at(i);
400 }
401 for (int i = 0; i < static_cast<int>(nonce.length()); i++)
402 {
403 bytes_nonce.push_back(nonce.at(i));
404 }
405
406 result.insert(result.end(), bytes_dimension.begin(), bytes_dimension.end());
407 result.insert(result.end(), bytes_value.begin(), bytes_value.end());
408 result.insert(result.end(), bytes_covariance.begin(), bytes_covariance.end());
409 result.insert(result.end(), bytes_unit.begin(), bytes_unit.end());
410 result.insert(result.end(), bytes_time.begin(), bytes_time.end());
411 result.insert(result.end(), bytes_nonce.begin(), bytes_nonce.end());
412
413 return result;
414}
415
416template<typename T, int x, int y>
417inline std::vector<unsigned char> SOIL::Variable<T, x, y>::sha256(void)
418{
419 std::vector<unsigned char> data = this->bytes();
420 return SIGN::Hasher::sha256(data.data(), data.size());
421}
422
423template<typename T, int x, int y>
424inline std::vector<unsigned char> SOIL::Variable<T, x, y>::fingerprint(std::shared_ptr<SIGN::Signer> signer)
425{
426 return signer->sign(this->sha256());
427}
428
429template<typename T, int x, int y>
430inline std::vector<unsigned char> SOIL::Variable<T, x, y>::sign(std::shared_ptr<SIGN::Signer> signer)
431{
432 if (signer != NULL)
433 {
434 this->hash = this->fingerprint(signer);
435 }
436 else {
437 this->hash = this->sha256();
438 }
439
440 return this->hash;
441}
442
443template<typename T, int x, int y>
444inline bool SOIL::Variable<T, x, y>::mqtt(std::shared_ptr<MQTT::Publisher> publisher, int qos, bool retain)
445{
446 std::string topic = boost::algorithm::join(this->fqid(), "/");
447 return publisher->publish(topic, this->json(), qos, retain);
448}
449
450
451template<typename T, int x, int y>
453{
454 this->read();
455
456 HTTP::Response response;
457 response.set_body(this->wjson());
458 response.set_status_code(HTTP::Status::OK);
459
460 return response;
461}
462
463template<typename T, int x, int y>
465{
466 HTTP::Response response;
467 response.set_body(this->wjson());
468 response.set_status_code(HTTP::Status::OK);
469
470 return response;
471}
472
473template<typename T, int x, int y>
474inline void SOIL::Variable<T, x, y>::update(const Container<T, x, y>& value, TIME time, std::string nonce)
475{
476 Figure<T, x, y>::update(value, time);
477 this->nonce = nonce;
478
479 hash.clear();
480 covariance.set_null(true);
481}
482
483
484
485
nlohmann::json json
std::vector< web::http::method > allowed_methods
Allowed methods.
Definition: Resource.h:42
static std::vector< unsigned char > sha256(const unsigned char *data, size_t length)
SHA256 hash.
Definition: Hasher.cpp:8
Data Container.
Definition: Container.h:22
HTTP::Json wjson(void)
WJSON representation.
Definition: Container.h:269
void set_null(bool _null=true)
Set null.
Definition: Container.h:87
std::vector< unsigned char > serialize_value(void) const
Serialize value.
Definition: Container.h:323
bool insert(std::string uuid, std::shared_ptr< Element > child)
Add Child Element.
Definition: Element.cpp:91
std::string uuid
Local UUID.
Definition: Element.h:53
std::string description
Description.
Definition: Element.h:67
std::string ontology
Ontology identifier.
Definition: Element.h:76
std::string name
Name.
Definition: Element.h:60
std::shared_ptr< Element > parent
Parent Pointer.
Definition: Element.h:39
std::recursive_mutex mutex
Element Mutex.
Definition: Element.h:83
std::shared_ptr< Element > self
Self Pointer.
Definition: Element.h:46
Intermediate class for Variable and Parameter that derives from Element.
Definition: Figure.h:49
Figure< T, x, y > & operator=(const Container< T, x, y > &value)
Assignment operator.
Definition: Figure.h:259
std::string unit
Unit.
Definition: Figure.h:63
virtual void update(const Container< T, x, y > &value, TIME time)
Update.
Definition: Figure.h:308
TIME time
Data Timestamp.
Definition: Figure.h:56
Container< T, x, y > value
Value.
Definition: Figure.h:70
Range< T > range
Range.
Definition: Figure.h:77
HTTP::Json wjson(void) override
HTTP JSON.
Definition: Figure.h:229
Range Helper Class.
Definition: Range.h:25
SOIL Time.
Definition: Time.h:13
Variable Class.
Definition: Variable.h:42
std::vector< unsigned char > sha256(void)
Calculate SHA256.
Definition: Variable.h:417
HTTP::Response handle_get(HTTP::Request message, std::smatch match=std::smatch()) override
HTTP GET Handler.
Definition: Variable.h:452
std::string nonce
Nonce.
Definition: Variable.h:51
std::shared_ptr< Variable > ptr(void)
Get Pointer.
Definition: Variable.h:277
void set_covariance(Container< T, x, x > covariance)
Set Covariance.
Definition: Variable.h:380
HTTP::Json wjson(void) override
HTTP JSON.
Definition: Variable.h:343
static std::shared_ptr< Variable > create(std::shared_ptr< Element > parent, std::string uuid, std::string name, std::string description, std::string unit, std::string ontology="", Range< T > range=Range< T >(), TIME time=TIME(), std::string nonce="")
Create new Variable.
Definition: Variable.h:328
Variable(std::shared_ptr< Element > parent, std::string uuid, std::string name, std::string description, std::string unit, std::string ontology="", Range< T > range=Range< T >(), TIME time=TIME(), std::string nonce="")
Constructor.
Definition: Variable.h:312
HTTP::Response handle_options(HTTP::Request message, std::smatch match=std::smatch()) override
HTTP OPTIONS Handler.
Definition: Variable.h:464
Variable< T, x, y > & operator=(const Container< T, x, y > &value)
Assignment operator.
Definition: Variable.h:335
bool mqtt(std::shared_ptr< MQTT::Publisher > publisher, int qos=0, bool retain=false)
Publish to MQTT.
Definition: Variable.h:444
virtual void read(void)
Read callback.
Definition: Variable.h:370
virtual void write(void)
Write callback.
Definition: Variable.h:375
std::vector< unsigned char > fingerprint(std::shared_ptr< SIGN::Signer > signer)
Calculate RSA fingerprint.
Definition: Variable.h:424
void update(const Container< T, x, y > &value, TIME time, std::string nonce="")
Update value.
Definition: Variable.h:474
std::vector< unsigned char > bytes(void)
Get bytewise representation.
Definition: Variable.h:387
Container< T, x, x > covariance
Covariance of the value.
Definition: Variable.h:74
~Variable()
Destructor.
Definition: Variable.h:323
std::vector< unsigned char > sign(std::shared_ptr< SIGN::Signer > signer=NULL)
Sign the variable data.
Definition: Variable.h:430
std::vector< unsigned char > hash
Checking Hash.
Definition: Variable.h:61
web::json::value Json
HTTP JSON.
Definition: Types.h:39
web::http::http_request Request
HTTP Request.
Definition: Types.h:11
web::http::http_response Response
HTTP Response.
Definition: Types.h:18
Type definitions.
Definition: Container.h:7
Time TIME
SOIL Time.
Definition: Types.h:54
DLL web::json::value to_json(const T &value)
Value to JSON.