EnigmaIOT  0.9.3
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 
28  return thisNode;
29 }
30 
31 void Node::printToSerial (Stream* port) {
32  port->println ();
33  port->printf ("Node: %d\n", nodeId);
34  char macstr[ENIGMAIOT_ADDR_LEN * 3];
35  mac2str (mac, macstr);
36  port->printf ("\tMAC Address: %s\n", macstr);
37  port->printf ("\tLast counter: %u\n", lastMessageCounter);
38  port->printf ("\tKey valid from: %lu ms ago\n", (millis () - keyValidFrom));
39  port->printf ("\tKey: %s\n", keyValid ? "Valid" : "Invalid");
40  port->print ("\tStatus: ");
41  switch (status) {
42  case UNREGISTERED:
43  port->println ("Unregistered");
44  break;
45  case INIT:
46  port->println ("Initializing");
47  break;
48  case SLEEP:
49  port->println ("Going to sleep");
50  break;
52  port->println ("Wait for server hello");
53  break;
54  case WAIT_FOR_DOWNLINK:
55  port->println ("Wait for Downlik");
56  break;
57  case REGISTERED:
58  port->println ("Registered. Wait for messages");
59  break;
60  default:
61  port->println (status);
62  }
63  port->println ();
64 }
65 
67  float weight = 1;
68 
70  for (int i = 0; i < RATE_AVE_ORDER; i++) {
71  rateFilter->addWeigth (weight);
72  weight = weight / 2;
73  }
74 
75 }
76 
78  keyValid (false),
80  initRateFilter ();
81 }
82 
83 Node::Node (node_t nodeData) :
84  keyValid (nodeData.keyValid),
85  status (nodeData.status),
86  lastMessageCounter (nodeData.lastMessageCounter),
87  nodeId (nodeData.nodeId),
88  keyValidFrom (nodeData.keyValidFrom)
89  //packetNumber (0),
90  //packetErrors (0),
91  //per (0.0)
92 {
93  memcpy (key, nodeData.key, sizeof (uint16_t));
94  memcpy (mac, nodeData.mac, 6);
95 
96  initRateFilter ();
97 }
98 
99 void Node::updatePacketsRate (float value) {
100  packetsHour = rateFilter->addValue (value);
101 }
102 
103 
104 void Node::reset () {
105  DEBUG_DBG ("Reset node");
106  //memset (mac, 0, 6);
107  memset (key, 0, KEY_LENGTH);
108  memset (nodeName, 0, NODE_NAME_LENGTH);
109  keyValid = false;
110  lastMessageCounter = 0;
111  keyValidFrom = 0;
113  if (rateFilter) {
114  DEBUG_DBG ("Reset packet rate");
115  rateFilter->clear ();
116  }
117  //sleepyNode = true;
118 }
119 
121  for (int i = 0; i < NUM_NODES; i++) {
122  nodes[i].nodeId = i;
123  }
124 }
125 
126 Node* NodeList::getNodeFromID (uint16_t nodeId) {
127  if (nodeId >= NUM_NODES)
128  return NULL;
129 
130  return &(nodes[nodeId]);
131 }
132 
133 Node* NodeList::getNodeFromMAC (const uint8_t* mac) {
134  uint16_t index = 0;
135 
136  while (index < NUM_NODES) {
137  if (!memcmp (nodes[index].mac, mac, 6)) {
138  if (nodes[index].status != UNREGISTERED) {
139  return &(nodes[index]);
140  }
141  }
142  index++;
143  }
144 
145  return NULL;
146 }
147 
148 Node* NodeList::getNodeFromName (const char* name) {
149  uint16_t index = 0;
150 
151  while (index < NUM_NODES) {
152  if (!strncmp (nodes[index].nodeName, name, NODE_NAME_LENGTH)) {
153  if (nodes[index].status != UNREGISTERED) {
154  return &(nodes[index]);
155  }
156  }
157  index++;
158  }
159 
160  return NULL;
161 }
162 
163 int8_t NodeList::checkNodeName (const char* name, const uint8_t* address) {
164  bool found = false;
165 
166  if (strlen (name) > NODE_NAME_LENGTH - 1) {
167  DEBUG_ERROR ("Name too long %s", name);
168  return TOO_LONG; // Enmpty name
169  }
170 
171  if (!strlen (name)) {
172  DEBUG_ERROR ("Empty name", name);
173  return EMPTY_NAME; // Too long name
174  }
175 
176  for (int i = 0; i < NUM_NODES; i++) {
177  // if node is not registered and has this node name
178  DEBUG_DBG ("Node %d status is %d", i, nodes[i].status);
179  if (nodes[i].status != UNREGISTERED) {
180  char* currentNodeNamme = nodes[i].getNodeName ();
181  DEBUG_DBG ("Node %d name is %s", i, currentNodeNamme ? currentNodeNamme : "NULL");
182  if (currentNodeNamme && !strncmp (currentNodeNamme, name, NODE_NAME_LENGTH)) {
183  // if addresses addresses are different
184  char addrStr[ENIGMAIOT_ADDR_LEN * 3];
185  DEBUG_INFO ("Found node name %s in Node List with address %s", name, mac2str (address, addrStr));
186  if (memcmp (nodes[i].getMacAddress (), address, ENIGMAIOT_ADDR_LEN)) {
187  DEBUG_ERROR ("Duplicated name %s", name);
188  return ALREADY_USED; // Already used
189  }
190  }
191  }
192  }
193  return NAME_OK; // Name was not used
194 }
195 
197  uint16_t index = 0;
198 
199  while (index < NUM_NODES) {
200  if (nodes[index].status != UNREGISTERED) {
201  return &(nodes[index]);
202  }
203  index++;
204  }
205 
206  return NULL;
207 }
208 
210  uint16_t counter = 0;
211 
212  for (int i = 0; i < NUM_NODES; i++) {
213  if (nodes[i].status != UNREGISTERED) {
214  counter++;
215  }
216  }
217  return counter;
218 }
219 
220 bool NodeList::unregisterNode (uint16_t nodeId) {
221  if (nodeId < NUM_NODES) {
222  nodes[nodeId].reset ();
223 
224  if (nodes[nodeId].status != UNREGISTERED) {
225  nodes[nodeId].status = UNREGISTERED;
226  return true;
227  }
228  }
229  return false;
230 }
231 
232 bool NodeList::unregisterNode (const uint8_t* mac) {
233  Node* node = getNodeFromMAC (mac);
234  if (node) {
235  node->reset ();
236  node->status = UNREGISTERED;
237  return true;
238  } else {
239  return false;
240  }
241 }
242 
244  if (node) {
245  node->reset ();
246 
247  if (nodes[node->nodeId].status != UNREGISTERED) {
248  nodes[node->nodeId].status = UNREGISTERED;
249  return true;
250  } else {
251  return false;
252  }
253  }
254  return false;
255 }
256 
257 Node* NodeList::getNextActiveNode (uint16_t nodeId) {
258  for (int i = nodeId + 1; i < NUM_NODES; i++) {
259  if (nodes[i].status != UNREGISTERED) {
260  return &(nodes[i]);
261  }
262  }
263  return NULL;
264 }
265 
267  for (int i = node.nodeId + 1; i < NUM_NODES; i++) {
268  if (nodes[i].status != UNREGISTERED) {
269  return &(nodes[i]);
270  }
271  }
272  return NULL;
273 }
274 
275 Node* NodeList::getNewNode (const uint8_t* mac) {
276  Node* node = getNodeFromMAC (mac);
277  if (node) {
278  return node;
279  } else {
280  for (int i = 0; i < NUM_NODES; i++) {
281  if (nodes[i].status == UNREGISTERED) {
282  nodes[i].setMacAddress (const_cast<uint8_t*>(mac));
283  return &(nodes[i]);
284  }
285  }
286  }
287  return NULL;
288 }
289 
290 void NodeList::printToSerial (Stream* port) {
291  for (int i = 0; i < NUM_NODES; i++) {
292  if (nodes[i].status != UNREGISTERED) {
293  nodes[i].printToSerial (port);
294  }
295  }
296 }
Node::lastMessageCounter
uint16_t lastMessageCounter
Last message counter state for specific Node.
Definition: NodeList.h:339
node_instance::lastMessageCounter
uint16_t lastMessageCounter
Last message counter state for specific Node.
Definition: NodeList.h:80
NodeList::findEmptyNode
Node * findEmptyNode()
Searches for a free place for a new Node instance.
Definition: NodeList.cpp:196
NodeList::getNodeFromName
Node * getNodeFromName(const char *name)
Gets node that correspond with given node name.
Definition: NodeList.cpp:148
EMPTY_NAME
@ EMPTY_NAME
Definition: NodeList.h:35
NodeList.h
EnigmaIoT sensor node management structures.
NodeList::printToSerial
void printToSerial(Stream *port)
Dumps node list data to a Stream object.
Definition: NodeList.cpp:290
NodeList::nodes
Node nodes[NUM_NODES]
Static Node array that holds maximum number of supported nodes.
Definition: NodeList.h:457
SLEEP
@ SLEEP
Definition: NodeList.h:29
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:275
Node::keyValid
bool keyValid
Node shared key valid.
Definition: NodeList.h:337
NodeList::getNodeFromMAC
Node * getNodeFromMAC(const uint8_t *mac)
Gets node that correspond with given address.
Definition: NodeList.cpp:133
NodeList::NodeList
NodeList()
Node list constructor.
Definition: NodeList.cpp:120
ENIGMAIOT_ADDR_LEN
static const size_t ENIGMAIOT_ADDR_LEN
Address size. Mac address = 6 bytes.
Definition: EnigmaIoTconfig.h:14
node_instance::key
uint8_t key[32]
Shared key.
Definition: NodeList.h:79
NODE_NAME_LENGTH
static const uint8_t NODE_NAME_LENGTH
Maximum number of characters of node name.
Definition: EnigmaIoTconfig.h:19
RATE_AVE_ORDER
static const int RATE_AVE_ORDER
Message rate filter order.
Definition: EnigmaIoTconfig.h:27
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:84
Node::nodeId
uint16_t nodeId
Node identifier asigned by gateway.
Definition: NodeList.h:340
NodeList::unregisterNode
bool unregisterNode(uint16_t nodeId)
Frees up a node and marks it as available.
Definition: NodeList.cpp:220
node_instance::nodeId
uint16_t nodeId
Node identifier asigned by gateway.
Definition: NodeList.h:78
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::setMacAddress
void setMacAddress(uint8_t *macAddress)
Sets node address.
Definition: NodeList.h:218
Node::keyValidFrom
timer_t keyValidFrom
Last time that Node and Gateway agreed a key.
Definition: NodeList.h:341
NAME_OK
@ NAME_OK
Definition: NodeList.h:33
Node::initRateFilter
void initRateFilter()
Starts smoothing filter.
Definition: NodeList.cpp:66
WAIT_FOR_SERVER_HELLO
@ WAIT_FOR_SERVER_HELLO
Definition: NodeList.h:26
mac2str
char * mac2str(const uint8_t *mac, char *buffer)
Debug helper function that generates a string that represent a MAC address.
Definition: helperFunctions.cpp:84
Node::reset
void reset()
Resets all node fields to a default initial and not registered state.
Definition: NodeList.cpp:104
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:338
Node::packetsHour
double packetsHour
Packet rate ffor a specific nope.
Definition: NodeList.h:332
NodeList::getNextActiveNode
Node * getNextActiveNode(uint16_t nodeId)
Gets next active node by nodeId.
Definition: NodeList.cpp:257
NUM_NODES
static const int NUM_NODES
Maximum number of nodes that this gateway can handle.
Definition: EnigmaIoTconfig.h:30
FilterClass
Definition: Filter.h:30
node_instance
Struct that define node fields. Used for long term storage needs.
Definition: NodeList.h:76
Node::key
uint8_t key[KEY_LENGTH]
Shared key.
Definition: NodeList.h:345
WAIT_FOR_DOWNLINK
@ WAIT_FOR_DOWNLINK
Definition: NodeList.h:27
node_instance::status
status_t status
Node state.
Definition: NodeList.h:83
Node::mac
uint8_t mac[ENIGMAIOT_ADDR_LEN]
Node address.
Definition: NodeList.h:344
Node::getNodeName
char * getNodeName()
Gets Node name.
Definition: NodeList.h:136
Node::rateFilter
FilterClass * rateFilter
Filter for message rate smoothing.
Definition: NodeList.h:347
node_instance::keyValidFrom
time_t keyValidFrom
Last time that Node and Gateway agreed a key.
Definition: NodeList.h:81
Node::updatePacketsRate
void updatePacketsRate(float value)
Adds a new message rate value for filter calculation.
Definition: NodeList.cpp:99
Node
Class definition for a single sensor Node.
Definition: NodeList.h:93
NodeList::checkNodeName
int8_t checkNodeName(const char *name, const uint8_t *address)
Check Node name for duplicate.
Definition: NodeList.cpp:163
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:26
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:131
Node::Node
Node()
Plain constructor.
Definition: NodeList.cpp:77
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:31
REGISTERED
@ REGISTERED
Definition: NodeList.h:28
node_instance::mac
uint8_t mac[ENIGMAIOT_ADDR_LEN]
Node address.
Definition: NodeList.h:77
helperFunctions.h
Auxiliary function definition.
NodeList::getNodeFromID
Node * getNodeFromID(uint16_t nodeId)
Gets node that correspond with given nodeId.
Definition: NodeList.cpp:126
Node::nodeName
char nodeName[NODE_NAME_LENGTH]
Node name. Use as a human friendly name to avoid use of numeric address*‍/.
Definition: NodeList.h:348
NodeList::countActiveNodes
uint16_t countActiveNodes()
Gets the number of active nodes (registered or registering)
Definition: NodeList.cpp:209
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: EnigmaIoTconfig.h:58
status
@ status
Definition: GwOutput_generic.h:25
AVERAGE_FILTER
@ AVERAGE_FILTER
Definition: Filter.h:26