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.
Revision 25:37ea43ff81be, committed 2016-12-16
- Comitter:
- IanBenzMaxim
- Date:
- Fri Dec 16 10:47:34 2016 -0600
- Parent:
- 24:434330962308
- Child:
- 26:80a16bc2c137
- Commit message:
- Now using unique secret for data signing between mbed node and server. Updated to mbed 5 for better platform support. Updated to latest version of 1-Wire library.
Changed in this revision
--- a/Display.hpp Wed Oct 19 13:23:41 2016 -0500
+++ b/Display.hpp Fri Dec 16 10:47:34 2016 -0600
@@ -56,8 +56,6 @@
struct Color
{
uint8_t R, G, B;
- Color(uint8_t R, uint8_t G, uint8_t B)
- : R(R), G(G), B(B) { }
};
/// Length in character os a display line.
--- a/Factory.cpp Wed Oct 19 13:23:41 2016 -0500
+++ b/Factory.cpp Fri Dec 16 10:47:34 2016 -0600
@@ -33,28 +33,29 @@
#include "Factory.hpp"
#include "SensorNode.hpp"
-#include "common.hpp"
#include "Masters/DS2465/DS2465.h"
#include "Slaves/Authenticators/DS28E15_22_25/DS28E15_22_25.h"
#include "wait_api.h"
using namespace OneWire;
-const uint8_t Factory::masterSecret[] = { 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x21,
- 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x31, 0x32 };
-const uint8_t Factory::invalidMasterSecret[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+/// The valid master secret for the system.
+static const DS2465::Secret masterSecret = { { 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x21,
+ 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x31, 0x32 } };
+/// An invalid master secret for example purposes.
+static const DS2465::Secret invalidMasterSecret = { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } };
-bool Factory::provision(DS2465 & ds2465)
+bool provisionCoprocessor(DS2465 & ds2465)
{
bool result = (ds2465.setMasterSecret(masterSecret) == ISha256MacCoproc::Success);
if (result)
{
SensorNode::AuthData authData;
DS28E15_22_25::Page pageData;
- std::memset(pageData, SensorNode::defaultPaddingByte, pageData.length);
- std::memcpy(pageData, authData.segment, authData.segment.length);
- result = (ds2465.writeScratchpad(pageData, pageData.length) == OneWireMaster::Success);
+ pageData.fill(uint8_t(SensorNode::defaultPaddingByte));
+ std::copy(authData.segment.begin(), authData.segment.end(), pageData.begin());
+ result = (ds2465.writeScratchpad(pageData.data(), pageData.size()) == OneWireMaster::Success);
}
if (result)
{
@@ -66,7 +67,7 @@
return result;
}
-bool Factory::provision(SensorNode & sensorNode, bool validSecret)
+bool provisionSensorNode(SensorNode & sensorNode, bool validSecret)
{
const int blockNum = sensorNode.authData.pageNum / 2;
const DS28E15_22_25::BlockProtection desiredProtection(false, false, false, true, blockNum); // Authentication Protection only
@@ -96,7 +97,7 @@
// Create constant partial secret
DS28E15_22_25::Scratchpad partialSecret;
DS28E15_22_25::Page pageData;
- std::memset(partialSecret, SensorNode::defaultPaddingByte, partialSecret.length);
+ partialSecret.fill(uint8_t(SensorNode::defaultPaddingByte));
// Read page data
if (result)
@@ -117,12 +118,12 @@
if (result)
{
DS28E15_22_25::Segment blankSegment;
- std::memset(blankSegment, SensorNode::defaultPaddingByte, blankSegment.length);
+ blankSegment.fill(uint8_t(SensorNode::defaultPaddingByte));
for (size_t i = 0; i < DS28E15_22_25::segmentsPerPage; i++)
{
result = (sensorNode.ds28e15.writeAuthSegment(sensorNode.ds2465, sensorNode.authData.pageNum, i,
((i == sensorNode.authData.segmentNum) ? sensorNode.authData.segment : blankSegment),
- pageData.toSegment(i), false) == OneWireSlave::Success);
+ DS28E15_22_25::segmentFromPage(i, pageData), false) == OneWireSlave::Success);
if (!result)
break;
--- a/Factory.hpp Wed Oct 19 13:23:41 2016 -0500
+++ b/Factory.hpp Fri Dec 16 10:47:34 2016 -0600
@@ -41,21 +41,14 @@
/// Represents the secure factory that will perform the initial provisioning of
/// Controllers (DS2465) and Sensor Nodes (DS28E15) for later authentication.
-class Factory
-{
-public:
- /// Provision the DS2465 on a Controller.
- /// @returns True on success.
- bool provision(OneWire::DS2465 & ds2465);
-
- /// Provision the DS28E15 on a Sensor Node.
- /// @param validSecret True to provision using the valid system secret or false to imitate an invalid Controller.
- /// @returns True on success.
- bool provision(SensorNode & sensorNode, bool validSecret);
-
-private:
- static const uint8_t masterSecret[]; ///< The valid master secret for the system.
- static const uint8_t invalidMasterSecret[]; ///< An invalid master secret for example purposes.
-};
+
+/// Provision the DS2465 on a Controller.
+/// @returns True on success.
+bool provisionCoprocessor(OneWire::DS2465 & ds2465);
+
+/// Provision the DS28E15 on a Sensor Node.
+/// @param validSecret True to provision using the valid system secret or false to imitate an invalid Controller.
+/// @returns True on success.
+bool provisionSensorNode(SensorNode & sensorNode, bool validSecret);
#endif
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/HexConversions.cpp Fri Dec 16 10:47:34 2016 -0600
@@ -0,0 +1,55 @@
+/*******************************************************************************
+* 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 <stdio.h>
+#include "HexConversions.hpp"
+
+const size_t charsPerByte = 2;
+
+std::string byteArrayToHexString(const uint8_t * byteArray, size_t byteArraySize)
+{
+ std::string hexString;
+ hexString.reserve(byteArraySize * charsPerByte);
+ byteArrayToHexString(byteArray, byteArraySize, hexString);
+ return hexString;
+}
+
+void byteArrayToHexString(const uint8_t * byteArray, size_t byteArraySize, std::string & hexString)
+{
+ char hexBuf[charsPerByte + 1];
+ for (size_t i = 0; i < byteArraySize; i++)
+ {
+ snprintf(hexBuf, (sizeof(hexBuf) / sizeof(hexBuf[0])), "%2.2X", byteArray[i]);
+ hexString.append(hexBuf, charsPerByte);
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HexConversions.hpp Fri Dec 16 10:47:34 2016 -0600 @@ -0,0 +1,50 @@ +/******************************************************************************* +* 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. +******************************************************************************* +*/ + +#ifndef HEXCONVERSIONS_HPP +#define HEXCONVERSIONS_HPP + +#include <string> +#include <stdint.h> +#include <stddef.h> + +/// Characters per byte for hex data. +extern const size_t charsPerByte; + +/// Creates a new hex string from a byte array. +std::string byteArrayToHexString(const uint8_t * byteArray, size_t byteArraySize); + +/// Appends a hex string created from a byte array to an existing string. +void byteArrayToHexString(const uint8_t * byteArray, size_t byteArraySize, std::string & hexString); + +#endif \ No newline at end of file
--- a/OneWire.lib Wed Oct 19 13:23:41 2016 -0500 +++ b/OneWire.lib Fri Dec 16 10:47:34 2016 -0600 @@ -1,1 +1,1 @@ -https://developer.mbed.org/teams/Maxim-Integrated/code/OneWire/#a1f0069f1832 +https://developer.mbed.org/teams/Maxim-Integrated/code/OneWire/#f0e0a7976846
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SensorData.hpp Fri Dec 16 10:47:34 2016 -0600
@@ -0,0 +1,52 @@
+/*******************************************************************************
+* 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.
+*******************************************************************************
+*/
+
+#ifndef SENSORDATA_HPP
+#define SENSORDATA_HPP
+
+#include <stdint.h>
+
+/// Contains a set of sensor measurements.
+struct SensorData
+{
+ static const int8_t tempAlarmLevel = 26;
+ static const uint8_t filterLifeAlarmLevel = 20;
+
+ int8_t temp;
+ uint8_t filterLife;
+
+ bool tempAlarm() const { return (temp >= tempAlarmLevel); }
+ bool filterLifeAlarm() const { return (filterLife <= filterLifeAlarmLevel); }
+};
+
+#endif
\ No newline at end of file
--- a/SensorNode.cpp Wed Oct 19 13:23:41 2016 -0500
+++ b/SensorNode.cpp Fri Dec 16 10:47:34 2016 -0600
@@ -32,7 +32,7 @@
*/
#include "SensorNode.hpp"
-#include "common.hpp"
+#include "SensorData.hpp"
#include "Masters/DS2465/DS2465.h"
#include "RomId/RomCommands.h"
#include "I2C.h"
@@ -82,9 +82,9 @@
DS28E15_22_25::Page pageData;
// Create constant partial secret
- std::memset(scratchpad, defaultPaddingByte, scratchpad.length);
+ scratchpad.fill(uint8_t(defaultPaddingByte));
// Read page data
- bool result = (ds2465.readMemory(DS2465::UserMemoryPage0, pageData, pageData.length, false) == OneWireMaster::Success);
+ bool result = (ds2465.readMemory(DS2465::UserMemoryPage0, pageData.data(), pageData.size(), false) == OneWireMaster::Success);
// Calculate secret
if (result)
{
@@ -132,7 +132,7 @@
#else
std::srand(userEntropy);
#endif
- for (size_t i = 0; i < challenge.length; i++)
+ for (size_t i = 0; i < challenge.size(); i++)
{
#ifdef TARGET_MAX32600
challenge[i] = MXC_TPU->prng_rnd_num;
--- a/SensorNode.hpp Wed Oct 19 13:23:41 2016 -0500
+++ b/SensorNode.hpp Fri Dec 16 10:47:34 2016 -0600
@@ -90,7 +90,8 @@
double initialLux() const { return m_initialLux; }
// Grant access to hardware interfaces for provisioning.
- friend class Factory;
+ friend bool provisionCoprocessor(OneWire::DS2465 & ds2465);
+ friend bool provisionSensorNode(SensorNode & sensorNode, bool validSecret);
private:
/// Authenticated data stored in DS28E15.
@@ -105,7 +106,7 @@
void reset()
{
- std::memset(segment, 0, segment.length);
+ segment.fill(0);
filterLife = initialFilterLife;
}
};
--- a/WebServerInterface.cpp Wed Oct 19 13:23:41 2016 -0500
+++ b/WebServerInterface.cpp Fri Dec 16 10:47:34 2016 -0600
@@ -32,18 +32,18 @@
*/
#include <vector>
-
#include "WebServerInterface.hpp"
#include "ESP8266.hpp"
#include "Slaves/Authenticators/ISha256MacCoproc.h"
-#include "common.hpp"
+#include "SensorData.hpp"
+#include "HexConversions.hpp"
#include "Serial.h"
#include "wait_api.h"
using OneWire::ISha256MacCoproc;
-const char WebServerInterface::wifiSsid[] = "WifiSsid";
-const char WebServerInterface::wifiPassword[] = "WifiPassword";
+const char WebServerInterface::wifiSsid[] = "TWS iPhone";
+const char WebServerInterface::wifiPassword[] = "maxim1234";
const char WebServerInterface::serverAddress[] = "www.mxim-security.us";
const unsigned int WebServerInterface::serverPort = 80;
const char WebServerInterface::serverPostPath[] = "/post.php";
@@ -61,12 +61,14 @@
/// Select the Transport Secret for the web server in the Controller.
/// @returns True on success.
-static bool setHttpPostSecret(ISha256MacCoproc & MacCoproc)
+static bool setHttpPostSecret(ISha256MacCoproc & MacCoproc, const OneWire::RomId & sessionId)
{
- ISha256MacCoproc::DevicePage::Buffer fillData;
- std::memset(fillData, defaultPaddingByte, ISha256MacCoproc::DevicePage::length);
- // static_assert(ISha256MacCoproc::DevicePage::length > ISha256MacCoproc::SlaveSecretData::length);
- return (MacCoproc.computeSlaveSecret(fillData, fillData, reinterpret_cast<const ISha256MacCoproc::SlaveSecretData::Buffer &>(fillData)) == ISha256MacCoproc::Success);
+ ISha256MacCoproc::DevicePage fillData;
+ fillData.fill(defaultPaddingByte);
+ ISha256MacCoproc::SlaveSecretData secretData;
+ secretData.fill(defaultPaddingByte);
+ std::copy(sessionId.buffer.begin(), sessionId.buffer.end(), secretData.begin());
+ return (MacCoproc.computeSlaveSecret(fillData, fillData, secretData) == ISha256MacCoproc::Success);
}
WebServerInterface::WebServerInterface(ESP8266 & esp8266, mbed::Serial * pc)
@@ -80,26 +82,19 @@
esp8266.setPowered(true);
esp8266.reset();
bool result = (esp8266.performSelfTest() == ESP8266::AT_OK);
- if (!result)
+ if (result)
{
- return false;
- }
- result = (esp8266.setCurrentWifiMode(ESP8266::softAP_station_mode) == ESP8266::AT_OK);
- if (!result)
- {
- return false;
+ result = (esp8266.setCurrentWifiMode(ESP8266::softAP_station_mode) == ESP8266::AT_OK);
}
- result = (esp8266.setMaxRFTXPower(10) == ESP8266::AT_OK);
- if (!result)
+ if (result)
{
- return false;
+ result = (esp8266.setMaxRFTXPower(10) == ESP8266::AT_OK);
}
- result = (esp8266.joinCurrentAccessPoint(wifiSsid, wifiPassword) == ESP8266::AT_OK);
- if (!result)
+ if (result)
{
- return false;
+ result = (esp8266.joinCurrentAccessPoint(wifiSsid, wifiPassword) == ESP8266::AT_OK);
}
- return true;
+ return result;
}
/// Format an HTTP GET request as a string for transmission.
@@ -129,19 +124,19 @@
ISha256MacCoproc::DeviceScratchpad block;
size_t index = 0;
ISha256MacCoproc::AuthMacData padding;
- std::memset(padding, defaultPaddingByte, padding.length);
- std::memset(output, defaultPaddingByte, output.length); // Set initial hash value
+ padding.fill(defaultPaddingByte);
+ output.fill(defaultPaddingByte); // Set initial hash value
while (index < ilen)
{
- if ((index + block.length) <= ilen) // Full block
+ if ((index + block.size()) <= ilen) // Full block
{
- std::memcpy(block, &input[index], block.length);
- index += block.length;
+ std::memcpy(block.data(), &input[index], block.size());
+ index += block.size();
}
else // Partial block with padding
{
- std::memcpy(block, &input[index], ilen - index);
- std::memset(&block[ilen - index], defaultPaddingByte, block.length - (ilen - index));
+ std::memcpy(block.data(), &input[index], ilen - index);
+ std::memset(&block[ilen - index], defaultPaddingByte, block.size() - (ilen - index));
index = ilen;
}
// Write data to coprocessor and hash block
@@ -207,13 +202,13 @@
// Combine initial post body with initial secret and hash
std::vector<uint8_t> hashInput;
hashInput.reserve(challengeLen + httpPost.length());
- hashInput.insert(hashInput.end(), challenge, challenge + challengeLen);
+ hashInput.assign(challenge, challenge + challengeLen);
hashInput.insert(hashInput.end(), httpPost.begin(), httpPost.end());
ISha256MacCoproc::Mac mac;
calculateHttpPostMac(macCoproc, &hashInput[0], hashInput.size(), mac);
char contentLen[5];
- snprintf(contentLen, sizeof(contentLen) / sizeof(contentLen[0]), "%u", (hashInput.size() - challengeLen) + (mac.length * charsPerByte) + 5 /* &MAC= */);
+ snprintf(contentLen, sizeof(contentLen) / sizeof(contentLen[0]), "%u", (hashInput.size() - challengeLen) + (mac.size() * charsPerByte) + 5 /* &MAC= */);
// Construct full post request
httpPost = "";
@@ -238,7 +233,7 @@
httpPost += fieldSeparator;
httpPost += "MAC";
httpPost += keyValSeparator;
- byteArrayToHexString(mac, mac.length, httpPost);
+ byteArrayToHexString(mac.data(), mac.size(), httpPost);
httpPost += newline;
return httpPost;
@@ -256,7 +251,7 @@
if (setSecret)
{
- result = setHttpPostSecret(macCoproc);
+ result = setHttpPostSecret(macCoproc, m_sessionId);
if (!result)
return result;
}
@@ -267,7 +262,7 @@
if (result)
{
// Request challenge
- result = (esp8266.sendData(formatHttpGet(serverAddress, serverChallengePath, sessionId)) == ESP8266::AT_OK);
+ result = (esp8266.sendData(formatHttpGet(serverAddress, serverChallengePath, m_sessionIdString)) == ESP8266::AT_OK);
if (result)
{
// Receive server response
@@ -309,7 +304,7 @@
result = (esp8266.openConnection(ESP8266::TCP, serverAddress, serverPort) == ESP8266::AT_OK);
if (result)
{
- result = (esp8266.sendData(formatHttpPost(serverAddress, serverPostPath, sessionId, macCoproc, event, postData, challenge)) == ESP8266::AT_OK);
+ result = (esp8266.sendData(formatHttpPost(serverAddress, serverPostPath, m_sessionIdString, macCoproc, event, postData, challenge)) == ESP8266::AT_OK);
wait_ms(ESP8266::sendDataRecoveryTimeMs); // Wait for ESP8266 specified recovery time
}
}
@@ -333,4 +328,10 @@
postBodyStream << fieldSeparator;
postBodyStream << "FilterLifeAlarm" << keyValSeparator << (sensorData.filterLifeAlarm() ? "true" : "false");
return postBodyStream.str();
+}
+
+void WebServerInterface::setSessionId(const OneWire::RomId & sessionId)
+{
+ m_sessionIdString = byteArrayToHexString(sessionId.buffer.data(), sessionId.buffer.size());
+ m_sessionId = sessionId;
}
\ No newline at end of file
--- a/WebServerInterface.hpp Wed Oct 19 13:23:41 2016 -0500
+++ b/WebServerInterface.hpp Fri Dec 16 10:47:34 2016 -0600
@@ -35,6 +35,7 @@
#define WEBSERVERINTERFACE_HPP
#include <string>
+#include "RomId/RomId.h"
/// The message type described by the POST.
enum PostEvent
@@ -52,10 +53,7 @@
/// through an HTTP challenge-respones scheme with SHA-256 data signing.
class WebServerInterface
{
-public:
- /// Session ID used by the web server to distinguish between multiple Controllers.
- std::string sessionId;
-
+public:
/// @param esp8266 Interface to ESP8266 for Wi-Fi access.
/// @param pc Optional serial interface for received web traffic.
WebServerInterface(ESP8266 & esp8266, mbed::Serial * pc = NULL);
@@ -75,7 +73,14 @@
/// Format sensor data as text suitable for use in a POST body.
/// @param sensorData Sensor data to format.
/// @returns Data formatted for web server.
- static std::string formatSensorDataPostBody(const SensorData & sensorData);
+ static std::string formatSensorDataPostBody(const SensorData & sensorData);
+
+ /// @{
+ /// Session ID used by the web server to distinguish between multiple Controllers.
+ const OneWire::RomId & sessionId() const { return m_sessionId; }
+ const std::string & sessionIdString() const { return m_sessionIdString; }
+ void setSessionId(const OneWire::RomId & sessionId);
+ /// @}
private:
/// @{
@@ -88,6 +93,9 @@
static const char serverChallengePath[];
/// @}
+ OneWire::RomId m_sessionId;
+ std::string m_sessionIdString;
+
ESP8266 & esp8266;
mbed::Serial * pc;
};
--- a/common.cpp Wed Oct 19 13:23:41 2016 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,55 +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 <stdio.h>
-#include "common.hpp"
-
-const size_t charsPerByte = 2;
-
-std::string byteArrayToHexString(const uint8_t * byteArray, size_t byteArraySize)
-{
- std::string hexString;
- hexString.reserve(byteArraySize * charsPerByte);
- byteArrayToHexString(byteArray, byteArraySize, hexString);
- return hexString;
-}
-
-void byteArrayToHexString(const uint8_t * byteArray, size_t byteArraySize, std::string & hexString)
-{
- char hexBuf[charsPerByte + 1];
- for (size_t i = 0; i < byteArraySize; i++)
- {
- snprintf(hexBuf, (sizeof(hexBuf) / sizeof(hexBuf[0])), "%2.2X", byteArray[i]);
- hexString.append(hexBuf, charsPerByte);
- }
-}
\ No newline at end of file
--- a/common.hpp Wed Oct 19 13:23:41 2016 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +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.
-*******************************************************************************
-*/
-
-#ifndef COMMON_HPP
-#define COMMON_HPP
-
-#include <string>
-#include <stdint.h>
-#include <stddef.h>
-
-/// Contains a set of sensor measurements.
-struct SensorData
-{
- static const int8_t tempAlarmLevel = 26;
- static const uint8_t filterLifeAlarmLevel = 20;
-
- int8_t temp;
- uint8_t filterLife;
-
- bool tempAlarm() const { return (temp >= tempAlarmLevel); }
- bool filterLifeAlarm() const { return (filterLife <= filterLifeAlarmLevel); }
-};
-
-/// Characters per byte for hex data.
-extern const size_t charsPerByte;
-
-/// Creates a new hex string from a byte array.
-std::string byteArrayToHexString(const uint8_t * byteArray, size_t byteArraySize);
-
-/// Appends a hex string created from a byte array to an existing string.
-void byteArrayToHexString(const uint8_t * byteArray, size_t byteArraySize, std::string & hexString);
-
-#endif
\ No newline at end of file
--- a/main.cpp Wed Oct 19 13:23:41 2016 -0500
+++ b/main.cpp Fri Dec 16 10:47:34 2016 -0600
@@ -33,7 +33,7 @@
#include <sstream>
-#include "common.hpp"
+#include "SensorData.hpp"
#include "WebServerInterface.hpp"
#include "Factory.hpp"
#include "SensorNode.hpp"
@@ -71,9 +71,10 @@
/// @{
/// LCD display colors.
-static const Display::Color Teal(0x00, 0xB2, 0xA9);
-static const Display::Color Red(0xFF, 0x00, 0x00);
-static const Display::Color Green(0x00, 0xFF, 0x00);
+static const Display::Color Teal = { 0x00, 0xB2, 0xA9 };
+static const Display::Color Red = { 0xFF, 0x00, 0x00 };
+static const Display::Color Green = { 0x00, 0xFF, 0x00 };
+static const Display::Color Purple = { 0x6E, 0x25, 0x85 };
/// @}
/// @{
@@ -87,7 +88,6 @@
static Display lcd(i2c, 0x78, 0x98);
static DS2465 ds2465(i2c, 0x30);
static SensorNode sensorNode(i2c, 0x90, 0x94, ds2465);
-static Factory factory;
static ESP8266 esp8266(D1, D0, D2, D3, 38400);
static WebServerInterface webIntf(esp8266, &pc);
/// @}
@@ -104,7 +104,7 @@
static bool buttonPressed(DigitalIn & button); ///< Checks if button is pressed (returns true) and waits for release.
static void displayStatus(Status status); ///< Display status message on LCD.
static void displaySensorData(const SensorData & sensorData); ///< Display sensor data on the LCD.
-static bool readWebSessionId(std::string & sessionId); ///< Read device's web session ID from it's nonvolatile storage.
+static bool readWebSessionId(OneWire::RomId & sessionId); ///< Read device's web session ID from it's nonvolatile storage.
#ifdef ASSEMBLY_TEST
#include "AssemblyTest.cpp"
@@ -138,13 +138,18 @@
// Read session ID
if (result)
{
- result = readWebSessionId(webIntf.sessionId);
+ OneWire::RomId sessionId;
+ result = readWebSessionId(sessionId);
+ if (result)
+ {
+ webIntf.setSessionId(sessionId);
+ }
}
// Provision DS2465 with master secret and page data
if (result)
{
- result = factory.provision(ds2465);
+ result = provisionCoprocessor(ds2465);
}
if (result)
@@ -207,7 +212,7 @@
case ProvisioningSensorNode:
if (!buttonPressed(invalidateButton)) // Provision normally
{
- if (factory.provision(sensorNode, true))
+ if (provisionSensorNode(sensorNode, true))
{
nextStatus = NormalOperation;
}
@@ -219,7 +224,7 @@
else // Invalidate button also pressed; Load invalid secret
{
// Provision with invalid secret
- if (factory.provision(sensorNode, false))
+ if (provisionSensorNode(sensorNode, false))
{
nextStatus = NormalOperation;
}
@@ -403,7 +408,7 @@
break;
case DisplaySessionId:
- lcd.writeLine("ID: " + webIntf.sessionId, Display::FirstLine);
+ lcd.writeLine("ID: " + webIntf.sessionIdString(), Display::FirstLine);
lcd.writeLine("Provision to begin", Display::SecondLine);
lcd.setBackLightColor(Teal);
break;
@@ -434,7 +439,7 @@
case SensorNodeNotAuthentic:
lcd.writeMessage("Sensor Node Not Authentic");
- lcd.setBackLightColor(Red);
+ lcd.setBackLightColor(Purple);
break;
case ControllerInitializationError:
@@ -458,19 +463,19 @@
static void displaySensorData(const SensorData & sensorData)
{
std::ostringstream stream;
- stream << "Chiller Temp: " << (int)sensorData.temp << "C";
+ stream << "Chiller Temp: " << static_cast<int>(sensorData.temp) << "C";
lcd.writeCompleteLine(stream.str(), Display::FirstLine);
stream.str(""); // Clear stream
- stream << "Filter Life: " << (unsigned int)sensorData.filterLife << "%";
+ stream << "Filter Life: " << static_cast<unsigned int>(sensorData.filterLife) << "%";
lcd.writeCompleteLine(stream.str(), Display::SecondLine);
- lcd.setBackLightColor((sensorData.tempAlarm() || sensorData.filterLifeAlarm()) ? Red : Green);
+ lcd.setBackLightColor(Green);
}
/// Read the Session ID to use with the web server from ROM.
/// @note Session ID is taken from the ROM ID of the MAX66242.
/// @param[out] Session ID string.
/// @returns True on success.
-static bool readWebSessionId(std::string & sessionId)
+static bool readWebSessionId(OneWire::RomId & sessionId)
{
const uint8_t I2C_address = 0x32;
const uint8_t ROM_address = 0x68;
@@ -480,11 +485,11 @@
if (i2c.write(I2C_address, reinterpret_cast<const char *>(&ROM_address), 1) != 0)
return false;
// Read ROM ID
- if (i2c.read(I2C_address, reinterpret_cast<char *>(&(static_cast<RomId::ByteBuffer &>(romId))), RomId::byteLen) != 0)
+ if (i2c.read(I2C_address, reinterpret_cast<char *>(romId.buffer.data()), romId.buffer.size()) != 0)
return false;
// Check if CRC valid
- if (!romId.crc8Valid())
+ if (!romId.valid())
return false;
- sessionId = byteArrayToHexString(romId, RomId::byteLen);
+ sessionId = romId;
return true;
}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os.lib Fri Dec 16 10:47:34 2016 -0600 @@ -0,0 +1,1 @@ +https://github.com/ARMmbed/mbed-os/#d5de476f74dd4de27012eb74ede078f6330dfc3f
--- a/mbed.bld Wed Oct 19 13:23:41 2016 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -http://mbed.org/users/mbed_official/code/mbed/builds/2e9cc70d1897 \ No newline at end of file
MAXREFDES143#: DeepCover Embedded Security in IoT Authenticated Sensing & Notification