MAXREFDES143#: DeepCover Embedded Security in IoT Authenticated Sensing & Notification
Dependencies: MaximInterface mbed
The MAXREFDES143# is an Internet of Things (IoT) embedded security reference design, built to protect an industrial sensing node by means of authentication and notification to a web server. The hardware includes a peripheral module representing a protected sensor node monitoring operating temperature and remaining life of a filter (simulated through ambient light sensing) and an mbed shield representing a controller node responsible for monitoring one or more sensor nodes. The design is hierarchical with each controller node communicating data from connected sensor nodes to a web server that maintains a centralized log and dispatches notifications as necessary. The mbed shield contains a Wi-Fi module, a DS2465 coprocessor with 1-Wire® master function, an LCD, LEDs, and pushbuttons. The protected sensor node contains a DS28E15 authenticator, a DS7505 temperature sensor, and a MAX44009 light sensor. The mbed shield communicates to a web server by the onboard Wi-Fi module and to the protected sensor node with I2C and 1-Wire. The MAXREFDES143# is equipped with a standard shield connector for immediate testing using an mbed board such as the MAX32600MBED#. The simplicity of this design enables rapid integration into any star-topology IoT network requiring the heightened security with low overhead provided by the SHA-256 symmetric-key algorithm.
More information about the MAXREFDES143# is available on the Maxim Integrated website.
Diff: ESP8266.cpp
- Revision:
- 32:0a09505a656d
- Parent:
- 30:0784010d6975
diff -r 7b10bcb3e0fc -r 0a09505a656d ESP8266.cpp
--- a/ESP8266.cpp Tue Apr 04 14:10:48 2017 -0500
+++ b/ESP8266.cpp Mon Nov 06 17:34:13 2017 -0600
@@ -28,30 +28,25 @@
* trademarks, maskwork rights, or any other form of intellectual
* property whatsoever. Maxim Integrated Products, Inc. retains all
* ownership rights.
-*******************************************************************************
-*/
+*******************************************************************************/
#include <cstdlib>
+#include <Timer.h>
+#include <wait_api.h>
#include "ESP8266.hpp"
-#include "Timer.h"
-#include "wait_api.h"
-static inline void disableRecvData()
-{
- __disable_irq();
-}
+static inline void disableRecvData() { __disable_irq(); }
-static inline void enableRecvData()
-{
- __enable_irq();
-}
+static inline void enableRecvData() { __enable_irq(); }
-ESP8266::ESP8266(const PinName tx, const PinName rx, const PinName rst, const PinName CH_PD, const int baud, mbed::Serial * debugMsgIntf)
- : AT_intf(tx, rx), resetPin(rst), powerDownPin(CH_PD), debugMsg(debugMsgIntf), parseRecvReset(false)
-{
+ESP8266::ESP8266(const PinName tx, const PinName rx, const PinName rst,
+ const PinName CH_PD, const int baud,
+ mbed::Serial * debugMsgIntf)
+ : AT_intf(tx, rx), resetPin(rst), powerDownPin(CH_PD),
+ debugMsg(debugMsgIntf), parseRecvReset(false) {
AT_intf.baud(baud);
AT_intf.attach(this, &ESP8266::recv_AT_data_cb);
-
+
// Ensure that device is not held in reset
if (resetPin.is_connected())
resetPin = 1;
@@ -59,10 +54,8 @@
setPowered(false);
}
-void ESP8266::reset()
-{
- if (resetPin.is_connected())
- {
+void ESP8266::reset() {
+ if (resetPin.is_connected()) {
resetPin = 0;
wait_ms(100);
resetPin = 1;
@@ -70,40 +63,34 @@
}
}
-bool ESP8266::powered() const
-{
+bool ESP8266::powered() const {
bool isPowered;
- if (powerDownPin.is_connected())
- {
+ if (powerDownPin.is_connected()) {
isPowered = powerDownPin.read();
- }
- else
- {
+ } else {
isPowered = false;
}
return isPowered;
}
-void ESP8266::setPowered(bool powered)
-{
+void ESP8266::setPowered(bool powered) {
if (powerDownPin.is_connected())
powerDownPin = powered;
}
-ESP8266::CmdResult ESP8266::performSelfTest()
-{
+ESP8266::CmdResult ESP8266::performSelfTest() {
return sendCommand(CmdBuilder(""));
}
-ESP8266::CmdResult ESP8266::setCurrentWifiMode(const ESP8266::WifiMode mode)
-{
+ESP8266::CmdResult ESP8266::setCurrentWifiMode(const ESP8266::WifiMode mode) {
CmdBuilder builder("CWMODE_CUR");
builder.addRawArgument(mode);
return sendCommand(builder);
}
-ESP8266::CmdResult ESP8266::joinCurrentAccessPoint(const std::string & ssid, const std::string & pwd, const std::string & bssid)
-{
+ESP8266::CmdResult ESP8266::joinCurrentAccessPoint(const std::string & ssid,
+ const std::string & pwd,
+ const std::string & bssid) {
CmdBuilder builder("CWJAP_CUR");
builder.addStringArgument(ssid);
builder.addStringArgument(pwd);
@@ -112,33 +99,31 @@
return sendCommand(builder);
}
-ESP8266::CmdResult ESP8266::quitAccessPoint()
-{
+ESP8266::CmdResult ESP8266::quitAccessPoint() {
return sendCommand(CmdBuilder("CWQAP"));
}
-ESP8266::CmdResult ESP8266::setMaxRFTXPower(const float power_dBm)
-{
+ESP8266::CmdResult ESP8266::setMaxRFTXPower(const float power_dBm) {
int power_arg = (int)(power_dBm * 4);
if (power_arg > 82)
power_arg = 82;
else if (power_arg < 0)
power_arg = 0;
-
+
CmdBuilder builder("RFPOWER");
builder.addRawArgument(power_arg);
return sendCommand(builder);
}
-ESP8266::CmdResult ESP8266::ping(const std::string & IP)
-{
+ESP8266::CmdResult ESP8266::ping(const std::string & IP) {
CmdBuilder builder("PING");
builder.addStringArgument(IP);
return sendCommand(builder);
}
-ESP8266::CmdResult ESP8266::openConnection(const ESP8266::ConnType type, const std::string & remoteIP, const unsigned int remotePort)
-{
+ESP8266::CmdResult ESP8266::openConnection(const ESP8266::ConnType type,
+ const std::string & remoteIP,
+ const unsigned int remotePort) {
CmdBuilder builder("CIPSTART");
builder.addStringArgument((type == TCP) ? "TCP" : "UDP");
builder.addStringArgument(remoteIP);
@@ -146,13 +131,11 @@
return sendCommand(builder);
}
-ESP8266::CmdResult ESP8266::closeConnection()
-{
+ESP8266::CmdResult ESP8266::closeConnection() {
return sendCommand(CmdBuilder("CIPCLOSE"));
}
-ESP8266::CmdResult ESP8266::sendData(const std::string & data)
-{
+ESP8266::CmdResult ESP8266::sendData(const std::string & data) {
CmdBuilder builder("CIPSEND");
builder.addRawArgument(data.length());
ESP8266::CmdResult result = sendCommand(builder);
@@ -161,105 +144,94 @@
return result;
}
-ESP8266::CmdResult ESP8266::sendCommand(const CmdBuilder & cmd)
-{
+ESP8266::CmdResult ESP8266::sendCommand(const CmdBuilder & cmd) {
return send_AT_data(cmd.str(), true);
}
-bool ESP8266::recvIpDataReadable()
-{
+bool ESP8266::recvIpDataReadable() {
bool result;
-
+
disableRecvData(); // Lock queue access
-
+
result = !recvIpDataBuffer.empty();
-
+
enableRecvData(); // Unlock queue access
-
+
return result;
}
-char ESP8266::getcRecvIpData()
-{
+char ESP8266::getcRecvIpData() {
char received;
-
+
disableRecvData(); // Lock queue access
-
+
// Pop next char or set to NTC if not data in buffer
if (!recvIpDataBuffer.pop(received))
received = '\0';
-
+
enableRecvData(); // Unlock queue access
-
+
return received;
}
-void ESP8266::clearRecvData()
-{
- disableRecvData(); // Lock queue access
-
- recvIpDataBuffer.reset();
- parseRecvReset = true;
-
- enableRecvData(); // Unlock queue access
+void ESP8266::clearRecvData() {
+ disableRecvData(); // Lock queue access
+
+ recvIpDataBuffer.reset();
+ parseRecvReset = true;
+
+ enableRecvData(); // Unlock queue access
}
-ESP8266::CmdResult ESP8266::send_AT_data(const std::string & cmdString, const bool expectEcho)
-{
+ESP8266::CmdResult ESP8266::send_AT_data(const std::string & cmdString,
+ const bool expectEcho) {
const int timeout_ms = 10000;
-
+
mbed::Timer timer;
ESP8266::CmdResult result = ESP8266::HardwareError;
std::string response;
-
+
disableRecvData(); // Lock for manual data handling in this procedure
-
+
// Flush receive buffer
while (AT_intf.readable())
AT_intf.getc();
-
+
// Begin counting for timeout
timer.start();
-
- for (size_t i = 0; i < cmdString.length(); i++)
- {
+
+ for (size_t i = 0; i < cmdString.length(); i++) {
// Write next character
- while (!AT_intf.writeable())
- {
- if (timer.read_ms() > timeout_ms)
- {
+ while (!AT_intf.writeable()) {
+ if (timer.read_ms() > timeout_ms) {
result = TimeoutError;
goto exit;
}
}
AT_intf.putc(cmdString[i]);
// Wait for echo
- if (expectEcho && (cmdString[i] != '\r') && (cmdString[i] != '\n'))
- {
- while (!AT_intf.readable())
- {
- if (timer.read_ms() > timeout_ms)
- {
+ if (expectEcho && (cmdString[i] != '\r') && (cmdString[i] != '\n')) {
+ while (!AT_intf.readable()) {
+ if (timer.read_ms() > timeout_ms) {
result = TimeoutError;
goto exit;
}
}
// Compare to written character
- if (AT_intf.getc() != cmdString[i])
- {
+ if (AT_intf.getc() != cmdString[i]) {
// Handle error
result = ESP8266::HardwareError;
goto exit;
}
}
}
-
- while (result == ESP8266::HardwareError)
- {
+
+ while (result == ESP8266::HardwareError) {
// Wait to receive something
response.clear();
- while (!read_line(response)) ;
-
+ while (!read_line(response))
+ ;
+
// Check if valid response
if (response == "OK")
result = ESP8266::AT_OK;
@@ -271,42 +243,34 @@
result = ESP8266::AT_OK;
else if (response == "ALREADY CONNECT") // Used by AT+CIPSTART
result = ESP8266::AT_OK;
-
- if (timer.read_ms() > timeout_ms)
- {
+
+ if (timer.read_ms() > timeout_ms) {
result = TimeoutError;
break;
}
}
-
+
exit:
enableRecvData(); // Enable interrupt processing
return result;
}
-bool ESP8266::read_line(std::string & line)
-{
+bool ESP8266::read_line(std::string & line) {
char received;
-
- while (AT_intf.readable())
- {
+
+ while (AT_intf.readable()) {
received = AT_intf.getc();
- if (received == '\n')
- {
+ if (received == '\n') {
return true;
- }
- else if (received != '\r')
- {
+ } else if (received != '\r') {
line.push_back(received);
}
}
return false;
}
-void ESP8266::recv_AT_data_cb()
-{
- while (AT_intf.readable())
- {
+void ESP8266::recv_AT_data_cb() {
+ while (AT_intf.readable()) {
char received = AT_intf.getc();
parseRecvIpData(received);
parseRecvConnClosedMsg(received);
@@ -314,153 +278,114 @@
}
}
-void ESP8266::parseRecvIpData(const char received)
-{
- enum DataRecvState
- {
- Header,
- Length,
- Data,
- Reset
- };
-
+void ESP8266::parseRecvIpData(const char received) {
+ enum DataRecvState { Header, Length, Data, Reset };
+
static const char findChars[] = "+IPD,";
static const size_t maxSizeDigits = 4;
-
+
static size_t dataFinishedSize = 0;
static size_t index = 0;
- static char sizeDigits[] = { '\0', '\0', '\0', '\0', '\0' };
+ static char sizeDigits[] = {'\0', '\0', '\0', '\0', '\0'};
static DataRecvState state = Header;
-
+
if (parseRecvReset)
state = Reset;
-
- switch (state)
- {
+
+ switch (state) {
case Reset:
default:
index = 0;
dataFinishedSize = 0;
state = Header;
// Continue processing switch
-
+
case Header:
- if (received == findChars[index])
- {
- if (findChars[++index] == '\0')
- {
+ if (received == findChars[index]) {
+ if (findChars[++index] == '\0') {
index = 0;
state = Length;
}
- }
- else
- {
+ } else {
state = Reset;
}
break;
-
- case Length:
- if ((received <= '9') && (received >= '0'))
- {
- if (index < maxSizeDigits)
- {
+
+ case Length:
+ if ((received <= '9') && (received >= '0')) {
+ if (index < maxSizeDigits) {
sizeDigits[index++] = received;
- }
- else
- {
+ } else {
state = Reset;
}
- }
- else if (received == ':')
- {
+ } else if (received == ':') {
dataFinishedSize = std::atoi(sizeDigits);
- if (dataFinishedSize == 0)
- {
+ if (dataFinishedSize == 0) {
state = Reset;
- }
- else
- {
+ } else {
index = 0;
state = Data;
}
- }
- else
- {
+ } else {
state = Reset;
}
break;
-
+
case Data:
- if (index < dataFinishedSize)
- {
+ if (index < dataFinishedSize) {
recvIpDataBuffer.push(received);
index++;
- }
- else
- {
+ } else {
state = Reset;
}
break;
};
}
-void ESP8266::parseRecvConnClosedMsg(const char received)
-{
+void ESP8266::parseRecvConnClosedMsg(const char received) {
static const char findChars[] = "CLOSED";
-
+
static int index = 0;
-
+
bool shouldReset = parseRecvReset;
-
- if (received == findChars[index])
- {
- if (findChars[++index] == '\0')
- {
+
+ if (received == findChars[index]) {
+ if (findChars[++index] == '\0') {
printDbgMsg(findChars);
shouldReset = true;
}
- }
- else
- {
+ } else {
shouldReset = true;
}
-
- if (shouldReset)
- {
+
+ if (shouldReset) {
index = 0;
}
}
-void ESP8266::printDbgMsg(const char * message)
-{
+void ESP8266::printDbgMsg(const char * message) {
if (debugMsg != NULL)
debugMsg->printf("%s", message);
}
-ESP8266::CmdBuilder::CmdBuilder(const std::string & cmd)
-{
- clear(cmd);
-}
+ESP8266::CmdBuilder::CmdBuilder(const std::string & cmd) { clear(cmd); }
-void ESP8266::CmdBuilder::clear(const std::string & cmd)
-{
+void ESP8266::CmdBuilder::clear(const std::string & cmd) {
numArgs = 0;
cmdStream.str("");
-
+
cmdStream << "AT";
if (cmd != "")
cmdStream << "+" << cmd;
}
-void ESP8266::CmdBuilder::addStringArgument(const std::string & arg)
-{
+void ESP8266::CmdBuilder::addStringArgument(const std::string & arg) {
std::ostringstream argStream;
argStream << "\"" << arg << "\"";
addRawArgument<std::string>(argStream.str());
}
-std::string ESP8266::CmdBuilder::str() const
-{
+std::string ESP8266::CmdBuilder::str() const {
std::string cmdString = cmdStream.str();
cmdString.append("\r\n");
return cmdString;
MAXREFDES143#: DeepCover Embedded Security in IoT Authenticated Sensing & Notification