
DeepCover Embedded Security in IoT: Public-key Secured Data Paths
Dependencies: MaximInterface
The MAXREFDES155# is an internet-of-things (IoT) embedded-security reference design, built to authenticate and control a sensing node using elliptic-curve-based public-key cryptography with control and notification from a web server.
The hardware includes an ARM® mbed™ shield and attached sensor endpoint. The shield contains a DS2476 DeepCover® ECDSA/SHA-2 coprocessor, Wifi communication, LCD push-button controls, and status LEDs. The sensor endpoint is attached to the shield using a 300mm cable and contains a DS28C36 DeepCover ECDSA/SHA-2 authenticator, IR-thermal sensor, and aiming laser for the IR sensor. The MAXREFDES155# is equipped with a standard Arduino® form-factor shield connector for immediate testing using an mbed board such as the MAX32600MBED#. The combination of these two devices represent an IoT device. Communication to the web server is accomplished with the shield Wifi circuitry. Communication from the shield to the attached sensor module is accomplished over I2C . The sensor module represents an IoT endpoint that generates small data with a requirement for message authenticity/integrity and secure on/off operational control.
The design is hierarchical with each mbed platform and shield communicating data from the sensor node to a web server that maintains a centralized log and dispatches notifications as necessary. The simplicity of this design enables rapid integration into any star-topology IoT network to provide security with the low overhead and cost provided by the ECDSA-P256 asymmetric-key and SHA-256 symmetric-key algorithms.
More information about the MAXREFDES155# is available on the Maxim Integrated website.
Revision 13:6a6225690c2e, committed 2017-11-06
- Comitter:
- IanBenzMaxim
- Date:
- Mon Nov 06 18:12:27 2017 -0600
- Parent:
- 12:46c5974a565f
- Child:
- 14:dc839a69379b
- Commit message:
- Updated to use MaximInterface.
Changed in this revision
--- a/Bitmap.cpp Thu Jun 01 14:21:58 2017 -0500 +++ b/Bitmap.cpp Mon Nov 06 18:12:27 2017 -0600 @@ -37,141 +37,114 @@ static const int pixelsPerSegment = 8; template <typename T> -static T divideRoundUp(const T dividend, const T divisor) -{ - return (dividend / divisor) + (((dividend % divisor) == 0) ? 0 : 1); +static T divideRoundUp(const T dividend, const T divisor) { + return (dividend / divisor) + (((dividend % divisor) == 0) ? 0 : 1); } -static int calculateSegmentsPerLine(int width) -{ - return divideRoundUp(width, pixelsPerSegment); +static int calculateSegmentsPerLine(int width) { + return divideRoundUp(width, pixelsPerSegment); } -static int calculateHeight(size_t size, int width) -{ - return static_cast<int>(divideRoundUp(size, static_cast<size_t>(calculateSegmentsPerLine(width)))); +static int calculateHeight(size_t size, int width) { + return static_cast<int>(divideRoundUp( + size, static_cast<size_t>(calculateSegmentsPerLine(width)))); } -static int calculateSegmentIndex(int x, int y, int width) -{ - return y * calculateSegmentsPerLine(width) + x / pixelsPerSegment; +static int calculateSegmentIndex(int x, int y, int width) { + return y * calculateSegmentsPerLine(width) + x / pixelsPerSegment; } -static int calculatePixelMask(int x) -{ - return 1 << (pixelsPerSegment - 1 - (x % pixelsPerSegment)); +static int calculatePixelMask(int x) { + return 1 << (pixelsPerSegment - 1 - (x % pixelsPerSegment)); } -Bitmap::Bitmap(int width, int height) : - m_width(std::max(width, minWidthHeight)), - m_height(std::max(height, minWidthHeight)), - m_data(calculateSegmentsPerLine(m_width) * m_height, 0x00) { } +Bitmap::Bitmap(int width, int height) + : m_width(std::max(width, minWidthHeight)), + m_height(std::max(height, minWidthHeight)), + m_data(calculateSegmentsPerLine(m_width) * m_height, 0x00) {} -Bitmap::Bitmap(const uint8_t * data, size_t size, int width) : - m_width(std::max(width, minWidthHeight)), - m_height(std::max(calculateHeight(size, width), minWidthHeight)), - m_data(calculateSegmentsPerLine(m_width) * m_height, 0x00) -{ - std::copy(data, data + size, m_data.begin()); +Bitmap::Bitmap(const uint8_t * data, size_t size, int width) + : m_width(std::max(width, minWidthHeight)), + m_height(std::max(calculateHeight(size, width), minWidthHeight)), + m_data(calculateSegmentsPerLine(m_width) * m_height, 0x00) { + std::copy(data, data + size, m_data.begin()); } -bool Bitmap::pixelEnabled(int x, int y) const -{ - bool enabled = false; - if ((x >= 0) && (x < m_width) && (y >= 0) && (y < m_height)) - { - enabled = m_data[calculateSegmentIndex(x, y, m_width)] & calculatePixelMask(x); - } - return enabled; +bool Bitmap::pixelEnabled(int x, int y) const { + bool enabled = false; + if ((x >= 0) && (x < m_width) && (y >= 0) && (y < m_height)) { + enabled = + m_data[calculateSegmentIndex(x, y, m_width)] & calculatePixelMask(x); + } + return enabled; } -void Bitmap::setPixelEnabled(int x, int y, bool enabled) -{ - if ((x >= 0) && (x < m_width) && (y >= 0) && (y < m_height)) - { - uint8_t & dataSegment = m_data[calculateSegmentIndex(x, y, m_width)]; - uint8_t dataMask = calculatePixelMask(x); - if (enabled) - { - dataSegment |= dataMask; - } - else - { - dataSegment &= ~dataMask; - } +void Bitmap::setPixelEnabled(int x, int y, bool enabled) { + if ((x >= 0) && (x < m_width) && (y >= 0) && (y < m_height)) { + uint8_t & dataSegment = m_data[calculateSegmentIndex(x, y, m_width)]; + uint8_t dataMask = calculatePixelMask(x); + if (enabled) { + dataSegment |= dataMask; + } else { + dataSegment &= ~dataMask; } + } } -void Bitmap::overlay(int x, int y, const uint8_t * data, size_t size, int width) -{ - if (width < minWidthHeight) - { - return; - } +void Bitmap::overlay(int x, int y, const uint8_t * data, size_t size, + int width) { + if (width < minWidthHeight) { + return; + } - const int segmentsPerLine = calculateSegmentsPerLine(width); - for (size_t segment = 0; segment < size; segment++) - { - const int curY = segment / segmentsPerLine; - if (!((y + curY) < m_height)) - { - break; - } - for (int pixel = 0; pixel < pixelsPerSegment; pixel++) - { - const int curX = (segment % segmentsPerLine) * pixelsPerSegment + pixel; - if (!(((x + curX) < m_width) && (curX < width))) - { - break; - } - setPixelEnabled(x + curX, y + curY, data[segment] & (1 << (pixelsPerSegment - 1 - pixel))); - } + const int segmentsPerLine = calculateSegmentsPerLine(width); + for (size_t segment = 0; segment < size; segment++) { + const int curY = segment / segmentsPerLine; + if (!((y + curY) < m_height)) { + break; } + for (int pixel = 0; pixel < pixelsPerSegment; pixel++) { + const int curX = (segment % segmentsPerLine) * pixelsPerSegment + pixel; + if (!(((x + curX) < m_width) && (curX < width))) { + break; + } + setPixelEnabled(x + curX, y + curY, + data[segment] & (1 << (pixelsPerSegment - 1 - pixel))); + } + } } -void Bitmap::overlay(int x, int y, const Bitmap & src) -{ - overlay(x, y, &src.m_data[0], src.m_data.size(), src.m_width); -} - -void Bitmap::clear() -{ - std::fill(m_data.begin(), m_data.end(), 0); +void Bitmap::overlay(int x, int y, const Bitmap & src) { + overlay(x, y, &src.m_data[0], src.m_data.size(), src.m_width); } -void Bitmap::clear(int x, int y, int width, int height) -{ - if (!((x >= 0) && (x < m_width) && (y >= 0) && (y < m_height))) - { - return; - } - if ((x + width) > m_width) - { - width = m_width - x; - } - if ((y + height) > m_height) - { - height = m_height - y; +void Bitmap::clear() { std::fill(m_data.begin(), m_data.end(), 0); } + +void Bitmap::clear(int x, int y, int width, int height) { + if (!((x >= 0) && (x < m_width) && (y >= 0) && (y < m_height))) { + return; + } + if ((x + width) > m_width) { + width = m_width - x; + } + if ((y + height) > m_height) { + height = m_height - y; + } + + const int startX = x; + const int startY = y; + while (y < (startY + height)) { + x = startX; + while (x < (startX + width)) { + if (((x % pixelsPerSegment) == 0) && + ((x + pixelsPerSegment) < (startX + width))) { + m_data[calculateSegmentIndex(x, y, m_width)] = 0; + x += pixelsPerSegment; + } else { + setPixelEnabled(x, y, false); + x++; + } } - - const int startX = x; - const int startY = y; - while (y < (startY + height)) - { - x = startX; - while (x < (startX + width)) - { - if (((x % pixelsPerSegment) == 0) && ((x + pixelsPerSegment) < (startX + width))) - { - m_data[calculateSegmentIndex(x, y, m_width)] = 0; - x += pixelsPerSegment; - } - else - { - setPixelEnabled(x, y, false); - x++; - } - } - y++; - } + y++; + } }
--- a/Bitmap.hpp Thu Jun 01 14:21:58 2017 -0500 +++ b/Bitmap.hpp Mon Nov 06 18:12:27 2017 -0600 @@ -38,56 +38,56 @@ #include <vector> /// Stores a black and white bitmap image. -class Bitmap -{ -public: - /// Construct a zero-initialized bitmap with specified dimensions. - /// @param width Width in pixels that is >= 1. - /// @param height Height in pixels that is >= 1. - Bitmap(int width, int height); +class Bitmap { +public: + /// Construct a zero-initialized bitmap with specified dimensions. + /// @param width Width in pixels that is >= 1. + /// @param height Height in pixels that is >= 1. + Bitmap(int width, int height); + + /// Load bitmap from a byte array. + /// @param data Array of scanline bitmap data. + /// @param size Size of data array. + /// @param width Width of loaded image in pixels that is >= 1. + Bitmap(const uint8_t * data, size_t size, int width); + + int width() const { return m_width; } ///< Width in pixels. + int height() const { return m_height; } ///< Height in pixels. + + /// Check if a pixel is enabled (black). + /// @returns + /// True if the pixel is enabled or false if the coordinate is out of range. + bool pixelEnabled(int x, int y) const; + /// Enable or disable a pixel. + /// @param True to set to black. False to set to white. + void setPixelEnabled(int x, int y, bool enabled); - /// Load bitmap from a byte array. - /// @param data Array of scanline bitmap data. - /// @param size Size of data array. - /// @param width Width of loaded image in pixels that is >= 1. - Bitmap(const uint8_t * data, size_t size, int width); - - int width() const { return m_width; } ///< Width in pixels. - int height() const { return m_height; } ///< Height in pixels. - - /// Check if a pixel is enabled (black). - /// @returns True if the pixel is enabled. Returns false if the coordinate is out of range. - bool pixelEnabled(int x, int y) const; - /// Enable or disable a pixel. - /// @param True to set to black. False to set to white. - void setPixelEnabled(int x, int y, bool enabled); - - /// Overlay another bitmap on top of this bitmap. - /// @param x x-coordinate location to overlay. - /// @param y y-coordinate location to overlay. - /// @param src Bitmap to overlay. - void overlay(int x, int y, const Bitmap & src); - - /// Overlay bitmap data from a byte array on top of this bitmap. - /// @param x x-coordinate location to overlay. - /// @param y y-coordinate location to overlay. - /// @param data Array of scanline bitmap data. - /// @param size Size of data array. - /// @param width Width of overlayed image in pixels that is >= 1. - void overlay(int x, int y, const uint8_t * data, size_t size, int width); - - /// Reset to initial state. - void clear(); - - /// Reset region to initial state. - /// @param x,y Coordinates to begin clearing at. - /// @param width,height Dimensions of the cleared region. - void clear(int x, int y, int width, int height); - + /// Overlay another bitmap on top of this bitmap. + /// @param x x-coordinate location to overlay. + /// @param y y-coordinate location to overlay. + /// @param src Bitmap to overlay. + void overlay(int x, int y, const Bitmap & src); + + /// Overlay bitmap data from a byte array on top of this bitmap. + /// @param x x-coordinate location to overlay. + /// @param y y-coordinate location to overlay. + /// @param data Array of scanline bitmap data. + /// @param size Size of data array. + /// @param width Width of overlayed image in pixels that is >= 1. + void overlay(int x, int y, const uint8_t * data, size_t size, int width); + + /// Reset to initial state. + void clear(); + + /// Reset region to initial state. + /// @param x,y Coordinates to begin clearing at. + /// @param width,height Dimensions of the cleared region. + void clear(int x, int y, int width, int height); + private: - int m_width; - int m_height; - std::vector<uint8_t> m_data; + int m_width; + int m_height; + std::vector<uint8_t> m_data; }; #endif
--- a/Button.cpp Thu Jun 01 14:21:58 2017 -0500 +++ b/Button.cpp Mon Nov 06 18:12:27 2017 -0600 @@ -32,46 +32,44 @@ #include "Button.hpp" -static const int deselectedBorderWidth = 1; // Border width when button is deselected. -static const int selectedBorderWidth = 2; // Border width when button is selected. -static const int borderPadding = selectedBorderWidth + 1; // Total width of the border region. +// Border width when button is deselected. +static const int deselectedBorderWidth = 1; +// Border width when button is selected. +static const int selectedBorderWidth = 2; +// Total width of the border region. +static const int borderPadding = selectedBorderWidth + 1; -Button::Button() -{ - m_border.setParent(this); - m_border.setBorderWidth(deselectedBorderWidth); - m_label.setParent(this); -} - -int Button::preferredWidth() const -{ - return m_label.preferredWidth() + 2 * borderPadding; +Button::Button() { + m_border.setParent(this); + m_border.setBorderWidth(deselectedBorderWidth); + m_label.setParent(this); } -int Button::preferredHeight() const -{ - return m_label.preferredHeight() + 2 * borderPadding; +int Button::preferredWidth() const { + return m_label.preferredWidth() + 2 * borderPadding; +} + +int Button::preferredHeight() const { + return m_label.preferredHeight() + 2 * borderPadding; } -void Button::focusChanged(bool focused) -{ - m_border.setBorderWidth(focused ? selectedBorderWidth : deselectedBorderWidth); - invalidate(); // Ensure border and text are redrawn together. +void Button::focusChanged(bool focused) { + m_border.setBorderWidth(focused ? selectedBorderWidth + : deselectedBorderWidth); + invalidate(); // Ensure border and text are redrawn together. } -void Button::resized() -{ - m_border.resize(width(), height()); - m_label.move(borderPadding, borderPadding); - m_label.resize(m_border.width() - 2 * borderPadding, m_border.height() - 2 * borderPadding); +void Button::resized() { + m_border.resize(width(), height()); + m_label.move(borderPadding, borderPadding); + m_label.resize(m_border.width() - 2 * borderPadding, + m_border.height() - 2 * borderPadding); } -bool Button::doProcessKey(Key key) -{ - bool handled = (key == LeftClickKey); - if (handled && m_clickedHandler) - { - m_clickedHandler(); - } - return handled; +bool Button::doProcessKey(Key key) { + bool handled = (key == LeftClickKey); + if (handled && m_clickedHandler) { + m_clickedHandler(this); + } + return handled; }
--- a/Button.hpp Thu Jun 01 14:21:58 2017 -0500 +++ b/Button.hpp Mon Nov 06 18:12:27 2017 -0600 @@ -33,52 +33,50 @@ #ifndef BUTTON_HPP #define BUTTON_HPP -#include <Callback.h> +#include <MaximInterface/Utilities/Function.hpp> #include "Graphic.hpp" #include "Text.hpp" #include "Rectangle.hpp" /// Clickable button control with text label. -class Button : public Graphic -{ +class Button : public Graphic { public: - typedef mbed::Callback<void()> EventHandler; + typedef MaximInterface::Function<void(Button *)> EventHandler; + + Button(); + + /// @{ + /// Text label of the button. + const std::string & text() const { return m_label.text(); } + void setText(const std::string & text) { m_label.setText(text); } + /// @} - Button(); - - /// @{ - /// Text label of the button. - const std::string & text() const { return m_label.text(); } - void setText(const std::string & text) { m_label.setText(text); } - /// @} - - /// @{ - /// Enable or disable word wrapping on the label. - bool wordWrap() const { return m_label.wordWrap(); } - void setWordWrap(bool wordWrap) { m_label.setWordWrap(wordWrap); } - /// @} - - /// @{ - /// @note Depends on text and wordWrap properties. Call update to refresh. - int preferredWidth() const; - int preferredHeight() const; - /// @} - - /// Set the event handler that is called when the button is clicked. - void setClickedHandler(const EventHandler & clickedHandler) - { - m_clickedHandler = clickedHandler; - } + /// @{ + /// Enable or disable word wrapping on the label. + bool wordWrap() const { return m_label.wordWrap(); } + void setWordWrap(bool wordWrap) { m_label.setWordWrap(wordWrap); } + /// @} + + /// @{ + /// @note Depends on text and wordWrap properties. Call update to refresh. + int preferredWidth() const; + int preferredHeight() const; + /// @} + + /// Set the event handler that is called when the button is clicked. + void setClickedHandler(const EventHandler & clickedHandler) { + m_clickedHandler = clickedHandler; + } protected: - virtual void focusChanged(bool focused); - virtual void resized(); - virtual bool doProcessKey(Key key); + virtual void focusChanged(bool focused); + virtual void resized(); + virtual bool doProcessKey(Key key); private: - Rectangle m_border; - Text m_label; - EventHandler m_clickedHandler; + Rectangle m_border; + Text m_label; + EventHandler m_clickedHandler; }; #endif
--- a/CC3100.cpp Thu Jun 01 14:21:58 2017 -0500 +++ b/CC3100.cpp Mon Nov 06 18:12:27 2017 -0600 @@ -50,13 +50,12 @@ \return None */ -void SimpleLinkGeneralEventHandler(SlDeviceEvent_t * pDevEvent) -{ - /* - * Most of the general errors are not FATAL are are to be handled - * appropriately by the application - */ - printf(" [GENERAL EVENT] \n\r"); +void SimpleLinkGeneralEventHandler(SlDeviceEvent_t * pDevEvent) { + /* + * Most of the general errors are not FATAL are are to be handled + * appropriately by the application + */ + printf(" [GENERAL EVENT] \n\r"); } /*! @@ -70,52 +69,46 @@ \warning */ -void SimpleLinkWlanEventHandler(SlWlanEvent_t * pWlanEvent) -{ - if(pWlanEvent == NULL) - { - printf(" [WLAN EVENT] NULL Pointer Error \n\r"); - return; - } - - switch (pWlanEvent->Event) - { - case SL_WLAN_CONNECT_EVENT: - currentState = CC3100::Connected; +void SimpleLinkWlanEventHandler(SlWlanEvent_t * pWlanEvent) { + if (pWlanEvent == NULL) { + printf(" [WLAN EVENT] NULL Pointer Error \n\r"); + return; + } + + switch (pWlanEvent->Event) { + case SL_WLAN_CONNECT_EVENT: + currentState = CC3100::Connected; - /* - * Information about the connected AP (like name, MAC etc) will be - * available in 'slWlanConnectAsyncResponse_t' - Applications - * can use it if required - * - * slWlanConnectAsyncResponse_t *pEventData = NULL; - * pEventData = &pWlanEvent->EventData.STAandP2PModeWlanConnected; - * - */ - break; + /* + * Information about the connected AP (like name, MAC etc) will be + * available in 'slWlanConnectAsyncResponse_t' - Applications + * can use it if required + * + * slWlanConnectAsyncResponse_t *pEventData = NULL; + * pEventData = &pWlanEvent->EventData.STAandP2PModeWlanConnected; + * + */ + break; - case SL_WLAN_DISCONNECT_EVENT: - { - currentState = CC3100::Disconnected; - - slWlanConnectAsyncResponse_t & pEventData = pWlanEvent->EventData.STAandP2PModeDisconnected; + case SL_WLAN_DISCONNECT_EVENT: { + currentState = CC3100::Disconnected; - /* If the user has initiated 'Disconnect' request, 'reason_code' is SL_USER_INITIATED_DISCONNECTION */ - if(SL_WLAN_DISCONNECT_USER_INITIATED_DISCONNECTION == pEventData.reason_code) - { - printf(" Device disconnected from the AP on application's request \n\r"); - } - else - { - printf(" Device disconnected from the AP on an ERROR..!! \n\r"); - } - } - break; + slWlanConnectAsyncResponse_t & pEventData = + pWlanEvent->EventData.STAandP2PModeDisconnected; - default: - printf(" [WLAN EVENT] Unexpected event \n\r"); - break; + /* If the user has initiated 'Disconnect' request, 'reason_code' is SL_USER_INITIATED_DISCONNECTION */ + if (SL_WLAN_DISCONNECT_USER_INITIATED_DISCONNECTION == + pEventData.reason_code) { + printf(" Device disconnected from the AP on application's request \n\r"); + } else { + printf(" Device disconnected from the AP on an ERROR..!! \n\r"); } + } break; + + default: + printf(" [WLAN EVENT] Unexpected event \n\r"); + break; + } } /*! @@ -130,26 +123,23 @@ \warning */ -void SimpleLinkNetAppEventHandler(SlNetAppEvent_t * pNetAppEvent) -{ - if (pNetAppEvent == NULL) - { - printf(" [NETAPP EVENT] NULL Pointer Error \n\r"); - return; - } - - switch (pNetAppEvent->Event) - { - case SL_NETAPP_IPV4_IPACQUIRED_EVENT: - currentState = CC3100::Connected; +void SimpleLinkNetAppEventHandler(SlNetAppEvent_t * pNetAppEvent) { + if (pNetAppEvent == NULL) { + printf(" [NETAPP EVENT] NULL Pointer Error \n\r"); + return; + } - //SlIpV4AcquiredAsync_t & pEventData = pNetAppEvent->EventData.ipAcquiredV4; - break; + switch (pNetAppEvent->Event) { + case SL_NETAPP_IPV4_IPACQUIRED_EVENT: + currentState = CC3100::Connected; - default: - printf(" [NETAPP EVENT] Unexpected event \n\r"); - break; - } + //SlIpV4AcquiredAsync_t & pEventData = pNetAppEvent->EventData.ipAcquiredV4; + break; + + default: + printf(" [NETAPP EVENT] Unexpected event \n\r"); + break; + } } /*! @@ -159,43 +149,40 @@ \return None */ -void SimpleLinkSockEventHandler(SlSockEvent_t *pSock) -{ - if(pSock == NULL) - { - printf(" [SOCK EVENT] NULL Pointer Error \n\r"); - return; - } - - switch( pSock->Event ) - { - case SL_SOCKET_TX_FAILED_EVENT: - /* - * TX Failed - * - * Information about the socket descriptor and status will be - * available in 'SlSockEventData_t' - Applications can use it if - * required - * - * SlSockEventData_u *pEventData = NULL; - * pEventData = & pSock->socketAsyncEvent; - */ - switch (pSock->socketAsyncEvent.SockTxFailData.status) - { - case SL_ECLOSE: - printf(" [SOCK EVENT] Close socket operation failed to transmit all queued packets\n\r"); - break; +void SimpleLinkSockEventHandler(SlSockEvent_t * pSock) { + if (pSock == NULL) { + printf(" [SOCK EVENT] NULL Pointer Error \n\r"); + return; + } - default: - printf(" [SOCK EVENT] Unexpected event \n\r"); - break; - } - break; + switch (pSock->Event) { + case SL_SOCKET_TX_FAILED_EVENT: + /* + * TX Failed + * + * Information about the socket descriptor and status will be + * available in 'SlSockEventData_t' - Applications can use it if + * required + * + * SlSockEventData_u *pEventData = NULL; + * pEventData = & pSock->socketAsyncEvent; + */ + switch (pSock->socketAsyncEvent.SockTxFailData.status) { + case SL_ECLOSE: + printf(" [SOCK EVENT] Close socket operation failed to transmit all " + "queued packets\n\r"); + break; default: - printf(" [SOCK EVENT] Unexpected event \n\r"); - break; + printf(" [SOCK EVENT] Unexpected event \n\r"); + break; } + break; + + default: + printf(" [SOCK EVENT] Unexpected event \n\r"); + break; + } } /*! @@ -209,384 +196,357 @@ \warning */ -static void SimpleLinkPingReport(SlPingReport_t * pPingReport) -{ - currentState = CC3100::Connected; +static void SimpleLinkPingReport(SlPingReport_t * pPingReport) { + currentState = CC3100::Connected; - if(pPingReport == NULL) - { - printf(" [PING REPORT] NULL Pointer Error\r\n"); - return; - } - - printf(" [PING REPORT] Sent: %lu, Received: %lu\r\n", pPingReport->PacketsSent, pPingReport->PacketsReceived); + if (pPingReport == NULL) { + printf(" [PING REPORT] NULL Pointer Error\r\n"); + return; + } + + printf(" [PING REPORT] Sent: %lu, Received: %lu\r\n", + pPingReport->PacketsSent, pPingReport->PacketsReceived); } -CC3100::SPI::SPI(PinName mosi, PinName miso, PinName sclk, PinName ssel) : spi(mosi, miso, sclk), cs(ssel, 1) { } +CC3100::SPI::SPI(PinName mosi, PinName miso, PinName sclk, PinName ssel) + : spi(mosi, miso, sclk), cs(ssel, 1) {} + +void CC3100::SPI::transfer(const uint8_t * txData, size_t dataSize, + uint8_t * rxData) { + const int cs_delay_ms = 5; -void CC3100::SPI::transfer(const uint8_t * txData, size_t dataSize, uint8_t * rxData) -{ - const int cs_delay_ms = 5; - - cs = 0; - wait_ms(cs_delay_ms); - for (size_t i = 0; i < dataSize; i++) - { - if (rxData == NULL) - spi.write(txData[i]); - else - rxData[i] = spi.write(txData[i]); - } - wait_ms(cs_delay_ms); - cs = 1; + cs = 0; + wait_ms(cs_delay_ms); + for (size_t i = 0; i < dataSize; i++) { + if (rxData == NULL) + spi.write(txData[i]); + else + rxData[i] = spi.write(txData[i]); + } + wait_ms(cs_delay_ms); + cs = 1; } -CC3100::CC3100() : spi(HOST_SPI_MOSI_PIN, HOST_SPI_MISO_PIN, HOST_SPI_CLK_PIN, HOST_SPI_nCS_PIN) { } +CC3100::CC3100() + : spi(HOST_SPI_MOSI_PIN, HOST_SPI_MISO_PIN, HOST_SPI_CLK_PIN, + HOST_SPI_nCS_PIN) {} -CC3100 & CC3100::instance() -{ - static CC3100 instance; - return instance; +CC3100 & CC3100::instance() { + static CC3100 instance; + return instance; } -int CC3100::start() -{ - // Adapter should be stopped. - if (currentState != Stopped) - return invalidState; - - int result = sl_Start(&spi, NULL, NULL); - if (result >= 0) - currentState = Disconnected; - return result; -} +int CC3100::start() { + // Adapter should be stopped. + if (currentState != Stopped) + return invalidState; -CC3100::State CC3100::state() const -{ - return currentState; + int result = sl_Start(&spi, NULL, NULL); + if (result >= 0) + currentState = Disconnected; + return result; } -int CC3100::stop() -{ - // Adapter should not be stopped. - if (currentState == Stopped) - return invalidState; - - int result = sl_Stop(0xFF); - if (result >= 0) - currentState = Stopped; - return result; +CC3100::State CC3100::state() const { return currentState; } + +int CC3100::stop() { + // Adapter should not be stopped. + if (currentState == Stopped) + return invalidState; + + int result = sl_Stop(0xFF); + if (result >= 0) + currentState = Stopped; + return result; } -void CC3100::update() -{ - sl_Task(); -} +void CC3100::update() { sl_Task(); } -int CC3100::setDateTime(const std::tm & dateTime) -{ - SlDateTime_t slDateTime = { - static_cast<_u32>(dateTime.tm_sec), // sl_tm_sec - static_cast<_u32>(dateTime.tm_min), // sl_tm_min - static_cast<_u32>(dateTime.tm_hour), // sl_tm_hour - static_cast<_u32>(dateTime.tm_mday), // sl_tm_day - static_cast<_u32>(dateTime.tm_mon), // sl_tm_mon - static_cast<_u32>(dateTime.tm_year) // sl_tm_year - }; - return sl_DevSet(SL_DEVICE_GENERAL_CONFIGURATION, - SL_DEVICE_GENERAL_CONFIGURATION_DATE_TIME, - sizeof(SlDateTime_t), - reinterpret_cast<const _u8 *>(&slDateTime)); +int CC3100::setDateTime(const std::tm & dateTime) { + SlDateTime_t slDateTime = { + static_cast<_u32>(dateTime.tm_sec), // sl_tm_sec + static_cast<_u32>(dateTime.tm_min), // sl_tm_min + static_cast<_u32>(dateTime.tm_hour), // sl_tm_hour + static_cast<_u32>(dateTime.tm_mday), // sl_tm_day + static_cast<_u32>(dateTime.tm_mon), // sl_tm_mon + static_cast<_u32>(dateTime.tm_year) // sl_tm_year + }; + return sl_DevSet(SL_DEVICE_GENERAL_CONFIGURATION, + SL_DEVICE_GENERAL_CONFIGURATION_DATE_TIME, + sizeof(SlDateTime_t), + reinterpret_cast<const _u8 *>(&slDateTime)); } -int CC3100::set_credentials(const char * ssid, const char * pass, nsapi_security_t security) -{ - this->ssid.assign(ssid); - this->pass.assign(pass); - this->security = security; - return 0; +int CC3100::set_credentials(const char * ssid, const char * pass, + nsapi_security_t security) { + this->ssid.assign(ssid); + this->pass.assign(pass); + this->security = security; + return 0; } -int CC3100::connect(const char * ssid, const char * pass, nsapi_security_t security, uint8_t channel) -{ - // Adapter should be disconnected. - if (currentState != Disconnected) - return invalidState; - - SlSecParams_t secParams = { - SL_SEC_TYPE_OPEN, // Type - const_cast<_i8 *>(reinterpret_cast<const _i8 *>(pass)), // Key - static_cast<_u8>(strlen(pass)), // KeyLen - }; - switch (security) - { - case NSAPI_SECURITY_WPA2: - case NSAPI_SECURITY_WPA: - case NSAPI_SECURITY_WPA_WPA2: - secParams.Type = SL_SEC_TYPE_WPA_WPA2; - break; - - case NSAPI_SECURITY_WEP: - secParams.Type = SL_SEC_TYPE_WEP; - break; - - case NSAPI_SECURITY_NONE: - case NSAPI_SECURITY_UNKNOWN: - secParams.Type = SL_SEC_TYPE_OPEN; - break; - } - int result = sl_WlanConnect(reinterpret_cast<const _i8 *>(ssid), strlen(ssid), NULL, &secParams, NULL); - if (result == SL_RET_CODE_OK) - { - // Wait for completion. - int attempts = 1000; - do - { - wait_ms(10); - update(); - } while ((currentState != Connected) && (--attempts > 0)); - if (attempts == 0) - result = SL_RET_CODE_ABORT; - } - return result; +int CC3100::connect(const char * ssid, const char * pass, + nsapi_security_t security, uint8_t channel) { + // Adapter should be disconnected. + if (currentState != Disconnected) + return invalidState; + + SlSecParams_t secParams = { + SL_SEC_TYPE_OPEN, // Type + const_cast<_i8 *>(reinterpret_cast<const _i8 *>(pass)), // Key + static_cast<_u8>(strlen(pass)), // KeyLen + }; + switch (security) { + case NSAPI_SECURITY_WPA2: + case NSAPI_SECURITY_WPA: + case NSAPI_SECURITY_WPA_WPA2: + secParams.Type = SL_SEC_TYPE_WPA_WPA2; + break; + + case NSAPI_SECURITY_WEP: + secParams.Type = SL_SEC_TYPE_WEP; + break; + + case NSAPI_SECURITY_NONE: + case NSAPI_SECURITY_UNKNOWN: + secParams.Type = SL_SEC_TYPE_OPEN; + break; + } + int result = sl_WlanConnect(reinterpret_cast<const _i8 *>(ssid), strlen(ssid), + NULL, &secParams, NULL); + if (result == SL_RET_CODE_OK) { + // Wait for completion. + int attempts = 1000; + do { + wait_ms(10); + update(); + } while ((currentState != Connected) && (--attempts > 0)); + if (attempts == 0) + result = SL_RET_CODE_ABORT; + } + return result; } -int CC3100::connect(const char * ssid, const char * username, const char * password) -{ - // Adapter should be disconnected. - if (currentState != Disconnected) - return invalidState; - - uint8_t values = 0; - sl_WlanSet(SL_WLAN_CFG_GENERAL_PARAM_ID, 19, 1, &values); - - SlSecParams_t secParams = { - SL_SEC_TYPE_WPA_ENT, // Type - const_cast<_i8 *>(reinterpret_cast<const _i8 *>(password)), // Key - static_cast<_u8>(strlen(password)) // KeyLen - }; - SlSecParamsExt_t secParamsExt = { - const_cast<_i8 *>(reinterpret_cast<const _i8 *>(username)), // User - static_cast<_u8>(strlen(username)), // UserLen - NULL, // AnonUser - 0, // AnonUserLen - 0, // CertIndex - SL_ENT_EAP_METHOD_PEAP0_MSCHAPv2 // EapMethod - }; - int result = sl_WlanConnect(reinterpret_cast<const _i8 *>(ssid), strlen(ssid), NULL, &secParams, &secParamsExt); - if (result == SL_RET_CODE_OK) - { - // Wait for completion. - int attempts = 1000; - do - { - wait_ms(10); - update(); - } while ((currentState != Connected) && (--attempts > 0)); - if (attempts == 0) - result = SL_RET_CODE_ABORT; - } - return result; +int CC3100::connect(const char * ssid, const char * username, + const char * password) { + // Adapter should be disconnected. + if (currentState != Disconnected) + return invalidState; + + uint8_t values = 0; + sl_WlanSet(SL_WLAN_CFG_GENERAL_PARAM_ID, 19, 1, &values); + + SlSecParams_t secParams = { + SL_SEC_TYPE_WPA_ENT, // Type + const_cast<_i8 *>(reinterpret_cast<const _i8 *>(password)), // Key + static_cast<_u8>(strlen(password)) // KeyLen + }; + SlSecParamsExt_t secParamsExt = { + const_cast<_i8 *>(reinterpret_cast<const _i8 *>(username)), // User + static_cast<_u8>(strlen(username)), // UserLen + NULL, // AnonUser + 0, // AnonUserLen + 0, // CertIndex + SL_ENT_EAP_METHOD_PEAP0_MSCHAPv2 // EapMethod + }; + int result = sl_WlanConnect(reinterpret_cast<const _i8 *>(ssid), strlen(ssid), + NULL, &secParams, &secParamsExt); + if (result == SL_RET_CODE_OK) { + // Wait for completion. + int attempts = 1000; + do { + wait_ms(10); + update(); + } while ((currentState != Connected) && (--attempts > 0)); + if (attempts == 0) + result = SL_RET_CODE_ABORT; + } + return result; } -int CC3100::disconnect() -{ - // Adapter should be connected. - if (currentState != Connected) - return invalidState; - - return sl_WlanDisconnect(); +int CC3100::disconnect() { + // Adapter should be connected. + if (currentState != Connected) + return invalidState; + + return sl_WlanDisconnect(); } -int CC3100::gethostbyname(const char *host, SocketAddress *address, nsapi_version_t version) -{ - // TODO: Add IPv6 support - - // Adapter should be connected. - if (currentState != Connected) - return invalidState; - - uint32_t addressInt; - int result; - int attempts = 1000; - do // Wait for DNS servers. - { - wait_ms(10); - result = sl_NetAppDnsGetHostByName(const_cast<_i8 *>(reinterpret_cast<const _i8 *>(host)), strlen(host), - reinterpret_cast<_u32 *>(&addressInt), SL_AF_INET); - } while ((result == SL_NET_APP_DNS_NO_SERVER) && (--attempts > 0)); - if (result == SL_RET_CODE_OK) - { - nsapi_addr_t addressBytes = { - NSAPI_IPv4, // version - 0, // bytes - }; - for (int i = 4; i > 0; i--) - { - addressBytes.bytes[i - 1] = addressInt; - addressInt >>= 8; - } - address->set_addr(addressBytes); +int CC3100::gethostbyname(const char * host, SocketAddress * address, + nsapi_version_t version) { + // TODO: Add IPv6 support + + // Adapter should be connected. + if (currentState != Connected) + return invalidState; + + uint32_t addressInt; + int result; + int attempts = 1000; + do // Wait for DNS servers. + { + wait_ms(10); + result = sl_NetAppDnsGetHostByName( + const_cast<_i8 *>(reinterpret_cast<const _i8 *>(host)), strlen(host), + reinterpret_cast<_u32 *>(&addressInt), SL_AF_INET); + } while ((result == SL_NET_APP_DNS_NO_SERVER) && (--attempts > 0)); + if (result == SL_RET_CODE_OK) { + nsapi_addr_t addressBytes = { + NSAPI_IPv4, // version + 0, // bytes + }; + for (int i = 4; i > 0; i--) { + addressBytes.bytes[i - 1] = addressInt; + addressInt >>= 8; } - return result; + address->set_addr(addressBytes); + } + return result; } -int CC3100::ping(const SocketAddress & address) -{ - // Adapter should be connected. - if (currentState != Connected) - return invalidState; - - SlPingStartCommand_t pingParams = { - 1000, // PingIntervalTime - 20, // PingSize - 3000, // PingRequestTimeout - 3, // TotalNumberOfAttempts - 0, // Flags - 0 // Ip - }; - for (int i = 0; i < 4; i++) - { - pingParams.Ip <<= 8; - pingParams.Ip |= address.get_addr().bytes[i]; - } - SlPingReport_t pingReport; - int result = sl_NetAppPingStart((SlPingStartCommand_t*)&pingParams, SL_AF_INET, - static_cast<SlPingReport_t *>(&pingReport), SimpleLinkPingReport); - if (result == SL_RET_CODE_OK) - { - // Wait for completion. - currentState = Pinging; - int attempts = 1000; - do - { - wait_ms(10); - update(); - } while ((currentState == Pinging) && (--attempts > 0)); - if (attempts == 0) - result = SL_RET_CODE_ABORT; - } - return result; +int CC3100::ping(const SocketAddress & address) { + // Adapter should be connected. + if (currentState != Connected) + return invalidState; + + SlPingStartCommand_t pingParams = { + 1000, // PingIntervalTime + 20, // PingSize + 3000, // PingRequestTimeout + 3, // TotalNumberOfAttempts + 0, // Flags + 0 // Ip + }; + for (int i = 0; i < 4; i++) { + pingParams.Ip <<= 8; + pingParams.Ip |= address.get_addr().bytes[i]; + } + SlPingReport_t pingReport; + int result = sl_NetAppPingStart( + (SlPingStartCommand_t *)&pingParams, SL_AF_INET, + static_cast<SlPingReport_t *>(&pingReport), SimpleLinkPingReport); + if (result == SL_RET_CODE_OK) { + // Wait for completion. + currentState = Pinging; + int attempts = 1000; + do { + wait_ms(10); + update(); + } while ((currentState == Pinging) && (--attempts > 0)); + if (attempts == 0) + result = SL_RET_CODE_ABORT; + } + return result; } -int CC3100::socket_open(nsapi_socket_t *handle, nsapi_protocol_t proto) -{ - int16_t result; - switch (proto) - { - case NSAPI_TCP: - result = sl_Socket(SL_AF_INET, SL_SOCK_STREAM, 0); - break; - - case NSAPI_UDP: - result = sl_Socket(SL_AF_INET, SL_SOCK_DGRAM, 0); - break; - - /*case SL_SEC_SOCKET: - result = sl_Socket(SL_AF_INET, SL_SOCK_STREAM, SL_SEC_SOCKET); - break;*/ - - default: - result = SL_SOC_ERROR; - break; - } - if (result >= 0) - { - *handle = new int16_t(result); - - // Set non-blocking. - SlSockNonblocking_t enableOption = { - 1 // NonblockingEnabled - }; - result = sl_SetSockOpt(*static_cast<int16_t *>(*handle), SL_SOL_SOCKET,SL_SO_NONBLOCKING, - reinterpret_cast<_u8 *>(&enableOption), sizeof(enableOption)); - - if (result < 0) - socket_close(*handle); - } - return result; +int CC3100::socket_open(nsapi_socket_t * handle, nsapi_protocol_t proto) { + int16_t result; + switch (proto) { + case NSAPI_TCP: + result = sl_Socket(SL_AF_INET, SL_SOCK_STREAM, 0); + break; + + case NSAPI_UDP: + result = sl_Socket(SL_AF_INET, SL_SOCK_DGRAM, 0); + break; + + /*case SL_SEC_SOCKET: + result = sl_Socket(SL_AF_INET, SL_SOCK_STREAM, SL_SEC_SOCKET); + break;*/ + + default: + result = SL_SOC_ERROR; + break; + } + if (result >= 0) { + *handle = new int16_t(result); + + // Set non-blocking. + SlSockNonblocking_t enableOption = { + 1 // NonblockingEnabled + }; + result = sl_SetSockOpt( + *static_cast<int16_t *>(*handle), SL_SOL_SOCKET, SL_SO_NONBLOCKING, + reinterpret_cast<_u8 *>(&enableOption), sizeof(enableOption)); + + if (result < 0) + socket_close(*handle); + } + return result; } -int CC3100::socket_set_cert_path(nsapi_socket_t handle, const char * certPath) -{ - // Set CA certificate. - return sl_SetSockOpt(*static_cast<int16_t *>(handle), SL_SOL_SOCKET, SL_SO_SECURE_FILES_CA_FILE_NAME, - certPath, strlen(certPath)); +int CC3100::socket_set_cert_path(nsapi_socket_t handle, const char * certPath) { + // Set CA certificate. + return sl_SetSockOpt(*static_cast<int16_t *>(handle), SL_SOL_SOCKET, + SL_SO_SECURE_FILES_CA_FILE_NAME, certPath, + strlen(certPath)); } -int CC3100::socket_close(nsapi_socket_t handle) -{ - int16_t * castedHandle = static_cast<int16_t *>(handle); - int result = sl_Close(*castedHandle); - delete castedHandle; - return result; +int CC3100::socket_close(nsapi_socket_t handle) { + int16_t * castedHandle = static_cast<int16_t *>(handle); + int result = sl_Close(*castedHandle); + delete castedHandle; + return result; } -int CC3100::socket_bind(nsapi_socket_t handle, const SocketAddress &address) -{ - // TODO: Add IPv6 support - if (address.get_addr().version != NSAPI_IPv4) - return SL_SOC_ERROR; - - SlSockAddrIn_t localAddr = { - AF_INET, // sin_family - sl_Htons(address.get_port()), // sin_port - { // sin_addr - 0 // s_addr - } - }; - for (int i = 4; i > 0; i--) - { - localAddr.sin_addr.s_addr <<= 8; - localAddr.sin_addr.s_addr |= address.get_addr().bytes[i - 1]; - } - return sl_Bind(*static_cast<int16_t *>(handle), reinterpret_cast<SlSockAddr_t *>(&localAddr), sizeof(localAddr)); +int CC3100::socket_bind(nsapi_socket_t handle, const SocketAddress & address) { + // TODO: Add IPv6 support + if (address.get_addr().version != NSAPI_IPv4) + return SL_SOC_ERROR; + + SlSockAddrIn_t localAddr = {AF_INET, // sin_family + sl_Htons(address.get_port()), // sin_port + { // sin_addr + 0 // s_addr + }}; + for (int i = 4; i > 0; i--) { + localAddr.sin_addr.s_addr <<= 8; + localAddr.sin_addr.s_addr |= address.get_addr().bytes[i - 1]; + } + return sl_Bind(*static_cast<int16_t *>(handle), + reinterpret_cast<SlSockAddr_t *>(&localAddr), + sizeof(localAddr)); } -int CC3100::socket_listen(nsapi_socket_t handle, int backlog) -{ - return sl_Listen(*static_cast<int16_t *>(handle), backlog); +int CC3100::socket_listen(nsapi_socket_t handle, int backlog) { + return sl_Listen(*static_cast<int16_t *>(handle), backlog); } -int CC3100::socket_connect(nsapi_socket_t handle, const SocketAddress &address) -{ - // TODO: Add IPv6 support - if (address.get_addr().version != NSAPI_IPv4) - return SL_SOC_ERROR; - - SlSockAddrIn_t addr = { - AF_INET, // sin_family - sl_Htons(address.get_port()), // sin_port - { // sin_addr - 0 // s_addr - } - }; - for (int i = 4; i > 0; i--) - { - addr.sin_addr.s_addr <<= 8; - addr.sin_addr.s_addr |= address.get_addr().bytes[i - 1]; - } - int result; - int attempts = 1000; - do - { - wait_ms(10); - result = sl_Connect(*static_cast<int16_t *>(handle), reinterpret_cast<SlSockAddr_t *>(&addr), sizeof(addr)); - } while ((result == SL_EALREADY) && (--attempts > 0)); - if (result > 0) - result = 0; - return result; +int CC3100::socket_connect(nsapi_socket_t handle, + const SocketAddress & address) { + // TODO: Add IPv6 support + if (address.get_addr().version != NSAPI_IPv4) + return SL_SOC_ERROR; + + SlSockAddrIn_t addr = {AF_INET, // sin_family + sl_Htons(address.get_port()), // sin_port + { // sin_addr + 0 // s_addr + }}; + for (int i = 4; i > 0; i--) { + addr.sin_addr.s_addr <<= 8; + addr.sin_addr.s_addr |= address.get_addr().bytes[i - 1]; + } + int result; + int attempts = 1000; + do { + wait_ms(10); + result = sl_Connect(*static_cast<int16_t *>(handle), + reinterpret_cast<SlSockAddr_t *>(&addr), sizeof(addr)); + } while ((result == SL_EALREADY) && (--attempts > 0)); + if (result > 0) + result = 0; + return result; } -int CC3100::socket_send(nsapi_socket_t handle, const void *data, unsigned size) -{ - return sl_Send(*static_cast<int16_t *>(handle), data, size, 0); +int CC3100::socket_send(nsapi_socket_t handle, const void * data, + unsigned size) { + return sl_Send(*static_cast<int16_t *>(handle), data, size, 0); } -int CC3100::socket_recv(nsapi_socket_t handle, void *data, unsigned size) -{ - int result = sl_Recv(*static_cast<int16_t *>(handle), data, size, 0); - if (result == SL_EAGAIN) - result = NSAPI_ERROR_WOULD_BLOCK; - return result; +int CC3100::socket_recv(nsapi_socket_t handle, void * data, unsigned size) { + int result = sl_Recv(*static_cast<int16_t *>(handle), data, size, 0); + if (result == SL_EAGAIN) + result = NSAPI_ERROR_WOULD_BLOCK; + return result; }
--- a/CC3100.hpp Thu Jun 01 14:21:58 2017 -0500 +++ b/CC3100.hpp Mon Nov 06 18:12:27 2017 -0600 @@ -37,113 +37,125 @@ #include <stddef.h> #include <ctime> #include <string> +#include <DigitalOut.h> +#include <SPI.h> #include <NetworkStack.h> #include <WiFiInterface.h> -#include <SPI.h> -#include <DigitalOut.h> /// CC3100 Wi-Fi station interface for mbed using SPI. -class CC3100 : public NetworkStack, public WiFiInterface -{ +class CC3100 : public NetworkStack, public WiFiInterface { public: - /// SPI bus interface. - class SPI - { - public: - SPI(PinName mosi, PinName miso, PinName sclk, PinName ssel); - void transfer(const uint8_t * txData, size_t dataSize, uint8_t * rxData); - - private: - mbed::SPI spi; - mbed::DigitalOut cs; - }; + /// SPI bus interface. + class SPI { + public: + SPI(PinName mosi, PinName miso, PinName sclk, PinName ssel); + void transfer(const uint8_t * txData, size_t dataSize, uint8_t * rxData); + + private: + mbed::SPI spi; + mbed::DigitalOut cs; + }; - /// CC3100 device state. - enum State - { - Stopped, - Disconnected, - ConnectedWithoutIp, - Connected, - Pinging - }; - - /// Result code occurring when the CC3100 is in an invalid state to perform and operation. - static const int invalidState = -1; + /// CC3100 device state. + enum State { + Stopped, + Disconnected, + ConnectedWithoutIp, + Connected, + Pinging + }; + + /// Result code occurring when the CC3100 is in an invalid state to perform and operation. + static const int invalidState = -1; - /// Retrieve the singleton instance. - static CC3100 & instance(); + /// Retrieve the singleton instance. + static CC3100 & instance(); + + /// Current state of the CC3100. + State state() const; + + /// Start the CC3100 so that nework functionality is available. + int start(); + /// Stop the CC3100 and enter a low power state. + int stop(); + /// Update the networking stack. This should be called regularly to dispatch events. + void update(); + /// Set the current date and time. + int setDateTime(const std::tm & dateTime); - /// Current state of the CC3100. - State state() const; - - /// Start the CC3100 so that nework functionality is available. - int start(); - /// Stop the CC3100 and enter a low power state. - int stop(); - /// Update the networking stack. This should be called regularly to dispatch events. - void update(); - /// Set the current date and time. - int setDateTime(const std::tm & dateTime); - - // WiFi station functionality - virtual int set_credentials(const char * ssid, const char * pass, nsapi_security_t security = NSAPI_SECURITY_NONE); - virtual int set_channel(uint8_t channel) { this->channel = channel; return 0; } - virtual int8_t get_rssi() { return 0; } // Not implemented - virtual int connect(const char * ssid, const char * pass, nsapi_security_t security = NSAPI_SECURITY_NONE, uint8_t channel = 0); - virtual int connect() { return connect(ssid.c_str(), pass.c_str(), security, channel); } - int connect(const char * ssid, const char * username, const char * password); - virtual int disconnect(); - virtual int scan(WiFiAccessPoint * res, unsigned count) { return invalidState; } // Not implemented - - // Network functionality - virtual const char * get_ip_address() { return NULL; } // Not implemented - virtual int gethostbyname(const char *host, SocketAddress *address, nsapi_version_t version = NSAPI_UNSPEC); - int ping(const SocketAddress & address); - virtual NetworkStack *get_stack() { return this; } - - // Socket functionality - virtual int socket_open(nsapi_socket_t *handle, nsapi_protocol_t proto); - int socket_set_cert_path(nsapi_socket_t handle, const char * certPath); - virtual int socket_close(nsapi_socket_t handle); - virtual int socket_bind(nsapi_socket_t handle, const SocketAddress &address); - virtual int socket_listen(nsapi_socket_t handle, int backlog); - virtual int socket_connect(nsapi_socket_t handle, const SocketAddress &address); - virtual int socket_accept(nsapi_socket_t server, nsapi_socket_t *handle, SocketAddress *address = 0) - { - // Not implemented - return invalidState; - } - virtual int socket_send(nsapi_socket_t handle, const void *data, unsigned size); - virtual int socket_recv(nsapi_socket_t handle, void *data, unsigned size); - virtual int socket_sendto(nsapi_socket_t handle, const SocketAddress &address, const void *data, unsigned size) - { - // Not implemented - return invalidState; - } - virtual int socket_recvfrom(nsapi_socket_t handle, SocketAddress *address, void *buffer, unsigned size) - { - // Not implemented - return invalidState; - } - virtual void socket_attach(nsapi_socket_t handle, void (*callback)(void *), void *data) - { - // Not implemented - } - + // WiFi station functionality + virtual int set_credentials(const char * ssid, const char * pass, + nsapi_security_t security = NSAPI_SECURITY_NONE); + virtual int set_channel(uint8_t channel) { + this->channel = channel; + return 0; + } + virtual int8_t get_rssi() { return 0; } // Not implemented + virtual int connect(const char * ssid, const char * pass, + nsapi_security_t security = NSAPI_SECURITY_NONE, + uint8_t channel = 0); + virtual int connect() { + return connect(ssid.c_str(), pass.c_str(), security, channel); + } + int connect(const char * ssid, const char * username, const char * password); + virtual int disconnect(); + virtual int scan(WiFiAccessPoint * res, unsigned count) { + // Not implemented + return invalidState; + } + + // Network functionality + virtual const char * get_ip_address() { return NULL; } // Not implemented + virtual int gethostbyname(const char * host, SocketAddress * address, + nsapi_version_t version = NSAPI_UNSPEC); + int ping(const SocketAddress & address); + virtual NetworkStack * get_stack() { return this; } + + // Socket functionality + virtual int socket_open(nsapi_socket_t * handle, nsapi_protocol_t proto); + int socket_set_cert_path(nsapi_socket_t handle, const char * certPath); + virtual int socket_close(nsapi_socket_t handle); + virtual int socket_bind(nsapi_socket_t handle, const SocketAddress & address); + virtual int socket_listen(nsapi_socket_t handle, int backlog); + virtual int socket_connect(nsapi_socket_t handle, + const SocketAddress & address); + virtual int socket_accept(nsapi_socket_t server, nsapi_socket_t * handle, + SocketAddress * address = 0) { + // Not implemented + return invalidState; + } + virtual int socket_send(nsapi_socket_t handle, const void * data, + unsigned size); + virtual int socket_recv(nsapi_socket_t handle, void * data, unsigned size); + virtual int socket_sendto(nsapi_socket_t handle, + const SocketAddress & address, const void * data, + unsigned size) { + // Not implemented + return invalidState; + } + virtual int socket_recvfrom(nsapi_socket_t handle, SocketAddress * address, + void * buffer, unsigned size) { + // Not implemented + return invalidState; + } + virtual void socket_attach(nsapi_socket_t handle, void (*callback)(void *), + void * data) { + // Not implemented + } + private: - SPI spi; - - std::string ssid; - std::string pass; - nsapi_security_t security; - uint8_t channel; - - CC3100(); - - // Uncopyable - CC3100(const CC3100 &); - const CC3100& operator=(const CC3100 &); + SPI spi; + + std::string ssid; + std::string pass; + nsapi_security_t security; + uint8_t channel; + + CC3100(); + + // Uncopyable + CC3100(const CC3100 &); + const CC3100 & operator=(const CC3100 &); }; #endif
--- a/CC3100_transport.cpp Thu Jun 01 14:21:58 2017 -0500 +++ b/CC3100_transport.cpp Mon Nov 06 18:12:27 2017 -0600 @@ -44,61 +44,52 @@ static mbed::DigitalOut nHIB(nHIB_PIN, 0); static SL_P_EVENT_HANDLER pIrqEventHandler = NULL; -static void* pIrqEventHandlerValue = NULL; +static void * pIrqEventHandlerValue = NULL; -SlFd_t sl_IfOpen(const char *ifName, unsigned long flags) -{ - SlFd_t fd = invalidFd; - if (ifName != NULL) - { - std::sscanf(ifName, "%p", &fd); - } - return fd; +SlFd_t sl_IfOpen(const char * ifName, unsigned long flags) { + SlFd_t fd = invalidFd; + if (ifName != NULL) { + std::sscanf(ifName, "%p", &fd); + } + return fd; } -int sl_IfClose(SlFd_t fd) -{ - return 0; // Success +int sl_IfClose(SlFd_t fd) { + return 0; // Success } -int sl_IfRead(SlFd_t fd, unsigned char *pBuff, int len) -{ - if (fd == invalidFd) - return 0; // Failure - std::memset(pBuff, 0xFF, len); - static_cast<CC3100::SPI *>(fd)->transfer(pBuff, len, pBuff); - return len; // Success +int sl_IfRead(SlFd_t fd, unsigned char * pBuff, int len) { + if (fd == invalidFd) + return 0; // Failure + std::memset(pBuff, 0xFF, len); + static_cast<CC3100::SPI *>(fd)->transfer(pBuff, len, pBuff); + return len; // Success } -int sl_IfWrite(SlFd_t fd, const unsigned char *pBuff, int len) -{ - if (fd == invalidFd) - return 0; // Failure - static_cast<CC3100::SPI *>(fd)->transfer(pBuff, len, NULL); - return len; // Success +int sl_IfWrite(SlFd_t fd, const unsigned char * pBuff, int len) { + if (fd == invalidFd) + return 0; // Failure + static_cast<CC3100::SPI *>(fd)->transfer(pBuff, len, NULL); + return len; // Success } -int sl_IfRegIntHdlr(SL_P_EVENT_HANDLER InterruptHdl , void* pValue) -{ - pIrqEventHandler = InterruptHdl; - pIrqEventHandlerValue = pValue; - return 0; // Success +int sl_IfRegIntHdlr(SL_P_EVENT_HANDLER InterruptHdl, void * pValue) { + pIrqEventHandler = InterruptHdl; + pIrqEventHandlerValue = pValue; + return 0; // Success } -static void interruptHandler(void) -{ - if (pIrqEventHandler != NULL) - pIrqEventHandler(pIrqEventHandlerValue); +static void interruptHandler(void) { + if (pIrqEventHandler != NULL) + pIrqEventHandler(pIrqEventHandlerValue); } -void sl_DeviceEnable(void) -{ - irq.rise(&interruptHandler); - nHIB = 1; +void sl_DeviceEnable(void) { + irq.rise(&interruptHandler); + nHIB = 1; } -void sl_DeviceDisable(void) -{ - irq.rise(NULL); - nHIB = 0; +void sl_DeviceDisable(void) { + irq.rise(NULL); + nHIB = 0; }
--- a/CC3100_transport.h Thu Jun 01 14:21:58 2017 -0500 +++ b/CC3100_transport.h Mon Nov 06 18:12:27 2017 -0600 @@ -43,7 +43,7 @@ \note On each porting or platform the type could be whatever is needed - integer, pointer to structure etc. */ -typedef void* SlFd_t; +typedef void * SlFd_t; /*! \brief type definition for the host interrupt handler @@ -51,7 +51,7 @@ registration of a new interrupt handler \note */ -typedef void (*SL_P_EVENT_HANDLER)(void* pValue); +typedef void (*SL_P_EVENT_HANDLER)(void * pValue); /*! \brief open spi communication port to be used for communicating with a @@ -79,7 +79,7 @@ \note \warning */ -SlFd_t sl_IfOpen(const char *ifName, unsigned long flags); +SlFd_t sl_IfOpen(const char * ifName, unsigned long flags); /*! \brief closes an opened spi communication port @@ -113,7 +113,7 @@ \note \warning */ -int sl_IfRead(SlFd_t fd, unsigned char *pBuff, int len); +int sl_IfRead(SlFd_t fd, unsigned char * pBuff, int len); /*! \brief attempts to write up to len bytes to the SPI channel @@ -138,7 +138,7 @@ the entire buffer write would be completed \warning */ -int sl_IfWrite(SlFd_t fd, const unsigned char *pBuff, int len); +int sl_IfWrite(SlFd_t fd, const unsigned char * pBuff, int len); /*! \brief register an interrupt handler for the host IRQ @@ -157,7 +157,7 @@ \warning */ -int sl_IfRegIntHdlr(SL_P_EVENT_HANDLER InterruptHdl , void* pValue); +int sl_IfRegIntHdlr(SL_P_EVENT_HANDLER InterruptHdl, void * pValue); /*! \brief Enable the Network Processor @@ -178,7 +178,7 @@ */ void sl_DeviceDisable(void); -#ifdef __cplusplus +#ifdef __cplusplus } #endif // __cplusplus
--- a/DS2476.cpp Thu Jun 01 14:21:58 2017 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,126 +0,0 @@ -/******************************************************************************* -* Copyright (C) 2017 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 <I2C.h> -#include <wait_api.h> -#include "DS2476.hpp" - -// DS2476 additional commands. -enum Command -{ - GenerateEcdsaSignature = 0x1E, - ComputeSha2UniqueSecret = 0x55, - ComputeSha2Hmac = 0x2D -}; - -DS2476::CmdResult DS2476::generateEcdsaSignature(KeyNum keyNum, Signature & signature) -{ - if (keyNum == KeyNumS) - { - return InvalidParameterError; - } - - Buffer buffer; - buffer.push_back(keyNum); - CmdResult result = writeCommand(GenerateEcdsaSignature, buffer); - if (result == Success) - { - wait_ms(generateEcdsaSignatureTimeMs); - result = readResponse(buffer); - if (result == Success) - { - if (buffer.size() == (1 + signature.r.size() + signature.s.size())) - { - result = convertResultByte(buffer[0]); - Buffer::const_iterator begin = buffer.begin() + 1; - Buffer::const_iterator end = begin + signature.s.size(); - std::copy(begin, end, signature.s.begin()); - begin = end; - end = begin + signature.r.size(); - std::copy(begin, end, signature.r.begin()); - } - else - { - result = CommunicationError; - } - } - } - return result; -} - -DS2476::CmdResult DS2476::computeSha2UniqueSecret(SecretNum msecretNum) -{ - Buffer buffer; - buffer.push_back(msecretNum << 4); - CmdResult result = writeCommand(ComputeSha2UniqueSecret, buffer); - if (result == Success) - { - wait_ms(sha256ComputationTimeMs); - result = readResponse(buffer); - if (result == Success) - { - if (buffer.size() == 1) - { - convertResultByte(buffer[0]); - } - else - { - result = CommunicationError; - } - } - } - return result; -} - -DS2476::CmdResult DS2476::computeSha2Hmac(HMAC & hmac) -{ - Buffer buffer; - CmdResult result = writeCommand(ComputeSha2Hmac, buffer); - if (result == Success) - { - wait_ms(sha256ComputationTimeMs); - result = readResponse(buffer); - if (result == Success) - { - if (buffer.size() == (1 + hmac.size())) - { - result = convertResultByte(buffer[0]); - std::copy(buffer.begin() + 1, buffer.end(), hmac.begin()); - } - else - { - result = CommunicationError; - } - } - } - return result; -}
--- a/DS2476.hpp Thu Jun 01 14:21:58 2017 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,58 +0,0 @@ -/******************************************************************************* -* Copyright (C) 2017 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 DS2476_HPP -#define DS2476_HPP - -#include "DS28C36.hpp" - -/// Interface to the DS2476 coprocessor. -class DS2476 : public DS28C36 -{ -public: - explicit DS2476(mbed::I2C & i2c, uint8_t i2cAddress = 0x76) : DS28C36(i2c, i2cAddress) { } - - /// Generate ECDSA signature. - /// @param keyNum Private key to use to create signature. Key S cannot be used with this command. - /// @param[out] signature Computed signature. - CmdResult generateEcdsaSignature(KeyNum keyNum, Signature & signature); - - /// Compute unique SHA2 secret. - /// @param msecretNum Master secret to use in computation. - CmdResult computeSha2UniqueSecret(SecretNum msecretNum); - - /// Compute SHA2 HMAC. - /// @param[out] hmac Computed HMAC. - CmdResult computeSha2Hmac(HMAC & hmac); -}; - -#endif
--- a/DS28C36.cpp Thu Jun 01 14:21:58 2017 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,694 +0,0 @@ -/******************************************************************************* -* Copyright (C) 2017 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 <I2C.h> -#include <wait_api.h> -#include "RomId.h" -#include "DS28C36.hpp" - -// DS28C36 commands. -enum Command -{ - WriteMemory = 0x96, - ReadMemory = 0x69, - WriteBuffer = 0x87, - ReadBuffer = 0x5A, - ReadPageProtection = 0xAA, - SetPageProtection = 0xC3, - DecrementCounter = 0xC9, - ReadRng = 0xD2, - EncryptedReadMemory = 0x4B, - ComputeAndReadPathAuthentication = 0xA5, - AuthenticatedSha2WriteMemory = 0x99, - ComputeAndLockSha2Secret = 0x3C, - GenerateEcc256KeyPair = 0xCB, - ComputeMultiblockHash = 0x33, - VerifyEcdsaSignature = 0x59, - AuthenticateEcdsaPublicKey = 0xA8, - AuthenticatedEcdsaWriteMemory = 0x89 -}; - -static const int i2cWriteOk = 1; - -DS28C36::CmdResult DS28C36::writeMemory(int pageNum, const Page & page) -{ - if (pageNum < UserData0 || pageNum >= numPages) - { - return InvalidParameterError; - } - - Buffer buffer; - buffer.reserve(1 + page.size()); - buffer.push_back(pageNum); - buffer.insert(buffer.end(), page.begin(), page.end()); - CmdResult result = writeCommand(WriteMemory, buffer); - if (result == Success) - { - wait_ms(writeMemoryTimeMs); - result = readResponse(buffer); - if (result == Success) - { - if (buffer.size() == 1) - { - result = convertResultByte(buffer[0]); - } - else - { - result = CommunicationError; - } - } - } - return result; -} - -DS28C36::CmdResult DS28C36::readMemory(int pageNum, Page & page) -{ - if (pageNum < UserData0 || pageNum >= numPages) - { - return InvalidParameterError; - } - - Buffer buffer; - buffer.push_back(pageNum); - CmdResult result = writeCommand(ReadMemory, buffer); - if (result == Success) - { - wait_ms(readMemoryTimeMs); - result = readResponse(buffer); - if (result == Success) - { - if (buffer.size() == (1 + page.size())) - { - result = convertResultByte(buffer[0]); - std::copy(buffer.begin() + 1, buffer.end(), page.begin()); - } - else - { - result = CommunicationError; - } - } - } - return result; -} - -DS28C36::CmdResult DS28C36::writeBuffer(const Buffer & data) -{ - return writeCommand(WriteBuffer, data); -} - -DS28C36::CmdResult DS28C36::readBuffer(Buffer & data) -{ - CmdResult result = writeCommand(ReadBuffer, Buffer()); - if (result == Success) - { - result = readResponse(data); - } - return result; -} - -DS28C36::CmdResult DS28C36::readPageProtection(int pageNum, PageProtection & protection) -{ - if (pageNum < UserData0 || pageNum >= numPages) - { - return InvalidParameterError; - } - - Buffer buffer; - buffer.push_back(pageNum); - CmdResult result = writeCommand(ReadPageProtection, buffer); - if (result == Success) - { - wait_ms(readMemoryTimeMs); - result = readResponse(buffer); - if (result == Success) - { - if (buffer.size() == 1) - { - protection.setStatusByte(buffer[0]); - } - else - { - result = CommunicationError; - } - } - } - return result; -} - -DS28C36::CmdResult DS28C36::setPageProtection(int pageNum, const PageProtection & protection) -{ - if (pageNum < UserData0 || pageNum >= numPages) - { - return InvalidParameterError; - } - - Buffer buffer; - buffer.push_back(pageNum); - buffer.push_back(protection.statusByte()); - CmdResult result = writeCommand(SetPageProtection, buffer); - if (result == Success) - { - wait_ms(writeMemoryTimeMs); - result = readResponse(buffer); - if (result == Success) - { - if (buffer.size() == 1) - { - result = convertResultByte(buffer[0]); - } - else - { - result = CommunicationError; - } - } - } - return result; -} - -DS28C36::CmdResult DS28C36::decrementCounter() -{ - Buffer buffer; - CmdResult result = writeCommand(DecrementCounter, buffer); - if (result == Success) - { - wait_ms(writeMemoryTimeMs); - result = readResponse(buffer); - if (result == Success) - { - if (buffer.size() == 1) - { - result = convertResultByte(buffer[0]); - } - else - { - result = CommunicationError; - } - } - } - return result; -} - -DS28C36::CmdResult DS28C36::readRng(int numBytes, Buffer & data) -{ - if ((numBytes < 1) || (numBytes > 64)) - { - return InvalidParameterError; - } - - data.clear(); - data.push_back(numBytes - 1); - CmdResult result = writeCommand(ReadRng, data); - if (result == Success) - { - wait_ms(sha256ComputationTimeMs); - result = readResponse(data); - if (result == Success) - { - if (data.size() != static_cast<Buffer::size_type>(numBytes)) - { - result = CommunicationError; - } - } - } - return result; -} - -DS28C36::CmdResult DS28C36::encryptedReadMemory(int pageNum, SecretNum secretNum, EncryptedPage & page) -{ - if (pageNum < UserData0 || pageNum >= numPages) - { - return InvalidParameterError; - } - - Buffer buffer; - buffer.push_back((secretNum << 6) | pageNum); - CmdResult result = writeCommand(EncryptedReadMemory, buffer); - if (result == Success) - { - wait_ms(readMemoryTimeMs + sha256ComputationTimeMs); - result = readResponse(buffer); - if (result == Success) - { - if (buffer.size() == (1 + page.challenge.size() + page.data.size())) - { - result = convertResultByte(buffer[0]); - Buffer::const_iterator begin = buffer.begin() + 1; - Buffer::const_iterator end = begin + page.challenge.size(); - std::copy(begin, end, page.challenge.begin()); - begin = end; - end = begin + page.data.size(); - std::copy(begin, end, page.data.begin()); - } - else - { - result = CommunicationError; - } - } - } - return result; -} - -DS28C36::CmdResult DS28C36::computeAndReadPageAuthentication(int pageNum, AuthType authType, Buffer & data) -{ - if (pageNum < UserData0 || pageNum >= numPages) - { - return InvalidParameterError; - } - - data.clear(); - data.push_back((authType << 5) | pageNum); - CmdResult result = writeCommand(ComputeAndReadPathAuthentication, data); - if (result == Success) - { - wait_ms(readMemoryTimeMs + ((authType < EcdsaWithKeyA) ? sha256ComputationTimeMs : generateEcdsaSignatureTimeMs)); - result = readResponse(data); - if (result == Success) - { - if (data.size() > 1) - { - result = convertResultByte(data[0]); - data.erase(data.begin()); - } - else - { - result = CommunicationError; - } - } - } - return result; -} - -DS28C36::CmdResult DS28C36::computeAndReadEcdsaPageAuthentication(int pageNum, KeyNum keyNum, Signature & signature) -{ - AuthType authType; - switch (keyNum) - { - case KeyNumA: - authType = EcdsaWithKeyA; - break; - case KeyNumB: - authType = EcdsaWithKeyB; - break; - case KeyNumC: - authType = EcdsaWithKeyC; - break; - default: - return InvalidParameterError; - } - Buffer data; - CmdResult result = computeAndReadPageAuthentication(pageNum, authType, data); - if (result == Success) - { - Buffer::const_iterator begin = data.begin(); - Buffer::const_iterator end = begin + signature.s.size(); - std::copy(begin, end, signature.s.begin()); - begin = end; - end = begin + signature.r.size(); - std::copy(begin, end, signature.r.begin()); - } - return result; -} - -DS28C36::CmdResult DS28C36::computeAndReadHmacPageAuthentication(int pageNum, SecretNum secretNum, HMAC & hmac) -{ - AuthType authType; - switch (secretNum) - { - case SecretNumA: - authType = HmacWithSecretA; - break; - case SecretNumB: - authType = HmacWithSecretB; - break; - case SecretNumS: - authType = HmacWithSecretS; - break; - default: - return InvalidParameterError; - } - Buffer data; - CmdResult result = computeAndReadPageAuthentication(pageNum, authType, data); - if (result == Success) - { - std::copy(data.begin(), data.end(), hmac.begin()); - } - return result; -} - -DS28C36::CmdResult DS28C36::authenticatedSha2WriteMemory(int pageNum, SecretNum secretNum, const Page & page) -{ - if (pageNum < UserData0 || pageNum >= numPages) - { - return InvalidParameterError; - } - - Buffer buffer; - buffer.reserve(1 + page.size()); - buffer.push_back((secretNum << 6) | pageNum); - buffer.insert(buffer.end(), page.begin(), page.end()); - CmdResult result = writeCommand(AuthenticatedSha2WriteMemory, buffer); - if (result == Success) - { - wait_ms(writeMemoryTimeMs + (2 * sha256ComputationTimeMs)); - result = readResponse(buffer); - if (buffer.size() == 1) - { - result = convertResultByte(buffer[0]); - } - else - { - result = CommunicationError; - } - } - return result; -} - -DS28C36::CmdResult DS28C36::computeAndLockSha2Secret(int pageNum, SecretNum msecretNum, SecretNum dsecretNum, bool writeProtectEnable) -{ - // User pages only - if (pageNum < UserData0 || pageNum > UserData15) - { - return InvalidParameterError; - } - - Buffer buffer; - buffer.push_back((dsecretNum << 6) | (msecretNum << 4) | pageNum); - buffer.push_back(writeProtectEnable ? 0x80 : 0x00); - CmdResult result = writeCommand(ComputeAndLockSha2Secret, buffer); - if (result == Success) - { - wait_ms(sha256ComputationTimeMs + ((writeProtectEnable ? 2 : 1) * writeMemoryTimeMs)); - result = readResponse(buffer); - if (buffer.size() == 1) - { - result = convertResultByte(buffer[0]); - } - else - { - result = CommunicationError; - } - } - return result; -} - -DS28C36::CmdResult DS28C36::generateEcc256KeyPair(KeyNum keyNum, bool writeProtectEnable) -{ - if (keyNum == KeyNumS) - { - return InvalidParameterError; - } - - Buffer buffer; - uint8_t parameter = keyNum; - if (writeProtectEnable) - { - parameter |= 0x80; - } - buffer.push_back(parameter); - CmdResult result = writeCommand(GenerateEcc256KeyPair, buffer); - if (result == Success) - { - wait_ms(generateEccKeyPairTimeMs); - result = readResponse(buffer); - if (result == Success) - { - if (buffer.size() == 1) - { - result = convertResultByte(buffer[0]); - } - else - { - result = CommunicationError; - } - } - } - return result; -} - -DS28C36::CmdResult DS28C36::computeMultiblockHash(bool firstBlock, bool lastBlock, const Buffer & data) -{ - uint8_t parameter = 0; - if (firstBlock) - { - parameter |= 0x40; - } - if (lastBlock) - { - parameter |= 0x80; - } - Buffer buffer; - buffer.reserve(1 + data.size()); - buffer.push_back(parameter); - buffer.insert(buffer.end(), data.begin(), data.end()); - CmdResult result = writeCommand(ComputeMultiblockHash, buffer); - if (result == Success) - { - wait_ms(sha256ComputationTimeMs); - result = readResponse(buffer); - if (result == Success) - { - if (buffer.size() == 1) - { - result = convertResultByte(buffer[0]); - } - else - { - result = CommunicationError; - } - } - } - return result; -} - -DS28C36::CmdResult DS28C36::verifyEcdsaSignature(KeyNum keyNum, HashType hashType, const Signature & signature, PioState pioa, PioState piob) -{ - uint8_t parameter = keyNum | (hashType << 2); - if (pioa != Unchanged) - { - parameter |= 0x20; - } - if (pioa == Conducting) - { - parameter |= 0x10; - } - if (piob != Unchanged) - { - parameter |= 0x80; - } - if (piob == Conducting) - { - parameter |= 0x40; - } - Buffer buffer; - buffer.reserve(1 + signature.r.size() + signature.s.size()); - buffer.push_back(parameter); - buffer.insert(buffer.end(), signature.r.begin(), signature.r.end()); - buffer.insert(buffer.end(), signature.s.begin(), signature.s.end()); - CmdResult result = writeCommand(VerifyEcdsaSignature, buffer); - if (result == Success) - { - wait_ms(verifyEsdsaSignatureOrComputeEcdhTimeMs + ((hashType == DataInBuffer) ? sha256ComputationTimeMs : 0)); - result = readResponse(buffer); - if (result == Success) - { - if (buffer.size() == 1) - { - result = convertResultByte(buffer[0]); - } - else - { - result = CommunicationError; - } - } - } - return result; -} - -DS28C36::CmdResult DS28C36::authenticateEcdsaPublicKey(bool authWrites, bool ecdh, KeyNum keyNum, int csOffset, const Signature & signature) -{ - if (((keyNum != KeyNumA) && (keyNum != KeyNumB)) || (csOffset < 0) || (csOffset > 31)) - { - return InvalidParameterError; - } - - uint8_t parameter = (csOffset << 3) | (keyNum << 2); - if (ecdh) - { - parameter |= 0x02; - } - if (authWrites) - { - parameter |= 0x01; - } - Buffer buffer; - buffer.reserve(1 + signature.r.size() + signature.s.size()); - buffer.push_back(parameter); - buffer.insert(buffer.end(), signature.r.begin(), signature.r.end()); - buffer.insert(buffer.end(), signature.s.begin(), signature.s.end()); - CmdResult result = writeCommand(AuthenticateEcdsaPublicKey, buffer); - if (result == Success) - { - wait_ms((ecdh ? 2 : 1) * verifyEsdsaSignatureOrComputeEcdhTimeMs); - result = readResponse(buffer); - if (result == Success) - { - if (buffer.size() == 1) - { - result = convertResultByte(buffer[0]); - } - else - { - result = CommunicationError; - } - } - } - return result; -} - -DS28C36::CmdResult DS28C36::authenticatedEcdsaWriteMemory(int pageNum, const Page & page) -{ - if (pageNum < UserData0 || pageNum >= numPages) - { - return InvalidParameterError; - } - - Buffer buffer; - buffer.reserve(1 + page.size()); - buffer.push_back(pageNum); - buffer.insert(buffer.end(), page.begin(), page.end()); - CmdResult result = writeCommand(AuthenticatedEcdsaWriteMemory, buffer); - if (result == Success) - { - wait_ms(verifyEsdsaSignatureOrComputeEcdhTimeMs + writeMemoryTimeMs + sha256ComputationTimeMs); - result = readResponse(buffer); - if (result == Success) - { - if (buffer.size() == 1) - { - result = convertResultByte(buffer[0]); - } - else - { - result = CommunicationError; - } - } - } - return result; -} - -DS28C36::CmdResult DS28C36::convertResultByte(uint8_t resultByte) -{ - CmdResult result; - switch (resultByte) - { - case Success: - case ProtectionError: - case InvalidParameterError: - case InvalidSequenceError: - case InvalidEcdsaInputOrResultError: - case AuthenticationError: - result = static_cast<CmdResult>(resultByte); - break; - - default: - result = CommunicationError; - break; - } - return result; -} - -DS28C36::CmdResult DS28C36::writeCommand(uint8_t command, const Buffer & parameters) -{ - m_i2c.start(); - if (m_i2c.write(m_i2cAddress) != i2cWriteOk) - { - m_i2c.stop(); - return CommunicationError; - } - if (m_i2c.write(command) != i2cWriteOk) - { - m_i2c.stop(); - return CommunicationError; - } - if (!parameters.empty()) - { - if (m_i2c.write(parameters.size()) != i2cWriteOk) - { - m_i2c.stop(); - return CommunicationError; - } - for (Buffer::const_iterator it = parameters.begin(); it != parameters.end(); it++) - { - if (m_i2c.write(*it) != i2cWriteOk) - { - m_i2c.stop(); - return CommunicationError; - } - } - } - m_i2c.stop(); - return Success; -} - -DS28C36::CmdResult DS28C36::readResponse(Buffer & response) -{ - CmdResult result; - m_i2c.start(); - if (m_i2c.write(m_i2cAddress | 1) == i2cWriteOk) - { - uint8_t length = m_i2c.read(1); - response.clear(); - response.reserve(length); - for (uint8_t i = 0; i < length; i++) - { - response.push_back(m_i2c.read(i < (length - 1))); - } - result = Success; - } - else - { - result = CommunicationError; - } - m_i2c.stop(); - return result; -} - -DS28C36::CmdResult DS28C36::readRomId(DS28C36 & ds28c36, OneWire::RomId & romId) -{ - Page page; - CmdResult result = ds28c36.readMemory(DS28C36::RomOptions, page); - if (result == Success) - { - std::copy(page.end() - romId.buffer.size(), page.end(), romId.buffer.begin()); - } - return result; -}
--- a/DS28C36.hpp Thu Jun 01 14:21:58 2017 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,335 +0,0 @@ -/******************************************************************************* -* Copyright (C) 2017 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 DS28C36_HPP -#define DS28C36_HPP - -#include <vector> -#include "array.h" - -namespace mbed { class I2C; } -namespace OneWire { class RomId; } - -/// Interface to the DS28C36 authenticator. -class DS28C36 -{ -public: - /// Device command results. - enum CmdResult - { - Success = 0xAA, - ProtectionError = 0x55, - InvalidParameterError = 0x77, - InvalidSequenceError = 0x33, - InvalidEcdsaInputOrResultError = 0x22, - AuthenticationError = 0x00, - CommunicationError = 0xFF ///< Special code for I2C communication error. - }; - - /// Device memory pages. - enum PageNum - { - UserData0 = 0, - UserData1, - UserData2, - UserData3, - UserData4, - UserData5, - UserData6, - UserData7, - UserData8, - UserData9, - UserData10, - UserData11, - UserData12, - UserData13, - UserData14, - UserData15, - PublicKeyAX, - PublicKeyAY, - PublicKeyBX, - PublicKeyBY, - PublicKeyCX, - PublicKeyCY, - PrivateKeyA, - PrivateKeyB, - PrivateKeyC, - SecretA, - SecretB, - DecrementCounter, - RomOptions, - GpioControl, - PublicKeySX, - PublicKeySY - }; - - /// Available keys for ECDSA operations. - enum KeyNum - { - KeyNumA = 0, - KeyNumB = 1, - KeyNumC = 2, - KeyNumS = 3 - }; - - /// Available secrets for HMAC operations. - enum SecretNum - { - SecretNumA = 0, - SecretNumB = 1, - SecretNumS = 2 - }; - - /// Data hash type when verifying an ECDSA signature. - enum HashType - { - HashInBuffer = 0, ///< Hash is loaded in the buffer. - DataInBuffer = 1, ///< Compute hash from data loaded in the buffer. - THASH = 2 ///< Use THASH from Compute Multiblock Hash command. - }; - - /// Available PIO states when verifying an ECDSA signature. - enum PioState - { - Unchanged, - Conducting, - HighImpedance - }; - - typedef OneWire::array<uint8_t, 32> Page; ///< Holds a device memory page. - typedef OneWire::array<uint8_t, 32> HMAC; ///< Holds a computed HMAC. - typedef std::vector<uint8_t> Buffer; ///< Holds a variable length device buffer. - - /// Holds a computed ECDSA signature. - struct Signature - { - Page r; - Page s; - }; - - /// Holds an encrypted device memory page. - struct EncryptedPage - { - OneWire::array<uint8_t, 8> challenge; - Page data; - }; - - /// Holds the protection status of a memory page. - class PageProtection - { - public: - /// Page protection types. - enum Protection - { - RP = 0x01, ///< Read protection. - WP = 0x02, ///< Write protection. - EM = 0x04, ///< EPROM emulation mode. - APH = 0x08, ///< Authentication write protection HMAC. - EPH = 0x10, ///< Encryption and authenticated write protection HMAC. - AUTH = 0x20, ///< Public Key C is set to authority public key. - ECH = 0x40, ///< Encrypted read and write using shared key from ECDH. - ECW = 0x80 ///< Authentication write protection ECDSA. - }; - - explicit PageProtection(uint8_t status = 0x00) : m_status(status) { } - - /// @{ - /// Byte representation used by the device. - uint8_t statusByte() const { return m_status; } - void setStatusByte(uint8_t status) { m_status = status; } - /// @} - - /// @{ - /// Get/set whether a protection type is enabled. - bool protectionEnabled(Protection protection) const - { - return ((m_status & protection) == protection); - } - void setProtectionEnabled(Protection protection, bool enabled) - { - if (enabled) { m_status |= protection; } - else { m_status &= ~protection; } - } - /// @} - - bool operator==(const PageProtection & rhs) const { return this->m_status == rhs.m_status; } - bool operator!=(const PageProtection & rhs) const { return !operator==(rhs); } - - private: - uint8_t m_status; - }; - - explicit DS28C36(mbed::I2C & i2c, uint8_t i2cAddress = 0x36) : - m_i2c(i2c), m_i2cAddress(i2cAddress) { } - - /// Write memory with no protection. - /// @param pageNum Number of page to write. - /// @param page Data to write. - CmdResult writeMemory(int pageNum, const Page & page); - - /// Read memory with no protection. - /// @param pageNum Number of page to read. - /// @param[out] page Data that was read. - CmdResult readMemory(int pageNum, Page & page); - - /// Write the temporary buffer. - /// @param data Data to write. - CmdResult writeBuffer(const Buffer & data); - - /// Read the temporary buffer. - /// @param[out] data Data that was read. - CmdResult readBuffer(Buffer & data); - - /// Read the protection settings of a page. - /// @param pageNum Number of page to read. - /// @param[out] protection Protection that was read. - CmdResult readPageProtection(int pageNum, PageProtection & protection); - - /// Set the protection settings of a page. - /// @param pageNum Number of page to write. - /// @param protection Protection to write. - CmdResult setPageProtection(int pageNum, const PageProtection & protection); - - /// Decrement the decrement-only counter. - CmdResult decrementCounter(); - - /// Read a block of random data from the RNG. - /// @param numBytes Number of bytes to read from 1 to 64. - /// @param[out] data Random data from RNG. - CmdResult readRng(int numBytes, Buffer & data); - - /// Read memory with encryption. - /// @param pageNum Number of page to read from. - /// @param secretNum Secret to use for encryption. - /// @param[out] page Data that was read. - CmdResult encryptedReadMemory(int pageNum, SecretNum secretNum, EncryptedPage & page); - - /// Compute and read page authentication with ECDSA. - /// @param pageNum Number of page to authenticate. - /// @param keyNum Private key to use for authentication. Key S cannot be used with this command. - /// @param[out] signature Computed page signature. - CmdResult computeAndReadEcdsaPageAuthentication(int pageNum, KeyNum keyNum, Signature & signature); - - /// Compute and read page authentication with HMAC. - /// @param pageNum Number of page to authenticate. - /// @param secretNum Secret to use for authentication. - /// @param[out] hmac Computed page HMAC. - CmdResult computeAndReadHmacPageAuthentication(int pageNum, SecretNum secretNum, HMAC & hmac); - - /// Write with SHA2 authentication. - /// @param pageNum Number of page to write. - /// @param secretNum Secret to use for authentication. - /// @param page Data to write. - CmdResult authenticatedSha2WriteMemory(int pageNum, SecretNum secretNum, const Page & page); - - /// Compute SHA2 secret and optionally lock. - /// @param pageNum Number of page to use in computation. - /// @param msecretNum Master secret to use in computation. - /// @param dsecretNum Destination secret to receive the computation result. - /// @param writeProtectEnable True to lock the destination secret against further writes. - CmdResult computeAndLockSha2Secret(int pageNum, SecretNum msecretNum, SecretNum dsecretNum, bool writeProtectEnable); - - /// Generate a new ECDSA key pair. - /// @param keyNum Key to generate. Key S cannot be used with this command. - /// @param writeProtectEnable True to lock the key against further writes. - CmdResult generateEcc256KeyPair(KeyNum keyNum, bool writeProtectEnable); - - /// Compute a hash over multiple blocks. - /// @param firstBlock True if this is the first block being hashed. - /// @param lastBlock True if thisis the last block being hashed. - /// @param data Data block to hash. Length should be 64 bytes unless this is the last block. - CmdResult computeMultiblockHash(bool firstBlock, bool lastBlock, const Buffer & data); - - /// Verify ECDSA signature. - /// @param keyNum Public key to use for verification. - /// @param hashType Source of the data hash input. - /// @param signature Signature to verify. - /// @param pioa New state of PIOA if verification successful. - /// @param piob New state of PIOB if verification successful. - CmdResult verifyEcdsaSignature(KeyNum keyNum, HashType hashType, const Signature & signature, PioState pioa = Unchanged, PioState piob = Unchanged); - - /// Authenticate a public key for authenticated writes or encrypted reads with ECDH. - /// @param authWrites True to select authentication for writes. - /// @param ecdh True to select ECDH key exchange. - /// @param keyNum Private key to use for ECDH key exchange. Key A or B can be selected. - /// @param csOffset Certificate customization field ending offset in buffer. - /// @param signature Signature to use for authentication of public key S. - CmdResult authenticateEcdsaPublicKey(bool authWrites, bool ecdh, KeyNum keyNum, int csOffset, const Signature & signature); - - /// Write with ECDSA authentication. - /// @param pageNum Number of page to write. - /// @param page Data to write. - CmdResult authenticatedEcdsaWriteMemory(int pageNum, const Page & page); - - /// Read the device ROM ID using the Read Memory command. - /// @param ds28c36 Device to read. - /// @param[out] romId Read ROM ID valid when operation is successful. - static CmdResult readRomId(DS28C36 & ds28c36, OneWire::RomId & romId); - -protected: - // Timing constants. - static const int generateEcdsaSignatureTimeMs = 50; - static const int generateEccKeyPairTimeMs = 100; - static const int verifyEsdsaSignatureOrComputeEcdhTimeMs = 150; - static const int sha256ComputationTimeMs = 3; - static const int readMemoryTimeMs = /*1*/ 2; - static const int writeMemoryTimeMs = 15; - - static CmdResult convertResultByte(uint8_t resultByte); - - CmdResult writeCommand(uint8_t command, const Buffer & parameters); - CmdResult readResponse(Buffer & response); - -private: - enum AuthType - { - HmacWithSecretA = 0, - HmacWithSecretB = 1, - HmacWithSecretS = 2, - EcdsaWithKeyA = 3, - EcdsaWithKeyB = 4, - EcdsaWithKeyC = 5 - }; - - static const int numPages = 32; - - mbed::I2C & m_i2c; - uint8_t m_i2cAddress; - - /// Compute any type of authentication on page. - /// @param pageNum Number of page to authenticate. - /// @param authType Method to use to compute authentication. - /// @param[out] data Raw computed page authentication. - CmdResult computeAndReadPageAuthentication(int pageNum, AuthType authType, Buffer & data); -}; - -#endif
--- a/Display.cpp Thu Jun 01 14:21:58 2017 -0500 +++ b/Display.cpp Mon Nov 06 18:12:27 2017 -0600 @@ -38,65 +38,58 @@ static const int height = 64; /// @} -Display::Display(PinName mosi, PinName miso, PinName sclk, PinName ssel, PinName a0) : - m_canvas(width, height), spi(mosi, miso, sclk), cs(ssel, 1), a0(a0, 0) -{ - spi.format(8, 3); // CPOL = 1, CPHA = 1 +Display::Display(PinName mosi, PinName miso, PinName sclk, PinName ssel, + PinName a0) + : m_canvas(width, height), spi(mosi, miso, sclk), cs(ssel, 1), a0(a0, 0) { + spi.format(8, 3); // CPOL = 1, CPHA = 1 } -void Display::initialize() -{ - sendCommand(0xA0); - sendCommand(0xAE); - sendCommand(0xC0); - sendCommand(0xA2); - sendCommand(0x2F); - sendCommand(0x26); - sendCommand(0x81); - sendCommand(0x11); - sendCommand(0xAF); +void Display::initialize() { + sendCommand(0xA0); + sendCommand(0xAE); + sendCommand(0xC0); + sendCommand(0xA2); + sendCommand(0x2F); + sendCommand(0x26); + sendCommand(0x81); + sendCommand(0x11); + sendCommand(0xAF); } -void Display::update() -{ - const int rowsPerPage = 8; - const int pages = height / rowsPerPage; - sendCommand(0xAE); - sendCommand(0x40); - for (int page = 0; page < pages; page++) - { - sendCommand(0xB0 + static_cast<uint8_t>(page)); - sendCommand(0x10); - sendCommand(0x00); - for (int column = 0; column < width; column++) - { - uint8_t segment = 0; - for (int pixel = 0; pixel < rowsPerPage; pixel++) - { - segment <<= 1; - if (m_canvas.pixelEnabled(column, ((pages - 1 - page) * rowsPerPage) + pixel)) - { - segment |= 1; - } - } - sendData(segment); +void Display::update() { + const int rowsPerPage = 8; + const int pages = height / rowsPerPage; + sendCommand(0xAE); + sendCommand(0x40); + for (int page = 0; page < pages; page++) { + sendCommand(0xB0 + static_cast<uint8_t>(page)); + sendCommand(0x10); + sendCommand(0x00); + for (int column = 0; column < width; column++) { + uint8_t segment = 0; + for (int pixel = 0; pixel < rowsPerPage; pixel++) { + segment <<= 1; + if (m_canvas.pixelEnabled(column, + ((pages - 1 - page) * rowsPerPage) + pixel)) { + segment |= 1; } + } + sendData(segment); } - sendCommand(0xAF); + } + sendCommand(0xAF); } -void Display::sendCommand(uint8_t command) -{ - cs = 0; - a0 = 0; - spi.write(command); - cs = 1; +void Display::sendCommand(uint8_t command) { + cs = 0; + a0 = 0; + spi.write(command); + cs = 1; } -void Display::sendData(uint8_t data) -{ - cs = 0; - a0 = 1; - spi.write(data); - cs = 1; +void Display::sendData(uint8_t data) { + cs = 0; + a0 = 1; + spi.write(data); + cs = 1; }
--- a/Display.hpp Thu Jun 01 14:21:58 2017 -0500 +++ b/Display.hpp Mon Nov 06 18:12:27 2017 -0600 @@ -34,34 +34,34 @@ #define DISPLAY_HPP #include <stdint.h> +#include <DigitalOut.h> #include <SPI.h> -#include <DigitalOut.h> #include "Bitmap.hpp" /// Interface to the SPI LCD module. -class Display -{ +class Display { public: - Display(PinName mosi, PinName miso, PinName sclk, PinName ssel, PinName a0); - - /// Initializes the display to a known configuration. Call before other operations. - void initialize(); - - Bitmap & canvas() { return m_canvas; } - const Bitmap & canvas() const { return m_canvas; } - - /// Updates the display with the specified bitmap. - /// @param canvas Bitmap to display which should typically match the width and height dimensions. - void update(); + Display(PinName mosi, PinName miso, PinName sclk, PinName ssel, PinName a0); + + /// Initializes the display to a known configuration. Call before other operations. + void initialize(); + + Bitmap & canvas() { return m_canvas; } + const Bitmap & canvas() const { return m_canvas; } + + /// Updates the display with the specified bitmap. + /// @param canvas + /// Bitmap to display which should typically match the width and height dimensions. + void update(); private: - Bitmap m_canvas; - mbed::SPI spi; - mbed::DigitalOut cs; - mbed::DigitalOut a0; - - void sendCommand(uint8_t command); - void sendData(uint8_t data); + Bitmap m_canvas; + mbed::SPI spi; + mbed::DigitalOut cs; + mbed::DigitalOut a0; + + void sendCommand(uint8_t command); + void sendData(uint8_t data); }; #endif
--- a/DisplayGraphicWindow.cpp Thu Jun 01 14:21:58 2017 -0500 +++ b/DisplayGraphicWindow.cpp Mon Nov 06 18:12:27 2017 -0600 @@ -30,51 +30,48 @@ * ownership rights. *******************************************************************************/ +#include "MakeFunction.hpp" #include "WindowManager.hpp" #include "DisplayGraphicWindow.hpp" -void DisplayGraphicWindow::returnClicked() -{ - if (windowManager() != NULL) - { - windowManager()->pop(); - } +void DisplayGraphicWindow::returnClicked(Button *) { + if (windowManager() != NULL) { + windowManager()->pop(); + } } -DisplayGraphicWindow::DisplayGraphicWindow(std::auto_ptr<Graphic> & displayGraphic) -{ - setDisplayGraphic(displayGraphic); - m_returnButton.setParent(this); - m_returnButton.setText("Return"); - m_returnButton.setClickedHandler(Button::EventHandler(this, &DisplayGraphicWindow::returnClicked)); - m_returnButton.setFocused(); +DisplayGraphicWindow::DisplayGraphicWindow( + std::auto_ptr<Graphic> & displayGraphic) { + setDisplayGraphic(displayGraphic); + m_returnButton.setParent(this); + m_returnButton.setText("Return"); + m_returnButton.setClickedHandler( + makeFunction(this, &DisplayGraphicWindow::returnClicked)); + m_returnButton.setFocused(); } -void DisplayGraphicWindow::setDisplayGraphic(std::auto_ptr<Graphic> & displayGraphic) -{ - if (displayGraphic.get() != NULL) - { - displayGraphic->setParent(this); - } - m_displayGraphic.reset(displayGraphic.release()); - invalidate(); +void DisplayGraphicWindow::setDisplayGraphic( + std::auto_ptr<Graphic> & displayGraphic) { + if (displayGraphic.get() != NULL) { + displayGraphic->setParent(this); + } + m_displayGraphic.reset(displayGraphic.release()); + invalidate(); } -void DisplayGraphicWindow::doRender(Bitmap & bitmap, int xOffset, int yOffset) const -{ - if (m_displayGraphic.get() != NULL) - { - m_displayGraphic->render(bitmap, xOffset + x(), yOffset + y()); - } - m_returnButton.render(bitmap, xOffset + x(), yOffset + y()); +void DisplayGraphicWindow::doRender(Bitmap & bitmap, int xOffset, + int yOffset) const { + if (m_displayGraphic.get() != NULL) { + m_displayGraphic->render(bitmap, xOffset + x(), yOffset + y()); + } + m_returnButton.render(bitmap, xOffset + x(), yOffset + y()); } -void DisplayGraphicWindow::resized() -{ - if (m_displayGraphic.get() != NULL) - { - m_displayGraphic->resize(width(), height()); - } - m_returnButton.resize(m_returnButton.preferredWidth(), m_returnButton.preferredHeight()); - m_returnButton.move(0, height() - m_returnButton.height()); +void DisplayGraphicWindow::resized() { + if (m_displayGraphic.get() != NULL) { + m_displayGraphic->resize(width(), height()); + } + m_returnButton.resize(m_returnButton.preferredWidth(), + m_returnButton.preferredHeight()); + m_returnButton.move(0, height() - m_returnButton.height()); }
--- a/DisplayGraphicWindow.hpp Thu Jun 01 14:21:58 2017 -0500 +++ b/DisplayGraphicWindow.hpp Mon Nov 06 18:12:27 2017 -0600 @@ -38,24 +38,24 @@ #include "Window.hpp" /// Displays a pop-up window with a user-specified graphic and a return button. -class DisplayGraphicWindow : public Window -{ +class DisplayGraphicWindow : public Window { public: - explicit DisplayGraphicWindow(std::auto_ptr<Graphic> & displayGraphic); - - /// Set the graphic that the window will display. - /// @param displayGraphic Heap allocated object that DisplayGraphicWindow will take ownership of. - void setDisplayGraphic(std::auto_ptr<Graphic> & displayGraphic); - + explicit DisplayGraphicWindow(std::auto_ptr<Graphic> & displayGraphic); + + /// Set the graphic that the window will display. + /// @param displayGraphic + /// Heap allocated object that DisplayGraphicWindow will take ownership of. + void setDisplayGraphic(std::auto_ptr<Graphic> & displayGraphic); + protected: - virtual void resized(); - virtual void doRender(Bitmap & bitmap, int xOffset, int yOffset) const; - + virtual void resized(); + virtual void doRender(Bitmap & bitmap, int xOffset, int yOffset) const; + private: - void returnClicked(); + void returnClicked(Button *); - std::auto_ptr<Graphic> m_displayGraphic; - Button m_returnButton; + std::auto_ptr<Graphic> m_displayGraphic; + Button m_returnButton; }; #endif
--- a/DisplayIdWindow.cpp Thu Jun 01 14:21:58 2017 -0500 +++ b/DisplayIdWindow.cpp Mon Nov 06 18:12:27 2017 -0600 @@ -31,6 +31,7 @@ *******************************************************************************/ #include <string> +#include "MakeFunction.hpp" #include "Text.hpp" #include "WindowManager.hpp" #include "WifiConnectWindow.hpp" @@ -38,62 +39,56 @@ extern std::string webId; -DisplayIdWindow::DisplayIdWindow(Mode mode) : m_mode(mode) -{ - m_continueButton.setParent(this); - switch (m_mode) - { - case PreConnectMode: - m_continueButton.setText("Continue"); - break; - - case PopupMode: - default: - m_continueButton.setText("Return"); - break; - } - m_continueButton.setClickedHandler(Button::EventHandler(this, &DisplayIdWindow::continueButtonClicked)); - m_continueButton.setFocused(); +DisplayIdWindow::DisplayIdWindow(Mode mode) : m_mode(mode) { + m_continueButton.setParent(this); + switch (m_mode) { + case PreConnectMode: + m_continueButton.setText("Continue"); + break; + + case PopupMode: + default: + m_continueButton.setText("Return"); + break; + } + m_continueButton.setClickedHandler( + makeFunction(this, &DisplayIdWindow::continueButtonClicked)); + m_continueButton.setFocused(); } -void DisplayIdWindow::doRender(Bitmap & bitmap, int xOffset, int yOffset) const -{ - Text description; - description.setText("Web ID: " + webId); - description.setWordWrap(true); - description.resize(width(), height()); - description.render(bitmap, xOffset + x(), yOffset + y()); - m_continueButton.render(bitmap, xOffset + x(), yOffset + y()); +void DisplayIdWindow::doRender(Bitmap & bitmap, int xOffset, + int yOffset) const { + Text description; + description.setText("Web ID: " + webId); + description.setWordWrap(true); + description.resize(width(), height()); + description.render(bitmap, xOffset + x(), yOffset + y()); + m_continueButton.render(bitmap, xOffset + x(), yOffset + y()); } -void DisplayIdWindow::resized() -{ - m_continueButton.resize(m_continueButton.preferredWidth(), m_continueButton.preferredHeight()); - m_continueButton.move( - (m_mode == PreConnectMode) ? (width() - m_continueButton.width()) : 0, - height() - m_continueButton.height() - ); +void DisplayIdWindow::resized() { + m_continueButton.resize(m_continueButton.preferredWidth(), + m_continueButton.preferredHeight()); + m_continueButton.move( + (m_mode == PreConnectMode) ? (width() - m_continueButton.width()) : 0, + height() - m_continueButton.height()); } -void DisplayIdWindow::continueButtonClicked() -{ - switch (m_mode) - { - case PreConnectMode: - if (windowManager() != NULL) - { - windowManager()->pop(); - std::auto_ptr<Window> window(new WifiConnectWindow); - windowManager()->push(window); - } - break; - - case PopupMode: - default: - if (windowManager() != NULL) - { - windowManager()->pop(); - } - break; +void DisplayIdWindow::continueButtonClicked(Button *) { + switch (m_mode) { + case PreConnectMode: + if (windowManager() != NULL) { + windowManager()->pop(); + std::auto_ptr<Window> window(new WifiConnectWindow); + windowManager()->push(window); } + break; + + case PopupMode: + default: + if (windowManager() != NULL) { + windowManager()->pop(); + } + break; + } }
--- a/DisplayIdWindow.hpp Thu Jun 01 14:21:58 2017 -0500 +++ b/DisplayIdWindow.hpp Mon Nov 06 18:12:27 2017 -0600 @@ -37,27 +37,25 @@ #include "Window.hpp" /// Displays the Web ID of the device before connecting to Wi-Fi or as a pop-up window. -class DisplayIdWindow : public Window -{ +class DisplayIdWindow : public Window { public: - /// Mode of the window which controls appearance and behavior. - enum Mode - { - PreConnectMode, ///< Displays a continue button which takes user to WifiConnectWindow. - PopupMode ///< Displays a return button that clears the pop-up. - }; - - explicit DisplayIdWindow(Mode mode); - + /// Mode of the window which controls appearance and behavior. + enum Mode { + PreConnectMode, ///< Displays a continue button which takes user to WifiConnectWindow. + PopupMode ///< Displays a return button that clears the pop-up. + }; + + explicit DisplayIdWindow(Mode mode); + protected: - virtual void resized(); - virtual void doRender(Bitmap & bitmap, int xOffset, int yOffset) const; - + virtual void resized(); + virtual void doRender(Bitmap & bitmap, int xOffset, int yOffset) const; + private: - Mode m_mode; - Button m_continueButton; - - void continueButtonClicked(); + Mode m_mode; + Button m_continueButton; + + void continueButtonClicked(Button *); }; #endif
--- a/ErrorWindow.cpp Thu Jun 01 14:21:58 2017 -0500 +++ b/ErrorWindow.cpp Mon Nov 06 18:12:27 2017 -0600 @@ -33,11 +33,10 @@ #include "Text.hpp" #include "ErrorWindow.hpp" -void ErrorWindow::doRender(Bitmap & bitmap, int xOffset, int yOffset) const -{ - Text text; - text.setText(m_errorText); - text.setWordWrap(true); - text.resize(width(), height()); - text.render(bitmap, xOffset + x(), yOffset + y()); +void ErrorWindow::doRender(Bitmap & bitmap, int xOffset, int yOffset) const { + Text text; + text.setText(m_errorText); + text.setWordWrap(true); + text.resize(width(), height()); + text.render(bitmap, xOffset + x(), yOffset + y()); }
--- a/ErrorWindow.hpp Thu Jun 01 14:21:58 2017 -0500 +++ b/ErrorWindow.hpp Mon Nov 06 18:12:27 2017 -0600 @@ -37,22 +37,25 @@ #include "Window.hpp" /// Displays a fatal error message to the user. -class ErrorWindow : public Window -{ +class ErrorWindow : public Window { public: - explicit ErrorWindow(const std::string & errorText) : m_errorText(errorText) { } + explicit ErrorWindow(const std::string & errorText) + : m_errorText(errorText) {} - /// @{ - /// Error text to display. - std::string errorText() const { return m_errorText; } - void setErrorText(const std::string & errorText) { m_errorText = errorText; invalidate(); } - /// @} + /// @{ + /// Error text to display. + std::string errorText() const { return m_errorText; } + void setErrorText(const std::string & errorText) { + m_errorText = errorText; + invalidate(); + } + /// @} protected: - virtual void doRender(Bitmap & bitmap, int xOffset, int yOffset) const; - + virtual void doRender(Bitmap & bitmap, int xOffset, int yOffset) const; + private: - std::string m_errorText; + std::string m_errorText; }; #endif
--- a/Factory.cpp Thu Jun 01 14:21:58 2017 -0500 +++ b/Factory.cpp Mon Nov 06 18:12:27 2017 -0600 @@ -30,268 +30,250 @@ * ownership rights. *******************************************************************************/ -#include "DS2476.hpp" +#include <MaximInterface/Devices/DS28C36_DS2476.hpp> #include "SensorNode.hpp" #include "Factory.hpp" +using namespace MaximInterface; + // Authority (web server) public key x-component. static const DS28C36::Page authPublicKeyX = { - 0x7A, 0xB9, 0xCD, 0x00, 0x3F, 0x42, 0xF3, 0x30, 0x76, 0x25, 0x9B, 0x6B, 0xFD, 0xC2, 0x6D, 0xE2, - 0xDB, 0x59, 0xA8, 0xD9, 0xE0, 0x68, 0x3E, 0x1B, 0xFF, 0x50, 0xCB, 0x6C, 0x18, 0xB6, 0xF2, 0xEB -}; + 0x7A, 0xB9, 0xCD, 0x00, 0x3F, 0x42, 0xF3, 0x30, 0x76, 0x25, 0x9B, + 0x6B, 0xFD, 0xC2, 0x6D, 0xE2, 0xDB, 0x59, 0xA8, 0xD9, 0xE0, 0x68, + 0x3E, 0x1B, 0xFF, 0x50, 0xCB, 0x6C, 0x18, 0xB6, 0xF2, 0xEB}; // Authority (web server) public key y-component. static const DS28C36::Page authPublicKeyY = { - 0x7F, 0xFC, 0xEE, 0xDD, 0x77, 0xE9, 0x63, 0x07, 0x62, 0x37, 0x33, 0x81, 0x17, 0x16, 0x58, 0x75, - 0x12, 0x88, 0x85, 0x58, 0x57, 0xC0, 0x15, 0xB8, 0x08, 0xDE, 0xB2, 0x3B, 0xD7, 0x8A, 0x9D, 0x2C -}; + 0x7F, 0xFC, 0xEE, 0xDD, 0x77, 0xE9, 0x63, 0x07, 0x62, 0x37, 0x33, + 0x81, 0x17, 0x16, 0x58, 0x75, 0x12, 0x88, 0x85, 0x58, 0x57, 0xC0, + 0x15, 0xB8, 0x08, 0xDE, 0xB2, 0x3B, 0xD7, 0x8A, 0x9D, 0x2C}; // Authority (web server) private key. static const DS28C36::Page authPrivateKey = { - 0xC5, 0x45, 0x5F, 0xFB, 0x45, 0xEA, 0x77, 0x0B, 0xF1, 0x1B, 0xE5, 0xD2, 0x21, 0xAD, 0x35, 0xF5, - 0x0B, 0x61, 0x7F, 0x66, 0xDB, 0xA0, 0xBD, 0xB6, 0x64, 0x75, 0x21, 0x4E, 0xB0, 0x98, 0x2D, 0x8E -}; + 0xC5, 0x45, 0x5F, 0xFB, 0x45, 0xEA, 0x77, 0x0B, 0xF1, 0x1B, 0xE5, + 0xD2, 0x21, 0xAD, 0x35, 0xF5, 0x0B, 0x61, 0x7F, 0x66, 0xDB, 0xA0, + 0xBD, 0xB6, 0x64, 0x75, 0x21, 0x4E, 0xB0, 0x98, 0x2D, 0x8E}; // Master secret for SHA-256 HMAC authentication. static const DS28C36::Page masterSecret = { - 0x6D, 0x52, 0xB6, 0x15, 0xDC, 0x80, 0xCF, 0xB1, 0x25, 0xB0, 0x76, 0xB7, 0x7C, 0xAC, 0x00, 0xF2, - 0xBC, 0x19, 0xBE, 0xD3, 0x2F, 0x9D, 0xC1, 0x42, 0x2A, 0xA5, 0xF6, 0xAE, 0x71, 0xF2, 0x25, 0xB6 -}; - -static const DS28C36::Page zeroPage = { }; - -static DS28C36::CmdResult generateRandomPage(DS28C36 & ds28c36, DS28C36::Page & page) -{ - DS28C36::Buffer data; - DS28C36::CmdResult result = ds28c36.readRng(page.size(), data); - if (result == DS28C36::Success) - { - std::copy(data.begin(), data.end(), page.begin()); - } - return result; -} + 0x6D, 0x52, 0xB6, 0x15, 0xDC, 0x80, 0xCF, 0xB1, 0x25, 0xB0, 0x76, + 0xB7, 0x7C, 0xAC, 0x00, 0xF2, 0xBC, 0x19, 0xBE, 0xD3, 0x2F, 0x9D, + 0xC1, 0x42, 0x2A, 0xA5, 0xF6, 0xAE, 0x71, 0xF2, 0x25, 0xB6}; -bool provisionAuthenticator(DS28C36 & ds28c36) -{ - DS28C36::CmdResult result = DS28C36::Success; - - // Page 0 - 15 - for (int pageNum = DS28C36::UserData0; pageNum <= DS28C36::UserData15; pageNum++) - { - result = ds28c36.writeMemory(pageNum, zeroPage); - if (result != DS28C36::Success) - return false; - } - // Page 16, 17, 22 - DS28C36::Page page; - result = generateRandomPage(ds28c36, page); - if (result != DS28C36::Success) - return false; - result = ds28c36.writeMemory(DS28C36::PublicKeyAX, page); - if (result != DS28C36::Success) - return false; - result = generateRandomPage(ds28c36, page); - if (result != DS28C36::Success) - return false; - result = ds28c36.writeMemory(DS28C36::PublicKeyAY, page); - if (result != DS28C36::Success) - return false; - result = generateRandomPage(ds28c36, page); - if (result != DS28C36::Success) - return false; - result = ds28c36.writeMemory(DS28C36::PrivateKeyA, page); - if (result != DS28C36::Success) - return false; - // Page 18, 19, 23 - result = generateRandomPage(ds28c36, page); - if (result != DS28C36::Success) - return false; - result = ds28c36.writeMemory(DS28C36::PublicKeyBX, page); - if (result != DS28C36::Success) - return false; - result = generateRandomPage(ds28c36, page); - if (result != DS28C36::Success) - return false; - result = ds28c36.writeMemory(DS28C36::PublicKeyBY, page); - if (result != DS28C36::Success) - return false; - result = generateRandomPage(ds28c36, page); - if (result != DS28C36::Success) - return false; - result = ds28c36.writeMemory(DS28C36::PrivateKeyB, page); - if (result != DS28C36::Success) - return false; - // Page 20, 21, 24 - result = generateRandomPage(ds28c36, page); - if (result != DS28C36::Success) - return false; - result = ds28c36.writeMemory(DS28C36::PublicKeyCX, page); - if (result != DS28C36::Success) - return false; - result = generateRandomPage(ds28c36, page); - if (result != DS28C36::Success) - return false; - result = ds28c36.writeMemory(DS28C36::PublicKeyCY, page); - if (result != DS28C36::Success) - return false; - result = generateRandomPage(ds28c36, page); - if (result != DS28C36::Success) - return false; - result = ds28c36.writeMemory(DS28C36::PrivateKeyC, page); - if (result != DS28C36::Success) - return false; - // Page 25 - result = ds28c36.writeMemory(DS28C36::SecretA, masterSecret); - if (result != DS28C36::Success) - return false; - result = ds28c36.writeBuffer(DS28C36::Buffer(32, 0x00)); - if (result != DS28C36::Success) - return false; - result = ds28c36.computeAndLockSha2Secret(DS28C36::UserData0, DS28C36::SecretNumA, DS28C36::SecretNumA, false); - if (result != DS28C36::Success) - return false; - // Page 26 - result = generateRandomPage(ds28c36, page); - if (result != DS28C36::Success) - return false; - result = ds28c36.writeMemory(DS28C36::SecretB, page); - if (result != DS28C36::Success) - return false; - // Page 28 - result = ds28c36.setPageProtection(DS28C36::RomOptions, DS28C36::PageProtection(DS28C36::PageProtection::APH)); - if (result != DS28C36::Success) - return false; - // Page 29 - result = ds28c36.setPageProtection(DS28C36::GpioControl, DS28C36::PageProtection(DS28C36::PageProtection::APH)); - if (result != DS28C36::Success) - return false; - - return true; +error_code provisionAuthenticator(DS28C36 & ds28c36) { + const DS28C36::Page zeroPage = {}; + error_code result; + // Page 0 - 15 + for (int pageNum = DS28C36::UserData0; pageNum <= DS28C36::UserData15; + pageNum++) { + result = ds28c36.writeMemory(pageNum, zeroPage); + if (result) + return result; + } + // Page 16, 17, 22 + DS28C36::Page page; + result = readRng(ds28c36, page.data(), page.size()); + if (result) + return result; + result = ds28c36.writeMemory(DS28C36::PublicKeyAX, page); + if (result) + return result; + result = readRng(ds28c36, page.data(), page.size()); + if (result) + return result; + result = ds28c36.writeMemory(DS28C36::PublicKeyAY, page); + if (result) + return result; + result = readRng(ds28c36, page.data(), page.size()); + if (result) + return result; + result = ds28c36.writeMemory(DS28C36::PrivateKeyA, page); + if (result) + return result; + // Page 18, 19, 23 + result = readRng(ds28c36, page.data(), page.size()); + if (result) + return result; + result = ds28c36.writeMemory(DS28C36::PublicKeyBX, page); + if (result) + return result; + result = readRng(ds28c36, page.data(), page.size()); + if (result) + return result; + result = ds28c36.writeMemory(DS28C36::PublicKeyBY, page); + if (result) + return result; + result = readRng(ds28c36, page.data(), page.size()); + if (result) + return result; + result = ds28c36.writeMemory(DS28C36::PrivateKeyB, page); + if (result) + return result; + // Page 20, 21, 24 + result = readRng(ds28c36, page.data(), page.size()); + if (result) + return result; + result = ds28c36.writeMemory(DS28C36::PublicKeyCX, page); + if (result) + return result; + result = readRng(ds28c36, page.data(), page.size()); + if (result) + return result; + result = ds28c36.writeMemory(DS28C36::PublicKeyCY, page); + if (result) + return result; + result = readRng(ds28c36, page.data(), page.size()); + if (result) + return result; + result = ds28c36.writeMemory(DS28C36::PrivateKeyC, page); + if (result) + return result; + // Page 25 + result = ds28c36.writeMemory(DS28C36::SecretA, masterSecret); + if (result) + return result; + result = ds28c36.writeBuffer(zeroPage.data(), zeroPage.size()); + if (result) + return result; + result = ds28c36.computeAndLockSha2Secret( + DS28C36::UserData0, DS28C36::SecretNumA, DS28C36::SecretNumA, false); + if (result) + return result; + // Page 26 + result = readRng(ds28c36, page.data(), page.size()); + if (result) + return result; + result = ds28c36.writeMemory(DS28C36::SecretB, page); + if (result) + return result; + // Page 28 + result = ds28c36.setPageProtection(DS28C36::RomOptions, DS28C36::APH); + if (result) + return result; + // Page 29 + result = ds28c36.setPageProtection(DS28C36::GpioControl, DS28C36::APH); + return result; } -bool provisionCoprocessor(DS2476 & ds2476) -{ - // Page 0, 1 - DS2476::CmdResult result = ds2476.writeMemory(DS2476::UserData0, zeroPage); - if (result != DS2476::Success) - return false; - result = ds2476.writeMemory(DS2476::UserData1, zeroPage); - if (result != DS2476::Success) - return false; - // Page 2 - 13 - DS2476::Page page; - for (int pageNum = DS2476::UserData2; pageNum <= DS2476::UserData13; pageNum++) - { - result = generateRandomPage(ds2476, page); - if (result != DS2476::Success) - return false; - result = ds2476.writeMemory(pageNum, page); - if (result != DS2476::Success) - return false; - } - // Page 16, 17, 22 - result = ds2476.generateEcc256KeyPair(DS2476::KeyNumA, false); - if (result != DS2476::Success) - return false; - // Page 18, 19, 23 - result = generateRandomPage(ds2476, page); - if (result != DS2476::Success) - return false; - result = ds2476.writeMemory(DS2476::PublicKeyBX, page); - if (result != DS2476::Success) - return false; - result = generateRandomPage(ds2476, page); - if (result != DS2476::Success) - return false; - result = ds2476.writeMemory(DS2476::PublicKeyBY, page); - if (result != DS2476::Success) - return false; - result = generateRandomPage(ds2476, page); - if (result != DS2476::Success) - return false; - result = ds2476.writeMemory(DS2476::PrivateKeyB, page); - if (result != DS2476::Success) - return false; - // Page 20, 21, 24 - result = ds2476.writeMemory(DS2476::PublicKeyCX, authPublicKeyX); - if (result != DS2476::Success) - return false; - result = ds2476.writeMemory(DS2476::PublicKeyCY, authPublicKeyY); - if (result != DS2476::Success) - return false; - result = ds2476.writeMemory(DS2476::PrivateKeyC, authPrivateKey); - if (result != DS2476::Success) - return false; - // Page 25 - result = ds2476.writeMemory(DS2476::SecretA, masterSecret); - if (result != DS2476::Success) - return false; - // Page 26 - result = generateRandomPage(ds2476, page); - if (result != DS2476::Success) - return false; - result = ds2476.writeMemory(DS2476::SecretB, page); - if (result != DS2476::Success) - return false; - // Page 29 - /*result = ds2476.setPageProtection(DS2476::GpioControl, DS2476::PageProtection(DS2476::PageProtection::APH)); - if (result != DS2476::Success) - return false;*/ - // Page 14, 15 - DS2476::Buffer publicKeyA; - publicKeyA.reserve(page.size() * 2 + 1); - result = ds2476.readMemory(DS2476::PublicKeyAX, page); - if (result != DS2476::Success) - return false; - publicKeyA.assign(page.begin(), page.end()); - result = ds2476.readMemory(DS2476::PublicKeyAY, page); - if (result != DS2476::Success) - return false; - publicKeyA.insert(publicKeyA.end(), page.begin(), page.end()); - publicKeyA.insert(publicKeyA.end(), 0x00); // Customization - result = ds2476.writeBuffer(publicKeyA); - if (result != DS2476::Success) - return false; - DS2476::Signature writeCertificate; - result = ds2476.generateEcdsaSignature(DS2476::KeyNumC, writeCertificate); - if (result != DS2476::Success) - return false; - result = ds2476.writeMemory(DS2476::UserData14, writeCertificate.r); - if (result != DS2476::Success) - return false; - result = ds2476.writeMemory(DS2476::UserData15, writeCertificate.s); - if (result != DS2476::Success) - return false; - // Remove Private Key C and set protection - result = generateRandomPage(ds2476, page); - if (result != DS2476::Success) - return false; - result = ds2476.writeMemory(DS2476::PrivateKeyC, page); - if (result != DS2476::Success) - return false; - /*result = ds2476.setPageProtection(DS2476::PublicKeyCX, DS2476::PageProtection(DS2476::PageProtection::AUTH)); - if (result != DS2476::Success) - return false;*/ - - return true; +error_code provisionCoprocessor(DS2476 & ds2476) { + // Page 0, 1 + const DS2476::Page zeroPage = {}; + error_code result = ds2476.writeMemory(DS2476::UserData0, zeroPage); + if (result) + return result; + result = ds2476.writeMemory(DS2476::UserData1, zeroPage); + if (result) + return result; + // Page 2 - 13 + DS2476::Page page; + for (int pageNum = DS2476::UserData2; pageNum <= DS2476::UserData13; + pageNum++) { + result = readRng(ds2476, page.data(), page.size()); + if (result) + return result; + result = ds2476.writeMemory(pageNum, page); + if (result) + return result; + } + // Page 16, 17, 22 + result = ds2476.generateEcc256KeyPair(DS2476::KeyNumA, false); + if (result) + return result; + // Page 18, 19, 23 + result = readRng(ds2476, page.data(), page.size()); + if (result) + return result; + result = ds2476.writeMemory(DS2476::PublicKeyBX, page); + if (result) + return result; + result = readRng(ds2476, page.data(), page.size()); + if (result) + return result; + result = ds2476.writeMemory(DS2476::PublicKeyBY, page); + if (result) + return result; + result = readRng(ds2476, page.data(), page.size()); + if (result) + return result; + result = ds2476.writeMemory(DS2476::PrivateKeyB, page); + if (result) + return result; + // Page 20, 21, 24 + result = ds2476.writeMemory(DS2476::PublicKeyCX, authPublicKeyX); + if (result) + return result; + result = ds2476.writeMemory(DS2476::PublicKeyCY, authPublicKeyY); + if (result) + return result; + result = ds2476.writeMemory(DS2476::PrivateKeyC, authPrivateKey); + if (result) + return result; + // Page 25 + result = ds2476.writeMemory(DS2476::SecretA, masterSecret); + if (result) + return result; + // Page 26 + result = readRng(ds2476, page.data(), page.size()); + if (result) + return result; + result = ds2476.writeMemory(DS2476::SecretB, page); + if (result) + return result; + // Page 29 + /*result = ds2476.setPageProtection(DS2476::GpioControl, DS2476::APH); + if (result) + return result;*/ + // Page 14, 15 + std::vector<uint8_t> publicKeyA; + publicKeyA.reserve(page.size() * 2 + 1); + result = ds2476.readMemory(DS2476::PublicKeyAX, page); + if (result) + return result; + publicKeyA.assign(page.begin(), page.end()); + result = ds2476.readMemory(DS2476::PublicKeyAY, page); + if (result) + return result; + publicKeyA.insert(publicKeyA.end(), page.begin(), page.end()); + publicKeyA.insert(publicKeyA.end(), 0x00); // Customization + result = ds2476.writeBuffer(&publicKeyA[0], publicKeyA.size()); + if (result) + return result; + Ecc256::Signature writeCertificate; + result = ds2476.generateEcdsaSignature(DS2476::KeyNumC, writeCertificate); + if (result) + return result; + result = ds2476.writeMemory(DS2476::UserData14, writeCertificate.r); + if (result) + return result; + result = ds2476.writeMemory(DS2476::UserData15, writeCertificate.s); + if (result) + return result; + // Remove Private Key C and set protection + result = readRng(ds2476, page.data(), page.size()); + if (result) + return result; + result = ds2476.writeMemory(DS2476::PrivateKeyC, page); + /*if (result) + return result; + result = ds2476.setPageProtection(DS2476::PublicKeyCX, + DS2476::PageProtection::AUTH);*/ + return result; } -bool checkAuthenticatorProvisioned(DS28C36 & ds28c36, bool & provisioned) -{ - DS28C36::PageProtection protection; - DS28C36::CmdResult result = ds28c36.readPageProtection(DS28C36::GpioControl, protection); - if (result != DS28C36::Success) - return false; - provisioned = protection.protectionEnabled(DS28C36::PageProtection::APH); - return true; +error_code checkAuthenticatorProvisioned(DS28C36 & ds28c36, + bool & provisioned) { + DS28C36::PageProtection protection; + const error_code result = + ds28c36.readPageProtection(DS28C36::GpioControl, protection); + if (!result) + provisioned = protection.test(DS28C36::APH); + return result; } -bool checkCoprocessorProvisioned(DS2476 & ds2476, bool & provisioned) -{ - DS2476::Page page; - DS2476::CmdResult result = ds2476.readMemory(DS2476::PublicKeyCX, page); - if (result != DS2476::Success) - return false; +error_code checkCoprocessorProvisioned(DS2476 & ds2476, bool & provisioned) { + DS2476::Page page; + const error_code result = ds2476.readMemory(DS2476::PublicKeyCX, page); + if (!result) provisioned = (page == authPublicKeyX); - return true; + return result; }
--- a/Factory.hpp Thu Jun 01 14:21:58 2017 -0500 +++ b/Factory.hpp Mon Nov 06 18:12:27 2017 -0600 @@ -31,31 +31,41 @@ *******************************************************************************/ /// @file Contains provisioning commands for the DS2476 and DS28C36. -/// Provisioning would typically be performed separately at a secure location during the device -/// manufacturing stage. +/// Provisioning would typically be performed separately at a secure location +/// during the device manufacturing stage. #ifndef FACTORY_HPP #define FACTORY_HPP +#include <MaximInterface/Utilities/system_error.hpp> + +namespace MaximInterface { class DS2476; class DS28C36; +} // namespace MaximInterface /// Provision the specified DS28C36 for this application. /// @returns True if the provisioning was successful. -bool provisionAuthenticator(DS28C36 & ds28c36); +MaximInterface::error_code +provisionAuthenticator(MaximInterface::DS28C36 & ds28c36); /// Provision the specified DS2476 for this application. /// @returns True if the provisioning was successful. -bool provisionCoprocessor(DS2476 & ds2476); +MaximInterface::error_code +provisionCoprocessor(MaximInterface::DS2476 & ds2476); /// Check if the coprocessor is provisioned. /// @param provisioned True if the sensor board is provisioned. /// @returns True if provisioning check was successful. -bool checkAuthenticatorProvisioned(DS28C36 & ds28c36, bool & provisioned); +MaximInterface::error_code +checkAuthenticatorProvisioned(MaximInterface::DS28C36 & ds28c36, + bool & provisioned); /// Check if the coprocessor is provisioned. /// @param provisioned True if the sensor board is provisioned. /// @returns True if provisioning check was successful. -bool checkCoprocessorProvisioned(DS2476 & ds2476, bool & provisioned); +MaximInterface::error_code +checkCoprocessorProvisioned(MaximInterface::DS2476 & ds2476, + bool & provisioned); #endif
--- a/Graphic.cpp Thu Jun 01 14:21:58 2017 -0500 +++ b/Graphic.cpp Mon Nov 06 18:12:27 2017 -0600 @@ -37,236 +37,203 @@ static const int minWidthHeight = 1; -Graphic::Graphic() : - m_parent(NULL), m_children(), m_focusedChild(NULL), - m_x(0), m_y(0), m_width(minWidthHeight), m_height(minWidthHeight), - m_valid(false) { } +Graphic::Graphic() + : m_parent(NULL), m_children(), m_focusedChild(NULL), m_x(0), m_y(0), + m_width(minWidthHeight), m_height(minWidthHeight), m_valid(false) {} + +static void setParentNull(Graphic * node) { node->setParent(NULL); } -static void setParentNull(Graphic * node) -{ - node->setParent(NULL); -} - -Graphic::~Graphic() -{ - // Set children's parent to NULL. - std::for_each(m_children.begin(), m_children.end(), setParentNull); - // Remove from parent. - setParent(NULL); +Graphic::~Graphic() { + // Set children's parent to NULL. + std::for_each(m_children.begin(), m_children.end(), setParentNull); + // Remove from parent. + setParent(NULL); } -void Graphic::setParent(Graphic * parent) -{ - if ((m_parent == parent) || (parent == this)) - return; - - if (m_parent != NULL) - { - // Remove this from the old parent's list of children. - m_parent->m_children.erase(std::remove(m_parent->m_children.begin(), m_parent->m_children.end(), this)); - // Ensure that the old parent's focused child is not this. - if (m_parent->m_focusedChild == this) - { - m_parent->m_focusedChild = NULL; - } - // Signal children changed event on old parent. - m_parent->childrenChanged(); +void Graphic::setParent(Graphic * parent) { + if ((m_parent == parent) || (parent == this)) + return; + + if (m_parent != NULL) { + // Remove this from the old parent's list of children. + m_parent->m_children.erase(std::remove(m_parent->m_children.begin(), + m_parent->m_children.end(), this)); + // Ensure that the old parent's focused child is not this. + if (m_parent->m_focusedChild == this) { + m_parent->m_focusedChild = NULL; } - if (parent != NULL) - { - // Add this to new parent's list of children. - parent->m_children.push_back(this); - // Signal children changed event on new parent. - parent->childrenChanged(); - } - m_parent = parent; + // Signal children changed event on old parent. + m_parent->childrenChanged(); + } + if (parent != NULL) { + // Add this to new parent's list of children. + parent->m_children.push_back(this); + // Signal children changed event on new parent. + parent->childrenChanged(); + } + m_parent = parent; } -bool Graphic::focused() const -{ - // First check if a focused child has not been set on this graphic. - bool focused = (m_focusedChild == NULL); - // Then check if each parent has the correct focused child set. - for (const Graphic * node = this; focused && (node->m_parent != NULL); node = node->m_parent) - { - focused = (node->m_parent->m_focusedChild == node); - } - return focused; +bool Graphic::focused() const { + // First check if a focused child has not been set on this graphic. + bool focused = (m_focusedChild == NULL); + // Then check if each parent has the correct focused child set. + for (const Graphic * node = this; focused && (node->m_parent != NULL); + node = node->m_parent) { + focused = (node->m_parent->m_focusedChild == node); + } + return focused; } -void Graphic::setFocused() -{ - // Locate top-level parent. - Graphic * node = this; - while (node->m_parent != NULL) - { - node = node->m_parent; - } - // Locate currently focused item. - while (node->m_focusedChild != NULL) - { - node = node->m_focusedChild; - } - // Do nothing if this is already focused. - if (node == this) - return; - - // Create new focus chain by setting the focused child of each parent. - m_focusedChild = NULL; - for (Graphic * node = this; node->m_parent != NULL; node = node->m_parent) - { - node->m_parent->m_focusedChild = node; - } - // Raise focus changed events on both nodes. - node->focusChanged(false); - focusChanged(true); +void Graphic::setFocused() { + // Locate top-level parent. + Graphic * node = this; + while (node->m_parent != NULL) { + node = node->m_parent; + } + // Locate currently focused item. + while (node->m_focusedChild != NULL) { + node = node->m_focusedChild; + } + // Do nothing if this is already focused. + if (node == this) + return; + + // Create new focus chain by setting the focused child of each parent. + m_focusedChild = NULL; + for (Graphic * node = this; node->m_parent != NULL; node = node->m_parent) { + node->m_parent->m_focusedChild = node; + } + // Raise focus changed events on both nodes. + node->focusChanged(false); + focusChanged(true); } -void Graphic::move(int x, int y) -{ - if (m_x != x || m_y != y) - { - m_x = x; - m_y = y; - invalidate(); - moved(); - } +void Graphic::move(int x, int y) { + if (m_x != x || m_y != y) { + m_x = x; + m_y = y; + invalidate(); + moved(); + } } -void Graphic::resize(int width, int height) -{ - if (m_width != width || m_height != height) - { - m_width = std::max(width, minWidthHeight); - m_height = std::max(height, minWidthHeight); - invalidate(); - resized(); - } +void Graphic::resize(int width, int height) { + if (m_width != width || m_height != height) { + m_width = std::max(width, minWidthHeight); + m_height = std::max(height, minWidthHeight); + invalidate(); + resized(); + } } // Functor overlays rendered graphics onto a bitmap. -class RenderOverlay -{ +class RenderOverlay { public: - RenderOverlay(Bitmap & bitmap, int xOffset, int yOffset) : - bitmap(bitmap), xOffset(xOffset), yOffset(yOffset) { } - - void operator()(const Graphic * graphic) - { - if (graphic != NULL) - { - graphic->render(bitmap, xOffset, yOffset); - } + RenderOverlay(Bitmap & bitmap, int xOffset, int yOffset) + : bitmap(bitmap), xOffset(xOffset), yOffset(yOffset) {} + + void operator()(const Graphic * graphic) { + if (graphic != NULL) { + graphic->render(bitmap, xOffset, yOffset); } - + } + private: - Bitmap & bitmap; - const int xOffset; - const int yOffset; + Bitmap & bitmap; + const int xOffset; + const int yOffset; }; -void Graphic::doRender(Bitmap & bitmap, int xOffset, int yOffset) const -{ - std::for_each(m_children.begin(), m_children.end(), - RenderOverlay(bitmap, xOffset + x(), yOffset + y())); +void Graphic::doRender(Bitmap & bitmap, int xOffset, int yOffset) const { + std::for_each(m_children.begin(), m_children.end(), + RenderOverlay(bitmap, xOffset + x(), yOffset + y())); } -void Graphic::render(Bitmap & bitmap, int xOffset, int yOffset) const -{ - // Clear region. - bitmap.clear(xOffset + x(), yOffset + y(), width(), height()); - // Do actual rendering. - doRender(bitmap, xOffset, yOffset); +void Graphic::render(Bitmap & bitmap, int xOffset, int yOffset) const { + // Clear region. + bitmap.clear(xOffset + x(), yOffset + y(), width(), height()); + // Do actual rendering. + doRender(bitmap, xOffset, yOffset); } -void Graphic::render(Bitmap & bitmap) const -{ - int xOffset = 0; - int yOffset = 0; - for (const Graphic * graphic = parent(); graphic != NULL; graphic = graphic->parent()) - { - xOffset += graphic->x(); - yOffset += graphic->y(); - } - render(bitmap, xOffset, yOffset); +void Graphic::render(Bitmap & bitmap) const { + int xOffset = 0; + int yOffset = 0; + for (const Graphic * graphic = parent(); graphic != NULL; + graphic = graphic->parent()) { + xOffset += graphic->x(); + yOffset += graphic->y(); + } + render(bitmap, xOffset, yOffset); } -void Graphic::updateAll() -{ - // Perform updated event on this graphic. - updated(); - // Call recursively on each child. - std::for_each(m_children.begin(), m_children.end(), std::mem_fun(&Graphic::updateAll)); +void Graphic::updateAll() { + // Perform updated event on this graphic. + updated(); + // Call recursively on each child. + std::for_each(m_children.begin(), m_children.end(), + std::mem_fun(&Graphic::updateAll)); } -bool Graphic::redrawInvalid(Bitmap & canvas) -{ - bool redraw = !m_valid; - if (redraw) - { - // Redraw if invalid. - render(canvas); - // Set all children to valid since they were incorporated in the redraw. - setAllValid(); +bool Graphic::redrawInvalid(Bitmap & canvas) { + bool redraw = !m_valid; + if (redraw) { + // Redraw if invalid. + render(canvas); + // Set all children to valid since they were incorporated in the redraw. + setAllValid(); + } else { + // Call recursively on each child. + for (ChildContainer::iterator it = m_children.begin(); + it != m_children.end(); it++) { + if ((*it)->redrawInvalid(canvas)) { + redraw = true; + } } - else - { - // Call recursively on each child. - for (ChildContainer::iterator it = m_children.begin(); it != m_children.end(); it++) - { - if ((*it)->redrawInvalid(canvas)) - { - redraw = true; - } - } - } - return redraw; + } + return redraw; } -void Graphic::setAllValid() -{ - m_valid = true; - // Call recursively on each child. - std::for_each(m_children.begin(), m_children.end(), std::mem_fun(&Graphic::setAllValid)); +void Graphic::setAllValid() { + m_valid = true; + // Call recursively on each child. + std::for_each(m_children.begin(), m_children.end(), + std::mem_fun(&Graphic::setAllValid)); } -bool Graphic::update(Bitmap * canvas) -{ - bool redraw = false; - updateAll(); - if (canvas != NULL) - { - redraw = redrawInvalid(*canvas); - } - return redraw; +bool Graphic::update(Bitmap * canvas) { + bool redraw = false; + updateAll(); + if (canvas != NULL) { + redraw = redrawInvalid(*canvas); + } + return redraw; } -bool Graphic::processKey(Key key) -{ - // Find focused child. - Graphic * receiver = this; - while (receiver->m_focusedChild != NULL) - { - receiver = receiver->m_focusedChild; - } - // Pass event to focused child and then to each parent until handled. - bool handled = false; - do - { - handled = receiver->doProcessKey(key); - receiver = receiver->m_parent; - } while (!handled && (receiver != NULL)); - return handled; +bool Graphic::processKey(Key key) { + // Find focused child. + Graphic * receiver = this; + while (receiver->m_focusedChild != NULL) { + receiver = receiver->m_focusedChild; + } + // Pass event to focused child and then to each parent until handled. + bool handled = false; + do { + handled = receiver->doProcessKey(key); + receiver = receiver->m_parent; + } while (!handled && (receiver != NULL)); + return handled; } void Graphic::childrenChanged() { invalidate(); } -void Graphic::focusChanged(bool) { } +void Graphic::focusChanged(bool) {} -void Graphic::moved() { } +void Graphic::moved() {} -void Graphic::resized() { } +void Graphic::resized() {} -void Graphic::updated() { } +void Graphic::updated() {} bool Graphic::doProcessKey(Key) { return false; }
--- a/Graphic.hpp Thu Jun 01 14:21:58 2017 -0500 +++ b/Graphic.hpp Mon Nov 06 18:12:27 2017 -0600 @@ -40,125 +40,130 @@ class Bitmap; /// Base class for all graphical elements. -/// @details Includes unique parent-child relationships for creating trees of graphical objects. -class Graphic -{ +/// @details Includes unique parent-child relationships for creating trees of +/// graphical objects. +class Graphic { public: - typedef std::vector<Graphic *> ChildContainer; + typedef std::vector<Graphic *> ChildContainer; + + Graphic(); + virtual ~Graphic(); + + /// @{ + /// Get or set the parent graphic of this graphic. Set to NULL if this graphic + /// has no parent. + Graphic * parent() { return m_parent; } + const Graphic * parent() const { return m_parent; } + /// @note Adds this graphic to the parent's list of children. + /// @sa childrenChanged + void setParent(Graphic * parent); + /// @} + /// List of child graphics for this parent. + /// @note Children should be added and removed by calling setParent. Children + /// will be removed automatically when they are destroyed. + const ChildContainer & children() const { return m_children; } - Graphic(); - virtual ~Graphic(); - - /// @{ - /// Get or set the parent graphic of this graphic. Set to NULL if this graphic has not parent. - Graphic * parent() { return m_parent; } - const Graphic * parent() const { return m_parent; } - /// @note Adds this graphic to the parent's list of children. - /// @sa childrenChanged - void setParent(Graphic * parent); - /// @} - /// List of child graphics for this parent. - /// @note Children should be added and removed by calling setParent. Children will be removed - /// automatically when they are destroyed. - const ChildContainer & children() const { return m_children; } - - /// @brief Check if this graphic is focused. - /// @returns True if focused. - bool focused() const; - /// @brief Set this graphic as the focused graphic. - /// @details The focused graphic is the first to receive input events such as key presses. - /// @sa focusChanged - void setFocused(); + /// @brief Check if this graphic is focused. + /// @returns True if focused. + bool focused() const; + /// @brief Set this graphic as the focused graphic. + /// @details The focused graphic is the first to receive input events such as + /// key presses. + /// @sa focusChanged + void setFocused(); + + /// @{ + /// Coordinates of this graphic in pixels. + /// @details + /// Coordinates are relative to the top-left corner of the parent graphic. + int x() const { return m_x; } + int y() const { return m_y; } + /// @} + + /// @{ + /// Displayed dimensions of this graphic in pixels. + int width() const { return m_width; } + int height() const { return m_height; } + /// @} + + /// Move graphic to a new location measured in pixels. + /// @details + /// Coordinates are relative to the top-left corner of the parent graphic. + /// @sa moved + void move(int x, int y); - /// @{ - /// Coordinates of this graphic in pixels. - /// @details Coordinates are relative to the top-left corner of the parent graphic. - int x() const { return m_x; } - int y() const { return m_y; } - /// @} - - /// @{ - /// Displayed dimensions of this graphic in pixels. - int width() const { return m_width; } - int height() const { return m_height; } - /// @} - - /// Move graphic to a new location measured in pixels. - /// @details Coordinates are relative to the top-left corner of the parent graphic. - /// @sa moved - void move(int x, int y); - - /// Resize graphic to a new size measure in pixels. Minimum width and height is 1. - /// @sa resized - void resize(int width, int height); - - /// @{ - /// Render this graphic onto a bitmap. - void render(Bitmap & bitmap, int xOffset, int yOffset) const; - void render(Bitmap & bitmap) const; - /// @} - - /// Update this graphic and all child graphics. Checks if graphic has been invalidated and - /// should be redrawn. - /// @param canvas Canvas used for rendering. May be set to NULL to defer redraw. - /// @returns True if the canvas has been updated. - /// @sa updated - bool update(Bitmap * canvas); - - /// Process a key-press input event. - /// @details - /// The event will first be directed to the focused graphic. Processing will proceed to each - /// parent graphic until it has been handled. - /// @sa doProcessKey - /// @returns True if the key event was handled. - bool processKey(Key key); - -protected: - /// Mark the visual region as invalid. - /// @note Indicates a redraw is necessary during next update. - void invalidate() { m_valid = false; } - - /// Event handler for when a child is added or removed. - virtual void childrenChanged(); - - /// Event handler for when this graphic has been focused or unfocused. - /// @param focused True if focused or false if unfocused. - virtual void focusChanged(bool focused); - - /// Event handler for when this graphic has been moved. - virtual void moved(); - - /// Event handler for when this graphic has been resized. - virtual void resized(); - - /// Event handler for when this graphic has been updated. - virtual void updated(); - - /// Render this graphic onto a bitmap. - /// @details The default implementation renders each child in order. - virtual void doRender(Bitmap & bitmap, int xOffset, int yOffset) const; - - /// Process a key-press input event. - /// @returns True if the key event was handled. False if the key event should be propagated. - virtual bool doProcessKey(Key); + /// Resize graphic to a new size measure in pixels. Minimum width and height is 1. + /// @sa resized + void resize(int width, int height); + + /// @{ + /// Render this graphic onto a bitmap. + void render(Bitmap & bitmap, int xOffset, int yOffset) const; + void render(Bitmap & bitmap) const; + /// @} + + /// Update this graphic and all child graphics. Checks if graphic has been + /// invalidated and should be redrawn. + /// @param canvas Canvas used for rendering. May be set to NULL to defer redraw. + /// @returns True if the canvas has been updated. + /// @sa updated + bool update(Bitmap * canvas); + + /// Process a key-press input event. + /// @details + /// The event will first be directed to the focused graphic. Processing will + /// proceed to each parent graphic until it has been handled. + /// @sa doProcessKey + /// @returns True if the key event was handled. + bool processKey(Key key); + +protected: + /// Mark the visual region as invalid. + /// @note Indicates a redraw is necessary during next update. + void invalidate() { m_valid = false; } + + /// Event handler for when a child is added or removed. + virtual void childrenChanged(); + + /// Event handler for when this graphic has been focused or unfocused. + /// @param focused True if focused or false if unfocused. + virtual void focusChanged(bool focused); + + /// Event handler for when this graphic has been moved. + virtual void moved(); + + /// Event handler for when this graphic has been resized. + virtual void resized(); + + /// Event handler for when this graphic has been updated. + virtual void updated(); + + /// Render this graphic onto a bitmap. + /// @details The default implementation renders each child in order. + virtual void doRender(Bitmap & bitmap, int xOffset, int yOffset) const; + + /// Process a key-press input event. + /// @returns True if the key event was handled. False if the key event should + /// be propagated. + virtual bool doProcessKey(Key); private: - Graphic * m_parent; - ChildContainer m_children; - Graphic * m_focusedChild; - int m_x; - int m_y; - int m_width; - int m_height; - bool m_valid; - - void updateAll(); - bool redrawInvalid(Bitmap & canvas); - void setAllValid(); - - // Uncopyable - Graphic(const Graphic &); - const Graphic & operator=(const Graphic &); + Graphic * m_parent; + ChildContainer m_children; + Graphic * m_focusedChild; + int m_x; + int m_y; + int m_width; + int m_height; + bool m_valid; + + void updateAll(); + bool redrawInvalid(Bitmap & canvas); + void setAllValid(); + + // Uncopyable + Graphic(const Graphic &); + const Graphic & operator=(const Graphic &); }; #endif
--- a/HexConversions.cpp Thu Jun 01 14:21:58 2017 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,61 +0,0 @@ -/******************************************************************************* -* Copyright (C) 2017 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 <cstdio> -#include "HexConversions.hpp" - -static const unsigned int charsPerByte = 2; - -std::string byteArrayToHexString(const uint8_t * byteArray, size_t byteArraySize) -{ - std::string hexString; - char hexBuf[charsPerByte + 1]; - for (size_t i = 0; i < byteArraySize; i++) - { - std::sprintf(hexBuf, "%2.2X", byteArray[i]); - hexString.append(hexBuf, charsPerByte); - } - return hexString; -} - -std::vector<uint8_t> hexStringToByteArray(const std::string & hexString) -{ - std::vector<uint8_t> byteArray; - byteArray.reserve(hexString.size() / charsPerByte + 1); - for (std::string::size_type i = 0; i < hexString.size(); i += charsPerByte) - { - unsigned int byte; - std::sscanf(hexString.substr(i, charsPerByte).c_str(), "%2x", &byte); - byteArray.push_back(static_cast<uint8_t>(byte)); - } - return byteArray; -}
--- a/HexConversions.hpp Thu Jun 01 14:21:58 2017 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,44 +0,0 @@ -/******************************************************************************* -* Copyright (C) 2017 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 <vector> -#include <stdint.h> -#include <stddef.h> - -std::string byteArrayToHexString(const uint8_t * byteArray, size_t byteArraySize); -std::vector<uint8_t> hexStringToByteArray(const std::string & hexString); - -#endif
--- a/Image.cpp Thu Jun 01 14:21:58 2017 -0500 +++ b/Image.cpp Mon Nov 06 18:12:27 2017 -0600 @@ -33,12 +33,9 @@ #include <cstdlib> #include "Image.hpp" -void Image::doRender(Bitmap & bitmap, int xOffset, int yOffset) const -{ - // Overlay centered. - bitmap.overlay( - xOffset + x() + std::abs(width() - m_bitmap.width()) / 2, - yOffset + y() + std::abs(height() - m_bitmap.height()) / 2, - m_bitmap - ); +void Image::doRender(Bitmap & bitmap, int xOffset, int yOffset) const { + // Overlay centered. + bitmap.overlay(xOffset + x() + std::abs(width() - m_bitmap.width()) / 2, + yOffset + y() + std::abs(height() - m_bitmap.height()) / 2, + m_bitmap); }
--- a/Image.hpp Thu Jun 01 14:21:58 2017 -0500 +++ b/Image.hpp Mon Nov 06 18:12:27 2017 -0600 @@ -37,19 +37,18 @@ #include "Graphic.hpp" /// Graphic type that displays a bitmap. -class Image : public Graphic -{ +class Image : public Graphic { public: - explicit Image(const Bitmap & bitmap) : m_bitmap(bitmap) { } - - int preferredWidth() const { return m_bitmap.width(); } - int preferredHeight() const { return m_bitmap.height(); } - + explicit Image(const Bitmap & bitmap) : m_bitmap(bitmap) {} + + int preferredWidth() const { return m_bitmap.width(); } + int preferredHeight() const { return m_bitmap.height(); } + protected: - virtual void doRender(Bitmap & bitmap, int xOffset, int yOffset) const; + virtual void doRender(Bitmap & bitmap, int xOffset, int yOffset) const; private: - Bitmap m_bitmap; + Bitmap m_bitmap; }; #endif
--- a/InitWindow.cpp Thu Jun 01 14:21:58 2017 -0500 +++ b/InitWindow.cpp Mon Nov 06 18:12:27 2017 -0600 @@ -32,17 +32,17 @@ #include <string> #include <wait_api.h> +#include <MaximInterface/Devices/DS28C36_DS2476.hpp> +#include <MaximInterface/Utilities/HexConversions.hpp> +#include <MaximInterface/Utilities/RomId.hpp> #include "Bitmap.hpp" +#include "CC3100.hpp" +#include "ErrorWindow.hpp" +#include "Factory.hpp" +#include "InitWindow.hpp" +#include "SensorNode.hpp" #include "Text.hpp" #include "WindowManager.hpp" -#include "RomId.h" -#include "CC3100.hpp" -#include "DS2476.hpp" -#include "SensorNode.hpp" -#include "Factory.hpp" -#include "ErrorWindow.hpp" -#include "InitWindow.hpp" -#include "HexConversions.hpp" #ifdef HARDWARE_TEST #include "HardwareTestWindow.hpp" @@ -50,6 +50,8 @@ #include "DisplayIdWindow.hpp" #endif +using namespace MaximInterface; + extern DS2476 coproc; extern SensorNode sensorNode; extern std::string webId; @@ -57,215 +59,206 @@ static const int maximLogoWidth = 128; static const int maximLogoHeight = 39; static const uint8_t maximLogoData[] = { - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 - ,0x00,0x01,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 - ,0x00,0x0f,0xff,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 - ,0x00,0x1f,0xff,0xf8,0x00,0x00,0x00,0x00,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x00 - ,0x00,0x7f,0xff,0xfc,0x00,0x00,0x00,0x00,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x00 - ,0x00,0xff,0xff,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 - ,0x01,0xff,0xff,0xff,0x00,0x1b,0x9c,0x1f,0x18,0xcc,0x6e,0x70,0x00,0x00,0x00,0x00 - ,0x03,0xff,0xff,0xff,0x80,0x1f,0xfe,0x3f,0x98,0xcc,0x7f,0xf8,0x00,0x00,0x00,0x00 - ,0x07,0xff,0xff,0xff,0xc0,0x1c,0xe6,0x31,0x8d,0x8c,0x73,0x98,0x00,0x00,0x00,0x00 - ,0x0f,0xff,0xff,0xff,0xe0,0x18,0xc6,0x01,0x8f,0x8c,0x63,0x18,0x00,0x00,0x00,0x00 - ,0x0f,0x80,0xfe,0x03,0xe0,0x18,0xc6,0x1f,0x87,0x0c,0x63,0x18,0x00,0x00,0x00,0x00 - ,0x1f,0x00,0x7c,0x01,0xf0,0x18,0xc6,0x39,0x8f,0x8c,0x63,0x18,0x00,0x00,0x00,0x00 - ,0x1f,0x00,0x3c,0x01,0xf0,0x18,0xc6,0x31,0x8d,0x8c,0x63,0x18,0x00,0x00,0x00,0x00 - ,0x3f,0x00,0x38,0x01,0xf8,0x18,0xc6,0x3f,0x98,0xcc,0x63,0x18,0x00,0x00,0x00,0x00 - ,0x3f,0x04,0x10,0x41,0xf8,0x18,0xc6,0x1d,0x98,0xcc,0x63,0x18,0x00,0x00,0x00,0x00 - ,0x3f,0x06,0x30,0xe1,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 - ,0x7f,0x06,0x20,0xe1,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 - ,0x7f,0x07,0x61,0xe1,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18 - ,0x7f,0x07,0xc1,0xe1,0xfc,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18 - ,0x7f,0x07,0xc3,0xe1,0xfc,0x18,0x00,0x18,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x18 - ,0x7f,0x07,0x83,0xe1,0xfc,0x00,0x00,0x18,0x00,0x00,0x40,0x00,0x06,0x00,0x00,0x18 - ,0x7f,0x07,0x81,0xe1,0xfc,0x18,0xde,0x3e,0x1e,0x0f,0xcd,0x8f,0x8f,0x87,0x81,0xd8 - ,0x3f,0x07,0x01,0xe1,0xf8,0x18,0xff,0x3e,0x3f,0x1f,0xcf,0x9f,0xcf,0x8f,0xc3,0xf8 - ,0x3f,0x07,0x00,0xe1,0xf8,0x18,0xe3,0x18,0x73,0x99,0x8e,0x18,0xc6,0x1c,0xe7,0x38 - ,0x3f,0x06,0x00,0xe1,0xf8,0x18,0xc3,0x18,0x61,0x99,0x8c,0x00,0xc6,0x18,0x66,0x18 - ,0x1f,0x06,0x10,0x61,0xf0,0x18,0xc3,0x18,0x7f,0x9f,0x8c,0x0f,0xc6,0x1f,0xe6,0x18 - ,0x1f,0x04,0x38,0x61,0xf0,0x18,0xc3,0x18,0x60,0x0f,0x0c,0x1c,0xc6,0x18,0x06,0x18 - ,0x1f,0x04,0x38,0x21,0xf0,0x18,0xc3,0x18,0x71,0x98,0x0c,0x18,0xc6,0x1c,0x67,0x38 - ,0x0f,0xff,0xff,0xff,0xe0,0x18,0xc3,0x1e,0x3f,0x9f,0x8c,0x1f,0xc7,0x8f,0xe3,0xf8 - ,0x07,0xff,0xff,0xff,0xe0,0x18,0xc3,0x0e,0x1f,0x3f,0xcc,0x0e,0xc3,0x87,0xc1,0xd8 - ,0x07,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x30,0xc0,0x00,0x00,0x00,0x00,0x00 - ,0x03,0xff,0xff,0xff,0x80,0x00,0x00,0x00,0x00,0x3f,0xc0,0x00,0x00,0x00,0x00,0x00 - ,0x01,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x1f,0x00,0x00,0x00,0x00,0x00,0x00 - ,0x00,0xff,0xff,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 - ,0x00,0x3f,0xff,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 - ,0x00,0x1f,0xff,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 - ,0x00,0x0f,0xff,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 - ,0x00,0x01,0xff,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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xe0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x1f, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xfe, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0xff, 0xff, 0xff, 0x00, 0x1b, 0x9c, 0x1f, 0x18, 0xcc, 0x6e, 0x70, + 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0x80, 0x1f, 0xfe, 0x3f, + 0x98, 0xcc, 0x7f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, + 0xc0, 0x1c, 0xe6, 0x31, 0x8d, 0x8c, 0x73, 0x98, 0x00, 0x00, 0x00, 0x00, + 0x0f, 0xff, 0xff, 0xff, 0xe0, 0x18, 0xc6, 0x01, 0x8f, 0x8c, 0x63, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x0f, 0x80, 0xfe, 0x03, 0xe0, 0x18, 0xc6, 0x1f, + 0x87, 0x0c, 0x63, 0x18, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x7c, 0x01, + 0xf0, 0x18, 0xc6, 0x39, 0x8f, 0x8c, 0x63, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x1f, 0x00, 0x3c, 0x01, 0xf0, 0x18, 0xc6, 0x31, 0x8d, 0x8c, 0x63, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x38, 0x01, 0xf8, 0x18, 0xc6, 0x3f, + 0x98, 0xcc, 0x63, 0x18, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x04, 0x10, 0x41, + 0xf8, 0x18, 0xc6, 0x1d, 0x98, 0xcc, 0x63, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x3f, 0x06, 0x30, 0xe1, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7f, 0x06, 0x20, 0xe1, 0xfc, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x07, 0x61, 0xe1, + 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, + 0x7f, 0x07, 0xc1, 0xe1, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x7f, 0x07, 0xc3, 0xe1, 0xfc, 0x18, 0x00, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x18, 0x7f, 0x07, 0x83, 0xe1, + 0xfc, 0x00, 0x00, 0x18, 0x00, 0x00, 0x40, 0x00, 0x06, 0x00, 0x00, 0x18, + 0x7f, 0x07, 0x81, 0xe1, 0xfc, 0x18, 0xde, 0x3e, 0x1e, 0x0f, 0xcd, 0x8f, + 0x8f, 0x87, 0x81, 0xd8, 0x3f, 0x07, 0x01, 0xe1, 0xf8, 0x18, 0xff, 0x3e, + 0x3f, 0x1f, 0xcf, 0x9f, 0xcf, 0x8f, 0xc3, 0xf8, 0x3f, 0x07, 0x00, 0xe1, + 0xf8, 0x18, 0xe3, 0x18, 0x73, 0x99, 0x8e, 0x18, 0xc6, 0x1c, 0xe7, 0x38, + 0x3f, 0x06, 0x00, 0xe1, 0xf8, 0x18, 0xc3, 0x18, 0x61, 0x99, 0x8c, 0x00, + 0xc6, 0x18, 0x66, 0x18, 0x1f, 0x06, 0x10, 0x61, 0xf0, 0x18, 0xc3, 0x18, + 0x7f, 0x9f, 0x8c, 0x0f, 0xc6, 0x1f, 0xe6, 0x18, 0x1f, 0x04, 0x38, 0x61, + 0xf0, 0x18, 0xc3, 0x18, 0x60, 0x0f, 0x0c, 0x1c, 0xc6, 0x18, 0x06, 0x18, + 0x1f, 0x04, 0x38, 0x21, 0xf0, 0x18, 0xc3, 0x18, 0x71, 0x98, 0x0c, 0x18, + 0xc6, 0x1c, 0x67, 0x38, 0x0f, 0xff, 0xff, 0xff, 0xe0, 0x18, 0xc3, 0x1e, + 0x3f, 0x9f, 0x8c, 0x1f, 0xc7, 0x8f, 0xe3, 0xf8, 0x07, 0xff, 0xff, 0xff, + 0xe0, 0x18, 0xc3, 0x0e, 0x1f, 0x3f, 0xcc, 0x0e, 0xc3, 0x87, 0xc1, 0xd8, + 0x07, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x30, 0xc0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x3f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xf0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0f, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 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}; -InitWindow::InitWindow() : m_state(NotStarted) -{ - setFocused(); -} +InitWindow::InitWindow() : m_state(NotStarted) { setFocused(); } -void InitWindow::doRender(Bitmap & bitmap, int xOffset, int yOffset) const -{ - Text title; - title.setText("MAXREFDES155#"); - title.resize(title.preferredWidth(), title.preferredHeight()); - title.move(0, maximLogoHeight + 5); - Text description; - description.setText(m_state == Completed ? "Any key to begin" : "Initializing..."); - description.resize(description.preferredWidth(), description.preferredHeight()); - description.move(0, title.y() + title.height() + 5); - bitmap.overlay(xOffset + x(), yOffset + y(), - maximLogoData, sizeof(maximLogoData) / sizeof(maximLogoData[0]), maximLogoWidth); - title.render(bitmap, xOffset + x(), yOffset + y()); - description.render(bitmap, xOffset + x(), yOffset + y()); +void InitWindow::doRender(Bitmap & bitmap, int xOffset, int yOffset) const { + Text title; + title.setText("MAXREFDES155#"); + title.resize(title.preferredWidth(), title.preferredHeight()); + title.move(0, maximLogoHeight + 5); + Text description; + description.setText(m_state == Completed ? "Any key to begin" + : "Initializing..."); + description.resize(description.preferredWidth(), + description.preferredHeight()); + description.move(0, title.y() + title.height() + 5); + bitmap.overlay(xOffset + x(), yOffset + y(), maximLogoData, + sizeof(maximLogoData) / sizeof(maximLogoData[0]), + maximLogoWidth); + title.render(bitmap, xOffset + x(), yOffset + y()); + description.render(bitmap, xOffset + x(), yOffset + y()); } -void InitWindow::updated() -{ - switch (m_state) +void InitWindow::updated() { + switch (m_state) { + case NotStarted: + m_state = Running; + invalidate(); + break; + + case Running: { + // Enable coprocessor. + error_code result = enableCoprocessor(coproc); + if (result) { + if (windowManager() != NULL) { + windowManager()->pop(); + std::auto_ptr<Window> window( + new ErrorWindow("Failed to enable coprocessor")); + windowManager()->push(window); + } + break; + } + + // Enable ROM ID. { - case NotStarted: - m_state = Running; - invalidate(); + DS2476::Page page; + result = coproc.readMemory(DS2476::RomOptions, page); + if (!result) { + page[0] = 0xAA; + result = coproc.writeMemory(DS2476::RomOptions, page); + } + if (result) { + if (windowManager() != NULL) { + windowManager()->pop(); + std::auto_ptr<Window> window( + new ErrorWindow("Failed to enable ROM ID")); + windowManager()->push(window); + } + break; + } + } + + // Read ROM ID. + { + RomId romId; + result = readRomIdAndManId(coproc, &romId, NULL); + if (result) { + if (windowManager() != NULL) { + windowManager()->pop(); + std::auto_ptr<Window> window( + new ErrorWindow("Failed to read ROM ID")); + windowManager()->push(window); + } break; - - case Running: - { - { - DS2476::Page page; - - // Enable coprocessor. - DS2476::CmdResult result = coproc.readMemory(DS2476::GpioControl, page); - if (result == DS2476::Success) - { - page[0] = 0xAA; - result = coproc.writeMemory(DS2476::GpioControl, page); - } - if (result != DS2476::Success) - { - if (windowManager() != NULL) - { - windowManager()->pop(); - std::auto_ptr<Window> window(new ErrorWindow("Failed to enable coprocessor")); - windowManager()->push(window); - } - break; - } - - // Enable ROM ID. - result = coproc.readMemory(DS2476::RomOptions, page); - if (result == DS2476::Success) - { - page[0] = 0xAA; - result = coproc.writeMemory(DS2476::RomOptions, page); - } - if (result != DS2476::Success) - { - if (windowManager() != NULL) - { - windowManager()->pop(); - std::auto_ptr<Window> window(new ErrorWindow("Failed to enable ROM ID")); - windowManager()->push(window); - } - break; - } - } - - // Read ROM ID. - { - OneWire::RomId romId; - DS2476::CmdResult result = DS2476::readRomId(coproc, romId); - if (result != DS2476::Success) - { - if (windowManager() != NULL) - { - windowManager()->pop(); - std::auto_ptr<Window> window(new ErrorWindow("Failed to read ROM ID")); - windowManager()->push(window); - } - break; - } - if (!romId.valid()) - { - if (windowManager() != NULL) - { - windowManager()->pop(); - std::auto_ptr<Window> window(new ErrorWindow("ROM ID is not valid")); - windowManager()->push(window); - } - break; - } - webId = byteArrayToHexString(romId.buffer.data(), romId.buffer.size()); - } + } + if (!valid(romId)) { + if (windowManager() != NULL) { + windowManager()->pop(); + std::auto_ptr<Window> window(new ErrorWindow("ROM ID is not valid")); + windowManager()->push(window); + } + break; + } + webId = byteArrayToHexString(romId.data(), romId.size()); + } - // Provision DS2476 if necessary. - { - bool provisioned; - bool result = checkCoprocessorProvisioned(coproc, provisioned); - if (!result) - { - if (windowManager() != NULL) - { - windowManager()->pop(); - std::auto_ptr<Window> window(new ErrorWindow("Failed to check coprocessor provisioned")); - windowManager()->push(window); - } - break; - } - if (!provisioned) - { - bool provisionResult = provisionCoprocessor(coproc); - if (!provisionResult) - { - if (windowManager() != NULL) - { - windowManager()->pop(); - std::auto_ptr<Window> window(new ErrorWindow("Failed to provision coprocessor")); - windowManager()->push(window); - } - break; - } - } - } - - // Always start with laser disabled. - sensorNode.setLaserEnabled(false); - - int result = CC3100::instance().start(); - if (result != 0) - { - if (windowManager() != NULL) - { - windowManager()->pop(); - std::auto_ptr<Window> window(new ErrorWindow("Failed to start WiFi interface")); - windowManager()->push(window); - } - } - wait_ms(1500); + // Provision DS2476 if necessary. + { + bool provisioned; + result = checkCoprocessorProvisioned(coproc, provisioned); + if (result) { + if (windowManager() != NULL) { + windowManager()->pop(); + std::auto_ptr<Window> window( + new ErrorWindow("Failed to check coprocessor provisioned")); + windowManager()->push(window); + } + break; + } + if (!provisioned) { + result = provisionCoprocessor(coproc); + if (result) { + if (windowManager() != NULL) { + windowManager()->pop(); + std::auto_ptr<Window> window( + new ErrorWindow("Failed to provision coprocessor")); + windowManager()->push(window); + } + break; } - - m_state = Completed; - invalidate(); - break; - - case Completed: - break; + } } + + // Always start with laser disabled. + sensorNode.detect(); + sensorNode.setLaserEnabled(false); + + const int cc3100Result = CC3100::instance().start(); + if (cc3100Result != 0) { + if (windowManager() != NULL) { + windowManager()->pop(); + std::auto_ptr<Window> window( + new ErrorWindow("Failed to start WiFi interface")); + windowManager()->push(window); + } + } + wait_ms(1500); + + m_state = Completed; + invalidate(); + break; + } + + case Completed: + break; + } } -bool InitWindow::doProcessKey(Key) -{ - if (m_state == Completed) - { - if (windowManager() != NULL) - { - windowManager()->pop(); +bool InitWindow::doProcessKey(Key) { + if (m_state == Completed) { + if (windowManager() != NULL) { + windowManager()->pop(); #ifdef HARDWARE_TEST - std::auto_ptr<Window> window(new HardwareTestWindow); + std::auto_ptr<Window> window(new HardwareTestWindow); #else - std::auto_ptr<Window> window(new DisplayIdWindow(DisplayIdWindow::PreConnectMode)); + std::auto_ptr<Window> window( + new DisplayIdWindow(DisplayIdWindow::PreConnectMode)); #endif - windowManager()->push(window); - } + windowManager()->push(window); } - return true; + } + return true; }
--- a/InitWindow.hpp Thu Jun 01 14:21:58 2017 -0500 +++ b/InitWindow.hpp Mon Nov 06 18:12:27 2017 -0600 @@ -36,25 +36,23 @@ #include "Window.hpp" /// Displays a welcome screen while initializing the DS2476 and CC3100. -class InitWindow : public Window -{ +class InitWindow : public Window { public: - InitWindow(); - + InitWindow(); + protected: - virtual void updated(); - virtual void doRender(Bitmap & bitmap, int xOffset, int yOffset) const; - virtual bool doProcessKey(Key); - + virtual void updated(); + virtual void doRender(Bitmap & bitmap, int xOffset, int yOffset) const; + virtual bool doProcessKey(Key); + private: - enum State - { - NotStarted, // Display the welcome screen before starting initialization. - Running, // Initialization performed here. - Completed // Display prompt to continue. - }; + enum State { + NotStarted, // Display the welcome screen before starting initialization. + Running, // Initialization performed here. + Completed // Display prompt to continue. + }; - State m_state; + State m_state; }; #endif
--- a/Keys.hpp Thu Jun 01 14:21:58 2017 -0500 +++ b/Keys.hpp Mon Nov 06 18:12:27 2017 -0600 @@ -34,8 +34,7 @@ #define KEYS_HPP /// Hardware keys on the board. -enum Key -{ +enum Key { UpKey, DownKey, LeftKey,
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MakeFunction.hpp Mon Nov 06 18:12:27 2017 -0600 @@ -0,0 +1,46 @@ +/******************************************************************************* +* Copyright (C) 2017 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 MAKEFUNCTION_HPP +#define MAKEFUNCTION_HPP + +#include <functional> +#include <MaximInterface/Utilities/Function.hpp> + +template <typename ClassType, typename ArgumentType, typename ResultType> +typename MaximInterface::Function<ResultType(ArgumentType)> +makeFunction(ClassType * instance, + ResultType (ClassType::*method)(ArgumentType)) { + return std::bind1st(std::mem_fun(method), instance); +} + +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MaximInterface.lib Mon Nov 06 18:12:27 2017 -0600 @@ -0,0 +1,1 @@ +https://os.mbed.com/teams/Maxim-Integrated/code/MaximInterface/#dbc089c57059
--- a/NormalOperationWindow.cpp Thu Jun 01 14:21:58 2017 -0500 +++ b/NormalOperationWindow.cpp Mon Nov 06 18:12:27 2017 -0600 @@ -41,765 +41,685 @@ #include <cstdio> #include <string> #include <utility> +#include <MaximInterface/Devices/DS28C36_DS2476.hpp> +#include <MaximInterface/Utilities/HexConversions.hpp> +#include "DisplayGraphicWindow.hpp" +#include "DisplayIdWindow.hpp" +#include "ErrorWindow.hpp" #include "Image.hpp" +#include "MakeFunction.hpp" +#include "NormalOperationWindow.hpp" #include "Text.hpp" #include "WindowManager.hpp" -#include "ErrorWindow.hpp" -#include "DisplayIdWindow.hpp" -#include "NormalOperationWindow.hpp" -#include "DisplayGraphicWindow.hpp" -#include "HexConversions.hpp" -#include "DS2476.hpp" -#include "SensorNode.hpp" + +using namespace MaximInterface; extern DS2476 coproc; extern SensorNode sensorNode; extern std::string webId; extern "C" { - void ComputeSHA256(unsigned char* message, short length, unsigned short skipconst, - unsigned short reverse, unsigned char* digest); +void ComputeSHA256(unsigned char * message, short length, + unsigned short skipconst, unsigned short reverse, + unsigned char * digest); } -static const size_t defaultChunkSize = 256; // Default allocation size for rapidjson. -static const int jsonMaxDecimalPlaces = 2; // Number of decimal places to use when writing JSON. +// Default allocation size for rapidjson. +static const size_t defaultChunkSize = 256; +// Number of decimal places to use when writing JSON. +static const int jsonMaxDecimalPlaces = 2; // Separate multiple JSON commands received on the socket. // Returns a list of begin and end iterators within the input message. -static std::vector<std::pair<const char *, const char *> > separateCommands(const char * receivedData, size_t receivedDataSize) -{ - std::vector<std::pair<const char *, const char *> > commands; - int counter = 0; - size_t beginIdx; - for (size_t i = 0; i < receivedDataSize; i++) - { - if (receivedData[i] == '{') - { - if (counter == 0) - { - beginIdx = i; - } - counter++; +static std::vector<std::pair<const char *, const char *> > +separateCommands(const char * receivedData, size_t receivedDataSize) { + std::vector<std::pair<const char *, const char *> > commands; + int counter = 0; + size_t beginIdx; + for (size_t i = 0; i < receivedDataSize; i++) { + if (receivedData[i] == '{') { + if (counter == 0) { + beginIdx = i; + } + counter++; + } else if (receivedData[i] == '}') { + if (counter > 0) { + counter--; + if (counter == 0) { + commands.push_back( + std::make_pair(&receivedData[beginIdx], &receivedData[i + 1])); } - else if (receivedData[i] == '}') - { - if (counter > 0) - { - counter--; - if (counter == 0) - { - commands.push_back(std::make_pair(&receivedData[beginIdx], &receivedData[i + 1])); - } - } - } + } } - return commands; + } + return commands; } // Creates a new command challenge, and adds it to an existing JSON document. -static DS2476::CmdResult addCommandChallenge(rapidjson::Document & document, CommandChallenge & commandChallenge) -{ - DS2476::Buffer buffer; - DS2476::CmdResult result = coproc.readRng(commandChallenge.size(), buffer); - if (result == DS2476::Success) - { - std::copy(buffer.begin(), buffer.end(), commandChallenge.begin()); - document.AddMember("challenge", rapidjson::Value(byteArrayToHexString(commandChallenge.data(), - commandChallenge.size()).c_str(), document.GetAllocator()).Move(), document.GetAllocator()); - } - return result; +static error_code addCommandChallenge(rapidjson::Document & document, + CommandChallenge & commandChallenge) { + error_code result = + readRng(coproc, commandChallenge.data(), commandChallenge.size()); + if (!result) { + document.AddMember( + "challenge", + rapidjson::Value(byteArrayToHexString(commandChallenge.data(), + commandChallenge.size()).c_str(), + document.GetAllocator()).Move(), + document.GetAllocator()); + } + return result; } // Adds signature information to an existing JSON document. -static DS2476::CmdResult signData(bool validSignature, const ResponseChallenge & challenge, rapidjson::Document & document) -{ - // Move contents of document to a new location and create an empty object in document. - rapidjson::Value data(rapidjson::kObjectType); - data.Swap(document); - // Convert data to a string and generate a signature from that string. - rapidjson::StringBuffer dataBuffer; - rapidjson::Writer<rapidjson::StringBuffer> writer(dataBuffer); - writer.SetMaxDecimalPlaces(jsonMaxDecimalPlaces); - data.Accept(writer); - std::vector<uint8_t> signDataBuffer(dataBuffer.GetString(), dataBuffer.GetString() + dataBuffer.GetLength()); - signDataBuffer.insert(signDataBuffer.end(), challenge.begin(), challenge.end()); - DS2476::Buffer ds2476Buffer(32); - ComputeSHA256(&signDataBuffer[0], signDataBuffer.size(), false, false, &ds2476Buffer[0]); - DS2476::CmdResult result = coproc.writeBuffer(ds2476Buffer); - if (result == DS2476::Success) - { - DS2476::Signature signatureBuffer; - result = coproc.generateEcdsaSignature(DS2476::KeyNumA, signatureBuffer); - if (result == DS2476::Success) - { - if (!validSignature) - signatureBuffer.r[0]++; - // Construct the final document with the original data and the generated signature. - rapidjson::Value signature(rapidjson::kObjectType); - signature.AddMember("r", rapidjson::Value(byteArrayToHexString(signatureBuffer.r.data(), - signatureBuffer.r.size()).c_str(), document.GetAllocator()).Move(), document.GetAllocator()); - signature.AddMember("s", rapidjson::Value(byteArrayToHexString(signatureBuffer.s.data(), - signatureBuffer.s.size()).c_str(), document.GetAllocator()).Move(), document.GetAllocator()); - document.AddMember("data", data, document.GetAllocator()); - document.AddMember("signature", signature, document.GetAllocator()); - } +static error_code signData(bool validSignature, + const ResponseChallenge & challenge, + rapidjson::Document & document) { + // Move contents of the document to a new location, and create an empty object + // in the document. + rapidjson::Value data(rapidjson::kObjectType); + data.Swap(document); + // Convert data to a string and generate a signature from that string. + rapidjson::StringBuffer dataBuffer; + rapidjson::Writer<rapidjson::StringBuffer> writer(dataBuffer); + writer.SetMaxDecimalPlaces(jsonMaxDecimalPlaces); + data.Accept(writer); + std::vector<uint8_t> signDataBuffer( + dataBuffer.GetString(), dataBuffer.GetString() + dataBuffer.GetLength()); + signDataBuffer.insert(signDataBuffer.end(), challenge.begin(), + challenge.end()); + Sha256::Hash hash; + ComputeSHA256(&signDataBuffer[0], signDataBuffer.size(), false, false, + hash.data()); + error_code result = coproc.writeBuffer(hash.data(), hash.size()); + if (!result) { + Ecc256::Signature signatureBuffer; + result = coproc.generateEcdsaSignature(DS2476::KeyNumA, signatureBuffer); + if (!result) { + if (!validSignature) + signatureBuffer.r[0]++; + // Construct the final document with the original data and the generated + // signature. + rapidjson::Value signature(rapidjson::kObjectType); + signature.AddMember( + "r", + rapidjson::Value(byteArrayToHexString(signatureBuffer.r.data(), + signatureBuffer.r.size()).c_str(), + document.GetAllocator()).Move(), + document.GetAllocator()); + signature.AddMember( + "s", + rapidjson::Value(byteArrayToHexString(signatureBuffer.s.data(), + signatureBuffer.s.size()).c_str(), + document.GetAllocator()).Move(), + document.GetAllocator()); + document.AddMember("data", data, document.GetAllocator()); + document.AddMember("signature", signature, document.GetAllocator()); } - return result; + } + return result; } -// Finalizes a command response to the server by adding the next command challenge and signing the data. -static DS2476::CmdResult finalizeResponse(bool validSignature, const ResponseChallenge & responseChallenge, - rapidjson::Document & document, CommandChallenge & commandChallenge) -{ - DS2476::CmdResult result = addCommandChallenge(document, commandChallenge); - if (result == DS2476::Success) - { - result = signData(validSignature, responseChallenge, document); - } - return result; +// Finalizes a command response to the server by adding the next command +// challenge and signing the data. +static error_code finalizeResponse(bool validSignature, + const ResponseChallenge & responseChallenge, + rapidjson::Document & document, + CommandChallenge & commandChallenge) { + error_code result = addCommandChallenge(document, commandChallenge); + if (!result) { + result = signData(validSignature, responseChallenge, document); + } + return result; } // Parse and verify a signed JSON string. template <typename VerifyDataIt> -static DS2476::CmdResult verifySignedData(VerifyDataIt verifyDataBegin, VerifyDataIt verifyDataEnd, - const CommandChallenge & commandChallenge, rapidjson::Document & signedData) -{ - using rapidjson::Value; - using std::string; - - // Parse string and validate object schema. - string verifyData(verifyDataBegin, verifyDataEnd); - signedData.Parse(verifyData.c_str()); - if (!(signedData.IsObject() && signedData.HasMember("data") && signedData.HasMember("signature"))) - { - signedData.RemoveAllMembers(); - return DS2476::AuthenticationError; - } - Value & data = signedData["data"]; - const Value & signature = signedData["signature"]; - if (!(data.IsObject() && signature.IsObject() && signature.HasMember("r") && signature.HasMember("s"))) - { - signedData.RemoveAllMembers(); - return DS2476::AuthenticationError; - } - const Value & signatureR = signature["r"]; - const Value & signatureS = signature["s"]; - if (!(signatureR.IsString() && signatureS.IsString())) - { - signedData.RemoveAllMembers(); - return DS2476::AuthenticationError; - } - - // Parse signature. - std::vector<uint8_t> parsedBytes = - hexStringToByteArray(string(signatureR.GetString(), signatureR.GetStringLength())); - DS2476::Signature signatureBuffer; - if (parsedBytes.size() != signatureBuffer.r.size()) - { - signedData.RemoveAllMembers(); - return DS2476::AuthenticationError; - } - std::copy(parsedBytes.begin(), parsedBytes.end(), signatureBuffer.r.begin()); - parsedBytes = hexStringToByteArray(string(signatureS.GetString(), signatureS.GetStringLength())); - if (parsedBytes.size() != signatureBuffer.s.size()) - { - signedData.RemoveAllMembers(); - return DS2476::AuthenticationError; - } - std::copy(parsedBytes.begin(), parsedBytes.end(), signatureBuffer.s.begin()); - - // Get data to hash. - // Need to use string searching here since there isn't currently a way to access raw elements - // in rapidjson, and creating another copy of the data might consume too much memory. - const string rawDataSearch("\"data\":"); - string::size_type rawDataBegin = verifyData.find(rawDataSearch); - if ((rawDataBegin == string::npos) || ((rawDataBegin + rawDataSearch.size()) >= verifyData.size())) - { - signedData.RemoveAllMembers(); - return DS2476::AuthenticationError; - } - rawDataBegin += rawDataSearch.size(); - string::size_type rawDataEnd = verifyData.find(",\"signature\"", rawDataBegin); - if (rawDataEnd == string::npos) - { - signedData.RemoveAllMembers(); - return DS2476::AuthenticationError; - } - verifyData.erase(rawDataEnd); - verifyData.erase(0, rawDataBegin); - // Add in command challenge to data that will be verified. - verifyData.append(commandChallenge.begin(), commandChallenge.end()); - - // Compute hash of the data. - const string::size_type chunkSize = 64; - for (string::size_type i = 0; i < verifyData.size(); i += chunkSize) - { - const string::size_type remainingLength = verifyData.size() - i; - DS2476::CmdResult result = coproc.computeMultiblockHash(i == 0, remainingLength < chunkSize, - DS2476::Buffer(verifyData.c_str() + i, verifyData.c_str() + i + std::min(remainingLength, chunkSize))); - if (result != DS2476::Success) - { - signedData.RemoveAllMembers(); - return result; - } - } - // Verify signature. - DS2476::CmdResult result = - coproc.verifyEcdsaSignature(DS2476::KeyNumC, DS2476::THASH, signatureBuffer); - if (result != DS2476::Success) - { - signedData.RemoveAllMembers(); - return result; - } - - // Strip signing information from document. - rapidjson::Value swapObject(rapidjson::kObjectType); - swapObject.Swap(data); - swapObject.Swap(signedData); +static error_code verifySignedData(VerifyDataIt verifyDataBegin, + VerifyDataIt verifyDataEnd, + const CommandChallenge & commandChallenge, + rapidjson::Document & signedData) { + using rapidjson::Value; + using std::string; + + // Parse string and validate object schema. + string verifyData(verifyDataBegin, verifyDataEnd); + signedData.Parse(verifyData.c_str()); + if (!(signedData.IsObject() && signedData.HasMember("data") && + signedData.HasMember("signature"))) { + signedData.RemoveAllMembers(); + return make_error_code(DS2476::AuthenticationError); + } + Value & data = signedData["data"]; + const Value & signature = signedData["signature"]; + if (!(data.IsObject() && signature.IsObject() && signature.HasMember("r") && + signature.HasMember("s"))) { + signedData.RemoveAllMembers(); + return make_error_code(DS2476::AuthenticationError); + } + const Value & signatureR = signature["r"]; + const Value & signatureS = signature["s"]; + if (!(signatureR.IsString() && signatureS.IsString())) { + signedData.RemoveAllMembers(); + return make_error_code(DS2476::AuthenticationError); + } + + // Parse signature. + std::vector<uint8_t> parsedBytes = hexStringToByteArray( + string(signatureR.GetString(), signatureR.GetStringLength())); + Ecc256::Signature signatureBuffer; + if (parsedBytes.size() != signatureBuffer.r.size()) { + signedData.RemoveAllMembers(); + return make_error_code(DS2476::AuthenticationError); + } + std::copy(parsedBytes.begin(), parsedBytes.end(), signatureBuffer.r.begin()); + parsedBytes = hexStringToByteArray( + string(signatureS.GetString(), signatureS.GetStringLength())); + if (parsedBytes.size() != signatureBuffer.s.size()) { + signedData.RemoveAllMembers(); + return make_error_code(DS2476::AuthenticationError); + } + std::copy(parsedBytes.begin(), parsedBytes.end(), signatureBuffer.s.begin()); + + // Get data to hash. + // Need to use string searching here since there isn't currently a way to + // access raw elements in rapidjson, and creating another copy of the data + // might consume too much memory. + const string rawDataSearch("\"data\":"); + string::size_type rawDataBegin = verifyData.find(rawDataSearch); + if ((rawDataBegin == string::npos) || + ((rawDataBegin + rawDataSearch.size()) >= verifyData.size())) { + signedData.RemoveAllMembers(); + return make_error_code(DS2476::AuthenticationError); + } + rawDataBegin += rawDataSearch.size(); + string::size_type rawDataEnd = + verifyData.find(",\"signature\"", rawDataBegin); + if (rawDataEnd == string::npos) { + signedData.RemoveAllMembers(); + return make_error_code(DS2476::AuthenticationError); + } + verifyData.erase(rawDataEnd); + verifyData.erase(0, rawDataBegin); + // Add in command challenge to data that will be verified. + verifyData.append(commandChallenge.begin(), commandChallenge.end()); + + // Compute hash of the data. + error_code result = computeMultiblockHash( + coproc, reinterpret_cast<const uint_least8_t *>(verifyData.data()), + verifyData.size()); + if (result) { + signedData.RemoveAllMembers(); return result; + } + // Verify signature. + result = coproc.verifyEcdsaSignature(DS2476::KeyNumC, DS2476::THASH, + signatureBuffer); + if (result) { + signedData.RemoveAllMembers(); + return result; + } + + // Strip signing information from document. + rapidjson::Value swapObject(rapidjson::kObjectType); + swapObject.Swap(data); + swapObject.Swap(signedData); + return result; } // Send a JSON document to the server. -static void sendJson(const rapidjson::Value & document, TCPSocket & socket) -{ - rapidjson::StringBuffer buffer; - rapidjson::Writer<rapidjson::StringBuffer> writer(buffer); - writer.SetMaxDecimalPlaces(jsonMaxDecimalPlaces); - document.Accept(writer); - socket.send(buffer.GetString(), buffer.GetLength()); -} - -void NormalOperationWindow::sendMessage(const char * message) -{ - rapidjson::MemoryPoolAllocator<> allocator(defaultChunkSize); - rapidjson::Document document(rapidjson::kObjectType, &allocator); - document.AddMember("message", rapidjson::StringRef(message), document.GetAllocator()); - sendJson(document, *socket); -} - -static std::string getValidSignatureButtonText(bool validSignature) -{ - return validSignature ? "Use invalid sig." : "Use valid sig."; +static void sendJson(const rapidjson::Value & document, TCPSocket & socket) { + rapidjson::StringBuffer buffer; + rapidjson::Writer<rapidjson::StringBuffer> writer(buffer); + writer.SetMaxDecimalPlaces(jsonMaxDecimalPlaces); + document.Accept(writer); + socket.send(buffer.GetString(), buffer.GetLength()); } -void NormalOperationWindow::showWebId() -{ - if (windowManager() != NULL) - { - std::auto_ptr<Window> window(new DisplayIdWindow(DisplayIdWindow::PopupMode)); - windowManager()->push(window); - } +void NormalOperationWindow::sendMessage(const char * message) { + rapidjson::MemoryPoolAllocator<> allocator(defaultChunkSize); + rapidjson::Document document(rapidjson::kObjectType, &allocator); + document.AddMember("message", rapidjson::StringRef(message), + document.GetAllocator()); + sendJson(document, *socket); } -void NormalOperationWindow::toggleValidSignature() -{ - validSignature = !validSignature; - validSignatureButton.setText(getValidSignatureButtonText(validSignature)); -} - -NormalOperationWindow::NormalOperationWindow(std::auto_ptr<TCPSocket> & socket) : - socket(socket) /* Move construct */, sendChallenge(true), - validSignature(true), lastSensorNodeState(Disconnected), lastObjectTemp(0), lastAmbientTemp(0) -{ - assert(this->socket.get() != NULL); - - validSignatureButton.setParent(this); - validSignatureButton.setText(getValidSignatureButtonText(validSignature)); - validSignatureButton.setClickedHandler(Button::EventHandler(this, &NormalOperationWindow::toggleValidSignature)); - showWebIdButton.setParent(this); - showWebIdButton.setText("Show web ID"); - showWebIdButton.setClickedHandler(Button::EventHandler(this, &NormalOperationWindow::showWebId)); - validSignatureButton.setFocused(); +static std::string getValidSignatureButtonText(bool validSignature) { + return validSignature ? "Use invalid sig." : "Use valid sig."; } -NormalOperationWindow::SensorNodeState NormalOperationWindow::detectSensorNode() -{ - SensorNodeState sensorNodeState; - if (sensorNode.detect()) - { - bool provisioned; - if (sensorNode.getProvisioned(provisioned)) - { - if (provisioned) - { - if (sensorNode.authenticate()) - { - bool laserEnabled; - if (sensorNode.getLaserEnabled(laserEnabled)) - { - sensorNodeState = (laserEnabled ? ValidLaserEnabled : ValidLaserDisabled); - } - else - { - sensorNodeState = Disconnected; - } - } - else - { - sensorNodeState = Invalid; - } - } - else - { - bool provisionResult = sensorNode.provision(); - if (provisionResult) - { - // Detect the new state after provisioning. - sensorNodeState = detectSensorNode(); - } - else - { - sensorNodeState = FailedProvision; - } - } - } - else - { - sensorNodeState = Disconnected; - } - } - else - { - sensorNodeState = Disconnected; - } - return sensorNodeState; +void NormalOperationWindow::showWebId(Button *) { + if (windowManager() != NULL) { + std::auto_ptr<Window> window( + new DisplayIdWindow(DisplayIdWindow::PopupMode)); + windowManager()->push(window); + } +} + +void NormalOperationWindow::toggleValidSignature(Button *) { + validSignature = !validSignature; + validSignatureButton.setText(getValidSignatureButtonText(validSignature)); +} + +NormalOperationWindow::NormalOperationWindow(std::auto_ptr<TCPSocket> & socket) + : socket(socket) /* Move construct */, sendChallenge(true), + validSignature(true), lastSensorNodeState(SensorNode::Disconnected), + lastObjectTemp(0), lastAmbientTemp(0) { + assert(this->socket.get() != NULL); + + validSignatureButton.setParent(this); + validSignatureButton.setText(getValidSignatureButtonText(validSignature)); + validSignatureButton.setClickedHandler( + makeFunction(this, &NormalOperationWindow::toggleValidSignature)); + showWebIdButton.setParent(this); + showWebIdButton.setText("Show web ID"); + showWebIdButton.setClickedHandler( + makeFunction(this, &NormalOperationWindow::showWebId)); + validSignatureButton.setFocused(); } -NormalOperationWindow::Result NormalOperationWindow::sendStatus(const ResponseChallenge & responseChallenge) -{ - rapidjson::MemoryPoolAllocator<> allocator(defaultChunkSize); - rapidjson::Document document(rapidjson::kObjectType, &allocator); - - // Insert Web ID. - document.AddMember("id", rapidjson::StringRef(webId.c_str()), document.GetAllocator()); - - // Insert device public key. - rapidjson::Value publicKey(rapidjson::kObjectType); - DS2476::Page page; - DS2476::CmdResult result = coproc.readMemory(DS2476::PublicKeyAX, page); - if (result != DS2476::Success) - { - if (windowManager() != NULL) - { - windowManager()->pop(); - std::auto_ptr<Window> window(new ErrorWindow("Failed to read PublicKeyAX")); - windowManager()->push(window); - } - return WindowsChanged; +NormalOperationWindow::Result +NormalOperationWindow::sendStatus(const ResponseChallenge & responseChallenge) { + rapidjson::MemoryPoolAllocator<> allocator(defaultChunkSize); + rapidjson::Document document(rapidjson::kObjectType, &allocator); + + // Insert Web ID. + document.AddMember("id", rapidjson::StringRef(webId.c_str()), + document.GetAllocator()); + + // Insert device public key. + rapidjson::Value publicKey(rapidjson::kObjectType); + DS2476::Page page; + error_code result = coproc.readMemory(DS2476::PublicKeyAX, page); + if (result) { + if (windowManager() != NULL) { + windowManager()->pop(); + std::auto_ptr<Window> window( + new ErrorWindow("Failed to read PublicKeyAX")); + windowManager()->push(window); } - publicKey.AddMember("x", rapidjson::Value(byteArrayToHexString(page.data(), page.size()).c_str(), - document.GetAllocator()).Move(), document.GetAllocator()); - result = coproc.readMemory(DS2476::PublicKeyAY, page); - if (result != DS2476::Success) - { - if (windowManager() != NULL) - { - windowManager()->pop(); - std::auto_ptr<Window> window(new ErrorWindow("Failed to read PublicKeyAY")); - windowManager()->push(window); - } - return WindowsChanged; + return WindowsChanged; + } + publicKey.AddMember( + "x", + rapidjson::Value(byteArrayToHexString(page.data(), page.size()).c_str(), + document.GetAllocator()).Move(), + document.GetAllocator()); + result = coproc.readMemory(DS2476::PublicKeyAY, page); + if (result) { + if (windowManager() != NULL) { + windowManager()->pop(); + std::auto_ptr<Window> window( + new ErrorWindow("Failed to read PublicKeyAY")); + windowManager()->push(window); } - publicKey.AddMember("y", rapidjson::Value(byteArrayToHexString(page.data(), page.size()).c_str(), - document.GetAllocator()).Move(), document.GetAllocator()); - document.AddMember("publicKey", publicKey, document.GetAllocator()); + return WindowsChanged; + } + publicKey.AddMember( + "y", + rapidjson::Value(byteArrayToHexString(page.data(), page.size()).c_str(), + document.GetAllocator()).Move(), + document.GetAllocator()); + document.AddMember("publicKey", publicKey, document.GetAllocator()); - // Insert device certificate. - rapidjson::Value certificate(rapidjson::kObjectType); - result = coproc.readMemory(DS2476::UserData14, page); - if (result != DS2476::Success) - { - if (windowManager() != NULL) - { - windowManager()->pop(); - std::auto_ptr<Window> window(new ErrorWindow("Failed to read UserData14")); - windowManager()->push(window); - } - return WindowsChanged; + // Insert device certificate. + rapidjson::Value certificate(rapidjson::kObjectType); + result = coproc.readMemory(DS2476::UserData14, page); + if (result) { + if (windowManager() != NULL) { + windowManager()->pop(); + std::auto_ptr<Window> window( + new ErrorWindow("Failed to read UserData14")); + windowManager()->push(window); } - certificate.AddMember("r", rapidjson::Value(byteArrayToHexString(page.data(), page.size()).c_str(), - document.GetAllocator()).Move(), document.GetAllocator()); - result = coproc.readMemory(DS2476::UserData15, page); - if (result != DS2476::Success) - { - if (windowManager() != NULL) - { - windowManager()->pop(); - std::auto_ptr<Window> window(new ErrorWindow("Failed to read UserData15")); - windowManager()->push(window); - } - return WindowsChanged; + return WindowsChanged; + } + certificate.AddMember( + "r", + rapidjson::Value(byteArrayToHexString(page.data(), page.size()).c_str(), + document.GetAllocator()).Move(), + document.GetAllocator()); + result = coproc.readMemory(DS2476::UserData15, page); + if (result) { + if (windowManager() != NULL) { + windowManager()->pop(); + std::auto_ptr<Window> window( + new ErrorWindow("Failed to read UserData15")); + windowManager()->push(window); } - certificate.AddMember("s", rapidjson::Value(byteArrayToHexString(page.data(), page.size()).c_str(), - document.GetAllocator()).Move(), document.GetAllocator()); - document.AddMember("certificate", certificate, document.GetAllocator()); - - // Sign data and transmit to server. - result = finalizeResponse(validSignature, responseChallenge, document, commandChallenge); - if (result != DS2476::Success) - { - if (windowManager() != NULL) - { - windowManager()->pop(); - std::auto_ptr<Window> window(new ErrorWindow("Failed to sign data")); - windowManager()->push(window); - } - return WindowsChanged; + return WindowsChanged; + } + certificate.AddMember( + "s", + rapidjson::Value(byteArrayToHexString(page.data(), page.size()).c_str(), + document.GetAllocator()).Move(), + document.GetAllocator()); + document.AddMember("certificate", certificate, document.GetAllocator()); + + // Sign data and transmit to server. + result = finalizeResponse(validSignature, responseChallenge, document, + commandChallenge); + if (result) { + if (windowManager() != NULL) { + windowManager()->pop(); + std::auto_ptr<Window> window(new ErrorWindow("Failed to sign data")); + windowManager()->push(window); } - sendJson(document, *socket); - return NoChange; + return WindowsChanged; + } + sendJson(document, *socket); + return NoChange; } -NormalOperationWindow::Result NormalOperationWindow::sendObjectTemp(const ResponseChallenge & responseChallenge) -{ - rapidjson::MemoryPoolAllocator<> allocator(defaultChunkSize); - rapidjson::Document document(rapidjson::kObjectType, &allocator); - - // Read object temperature and add to document. - double objectTemp; - bool sensorResult = sensorNode.readTemp(SensorNode::ObjectTemp, objectTemp); - if (!sensorResult) - { - if (windowManager() != NULL) - { - windowManager()->pop(); - std::auto_ptr<Window> window(new ErrorWindow("Failed to read object temperature")); - windowManager()->push(window); - } - return WindowsChanged; +NormalOperationWindow::Result NormalOperationWindow::sendObjectTemp( + const ResponseChallenge & responseChallenge) { + rapidjson::MemoryPoolAllocator<> allocator(defaultChunkSize); + rapidjson::Document document(rapidjson::kObjectType, &allocator); + + // Read object temperature and add to document. + double objectTemp; + bool sensorResult = sensorNode.readTemp(SensorNode::ObjectTemp, objectTemp); + if (!sensorResult) { + if (windowManager() != NULL) { + windowManager()->pop(); + std::auto_ptr<Window> window( + new ErrorWindow("Failed to read object temperature")); + windowManager()->push(window); } - document.AddMember("objectTemp", objectTemp, document.GetAllocator()); - - // Sign data and transmit to server. - DS2476::CmdResult coprocResult = finalizeResponse(validSignature, responseChallenge, document, commandChallenge); - if (coprocResult != DS2476::Success) - { - if (windowManager() != NULL) - { - windowManager()->pop(); - std::auto_ptr<Window> window(new ErrorWindow("Failed to sign data")); - windowManager()->push(window); - } - return WindowsChanged; + return WindowsChanged; + } + document.AddMember("objectTemp", objectTemp, document.GetAllocator()); + + // Sign data and transmit to server. + error_code coprocResult = finalizeResponse(validSignature, responseChallenge, + document, commandChallenge); + if (coprocResult) { + if (windowManager() != NULL) { + windowManager()->pop(); + std::auto_ptr<Window> window(new ErrorWindow("Failed to sign data")); + windowManager()->push(window); } - sendJson(document, *socket); + return WindowsChanged; + } + sendJson(document, *socket); - lastObjectTemp = objectTemp; - return NoChange; + lastObjectTemp = objectTemp; + return NoChange; } -NormalOperationWindow::Result NormalOperationWindow::sendAmbientTemp(const ResponseChallenge & responseChallenge) -{ - rapidjson::MemoryPoolAllocator<> allocator(defaultChunkSize); - rapidjson::Document document(rapidjson::kObjectType, &allocator); - - // Read ambient temperature and add to document. - double ambientTemp; - bool sensorResult = sensorNode.readTemp(SensorNode::AmbientTemp, ambientTemp); - if (!sensorResult) - { - if (windowManager() != NULL) - { - windowManager()->pop(); - std::auto_ptr<Window> window(new ErrorWindow("Failed to read ambient temperature")); - windowManager()->push(window); - } - return WindowsChanged; +NormalOperationWindow::Result NormalOperationWindow::sendAmbientTemp( + const ResponseChallenge & responseChallenge) { + rapidjson::MemoryPoolAllocator<> allocator(defaultChunkSize); + rapidjson::Document document(rapidjson::kObjectType, &allocator); + + // Read ambient temperature and add to document. + double ambientTemp; + bool sensorResult = sensorNode.readTemp(SensorNode::AmbientTemp, ambientTemp); + if (!sensorResult) { + if (windowManager() != NULL) { + windowManager()->pop(); + std::auto_ptr<Window> window( + new ErrorWindow("Failed to read ambient temperature")); + windowManager()->push(window); } - document.AddMember("ambientTemp", ambientTemp, document.GetAllocator()); - - // Sign data and transmit to server. - DS2476::CmdResult coprocResult = finalizeResponse(validSignature, responseChallenge, document, commandChallenge); - if (coprocResult != DS2476::Success) - { - if (windowManager() != NULL) - { - windowManager()->pop(); - std::auto_ptr<Window> window(new ErrorWindow("Failed to sign data")); - windowManager()->push(window); - } - return WindowsChanged; + return WindowsChanged; + } + document.AddMember("ambientTemp", ambientTemp, document.GetAllocator()); + + // Sign data and transmit to server. + error_code coprocResult = finalizeResponse(validSignature, responseChallenge, + document, commandChallenge); + if (coprocResult) { + if (windowManager() != NULL) { + windowManager()->pop(); + std::auto_ptr<Window> window(new ErrorWindow("Failed to sign data")); + windowManager()->push(window); } - sendJson(document, *socket); - - lastAmbientTemp = ambientTemp; - return NoChange; + return WindowsChanged; + } + sendJson(document, *socket); + + lastAmbientTemp = ambientTemp; + return NoChange; +} + +void NormalOperationWindow::displayImage( + const std::vector<uint8_t> & imageData) { + if (windowManager() != NULL) { + std::auto_ptr<Graphic> image( + new Image(Bitmap(&imageData[0], imageData.size(), 64))); + std::auto_ptr<Window> window(new DisplayGraphicWindow(image)); + windowManager()->push(window); + } } -void NormalOperationWindow::displayImage(const std::vector<uint8_t> & imageData) -{ - if (windowManager() != NULL) - { - std::auto_ptr<Graphic> image(new Image(Bitmap(&imageData[0], imageData.size(), 64))); - std::auto_ptr<Window> window(new DisplayGraphicWindow(image)); +NormalOperationWindow::Result +NormalOperationWindow::processReceivedData(size_t recvBufSize) { + // Separate commands and process each one. + std::vector<std::pair<const char *, const char *> > commands = + separateCommands(recvBuf, recvBufSize); + for (std::vector<std::pair<const char *, const char *> >::const_iterator it = + commands.begin(); + it != commands.end(); it++) { + rapidjson::MemoryPoolAllocator<> allocator(defaultChunkSize); + rapidjson::Document data(&allocator); + // Verify command signature. + error_code verifySignedResult = + verifySignedData(it->first, it->second, commandChallenge, data); + if (!verifySignedResult) { + // Verify command schema. + sendMessage("Received data is authentic"); + if (data.IsObject() && data.HasMember("command")) { + const rapidjson::Value & command = data["command"]; + if (command.IsString()) { + // Parse challenge if included. + ResponseChallenge responseChallenge; + if (data.HasMember("challenge")) { + const rapidjson::Value & challenge = data["challenge"]; + if (challenge.IsString()) { + responseChallenge = hexStringToByteArray(std::string( + challenge.GetString(), challenge.GetStringLength())); + } + } + + // Execute the command. + if (command == "getStatus") { + Result result = sendStatus(responseChallenge); + if (result != NoChange) + return result; + } else if (command == "readObjectTemp") { + if ((lastSensorNodeState == SensorNode::ValidLaserDisabled) || + (lastSensorNodeState == SensorNode::ValidLaserEnabled)) { + Result result = sendObjectTemp(responseChallenge); + if (result != NoChange) + return result; + invalidate(); + } + } else if (command == "readAmbientTemp") { + if ((lastSensorNodeState == SensorNode::ValidLaserDisabled) || + (lastSensorNodeState == SensorNode::ValidLaserEnabled)) { + Result result = sendAmbientTemp(responseChallenge); + if (result != NoChange) + return result; + invalidate(); + } + } else if (command == "enableModule") { + if (lastSensorNodeState == SensorNode::ValidLaserDisabled) { + const error_code result = sensorNode.setLaserEnabled( + true, + makeFunction(this, &NormalOperationWindow::sendMessage)); + if (!result) { + lastSensorNodeState = SensorNode::ValidLaserEnabled; + invalidate(); + } + } + } else if (command == "disableModule") { + if (lastSensorNodeState == SensorNode::ValidLaserEnabled) { + const error_code result = sensorNode.setLaserEnabled( + false, + makeFunction(this, &NormalOperationWindow::sendMessage)); + if (!result) { + lastSensorNodeState = SensorNode::ValidLaserDisabled; + invalidate(); + } + } + } else if (command == "displayImage") { + if (data.HasMember("image")) { + const rapidjson::Value & image = data["image"]; + if (image.IsString()) { + displayImage(hexStringToByteArray( + std::string(image.GetString(), image.GetStringLength()))); + return WindowsChanged; + } + } + } + } + } + } else if (verifySignedResult == + make_error_code(DS2476::AuthenticationError)) { + const char message[] = "Received data is not authentic"; + sendMessage(message); + std::auto_ptr<Graphic> messageText(new Text); + Text & messageTextRef = *static_cast<Text *>(messageText.get()); + messageTextRef.setText(message); + messageTextRef.setWordWrap(true); + if (windowManager() != NULL) { + std::auto_ptr<Window> window(new DisplayGraphicWindow(messageText)); windowManager()->push(window); + } + return WindowsChanged; + } else { + const char message[] = "Unable to verify received data"; + sendMessage(message); + if (windowManager() != NULL) { + std::auto_ptr<Window> window(new ErrorWindow(message)); + windowManager()->push(window); + } + return WindowsChanged; } + } + return NoChange; } -NormalOperationWindow::Result NormalOperationWindow::processReceivedData(size_t recvBufSize) -{ - // Separate commands and process each one. - std::vector<std::pair<const char *, const char *> > commands = separateCommands(recvBuf, recvBufSize); - for (std::vector<std::pair<const char *, const char *> >::const_iterator it = commands.begin(); it != commands.end(); it++) - { - rapidjson::MemoryPoolAllocator<> allocator(defaultChunkSize); - rapidjson::Document data(&allocator); - // Verify command signature. - DS2476::CmdResult verifySignedResult = verifySignedData(it->first, it->second, commandChallenge, data); - switch (verifySignedResult) - { - case DS2476::Success: // Command passed authentication. - { - // Verify command schema. - sendMessage("Received data is authentic"); - if (data.IsObject() && data.HasMember("command")) - { - const rapidjson::Value & command = data["command"]; - if (command.IsString()) - { - // Parse challenge if included. - ResponseChallenge responseChallenge; - if (data.HasMember("challenge")) - { - const rapidjson::Value & challenge = data["challenge"]; - if (challenge.IsString()) - { - responseChallenge = - hexStringToByteArray(std::string(challenge.GetString(), challenge.GetStringLength())); - } - } - - // Execute the command. - if (command == "getStatus") - { - Result result = sendStatus(responseChallenge); - if (result != NoChange) - return result; - } - else if (command == "readObjectTemp") - { - if ((lastSensorNodeState == ValidLaserDisabled) || (lastSensorNodeState == ValidLaserEnabled)) - { - Result result = sendObjectTemp(responseChallenge); - if (result != NoChange) - return result; - invalidate(); - } - } - else if (command == "readAmbientTemp") - { - if ((lastSensorNodeState == ValidLaserDisabled) || (lastSensorNodeState == ValidLaserEnabled)) - { - Result result = sendAmbientTemp(responseChallenge); - if (result != NoChange) - return result; - invalidate(); - } - } - else if (command == "enableModule") - { - if (lastSensorNodeState == ValidLaserDisabled) - { - if (sensorNode.setLaserEnabled(true, - SensorNode::PrintHandler(this, &NormalOperationWindow::sendMessage))) - { - lastSensorNodeState = ValidLaserEnabled; - invalidate(); - } - } - } - else if (command == "disableModule") - { - if (lastSensorNodeState == ValidLaserEnabled) - { - if (sensorNode.setLaserEnabled(false, - SensorNode::PrintHandler(this, &NormalOperationWindow::sendMessage))) - { - lastSensorNodeState = ValidLaserDisabled; - invalidate(); - } - } - } - else if (command == "displayImage") - { - if (data.HasMember("image")) - { - const rapidjson::Value & image = data["image"]; - if (image.IsString()) - { - displayImage( - hexStringToByteArray( - std::string(image.GetString(), image.GetStringLength()) - ) - ); - return WindowsChanged; - } - } - } - } - } - } - break; - - case DS2476::AuthenticationError: // Command failed authentication. - { - const char message[] = "Received data is not authentic"; - sendMessage(message); - std::auto_ptr<Graphic> messageText(new Text); - Text & messageTextRef = *static_cast<Text *>(messageText.get()); - messageTextRef.setText(message); - messageTextRef.setWordWrap(true); - if (windowManager() != NULL) - { - std::auto_ptr<Window> window(new DisplayGraphicWindow(messageText)); - windowManager()->push(window); - } - } - return WindowsChanged; - - default: // Hardware error occurred. - { - const char message[] = "Unable to verify received data"; - sendMessage(message); - if (windowManager() != NULL) - { - std::auto_ptr<Window> window(new ErrorWindow(message)); - windowManager()->push(window); - } - } - return WindowsChanged; - } - } - return NoChange; +void NormalOperationWindow::resized() { + showWebIdButton.resize(width(), showWebIdButton.preferredHeight()); + showWebIdButton.move(0, height() - showWebIdButton.height()); + validSignatureButton.resize(width(), validSignatureButton.preferredHeight()); + validSignatureButton.move(0, showWebIdButton.y() - + validSignatureButton.height() - 1); +} + +static std::string doubleToString(double input) { + char inputString[8]; + snprintf(inputString, sizeof(inputString) / sizeof(inputString[0]), "%.2f", + input); + return std::string(inputString); +} + +void NormalOperationWindow::doRender(Bitmap & bitmap, int xOffset, + int yOffset) const { + // Format current status text. + std::string sensorNodeStateText; + switch (lastSensorNodeState) { + case SensorNode::Disconnected: + sensorNodeStateText = "Disconnected"; + break; + + case SensorNode::Invalid: + sensorNodeStateText = "Invalid"; + break; + + case SensorNode::ValidLaserDisabled: + sensorNodeStateText = "Valid, laser disabled"; + break; + + case SensorNode::ValidLaserEnabled: + sensorNodeStateText = "Valid, laser enabled"; + break; + + case SensorNode::NotProvisioned: + break; + } + + Text description; + description.setText("Object temp: " + doubleToString(lastObjectTemp) + + "\nAmbient temp: " + doubleToString(lastAmbientTemp) + + "\nSensor node: " + sensorNodeStateText); + description.resize(width(), validSignatureButton.y()); + description.setWordWrap(true); + description.render(bitmap, xOffset + x(), yOffset + y()); + validSignatureButton.render(bitmap, xOffset + x(), yOffset + y()); + showWebIdButton.render(bitmap, xOffset + x(), yOffset + y()); } -void NormalOperationWindow::resized() -{ - showWebIdButton.resize(width(), showWebIdButton.preferredHeight()); - showWebIdButton.move(0, height() - showWebIdButton.height()); - validSignatureButton.resize(width(), validSignatureButton.preferredHeight()); - validSignatureButton.move(0, showWebIdButton.y() - validSignatureButton.height() - 1); -} - -static std::string doubleToString(double input) -{ - char inputString[8]; - snprintf(inputString, sizeof(inputString) / sizeof(inputString[0]), "%.2f", input); - return std::string(inputString); -} +void NormalOperationWindow::updated() { + // Detect sensor node. + std::pair<SensorNode::State, error_code> sensorNodeState = + sensorNode.detect(); + if (sensorNodeState.first == SensorNode::NotProvisioned) { + const error_code result = sensorNode.provision(); + if (result) { + if (windowManager() != NULL) { + windowManager()->pop(); + std::auto_ptr<Window> window( + new ErrorWindow("Sensor node provision failed")); + windowManager()->push(window); + } + return; + } + sensorNodeState = sensorNode.detect(); + } + if (sensorNodeState.first != lastSensorNodeState) { + lastSensorNodeState = sensorNodeState.first; + invalidate(); + } -void NormalOperationWindow::doRender(Bitmap & bitmap, int xOffset, int yOffset) const -{ - // Format current status text. - std::string sensorNodeStateText; - switch (lastSensorNodeState) - { - case Disconnected: - sensorNodeStateText = "Disconnected"; - break; - - case Invalid: - sensorNodeStateText = "Invalid"; - break; - - case ValidLaserDisabled: - sensorNodeStateText = "Valid, laser disabled"; - break; - - case ValidLaserEnabled: - sensorNodeStateText = "Valid, laser enabled"; - break; - - case FailedProvision: - break; + // Send challenge on first connection. + if (sendChallenge) { + rapidjson::MemoryPoolAllocator<> allocator(defaultChunkSize); + rapidjson::Document document(rapidjson::kObjectType, &allocator); + error_code result = addCommandChallenge(document, commandChallenge); + if (!result) { + sendJson(document, *socket); + sendChallenge = false; } - - Text description; - description.setText("Object temp: " + doubleToString(lastObjectTemp) + - "\nAmbient temp: " + doubleToString(lastAmbientTemp) + - "\nSensor node: " + sensorNodeStateText); - description.resize(width(), validSignatureButton.y()); - description.setWordWrap(true); - description.render(bitmap, xOffset + x(), yOffset + y()); - validSignatureButton.render(bitmap, xOffset + x(), yOffset + y()); - showWebIdButton.render(bitmap, xOffset + x(), yOffset + y()); + } + // Process socket data. + else { + int recvResult = + socket->recv(recvBuf, sizeof(recvBuf) / sizeof(recvBuf[0])); + if (recvResult > 0) { + std::printf("%*s\n", recvResult, recvBuf); + Result result = processReceivedData(recvResult); + if (result != NoChange) + return; + } else if (recvResult != NSAPI_ERROR_WOULD_BLOCK) { + if (windowManager() != NULL) { + windowManager()->pop(); + std::auto_ptr<Window> window(new ErrorWindow("Socket receive failed")); + windowManager()->push(window); + } + return; + } + } } -void NormalOperationWindow::updated() -{ - // Detect sensor node. - SensorNodeState sensorNodeState = detectSensorNode(); - if (sensorNodeState == FailedProvision) - { - if (windowManager() != NULL) - { - windowManager()->pop(); - std::auto_ptr<Window> window(new ErrorWindow("Sensor node provision failed")); - windowManager()->push(window); - } - return; - } - if (sensorNodeState != lastSensorNodeState) - { - lastSensorNodeState = sensorNodeState; - invalidate(); - } - - // Send challenge on first connection. - if (sendChallenge) - { - rapidjson::MemoryPoolAllocator<> allocator(defaultChunkSize); - rapidjson::Document document(rapidjson::kObjectType, &allocator); - DS2476::CmdResult result = addCommandChallenge(document, commandChallenge); - if (result == DS2476::Success) - { - sendJson(document, *socket); - sendChallenge = false; - } - } - // Process socket data. - else - { - int recvResult = socket->recv(recvBuf, sizeof(recvBuf) / sizeof(recvBuf[0])); - if (recvResult > 0) - { - std::printf("%*s\n", recvResult, recvBuf); - Result result = processReceivedData(recvResult); - if (result != NoChange) - return; - } - else if (recvResult != NSAPI_ERROR_WOULD_BLOCK) - { - if (windowManager() != NULL) - { - windowManager()->pop(); - std::auto_ptr<Window> window(new ErrorWindow("Socket receive failed")); - windowManager()->push(window); - } - return; - } - } +bool NormalOperationWindow::doProcessKey(Key key) { + bool handled; + switch (key) { + case UpKey: + validSignatureButton.setFocused(); + handled = true; + break; + + case DownKey: + showWebIdButton.setFocused(); + handled = true; + break; + + default: + handled = false; + break; + } + return handled; } - -bool NormalOperationWindow::doProcessKey(Key key) -{ - bool handled; - switch (key) - { - case UpKey: - validSignatureButton.setFocused(); - handled = true; - break; - - case DownKey: - showWebIdButton.setFocused(); - handled = true; - break; - - default: - handled = false; - break; - } - return handled; -} -
--- a/NormalOperationWindow.hpp Thu Jun 01 14:21:58 2017 -0500 +++ b/NormalOperationWindow.hpp Mon Nov 06 18:12:27 2017 -0600 @@ -36,74 +36,66 @@ #include <memory> #include <vector> #include <TCPSocket.h> -#include <array.h> +#include <MaximInterface/Utilities/array.hpp> #include "Button.hpp" +#include "SensorNode.hpp" #include "Window.hpp" /// Challenge received from the server with a command to sign the response against. typedef std::vector<uint8_t> ResponseChallenge; -/// Challenge sent to the server with a command response to sign the next command against. -typedef OneWire::array<uint8_t, 32> CommandChallenge; +/// Challenge sent to the server with a command response to sign the next +/// command against. +typedef MaximInterface::array<uint8_t, 32> CommandChallenge; -/// Handles normal operation of the demo including displaying status information and processing -/// commands from the server. -class NormalOperationWindow : public Window -{ +/// Handles normal operation of the demo including displaying status information +/// and processing commands from the server. +class NormalOperationWindow : public Window { public: - /// @param socket Socket that has been initialized by connecting to the web server. This must - /// be a heap allocated object that NormalOperationWindow will take ownership of. - explicit NormalOperationWindow(std::auto_ptr<TCPSocket> & socket); + /// @param socket Socket that has been initialized by connecting to the web + /// server. This must be a heap allocated object that NormalOperationWindow + /// will take ownership of. + explicit NormalOperationWindow(std::auto_ptr<TCPSocket> & socket); protected: - virtual void resized(); - virtual void updated(); - virtual void doRender(Bitmap & bitmap, int xOffset, int yOffset) const; - virtual bool doProcessKey(Key key); - + virtual void resized(); + virtual void updated(); + virtual void doRender(Bitmap & bitmap, int xOffset, int yOffset) const; + virtual bool doProcessKey(Key key); + private: - enum SensorNodeState - { - Disconnected, // No sensor node is connected. - Invalid, // Sensor node is not valid. - ValidLaserDisabled, // Sensor node is valid, and laser is disabled. - ValidLaserEnabled, // Sensor node is valid, and laser is enabled. - FailedProvision // Attempt to provision sensor node failed. - }; - - enum Result - { - NoChange, // Windows not changed; No redraw required. - WindowsChanged // Windows have changed; Redraw is required. - }; - - std::auto_ptr<TCPSocket> socket; - char recvBuf[1280]; // Socket receive buffer. Must be large enough to hold the largest command. - CommandChallenge commandChallenge; - bool sendChallenge; + enum Result { + NoChange, // Windows not changed; No redraw required. + WindowsChanged // Windows have changed; Redraw is required. + }; + + std::auto_ptr<TCPSocket> socket; + // Socket receive buffer. Must be large enough to hold the largest command. + char recvBuf[1280]; + CommandChallenge commandChallenge; + bool sendChallenge; - // Device status information. - bool validSignature; - SensorNodeState lastSensorNodeState; - double lastObjectTemp; - double lastAmbientTemp; - - Button validSignatureButton; - Button showWebIdButton; - - // Button event handlers. - void showWebId(); - void toggleValidSignature(); - - // Send a message to the server message log. - void sendMessage(const char * message); - - static SensorNodeState detectSensorNode(); - Result processReceivedData(size_t recvBufSize); - Result sendStatus(const ResponseChallenge & responseChallenge); - Result sendObjectTemp(const ResponseChallenge & responseChallenge); - Result sendAmbientTemp(const ResponseChallenge & responseChallenge); - void displayImage(const std::vector<uint8_t> & imageData); + // Device status information. + bool validSignature; + SensorNode::State lastSensorNodeState; + double lastObjectTemp; + double lastAmbientTemp; + + Button validSignatureButton; + Button showWebIdButton; + + // Button event handlers. + void showWebId(Button *); + void toggleValidSignature(Button *); + + // Send a message to the server message log. + void sendMessage(const char * message); + + Result processReceivedData(size_t recvBufSize); + Result sendStatus(const ResponseChallenge & responseChallenge); + Result sendObjectTemp(const ResponseChallenge & responseChallenge); + Result sendAmbientTemp(const ResponseChallenge & responseChallenge); + void displayImage(const std::vector<uint8_t> & imageData); }; #endif
--- a/OneWire.lib Thu Jun 01 14:21:58 2017 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -https://developer.mbed.org/teams/Maxim-Integrated/code/OneWire/#cf38f48a2a49
--- a/Rectangle.cpp Thu Jun 01 14:21:58 2017 -0500 +++ b/Rectangle.cpp Mon Nov 06 18:12:27 2017 -0600 @@ -36,27 +36,20 @@ static const int minBorderWidth = 1; -Rectangle::Rectangle() : m_borderWidth(minBorderWidth) { } +Rectangle::Rectangle() : m_borderWidth(minBorderWidth) {} -void Rectangle::setBorderWidth(int borderWidth) -{ - m_borderWidth = std::max(borderWidth, minBorderWidth); - invalidate(); +void Rectangle::setBorderWidth(int borderWidth) { + m_borderWidth = std::max(borderWidth, minBorderWidth); + invalidate(); } -void Rectangle::doRender(Bitmap & bitmap, int xOffset, int yOffset) const -{ - for (int curX = 0; (curX < width()) && (curX < bitmap.width()); curX++) - { - for (int curY = 0; (curY < height()) && (curY < bitmap.height()); curY++) - { - if ((curX < borderWidth()) || - (curX >= (width() - borderWidth())) || - (curY < borderWidth()) || - (curY >= (height() - borderWidth()))) - { - bitmap.setPixelEnabled(xOffset + x() + curX, yOffset + y() + curY, true); - } - } +void Rectangle::doRender(Bitmap & bitmap, int xOffset, int yOffset) const { + for (int curX = 0; (curX < width()) && (curX < bitmap.width()); curX++) { + for (int curY = 0; (curY < height()) && (curY < bitmap.height()); curY++) { + if ((curX < borderWidth()) || (curX >= (width() - borderWidth())) || + (curY < borderWidth()) || (curY >= (height() - borderWidth()))) { + bitmap.setPixelEnabled(xOffset + x() + curX, yOffset + y() + curY, true); + } } + } }
--- a/Rectangle.hpp Thu Jun 01 14:21:58 2017 -0500 +++ b/Rectangle.hpp Mon Nov 06 18:12:27 2017 -0600 @@ -36,23 +36,22 @@ #include "Graphic.hpp" /// Rectangle graphical primitive. -class Rectangle : public Graphic -{ +class Rectangle : public Graphic { public: - Rectangle(); - - /// @{ - /// Width of the border in pixels on all sides. Minimum width is 1. - /// @note The width of a rectangle is inclusive of the border. - int borderWidth() const { return m_borderWidth; } - void setBorderWidth(int borderWidth); - /// @} - + Rectangle(); + + /// @{ + /// Width of the border in pixels on all sides. Minimum width is 1. + /// @note The width of a rectangle is inclusive of the border. + int borderWidth() const { return m_borderWidth; } + void setBorderWidth(int borderWidth); + /// @} + protected: - virtual void doRender(Bitmap & bitmap, int xOffset, int yOffset) const; - + virtual void doRender(Bitmap & bitmap, int xOffset, int yOffset) const; + private: - int m_borderWidth; + int m_borderWidth; }; #endif
--- a/SensorNode.cpp Thu Jun 01 14:21:58 2017 -0500 +++ b/SensorNode.cpp Mon Nov 06 18:12:27 2017 -0600 @@ -32,222 +32,203 @@ #include <string> #include <I2C.h> -#include "RomId.h" -#include "HexConversions.hpp" -#include "DS2476.hpp" +#include <MaximInterface/Utilities/RomId.hpp> +#include <MaximInterface/Utilities/ManId.hpp> +#include <MaximInterface/Utilities/HexConversions.hpp> +#include <MaximInterface/Platforms/mbed/Sleep.hpp> #include "Factory.hpp" #include "SensorNode.hpp" +using namespace MaximInterface; + // I2C address of the MLX90614. static const uint8_t mlx90614Addr = 0xB4; -/// DS2476 derives the slave secret for a certain DS28C36 from the master secret. -/// @param ds2476 DS2476 that will compute slave secret. -/// @param ds28c36 DS28C36 containing the slave secret of interest. -/// @param[out] message Contains the HMAC input used when computing the slave secret. Output to -/// prevent redundant page reads. -/// @param print Optional callback for displaying informational messages to the user. -/// @returns True if the operation was successful. -static bool setSlaveSecret(DS2476 & ds2476, DS28C36 & ds28c36, DS2476::Buffer & message, - const SensorNode::PrintHandler & print = SensorNode::PrintHandler()) -{ - if (print) - { - print("Computing slave secret"); - print("Reading DS28C36 ROM Options page for ROM ID and MAN ID"); - } - DS28C36::Page page; - DS28C36::CmdResult result = ds28c36.readMemory(DS28C36::RomOptions, page); - if (result != DS28C36::Success) - return false; - message.clear(); - message.reserve(75); - message.assign(page.begin() + 24, page.end()); - OneWire::array<uint8_t, 2> manId = { page[22], page[23] }; - if (print) - { - print("Reading User Data 0 page"); - } - result = ds28c36.readMemory(DS28C36::UserData0, page); - if (result != DS28C36::Success) - return false; - message.insert(message.end(), page.begin(), page.end()); - message.insert(message.end(), 32, 0x00); - message.insert(message.end(), DS28C36::UserData0); - message.insert(message.end(), manId.begin(), manId.end()); - if (print) - { - print(("Creating HMAC message (ROM ID | Binding Data (Page Data) | Partial Secret (Buffer) | Page # | MAN ID): " + - byteArrayToHexString(&message[0], message.size())).c_str()); - print("Writing HMAC message to DS2476 buffer"); - } - result = ds2476.writeBuffer(message); - if (result != DS2476::Success) - return false; - if (print) - { - print("DS2476 computes slave secret from master secret (Secret A) and message in buffer"); - } - result = ds2476.computeSha2UniqueSecret(DS2476::SecretNumA); - if (result != DS2476::Success) - return false; - return true; +SensorNode::SensorNode(I2CMaster & i2c, DS2476 & ds2476) + : i2c(i2c), ds28c36(MaximInterface::mbed::Sleep::instance(), i2c), + ds2476(ds2476) {} + +std::pair<SensorNode::State, error_code> SensorNode::detect() { + std::pair<State, error_code> result; + result.second = readRomIdAndManId(ds28c36, &romId, &manId); + if (result.second || !valid(romId)) { + result.first = Disconnected; + return result; + } + + bool provisioned; + result.second = getProvisioned(provisioned); + if (result.second) { + result.first = Disconnected; + return result; + } + if (!provisioned) { + result.first = NotProvisioned; + return result; + } + + result.second = authenticate(); + if (result.second) { + result.first = + (result.second == make_error_code(DS28C36::AuthenticationError)) + ? Invalid + : Disconnected; + return result; + } + + bool laserEnabled; + result.second = getLaserEnabled(laserEnabled); + if (result.second) { + result.first = Disconnected; + } else { + result.first = laserEnabled ? ValidLaserEnabled : ValidLaserDisabled; + } + return result; } -SensorNode::SensorNode(mbed::I2C & i2c, DS2476 & ds2476) : i2c(i2c), ds28c36(i2c), ds2476(ds2476) { } +bool SensorNode::readTemp(TempStyle style, double & temp) { + uint8_t data[2]; + switch (style) { + case ObjectTemp: + default: + data[0] = 0x07; + break; -bool SensorNode::detect() -{ - // Read ROM ID - OneWire::RomId romId; - return (DS28C36::readRomId(ds28c36, romId) == DS28C36::Success) && romId.valid(); + case AmbientTemp: + data[0] = 0x06; + break; + } + error_code result = i2c.writePacket(mlx90614Addr, data, 1, false); + if (result) { + i2c.stop(); + return false; + } + result = i2c.readPacket(mlx90614Addr, data, 2, true); + if (result) { + i2c.stop(); + return false; + } + temp = ((static_cast<uint_fast16_t>(data[1]) << 8) | data[0]) * 0.02 - 273.15; + return true; } -bool SensorNode::readTemp(TempStyle style, double & temp) -{ - uint8_t data[2]; - switch (style) - { - case ObjectTemp: - default: - data[0] = 0x07; - break; - - case AmbientTemp: - data[0] = 0x06; - break; - } - int result = i2c.write(mlx90614Addr, reinterpret_cast<const char *>(data), 1, true); - if (result != 0) - { - i2c.stop(); - return false; - } - result = i2c.read(mlx90614Addr, reinterpret_cast<char *>(data), 2, false); - if (result != 0) - { - i2c.stop(); - return false; - } - temp = ((static_cast<uint_fast16_t>(data[1]) << 8) | data[0]) * 0.02 - 273.15; - return true; -} - -bool SensorNode::getProvisioned(bool & provisioned) -{ - return checkAuthenticatorProvisioned(ds28c36, provisioned); -} - -bool SensorNode::provision() -{ - return provisionAuthenticator(ds28c36); +error_code SensorNode::getProvisioned(bool & provisioned) { + return checkAuthenticatorProvisioned(ds28c36, provisioned); } -bool SensorNode::authenticate() -{ - // Compute slave secret on coprocessor. - DS2476::Buffer message; - if (!setSlaveSecret(ds2476, ds28c36, message)) - return false; - - // Compute HMAC on coprocessor. - // ROM ID, Page 0, and MAN ID are already in message. - DS2476::Buffer challenge; - DS2476::CmdResult result = ds2476.readRng(32, challenge); - if (result != DS2476::Success) - return false; - std::copy(challenge.begin(), challenge.end(), message.begin() + 40); - result = ds2476.writeBuffer(message); - if (result != DS2476::Success) - return false; - DS2476::HMAC computedHmac; - result = ds2476.computeSha2Hmac(computedHmac); - if (result != DS2476::Success) - return false; - - // Compute HMAC on device. - result = ds28c36.writeBuffer(challenge); - if (result != DS28C36::Success) - return false; - DS28C36::HMAC deviceHmac; - result = ds28c36.computeAndReadHmacPageAuthentication(DS28C36::UserData0, DS28C36::SecretNumA, deviceHmac); - if (result != DS28C36::Success) - return false; - - return computedHmac == deviceHmac; +error_code SensorNode::provision() { return provisionAuthenticator(ds28c36); } + +error_code SensorNode::authenticate() { + // Compute slave secret on coprocessor. + DS28C36::Page page; + error_code result = ds28c36.readMemory(DS28C36::UserData0, page); + if (result) + return result; + DS28C36::Page challenge = {}; + DS2476::PageAuthenticationData message = DS2476::createPageAuthenticationData( + romId, page, challenge, DS28C36::UserData0, manId); + result = ds2476.writeBuffer(message.data(), message.size()); + if (result) + return result; + result = ds2476.computeSha2UniqueSecret(DS2476::SecretNumA); + if (result) + return result; + + // Compute HMAC on coprocessor. + // ROM ID, Page 0, and MAN ID are already in message. + result = readRng(ds2476, challenge.data(), challenge.size()); + if (result) + return result; + std::copy(challenge.begin(), challenge.end(), message.begin() + 40); + result = ds2476.writeBuffer(message.data(), message.size()); + if (result) + return result; + Sha256::Hash computedHmac; + result = ds2476.computeSha2Hmac(computedHmac); + if (result) + return result; + + // Compute HMAC on device. + result = ds28c36.writeBuffer(challenge.data(), challenge.size()); + if (result) + return result; + Sha256::Hash deviceHmac; + result = ds28c36.computeAndReadHmacPageAuthentication( + DS28C36::UserData0, DS28C36::SecretNumA, deviceHmac); + if (result) + return result; + + if (computedHmac != deviceHmac) + result = make_error_code(DS28C36::AuthenticationError); + return result; } -bool SensorNode::setLaserEnabled(bool enabled, const PrintHandler & print) -{ - if (print) - { - print((std::string(enabled ? "Enabling" : "Disabling") + " laser").c_str()); - } - - // Compute slave secret on coprocessor. - DS2476::Buffer message; - if (!setSlaveSecret(ds2476, ds28c36, message, print)) - return false; - - // Compute write HMAC. - // ROM ID and MAN ID are already in message. - if (print) - { - print("Reading GPIO Control page"); - print((std::string("Modify copy of GPIO Control page to set GPIO B state to ") + - (enabled ? "conducting" : "high-impedance")).c_str()); - } - DS28C36::Page page; - DS28C36::CmdResult result = ds28c36.readMemory(DS28C36::GpioControl, page); - if (result != DS28C36::Success) - return false; - std::copy(page.begin(), page.end(), message.begin() + 8); - page[1] = (enabled ? 0xAA : 0x55); - std::copy(page.begin(), page.end(), message.begin() + 40); - message[72] = DS28C36::GpioControl; - if (print) - { - print(("Creating HMAC message (ROM ID | Old Page Data | New Page Data | Page # | MAN ID): " + - byteArrayToHexString(&message[0], message.size())).c_str()); - print("Writing HMAC message to DS2476 buffer"); - } - result = ds2476.writeBuffer(message); - if (result != DS2476::Success) - return false; - DS2476::HMAC hmac; - result = ds2476.computeSha2Hmac(hmac); - if (result != DS2476::Success) - return false; - - if (print) - { - print(("DS2476 computes write authentication HMAC from slave secret (Secret S) and message in buffer: " + - byteArrayToHexString(hmac.data(), hmac.size())).c_str()); - print("Write authentication HMAC is written to DS28C36 buffer"); - print("DS28C36 computes an HMAC to compare to the write authentication HMAC after receiving Page # and New Page Data"); - } - - // Write page data. - result = ds28c36.writeBuffer(DS28C36::Buffer(hmac.begin(), hmac.end())); - if (result != DS28C36::Success) - return false; - result = ds28c36.authenticatedSha2WriteMemory(DS28C36::GpioControl, DS28C36::SecretNumA, page); - if (result != DS28C36::Success) - return false; - if (print) - { - print("DS28C36 updates page data which changes GPIO B state"); - print((std::string("Laser is now ") + (enabled ? "enabled" : "disabled")).c_str()); - } - return true; +error_code SensorNode::setLaserEnabled(bool enabled, + const PrintHandler & print) { + if (print) { + print((std::string(enabled ? "Enabling" : "Disabling") + " laser").c_str()); + } + + // Compute write HMAC. + // ROM ID and MAN ID are already in message. + if (print) { + print("Reading GPIO Control page"); + print((std::string( + "Modify copy of GPIO Control page to set GPIO B state to ") + + (enabled ? "conducting" : "high-impedance")).c_str()); + } + DS28C36::Page oldPage; + error_code result = ds28c36.readMemory(DS28C36::GpioControl, oldPage); + if (result) + return result; + DS28C36::Page newPage = oldPage; + newPage[1] = (enabled ? 0xAA : 0x55); + const DS2476::PageAuthenticationData message = + DS2476::createPageAuthenticationData(romId, oldPage, newPage, + DS28C36::GpioControl, manId); + if (print) { + print(("Creating HMAC message (ROM ID | Old Page Data | New Page Data | " + "Page # | MAN ID): " + + byteArrayToHexString(&message[0], message.size())).c_str()); + print("Writing HMAC message to DS2476 buffer"); + } + result = ds2476.writeBuffer(message.data(), message.size()); + if (result) + return result; + Sha256::Hash hmac; + result = ds2476.computeSha2Hmac(hmac); + if (result) + return result; + + if (print) { + print(("DS2476 computes write authentication HMAC from slave secret " + "(Secret S) and message in buffer: " + + byteArrayToHexString(hmac.data(), hmac.size())).c_str()); + print("Write authentication HMAC is written to DS28C36 buffer"); + print("DS28C36 computes an HMAC to compare to the write authentication " + "HMAC after receiving Page # and New Page Data"); + } + + // Write page data. + result = ds28c36.writeBuffer(hmac.data(), hmac.size()); + if (result) + return result; + result = ds28c36.authenticatedSha2WriteMemory(DS28C36::GpioControl, + DS28C36::SecretNumA, newPage); + if (result) + return result; + if (print) { + print("DS28C36 updates page data which changes GPIO B state"); + print((std::string("Laser is now ") + (enabled ? "enabled" : "disabled")) + .c_str()); + } + return result; } -bool SensorNode::getLaserEnabled(bool & enabled) -{ - DS28C36::Page page; - DS28C36::CmdResult result = ds28c36.readMemory(DS28C36::GpioControl, page); - if (result != DS28C36::Success) - return false; +error_code SensorNode::getLaserEnabled(bool & enabled) { + DS28C36::Page page; + const error_code result = ds28c36.readMemory(DS28C36::GpioControl, page); + if (!result) enabled = (page[1] == 0xAA); - return true; + return result; }
--- a/SensorNode.hpp Thu Jun 01 14:21:58 2017 -0500 +++ b/SensorNode.hpp Mon Nov 06 18:12:27 2017 -0600 @@ -34,68 +34,81 @@ #define SENSORNODE_HPP #include <stdint.h> -#include <Callback.h> -#include "DS28C36.hpp" +#include <utility> +#include <MaximInterface/Devices/DS28C36_DS2476.hpp> +#include <MaximInterface/Utilities/Function.hpp> -namespace mbed { class I2C; } +namespace MaximInterface { class DS2476; +class I2CMaster; +} // namespace MaximInterface /// Interface to the authenticated sensor node peripheral board. -class SensorNode -{ +class SensorNode { public: - /// Prints a null-terminated char string. - typedef mbed::Callback<void(const char *)> PrintHandler; + /// Prints a null-terminated char string. + typedef MaximInterface::Function<void(const char *)> PrintHandler; + + /// Style of temperature to measure. + enum TempStyle { AmbientTemp, ObjectTemp }; + + enum State { + Disconnected, // No sensor node is connected. + Invalid, // Sensor node is not valid. + ValidLaserDisabled, // Sensor node is valid, and laser is disabled. + ValidLaserEnabled, // Sensor node is valid, and laser is enabled. + NotProvisioned // Sensor node is not provisioned. + }; + + /// @param i2c + /// I2C bus connected to the sensor node. Communicates with DS28C36 and MLX90614. + /// @param ds2476 Coprocessor used for authentication computations. + SensorNode(MaximInterface::I2CMaster & i2c, MaximInterface::DS2476 & ds2476); + + /// Detects if a potential sensor node is connected. + /// @returns True if something was detected. + std::pair<State, MaximInterface::error_code> detect(); + + /// Enable or disable the laser. + /// @param enabled True to enable the laser or false to disable. + /// @param print + /// Optional callback for displaying informational messages to the user. + /// @returns True if the operation was successful. + MaximInterface::error_code + setLaserEnabled(bool enabled, const PrintHandler & print = PrintHandler()); - /// Style of temperature to measure. - enum TempStyle - { - AmbientTemp, - ObjectTemp - }; - - /// @param i2c I2C bus connected to the sensor node. Communicates with DS28C36 and MLX90614. - /// @param ds2476 Coprocessor used for authentication computations. - SensorNode(mbed::I2C & i2c, DS2476 & ds2476); - - /// Detects if a potential sensor node is connected. - /// @returns True if something was detected. - bool detect(); - - /// Checks if the sensor node is authentic. - /// @returns True if the sensor node passed the authentication check. - bool authenticate(); - - /// Checks if the laser is enabled. - /// @param[out] enabled Set to true if the laser is enabled. Only valid if check successful. - /// @returns True if check was successful. - bool getLaserEnabled(bool & enabled); - - /// Enable or disable the laser. - /// @param enabled True to enable the laser or false to disable. - /// @param print Optional callback for displaying informational messages to the user. - /// @returns True if the operation was successful. - bool setLaserEnabled(bool enabled, const PrintHandler & print = PrintHandler()); - - /// Get a temperature measurement from the MLX90614. - /// @param style Temperature style to read. - /// @param[out] temp Temperature in Celsius. Only valid if operation successful. - /// @returns True if the operation was successful. - bool readTemp(TempStyle style, double & temp); - - /// Checks if the sensor node is provisioned. - /// @param[out] provisioned True if provisioned. Only valid if check successful. - /// @returns True if the check was successful. - bool getProvisioned(bool & provisioned); - - /// Provision the sensor node. - /// @returns True if the operation was successful. - bool provision(); - + /// Get a temperature measurement from the MLX90614. + /// @param style Temperature style to read. + /// @param[out] temp Temperature in Celsius. Only valid if operation successful. + /// @returns True if the operation was successful. + bool readTemp(TempStyle style, double & temp); + + /// Provision the sensor node. + /// @returns True if the operation was successful. + MaximInterface::error_code provision(); + private: - mbed::I2C & i2c; - DS28C36 ds28c36; - DS2476 & ds2476; + /// Checks if the sensor node is authentic. + /// @returns True if the sensor node passed the authentication check. + MaximInterface::error_code authenticate(); + + /// Checks if the laser is enabled. + /// @param[out] enabled + /// Set to true if the laser is enabled. Only valid if check successful. + /// @returns True if check was successful. + MaximInterface::error_code getLaserEnabled(bool & enabled); + + /// Checks if the sensor node is provisioned. + /// @param[out] provisioned + /// True if provisioned. Only valid if check successful. + /// @returns True if the check was successful. + MaximInterface::error_code getProvisioned(bool & provisioned); + + MaximInterface::I2CMaster & i2c; + MaximInterface::DS28C36 ds28c36; + MaximInterface::DS2476 & ds2476; + MaximInterface::RomId romId; + MaximInterface::ManId manId; }; #endif
--- a/Text.cpp Thu Jun 01 14:21:58 2017 -0500 +++ b/Text.cpp Mon Nov 06 18:12:27 2017 -0600 @@ -48,329 +48,311 @@ static const unsigned char printableCharEnd = 0x7E; static const uint8_t characterMap[][characterHeight] = { - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // ' ' - { 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x20 }, // '!' - { 0x50, 0x50, 0x50, 0x00, 0x00, 0x00, 0x00 }, // '"' - { 0x50, 0x50, 0xF8, 0x50, 0xF8, 0x50, 0x50 }, // '#' - { 0x20, 0x78, 0xA0, 0x70, 0x28, 0xF0, 0x20 }, // '$' - { 0xC0, 0xC8, 0x10, 0x20, 0x40, 0x98, 0x18 }, // '%' - { 0x60, 0x90, 0xA0, 0x40, 0xA8, 0x90, 0x68 }, // '&' - { 0x60, 0x20, 0x40, 0x00, 0x00, 0x00, 0x00 }, // ''' - { 0x10, 0x20, 0x40, 0x40, 0x40, 0x20, 0x10 }, // '(' - { 0x40, 0x20, 0x10, 0x10, 0x10, 0x20, 0x40 }, // ')' - { 0x00, 0x20, 0xA8, 0x70, 0xA8, 0x20, 0x00 }, // '*' - { 0x00, 0x20, 0x20, 0xF8, 0x20, 0x20, 0x00 }, // '+' - { 0x00, 0x00, 0x00, 0x00, 0x60, 0x20, 0x40 }, // ',' - { 0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00 }, // '-' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60 }, // '.' - { 0x00, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00 }, // '/' - { 0x70, 0x88, 0x98, 0xA8, 0xC8, 0x88, 0x70 }, // '0' - { 0x20, 0x60, 0x20, 0x20, 0x20, 0x20, 0x70 }, // '1' - { 0x70, 0x88, 0x08, 0x10, 0x20, 0x40, 0xF8 }, // '2' - { 0xF8, 0x10, 0x20, 0x10, 0x08, 0x88, 0x70 }, // '3' - { 0x10, 0x30, 0x50, 0x90, 0xF8, 0x10, 0x10 }, // '4' - { 0xF8, 0x80, 0xF0, 0x08, 0x08, 0x88, 0x70 }, // '5' - { 0x30, 0x40, 0x80, 0xF0, 0x88, 0x88, 0x70 }, // '6' - { 0xF8, 0x08, 0x10, 0x20, 0x40, 0x40, 0x40 }, // '7' - { 0x70, 0x88, 0x88, 0x70, 0x88, 0x88, 0x70 }, // '8' - { 0x70, 0x88, 0x88, 0x78, 0x08, 0x10, 0x60 }, // '9' - { 0x00, 0x60, 0x60, 0x00, 0x60, 0x60, 0x00 }, // ':' - { 0x00, 0x60, 0x60, 0x00, 0x60, 0x20, 0x40 }, // ';' - { 0x10, 0x20, 0x40, 0x80, 0x40, 0x20, 0x10 }, // '<' - { 0x00, 0x00, 0xF8, 0x00, 0xF8, 0x00, 0x00 }, // '=' - { 0x40, 0x20, 0x10, 0x08, 0x10, 0x20, 0x40 }, // '>' - { 0x70, 0x88, 0x08, 0x10, 0x20, 0x00, 0x20 }, // '?' - { 0x70, 0x88, 0x08, 0x68, 0xA8, 0xA8, 0x70 }, // '@' - { 0x70, 0x88, 0x88, 0x88, 0xF8, 0x88, 0x88 }, // 'A' - { 0xF0, 0x88, 0x88, 0xF0, 0x88, 0x88, 0xF0 }, // 'B' - { 0x70, 0x88, 0x80, 0x80, 0x80, 0x88, 0x70 }, // 'C' - { 0xE0, 0x90, 0x88, 0x88, 0x88, 0x90, 0xE0 }, // 'D' - { 0xF8, 0x80, 0x80, 0xF0, 0x80, 0x80, 0xF8 }, // 'E' - { 0xF8, 0x80, 0x80, 0xF0, 0x80, 0x80, 0x80 }, // 'F' - { 0x70, 0x88, 0x80, 0xB8, 0x88, 0x88, 0x78 }, // 'G' - { 0x88, 0x88, 0x88, 0xF8, 0x88, 0x88, 0x88 }, // 'H' - { 0x70, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70 }, // 'I' - { 0x38, 0x10, 0x10, 0x10, 0x10, 0x90, 0x60 }, // 'J' - { 0x88, 0x90, 0xA0, 0xC0, 0xA0, 0x90, 0x88 }, // 'K' - { 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xF8 }, // 'L' - { 0x88, 0xD8, 0xA8, 0xA8, 0x88, 0x88, 0x88 }, // 'M' - { 0x88, 0x88, 0xC8, 0xA8, 0x98, 0x88, 0x88 }, // 'N' - { 0x70, 0x88, 0x88, 0x88, 0x88, 0x88, 0x70 }, // 'O' - { 0xF0, 0x88, 0x88, 0xF0, 0x80, 0x80, 0x80 }, // 'P' - { 0x70, 0x88, 0x88, 0x88, 0xA8, 0x90, 0x68 }, // 'Q' - { 0xF0, 0x88, 0x88, 0xF0, 0xA0, 0x90, 0x88 }, // 'R' - { 0x78, 0x80, 0x80, 0x70, 0x08, 0x08, 0xF0 }, // 'S' - { 0xF8, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 }, // 'T' - { 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x70 }, // 'U' - { 0x88, 0x88, 0x88, 0x88, 0x88, 0x50, 0x20 }, // 'V' - { 0x88, 0x88, 0x88, 0xA8, 0xA8, 0xA8, 0x50 }, // 'W' - { 0x88, 0x88, 0x50, 0x20, 0x50, 0x88, 0x88 }, // 'X' - { 0x88, 0x88, 0x88, 0x50, 0x20, 0x20, 0x20 }, // 'Y' - { 0xF8, 0x08, 0x10, 0x20, 0x40, 0x80, 0xF8 }, // 'Z' - { 0x70, 0x40, 0x40, 0x40, 0x40, 0x40, 0x70 }, // '[' - { 0x00, 0x80, 0x40, 0x20, 0x10, 0x08, 0x00 }, // '\' - { 0x70, 0x10, 0x10, 0x10, 0x10, 0x10, 0x70 }, // ']' - { 0x20, 0x50, 0x88, 0x00, 0x00, 0x00, 0x00 }, // '^' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8 }, // '_' - { 0x40, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00 }, // '`' - { 0x00, 0x00, 0x70, 0x08, 0x78, 0x88, 0x78 }, // 'a' - { 0x80, 0x80, 0xB0, 0xC8, 0x88, 0x88, 0xF0 }, // 'b' - { 0x00, 0x00, 0x70, 0x80, 0x80, 0x88, 0x70 }, // 'c' - { 0x08, 0x08, 0x68, 0x98, 0x88, 0x88, 0x78 }, // 'd' - { 0x00, 0x00, 0x70, 0x88, 0xF8, 0x80, 0x70 }, // 'e' - { 0x30, 0x48, 0x40, 0xE0, 0x40, 0x40, 0x40 }, // 'f' - { 0x00, 0x78, 0x88, 0x88, 0x78, 0x08, 0x70 }, // 'g' - { 0x80, 0x80, 0xB0, 0xC8, 0x88, 0x88, 0x88 }, // 'h' - { 0x20, 0x00, 0x60, 0x20, 0x20, 0x20, 0x70 }, // 'i' - { 0x10, 0x00, 0x30, 0x10, 0x10, 0x90, 0x60 }, // 'j' - { 0x80, 0x80, 0x90, 0xA0, 0xC0, 0xA0, 0x90 }, // 'k' - { 0x60, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70 }, // 'l' - { 0x00, 0x00, 0xD0, 0xA8, 0xA8, 0x88, 0x88 }, // 'm' - { 0x00, 0x00, 0xB0, 0xC8, 0x88, 0x88, 0x88 }, // 'n' - { 0x00, 0x00, 0x70, 0x88, 0x88, 0x88, 0x70 }, // 'o' - { 0x00, 0x00, 0xF0, 0x88, 0xF0, 0x80, 0x80 }, // 'p' - { 0x00, 0x00, 0x68, 0x98, 0x78, 0x08, 0x08 }, // 'q' - { 0x00, 0x00, 0xB0, 0xC8, 0x80, 0x80, 0x80 }, // 'r' - { 0x00, 0x00, 0x70, 0x80, 0x70, 0x08, 0xF0 }, // 's' - { 0x40, 0x40, 0xE0, 0x40, 0x40, 0x48, 0x30 }, // 't' - { 0x00, 0x00, 0x88, 0x88, 0x88, 0x98, 0x68 }, // 'u' - { 0x00, 0x00, 0x88, 0x88, 0x88, 0x41, 0x20 }, // 'v' - { 0x00, 0x00, 0x88, 0x88, 0xA8, 0xA8, 0x50 }, // 'w' - { 0x00, 0x00, 0x88, 0x50, 0x20, 0x50, 0x88 }, // 'x' - { 0x00, 0x00, 0x88, 0x88, 0x78, 0x08, 0x70 }, // 'y' - { 0x00, 0x00, 0xF8, 0x10, 0x20, 0x40, 0xF8 }, // 'z' - { 0x10, 0x20, 0x20, 0x40, 0x20, 0x20, 0x10 }, // '{' - { 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 }, // '|' - { 0x40, 0x20, 0x20, 0x10, 0x20, 0x20, 0x40 }, // '}' - { 0x00, 0x00, 0x40, 0xA8, 0x10, 0x00, 0x00 } // '~' + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // ' ' + {0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x20}, // '!' + {0x50, 0x50, 0x50, 0x00, 0x00, 0x00, 0x00}, // '"' + {0x50, 0x50, 0xF8, 0x50, 0xF8, 0x50, 0x50}, // '#' + {0x20, 0x78, 0xA0, 0x70, 0x28, 0xF0, 0x20}, // '$' + {0xC0, 0xC8, 0x10, 0x20, 0x40, 0x98, 0x18}, // '%' + {0x60, 0x90, 0xA0, 0x40, 0xA8, 0x90, 0x68}, // '&' + {0x60, 0x20, 0x40, 0x00, 0x00, 0x00, 0x00}, // ''' + {0x10, 0x20, 0x40, 0x40, 0x40, 0x20, 0x10}, // '(' + {0x40, 0x20, 0x10, 0x10, 0x10, 0x20, 0x40}, // ')' + {0x00, 0x20, 0xA8, 0x70, 0xA8, 0x20, 0x00}, // '*' + {0x00, 0x20, 0x20, 0xF8, 0x20, 0x20, 0x00}, // '+' + {0x00, 0x00, 0x00, 0x00, 0x60, 0x20, 0x40}, // ',' + {0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00}, // '-' + {0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60}, // '.' + {0x00, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00}, // '/' + {0x70, 0x88, 0x98, 0xA8, 0xC8, 0x88, 0x70}, // '0' + {0x20, 0x60, 0x20, 0x20, 0x20, 0x20, 0x70}, // '1' + {0x70, 0x88, 0x08, 0x10, 0x20, 0x40, 0xF8}, // '2' + {0xF8, 0x10, 0x20, 0x10, 0x08, 0x88, 0x70}, // '3' + {0x10, 0x30, 0x50, 0x90, 0xF8, 0x10, 0x10}, // '4' + {0xF8, 0x80, 0xF0, 0x08, 0x08, 0x88, 0x70}, // '5' + {0x30, 0x40, 0x80, 0xF0, 0x88, 0x88, 0x70}, // '6' + {0xF8, 0x08, 0x10, 0x20, 0x40, 0x40, 0x40}, // '7' + {0x70, 0x88, 0x88, 0x70, 0x88, 0x88, 0x70}, // '8' + {0x70, 0x88, 0x88, 0x78, 0x08, 0x10, 0x60}, // '9' + {0x00, 0x60, 0x60, 0x00, 0x60, 0x60, 0x00}, // ':' + {0x00, 0x60, 0x60, 0x00, 0x60, 0x20, 0x40}, // ';' + {0x10, 0x20, 0x40, 0x80, 0x40, 0x20, 0x10}, // '<' + {0x00, 0x00, 0xF8, 0x00, 0xF8, 0x00, 0x00}, // '=' + {0x40, 0x20, 0x10, 0x08, 0x10, 0x20, 0x40}, // '>' + {0x70, 0x88, 0x08, 0x10, 0x20, 0x00, 0x20}, // '?' + {0x70, 0x88, 0x08, 0x68, 0xA8, 0xA8, 0x70}, // '@' + {0x70, 0x88, 0x88, 0x88, 0xF8, 0x88, 0x88}, // 'A' + {0xF0, 0x88, 0x88, 0xF0, 0x88, 0x88, 0xF0}, // 'B' + {0x70, 0x88, 0x80, 0x80, 0x80, 0x88, 0x70}, // 'C' + {0xE0, 0x90, 0x88, 0x88, 0x88, 0x90, 0xE0}, // 'D' + {0xF8, 0x80, 0x80, 0xF0, 0x80, 0x80, 0xF8}, // 'E' + {0xF8, 0x80, 0x80, 0xF0, 0x80, 0x80, 0x80}, // 'F' + {0x70, 0x88, 0x80, 0xB8, 0x88, 0x88, 0x78}, // 'G' + {0x88, 0x88, 0x88, 0xF8, 0x88, 0x88, 0x88}, // 'H' + {0x70, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70}, // 'I' + {0x38, 0x10, 0x10, 0x10, 0x10, 0x90, 0x60}, // 'J' + {0x88, 0x90, 0xA0, 0xC0, 0xA0, 0x90, 0x88}, // 'K' + {0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xF8}, // 'L' + {0x88, 0xD8, 0xA8, 0xA8, 0x88, 0x88, 0x88}, // 'M' + {0x88, 0x88, 0xC8, 0xA8, 0x98, 0x88, 0x88}, // 'N' + {0x70, 0x88, 0x88, 0x88, 0x88, 0x88, 0x70}, // 'O' + {0xF0, 0x88, 0x88, 0xF0, 0x80, 0x80, 0x80}, // 'P' + {0x70, 0x88, 0x88, 0x88, 0xA8, 0x90, 0x68}, // 'Q' + {0xF0, 0x88, 0x88, 0xF0, 0xA0, 0x90, 0x88}, // 'R' + {0x78, 0x80, 0x80, 0x70, 0x08, 0x08, 0xF0}, // 'S' + {0xF8, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20}, // 'T' + {0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x70}, // 'U' + {0x88, 0x88, 0x88, 0x88, 0x88, 0x50, 0x20}, // 'V' + {0x88, 0x88, 0x88, 0xA8, 0xA8, 0xA8, 0x50}, // 'W' + {0x88, 0x88, 0x50, 0x20, 0x50, 0x88, 0x88}, // 'X' + {0x88, 0x88, 0x88, 0x50, 0x20, 0x20, 0x20}, // 'Y' + {0xF8, 0x08, 0x10, 0x20, 0x40, 0x80, 0xF8}, // 'Z' + {0x70, 0x40, 0x40, 0x40, 0x40, 0x40, 0x70}, // '[' + {0x00, 0x80, 0x40, 0x20, 0x10, 0x08, 0x00}, // '\' + {0x70, 0x10, 0x10, 0x10, 0x10, 0x10, 0x70}, // ']' + {0x20, 0x50, 0x88, 0x00, 0x00, 0x00, 0x00}, // '^' + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8}, // '_' + {0x40, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00}, // '`' + {0x00, 0x00, 0x70, 0x08, 0x78, 0x88, 0x78}, // 'a' + {0x80, 0x80, 0xB0, 0xC8, 0x88, 0x88, 0xF0}, // 'b' + {0x00, 0x00, 0x70, 0x80, 0x80, 0x88, 0x70}, // 'c' + {0x08, 0x08, 0x68, 0x98, 0x88, 0x88, 0x78}, // 'd' + {0x00, 0x00, 0x70, 0x88, 0xF8, 0x80, 0x70}, // 'e' + {0x30, 0x48, 0x40, 0xE0, 0x40, 0x40, 0x40}, // 'f' + {0x00, 0x78, 0x88, 0x88, 0x78, 0x08, 0x70}, // 'g' + {0x80, 0x80, 0xB0, 0xC8, 0x88, 0x88, 0x88}, // 'h' + {0x20, 0x00, 0x60, 0x20, 0x20, 0x20, 0x70}, // 'i' + {0x10, 0x00, 0x30, 0x10, 0x10, 0x90, 0x60}, // 'j' + {0x80, 0x80, 0x90, 0xA0, 0xC0, 0xA0, 0x90}, // 'k' + {0x60, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70}, // 'l' + {0x00, 0x00, 0xD0, 0xA8, 0xA8, 0x88, 0x88}, // 'm' + {0x00, 0x00, 0xB0, 0xC8, 0x88, 0x88, 0x88}, // 'n' + {0x00, 0x00, 0x70, 0x88, 0x88, 0x88, 0x70}, // 'o' + {0x00, 0x00, 0xF0, 0x88, 0xF0, 0x80, 0x80}, // 'p' + {0x00, 0x00, 0x68, 0x98, 0x78, 0x08, 0x08}, // 'q' + {0x00, 0x00, 0xB0, 0xC8, 0x80, 0x80, 0x80}, // 'r' + {0x00, 0x00, 0x70, 0x80, 0x70, 0x08, 0xF0}, // 's' + {0x40, 0x40, 0xE0, 0x40, 0x40, 0x48, 0x30}, // 't' + {0x00, 0x00, 0x88, 0x88, 0x88, 0x98, 0x68}, // 'u' + {0x00, 0x00, 0x88, 0x88, 0x88, 0x41, 0x20}, // 'v' + {0x00, 0x00, 0x88, 0x88, 0xA8, 0xA8, 0x50}, // 'w' + {0x00, 0x00, 0x88, 0x50, 0x20, 0x50, 0x88}, // 'x' + {0x00, 0x00, 0x88, 0x88, 0x78, 0x08, 0x70}, // 'y' + {0x00, 0x00, 0xF8, 0x10, 0x20, 0x40, 0xF8}, // 'z' + {0x10, 0x20, 0x20, 0x40, 0x20, 0x20, 0x10}, // '{' + {0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20}, // '|' + {0x40, 0x20, 0x20, 0x10, 0x20, 0x20, 0x40}, // '}' + {0x00, 0x00, 0x40, 0xA8, 0x10, 0x00, 0x00} // '~' }; -static bool charPrintable(unsigned char c) -{ - return (c >= printableCharBegin) && (c <= printableCharEnd); +static bool charPrintable(unsigned char c) { + return (c >= printableCharBegin) && (c <= printableCharEnd); } -static void removeNonprintableChars(string & s) -{ - s.erase(std::remove_if(s.begin(), s.end(), std::not1(std::ptr_fun(charPrintable))), s.end()); +static void removeNonprintableChars(string & s) { + s.erase(std::remove_if(s.begin(), s.end(), + std::not1(std::ptr_fun(charPrintable))), + s.end()); } -static bool compareStringLength(const string & a, const string & b) -{ - return a.length() < b.length(); +static bool compareStringLength(const string & a, const string & b) { + return a.length() < b.length(); } +namespace { + // Functor trims string if it exceeds a certain length. -class TrimString -{ +class TrimString { public: - TrimString(string::size_type maxSize) : maxSize(maxSize) { } - - void operator()(string & s) - { - if (s.size() > maxSize) - { - s.resize(maxSize); - } + TrimString(string::size_type maxSize) : maxSize(maxSize) {} + + void operator()(string & s) { + if (s.size() > maxSize) { + s.resize(maxSize); } - + } + private: - string::size_type maxSize; + string::size_type maxSize; }; +} // namespace + // Split a string based on a character token. Token will be removed. -static std::list<string> tokenizeString(const string & toSplit, char token) -{ - std::list<string> toSplitLines; - string::size_type beginIdx = 0, endIdx; - do - { - endIdx = toSplit.find(token, beginIdx); - toSplitLines.push_back(toSplit.substr(beginIdx, endIdx == string::npos ? string::npos : endIdx - beginIdx)); - beginIdx = endIdx + 1; - } while (endIdx != string::npos); - return toSplitLines; +static std::list<string> tokenizeString(const string & toSplit, char token) { + std::list<string> toSplitLines; + string::size_type beginIdx = 0, endIdx; + do { + endIdx = toSplit.find(token, beginIdx); + toSplitLines.push_back(toSplit.substr( + beginIdx, endIdx == string::npos ? string::npos : endIdx - beginIdx)); + beginIdx = endIdx + 1; + } while (endIdx != string::npos); + return toSplitLines; } // Word wrap string into lines based on a specified line length. -static std::list<string> wrapLines(const string & toSplit, const string::size_type lineLen) -{ - std::list<string> toSplitLines; - string::size_type beginIdx = 0; - if (lineLen > 0) - { - // Split lines as much as necessary. - string::size_type endIdx = lineLen; - while (((toSplit.length() - beginIdx) > lineLen) && (endIdx != string::npos)) - { - endIdx = toSplit.rfind(' ', endIdx); - if ((endIdx == string::npos) || (endIdx <= beginIdx)) - { - // Current word is too long to split. Find end of current word. - endIdx = toSplit.find(' ', beginIdx); - } - if (endIdx != string::npos) - { - toSplitLines.push_back(toSplit.substr(beginIdx, endIdx - beginIdx)); - beginIdx = endIdx + 1; - endIdx = beginIdx + lineLen; - } - } +static std::list<string> wrapLines(const string & toSplit, + const string::size_type lineLen) { + std::list<string> toSplitLines; + string::size_type beginIdx = 0; + if (lineLen > 0) { + // Split lines as much as necessary. + string::size_type endIdx = lineLen; + while (((toSplit.length() - beginIdx) > lineLen) && + (endIdx != string::npos)) { + endIdx = toSplit.rfind(' ', endIdx); + if ((endIdx == string::npos) || (endIdx <= beginIdx)) { + // Current word is too long to split. Find end of current word. + endIdx = toSplit.find(' ', beginIdx); + } + if (endIdx != string::npos) { + toSplitLines.push_back(toSplit.substr(beginIdx, endIdx - beginIdx)); + beginIdx = endIdx + 1; + endIdx = beginIdx + lineLen; + } } - // Last line is any remaining characters. - toSplitLines.push_back(toSplit.substr(beginIdx, toSplit.length() - beginIdx)); - return toSplitLines; + } + // Last line is any remaining characters. + toSplitLines.push_back(toSplit.substr(beginIdx, toSplit.length() - beginIdx)); + return toSplitLines; } -Text::Text() : m_text(), m_wordWrap(false), m_charSpacing(1), m_lineSpacing(1), - m_textLines(), m_preferredWidth(invalidWidthHeight), m_preferredHeight(invalidWidthHeight) { } +Text::Text() + : m_text(), m_wordWrap(false), m_charSpacing(1), m_lineSpacing(1), + m_textLines(), m_preferredWidth(invalidWidthHeight), + m_preferredHeight(invalidWidthHeight) {} -void Text::setText(const string & text) -{ - if (m_text != text) - { - m_text = text; - invalidate(); - m_preferredWidth = m_preferredHeight = invalidWidthHeight; - } +void Text::setText(const string & text) { + if (m_text != text) { + m_text = text; + invalidate(); + m_preferredWidth = m_preferredHeight = invalidWidthHeight; + } } -void Text::setWordWrap(bool wordWrap) -{ - if (m_wordWrap != wordWrap) - { - m_wordWrap = wordWrap; - invalidate(); - m_preferredWidth = m_preferredHeight = invalidWidthHeight; - } +void Text::setWordWrap(bool wordWrap) { + if (m_wordWrap != wordWrap) { + m_wordWrap = wordWrap; + invalidate(); + m_preferredWidth = m_preferredHeight = invalidWidthHeight; + } } -void Text::setLineSpacing(int lineSpacing) -{ - if (lineSpacing > 0 && m_lineSpacing != lineSpacing) - { - m_lineSpacing = lineSpacing; - invalidate(); - m_preferredHeight = invalidWidthHeight; - } +void Text::setLineSpacing(int lineSpacing) { + if (lineSpacing > 0 && m_lineSpacing != lineSpacing) { + m_lineSpacing = lineSpacing; + invalidate(); + m_preferredHeight = invalidWidthHeight; + } } -void Text::setCharSpacing(int charSpacing) -{ - if (charSpacing > 0 && m_charSpacing != charSpacing) - { - m_charSpacing = charSpacing; - invalidate(); - m_preferredWidth = invalidWidthHeight; - if (wordWrap()) - { - m_preferredHeight = invalidWidthHeight; - } +void Text::setCharSpacing(int charSpacing) { + if (charSpacing > 0 && m_charSpacing != charSpacing) { + m_charSpacing = charSpacing; + invalidate(); + m_preferredWidth = invalidWidthHeight; + if (wordWrap()) { + m_preferredHeight = invalidWidthHeight; } + } } -int Text::preferredWidth() const -{ - if (m_preferredWidth == invalidWidthHeight) - { - calculateLayout(); - } - return m_preferredWidth; +int Text::preferredWidth() const { + if (m_preferredWidth == invalidWidthHeight) { + calculateLayout(); + } + return m_preferredWidth; +} + +int Text::preferredHeight() const { + if (m_preferredHeight == invalidWidthHeight) { + calculateLayout(); + } + return m_preferredHeight; } -int Text::preferredHeight() const -{ - if (m_preferredHeight == invalidWidthHeight) - { - calculateLayout(); - } - return m_preferredHeight; -} - -void Text::resized() -{ - m_preferredWidth = invalidWidthHeight; - if (wordWrap()) - { - m_preferredHeight = invalidWidthHeight; - } +void Text::resized() { + m_preferredWidth = invalidWidthHeight; + if (wordWrap()) { + m_preferredHeight = invalidWidthHeight; + } } -void Text::doRender(Bitmap & bitmap, int xOffset, int yOffset) const -{ - using std::list; - - // Ensure layout is up to date. - if (m_preferredWidth == invalidWidthHeight || m_preferredHeight == invalidWidthHeight) - { - calculateLayout(); +void Text::doRender(Bitmap & bitmap, int xOffset, int yOffset) const { + using std::list; + + // Ensure layout is up to date. + if (m_preferredWidth == invalidWidthHeight || + m_preferredHeight == invalidWidthHeight) { + calculateLayout(); + } + + // Render each line. + int lineNum = 0; + for (list<string>::const_iterator lineIt = m_textLines.begin(); + lineIt != m_textLines.end(); lineIt++) { + // Render each character. + for (string::size_type charNum = 0; charNum < lineIt->length(); charNum++) { + bitmap.overlay(xOffset + x() + charNum * (characterWidth + m_charSpacing), + yOffset + y() + + lineNum * (characterHeight + m_lineSpacing), + &characterMap[(*lineIt)[charNum] - printableCharBegin][0], + characterHeight, characterWidth); } - - // Render each line. - int lineNum = 0; - for (list<string>::const_iterator lineIt = m_textLines.begin(); lineIt != m_textLines.end(); lineIt++) - { - // Render each character. - for (string::size_type charNum = 0; charNum < lineIt->length(); charNum++) - { - bitmap.overlay( - xOffset + x() + charNum * (characterWidth + m_charSpacing), - yOffset + y() + lineNum * (characterHeight + m_lineSpacing), - &characterMap[(*lineIt)[charNum] - printableCharBegin][0], - characterHeight, - characterWidth - ); - } - lineNum++; - } + lineNum++; + } } -void Text::calculateLayout() const -{ - using std::list; - - // Split string into lines. - m_textLines = tokenizeString(m_text, '\n'); - - // Remove non-printable characters. - std::for_each(m_textLines.begin(), m_textLines.end(), removeNonprintableChars); - - const int lineLen = - (width() / (characterWidth + m_charSpacing)) + - (((width() % (characterWidth + m_charSpacing)) >= characterWidth) ? 1 : 0); - const int numLines = - (height() / (characterHeight + m_lineSpacing)) + - (((height() % (characterHeight + m_lineSpacing)) >= characterHeight) ? 1 : 0); - - // Word wrap lines if enabled. - if (m_wordWrap) - { - list<string>::iterator lineIt = m_textLines.begin(); - while (lineIt != m_textLines.end()) - { - list<string>::iterator nextLineIt = lineIt; - nextLineIt++; - - // Wrap current line. - list<string> wrappedLines = wrapLines(*lineIt, lineLen); - m_textLines.splice(lineIt, wrappedLines); - // Remove old line. - m_textLines.erase(lineIt); +void Text::calculateLayout() const { + using std::list; + + // Split string into lines. + m_textLines = tokenizeString(m_text, '\n'); + + // Remove non-printable characters. + std::for_each(m_textLines.begin(), m_textLines.end(), + removeNonprintableChars); + + const int lineLen = + (width() / (characterWidth + m_charSpacing)) + + (((width() % (characterWidth + m_charSpacing)) >= characterWidth) ? 1 + : 0); + const int numLines = + (height() / (characterHeight + m_lineSpacing)) + + (((height() % (characterHeight + m_lineSpacing)) >= characterHeight) ? 1 + : 0); + + // Word wrap lines if enabled. + if (m_wordWrap) { + list<string>::iterator lineIt = m_textLines.begin(); + while (lineIt != m_textLines.end()) { + list<string>::iterator nextLineIt = lineIt; + nextLineIt++; - lineIt = nextLineIt; - } + // Wrap current line. + list<string> wrappedLines = wrapLines(*lineIt, lineLen); + m_textLines.splice(lineIt, wrappedLines); + // Remove old line. + m_textLines.erase(lineIt); + + lineIt = nextLineIt; } - - // Calculate preferred size. - string::size_type maxLineLength = - std::max_element(m_textLines.begin(), m_textLines.end(), compareStringLength)->length(); - m_preferredWidth = (maxLineLength > 0) ? - (maxLineLength * characterWidth) + ((maxLineLength - 1) * m_charSpacing) : 1; - m_preferredHeight = - (m_textLines.size() * characterHeight) + ((m_textLines.size() - 1) * m_lineSpacing); - - // Remove clipped text. - if (m_textLines.size() > static_cast<list<string>::size_type>(numLines)) - m_textLines.resize(numLines); - std::for_each(m_textLines.begin(), m_textLines.end(), TrimString(lineLen)); + } + + // Calculate preferred size. + string::size_type maxLineLength = + std::max_element(m_textLines.begin(), m_textLines.end(), + compareStringLength)->length(); + m_preferredWidth = (maxLineLength > 0) + ? (maxLineLength * characterWidth) + + ((maxLineLength - 1) * m_charSpacing) + : 1; + m_preferredHeight = (m_textLines.size() * characterHeight) + + ((m_textLines.size() - 1) * m_lineSpacing); + + // Remove clipped text. + if (m_textLines.size() > static_cast<list<string>::size_type>(numLines)) + m_textLines.resize(numLines); + std::for_each(m_textLines.begin(), m_textLines.end(), TrimString(lineLen)); }
--- a/Text.hpp Thu Jun 01 14:21:58 2017 -0500 +++ b/Text.hpp Mon Nov 06 18:12:27 2017 -0600 @@ -38,57 +38,57 @@ #include "Graphic.hpp" /// Text graphical primitive. -class Text : public Graphic -{ +class Text : public Graphic { public: - Text(); - - /// @{ - /// Text string to display. - /// @details Only printable ASCII characters and the line feed ('\n') will be displayed. - const std::string & text() const { return m_text; } - void setText(const std::string & text); - /// @} - - /// @{ - /// Lines will wrapped when they are too long to be displayed with the current width. - bool wordWrap() const { return m_wordWrap; } - void setWordWrap(bool wordWrap); - /// @} - - /// @{ - /// Spacing in pixels between characters. - int charSpacing() const { return m_charSpacing; } - void setCharSpacing(int charSpacing); - /// @} - - /// @{ - /// Spacing in pixels between lines. - int lineSpacing() const { return m_lineSpacing; } - void setLineSpacing(int lineSpacing); - /// @} - - /// @{ - /// @note Preferred width and height are calculated after word wrapping. - int preferredWidth() const; - int preferredHeight() const; - /// @} - + Text(); + + /// @{ + /// Text string to display. + /// @details + /// Only printable ASCII characters and the line feed ('\n') will be displayed. + const std::string & text() const { return m_text; } + void setText(const std::string & text); + /// @} + + /// @{ + /// Lines will wrapped when they are too long to be displayed with the current width. + bool wordWrap() const { return m_wordWrap; } + void setWordWrap(bool wordWrap); + /// @} + + /// @{ + /// Spacing in pixels between characters. + int charSpacing() const { return m_charSpacing; } + void setCharSpacing(int charSpacing); + /// @} + + /// @{ + /// Spacing in pixels between lines. + int lineSpacing() const { return m_lineSpacing; } + void setLineSpacing(int lineSpacing); + /// @} + + /// @{ + /// @note Preferred width and height are calculated after word wrapping. + int preferredWidth() const; + int preferredHeight() const; + /// @} + protected: - virtual void resized(); - virtual void doRender(Bitmap & bitmap, int xOffset, int yOffset) const; + virtual void resized(); + virtual void doRender(Bitmap & bitmap, int xOffset, int yOffset) const; private: - void calculateLayout() const; + void calculateLayout() const; - std::string m_text; - bool m_wordWrap; - int m_charSpacing; - int m_lineSpacing; - - mutable std::list<std::string> m_textLines; - mutable int m_preferredWidth; - mutable int m_preferredHeight; + std::string m_text; + bool m_wordWrap; + int m_charSpacing; + int m_lineSpacing; + + mutable std::list<std::string> m_textLines; + mutable int m_preferredWidth; + mutable int m_preferredHeight; }; #endif
--- a/WifiConnectWindow.cpp Thu Jun 01 14:21:58 2017 -0500 +++ b/WifiConnectWindow.cpp Mon Nov 06 18:12:27 2017 -0600 @@ -34,153 +34,143 @@ #include <wait_api.h> #include <TCPSocket.h> #include "CC3100.hpp" -#include "WindowManager.hpp" #include "DisplayIdWindow.hpp" +#include "ErrorWindow.hpp" +#include "MakeFunction.hpp" #include "NormalOperationWindow.hpp" -#include "ErrorWindow.hpp" #include "WifiConnectWindow.hpp" +#include "WindowManager.hpp" static const char wifiSsid[] = "MAXREFDES155"; static const char wifiPassword[] = "maxim1234"; static const char serverAddress[] = "www.maxim-security.com"; static const uint16_t serverPort = 3900; -WifiConnectWindow::WifiConnectWindow() : m_state(NotStarted) -{ - m_description.setParent(this); - m_description.setText("WiFi SSID: " + std::string(wifiSsid) + "\nWiFi Password: " + std::string(wifiPassword)); - m_description.setWordWrap(true); - m_backButton.setParent(this); - m_backButton.setText("Back"); - m_backButton.setClickedHandler(Button::EventHandler(this, &WifiConnectWindow::backButtonClicked)); - m_continueButton.setParent(this); - m_continueButton.setText("Connect to WiFi"); - m_continueButton.setClickedHandler(Button::EventHandler(this, &WifiConnectWindow::continueButtonClicked)); - m_continueButton.setFocused(); +WifiConnectWindow::WifiConnectWindow() : m_state(NotStarted) { + m_description.setParent(this); + m_description.setText("WiFi SSID: " + std::string(wifiSsid) + + "\nWiFi Password: " + std::string(wifiPassword)); + m_description.setWordWrap(true); + m_backButton.setParent(this); + m_backButton.setText("Back"); + m_backButton.setClickedHandler( + makeFunction(this, &WifiConnectWindow::backButtonClicked)); + m_continueButton.setParent(this); + m_continueButton.setText("Connect to WiFi"); + m_continueButton.setClickedHandler( + makeFunction(this, &WifiConnectWindow::continueButtonClicked)); + m_continueButton.setFocused(); } -void WifiConnectWindow::updated() -{ - switch (m_state) - { - case NotStarted: - break; - - case PreConnect: - m_backButton.setParent(NULL); - m_continueButton.setParent(NULL); - m_description.setText("Connecting to WiFi network..."); - m_state = WiFiConnect; - break; - - case WiFiConnect: - { - // Connect to AP. - int result = CC3100::instance().connect(wifiSsid, wifiPassword, NSAPI_SECURITY_WPA2); - if (result != 0) - { - if (windowManager() != NULL) - { - windowManager()->pop(); - std::auto_ptr<Window> window(new ErrorWindow("WiFi connect failed")); - windowManager()->push(window); - } - break; - } - - m_description.setText("Connecting to server..."); - m_state = ServerConnect; - } - break; - - case ServerConnect: - { - // Get IP address from DNS lookup. - SocketAddress socketAddress; - int result = CC3100::instance().gethostbyname(serverAddress, &socketAddress); - if (result != 0) - { - if (windowManager() != NULL) - { - windowManager()->pop(); - std::auto_ptr<Window> window(new ErrorWindow("Hostname lookup failed")); - windowManager()->push(window); - } - break; - } - - // Open socket connection. - std::auto_ptr<TCPSocket> socket(new TCPSocket(&CC3100::instance())); - socket->set_blocking(false); - socketAddress.set_port(serverPort); - result = socket->connect(socketAddress); - if (result != 0) - { - if (windowManager() != NULL) - { - windowManager()->pop(); - std::auto_ptr<Window> window(new ErrorWindow("Socket connect failed")); - windowManager()->push(window); - } - break; - } - - if (windowManager() != NULL) - { - windowManager()->pop(); - std::auto_ptr<Window> window(new NormalOperationWindow(socket)); - windowManager()->push(window); - } - } - break; +void WifiConnectWindow::updated() { + switch (m_state) { + case NotStarted: + break; + + case PreConnect: + m_backButton.setParent(NULL); + m_continueButton.setParent(NULL); + m_description.setText("Connecting to WiFi network..."); + m_state = WiFiConnect; + break; + + case WiFiConnect: { + // Connect to AP. + int result = + CC3100::instance().connect(wifiSsid, wifiPassword, NSAPI_SECURITY_WPA2); + if (result != 0) { + if (windowManager() != NULL) { + windowManager()->pop(); + std::auto_ptr<Window> window(new ErrorWindow("WiFi connect failed")); + windowManager()->push(window); + } + break; } + + m_description.setText("Connecting to server..."); + m_state = ServerConnect; + } break; + + case ServerConnect: { + // Get IP address from DNS lookup. + SocketAddress socketAddress; + int result = + CC3100::instance().gethostbyname(serverAddress, &socketAddress); + if (result != 0) { + if (windowManager() != NULL) { + windowManager()->pop(); + std::auto_ptr<Window> window(new ErrorWindow("Hostname lookup failed")); + windowManager()->push(window); + } + break; + } + + // Open socket connection. + std::auto_ptr<TCPSocket> socket(new TCPSocket(&CC3100::instance())); + socket->set_blocking(false); + socketAddress.set_port(serverPort); + result = socket->connect(socketAddress); + if (result != 0) { + if (windowManager() != NULL) { + windowManager()->pop(); + std::auto_ptr<Window> window(new ErrorWindow("Socket connect failed")); + windowManager()->push(window); + } + break; + } + + if (windowManager() != NULL) { + windowManager()->pop(); + std::auto_ptr<Window> window(new NormalOperationWindow(socket)); + windowManager()->push(window); + } + } break; + } } -void WifiConnectWindow::resized() -{ - m_backButton.resize(m_backButton.preferredWidth(), m_backButton.preferredHeight()); - m_backButton.move(0, height() - m_backButton.height()); - m_continueButton.resize(m_continueButton.preferredWidth(), m_continueButton.preferredHeight()); - m_continueButton.move(width() - m_continueButton.width(), height() - m_continueButton.height()); - m_description.resize(width(), std::min(m_backButton.y(), m_continueButton.y())); +void WifiConnectWindow::resized() { + m_backButton.resize(m_backButton.preferredWidth(), + m_backButton.preferredHeight()); + m_backButton.move(0, height() - m_backButton.height()); + m_continueButton.resize(m_continueButton.preferredWidth(), + m_continueButton.preferredHeight()); + m_continueButton.move(width() - m_continueButton.width(), + height() - m_continueButton.height()); + m_description.resize(width(), + std::min(m_backButton.y(), m_continueButton.y())); } -bool WifiConnectWindow::doProcessKey(Key key) -{ - bool handled; - switch (key) - { - case LeftKey: - m_backButton.setFocused(); - handled = true; - break; - - case RightKey: - m_continueButton.setFocused(); - handled = true; - break; - - default: - handled = false; - break; - } - return handled; +bool WifiConnectWindow::doProcessKey(Key key) { + bool handled; + switch (key) { + case LeftKey: + m_backButton.setFocused(); + handled = true; + break; + + case RightKey: + m_continueButton.setFocused(); + handled = true; + break; + + default: + handled = false; + break; + } + return handled; } -void WifiConnectWindow::continueButtonClicked() -{ - if (m_state == NotStarted) - { - m_state = PreConnect; - } +void WifiConnectWindow::continueButtonClicked(Button *) { + if (m_state == NotStarted) { + m_state = PreConnect; + } } -void WifiConnectWindow::backButtonClicked() -{ - if (windowManager() != NULL) - { - windowManager()->pop(); - std::auto_ptr<Window> window(new DisplayIdWindow(DisplayIdWindow::PreConnectMode)); - windowManager()->push(window); - } +void WifiConnectWindow::backButtonClicked(Button *) { + if (windowManager() != NULL) { + windowManager()->pop(); + std::auto_ptr<Window> window( + new DisplayIdWindow(DisplayIdWindow::PreConnectMode)); + windowManager()->push(window); + } }
--- a/WifiConnectWindow.hpp Thu Jun 01 14:21:58 2017 -0500 +++ b/WifiConnectWindow.hpp Mon Nov 06 18:12:27 2017 -0600 @@ -33,37 +33,36 @@ #ifndef WIFICONNECTSTATE_HPP #define WIFICONNECTSTATE_HPP +#include "Button.hpp" #include "Text.hpp" -#include "Button.hpp" #include "Window.hpp" -/// Displays Wi-Fi connection information, connects to the Wi-Fi AP, and connects to the server. -class WifiConnectWindow : public Window -{ +/// Displays Wi-Fi connection information, connects to the Wi-Fi AP, and +/// connects to the server. +class WifiConnectWindow : public Window { public: - WifiConnectWindow(); - + WifiConnectWindow(); + protected: - virtual void resized(); - virtual void updated(); - virtual bool doProcessKey(Key key); - + virtual void resized(); + virtual void updated(); + virtual bool doProcessKey(Key key); + private: - enum State - { - NotStarted, // Display Wi-Fi connection information. - PreConnect, // Display connecting to Wi-Fi message. - WiFiConnect, // Connect to Wi-Fi AP. - ServerConnect // Connect to server. - }; - - State m_state; - Text m_description; - Button m_backButton; - Button m_continueButton; - - void continueButtonClicked(); - void backButtonClicked(); + enum State { + NotStarted, // Display Wi-Fi connection information. + PreConnect, // Display connecting to Wi-Fi message. + WiFiConnect, // Connect to Wi-Fi AP. + ServerConnect // Connect to server. + }; + + State m_state; + Text m_description; + Button m_backButton; + Button m_continueButton; + + void continueButtonClicked(Button *); + void backButtonClicked(Button *); }; #endif
--- a/Window.hpp Thu Jun 01 14:21:58 2017 -0500 +++ b/Window.hpp Mon Nov 06 18:12:27 2017 -0600 @@ -38,24 +38,22 @@ class WindowManager; /// Adds window properties to a Graphic. -class Window : public Graphic -{ +class Window : public Graphic { public: - Window() : m_windowManager(NULL) { } - - /// @{ - /// Current window manager or NULL if no window manager has been set. - const WindowManager * windowManager() const { return m_windowManager; } - WindowManager * windowManager() { return m_windowManager; } - void setWindowManager(WindowManager * windowManager) - { - m_windowManager = windowManager; - invalidate(); - } - /// @} - + Window() : m_windowManager(NULL) {} + + /// @{ + /// Current window manager or NULL if no window manager has been set. + const WindowManager * windowManager() const { return m_windowManager; } + WindowManager * windowManager() { return m_windowManager; } + void setWindowManager(WindowManager * windowManager) { + m_windowManager = windowManager; + invalidate(); + } + /// @} + private: - WindowManager * m_windowManager; + WindowManager * m_windowManager; }; #endif
--- a/WindowManager.cpp Thu Jun 01 14:21:58 2017 -0500 +++ b/WindowManager.cpp Mon Nov 06 18:12:27 2017 -0600 @@ -35,94 +35,71 @@ #include "Bitmap.hpp" #include "WindowManager.hpp" -static void deleteWindow(Window * window) -{ - delete window; -} +static void deleteWindow(Window * window) { delete window; } -WindowManager::~WindowManager() -{ - // Free all windows. - std::for_each(windowStack.begin(), windowStack.end(), deleteWindow); - std::for_each(actionQueue.begin(), actionQueue.end(), deleteWindow); +WindowManager::~WindowManager() { + // Free all windows. + std::for_each(windowStack.begin(), windowStack.end(), deleteWindow); + std::for_each(actionQueue.begin(), actionQueue.end(), deleteWindow); } -void WindowManager::processAction(Window * window) -{ - if (window == NULL) - { - if (!windowStack.empty()) - { - delete windowStack.back(); - windowStack.pop_back(); - } +void WindowManager::processAction(Window * window) { + if (window == NULL) { + if (!windowStack.empty()) { + delete windowStack.back(); + windowStack.pop_back(); } - else - { - windowStack.push_back(window); - } + } else { + windowStack.push_back(window); + } } -void WindowManager::push(std::auto_ptr<Window> & window) -{ - if (window.get() != NULL) - { - window->resize(canvas.width(), canvas.height()); - window->move(0, 0); - window->setWindowManager(NULL); - actionQueue.push_back(window.release()); - } -} - -void WindowManager::pop() -{ - actionQueue.push_back(NULL); +void WindowManager::push(std::auto_ptr<Window> & window) { + if (window.get() != NULL) { + window->resize(canvas.width(), canvas.height()); + window->move(0, 0); + window->setWindowManager(NULL); + actionQueue.push_back(window.release()); + } } -bool WindowManager::update() -{ - bool redraw = false; - - // Perform all queued push / pop actions. - if (!actionQueue.empty()) - { - if (!windowStack.empty()) - { - windowStack.back()->setWindowManager(NULL); - } - std::for_each(actionQueue.begin(), actionQueue.end(), - std::bind1st(std::mem_fun(&WindowManager::processAction), this)); - actionQueue.clear(); - if (windowStack.empty()) - { - canvas.clear(); - redraw = true; - } - else - { - windowStack.back()->setWindowManager(this); - } +void WindowManager::pop() { actionQueue.push_back(NULL); } + +bool WindowManager::update() { + bool redraw = false; + + // Perform all queued push / pop actions. + if (!actionQueue.empty()) { + if (!windowStack.empty()) { + windowStack.back()->setWindowManager(NULL); } - - if (!windowStack.empty()) - { - // Update all windows. Only allow redraw of the top window. - for (std::vector<Window *>::reverse_iterator it = windowStack.rbegin(); it != windowStack.rend(); it++) - { - if ((*it)->update(it == windowStack.rbegin() ? &canvas : NULL)) - { - redraw = true; - } - } + std::for_each( + actionQueue.begin(), actionQueue.end(), + std::bind1st(std::mem_fun(&WindowManager::processAction), this)); + actionQueue.clear(); + if (windowStack.empty()) { + canvas.clear(); + redraw = true; + } else { + windowStack.back()->setWindowManager(this); } - - return redraw; + } + + if (!windowStack.empty()) { + // Update all windows. Only allow redraw of the top window. + for (std::vector<Window *>::reverse_iterator it = windowStack.rbegin(); + it != windowStack.rend(); it++) { + if ((*it)->update(it == windowStack.rbegin() ? &canvas : NULL)) { + redraw = true; + } + } + } + + return redraw; } -void WindowManager::processKey(Key key) -{ - if (!windowStack.empty()) - { - windowStack.back()->processKey(key); - } +void WindowManager::processKey(Key key) { + if (!windowStack.empty()) { + windowStack.back()->processKey(key); + } }
--- a/WindowManager.hpp Thu Jun 01 14:21:58 2017 -0500 +++ b/WindowManager.hpp Mon Nov 06 18:12:27 2017 -0600 @@ -41,39 +41,40 @@ class Bitmap; /// Stack based window manager. -class WindowManager -{ +class WindowManager { public: - /// @param canvas Canvas to use for rendering. - WindowManager(Bitmap & canvas) : canvas(canvas) { } - ~WindowManager(); - - /// Push a window onto the top of the stack. - /// @details The operation will be queued until the next update. - /// @param window Heap allocated object that WindowManager will take ownership of. - void push(std::auto_ptr<Window> & window); - - /// Pop a window from the top of the stack. - /// @details The operation will be queued until the next update. The popped window will be deleted. - void pop(); - - /// Updates all windows and redraws the top window if invalid. - /// @returns True if the canvas has been updated. - bool update(); - - /// Forwards a key-press input event to the top window for processing. - void processKey(Key key); + /// @param canvas Canvas to use for rendering. + WindowManager(Bitmap & canvas) : canvas(canvas) {} + ~WindowManager(); + + /// Push a window onto the top of the stack. + /// @details The operation will be queued until the next update. + /// @param window + /// Heap allocated object that WindowManager will take ownership of. + void push(std::auto_ptr<Window> & window); + + /// Pop a window from the top of the stack. + /// @details The operation will be queued until the next update. The popped + /// window will be deleted. + void pop(); + + /// Updates all windows and redraws the top window if invalid. + /// @returns True if the canvas has been updated. + bool update(); + + /// Forwards a key-press input event to the top window for processing. + void processKey(Key key); private: - void processAction(Window * window); + void processAction(Window * window); - Bitmap & canvas; - std::vector<Window *> windowStack; - std::vector<Window *> actionQueue; - - // Uncopyable - WindowManager(const WindowManager &); - const WindowManager & operator=(const WindowManager &); + Bitmap & canvas; + std::vector<Window *> windowStack; + std::vector<Window *> actionQueue; + + // Uncopyable + WindowManager(const WindowManager &); + const WindowManager & operator=(const WindowManager &); }; #endif
--- a/main.cpp Thu Jun 01 14:21:58 2017 -0500 +++ b/main.cpp Mon Nov 06 18:12:27 2017 -0600 @@ -33,13 +33,15 @@ #include <string> #include <DigitalIn.h> #include <I2C.h> -#include "SensorNode.hpp" -#include "DS2476.hpp" +#include <MaximInterface/Platforms/mbed/I2CMaster.hpp> +#include <MaximInterface/Platforms/mbed/Sleep.hpp> +#include <MaximInterface/Devices/DS28C36_DS2476.hpp> #include "CC3100.hpp" #include "Display.hpp" +#include "InitWindow.hpp" #include "Keys.hpp" +#include "SensorNode.hpp" #include "WindowManager.hpp" -#include "InitWindow.hpp" static mbed::DigitalIn upButton(D5); static mbed::DigitalIn downButton(D4); @@ -51,71 +53,56 @@ static Display display(D11, D12, D13, D7, D6); static WindowManager windowManager(display.canvas()); -static mbed::I2C i2c(D14, D15); -DS2476 coproc(i2c); +static mbed::I2C mbedI2C(D14, D15); +static MaximInterface::mbed::I2CMaster i2c(mbedI2C); +MaximInterface::DS2476 coproc(MaximInterface::mbed::Sleep::instance(), i2c); SensorNode sensorNode(i2c, coproc); std::string webId; static bool buttonPressed(mbed::DigitalIn & button); -int main() -{ - i2c.frequency(100000); - display.initialize(); - // Set initial window. - { - std::auto_ptr<Window> window(new InitWindow); - windowManager.push(window); +int main() { + mbedI2C.frequency(100000); + display.initialize(); + // Set initial window. + { + std::auto_ptr<Window> window(new InitWindow); + windowManager.push(window); + } + while (true) { + // Update window manager and redraw screen if necessary. + if (windowManager.update()) { + display.update(); } - while (true) - { - // Update window manager and redraw screen if necessary. - if (windowManager.update()) - { - display.update(); - } - // Update CC3100 Wi-Fi interface. - CC3100::instance().update(); - // Check if any buttons are pressed. - if (buttonPressed(leftClickButton)) - { - windowManager.processKey(LeftClickKey); - } - else if (buttonPressed(rightClickButton)) - { - windowManager.processKey(RightClickKey); - } - else if (buttonPressed(upButton)) - { - windowManager.processKey(UpKey); - } - else if (buttonPressed(downButton)) - { - windowManager.processKey(DownKey); - } - else if (buttonPressed(leftButton)) - { - windowManager.processKey(LeftKey); - } - else if (buttonPressed(rightButton)) - { - windowManager.processKey(RightKey); - } + // Update CC3100 Wi-Fi interface. + CC3100::instance().update(); + // Check if any buttons are pressed. + if (buttonPressed(leftClickButton)) { + windowManager.processKey(LeftClickKey); + } else if (buttonPressed(rightClickButton)) { + windowManager.processKey(RightClickKey); + } else if (buttonPressed(upButton)) { + windowManager.processKey(UpKey); + } else if (buttonPressed(downButton)) { + windowManager.processKey(DownKey); + } else if (buttonPressed(leftButton)) { + windowManager.processKey(LeftKey); + } else if (buttonPressed(rightButton)) { + windowManager.processKey(RightKey); } + } } /// Checks if button is pressed and waits for release. /// @param button Active low button to check. /// @returns True if pressed. -static bool buttonPressed(mbed::DigitalIn & button) -{ - const int buttonPressed = 0; // Active low - if (button == buttonPressed) - { - while (button == buttonPressed) ; - return true; - } - // else - return false; +static bool buttonPressed(mbed::DigitalIn & button) { + const int buttonPressed = 0; // Active low + if (button == buttonPressed) { + while (button == buttonPressed); + return true; + } + // else + return false; }