HAN-FUN API  1.5.3
This project provides the common implementation of ULE Alliance's HAN-FUN application protocol.
device_management.h
Go to the documentation of this file.
1 // =============================================================================
16 // =============================================================================
17 #ifndef HF_DEVICE_MANGEMENT_H
18 #define HF_DEVICE_MANGEMENT_H
19 
20 #include "hanfun/common.h"
21 #include "hanfun/uids.h"
22 
23 #include "hanfun/protocol.h"
24 
25 #include "hanfun/core.h"
26 #include "hanfun/device.h"
27 #include "hanfun/units.h"
28 
30 
31 namespace HF
32 {
33  // Forward declarations
34 
35  namespace Devices
36  {
37  namespace Concentrator
38  {
39  struct IUnit0;
40 
41  } // namespace Concentrator
42 
43  } // namespace Devices
44 
45  namespace Core
46  {
47  // Forward declaration.
48  namespace DeviceManagement
49  {
50  struct IServer;
51  } // namespace DeviceManagement
52 
68  uint8_t uid);
69 
73  namespace DeviceManagement
74  {
82  typedef enum _CMD
84  {
85  REGISTER_CMD = 0x01,
86  DEREGISTER_CMD = 0x02,
88  END_SESSION_CMD = 0x04,
89  GET_ENTRIES_CMD = 0x05,
90  __LAST_CMD__ = GET_ENTRIES_CMD
91  } CMD;
92 
94  typedef enum _Attributes
95  {
97  __LAST_ATTR__ = NUMBER_OF_ENTRIES_ATTR
98  } Attributes;
99 
100  constexpr static uint16_t START_ADDR = 0x0001;
101  constexpr static uint16_t END_ADDR = 0x7FFE;
102 
103  // =============================================================================
104 
108  struct Unit
109  {
110  uint8_t id;
111  uint16_t profile;
112 
114  std::vector<Common::Interface> interfaces;
115 
122  Unit(uint8_t id = 0, uint16_t profile = 0):
123  id(id), profile(profile)
124  {}
125 
131  Unit(const HF::Units::IUnit &unit):
132  id(unit.id()), profile(unit.uid()), interfaces(unit.interfaces())
133  {}
134 
136  static constexpr uint16_t min_size = sizeof(uint8_t) // Unit entry size.
137  + sizeof(uint8_t) // Unit ID.
138  + sizeof(uint16_t); // Unit's profile UID.
139 
141  uint16_t size() const;
142 
144  uint16_t pack(Common::ByteArray &array, uint16_t offset = 0) const;
145 
147  uint16_t unpack(const Common::ByteArray &array, uint16_t offset = 0);
148 
162  bool has_interface(uint16_t itf_uid, HF::Interface::Role role) const;
163  };
164 
166 
170  struct Device
171  {
172  uint16_t address;
173  std::vector<Unit> units;
174 
175  uint16_t emc;
176 
178 
179  Device(): address(Protocol::BROADCAST_ADDR), emc(0)
180  {}
181 
182  virtual ~Device()
183  {}
184 
185  // =============================================================================
186  // Serializable API
187  // =============================================================================
188 
190  static constexpr uint16_t min_size = sizeof(uint16_t) // Device Address.
191  + sizeof(uint8_t); // Number of units.
192 
194  uint16_t size() const;
195 
197  uint16_t pack(Common::ByteArray &array, uint16_t offset = 0) const;
198 
200  uint16_t unpack(const Common::ByteArray &array, uint16_t offset = 0);
201 
202  // =============================================================================
203  // Operators
204  // =============================================================================
205 
207  bool operator==(Device &other)
208  {
209  if (this->address != other.address || this->uid != other.uid)
210  {
211  return false;
212  }
213  else
214  {
215  return true;
216  }
217  }
218 
220  bool operator!=(Device &other)
221  {
222  return !(*this == other);
223  }
224 
225  // =============================================================================
226  // Helpers
227  // =============================================================================
228 
229  UnitPtr unit(uint16_t id) const
230  {
231  auto it = std::find_if(units.begin(), units.end(), [id](const Unit &unit)
232  {
233  return unit.id == id;
234  });
235 
236  if (it == units.end())
237  {
238  return UnitPtr();
239  }
240  else
241  {
242  return UnitPtr(*(it.base()));
243  }
244  }
245  };
246 
247  typedef Common::Pointer<const Device> DevicePtr;
248 
249  // =============================================================================
250  // Register Command Messages
251  // =============================================================================
252 
257  {
258  uint16_t emc;
259  std::vector<Unit> units;
260 
262 
269  RegisterMessage(uint16_t emc = 0x0000, HF::UID::UID _uid = HF::UID::UID()):
270  emc(emc), uid(_uid)
271  {}
272 
273  virtual ~RegisterMessage();
274 
276  static constexpr uint16_t min_size = UID::UID_T::min_size // UID.
277  + sizeof(uint8_t); // Number of units.
278 
280  uint16_t size() const;
281 
283  uint16_t pack(Common::ByteArray &array, uint16_t offset = 0) const;
284 
286  uint16_t unpack(const Common::ByteArray &array, uint16_t offset = 0);
287  };
288 
293  {
294  uint16_t address;
295  uint16_t emc;
296 
297  RegisterResponse(uint16_t address = Protocol::BROADCAST_ADDR, uint16_t emc = 0):
298  address(address & Protocol::BROADCAST_ADDR), emc(emc)
299  {}
300 
301  uint16_t size() const;
302 
303  uint16_t pack(Common::ByteArray &array, uint16_t offset = 0) const;
304 
305  uint16_t unpack(const Common::ByteArray &array, uint16_t offset = 0);
306  };
307 
308  // =============================================================================
309  // De-register Command Messages.
310  // =============================================================================
311 
316  {
317  uint16_t address;
318 
324  DeregisterMessage(uint16_t address = 0):
326  {}
327 
329  static constexpr uint16_t min_size = sizeof(uint16_t); // Device Address.
330 
332  uint16_t size() const;
333 
335  uint16_t pack(Common::ByteArray &array, uint16_t offset = 0) const;
336 
338  uint16_t unpack(const Common::ByteArray &array, uint16_t offset = 0);
339  };
340 
344  struct IEntries: public Common::IEntries<Device>
345  {
354  virtual DevicePtr find(uint16_t address) const = 0;
355 
364  virtual DevicePtr find(const HF::UID::UID &uid) const = 0;
365 
371  virtual uint16_t next_address() const = 0;
372  };
373 
385 
389  class Base: public Service<HF::Interface::DEVICE_MANAGEMENT>
390  {
391  protected:
392 
399  };
400 
404  class Client: public ServiceRole<Base, HF::Interface::CLIENT_ROLE>,
405  protected SessionManagement::Client<Device>
406  {
408 
409  protected:
410 
411  uint16_t _address;
412 
413  public:
414 
416 
423  Service(unit), SessionMgr(), _address(Protocol::BROADCAST_ADDR)
424  {}
425 
426  virtual ~Client() {}
427 
433  virtual uint16_t address() const
434  {
435  return _address;
436  }
437 
445  {
446  return *this;
447  }
448 
449  // ======================================================================
450  // Commands
451  // ======================================================================
454 
458  void register_device();
459 
465  void deregister(uint16_t address);
466 
470  void deregister()
471  {
472  deregister(_address);
473  }
474 
475  // ======================================================================
476  // Session Management
477  // ======================================================================
478 
482  void start_session() const
483  {
486  }
487 
494  void get_entries(uint16_t offset, uint8_t count = 0) const
495  {
496  SessionMgr::get_entries<SERVER_ROLE, Interface::DEVICE_MANAGEMENT,
497  GET_ENTRIES_CMD>(offset, count);
498  }
499 
503  void end_session() const
504  {
506  END_SESSION_CMD>();
507  }
508 
510  // ======================================================================
511 
512  // ======================================================================
513  // Events
514  // ======================================================================
517 
524  virtual void registered(RegisterResponse &response);
525 
533 
535  // ======================================================================
536 
537  using Service::send;
538 
540  void send(const Protocol::Address &addr, Protocol::Message &message)
541  {
542  Service::send(addr, message);
543  }
544 
545  protected:
546 
547  using ServiceRole::payload_size;
548 
549  uint16_t payload_size(Protocol::Message::Interface &itf) const;
550 
551  Common::Result handle_command(Protocol::Packet &packet, Common::ByteArray &payload,
552  uint16_t offset);
553  };
554 
558  struct IServer: public ServiceRole<Base, HF::Interface::SERVER_ROLE>
559  {
560  virtual ~IServer() {}
561 
562  // =============================================================================
563  // API
564  // =============================================================================
565 
575 
584  DevicePtr entry(uint16_t address) const;
585 
594  DevicePtr entry(const HF::UID::UID &uid) const
595  {
596  return entries().find(uid);
597  }
598 
605  virtual IEntries &entries() const = 0;
606 
613  virtual SessionManagement::IServer &sessions() = 0;
614 
615  // =============================================================================
616  // Interface Attribute API.
617  // =============================================================================
618 
619  HF::Attributes::IAttribute *attribute(uint8_t uid)
620  {
621  return Core::create_attribute(this, uid);
622  }
623 
624  HF::Attributes::UIDS attributes(uint8_t pack_id =
626  {
627  UNUSED(pack_id);
629  }
630 
636  virtual uint16_t next_address()
637  {
638  return entries().next_address();
639  }
640 
641  // ======================================================================
642  // Events
643  // ======================================================================
646 
653  virtual void registered(DevicePtr &device)
654  {
655  UNUSED(device);
656  }
657 
664  virtual void deregistered(DevicePtr &device)
665  {
666  UNUSED(device);
667  }
668 
670  // ======================================================================
671 
672  protected:
673 
680  {}
681  };
682 
686  struct AbstractServer: public IServer
687  {
688  virtual ~AbstractServer() {}
689 
690  // =============================================================================
691  // API
692  // =============================================================================
693 
694  protected:
695 
702  {}
703 
704  // ======================================================================
705  // Events
706  // ======================================================================
709 
714  Common::ByteArray &payload, uint16_t offset);
715 
720  Common::ByteArray &payload, uint16_t offset);
721 
723  // ======================================================================
724 
725  // ======================================================================
726  // Commands
727  // ======================================================================
730 
743  virtual bool authorized(uint8_t member, DevicePtr &source, DevicePtr &destination);
744 
754  virtual Common::Result deregister(DevicePtr &device);
755 
757  // ======================================================================
758 
760 
761  uint16_t payload_size(Protocol::Message::Interface &itf) const;
762 
763  Common::Result handle_command(Protocol::Packet &packet, Common::ByteArray &payload,
764  uint16_t offset);
765  };
766 
770  struct Entries: public IEntries
771  {
772  typedef std::vector<Device> Container;
773  typedef Container::iterator iterator;
774  typedef Container::const_iterator const_iterator;
775  typedef Container::value_type value_type;
776 
777  uint16_t size() const
778  {
779  return db.size();
780  }
781 
782  Common::Result save(const Device &entry);
783 
791  Common::Result destroy(const Device &entry);
792 
793  DevicePtr find(uint16_t address) const;
794 
795  DevicePtr find(const HF::UID::UID &uid) const;
796 
797  uint16_t next_address() const;
798 
804  iterator begin()
805  {
806  return db.begin();
807  }
808 
814  iterator end()
815  {
816  return db.end();
817  }
818 
824  const_iterator begin() const
825  {
826  return db.cbegin();
827  }
828 
834  const_iterator end() const
835  {
836  return db.cend();
837  }
838 
839  protected:
840 
842  Container db;
843  };
844 
849  template<typename _Entries = DeviceManagement::Entries>
850  struct Server: public AbstractServer, public SessionManagement::Server<_Entries>
851  {
853  typedef typename SessionMgr::Container Container;
854 
861  AbstractServer(unit), SessionManagement::Server<_Entries>()
862  {}
863 
864  virtual ~Server()
865  {}
866 
867  Container &entries() const
868  {
869  return SessionMgr::entries();
870  }
871 
873  {
874  return *this;
875  }
876 
877  using AbstractServer::send;
878 
879  void send(const Protocol::Address &addr, Protocol::Message &message)
880  {
881  AbstractServer::send(addr, message);
882  }
883 
884  protected:
885 
886  uint16_t payload_size(Protocol::Message::Interface &itf) const
887  {
888  switch (itf.member)
889  {
890  case START_SESSION_CMD:
892 
893  case GET_ENTRIES_CMD:
895 
896  case END_SESSION_CMD:
898 
899  default:
900  return AbstractService::payload_size(itf);
901  }
902  }
903 
904  Common::Result handle_command(Protocol::Packet &packet, Common::ByteArray &payload,
905  uint16_t offset)
906  {
907  switch (packet.message.itf.member)
908  {
909  case START_SESSION_CMD:
911  offset);
912 
913  case GET_ENTRIES_CMD:
914  return SessionMgr::handle_command(SessionManagement::GET, packet, payload,
915  offset);
916 
917  case END_SESSION_CMD:
918  return SessionMgr::handle_command(SessionManagement::END, packet, payload,
919  offset);
920 
921  default:
922  return AbstractServer::handle_command(packet, payload, offset);
923  }
924  }
925 
926  using SessionMgr::entries;
927  };
928 
929  // =========================================================================
930  // Default API Implementations
931  // =========================================================================
932 
933  typedef Server<> DefaultServer;
934 
935  // =============================================================================
936  // Operators
937  // =============================================================================
938 
939  inline bool operator==(const Unit &lhs, const Unit &rhs)
940  {
941  if (lhs.id != rhs.id)
942  {
943  return false;
944  }
945 
946  if (lhs.profile != rhs.profile)
947  {
948  return false;
949  }
950 
951  if (lhs.interfaces.size() != rhs.interfaces.size())
952  {
953  return false;
954  }
955 
956  for (uint8_t i = 0; i < lhs.interfaces.size(); i++)
957  {
958  if (lhs.interfaces[i] != rhs.interfaces[i])
959  {
960  return false;
961  }
962  }
963 
964  return true;
965  }
966 
967  inline bool operator!=(const Unit &lhs, const Unit &rhs)
968  {
969  return !(lhs == rhs);
970  }
971 
972  inline bool operator==(const Device &lhs, const Device &rhs)
973  {
974  if (lhs.address != rhs.address)
975  {
976  return false;
977  }
978 
979  if (lhs.units.size() != rhs.units.size())
980  {
981  return false;
982  }
983 
984  for (uint8_t i = 0; i < lhs.units.size(); i++)
985  {
986  if (lhs.units[i] != rhs.units[i])
987  {
988  return false;
989  }
990  }
991 
992  return true;
993  }
994 
995  inline bool operator!=(const Device &lhs, const Device &rhs)
996  {
997  return !(lhs == rhs);
998  }
999 
1002  } // namespace DeviceManagement
1003 
1004  } // namespace Core
1005 
1006 } // namespace HF
1007 
1013 // =============================================================================
1014 // Stream Helpers
1015 // =============================================================================
1016 
1025 std::ostream &operator<<(std::ostream &stream, const HF::Core::DeviceManagement::CMD command);
1026 
1035 std::ostream &operator<<(std::ostream &stream,
1036  const HF::Core::DeviceManagement::Attributes attribute);
1037 
1040 #endif /* HF_DEVICE_MANGEMENT_H */
uint16_t address
Address of the device to de-register.
DevicePtr find(uint16_t address) const
Return the Device entry for the given address.
HF::Devices::Concentrator::IUnit0 & unit0() const
Return a reference to the unit that this service belongs to.
iterator begin()
Get an iterator to the start of the entries in this container.
static constexpr uint16_t min_size
Minimum pack/unpack required data size.
bool operator!=(Device &other)
Not equals operator.
uint16_t size() const
Number bytes needed to serialize the message.
void send(const Protocol::Address &addr, Protocol::Message &message)
Send message msg to the network address given by addr.
bool response(Message::Type type)
Check if message is a response.
This represent the special unit with ID/UID = 0.
Definition: core.h:67
Helper template to inject session management functionality into services requiring it - Server side...
SessionManagement::Client< Device > SessionMgr
Device HAN-FUN Address.
Default implementation of the persistence API.
Message message
Packet message payload;.
Definition: protocol.h:306
const_iterator end() const
Get a constant iterator to the start of the entries in this container.
static constexpr uint16_t min_size
Minimum pack/unpack required data size.
uint16_t size() const
Number bytes needed to serialize the message.
Helper template to inject session management functionality into services requiring it - Client side...
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.
void end_session() const
End read entries session.
List of attributes UIDs.
Definition: attributes.h:176
std::ostream & operator<<(std::ostream &stream, const HF::Core::DeviceManagement::CMD command)
Convert the given command into a string and write it to the given stream.
DevicePtr entry(const HF::UID::UID &uid) const
Return the Device entry for the given UID.
Device Management interface : Server side default implementation.
Return all mandatory attributes for the interface.
Definition: attributes.h:842
This file contains the common defines for the HAN-FUN library.
Unit(const HF::Units::IUnit &unit)
Constructor.
Units::IUnit * unit(uint8_t id) const
Return pointer to the unit with the given id.
This file contains the forward declarations of the core services and interfaces implementing classes...
iterator end()
Get an iterator to the end of the entries in this container.
void deregister()
Send a de-register message for current address.
virtual void registered(DevicePtr &device)
Indicate that a device has been registered.
uint16_t unpack(const Common::ByteArray &array, uint16_t offset=0)
Read a message from a ByteArray.
bool operator==(Device &other)
Equals operator.
virtual uint16_t next_address()
Return next available address for registering a device.
virtual SessionManagement::IServer & sessions()=0
Reference to the session management API.
uint16_t unpack(const Common::ByteArray &array, uint16_t offset=0)
Read a message from a ByteArray.
constexpr uint16_t BROADCAST_ADDR
HAN-FUN Broadcast - device address.
Definition: protocol.h:45
Container & entries() const
Return the container for the service entries.
Device Management interface : Client side.
DeregisterMessage(uint16_t address=0)
Constructor.
void send(Protocol::Packet &packet)
Send given packet into the HAN-FUN network.
This file contains the definitions for the HAN-FUN protocol messages.
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.
Client(Unit0 &unit)
Constructor.
void get_entries(uint16_t offset, uint8_t count=0) const
Read entries.
virtual Common::Result register_device(Protocol::Packet &packet, Common::ByteArray &payload, uint16_t offset)
This method is called when a registration message is received.
uint16_t address
Device Address.
const_iterator begin() const
Get a constant iterator to the start of the entries in this container.
void start_session() const
Start read entries session.
Helper class used to implement custom functionality to the device management server side...
Parent class for bind management - server role.
bool has_interface(uint16_t itf_uid, HF::Interface::Role role) const
This method checks if the remote device unit implements the given interface.
HF::Attributes::IAttribute * create_attribute(uint8_t uid)
Create an attribute object that can hold the attribute with the given uid. (HF::Core::DeviceManagemen...
static constexpr uint16_t min_size
Minimum pack/unpack required data size.
Role
Interface roles.
Definition: interface.h:48
virtual void deregistered(DevicePtr &device)
Indicate that a device has been de-registered.
Container db
Actual container for the entries.
End the session for device.
virtual void registered(RegisterResponse &response)
This method is called when a response to a registration message is received.
void send(const Protocol::Address &addr, Protocol::Message &message)
Send message msg to the network address given by addr.
Device Management interface UID.
Definition: interface.h:60
virtual void deregistered(Protocol::Response &response)
This method is called when a response to a de-registration message is received.
Unit 0 interface API for HAN-FUN Concentrators.
Definition: devices.h:607
uint16_t address() const
Return the device address on the HAN-FUN network, when the device is registered, or HF_BROADCAST_ADDR...
Definition: devices.h:858
HF::UID::UID uid
Device units listing.
Unit0 & unit() const
The device this unit is associated with.
Definition: core.h:142
virtual uint16_t next_address() const =0
Return next available address for registering a device.
virtual Common::Result deregister_device(Protocol::Packet &packet, Common::ByteArray &payload, uint16_t offset)
This method is called when a de-registration message is received.
uint16_t emc
Device EMC if applicable, 0 otherwise.
Wrapper around UID_T pointer&#39;s.
Definition: uids.h:531
This class represents a byte array.
This file contains the definitions for the session management functionality.
RegisterMessage(uint16_t emc=0x0000, HF::UID::UID _uid=HF::UID::UID())
Device UID.
uint16_t size() const
Number bytes needed to serialize the message.
Network Address.
Definition: protocol.h:201
uint8_t member
Interface destination member.
Definition: protocol.h:99
Interface Address.
Definition: protocol.h:93
Network Message.
Definition: protocol.h:60
virtual uint16_t payload_size(Protocol::Message &message) const
Return the minimal payload size that should be present for the given message.
This file contains the definitions for the HAN-FUN unit implementation.
Session Management API : Server side.
This file contains the declaration of the classes that implement the HAN-FUN UIDs.
uint16_t emc
HAN-FUN Concentrator EMC if applicable.
static constexpr uint16_t min_size
Minimum pack/unpack required data size.
Unit(uint8_t id=0, uint16_t profile=0)
Constructor.
IServer(Unit0 &unit)
Constructor.
Base(Unit0 &unit)
Constructor.
HAN-FUN Protocol Packet.
Definition: protocol.h:298
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.
SessionMgr & session()
Reference to the session management API.
virtual Common::Result deregister(DevicePtr &device)
De-register the device that corresponds to the given Device entry.
Interface itf
Interface Address.
Definition: protocol.h:129
SessionMgr & sessions()
Reference to the session management API.
uint16_t unpack(const Common::ByteArray &array, uint16_t offset=0)
Read a message from a ByteArray.
Interface/Service Attribute API.
Definition: attributes.h:44
void register_device()
Send a register message.
uint16_t size() const
Number bytes needed to serialize the message.
This class represents the interface implemented by all HAN-FUN units.
Definition: units.h:48
Server(Unit0 &unit)
Constructor.
Parent class for the response messages.
Definition: protocol.h:368
Common::Result handle_command(CMD cmd, Protocol::Packet &packet, Common::ByteArray &payload, uint16_t offset=0)
Handle command request/response messages.
Class template for all interfaces role implementations.
Definition: core.h:225
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.
uint16_t unpack(const Common::ByteArray &array, uint16_t offset=0)
Read a message from a ByteArray.
Simple raw pointer wrapper.
std::vector< Unit > units
Device EMC if applicable, 0 otherwise.
#define UNUSED(x)
Helper macro to remove warning about unused function/method argument.
virtual uint16_t address() const
Return the address given by the HF Concentrator to the Device.
DevicePtr entry(uint16_t address) const
Return the Device entry for the given address.
Device Management - Persistent Storage API.
This file contains the declaration of the API for a HAN-FUN device.
End Session Read Registration Info.
uint16_t next_address() const
Return next available address for registering a device.
void request() const
Helper method to create a session management request.
static constexpr uint16_t min_size
Minimum pack/unpack required data size.
Definition: uids.h:94
Container & entries() const
Get a reference to the current object implementing the persistence API, for the device information...
Common::Result destroy(const Device &entry)
Destroy the given entry in the persistent storage.
virtual bool authorized(uint8_t member, DevicePtr &source, DevicePtr &destination)
This method serves to indicate if a given member of the interface can be used by the source device af...
std::vector< Unit > units
Unit list of the interface.
std::vector< Common::Interface > interfaces
Optional interfaces.
Class template for all core services implementations.
Definition: core.h:188
virtual IEntries & entries() const =0
Get a reference to the current object implementing the persistence API, for the device information...
uint16_t payload_size(CMD cmd) const
Get the minimum number of bytes necessary to pack/unpack a message of the given command.
virtual DevicePtr find(uint16_t address) const =0
Return the Device entry for the given address.
Device Management interface : Server side API.
Result
Commands result codes.
uint16_t size() const
Return the number of entries in the container.
Parent class for the Device Management interface implementation.
Start Session Read Registration Info.
HF::Attributes::IAttribute * create_attribute(HF::Core::AttributeReporting::IServer *server, uint8_t uid)
Create an attribute object that can hold the attribute with the given uid.
uint16_t address
Address for the device to use.
Start a new session for a device.
Basic API for persistent storage implementations.
Top-level namespace for the HAN-FUN library.
Definition: attributes.h:22