EnigmaIOT  0.9.8
Secure sensor and gateway platform based on ESP8266 and ESP32
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
NodeList.cpp
Go to the documentation of this file.
1 
8 #include "NodeList.h"
9 #include "helperFunctions.h"
10 
11 void Node::setEncryptionKey (const uint8_t* key) {
12  if (key) {
13  memcpy (this->key, key, KEY_LENGTH);
14  }
15 }
16 
18  node_t thisNode;
19 
20  memcpy (thisNode.key, key, KEY_LENGTH);
21  thisNode.keyValid = keyValid;
22  thisNode.keyValidFrom = keyValidFrom;
23  memcpy (thisNode.mac, mac, 6);
24  thisNode.nodeId = nodeId;
26  thisNode.status = status;
27  memcpy (thisNode.nodeName, getNodeName (), NODE_NAME_LENGTH);
28 
29  return thisNode;
30 }
31 
32 void Node::printToSerial (Stream* port) {
33  port->println ();
34  port->printf ("Node: %d\n", nodeId);
35  char macstr[ENIGMAIOT_ADDR_LEN * 3];
36  mac2str (mac, macstr);
37  port->printf ("\tMAC Address: %s\n", macstr);
38  port->printf ("\tLast counter: %u\n", lastMessageCounter);
39  port->printf ("\tKey valid from: %lu ms ago\n", (millis () - keyValidFrom));
40  port->printf ("\tKey: %s\n", keyValid ? "Valid" : "Invalid");
41  port->print ("\tStatus: ");
42  switch (status) {
43  case UNREGISTERED:
44  port->println ("Unregistered");
45  break;
46  case INIT:
47  port->println ("Initializing");
48  break;
49  case SLEEP:
50  port->println ("Going to sleep");
51  break;
53  port->println ("Wait for server hello");
54  break;
55  case WAIT_FOR_DOWNLINK:
56  port->println ("Wait for Downlik");
57  break;
58  case REGISTERED:
59  port->println ("Registered. Wait for messages");
60  break;
61  default:
62  port->println (status);
63  }
64  port->println ();
65 }
66 
68  float weight = 1;
69 
71  for (int i = 0; i < RATE_AVE_ORDER; i++) {
72  rateFilter->addWeigth (weight);
73  weight = weight / 2;
74  }
75 
76 }
77 
79  keyValid (false),
81  initRateFilter ();
82 }
83 
84 Node::Node (node_t nodeData) :
85  keyValid (nodeData.keyValid),
86  status (nodeData.status),
87  lastMessageCounter (nodeData.lastMessageCounter),
88  nodeId (nodeData.nodeId),
89  keyValidFrom (nodeData.keyValidFrom),
90  sleepyNode (nodeData.sleepyNode)
91  //packetNumber (0),
92  //packetErrors (0),
93  //per (0.0)
94 {
95  memcpy (key, nodeData.key, sizeof (uint16_t));
96  memcpy (mac, nodeData.mac, 6);
97 
98  initRateFilter ();
99 }
100 
101 void Node::updatePacketsRate (float value) {
102  packetsHour = rateFilter->addValue (value);
103 }
104 
105 
106 void Node::reset () {
107  DEBUG_DBG ("Reset node");
108  //memset (mac, 0, 6);
109  memset (key, 0, KEY_LENGTH);
110  memset (nodeName, 0, NODE_NAME_LENGTH);
111  keyValid = false;
112  lastMessageCounter = 0;
113  lastControlCounter = 0;
115  keyValidFrom = 0;
117  enigmaIOTVersion[0] = 0;
118  enigmaIOTVersion[1] = 0;
119  enigmaIOTVersion[2] = 0;
120  //broadcastEnabled = false;
121  broadcastKeyRequested = false;
122  if (rateFilter) {
123  DEBUG_DBG ("Reset packet rate");
124  rateFilter->clear ();
125  }
126  //sleepyNode = true;
127 }
128 
130  for (int i = 0; i < NUM_NODES; i++) {
131  nodes[i].nodeId = i;
132  }
133 }
134 
135 Node* NodeList::getNodeFromID (uint16_t nodeId) {
136  if (nodeId >= NUM_NODES)
137  return NULL;
138 
139  return &(nodes[nodeId]);
140 }
141 
142 Node* NodeList::getNodeFromMAC (const uint8_t* mac) {
143  uint16_t index = 0;
144 
145  if (!memcmp (broadcastNode.getEncriptionKey (), mac, ENIGMAIOT_ADDR_LEN)) {
146  return &broadcastNode;
147  }
148 
149  while (index < NUM_NODES) {
150  if (!memcmp (nodes[index].mac, mac, ENIGMAIOT_ADDR_LEN)) {
151  if (nodes[index].status != UNREGISTERED) {
152  return &(nodes[index]);
153  }
154  }
155  index++;
156  }
157 
158  return NULL;
159 }
160 
162  //broadcastNode = new Node ();
163  //node_t node;
164 
165  //uint8_t broadcastAddress[ENIGMAIOT_ADDR_LEN];
166  //memcpy (broadcastAddress, BROADCAST_ADDRESS, ENIGMAIOT_ADDR_LEN);
168  broadcastNode.setNodeId (0xffff);
170  broadcastNode.setSleepy (false);
172 }
173 
174 Node* NodeList::getNodeFromName (const char* name) {
175  uint16_t index = 0;
176 
177  // Check if address is an address as an string
178  uint8_t netAddr[ENIGMAIOT_ADDR_LEN];
179  if (str2mac (name, netAddr)) {
180  return getNodeFromMAC (netAddr);
181  }
182 
183  // check if destination is broadcast
184  if (!strncmp (name, broadcastNode.getNodeName (), NODE_NAME_LENGTH)) {
185  DEBUG_DBG ("Address '%s' is broadcast node", name);
186  return &broadcastNode;
187  }
188 
189  while (index < NUM_NODES) {
190  if (!strncmp (nodes[index].nodeName, name, NODE_NAME_LENGTH)) {
191  if (nodes[index].status != UNREGISTERED) {
192  return &(nodes[index]);
193  }
194  }
195  index++;
196  }
197 
198  return NULL;
199 }
200 
201 int8_t NodeList::checkNodeName (const char* name, const uint8_t* address) {
202  //bool found = false;
203 
204  if (strlen (name) > NODE_NAME_LENGTH - 1) {
205  DEBUG_ERROR ("Name too long %s", name);
206  return TOO_LONG; // Enmpty name
207  }
208 
209  if (!strlen (name)) {
210  DEBUG_ERROR ("Empty name", name);
211  return EMPTY_NAME; // Too long name
212  }
213 
214  for (int i = 0; i < NUM_NODES; i++) {
215  // if node is not registered and has this node name
216  DEBUG_DBG ("Node %d status is %d", i, nodes[i].status);
217  if (nodes[i].status != UNREGISTERED) {
218  char* currentNodeNamme = nodes[i].getNodeName ();
219  DEBUG_DBG ("Node %d name is %s", i, currentNodeNamme ? currentNodeNamme : "NULL");
220  if (currentNodeNamme && !strncmp (currentNodeNamme, name, NODE_NAME_LENGTH)) {
221  // if addresses addresses are different
222  //char addrStr[ENIGMAIOT_ADDR_LEN * 3];
223  DEBUG_INFO ("Found node name %s in Node List with address %s", name, mac2str (address));
224  if (memcmp (nodes[i].getMacAddress (), address, ENIGMAIOT_ADDR_LEN)) {
225  DEBUG_ERROR ("Duplicated name %s", name);
226  return ALREADY_USED; // Already used
227  }
228  }
229  }
230  }
231  return NAME_OK; // Name was not used
232 }
233 
235  uint16_t index = 0;
236 
237  while (index < NUM_NODES) {
238  if (nodes[index].status != UNREGISTERED) {
239  return &(nodes[index]);
240  }
241  index++;
242  }
243 
244  return NULL;
245 }
246 
248  uint16_t counter = 0;
249 
250  for (int i = 0; i < NUM_NODES; i++) {
251  if (nodes[i].status != UNREGISTERED) {
252  counter++;
253  }
254  }
255  return counter;
256 }
257 
258 bool NodeList::unregisterNode (uint16_t nodeId) {
259  if (nodeId < NUM_NODES) {
260  nodes[nodeId].reset ();
261 
262  if (nodes[nodeId].status != UNREGISTERED) {
263  nodes[nodeId].status = UNREGISTERED;
264  return true;
265  }
266  }
267  return false;
268 }
269 
270 bool NodeList::unregisterNode (const uint8_t* mac) {
271  Node* node = getNodeFromMAC (mac);
272  if (node) {
273  node->reset ();
274  node->status = UNREGISTERED;
275  return true;
276  } else {
277  return false;
278  }
279 }
280 
282  if (node) {
283  node->reset ();
284 
285  if (nodes[node->nodeId].status != UNREGISTERED) {
286  nodes[node->nodeId].status = UNREGISTERED;
287  return true;
288  } else {
289  return false;
290  }
291  }
292  return false;
293 }
294 
295 Node* NodeList::getNextActiveNode (uint16_t nodeId) {
296  if (nodeId == 0xFFFF) {
297  if (nodes[0].status != UNREGISTERED) {
298  return &(nodes[0]);
299  }
300  }
301  for (int i = nodeId + 1; i < NUM_NODES; i++) {
302  if (nodes[i].status != UNREGISTERED) {
303  return &(nodes[i]);
304  }
305  }
306  return NULL;
307 }
308 
310  if (!node) {
311  if (nodes[0].status != UNREGISTERED) {
312  return &(nodes[0]);
313  }
314  node = &(nodes[0]);
315  }
316  for (int i = node->nodeId + 1; i < NUM_NODES; i++) {
317  if (nodes[i].status != UNREGISTERED) {
318  return &(nodes[i]);
319  }
320  }
321  return NULL;
322 }
323 
324 Node* NodeList::getNewNode (const uint8_t* mac) {
325  Node* node = getNodeFromMAC (mac);
326  if (node) {
327  return node;
328  } else {
329  for (int i = 0; i < NUM_NODES; i++) {
330  if (nodes[i].status == UNREGISTERED) {
331  nodes[i].setMacAddress (const_cast<uint8_t*>(mac));
332  nodes[i].reset ();
333  return &(nodes[i]);
334  }
335  }
336  }
337  return NULL;
338 }
339 
340 void NodeList::printToSerial (Stream* port) {
341  for (int i = 0; i < NUM_NODES; i++) {
342  if (nodes[i].status != UNREGISTERED) {
343  nodes[i].printToSerial (port);
344  }
345  }
346 }
Node::lastMessageCounter
uint16_t lastMessageCounter
Last message counter state for specific Node.
Definition: NodeList.h:479
NodeList::broadcastNode
Node broadcastNode
Node instance that holds data used for broadcast messages. This does not represent any individual nod...
Definition: NodeList.h:633
Node::broadcastKeyRequested
bool broadcastKeyRequested
Node is waiting for broadcast key.
Definition: NodeList.h:486
node_instance::lastMessageCounter
uint16_t lastMessageCounter
Last message counter state for specific Node.
Definition: NodeList.h:93
NodeList::findEmptyNode
Node * findEmptyNode()
Searches for a free place for a new Node instance.
Definition: NodeList.cpp:234
NodeList::getNodeFromName
Node * getNodeFromName(const char *name)
Gets node that correspond with given node name.
Definition: NodeList.cpp:174
EMPTY_NAME
@ EMPTY_NAME
Definition: NodeList.h:35
ENIGMAIOT_ADDR_LEN
static const size_t ENIGMAIOT_ADDR_LEN
Address size. Mac address = 6 bytes.
Definition: EnigmaIoTconfigAdvanced.h:23
Node::setNodeName
void setNodeName(const char *name)
Sets Node name.
Definition: NodeList.h:164
NodeList.h
EnigmaIoT sensor node management structures.
NodeList::printToSerial
void printToSerial(Stream *port)
Dumps node list data to a Stream object.
Definition: NodeList.cpp:340
Node::setStatus
void setStatus(status_t status)
Sets status for finite state machine that represents node.
Definition: NodeList.h:308
NodeList::nodes
Node nodes[NUM_NODES]
Static Node array that holds maximum number of supported nodes.
Definition: NodeList.h:632
NODE_NAME_LENGTH
static const uint8_t NODE_NAME_LENGTH
Maximum number of characters of node name.
Definition: EnigmaIoTconfigAdvanced.h:25
SLEEP
@ SLEEP
Definition: NodeList.h:29
NodeList::initBroadcastNode
void initBroadcastNode()
Init broadcast node data.
Definition: NodeList.cpp:161
NodeList::getNewNode
Node * getNewNode(const uint8_t *mac)
Finds a node that correspond with given address of creates a new one if it does not exist.
Definition: NodeList.cpp:324
Node::setNodeId
void setNodeId(uint16_t nodeId)
Sets a new Node identifier.
Definition: NodeList.h:144
str2mac
uint8_t * str2mac(const char *macAddrString, uint8_t *macBytes)
Debug helper function that creates MAC address byte array from text representation.
Definition: helperFunctions.cpp:104
Node::keyValid
bool keyValid
Node shared key valid.
Definition: NodeList.h:477
NodeList::getNodeFromMAC
Node * getNodeFromMAC(const uint8_t *mac)
Gets node that correspond with given address.
Definition: NodeList.cpp:142
NodeList::NodeList
NodeList()
Node list constructor.
Definition: NodeList.cpp:129
node_instance::key
uint8_t key[32]
Shared key.
Definition: NodeList.h:92
RATE_AVE_ORDER
static const int RATE_AVE_ORDER
Message rate filter order.
Definition: EnigmaIoTconfig.h:29
Node::getNodeData
node_t getNodeData()
Gets a struct that represents node object. May be used for node serialization.
Definition: NodeList.cpp:17
node_instance::keyValid
bool keyValid
Node shared key valid.
Definition: NodeList.h:99
Node::nodeId
uint16_t nodeId
Node identifier asigned by gateway.
Definition: NodeList.h:482
NodeList::unregisterNode
bool unregisterNode(uint16_t nodeId)
Frees up a node and marks it as available.
Definition: NodeList.cpp:258
node_instance::nodeId
uint16_t nodeId
Node identifier asigned by gateway.
Definition: NodeList.h:91
INIT
@ INIT
Definition: NodeList.h:25
FilterClass::addValue
float addValue(float value)
Pushes a new value for calculation. Until the buffer is filled up to filter order,...
Definition: Filter.cpp:12
Node::enigmaIOTVersion
uint8_t enigmaIOTVersion[3]
Protocol version, filled when a version message is received.
Definition: NodeList.h:495
Node::lastControlCounter
uint16_t lastControlCounter
Last message counter state for specific Node.
Definition: NodeList.h:480
Node::keyValidFrom
timer_t keyValidFrom
Last time that Node and Gateway agreed a key.
Definition: NodeList.h:483
node_instance::nodeName
char nodeName[NODE_NAME_LENGTH]
Node name. Use as a human friendly name to avoid use of numeric address.
Definition: NodeList.h:101
NAME_OK
@ NAME_OK
Definition: NodeList.h:33
Node::setSleepy
void setSleepy(bool sleepy)
Sets node working mode regarding battery saving strategy. If node is sleepy it will turn into deep sl...
Definition: NodeList.h:334
Node::initRateFilter
void initRateFilter()
Starts smoothing filter.
Definition: NodeList.cpp:67
WAIT_FOR_SERVER_HELLO
@ WAIT_FOR_SERVER_HELLO
Definition: NodeList.h:26
Node::reset
void reset()
Resets all node fields to a default initial and not registered state.
Definition: NodeList.cpp:106
Node::setEncryptionKey
void setEncryptionKey(const uint8_t *key)
Sets encryption key.
Definition: NodeList.cpp:11
Node::status
status_t status
Current node status. See enum node_status
Definition: NodeList.h:478
Node::packetsHour
double packetsHour
Packet rate for a specific nope.
Definition: NodeList.h:472
NodeList::getNextActiveNode
Node * getNextActiveNode(uint16_t nodeId)
Gets next active node by nodeId.
Definition: NodeList.cpp:295
Node::getEncriptionKey
uint8_t * getEncriptionKey()
Gets Node encryption key.
Definition: NodeList.h:173
NUM_NODES
static const int NUM_NODES
Maximum number of nodes that this gateway can handle.
Definition: EnigmaIoTconfig.h:32
FilterClass
Definition: Filter.h:29
node_instance
Struct that define node fields. Used for long term storage needs.
Definition: NodeList.h:89
Node::key
uint8_t key[KEY_LENGTH]
Shared key.
Definition: NodeList.h:490
Node::lastDownlinkMsgCounter
uint16_t lastDownlinkMsgCounter
Last downlink message counter state for specific Node.
Definition: NodeList.h:481
WAIT_FOR_DOWNLINK
@ WAIT_FOR_DOWNLINK
Definition: NodeList.h:27
node_instance::status
status_t status
Node state.
Definition: NodeList.h:98
BROADCAST_NONE_NAME
static const char BROADCAST_NONE_NAME[]
Name to reference broadcast node.
Definition: EnigmaIoTconfigAdvanced.h:27
Node::setMacAddress
void setMacAddress(const uint8_t *macAddress)
Sets node address.
Definition: NodeList.h:266
Node::mac
uint8_t mac[ENIGMAIOT_ADDR_LEN]
Node address.
Definition: NodeList.h:489
KEY_LENGTH
const uint8_t KEY_LENGTH
Key length used by selected crypto algorythm. The only tested value is 32. Change it only if you know...
Definition: EnigmaIoTconfigAdvanced.h:70
Node::getNodeName
char * getNodeName()
Gets Node name.
Definition: NodeList.h:152
Node::rateFilter
FilterClass * rateFilter
Filter for message rate smoothing.
Definition: NodeList.h:492
node_instance::keyValidFrom
time_t keyValidFrom
Last time that Node and Gateway agreed a key.
Definition: NodeList.h:96
BROADCAST_ADDRESS
static const uint8_t BROADCAST_ADDRESS[]
Broadcast address.
Definition: EnigmaIoTconfigAdvanced.h:26
Node::updatePacketsRate
void updatePacketsRate(float value)
Adds a new message rate value for filter calculation.
Definition: NodeList.cpp:101
Node
Class definition for a single sensor Node.
Definition: NodeList.h:109
NodeList::checkNodeName
int8_t checkNodeName(const char *name, const uint8_t *address)
Check Node name for duplicate.
Definition: NodeList.cpp:201
FilterClass::addWeigth
float addWeigth(float coeff)
Adds a new weighting value. It is pushed on the array so latest value will be used for older data.
Definition: Filter.cpp:25
TOO_LONG
@ TOO_LONG
Definition: NodeList.h:36
ALREADY_USED
@ ALREADY_USED
Definition: NodeList.h:34
UNREGISTERED
@ UNREGISTERED
Definition: NodeList.h:24
FilterClass::clear
void clear()
Resets state of the filter to an initial value.
Definition: Filter.cpp:128
Node::Node
Node()
Plain constructor.
Definition: NodeList.cpp:78
Node::printToSerial
void printToSerial(Stream *port=&Serial)
Dumps node data to the given stream, Serial by default. This method may be used for debugging.
Definition: NodeList.cpp:32
REGISTERED
@ REGISTERED
Definition: NodeList.h:28
node_instance::mac
uint8_t mac[ENIGMAIOT_ADDR_LEN]
Node address.
Definition: NodeList.h:90
mac2str
char * mac2str(const uint8_t *mac, char *extBuffer)
Debug helper function that generates a string that represent a MAC address.
Definition: helperFunctions.cpp:85
helperFunctions.h
Auxiliary function definition.
NodeList::getNodeFromID
Node * getNodeFromID(uint16_t nodeId)
Gets node that correspond with given nodeId.
Definition: NodeList.cpp:135
Node::nodeName
char nodeName[NODE_NAME_LENGTH]
Node name. Use as a human friendly name to avoid use of numeric address.
Definition: NodeList.h:493
EnigmaIoTUpdate.sleepyNode
bool sleepyNode
Definition: EnigmaIoTUpdate.py:13
NodeList::countActiveNodes
uint16_t countActiveNodes()
Gets the number of active nodes (registered or registering)
Definition: NodeList.cpp:247
status
@ status
Definition: GwOutput_generic.h:25
AVERAGE_FILTER
@ AVERAGE_FILTER
Definition: Filter.h:26