HAN-FUN API  1.5.3
This project provides the common implementation of ULE Alliance's HAN-FUN application protocol.
uids.h
Go to the documentation of this file.
1 // =============================================================================
16 // =============================================================================
17 #ifndef HF_UIDS_H
18 #define HF_UIDS_H
19 
20 #include "hanfun/common.h"
21 
22 namespace HF
23 {
24  // =============================================================================
25  // UID implementation
26  // =============================================================================
27 
31  namespace UID
32  {
41  typedef enum _Type
43  {
44  NONE_UID = 0x00,
45  DECT_UID = 0x01,
46  MAC_UID = 0x02,
47  URI_UID = 0x03,
48  } Type;
49 
55  struct UID_T: public Common::Serializable, public Common::Cloneable<UID_T>
56  {
62  virtual uint8_t type() const = 0;
63 
64  bool operator==(const UID_T &other) const
65  {
66  return (this->compare(other) == 0);
67  }
68 
69  bool operator!=(const UID_T &other) const
70  {
71  return !(*this == other);
72  }
73 
88  virtual int compare(const UID_T &other) const
89  {
90  return (this->type() - other.type());
91  }
92 
94  static constexpr uint16_t min_size = sizeof(uint8_t) // UID Type.
95  + sizeof(uint8_t); // Size of the UID.
96 
98  uint16_t size() const
99  {
100  return min_size;
101  }
102 
104  uint16_t pack(Common::ByteArray &array, uint16_t offset = 0) const
105  {
106  HF_SERIALIZABLE_CHECK(array, offset, min_size);
107 
108  array.write(offset, this->type());
109 
110  return sizeof(uint8_t);
111  }
112 
114  uint16_t unpack(const Common::ByteArray &array, uint16_t offset = 0)
115  {
116  HF_SERIALIZABLE_CHECK(array, offset, min_size);
117 
118  uint8_t type;
119  array.read(offset, type);
120 
121  assert((type & (~0x80)) == this->type());
122 
123  return sizeof(uint8_t);
124  }
125  };
126 
132  template<uint8_t _type>
133  struct Abstract: public UID_T
134  {
135  uint8_t type() const
136  {
137  return _type;
138  }
139  };
140 
144  struct NONE: public Abstract<NONE_UID>
145  {
146  uint16_t pack(Common::ByteArray &array, uint16_t offset = 0) const
147  {
148  HF_SERIALIZABLE_CHECK(array, offset, min_size);
149 
150  offset += UID_T::pack(array, offset);
151 
152  array.write(offset, (uint8_t) 0);
153 
154  return min_size;
155  }
156 
157  uint16_t unpack(const Common::ByteArray &array, uint16_t offset = 0)
158  {
159  HF_SERIALIZABLE_CHECK(array, offset, min_size);
160 
161  uint16_t res = UID_T::unpack(array, offset);
162 
163  if (res == 0)
164  {
165  return 0;
166  }
167 
168  offset += res;
169 
170  uint8_t size;
171  array.read(offset, size);
172 
173  assert(size == 0);
174 
175  return min_size;
176  }
177 
178  NONE *clone() const
179  {
180  return new NONE(*this);
181  }
182  };
183 
191  template<typename _Class, uint8_t _size, uint8_t _type>
192  class ByteArray: public Abstract<_type>
193  {
194  protected:
195 
196  uint8_t value[_size];
197 
198  public:
199 
200  ByteArray(): Abstract<_type>() {}
201 
207  ByteArray(uint8_t _value[_size]): Abstract<_type>()
208  {
209  memcpy(value, _value, _size * sizeof(uint8_t));
210  }
211 
217  ByteArray(uint8_t _value): Abstract<_type>()
218  {
219  memset(value, _value, _size * sizeof(uint8_t));
220  }
221 
223  static constexpr uint16_t min_size = UID_T::min_size + _size;
224 
225  uint16_t size() const
226  {
227  return min_size;
228  }
229 
230  uint16_t pack(Common::ByteArray &array, uint16_t offset = 0) const
231  {
232  HF_SERIALIZABLE_CHECK(array, offset, min_size);
233 
234  offset += Abstract<_type>::pack(array, offset);
235 
236  offset += array.write(offset, (uint8_t) sizeof(value));
237 
238  for (uint8_t i = 0; i < sizeof(value); i++)
239  {
240  offset += array.write(offset, value[i]);
241  }
242 
243  return min_size;
244  }
245 
246  uint16_t unpack(const Common::ByteArray &array, uint16_t offset = 0)
247  {
248  HF_SERIALIZABLE_CHECK(array, offset, min_size);
249 
250  offset += Abstract<_type>::unpack(array, offset);
251 
252  uint8_t size;
253  offset += array.read(offset, size);
254 
255  assert(size == sizeof(value));
256 
257  if (size != sizeof(value))
258  {
259  return 0;
260  }
261 
262  for (uint8_t i = 0; i < size; i++)
263  {
264  offset += array.read(offset, value[i]);
265  }
266 
267  return min_size;
268  }
269 
270  // ===================================================================
271  // API
272  // ===================================================================
273 
274  int compare(const UID_T &other) const
275  {
276  int res = Abstract<_type>::compare(other);
277 
278  return (res ==
279  0 ? memcmp(value, ((_Class *) &other)->value, sizeof(value)) : res);
280  }
281 
282  // =============================================================================
283  // Array style API.
284  // =============================================================================
285 
293  uint8_t const &operator[](uint16_t index) const
294  {
295  return value[index];
296  }
297 
305  uint8_t &operator[](uint16_t index)
306  {
307  return value[index];
308  }
309 
320  uint8_t const &at(uint16_t index) const
321  {
322  assert(index < _size);
323  return value[index];
324  }
325 
336  uint8_t &at(uint16_t index)
337  {
338  assert(index < _size);
339  return value[index];
340  }
341 
342  // =============================================================================
343  // Helper API
344  // =============================================================================
345 
351  void fill(uint8_t byte)
352  {
353  memset(value, byte, sizeof(value));
354  }
355 
359  void clear()
360  {
361  memset(value, 0, sizeof(value));
362  }
363 
369  static uint16_t length()
370  {
371  return _size;
372  }
373  };
374 
378  struct DECT: public ByteArray<DECT, 5, DECT_UID>
379  {
381  constexpr static uint8_t SIZE = 5;
382 
383  DECT(): ByteArray<DECT, 5, DECT_UID>(0xFF)
384  {}
385 
391  DECT(uint8_t _value[5]): ByteArray<DECT, 5, DECT_UID>(_value)
392  {}
393 
394  // ===================================================================
395  // Cloneable
396  // ===================================================================
397 
398  DECT *clone() const
399  {
400  return new DECT(*this);
401  }
402  };
403 
407  struct MAC: public ByteArray<MAC, 6, MAC_UID>
408  {
410  constexpr static uint8_t SIZE = 6;
411 
412  MAC(): ByteArray<MAC, 6, MAC_UID>()
413  {}
414 
415  MAC(uint8_t _value[6]): ByteArray<MAC, 6, MAC_UID>(_value)
416  {}
417 
418  // ===================================================================
419  // Cloneable
420  // ===================================================================
421 
422  MAC *clone() const
423  {
424  return new MAC(*this);
425  }
426  };
427 
431  struct URI: public Abstract<URI_UID>
432  {
433  std::string value;
434 
435  URI()
436  {}
437 
438  URI(const std::string &value):
439  value(value)
440  {}
441 
442  uint16_t size() const
443  {
444  return Abstract<URI_UID>::size() + value.size();
445  }
446 
447  uint16_t pack(Common::ByteArray &array, uint16_t offset = 0) const
448  {
449  HF_SERIALIZABLE_CHECK(array, offset, size());
450 
451  uint16_t start = offset;
452 
453  offset += Abstract<URI_UID>::pack(array, offset);
454 
455  assert(value.size() <= 0xFF);
456  offset += array.write(offset, (uint8_t) value.size());
457 
458  for (uint8_t i = 0; i < value.size(); i++)
459  {
460  offset += array.write(offset, (uint8_t) value[i]);
461  }
462 
463  return offset - start;
464  }
465 
466  uint16_t unpack(const Common::ByteArray &array, uint16_t offset = 0)
467  {
468  HF_SERIALIZABLE_CHECK(array, offset, min_size);
469 
470  uint16_t start = offset;
471 
472  offset += Abstract<URI_UID>::unpack(array, offset);
473 
474  uint8_t size;
475  offset += array.read(offset, size);
476 
477  HF_SERIALIZABLE_CHECK(array, offset, size);
478 
479  value = std::string(size, 0);
480 
481  for (uint8_t i = 0; i < size; i++)
482  {
483  uint8_t c;
484  offset += array.read(offset, c);
485  value[i] = c;
486  }
487 
488  return offset - start;
489  }
490 
491  // ===================================================================
492  // Cloneable
493  // ===================================================================
494 
495  URI *clone() const
496  {
497  return new URI(*this);
498  }
499 
500  // ===================================================================
501  // API
502  // ===================================================================
503 
504  int compare(const UID_T &other) const
505  {
506  int res = Abstract<URI_UID>::compare(other);
507 
508  return (res == 0 ? value.compare(((URI *) &other)->value) : res);
509  }
510 
516  std::string str() const
517  {
518  return value;
519  }
520  };
521 
532  {
534  UID_T *_raw;
535 
537  bool owner;
538 
539  public:
540 
541  UID(): _raw(new NONE()), owner(true)
542  {}
543 
550  UID(UID_T *_uid, bool _owner = false):
551  _raw(_uid), owner(_owner)
552  {
553  assert(_uid != nullptr);
554  }
555 
561  UID(UID &&other): _raw(other._raw), owner(other.owner)
562  {
563  other.owner = false;
564  }
565 
573  UID(const UID &other): _raw(other._raw->clone()), owner(true)
574  {}
575 
576  virtual ~UID()
577  {
578  if (owner)
579  {
580  delete _raw;
581  }
582  }
583 
584  // =============================================================================
585  // API
586  // =============================================================================
587 
589  uint8_t type() const
590  {
591  return _raw->type();
592  }
593 
594  bool operator==(const UID &other) const
595  {
596  return (this->_raw->compare(*(other._raw)) == 0);
597  }
598 
599  bool operator!=(const UID &other) const
600  {
601  return !(*this == other);
602  }
603 
604  uint16_t size() const
605  {
606  return _raw->size();
607  }
608 
609  uint16_t pack(Common::ByteArray &array, uint16_t offset) const
610  {
611  return _raw->pack(array, offset);
612  }
613 
614  uint16_t unpack(const Common::ByteArray &array, uint16_t offset);
615 
616  // =============================================================================
617  // Utils
618  // =============================================================================
619 
627  UID &operator=(const UID &other)
628  {
629  // Ship if same object.
630  if (this == &other)
631  {
632  return *this;
633  }
634 
635  // Delete current wrapped object if owner.
636  if (this->owner)
637  {
638  delete this->_raw;
639  }
640 
641  // Clone wrapped UID_T and take ownership of the clone.
642  this->_raw = other._raw->clone();
643  this->owner = true;
644 
645  return *this;
646  }
647 
655  UID &operator=(UID &&other)
656  {
657  std::swap(this->_raw, other._raw);
658  std::swap(this->owner, other.owner);
659 
660  return *this;
661  }
662 
675  {
676  if (owner)
677  {
678  delete this->_raw;
679  }
680 
681  _raw = _uid;
682  owner = true;
683 
684  return *this;
685  }
686 
688  int compare(const UID &other) const
689  {
690  return _raw->compare(*(other._raw));
691  }
692 
694  int compare(const UID_T &other) const
695  {
696  return _raw->compare(other);
697  }
698 
704  UID_T const *raw() const
705  {
706  return _raw;
707  }
708 
710  float changed(const UID &other) const
711  {
712  UNUSED(other);
713  return 0.0;
714  }
715  };
716 
719  } // namespace UID
720 
721 } // namespace HF
722 
723 // =============================================================================
724 // Helper Functions
725 // =============================================================================
726 
732 inline bool operator==(const HF::UID::UID &lhs, const HF::UID::UID_T &rhs)
733 {
734  return (lhs.compare(rhs) == 0);
735 }
736 
737 inline bool operator==(const HF::UID::UID_T &lhs, const HF::UID::UID &rhs)
738 {
739  return (rhs.compare(lhs) == 0);
740 }
741 
742 inline bool operator!=(const HF::UID::UID &lhs, const HF::UID::UID_T &rhs)
743 {
744  return !(lhs == rhs);
745 }
746 
747 inline bool operator!=(const HF::UID::UID_T &lhs, const HF::UID::UID &rhs)
748 {
749  return !(lhs == rhs);
750 }
751 
760 std::ostream &operator<<(std::ostream &stream, const HF::UID::UID &uid);
761 
764 #endif /* HF_UIDS_H */
uint8_t const & at(uint16_t index) const
Get byte at the given index, asserting that the index is within the correct range.
Definition: uids.h:320
uint16_t unpack(const Common::ByteArray &array, uint16_t offset=0)
Read a message from a ByteArray.
Definition: uids.h:246
std::ostream & operator<<(std::ostream &stream, const HF::UID::UID &uid)
Convert the given uid into a string and write it to the given stream.
Media Access Control (IEEE-MAC-48)
Definition: uids.h:46
uint16_t size() const
Number bytes needed to serialize the message.
Definition: uids.h:225
uint16_t write(uint16_t offset, uint8_t data)
Write a byte into the array at the given offset.
This class represents the interface that cloneable objects need to implement.
virtual uint8_t type() const =0
Type of the UID.
Helper template parent class for all UID&#39;s implementation.
Definition: uids.h:133
Type
Types of UIDs available.
Definition: uids.h:42
void clear()
Fill the underlining byte array with 0.
Definition: uids.h:359
virtual T * clone() const =0
Create a clone object of the object where this method is being called.
uint16_t unpack(const Common::ByteArray &array, uint16_t offset=0)
Read a message from a ByteArray.
Definition: uids.h:114
This file contains the common defines for the HAN-FUN library.
UID(UID_T *_uid, bool _owner=false)
Constructor.
Definition: uids.h:550
This represents the common interface for message serialization.
uint16_t size() const
Number bytes needed to serialize the message.
Definition: uids.h:442
float changed(const UID &other) const
This method is used to get the percentage of change that the attribute has in relation to the value p...
Definition: uids.h:710
UID(const UID &other)
Copy constructor.
Definition: uids.h:573
uint16_t size() const
Number bytes needed to serialize the message.
Definition: uids.h:604
uint8_t type() const
Type of the UID.
Definition: uids.h:589
void fill(uint8_t byte)
Fill the underlining byte array with the given value.
Definition: uids.h:351
uint8_t type() const
Type of the UID.
Definition: uids.h:135
UID_T const * raw() const
Get the underling wrapped UID_T pointer.
Definition: uids.h:704
RFPI or IPUI.
Definition: uids.h:45
URI * clone() const
Create a clone object of the object where this method is being called.
Definition: uids.h:495
URI UID class.
Definition: uids.h:431
uint16_t pack(Common::ByteArray &array, uint16_t offset) const
Write the object on to a ByteArray so it can be sent over the network.
Definition: uids.h:609
Uniform Resource Identifier.
Definition: uids.h:47
static constexpr uint8_t SIZE
Number of bytes in a RFPI UID.
Definition: uids.h:381
UID & operator=(UID_T *_uid)
Use the given pointer as the pointer of the underlining UID to wrap around of.
Definition: uids.h:674
Helper template parent class for all UIDs based on fixed number of bytes.
Definition: uids.h:192
IEEE MAC-48b UID class.
Definition: uids.h:407
#define HF_SERIALIZABLE_CHECK(__array, __offset, __size)
Helper macro to check if the given __array has enough size so __size bytes can be written/read from t...
ByteArray(uint8_t _value)
Constructor.
Definition: uids.h:217
ByteArray(uint8_t _value[_size])
Constructor.
Definition: uids.h:207
static constexpr uint16_t min_size
Minimum pack/unpack required data size.
Definition: uids.h:223
int compare(const UID &other) const
Compare the current UID with the given UID.
Definition: uids.h:688
virtual int compare(const UID_T &other) const
Compare the current UID with the given UID.
Definition: uids.h:88
uint8_t const & operator[](uint16_t index) const
Get byte at the given index.
Definition: uids.h:293
uint8_t & at(uint16_t index)
Get byte at the given index, asserting that the index is within the correct range.
Definition: uids.h:336
Wrapper around UID_T pointer&#39;s.
Definition: uids.h:531
This class represents a byte array.
UID(UID &&other)
Move constructor.
Definition: uids.h:561
DECT(uint8_t _value[5])
Constructor.
Definition: uids.h:391
uint16_t pack(Common::ByteArray &array, uint16_t offset=0) const
Write the object on to a ByteArray so it can be sent over the network.
Definition: uids.h:104
uint16_t pack(Common::ByteArray &array, uint16_t offset=0) const
Write the object on to a ByteArray so it can be sent over the network.
Definition: uids.h:146
uint16_t size() const
Number bytes needed to serialize the message.
Definition: uids.h:98
UID & operator=(UID &&other)
Move assignment operator.
Definition: uids.h:655
std::string str() const
Return the string value associated with this URI.
Definition: uids.h:516
Empty UID.
Definition: uids.h:44
NONE * clone() const
Create a clone object of the object where this method is being called.
Definition: uids.h:178
uint16_t pack(Common::ByteArray &array, uint16_t offset=0) const
Write the object on to a ByteArray so it can be sent over the network.
Definition: uids.h:447
DECT * clone() const
Create a clone object of the object where this method is being called.
Definition: uids.h:398
uint16_t unpack(const Common::ByteArray &array, uint16_t offset=0)
Read a message from a ByteArray.
Definition: uids.h:157
uint16_t read(uint16_t offset, uint8_t &data) const
Read the byte at offset into data.
int compare(const UID_T &other) const
Compare the current UID with the given UID.
Definition: uids.h:504
API for all UIDs.
Definition: uids.h:55
int compare(const UID_T &other) const
Compare the current UID with the given UID.
Definition: uids.h:694
uint16_t unpack(const Common::ByteArray &array, uint16_t offset=0)
Read a message from a ByteArray.
Definition: uids.h:466
MAC * clone() const
Create a clone object of the object where this method is being called.
Definition: uids.h:422
#define UNUSED(x)
Helper macro to remove warning about unused function/method argument.
static uint16_t length()
Return the number of bytes in the underlining byte array.
Definition: uids.h:369
DECT UID class.
Definition: uids.h:378
This class represents an empty UID.
Definition: uids.h:144
static constexpr uint16_t min_size
Minimum pack/unpack required data size.
Definition: uids.h:94
uint8_t & operator[](uint16_t index)
Get byte at the given index.
Definition: uids.h:305
static constexpr uint8_t SIZE
Number of bytes in a MAC UID.
Definition: uids.h:410
uint16_t pack(Common::ByteArray &array, uint16_t offset=0) const
Write the object on to a ByteArray so it can be sent over the network.
Definition: uids.h:230
uint16_t unpack(const Common::ByteArray &array, uint16_t offset)
Read a message from a ByteArray.
UID & operator=(const UID &other)
Copy assignment operator.
Definition: uids.h:627
int compare(const UID_T &other) const
Compare the current UID with the given UID.
Definition: uids.h:274
Top-level namespace for the HAN-FUN library.
Definition: attributes.h:22