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
--- 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;