EnigmaIOT  0.9.8
Secure sensor and gateway platform based on ESP8266 and ESP32
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