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
EnigmaIOTGatewayDummy.cpp
Go to the documentation of this file.
1 
10 #include <Arduino.h>
11 
12 #include <GwOutput_generic.h>
13 #include "GwOutput_dummy.h"
14 
15 #ifdef ESP32
16 #include <WiFi.h>
17 #include <AsyncTCP.h> // Comment to compile for ESP8266
18 #include <Update.h>
19 #include <SPIFFS.h>
20 #include "esp_system.h"
21 #include "esp_event.h"
22 #include "esp_tls.h"
23 #include "soc/soc.h" // Disable brownout problems
24 #include "soc/rtc_cntl_reg.h" // Disable brownout problems
25 #elif defined(ESP8266)
26 #include <ESP8266WiFi.h>
27 #include <ESPAsyncTCP.h> // Comment to compile for ESP32
28 #include <Hash.h>
29 #include <SPI.h>
30 #endif // ESP32
31 
32 
33 #include <CayenneLPP.h>
34 #include <FS.h>
35 
36 #include <EnigmaIOTGateway.h>
37 #include <helperFunctions.h>
38 #include <EnigmaIOTdebug.h>
39 #include <espnow_hal.h>
40 #include <Curve25519.h>
41 #include <ChaChaPoly.h>
42 #include <Poly1305.h>
43 #include <SHA256.h>
44 #include <ArduinoJson.h>
45 #include <DNSServer.h>
46 #include <ESPAsyncWebServer.h>
47 #include <ESPAsyncWiFiManager.h>
48 
49 #ifndef BUILTIN_LED
50 #define BUILTIN_LED 5
51 #endif // BUILTIN_LED
52 
53 #define BLUE_LED BUILTIN_LED
54 #define RED_LED BUILTIN_LED
55 
56 #ifdef ESP32
57 TimerHandle_t connectionLedTimer;
58 #elif defined(ESP8266)
59 ETSTimer connectionLedTimer;
60 #endif // ESP32
61 
63 boolean connectionLedFlashing = false;
64 
65 void flashConnectionLed (void* led) {
66  //digitalWrite (*(int*)led, !digitalRead (*(int*)led));
67  digitalWrite (BUILTIN_LED, !digitalRead (BUILTIN_LED));
68 }
69 
70 void startConnectionFlash (int period) {
71 #ifdef ESP32
72  if (!connectionLedFlashing) {
73  connectionLedFlashing = true;
74  connectionLedTimer = xTimerCreate ("led_flash", pdMS_TO_TICKS (period), pdTRUE, (void*)0, flashConnectionLed);
75  xTimerStart (connectionLedTimer, 0);
76  }
77 #elif defined (ESP8266)
78  ets_timer_disarm (&connectionLedTimer);
79  if (!connectionLedFlashing) {
80  connectionLedFlashing = true;
81  ets_timer_arm_new (&connectionLedTimer, period, true, true);
82  }
83 #endif // ESP32
84 }
85 
87 #ifdef ESP32
89  connectionLedFlashing = false;
90  xTimerStop (connectionLedTimer, 0);
91  xTimerDelete (connectionLedTimer, 0);
92  }
93 #elif defined(ESP8266)
95  connectionLedFlashing = false;
96  ets_timer_disarm (&connectionLedTimer);
97  digitalWrite (connectionLed, HIGH);
98  }
99 #endif // ESP32
100 }
101 
102 void wifiManagerExit (boolean status) {
104 }
105 
108 }
109 
110 void processRxControlData (char* macStr, uint8_t* data, uint8_t length) {
111  if (data) {
112  GwOutput.outputControlSend (macStr, data, length);
113  }
114 }
115 
116 void processRxData (uint8_t* mac, uint8_t* buffer, uint8_t length, uint16_t lostMessages, bool control, gatewayPayloadEncoding_t payload_type, char* nodeName = NULL) {
117  //uint8_t *addr = mac;
118  size_t pld_size;
119  const int PAYLOAD_SIZE = 512;
120  char payload[PAYLOAD_SIZE];
121 
122  //payload = (char*)malloc (PAYLOAD_SIZE);
123 
124  char mac_str[ENIGMAIOT_ADDR_LEN * 3];
125  mac2str (mac, mac_str);
126  if (control) {
127  processRxControlData (nodeName ? nodeName : mac_str, buffer, length);
128  return;
129  }
130  //char* netName = EnigmaIOTGateway.getNetworkName ();
131  if (payload_type == CAYENNELPP) {
132  const int capacity = JSON_ARRAY_SIZE (25) + 25 * JSON_OBJECT_SIZE (4);
133  DynamicJsonDocument jsonBuffer (capacity);
134  JsonArray root = jsonBuffer.createNestedArray ();
135  CayenneLPP cayennelpp (MAX_DATA_PAYLOAD_SIZE);
136 
137  cayennelpp.decode ((uint8_t*)buffer, length, root);
138  uint8_t error = cayennelpp.getError ();
139  if (error != LPP_ERROR_OK) {
140  DEBUG_ERROR ("Error decoding CayenneLPP data: %d", error);
141  return;
142  }
143  pld_size = serializeJson (root, payload, PAYLOAD_SIZE);
144  } else if (payload_type == MSG_PACK) {
145  const int capacity = JSON_ARRAY_SIZE (25) + 25 * JSON_OBJECT_SIZE (4);
146  DynamicJsonDocument jsonBuffer (capacity);
147  DeserializationError error = deserializeMsgPack (jsonBuffer, buffer, length);
148  if (error != DeserializationError::Ok) {
149  DEBUG_ERROR ("Error decoding MSG Pack data: %s", error.c_str ());
150  return;
151  }
152  pld_size = serializeJson (jsonBuffer, payload, PAYLOAD_SIZE);
153  } else if (payload_type == RAW) {
154  if (length <= PAYLOAD_SIZE) {
155  memcpy (payload, buffer, length);
156  pld_size = length;
157  } else { // This will not happen but may lead to errors in case of using another physical transport
158  memcpy (payload, buffer, PAYLOAD_SIZE);
159  pld_size = PAYLOAD_SIZE;
160  }
161  }
162 
163  GwOutput.outputDataSend (mac_str, payload, pld_size);
164  DEBUG_INFO ("Published data message from %s: %s", mac_str, payload);
165  if (lostMessages > 0) {
166  pld_size = snprintf (payload, PAYLOAD_SIZE, "%u", lostMessages);
167  GwOutput.outputDataSend (mac_str, payload, pld_size, GwOutput_data_type::lostmessages);
168  //DEBUG_INFO ("Published MQTT from %s: %s", mac_str, payload);
169  }
170  pld_size = snprintf (payload, PAYLOAD_SIZE, "{\"per\":%e,\"lostmessages\":%u,\"totalmessages\":%u,\"packetshour\":%.2f}",
171  EnigmaIOTGateway.getPER ((uint8_t*)mac),
172  EnigmaIOTGateway.getErrorPackets ((uint8_t*)mac),
173  EnigmaIOTGateway.getTotalPackets ((uint8_t*)mac),
174  EnigmaIOTGateway.getPacketsHour ((uint8_t*)mac));
175  GwOutput.outputDataSend (mac_str, payload, pld_size, GwOutput_data_type::status);
176  //DEBUG_INFO ("Published MQTT from %s: %s", mac_str, payload);
177  //free (payload);
178 }
179 
180 void onDownlinkData (uint8_t* address, char* nodeName, control_message_type_t msgType, char* data, unsigned int len) {
181  //char* buffer;
182  char buffer[1024];
183  unsigned int bufferLen = len;
184 
185  if (nodeName) {
186  DEBUG_INFO ("DL Message for %s. Type 0x%02X", nodeName, msgType);
187  } else {
188  DEBUG_INFO ("DL Message for " MACSTR ". Type 0x%02X", MAC2STR (address), msgType);
189  }
190  DEBUG_DBG ("Data: %.*s", len, data);
191 
192  //buffer = (char*)malloc (len + 1);
193  sprintf (buffer, "%.*s", len, data);
194  bufferLen++;
195 
196  if (!EnigmaIOTGateway.sendDownstream (address, (uint8_t*)buffer, bufferLen, msgType)) {
197  DEBUG_ERROR ("Error sending esp_now message to " MACSTR, MAC2STR (address));
198  } else {
199  DEBUG_DBG ("Esp-now message sent or queued correctly");
200  }
201 
202  //free (buffer);
203 }
204 
205 void newNodeConnected (uint8_t* mac, uint16_t node_id, char* nodeName = NULL) {
206  if (nodeName) {
207  if (!GwOutput.newNodeSend (nodeName, node_id)) {
208  DEBUG_WARN ("Error sending new node %s", nodeName);
209  } else {
210  DEBUG_DBG ("New node %s message sent", nodeName);
211  }
212  } else {
213  char macstr[ENIGMAIOT_ADDR_LEN * 3];
214  mac2str (mac, macstr);
215  if (!GwOutput.newNodeSend (macstr, node_id)) {
216  DEBUG_WARN ("Error sending new node %s", macstr);
217  } else {
218  DEBUG_DBG ("New node %s message sent", macstr);
219  }
220  }
221 
222 }
223 
224 void nodeDisconnected (uint8_t* mac, gwInvalidateReason_t reason) {
225  char macstr[ENIGMAIOT_ADDR_LEN * 3];
226  mac2str (mac, macstr);
227  //Serial.printf ("Node %s disconnected. Reason %u\n", macstr, reason);
228  if (!GwOutput.nodeDisconnectedSend (macstr, reason)) {
229  DEBUG_WARN ("Error sending node disconnected %s reason %d", macstr, reason);
230  } else {
231  DEBUG_DBG ("Node %s disconnected message sent. Reason %d", macstr, reason);
232  }
233 }
234 
235 #ifdef ESP32
236 // void EnigmaIOTGateway_handle (void* param) {
237 // for (;;) {
238 // EnigmaIOTGateway.handle ();
239 // vTaskDelay (0);
240 // }
241 // }
242 
243 // void GwOutput_handle (void* param) {
244 // for (;;) {
245 // GwOutput.loop ();
246 // vTaskDelay (0);
247 // }
248 // }
249 
250 TaskHandle_t xEnigmaIOTGateway_handle = NULL;
251 TaskHandle_t gwoutput_handle = NULL;
252 #endif // ESP32
253 
254 void setup () {
255  Serial.begin (115200); Serial.println (); Serial.println ();
256 
257 #ifdef ESP32
258  // Turn-off the 'brownout detector' to avoid random restarts during wake up,
259  // normally due to bad quality regulator on board
260  WRITE_PERI_REG (RTC_CNTL_BROWN_OUT_REG, 0);
261 #endif
262 
263 #ifdef ESP8266
264  ets_timer_setfn (&connectionLedTimer, flashConnectionLed, (void*)&connectionLed);
265 #elif defined ESP32
266 
267 #endif
268  pinMode (BUILTIN_LED, OUTPUT);
269  digitalWrite (BUILTIN_LED, HIGH);
270  startConnectionFlash (100);
271 
272 
273  if (!GwOutput.loadConfig ()) {
274  DEBUG_WARN ("Error reading config file");
275  }
276 
285 
286 #if CONNECT_TO_WIFI_AP == 1
287  WiFi.mode (WIFI_AP_STA);
288  WiFi.begin ();
290 #else
291  //WiFi.mode (WIFI_AP);
292 #endif // CONNECT_TO_WIFI_AP
293 
294 
297 
298  DEBUG_INFO ("STA MAC Address: %s", WiFi.macAddress ().c_str ());
299  DEBUG_INFO ("AP MAC Address: %s", WiFi.softAPmacAddress ().c_str ());
300  DEBUG_INFO ("BSSID Address: %s", WiFi.BSSIDstr ().c_str ());
301 
302  DEBUG_INFO ("IP address: %s", WiFi.localIP ().toString ().c_str ());
303  DEBUG_INFO ("AP IP address: %s", WiFi.softAPIP ().toString ().c_str ());
304  DEBUG_INFO ("WiFi Channel: %d", WiFi.channel ());
305 
306  DEBUG_INFO ("WiFi SSID: %s", WiFi.SSID ().c_str ());
307  DEBUG_INFO ("Network Name: %s", EnigmaIOTGateway.getNetworkName ());
308 
310  GwOutput.begin ();
311 
312 #ifdef ESP32
313  //xTaskCreate (EnigmaIOTGateway_handle, "handle", 10000, NULL, 1, &xEnigmaIOTGateway_handle);
314  //xTaskCreatePinnedToCore (EnigmaIOTGateway_handle, "handle", 4096, NULL, 0, &xEnigmaIOTGateway_handle, 1);
315  //xTaskCreatePinnedToCore (GwOutput_handle, "gwoutput", 10000, NULL, 2, &gwoutput_handle, 1);
316 #endif
317 }
318 
319 void loop () {
320 
321  GwOutput.loop ();
323 
324 }
EnigmaIOTGatewayClass::onWiFiManagerExit
void onWiFiManagerExit(onWiFiManagerExit_t handle)
Register callback to be called on wifi manager exit.
Definition: EnigmaIOTGateway.h:378
GatewayOutput_dummy::loadConfig
bool loadConfig()
Loads output module configuration.
Definition: GwOutput_dummy.cpp:39
loop
void loop()
Definition: EnigmaIOTGatewayDummy.cpp:319
ENIGMAIOT_ADDR_LEN
static const size_t ENIGMAIOT_ADDR_LEN
Address size. Mac address = 6 bytes.
Definition: EnigmaIoTconfigAdvanced.h:23
EnigmaIOTGatewayClass::onNodeDisconnected
void onNodeDisconnected(onNodeDisconnected_t handler)
Defines a function callback that will be called every time a node is disconnected.
Definition: EnigmaIOTGateway.h:557
GatewayOutput_dummy::configManagerStart
void configManagerStart(EnigmaIOTGatewayClass *enigmaIotGw)
Called when wifi manager starts config portal.
Definition: GwOutput_dummy.cpp:31
EnigmaIOTGatewayClass::onDataRx
void onDataRx(onGwDataRx_t handler)
Defines a function callback that will be called on every downlink data message that is received from ...
Definition: EnigmaIOTGateway.h:449
connectionLed
const int connectionLed
Definition: EnigmaIOTGatewayDummy.cpp:62
GwOutput_generic.h
Generic Gateway output module template.
MAX_DATA_PAYLOAD_SIZE
static const int MAX_DATA_PAYLOAD_SIZE
Maximun payload size for data packets.
Definition: EnigmaIoTconfigAdvanced.h:48
GatewayOutput_dummy::nodeDisconnectedSend
bool nodeDisconnectedSend(char *address, gwInvalidateReason_t reason)
Send node disconnection notification.
Definition: GwOutput_dummy.cpp:72
EnigmaIOTGatewayClass::configWiFiManager
bool configWiFiManager()
Starts configuration AP and web server and gets settings from it.
Definition: EnigmaIOTGateway.cpp:494
RAW
@ RAW
Definition: EnigmaIOTGateway.h:62
EnigmaIOTGatewayClass::getNetworkName
char * getNetworkName()
Gets EnigmaIOT network name.
Definition: EnigmaIOTGateway.h:349
GwOutput
GatewayOutput_dummy GwOutput
Definition: GwOutput_dummy.cpp:29
GatewayOutput_dummy::begin
bool begin()
Starts output module.
Definition: GwOutput_dummy.cpp:47
wifiManagerExit
void wifiManagerExit(boolean status)
Definition: EnigmaIOTGatewayDummy.cpp:102
nodeDisconnected
void nodeDisconnected(uint8_t *mac, gwInvalidateReason_t reason)
Definition: EnigmaIOTGatewayDummy.cpp:224
EnigmaIOTGatewayClass::setRxLed
void setRxLed(uint8_t led, time_t onTime=FLASH_LED_TIME)
Sets a LED to be flashed every time a message is received.
Definition: EnigmaIOTGateway.cpp:66
EnigmaIOTGatewayClass::handle
void handle()
This method should be called periodically for instance inside loop() function. It is used for interna...
Definition: EnigmaIOTGateway.cpp:867
EnigmaIOTGatewayClass::setTxLed
void setTxLed(uint8_t led, time_t onTime=FLASH_LED_TIME)
Sets a LED to be flashed every time a message is transmitted.
Definition: EnigmaIOTGateway.cpp:59
wifiManagerStarted
void wifiManagerStarted()
Definition: EnigmaIOTGatewayDummy.cpp:106
GatewayOutput_dummy::loop
void loop()
Should be called often for module management.
Definition: GwOutput_dummy.cpp:53
connectionLedFlashing
boolean connectionLedFlashing
Definition: EnigmaIOTGatewayDummy.cpp:63
onDownlinkData
void onDownlinkData(uint8_t *address, char *nodeName, control_message_type_t msgType, char *data, unsigned int len)
Definition: EnigmaIOTGatewayDummy.cpp:180
gatewayPayloadEncoding_t
gatewayPayloadEncoding_t
Definition: EnigmaIOTGateway.h:61
EnigmaIOTGatewayClass::getTotalPackets
uint32_t getTotalPackets(uint8_t *address)
Gets total packets sent by node that has a specific address.
Definition: EnigmaIOTGateway.cpp:1470
EnigmaIOTGatewayClass::onNewNode
void onNewNode(onNewNode_t handler)
Defines a function callback that will be called every time a node gets connected or reconnected.
Definition: EnigmaIOTGateway.h:528
EnigmaIOTGateway
EnigmaIOTGatewayClass EnigmaIOTGateway
Definition: EnigmaIOTGateway.cpp:2050
GatewayOutput_dummy::newNodeSend
bool newNodeSend(char *address, uint16_t node_id)
Send new node notification.
Definition: GwOutput_dummy.cpp:67
processRxData
void processRxData(uint8_t *mac, uint8_t *buffer, uint8_t length, uint16_t lostMessages, bool control, gatewayPayloadEncoding_t payload_type, char *nodeName=NULL)
Definition: EnigmaIOTGatewayDummy.cpp:116
EnigmaIOTGatewayClass::onWiFiManagerStarted
void onWiFiManagerStarted(simpleEventHandler_t handle)
Register callback to be called on wifi manager start.
Definition: EnigmaIOTGateway.h:386
MSG_PACK
@ MSG_PACK
Definition: EnigmaIOTGateway.h:65
MACSTR
#define MACSTR
Definition: helperFunctions.cpp:83
GatewayOutput_dummy::outputControlSend
bool outputControlSend(char *address, uint8_t *data, size_t length)
Send control data from nodes.
Definition: GwOutput_dummy.cpp:62
GatewayOutput_dummy::configManagerExit
void configManagerExit(bool status)
Called when wifi manager exits config portal.
Definition: GwOutput_dummy.cpp:43
RED_LED
#define RED_LED
Definition: EnigmaIOTGatewayDummy.cpp:54
newNodeConnected
void newNodeConnected(uint8_t *mac, uint16_t node_id, char *nodeName=NULL)
Definition: EnigmaIOTGatewayDummy.cpp:205
BUILTIN_LED
#define BUILTIN_LED
Definition: EnigmaIOTGatewayDummy.cpp:50
data
@ data
Definition: GwOutput_generic.h:23
Espnow_hal
Espnow_halClass Espnow_hal
Singleton instance of ESP-NOW class.
Definition: espnow_hal.cpp:20
EnigmaIOTGatewayClass::sendDownstream
bool sendDownstream(uint8_t *mac, const uint8_t *data, size_t len, control_message_type_t controlData, gatewayPayloadEncoding_t payload_type=RAW, char *nodeName=NULL)
Starts a downstream data message transmission.
Definition: EnigmaIOTGateway.cpp:364
EnigmaIOTGatewayClass::getErrorPackets
uint32_t getErrorPackets(uint8_t *address)
Gets number of errored packets of node that has a specific address.
Definition: EnigmaIOTGateway.cpp:1476
lostmessages
@ lostmessages
Definition: GwOutput_generic.h:24
setup
void setup()
Definition: EnigmaIOTGatewayDummy.cpp:254
EnigmaIOTGatewayClass::getPacketsHour
double getPacketsHour(uint8_t *address)
Gets packet rate sent by node that has a specific address, in packets per hour.
Definition: EnigmaIOTGateway.cpp:1482
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.
GatewayOutput_dummy::outputDataSend
bool outputDataSend(char *address, char *data, size_t length, GwOutput_data_type_t type=data)
Send data from nodes.
Definition: GwOutput_dummy.cpp:57
EnigmaIOTGateway.h
Library to build a gateway for EnigmaIoT system.
gwInvalidateReason_t
gwInvalidateReason_t
Key invalidation reason definition.
Definition: EnigmaIOTGateway.h:75
EnigmaIOTdebug.h
Auxiliary functions for debugging over Serial.
control_message_type_t
enum control_message_type control_message_type_t
flashConnectionLed
void flashConnectionLed(void *led)
Definition: EnigmaIOTGatewayDummy.cpp:65
EnigmaIOTGatewayClass::getPER
double getPER(uint8_t *address)
Gets packet error rate of node that has a specific address.
Definition: EnigmaIOTGateway.cpp:1460
CAYENNELPP
@ CAYENNELPP
Definition: EnigmaIOTGateway.h:63
stopConnectionFlash
void stopConnectionFlash()
Definition: EnigmaIOTGatewayDummy.cpp:86
EnigmaIOTGatewayClass::getNetworkKey
char * getNetworkKey(bool plain=false)
Gets hashed EnigmaIOT network key.
Definition: EnigmaIOTGateway.h:357
EnigmaIOTGatewayClass::begin
void begin(Comms_halClass *comm, uint8_t *networkKey=NULL, bool useDataCounter=true)
Initalizes communication basic data and starts accepting node registration.
Definition: EnigmaIOTGateway.cpp:736
espnow_hal.h
ESP-NOW communication system abstraction layer. To be used on ESP8266 or ESP32 platforms.
processRxControlData
void processRxControlData(char *macStr, uint8_t *data, uint8_t length)
Definition: EnigmaIOTGatewayDummy.cpp:110
status
@ status
Definition: GwOutput_generic.h:25
GwOutput_dummy.h
Dummy Gateway output module.
BLUE_LED
#define BLUE_LED
Definition: EnigmaIOTGatewayDummy.cpp:53
startConnectionFlash
void startConnectionFlash(int period)
Definition: EnigmaIOTGatewayDummy.cpp:70
GatewayOutput_dummy::setDlCallback
void setDlCallback(onDlData_t cb)
Set data processing function.
Definition: GwOutput_dummy.h:108