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:
- 28:e5cdaf13d299
- Parent:
- 27:81a87d29bedd
- Child:
- 29:590a7561318b
--- a/ESP8266.cpp Fri Dec 16 20:14:05 2016 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,489 +0,0 @@
-/*******************************************************************************
-* Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved.
-*
-* Permission is hereby granted, free of charge, to any person obtaining a
-* copy of this software and associated documentation files (the "Software"),
-* to deal in the Software without restriction, including without limitation
-* the rights to use, copy, modify, merge, publish, distribute, sublicense,
-* and/or sell copies of the Software, and to permit persons to whom the
-* Software is furnished to do so, subject to the following conditions:
-*
-* The above copyright notice and this permission notice shall be included
-* in all copies or substantial portions of the Software.
-*
-* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
-* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-* OTHER DEALINGS IN THE SOFTWARE.
-*
-* Except as contained in this notice, the name of Maxim Integrated
-* Products, Inc. shall not be used except as stated in the Maxim Integrated
-* Products, Inc. Branding Policy.
-*
-* The mere transfer of this software does not imply any licenses
-* of trade secrets, proprietary technology, copyrights, patents,
-* trademarks, maskwork rights, or any other form of intellectual
-* property whatsoever. Maxim Integrated Products, Inc. retains all
-* ownership rights.
-*******************************************************************************
-*/
-
-#include <cstdlib>
-#include "ESP8266.hpp"
-#include "Timer.h"
-#include "wait_api.h"
-
-ESP8266* ESP8266::defaultInstance = NULL;
-
-static inline void disableRecvData()
-{
- __disable_irq();
-}
-
-static inline void enableRecvData()
-{
- __enable_irq();
-}
-
-void ESP8266::setDefaultInstance(ESP8266 * const instance)
-{
- if (instance != NULL)
- defaultInstance = instance;
-}
-
-ESP8266** ESP8266::getDefaultInstance()
-{
- return &defaultInstance;
-}
-
-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;
- // Power down device at startup due to high current demand
- setPowered(false);
-
- if (defaultInstance == NULL)
- defaultInstance = this;
-}
-
-ESP8266::~ESP8266()
-{
- if (defaultInstance == this)
- defaultInstance = NULL;
-}
-
-void ESP8266::reset()
-{
- if (resetPin.is_connected())
- {
- resetPin = 0;
- wait_ms(100);
- resetPin = 1;
- wait_ms(1000);
- }
-}
-
-bool ESP8266::powered() const
-{
- bool isPowered;
- if (powerDownPin.is_connected())
- {
- isPowered = powerDownPin.read();
- }
- else
- {
- isPowered = false;
- }
- return isPowered;
-}
-
-void ESP8266::setPowered(bool powered)
-{
- if (powerDownPin.is_connected())
- powerDownPin = powered;
-}
-
-ESP8266::CmdResult ESP8266::performSelfTest()
-{
- return sendCommand(CmdBuilder(""));
-}
-
-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)
-{
- CmdBuilder builder("CWJAP_CUR");
- builder.addStringArgument(ssid);
- builder.addStringArgument(pwd);
- if (bssid != "")
- builder.addStringArgument(bssid);
- return sendCommand(builder);
-}
-
-ESP8266::CmdResult ESP8266::quitAccessPoint()
-{
- return sendCommand(CmdBuilder("CWQAP"));
-}
-
-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)
-{
- 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)
-{
- CmdBuilder builder("CIPSTART");
- builder.addStringArgument((type == TCP) ? "TCP" : "UDP");
- builder.addStringArgument(remoteIP);
- builder.addRawArgument(remotePort);
- return sendCommand(builder);
-}
-
-ESP8266::CmdResult ESP8266::closeConnection()
-{
- return sendCommand(CmdBuilder("CIPCLOSE"));
-}
-
-ESP8266::CmdResult ESP8266::sendData(const std::string & data)
-{
- CmdBuilder builder("CIPSEND");
- builder.addRawArgument(data.length());
- ESP8266::CmdResult result = sendCommand(builder);
- if (result == ESP8266::AT_OK)
- result = send_AT_data(data, false);
- return result;
-}
-
-ESP8266::CmdResult ESP8266::sendCommand(const CmdBuilder & cmd)
-{
- return send_AT_data(cmd.str(), true);
-}
-
-bool ESP8266::recvIpDataReadable()
-{
- bool result;
-
- disableRecvData(); // Lock queue access
-
- result = !recvIpDataBuffer.empty();
-
- enableRecvData(); // Unlock queue access
-
- return result;
-}
-
-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
-}
-
-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++)
- {
- // Write next character
- 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)
- {
- result = TimeoutError;
- goto exit;
- }
- }
- // Compare to written character
- if (AT_intf.getc() != cmdString[i])
- {
- // Handle error
- result = ESP8266::HardwareError;
- goto exit;
- }
- }
- }
-
- while (result == ESP8266::HardwareError)
- {
- // Wait to receive something
- response.clear();
- while (!read_line(response)) ;
-
- // Check if valid response
- if (response == "OK")
- result = ESP8266::AT_OK;
- else if (response == "FAIL")
- result = ESP8266::AT_FAIL;
- else if (response == "ERROR")
- result = ESP8266::AT_ERROR;
- else if (response == "SEND OK") // Used by AT+CIPSEND
- result = ESP8266::AT_OK;
- else if (response == "ALREADY CONNECT") // Used by AT+CIPSTART
- result = ESP8266::AT_OK;
-
- if (timer.read_ms() > timeout_ms)
- {
- result = TimeoutError;
- break;
- }
- }
-
-exit:
- enableRecvData(); // Enable interrupt processing
- return result;
-}
-
-bool ESP8266::read_line(std::string & line)
-{
- char received;
-
- while (AT_intf.readable())
- {
- received = AT_intf.getc();
- if (received == '\n')
- {
- return true;
- }
- else if (received != '\r')
- {
- line.push_back(received);
- }
- }
- return false;
-}
-
-void ESP8266::recv_AT_data_cb()
-{
- while (AT_intf.readable())
- {
- char received = AT_intf.getc();
- parseRecvIpData(received);
- parseRecvConnClosedMsg(received);
- parseRecvReset = false;
- }
-}
-
-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 DataRecvState state = Header;
-
- if (parseRecvReset)
- state = Reset;
-
- switch (state)
- {
- case Reset:
- default:
- index = 0;
- dataFinishedSize = 0;
- state = Header;
- // Continue processing switch
-
- case Header:
- if (received == findChars[index])
- {
- if (findChars[++index] == '\0')
- {
- index = 0;
- state = Length;
- }
- }
- else
- {
- state = Reset;
- }
- break;
-
- case Length:
- if ((received <= '9') && (received >= '0'))
- {
- if (index < maxSizeDigits)
- {
- sizeDigits[index++] = received;
- }
- else
- {
- state = Reset;
- }
- }
- else if (received == ':')
- {
- dataFinishedSize = std::atoi(sizeDigits);
- if (dataFinishedSize == 0)
- {
- state = Reset;
- }
- else
- {
- index = 0;
- state = Data;
- }
- }
- else
- {
- state = Reset;
- }
- break;
-
- case Data:
- if (index < dataFinishedSize)
- {
- recvIpDataBuffer.push(received);
- index++;
- }
- else
- {
- state = Reset;
- }
- break;
- };
-}
-
-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')
- {
- printDbgMsg(findChars);
- shouldReset = true;
- }
- }
- else
- {
- shouldReset = true;
- }
-
- if (shouldReset)
- {
- index = 0;
- }
-}
-
-void ESP8266::printDbgMsg(const char * message)
-{
- if (debugMsg != NULL)
- debugMsg->printf("%s", message);
-}
-
-ESP8266::CmdBuilder::CmdBuilder(const std::string & cmd)
-{
- clear(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)
-{
- std::ostringstream argStream;
- argStream << "\"" << arg << "\"";
- addRawArgument<std::string>(argStream.str());
-}
-
-std::string ESP8266::CmdBuilder::str() const
-{
- std::string cmdString = cmdStream.str();
- cmdString.append("\r\n");
- return cmdString;
-}
\ No newline at end of file
MAXREFDES143#: DeepCover Embedded Security in IoT Authenticated Sensing & Notification