centralized/server.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2015 Pavel Kirienko <pavel.kirienko@gmail.com>
3  */
4 
5 #ifndef UAVCAN_PROTOCOL_DYNAMIC_NODE_ID_SERVER_CENTRALIZED_SERVER_HPP_INCLUDED
6 #define UAVCAN_PROTOCOL_DYNAMIC_NODE_ID_SERVER_CENTRALIZED_SERVER_HPP_INCLUDED
7 
9 #include <uavcan/debug.hpp>
14 
15 namespace uavcan
16 {
17 namespace dynamic_node_id_server
18 {
19 namespace centralized
20 {
28 class Server : public AbstractServer
29 {
31 
32  /*
33  * Private methods
34  */
35  bool isNodeIDTaken(const NodeID node_id) const
36  {
37  return storage_.isNodeIDOccupied(node_id);
38  }
39 
40  void tryPublishAllocationResult(const NodeID node_id, const UniqueID& unique_id)
41  {
42  const int res = allocation_request_manager_.broadcastAllocationResponse(unique_id, node_id);
43  if (res < 0)
44  {
46  node_.registerInternalFailure("Dynamic allocation response");
47  }
48  }
49 
50  /*
51  * Methods of IAllocationRequestHandler
52  */
54  {
55  return true; // Because there's only one Centralized server in the system
56  }
57 
58  virtual void handleAllocationRequest(const UniqueID& unique_id, const NodeID preferred_node_id)
59  {
60  const NodeID existing_node_id = storage_.getNodeIDForUniqueID(unique_id);
61  if (existing_node_id.isValid())
62  {
63  tryPublishAllocationResult(existing_node_id, unique_id);
64  }
65  else
66  {
67  const NodeID allocated_node_id =
68  NodeIDSelector<Server>(this, &Server::isNodeIDTaken).findFreeNodeID(preferred_node_id);
69 
70  if (allocated_node_id.isUnicast())
71  {
72  const int res = storage_.add(allocated_node_id, unique_id);
73  if (res >= 0)
74  {
75  tryPublishAllocationResult(allocated_node_id, unique_id);
76  }
77  else
78  {
80  node_.registerInternalFailure("CentralizedServer storage add");
81  }
82  }
83  else
84  {
85  UAVCAN_TRACE("dynamic_node_id_server::distributed::Server", "Request ignored - no free node ID left");
86  }
87  }
88  }
89 
90  /*
91  * Methods of INodeDiscoveryHandler
92  */
93  virtual bool canDiscoverNewNodes() const
94  {
95  return true; // Because there's only one Centralized server in the system
96  }
97 
98  virtual NodeAwareness checkNodeAwareness(NodeID node_id) const
99  {
101  }
102 
103  virtual void handleNewNodeDiscovery(const UniqueID* unique_id_or_null, NodeID node_id)
104  {
105  if (storage_.isNodeIDOccupied(node_id))
106  {
107  UAVCAN_ASSERT(0); // Such node is already known, the class that called this method should have known that
108  return;
109  }
110 
111  const int res = storage_.add(node_id, (unique_id_or_null == UAVCAN_NULLPTR) ? UniqueID() : *unique_id_or_null);
112  if (res < 0)
113  {
114  tracer_.onEvent(TraceError, res);
115  node_.registerInternalFailure("CentralizedServer storage add");
116  }
117  }
118 
119 public:
121  IStorageBackend& storage,
122  IEventTracer& tracer)
123  : AbstractServer(node, tracer)
124  , storage_(storage)
125  { }
126 
127  int init(const UniqueID& own_unique_id,
129  {
130  /*
131  * Initializing storage first, because the next step requires it to be loaded
132  */
133  int res = storage_.init();
134  if (res < 0)
135  {
136  return res;
137  }
138 
139  /*
140  * Common logic
141  */
142  res = AbstractServer::init(own_unique_id, priority);
143  if (res < 0)
144  {
145  return res;
146  }
147 
148  /*
149  * Making sure that the server is started with the same node ID
150  */
151  {
152  const NodeID stored_own_node_id = storage_.getNodeIDForUniqueID(getOwnUniqueID());
153  if (stored_own_node_id.isValid())
154  {
155  if (stored_own_node_id != node_.getNodeID())
156  {
157  return -ErrInvalidConfiguration;
158  }
159  }
160  else
161  {
162  res = storage_.add(node_.getNodeID(), getOwnUniqueID());
163  if (res < 0)
164  {
165  return res;
166  }
167  }
168  }
169 
170  return 0;
171  }
172 
173  uint8_t getNumAllocations() const { return storage_.getSize(); }
174 };
175 
176 }
177 }
178 }
179 
180 #endif // UAVCAN_PROTOCOL_DYNAMIC_NODE_ID_SERVER_CENTRALIZED_SERVER_HPP_INCLUDED
std::uint8_t uint8_t
Definition: std.hpp:24
int init(const UniqueID &own_unique_id, const TransferPriority priority=TransferPriority::OneHigherThanLowest)
bool isUnicast() const
Definition: transfer.hpp:136
virtual void onEvent(TraceCode event_code, int64_t event_argument)=0
Server(INode &node, IStorageBackend &storage, IEventTracer &tracer)
int init(const UniqueID &own_unique_id, const TransferPriority priority)
virtual void handleAllocationRequest(const UniqueID &unique_id, const NodeID preferred_node_id)
int add(const NodeID node_id, const UniqueID &unique_id)
Definition: storage.hpp:86
void tryPublishAllocationResult(const NodeID node_id, const UniqueID &unique_id)
protocol::dynamic_node_id::server::Entry::FieldTypes::unique_id UniqueID
virtual void registerInternalFailure(const char *msg)=0
NodeID getNodeIDForUniqueID(const UniqueID &unique_id) const
Definition: storage.hpp:133
virtual void handleNewNodeDiscovery(const UniqueID *unique_id_or_null, NodeID node_id)
NodeID getNodeID() const
bool isValid() const
Definition: transfer.hpp:134
int broadcastAllocationResponse(const UniqueID &unique_id, NodeID allocated_node_id)
virtual NodeAwareness checkNodeAwareness(NodeID node_id) const
TraceError
Definition: event.hpp:23
static const TransferPriority OneHigherThanLowest
Definition: transfer.hpp:40


uavcan_communicator
Author(s):
autogenerated on Wed Jan 11 2023 03:59:39