ProsecCoAP 🥂
 
Loading...
Searching...
No Matches
Observers.h
Go to the documentation of this file.
1
8#ifndef OBSERVERS_H_INCLUDED
9#define OBSERVERS_H_INCLUDED
10
11#include <Arduino.h>
12#include "../Definitions.h"
13
14namespace Coap
15{
16
23 {
24 private:
28 bool _active : 8;
29
33 IPAddress _ip;
37 uint16_t _port = 0;
44 uint8_t _token[COAP_MAX_TOKEN_LENGTH] = {0};
51 uint8_t _tokenLength = 0;
52
53 public:
57 Observer() : _active(false) {}
58
67 Observer(IPAddress ip, uint16_t port, const uint8_t *token, uint8_t tokenLength)
68 : _active(true), _ip(ip), _port(port), _tokenLength(tokenLength)
69 {
70 // Copy the token value, ensuring that we do not exceed the maximum token length.
71 memcpy(this->_token, token, tokenLength > COAP_MAX_TOKEN_LENGTH ? COAP_MAX_TOKEN_LENGTH : tokenLength);
72 }
73
80 bool isActive() const
81 {
82 return this->_active;
83 }
84
91 void setActive(bool active)
92 {
93 this->_active = active;
94 }
95
100 IPAddress getIp() const
101 {
102 return this->_ip;
103 }
104
109 uint16_t getPort() const
110 {
111 return this->_port;
112 }
113
118 const uint8_t *getToken() const
119 {
120 return this->_token;
121 }
122
127 uint8_t getTokenLength() const
128 {
129 return this->_tokenLength;
130 }
131
145 {
146 unsigned long currentTime = millis();
147 return currentTime & 0xFFFFFF; // Return only the least significant 24 bits.
148 }
149 };
150
165 template <size_t N>
167 {
168 // Ensure N is at least 1.
169 static_assert(N >= 1, "ObserverRegistry Error: N must be 1 or greater!");
170
171 private:
175 Observer _observers[N];
176
177 public:
183 Observer &operator[](size_t index)
184 {
185 return _observers[index];
186 }
187
193 const Observer &operator[](size_t index) const
194 {
195 return _observers[index];
196 }
197
203 size_t length() const
204 {
205 return N;
206 }
207
213 size_t countActive() const
214 {
215 size_t count = 0;
216 for (size_t i = 0; i < N; i++)
217 {
218 if (this->_observers[i].isActive())
219 count++;
220 }
221 return count;
222 }
223
238 ErrorCode add(IPAddress ip, uint16_t port, const uint8_t *token, uint8_t tokenLength)
239 {
240 // We MUST check if the observer is already present before trying to add it, to avoid duplicates.
241 for (size_t i = 0; i < N; i++)
242 {
243 if (!this->_observers[i].isActive())
244 continue; // Skip inactive observers.
245
246 // An observer is considered the same if it matches the combination of IP address, port, token and token length.
247 if (this->_observers[i].getIp() == ip &&
248 this->_observers[i].getPort() == port &&
249 this->_observers[i].getTokenLength() == tokenLength &&
250 memcmp(this->_observers[i].getToken(), token, tokenLength) == 0)
251 {
252 // Matching active observer found. No need to add it again.
253 return ErrorCode::OK;
254 }
255 }
256
257 // New observer.
258 // Find the first inactive observer slot and add the new observer there.
259 for (size_t i = 0; i < N; i++)
260 {
261 if (!this->_observers[i].isActive())
262 {
263 // Inactive slot found. Add the new observer here (active by default, see constructor).
264 this->_observers[i] = Observer(ip, port, token, tokenLength);
265 return ErrorCode::OK;
266 }
267 }
268
270 }
271
285 ErrorCode remove(IPAddress ip, uint16_t port, const uint8_t *token, uint8_t tokenLength)
286 {
287 // Find the observer matching the given parameters and remove it.
288 for (size_t i = 0; i < N; i++)
289 {
290 if (!this->_observers[i].isActive())
291 continue; // Skip inactive observers.
292 if (this->_observers[i].getIp() == ip &&
293 this->_observers[i].getPort() == port &&
294 this->_observers[i].getTokenLength() == tokenLength &&
295 memcmp(this->_observers[i].getToken(), token, tokenLength) == 0)
296 {
297 // Matching observer found. Remove it by marking it as inactive.
298 this->_observers[i].setActive(false);
299 return ErrorCode::OK;
300 }
301 }
303 }
304
316 ErrorCode remove(IPAddress ip, uint16_t port)
317 {
319 // Find the observer matching the given parameters and remove it.
320 for (size_t i = 0; i < N; i++)
321 {
322 if (!this->_observers[i].isActive())
323 continue; // Skip inactive observers.
324 if (this->_observers[i].getIp() == ip &&
325 this->_observers[i].getPort() == port)
326 {
327 // Matching observer found. Remove it by marking it as inactive.
328 this->_observers[i].setActive(false);
329 result = ErrorCode::OK;
330 }
331 }
332 return result;
333 }
334
345 ErrorCode remove(IPAddress ip)
346 {
348 // Find the observer matching the given parameters and remove it.
349 for (size_t i = 0; i < N; i++)
350 {
351 if (!this->_observers[i].isActive())
352 continue; // Skip inactive observers.
353 if (this->_observers[i].getIp() == ip)
354 {
355 // Matching observer found. Remove it by marking it as inactive.
356 this->_observers[i].setActive(false);
357 result = ErrorCode::OK;
358 }
359 }
360 return result;
361 }
362
371 ErrorCode remove(const Observer &observer)
372 {
373 return this->remove(observer.getIp(), observer.getPort(), observer.getToken(), observer.getTokenLength());
374 }
375 };
376}
377
378#endif // OBSERVERS_H_INCLUDED
A resource observer registry.
Definition Observers.h:167
ErrorCode remove(const Observer &observer)
Remove an observer from the registry.
Definition Observers.h:371
size_t countActive() const
Get the number of active observers currently stored in the registry.
Definition Observers.h:213
size_t length() const
Get the maximum number of observers that can be stored in the registry.
Definition Observers.h:203
ErrorCode remove(IPAddress ip, uint16_t port, const uint8_t *token, uint8_t tokenLength)
Remove an observer from the registry.
Definition Observers.h:285
ErrorCode add(IPAddress ip, uint16_t port, const uint8_t *token, uint8_t tokenLength)
Add a new observer to the registry.
Definition Observers.h:238
ErrorCode remove(IPAddress ip, uint16_t port)
Remove any observers with the given combination of IP and port.
Definition Observers.h:316
ErrorCode remove(IPAddress ip)
Remove any observers with the given IP.
Definition Observers.h:345
Observer & operator[](size_t index)
Get the observer at the given index.
Definition Observers.h:183
const Observer & operator[](size_t index) const
Get the observer at the given index.
Definition Observers.h:193
A remote CoAP observer, actively observing a resource.
Definition Observers.h:23
uint8_t getTokenLength() const
Get the token length used by the observer.
Definition Observers.h:127
Observer()
Default constructor that creates an inactive observer.
Definition Observers.h:57
const uint8_t * getToken() const
Get the token pointer used by the observer.
Definition Observers.h:118
uint16_t getPort() const
Get the port of the observer.
Definition Observers.h:109
Observer(IPAddress ip, uint16_t port, const uint8_t *token, uint8_t tokenLength)
Constructor that creates an active observer with the given parameters.
Definition Observers.h:67
void setActive(bool active)
Set the observer as active or inactive.
Definition Observers.h:91
bool isActive() const
Check if the observer is currently active.
Definition Observers.h:80
IPAddress getIp() const
Get the IP address of the observer.
Definition Observers.h:100
uint32_t getNextSequentialNumber()
The sequential number for notifications, as per specifications.
Definition Observers.h:144
constexpr uint8_t COAP_MAX_TOKEN_LENGTH
The maximum length of a CoAP token.
Definition Definitions.h:149
Namespace for the library.
Definition Definitions.h:155
ErrorCode
Error codes used in the library.
Definition Definitions.h:321
IPAddress ip(192, 168, 0, DEVICE_ID)