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.

Committer:
IanBenzMaxim
Date:
Tue Dec 03 12:56:25 2019 -0600
Revision:
18:c2631e985780
Parent:
17:5926077e5345
Updated MaximInterface to version 2.1.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
IanBenzMaxim 0:33d4e66780c0 1 /*******************************************************************************
IanBenzMaxim 16:a004191a79ab 2 * Copyright (C) Maxim Integrated Products, Inc., All Rights Reserved.
IanBenzMaxim 0:33d4e66780c0 3 *
IanBenzMaxim 0:33d4e66780c0 4 * Permission is hereby granted, free of charge, to any person obtaining a
IanBenzMaxim 0:33d4e66780c0 5 * copy of this software and associated documentation files (the "Software"),
IanBenzMaxim 0:33d4e66780c0 6 * to deal in the Software without restriction, including without limitation
IanBenzMaxim 0:33d4e66780c0 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
IanBenzMaxim 0:33d4e66780c0 8 * and/or sell copies of the Software, and to permit persons to whom the
IanBenzMaxim 0:33d4e66780c0 9 * Software is furnished to do so, subject to the following conditions:
IanBenzMaxim 0:33d4e66780c0 10 *
IanBenzMaxim 0:33d4e66780c0 11 * The above copyright notice and this permission notice shall be included
IanBenzMaxim 0:33d4e66780c0 12 * in all copies or substantial portions of the Software.
IanBenzMaxim 0:33d4e66780c0 13 *
IanBenzMaxim 0:33d4e66780c0 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
IanBenzMaxim 0:33d4e66780c0 15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
IanBenzMaxim 0:33d4e66780c0 16 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IanBenzMaxim 0:33d4e66780c0 17 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
IanBenzMaxim 0:33d4e66780c0 18 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
IanBenzMaxim 0:33d4e66780c0 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
IanBenzMaxim 0:33d4e66780c0 20 * OTHER DEALINGS IN THE SOFTWARE.
IanBenzMaxim 0:33d4e66780c0 21 *
IanBenzMaxim 0:33d4e66780c0 22 * Except as contained in this notice, the name of Maxim Integrated
IanBenzMaxim 0:33d4e66780c0 23 * Products, Inc. shall not be used except as stated in the Maxim Integrated
IanBenzMaxim 0:33d4e66780c0 24 * Products, Inc. Branding Policy.
IanBenzMaxim 0:33d4e66780c0 25 *
IanBenzMaxim 0:33d4e66780c0 26 * The mere transfer of this software does not imply any licenses
IanBenzMaxim 0:33d4e66780c0 27 * of trade secrets, proprietary technology, copyrights, patents,
IanBenzMaxim 0:33d4e66780c0 28 * trademarks, maskwork rights, or any other form of intellectual
IanBenzMaxim 0:33d4e66780c0 29 * property whatsoever. Maxim Integrated Products, Inc. retains all
IanBenzMaxim 0:33d4e66780c0 30 * ownership rights.
IanBenzMaxim 0:33d4e66780c0 31 *******************************************************************************/
IanBenzMaxim 0:33d4e66780c0 32
IanBenzMaxim 3:d2799d8497c0 33 #include <cstdio>
IanBenzMaxim 3:d2799d8497c0 34 #include <cstring>
IanBenzMaxim 0:33d4e66780c0 35 #include <simplelink.h>
IanBenzMaxim 17:5926077e5345 36 #include <mbed-os/drivers/InterruptIn.h>
IanBenzMaxim 16:a004191a79ab 37 #include <mbed-os/platform/mbed_wait_api.h>
IanBenzMaxim 0:33d4e66780c0 38 #include "CC3100.hpp"
IanBenzMaxim 0:33d4e66780c0 39
IanBenzMaxim 3:d2799d8497c0 40 using std::printf;
IanBenzMaxim 3:d2799d8497c0 41 using std::strlen;
IanBenzMaxim 3:d2799d8497c0 42
IanBenzMaxim 0:33d4e66780c0 43 static CC3100::State currentState = CC3100::Stopped;
IanBenzMaxim 0:33d4e66780c0 44
IanBenzMaxim 17:5926077e5345 45 static mbed::InterruptIn irq(MBED_CONF_APP_CC3100_INTR_PIN);
IanBenzMaxim 17:5926077e5345 46 static mbed::DigitalOut nHIB(MBED_CONF_APP_CC3100_NHIB_PIN, 0);
IanBenzMaxim 17:5926077e5345 47
IanBenzMaxim 17:5926077e5345 48 static SL_P_EVENT_HANDLER pIrqEventHandler = NULL;
IanBenzMaxim 17:5926077e5345 49 static void * pIrqEventHandlerValue = NULL;
IanBenzMaxim 17:5926077e5345 50
IanBenzMaxim 17:5926077e5345 51 _SlFd_t sl_IfOpen(const char * ifName, unsigned long flags) {
IanBenzMaxim 17:5926077e5345 52 _SlFd_t fd = NULL;
IanBenzMaxim 17:5926077e5345 53 if (ifName) {
IanBenzMaxim 17:5926077e5345 54 std::sscanf(ifName, "%p", &fd);
IanBenzMaxim 17:5926077e5345 55 }
IanBenzMaxim 17:5926077e5345 56 return fd;
IanBenzMaxim 17:5926077e5345 57 }
IanBenzMaxim 17:5926077e5345 58
IanBenzMaxim 17:5926077e5345 59 int sl_IfClose(_SlFd_t fd) {
IanBenzMaxim 17:5926077e5345 60 return 0; // Success
IanBenzMaxim 17:5926077e5345 61 }
IanBenzMaxim 17:5926077e5345 62
IanBenzMaxim 17:5926077e5345 63 int sl_IfRead(_SlFd_t fd, unsigned char * pBuff, int len) {
IanBenzMaxim 17:5926077e5345 64 if (!fd) {
IanBenzMaxim 17:5926077e5345 65 return 0; // Failure
IanBenzMaxim 17:5926077e5345 66 }
IanBenzMaxim 17:5926077e5345 67 std::memset(pBuff, 0xFF, len);
IanBenzMaxim 17:5926077e5345 68 static_cast<CC3100::SPI *>(fd)->transfer(pBuff, len, pBuff);
IanBenzMaxim 17:5926077e5345 69 return len; // Success
IanBenzMaxim 17:5926077e5345 70 }
IanBenzMaxim 17:5926077e5345 71
IanBenzMaxim 17:5926077e5345 72 int sl_IfWrite(_SlFd_t fd, const unsigned char * pBuff, int len) {
IanBenzMaxim 17:5926077e5345 73 if (!fd) {
IanBenzMaxim 17:5926077e5345 74 return 0; // Failure
IanBenzMaxim 17:5926077e5345 75 }
IanBenzMaxim 17:5926077e5345 76 static_cast<CC3100::SPI *>(fd)->transfer(pBuff, len, NULL);
IanBenzMaxim 17:5926077e5345 77 return len; // Success
IanBenzMaxim 17:5926077e5345 78 }
IanBenzMaxim 17:5926077e5345 79
IanBenzMaxim 17:5926077e5345 80 int sl_IfRegIntHdlr(SL_P_EVENT_HANDLER InterruptHdl, void * pValue) {
IanBenzMaxim 17:5926077e5345 81 pIrqEventHandler = InterruptHdl;
IanBenzMaxim 17:5926077e5345 82 pIrqEventHandlerValue = pValue;
IanBenzMaxim 17:5926077e5345 83 return 0; // Success
IanBenzMaxim 17:5926077e5345 84 }
IanBenzMaxim 17:5926077e5345 85
IanBenzMaxim 17:5926077e5345 86 static void interruptHandler(void) {
IanBenzMaxim 17:5926077e5345 87 if (pIrqEventHandler) {
IanBenzMaxim 17:5926077e5345 88 pIrqEventHandler(pIrqEventHandlerValue);
IanBenzMaxim 17:5926077e5345 89 }
IanBenzMaxim 17:5926077e5345 90 }
IanBenzMaxim 17:5926077e5345 91
IanBenzMaxim 17:5926077e5345 92 void sl_DeviceEnable(void) {
IanBenzMaxim 17:5926077e5345 93 irq.rise(&interruptHandler);
IanBenzMaxim 17:5926077e5345 94 nHIB = 1;
IanBenzMaxim 17:5926077e5345 95 }
IanBenzMaxim 17:5926077e5345 96
IanBenzMaxim 17:5926077e5345 97 void sl_DeviceDisable(void) {
IanBenzMaxim 17:5926077e5345 98 irq.rise(NULL);
IanBenzMaxim 17:5926077e5345 99 nHIB = 0;
IanBenzMaxim 17:5926077e5345 100 }
IanBenzMaxim 17:5926077e5345 101
IanBenzMaxim 0:33d4e66780c0 102 /*!
IanBenzMaxim 0:33d4e66780c0 103 \brief This function handles general error events indication
IanBenzMaxim 0:33d4e66780c0 104
IanBenzMaxim 0:33d4e66780c0 105 \param[in] pDevEvent is the event passed to the handler
IanBenzMaxim 0:33d4e66780c0 106
IanBenzMaxim 0:33d4e66780c0 107 \return None
IanBenzMaxim 0:33d4e66780c0 108 */
IanBenzMaxim 13:6a6225690c2e 109 void SimpleLinkGeneralEventHandler(SlDeviceEvent_t * pDevEvent) {
IanBenzMaxim 13:6a6225690c2e 110 /*
IanBenzMaxim 13:6a6225690c2e 111 * Most of the general errors are not FATAL are are to be handled
IanBenzMaxim 13:6a6225690c2e 112 * appropriately by the application
IanBenzMaxim 13:6a6225690c2e 113 */
IanBenzMaxim 13:6a6225690c2e 114 printf(" [GENERAL EVENT] \n\r");
IanBenzMaxim 0:33d4e66780c0 115 }
IanBenzMaxim 0:33d4e66780c0 116
IanBenzMaxim 0:33d4e66780c0 117 /*!
IanBenzMaxim 0:33d4e66780c0 118 \brief This function handles WLAN events
IanBenzMaxim 0:33d4e66780c0 119
IanBenzMaxim 0:33d4e66780c0 120 \param[in] pWlanEvent is the event passed to the handler
IanBenzMaxim 0:33d4e66780c0 121
IanBenzMaxim 0:33d4e66780c0 122 \return None
IanBenzMaxim 0:33d4e66780c0 123
IanBenzMaxim 0:33d4e66780c0 124 \note
IanBenzMaxim 0:33d4e66780c0 125
IanBenzMaxim 0:33d4e66780c0 126 \warning
IanBenzMaxim 0:33d4e66780c0 127 */
IanBenzMaxim 13:6a6225690c2e 128 void SimpleLinkWlanEventHandler(SlWlanEvent_t * pWlanEvent) {
IanBenzMaxim 16:a004191a79ab 129 if (!pWlanEvent) {
IanBenzMaxim 13:6a6225690c2e 130 printf(" [WLAN EVENT] NULL Pointer Error \n\r");
IanBenzMaxim 13:6a6225690c2e 131 return;
IanBenzMaxim 13:6a6225690c2e 132 }
IanBenzMaxim 13:6a6225690c2e 133
IanBenzMaxim 13:6a6225690c2e 134 switch (pWlanEvent->Event) {
IanBenzMaxim 13:6a6225690c2e 135 case SL_WLAN_CONNECT_EVENT:
IanBenzMaxim 13:6a6225690c2e 136 currentState = CC3100::Connected;
IanBenzMaxim 0:33d4e66780c0 137
IanBenzMaxim 13:6a6225690c2e 138 /*
IanBenzMaxim 13:6a6225690c2e 139 * Information about the connected AP (like name, MAC etc) will be
IanBenzMaxim 13:6a6225690c2e 140 * available in 'slWlanConnectAsyncResponse_t' - Applications
IanBenzMaxim 13:6a6225690c2e 141 * can use it if required
IanBenzMaxim 13:6a6225690c2e 142 *
IanBenzMaxim 13:6a6225690c2e 143 * slWlanConnectAsyncResponse_t *pEventData = NULL;
IanBenzMaxim 13:6a6225690c2e 144 * pEventData = &pWlanEvent->EventData.STAandP2PModeWlanConnected;
IanBenzMaxim 13:6a6225690c2e 145 *
IanBenzMaxim 13:6a6225690c2e 146 */
IanBenzMaxim 13:6a6225690c2e 147 break;
IanBenzMaxim 0:33d4e66780c0 148
IanBenzMaxim 13:6a6225690c2e 149 case SL_WLAN_DISCONNECT_EVENT: {
IanBenzMaxim 13:6a6225690c2e 150 currentState = CC3100::Disconnected;
IanBenzMaxim 0:33d4e66780c0 151
IanBenzMaxim 13:6a6225690c2e 152 slWlanConnectAsyncResponse_t & pEventData =
IanBenzMaxim 13:6a6225690c2e 153 pWlanEvent->EventData.STAandP2PModeDisconnected;
IanBenzMaxim 0:33d4e66780c0 154
IanBenzMaxim 13:6a6225690c2e 155 /* If the user has initiated 'Disconnect' request, 'reason_code' is SL_USER_INITIATED_DISCONNECTION */
IanBenzMaxim 13:6a6225690c2e 156 if (SL_WLAN_DISCONNECT_USER_INITIATED_DISCONNECTION ==
IanBenzMaxim 13:6a6225690c2e 157 pEventData.reason_code) {
IanBenzMaxim 13:6a6225690c2e 158 printf(" Device disconnected from the AP on application's request \n\r");
IanBenzMaxim 13:6a6225690c2e 159 } else {
IanBenzMaxim 13:6a6225690c2e 160 printf(" Device disconnected from the AP on an ERROR..!! \n\r");
IanBenzMaxim 0:33d4e66780c0 161 }
IanBenzMaxim 13:6a6225690c2e 162 } break;
IanBenzMaxim 13:6a6225690c2e 163
IanBenzMaxim 13:6a6225690c2e 164 default:
IanBenzMaxim 13:6a6225690c2e 165 printf(" [WLAN EVENT] Unexpected event \n\r");
IanBenzMaxim 13:6a6225690c2e 166 break;
IanBenzMaxim 13:6a6225690c2e 167 }
IanBenzMaxim 0:33d4e66780c0 168 }
IanBenzMaxim 0:33d4e66780c0 169
IanBenzMaxim 0:33d4e66780c0 170 /*!
IanBenzMaxim 0:33d4e66780c0 171 \brief This function handles events for IP address acquisition via DHCP
IanBenzMaxim 0:33d4e66780c0 172 indication
IanBenzMaxim 0:33d4e66780c0 173
IanBenzMaxim 0:33d4e66780c0 174 \param[in] pNetAppEvent is the event passed to the handler
IanBenzMaxim 0:33d4e66780c0 175
IanBenzMaxim 0:33d4e66780c0 176 \return None
IanBenzMaxim 0:33d4e66780c0 177
IanBenzMaxim 0:33d4e66780c0 178 \note
IanBenzMaxim 0:33d4e66780c0 179
IanBenzMaxim 0:33d4e66780c0 180 \warning
IanBenzMaxim 0:33d4e66780c0 181 */
IanBenzMaxim 13:6a6225690c2e 182 void SimpleLinkNetAppEventHandler(SlNetAppEvent_t * pNetAppEvent) {
IanBenzMaxim 16:a004191a79ab 183 if (!pNetAppEvent) {
IanBenzMaxim 13:6a6225690c2e 184 printf(" [NETAPP EVENT] NULL Pointer Error \n\r");
IanBenzMaxim 13:6a6225690c2e 185 return;
IanBenzMaxim 13:6a6225690c2e 186 }
IanBenzMaxim 0:33d4e66780c0 187
IanBenzMaxim 13:6a6225690c2e 188 switch (pNetAppEvent->Event) {
IanBenzMaxim 13:6a6225690c2e 189 case SL_NETAPP_IPV4_IPACQUIRED_EVENT:
IanBenzMaxim 13:6a6225690c2e 190 currentState = CC3100::Connected;
IanBenzMaxim 0:33d4e66780c0 191
IanBenzMaxim 13:6a6225690c2e 192 //SlIpV4AcquiredAsync_t & pEventData = pNetAppEvent->EventData.ipAcquiredV4;
IanBenzMaxim 13:6a6225690c2e 193 break;
IanBenzMaxim 13:6a6225690c2e 194
IanBenzMaxim 13:6a6225690c2e 195 default:
IanBenzMaxim 13:6a6225690c2e 196 printf(" [NETAPP EVENT] Unexpected event \n\r");
IanBenzMaxim 13:6a6225690c2e 197 break;
IanBenzMaxim 13:6a6225690c2e 198 }
IanBenzMaxim 0:33d4e66780c0 199 }
IanBenzMaxim 0:33d4e66780c0 200
IanBenzMaxim 0:33d4e66780c0 201 /*!
IanBenzMaxim 0:33d4e66780c0 202 \brief This function handles socket events indication
IanBenzMaxim 0:33d4e66780c0 203
IanBenzMaxim 0:33d4e66780c0 204 \param[in] pSock is the event passed to the handler
IanBenzMaxim 0:33d4e66780c0 205
IanBenzMaxim 0:33d4e66780c0 206 \return None
IanBenzMaxim 0:33d4e66780c0 207 */
IanBenzMaxim 13:6a6225690c2e 208 void SimpleLinkSockEventHandler(SlSockEvent_t * pSock) {
IanBenzMaxim 16:a004191a79ab 209 if (!pSock) {
IanBenzMaxim 13:6a6225690c2e 210 printf(" [SOCK EVENT] NULL Pointer Error \n\r");
IanBenzMaxim 13:6a6225690c2e 211 return;
IanBenzMaxim 13:6a6225690c2e 212 }
IanBenzMaxim 0:33d4e66780c0 213
IanBenzMaxim 13:6a6225690c2e 214 switch (pSock->Event) {
IanBenzMaxim 13:6a6225690c2e 215 case SL_SOCKET_TX_FAILED_EVENT:
IanBenzMaxim 13:6a6225690c2e 216 /*
IanBenzMaxim 13:6a6225690c2e 217 * TX Failed
IanBenzMaxim 13:6a6225690c2e 218 *
IanBenzMaxim 13:6a6225690c2e 219 * Information about the socket descriptor and status will be
IanBenzMaxim 13:6a6225690c2e 220 * available in 'SlSockEventData_t' - Applications can use it if
IanBenzMaxim 13:6a6225690c2e 221 * required
IanBenzMaxim 13:6a6225690c2e 222 *
IanBenzMaxim 13:6a6225690c2e 223 * SlSockEventData_u *pEventData = NULL;
IanBenzMaxim 13:6a6225690c2e 224 * pEventData = & pSock->socketAsyncEvent;
IanBenzMaxim 13:6a6225690c2e 225 */
IanBenzMaxim 13:6a6225690c2e 226 switch (pSock->socketAsyncEvent.SockTxFailData.status) {
IanBenzMaxim 13:6a6225690c2e 227 case SL_ECLOSE:
IanBenzMaxim 13:6a6225690c2e 228 printf(" [SOCK EVENT] Close socket operation failed to transmit all "
IanBenzMaxim 13:6a6225690c2e 229 "queued packets\n\r");
IanBenzMaxim 13:6a6225690c2e 230 break;
IanBenzMaxim 0:33d4e66780c0 231
IanBenzMaxim 3:d2799d8497c0 232 default:
IanBenzMaxim 13:6a6225690c2e 233 printf(" [SOCK EVENT] Unexpected event \n\r");
IanBenzMaxim 13:6a6225690c2e 234 break;
IanBenzMaxim 0:33d4e66780c0 235 }
IanBenzMaxim 13:6a6225690c2e 236 break;
IanBenzMaxim 13:6a6225690c2e 237
IanBenzMaxim 13:6a6225690c2e 238 default:
IanBenzMaxim 13:6a6225690c2e 239 printf(" [SOCK EVENT] Unexpected event \n\r");
IanBenzMaxim 13:6a6225690c2e 240 break;
IanBenzMaxim 13:6a6225690c2e 241 }
IanBenzMaxim 0:33d4e66780c0 242 }
IanBenzMaxim 0:33d4e66780c0 243
IanBenzMaxim 0:33d4e66780c0 244 /*!
IanBenzMaxim 0:33d4e66780c0 245 \brief This function handles ping report events
IanBenzMaxim 0:33d4e66780c0 246
IanBenzMaxim 0:33d4e66780c0 247 \param[in] pPingReport holds the ping report statistics
IanBenzMaxim 0:33d4e66780c0 248
IanBenzMaxim 0:33d4e66780c0 249 \return None
IanBenzMaxim 0:33d4e66780c0 250
IanBenzMaxim 0:33d4e66780c0 251 \note
IanBenzMaxim 0:33d4e66780c0 252
IanBenzMaxim 0:33d4e66780c0 253 \warning
IanBenzMaxim 0:33d4e66780c0 254 */
IanBenzMaxim 13:6a6225690c2e 255 static void SimpleLinkPingReport(SlPingReport_t * pPingReport) {
IanBenzMaxim 13:6a6225690c2e 256 currentState = CC3100::Connected;
IanBenzMaxim 0:33d4e66780c0 257
IanBenzMaxim 16:a004191a79ab 258 if (!pPingReport) {
IanBenzMaxim 13:6a6225690c2e 259 printf(" [PING REPORT] NULL Pointer Error\r\n");
IanBenzMaxim 13:6a6225690c2e 260 return;
IanBenzMaxim 13:6a6225690c2e 261 }
IanBenzMaxim 13:6a6225690c2e 262
IanBenzMaxim 13:6a6225690c2e 263 printf(" [PING REPORT] Sent: %lu, Received: %lu\r\n",
IanBenzMaxim 13:6a6225690c2e 264 pPingReport->PacketsSent, pPingReport->PacketsReceived);
IanBenzMaxim 0:33d4e66780c0 265 }
IanBenzMaxim 0:33d4e66780c0 266
IanBenzMaxim 13:6a6225690c2e 267 CC3100::SPI::SPI(PinName mosi, PinName miso, PinName sclk, PinName ssel)
IanBenzMaxim 13:6a6225690c2e 268 : spi(mosi, miso, sclk), cs(ssel, 1) {}
IanBenzMaxim 13:6a6225690c2e 269
IanBenzMaxim 13:6a6225690c2e 270 void CC3100::SPI::transfer(const uint8_t * txData, size_t dataSize,
IanBenzMaxim 13:6a6225690c2e 271 uint8_t * rxData) {
IanBenzMaxim 13:6a6225690c2e 272 const int cs_delay_ms = 5;
IanBenzMaxim 0:33d4e66780c0 273
IanBenzMaxim 13:6a6225690c2e 274 cs = 0;
IanBenzMaxim 13:6a6225690c2e 275 wait_ms(cs_delay_ms);
IanBenzMaxim 16:a004191a79ab 276 for (size_t i = 0; i < dataSize; ++i) {
IanBenzMaxim 16:a004191a79ab 277 if (rxData) {
IanBenzMaxim 16:a004191a79ab 278 rxData[i] = spi.write(txData[i]);
IanBenzMaxim 16:a004191a79ab 279 } else {
IanBenzMaxim 13:6a6225690c2e 280 spi.write(txData[i]);
IanBenzMaxim 16:a004191a79ab 281 }
IanBenzMaxim 13:6a6225690c2e 282 }
IanBenzMaxim 13:6a6225690c2e 283 wait_ms(cs_delay_ms);
IanBenzMaxim 13:6a6225690c2e 284 cs = 1;
IanBenzMaxim 0:33d4e66780c0 285 }
IanBenzMaxim 0:33d4e66780c0 286
IanBenzMaxim 13:6a6225690c2e 287 CC3100::CC3100()
IanBenzMaxim 17:5926077e5345 288 : spi(MBED_CONF_APP_CC3100_MOSI_PIN, MBED_CONF_APP_CC3100_MISO_PIN,
IanBenzMaxim 17:5926077e5345 289 MBED_CONF_APP_CC3100_CLK_PIN, MBED_CONF_APP_CC3100_NCS_PIN) {}
IanBenzMaxim 0:33d4e66780c0 290
IanBenzMaxim 13:6a6225690c2e 291 CC3100 & CC3100::instance() {
IanBenzMaxim 13:6a6225690c2e 292 static CC3100 instance;
IanBenzMaxim 13:6a6225690c2e 293 return instance;
IanBenzMaxim 0:33d4e66780c0 294 }
IanBenzMaxim 0:33d4e66780c0 295
IanBenzMaxim 13:6a6225690c2e 296 int CC3100::start() {
IanBenzMaxim 13:6a6225690c2e 297 // Adapter should be stopped.
IanBenzMaxim 16:a004191a79ab 298 if (currentState != Stopped) {
IanBenzMaxim 13:6a6225690c2e 299 return invalidState;
IanBenzMaxim 16:a004191a79ab 300 }
IanBenzMaxim 0:33d4e66780c0 301
IanBenzMaxim 16:a004191a79ab 302 const int result = sl_Start(&spi, NULL, NULL);
IanBenzMaxim 16:a004191a79ab 303 if (result >= 0) {
IanBenzMaxim 13:6a6225690c2e 304 currentState = Disconnected;
IanBenzMaxim 16:a004191a79ab 305 }
IanBenzMaxim 13:6a6225690c2e 306 return result;
IanBenzMaxim 0:33d4e66780c0 307 }
IanBenzMaxim 0:33d4e66780c0 308
IanBenzMaxim 13:6a6225690c2e 309 CC3100::State CC3100::state() const { return currentState; }
IanBenzMaxim 13:6a6225690c2e 310
IanBenzMaxim 13:6a6225690c2e 311 int CC3100::stop() {
IanBenzMaxim 13:6a6225690c2e 312 // Adapter should not be stopped.
IanBenzMaxim 16:a004191a79ab 313 if (currentState == Stopped) {
IanBenzMaxim 13:6a6225690c2e 314 return invalidState;
IanBenzMaxim 16:a004191a79ab 315 }
IanBenzMaxim 13:6a6225690c2e 316
IanBenzMaxim 16:a004191a79ab 317 const int result = sl_Stop(0xFF);
IanBenzMaxim 16:a004191a79ab 318 if (result >= 0) {
IanBenzMaxim 13:6a6225690c2e 319 currentState = Stopped;
IanBenzMaxim 16:a004191a79ab 320 }
IanBenzMaxim 13:6a6225690c2e 321 return result;
IanBenzMaxim 0:33d4e66780c0 322 }
IanBenzMaxim 0:33d4e66780c0 323
IanBenzMaxim 13:6a6225690c2e 324 void CC3100::update() { sl_Task(); }
IanBenzMaxim 0:33d4e66780c0 325
IanBenzMaxim 13:6a6225690c2e 326 int CC3100::setDateTime(const std::tm & dateTime) {
IanBenzMaxim 16:a004191a79ab 327 const SlDateTime_t slDateTime = {
IanBenzMaxim 13:6a6225690c2e 328 static_cast<_u32>(dateTime.tm_sec), // sl_tm_sec
IanBenzMaxim 13:6a6225690c2e 329 static_cast<_u32>(dateTime.tm_min), // sl_tm_min
IanBenzMaxim 13:6a6225690c2e 330 static_cast<_u32>(dateTime.tm_hour), // sl_tm_hour
IanBenzMaxim 13:6a6225690c2e 331 static_cast<_u32>(dateTime.tm_mday), // sl_tm_day
IanBenzMaxim 13:6a6225690c2e 332 static_cast<_u32>(dateTime.tm_mon), // sl_tm_mon
IanBenzMaxim 13:6a6225690c2e 333 static_cast<_u32>(dateTime.tm_year) // sl_tm_year
IanBenzMaxim 13:6a6225690c2e 334 };
IanBenzMaxim 13:6a6225690c2e 335 return sl_DevSet(SL_DEVICE_GENERAL_CONFIGURATION,
IanBenzMaxim 13:6a6225690c2e 336 SL_DEVICE_GENERAL_CONFIGURATION_DATE_TIME,
IanBenzMaxim 13:6a6225690c2e 337 sizeof(SlDateTime_t),
IanBenzMaxim 13:6a6225690c2e 338 reinterpret_cast<const _u8 *>(&slDateTime));
IanBenzMaxim 0:33d4e66780c0 339 }
IanBenzMaxim 0:33d4e66780c0 340
IanBenzMaxim 13:6a6225690c2e 341 int CC3100::set_credentials(const char * ssid, const char * pass,
IanBenzMaxim 13:6a6225690c2e 342 nsapi_security_t security) {
IanBenzMaxim 13:6a6225690c2e 343 this->ssid.assign(ssid);
IanBenzMaxim 13:6a6225690c2e 344 this->pass.assign(pass);
IanBenzMaxim 13:6a6225690c2e 345 this->security = security;
IanBenzMaxim 13:6a6225690c2e 346 return 0;
IanBenzMaxim 0:33d4e66780c0 347 }
IanBenzMaxim 0:33d4e66780c0 348
IanBenzMaxim 13:6a6225690c2e 349 int CC3100::connect(const char * ssid, const char * pass,
IanBenzMaxim 13:6a6225690c2e 350 nsapi_security_t security, uint8_t channel) {
IanBenzMaxim 13:6a6225690c2e 351 // Adapter should be disconnected.
IanBenzMaxim 16:a004191a79ab 352 if (currentState != Disconnected) {
IanBenzMaxim 13:6a6225690c2e 353 return invalidState;
IanBenzMaxim 16:a004191a79ab 354 }
IanBenzMaxim 13:6a6225690c2e 355
IanBenzMaxim 13:6a6225690c2e 356 SlSecParams_t secParams = {
IanBenzMaxim 13:6a6225690c2e 357 SL_SEC_TYPE_OPEN, // Type
IanBenzMaxim 13:6a6225690c2e 358 const_cast<_i8 *>(reinterpret_cast<const _i8 *>(pass)), // Key
IanBenzMaxim 13:6a6225690c2e 359 static_cast<_u8>(strlen(pass)), // KeyLen
IanBenzMaxim 13:6a6225690c2e 360 };
IanBenzMaxim 13:6a6225690c2e 361 switch (security) {
IanBenzMaxim 13:6a6225690c2e 362 case NSAPI_SECURITY_WPA2:
IanBenzMaxim 13:6a6225690c2e 363 case NSAPI_SECURITY_WPA:
IanBenzMaxim 13:6a6225690c2e 364 case NSAPI_SECURITY_WPA_WPA2:
IanBenzMaxim 13:6a6225690c2e 365 secParams.Type = SL_SEC_TYPE_WPA_WPA2;
IanBenzMaxim 13:6a6225690c2e 366 break;
IanBenzMaxim 13:6a6225690c2e 367
IanBenzMaxim 13:6a6225690c2e 368 case NSAPI_SECURITY_WEP:
IanBenzMaxim 13:6a6225690c2e 369 secParams.Type = SL_SEC_TYPE_WEP;
IanBenzMaxim 13:6a6225690c2e 370 break;
IanBenzMaxim 13:6a6225690c2e 371
IanBenzMaxim 13:6a6225690c2e 372 case NSAPI_SECURITY_NONE:
IanBenzMaxim 13:6a6225690c2e 373 case NSAPI_SECURITY_UNKNOWN:
IanBenzMaxim 13:6a6225690c2e 374 secParams.Type = SL_SEC_TYPE_OPEN;
IanBenzMaxim 13:6a6225690c2e 375 break;
IanBenzMaxim 16:a004191a79ab 376
IanBenzMaxim 16:a004191a79ab 377 default:
IanBenzMaxim 16:a004191a79ab 378 return invalidState;
IanBenzMaxim 13:6a6225690c2e 379 }
IanBenzMaxim 13:6a6225690c2e 380 int result = sl_WlanConnect(reinterpret_cast<const _i8 *>(ssid), strlen(ssid),
IanBenzMaxim 13:6a6225690c2e 381 NULL, &secParams, NULL);
IanBenzMaxim 13:6a6225690c2e 382 if (result == SL_RET_CODE_OK) {
IanBenzMaxim 13:6a6225690c2e 383 // Wait for completion.
IanBenzMaxim 13:6a6225690c2e 384 int attempts = 1000;
IanBenzMaxim 13:6a6225690c2e 385 do {
IanBenzMaxim 13:6a6225690c2e 386 wait_ms(10);
IanBenzMaxim 13:6a6225690c2e 387 update();
IanBenzMaxim 13:6a6225690c2e 388 } while ((currentState != Connected) && (--attempts > 0));
IanBenzMaxim 16:a004191a79ab 389 if (attempts == 0) {
IanBenzMaxim 13:6a6225690c2e 390 result = SL_RET_CODE_ABORT;
IanBenzMaxim 16:a004191a79ab 391 }
IanBenzMaxim 13:6a6225690c2e 392 }
IanBenzMaxim 13:6a6225690c2e 393 return result;
IanBenzMaxim 0:33d4e66780c0 394 }
IanBenzMaxim 0:33d4e66780c0 395
IanBenzMaxim 13:6a6225690c2e 396 int CC3100::connect(const char * ssid, const char * username,
IanBenzMaxim 13:6a6225690c2e 397 const char * password) {
IanBenzMaxim 13:6a6225690c2e 398 // Adapter should be disconnected.
IanBenzMaxim 16:a004191a79ab 399 if (currentState != Disconnected) {
IanBenzMaxim 13:6a6225690c2e 400 return invalidState;
IanBenzMaxim 16:a004191a79ab 401 }
IanBenzMaxim 13:6a6225690c2e 402
IanBenzMaxim 13:6a6225690c2e 403 uint8_t values = 0;
IanBenzMaxim 13:6a6225690c2e 404 sl_WlanSet(SL_WLAN_CFG_GENERAL_PARAM_ID, 19, 1, &values);
IanBenzMaxim 13:6a6225690c2e 405
IanBenzMaxim 13:6a6225690c2e 406 SlSecParams_t secParams = {
IanBenzMaxim 13:6a6225690c2e 407 SL_SEC_TYPE_WPA_ENT, // Type
IanBenzMaxim 13:6a6225690c2e 408 const_cast<_i8 *>(reinterpret_cast<const _i8 *>(password)), // Key
IanBenzMaxim 13:6a6225690c2e 409 static_cast<_u8>(strlen(password)) // KeyLen
IanBenzMaxim 13:6a6225690c2e 410 };
IanBenzMaxim 13:6a6225690c2e 411 SlSecParamsExt_t secParamsExt = {
IanBenzMaxim 13:6a6225690c2e 412 const_cast<_i8 *>(reinterpret_cast<const _i8 *>(username)), // User
IanBenzMaxim 13:6a6225690c2e 413 static_cast<_u8>(strlen(username)), // UserLen
IanBenzMaxim 13:6a6225690c2e 414 NULL, // AnonUser
IanBenzMaxim 13:6a6225690c2e 415 0, // AnonUserLen
IanBenzMaxim 13:6a6225690c2e 416 0, // CertIndex
IanBenzMaxim 13:6a6225690c2e 417 SL_ENT_EAP_METHOD_PEAP0_MSCHAPv2 // EapMethod
IanBenzMaxim 13:6a6225690c2e 418 };
IanBenzMaxim 13:6a6225690c2e 419 int result = sl_WlanConnect(reinterpret_cast<const _i8 *>(ssid), strlen(ssid),
IanBenzMaxim 13:6a6225690c2e 420 NULL, &secParams, &secParamsExt);
IanBenzMaxim 13:6a6225690c2e 421 if (result == SL_RET_CODE_OK) {
IanBenzMaxim 13:6a6225690c2e 422 // Wait for completion.
IanBenzMaxim 13:6a6225690c2e 423 int attempts = 1000;
IanBenzMaxim 13:6a6225690c2e 424 do {
IanBenzMaxim 13:6a6225690c2e 425 wait_ms(10);
IanBenzMaxim 13:6a6225690c2e 426 update();
IanBenzMaxim 13:6a6225690c2e 427 } while ((currentState != Connected) && (--attempts > 0));
IanBenzMaxim 16:a004191a79ab 428 if (attempts == 0) {
IanBenzMaxim 13:6a6225690c2e 429 result = SL_RET_CODE_ABORT;
IanBenzMaxim 16:a004191a79ab 430 }
IanBenzMaxim 13:6a6225690c2e 431 }
IanBenzMaxim 13:6a6225690c2e 432 return result;
IanBenzMaxim 0:33d4e66780c0 433 }
IanBenzMaxim 0:33d4e66780c0 434
IanBenzMaxim 13:6a6225690c2e 435 int CC3100::disconnect() {
IanBenzMaxim 13:6a6225690c2e 436 // Adapter should be connected.
IanBenzMaxim 16:a004191a79ab 437 if (currentState != Connected) {
IanBenzMaxim 13:6a6225690c2e 438 return invalidState;
IanBenzMaxim 16:a004191a79ab 439 }
IanBenzMaxim 13:6a6225690c2e 440
IanBenzMaxim 13:6a6225690c2e 441 return sl_WlanDisconnect();
IanBenzMaxim 0:33d4e66780c0 442 }
IanBenzMaxim 0:33d4e66780c0 443
IanBenzMaxim 13:6a6225690c2e 444 int CC3100::gethostbyname(const char * host, SocketAddress * address,
IanBenzMaxim 13:6a6225690c2e 445 nsapi_version_t version) {
IanBenzMaxim 13:6a6225690c2e 446 // TODO: Add IPv6 support
IanBenzMaxim 13:6a6225690c2e 447
IanBenzMaxim 13:6a6225690c2e 448 // Adapter should be connected.
IanBenzMaxim 16:a004191a79ab 449 if (currentState != Connected) {
IanBenzMaxim 13:6a6225690c2e 450 return invalidState;
IanBenzMaxim 16:a004191a79ab 451 }
IanBenzMaxim 13:6a6225690c2e 452
IanBenzMaxim 13:6a6225690c2e 453 uint32_t addressInt;
IanBenzMaxim 13:6a6225690c2e 454 int result;
IanBenzMaxim 13:6a6225690c2e 455 int attempts = 1000;
IanBenzMaxim 16:a004191a79ab 456 // Wait for DNS servers.
IanBenzMaxim 16:a004191a79ab 457 do {
IanBenzMaxim 13:6a6225690c2e 458 wait_ms(10);
IanBenzMaxim 13:6a6225690c2e 459 result = sl_NetAppDnsGetHostByName(
IanBenzMaxim 13:6a6225690c2e 460 const_cast<_i8 *>(reinterpret_cast<const _i8 *>(host)), strlen(host),
IanBenzMaxim 13:6a6225690c2e 461 reinterpret_cast<_u32 *>(&addressInt), SL_AF_INET);
IanBenzMaxim 13:6a6225690c2e 462 } while ((result == SL_NET_APP_DNS_NO_SERVER) && (--attempts > 0));
IanBenzMaxim 13:6a6225690c2e 463 if (result == SL_RET_CODE_OK) {
IanBenzMaxim 13:6a6225690c2e 464 nsapi_addr_t addressBytes = {
IanBenzMaxim 13:6a6225690c2e 465 NSAPI_IPv4, // version
IanBenzMaxim 13:6a6225690c2e 466 0, // bytes
IanBenzMaxim 13:6a6225690c2e 467 };
IanBenzMaxim 16:a004191a79ab 468 for (int i = 4; i > 0; --i) {
IanBenzMaxim 13:6a6225690c2e 469 addressBytes.bytes[i - 1] = addressInt;
IanBenzMaxim 13:6a6225690c2e 470 addressInt >>= 8;
IanBenzMaxim 0:33d4e66780c0 471 }
IanBenzMaxim 13:6a6225690c2e 472 address->set_addr(addressBytes);
IanBenzMaxim 13:6a6225690c2e 473 }
IanBenzMaxim 13:6a6225690c2e 474 return result;
IanBenzMaxim 0:33d4e66780c0 475 }
IanBenzMaxim 0:33d4e66780c0 476
IanBenzMaxim 13:6a6225690c2e 477 int CC3100::ping(const SocketAddress & address) {
IanBenzMaxim 13:6a6225690c2e 478 // Adapter should be connected.
IanBenzMaxim 16:a004191a79ab 479 if (currentState != Connected) {
IanBenzMaxim 13:6a6225690c2e 480 return invalidState;
IanBenzMaxim 16:a004191a79ab 481 }
IanBenzMaxim 13:6a6225690c2e 482
IanBenzMaxim 13:6a6225690c2e 483 SlPingStartCommand_t pingParams = {
IanBenzMaxim 13:6a6225690c2e 484 1000, // PingIntervalTime
IanBenzMaxim 13:6a6225690c2e 485 20, // PingSize
IanBenzMaxim 13:6a6225690c2e 486 3000, // PingRequestTimeout
IanBenzMaxim 13:6a6225690c2e 487 3, // TotalNumberOfAttempts
IanBenzMaxim 13:6a6225690c2e 488 0, // Flags
IanBenzMaxim 13:6a6225690c2e 489 0 // Ip
IanBenzMaxim 13:6a6225690c2e 490 };
IanBenzMaxim 16:a004191a79ab 491 for (int i = 0; i < 4; ++i) {
IanBenzMaxim 13:6a6225690c2e 492 pingParams.Ip <<= 8;
IanBenzMaxim 13:6a6225690c2e 493 pingParams.Ip |= address.get_addr().bytes[i];
IanBenzMaxim 13:6a6225690c2e 494 }
IanBenzMaxim 13:6a6225690c2e 495 SlPingReport_t pingReport;
IanBenzMaxim 13:6a6225690c2e 496 int result = sl_NetAppPingStart(
IanBenzMaxim 13:6a6225690c2e 497 (SlPingStartCommand_t *)&pingParams, SL_AF_INET,
IanBenzMaxim 13:6a6225690c2e 498 static_cast<SlPingReport_t *>(&pingReport), SimpleLinkPingReport);
IanBenzMaxim 13:6a6225690c2e 499 if (result == SL_RET_CODE_OK) {
IanBenzMaxim 13:6a6225690c2e 500 // Wait for completion.
IanBenzMaxim 13:6a6225690c2e 501 currentState = Pinging;
IanBenzMaxim 13:6a6225690c2e 502 int attempts = 1000;
IanBenzMaxim 13:6a6225690c2e 503 do {
IanBenzMaxim 13:6a6225690c2e 504 wait_ms(10);
IanBenzMaxim 13:6a6225690c2e 505 update();
IanBenzMaxim 13:6a6225690c2e 506 } while ((currentState == Pinging) && (--attempts > 0));
IanBenzMaxim 16:a004191a79ab 507 if (attempts == 0) {
IanBenzMaxim 13:6a6225690c2e 508 result = SL_RET_CODE_ABORT;
IanBenzMaxim 16:a004191a79ab 509 }
IanBenzMaxim 13:6a6225690c2e 510 }
IanBenzMaxim 13:6a6225690c2e 511 return result;
IanBenzMaxim 0:33d4e66780c0 512 }
IanBenzMaxim 0:33d4e66780c0 513
IanBenzMaxim 13:6a6225690c2e 514 int CC3100::socket_open(nsapi_socket_t * handle, nsapi_protocol_t proto) {
IanBenzMaxim 13:6a6225690c2e 515 int16_t result;
IanBenzMaxim 13:6a6225690c2e 516 switch (proto) {
IanBenzMaxim 13:6a6225690c2e 517 case NSAPI_TCP:
IanBenzMaxim 13:6a6225690c2e 518 result = sl_Socket(SL_AF_INET, SL_SOCK_STREAM, 0);
IanBenzMaxim 13:6a6225690c2e 519 break;
IanBenzMaxim 13:6a6225690c2e 520
IanBenzMaxim 13:6a6225690c2e 521 case NSAPI_UDP:
IanBenzMaxim 13:6a6225690c2e 522 result = sl_Socket(SL_AF_INET, SL_SOCK_DGRAM, 0);
IanBenzMaxim 13:6a6225690c2e 523 break;
IanBenzMaxim 13:6a6225690c2e 524
IanBenzMaxim 13:6a6225690c2e 525 /*case SL_SEC_SOCKET:
IanBenzMaxim 13:6a6225690c2e 526 result = sl_Socket(SL_AF_INET, SL_SOCK_STREAM, SL_SEC_SOCKET);
IanBenzMaxim 13:6a6225690c2e 527 break;*/
IanBenzMaxim 13:6a6225690c2e 528
IanBenzMaxim 13:6a6225690c2e 529 default:
IanBenzMaxim 13:6a6225690c2e 530 result = SL_SOC_ERROR;
IanBenzMaxim 13:6a6225690c2e 531 break;
IanBenzMaxim 13:6a6225690c2e 532 }
IanBenzMaxim 13:6a6225690c2e 533 if (result >= 0) {
IanBenzMaxim 13:6a6225690c2e 534 *handle = new int16_t(result);
IanBenzMaxim 13:6a6225690c2e 535
IanBenzMaxim 13:6a6225690c2e 536 // Set non-blocking.
IanBenzMaxim 13:6a6225690c2e 537 SlSockNonblocking_t enableOption = {
IanBenzMaxim 13:6a6225690c2e 538 1 // NonblockingEnabled
IanBenzMaxim 13:6a6225690c2e 539 };
IanBenzMaxim 13:6a6225690c2e 540 result = sl_SetSockOpt(
IanBenzMaxim 13:6a6225690c2e 541 *static_cast<int16_t *>(*handle), SL_SOL_SOCKET, SL_SO_NONBLOCKING,
IanBenzMaxim 13:6a6225690c2e 542 reinterpret_cast<_u8 *>(&enableOption), sizeof(enableOption));
IanBenzMaxim 13:6a6225690c2e 543
IanBenzMaxim 16:a004191a79ab 544 if (result < 0) {
IanBenzMaxim 13:6a6225690c2e 545 socket_close(*handle);
IanBenzMaxim 16:a004191a79ab 546 }
IanBenzMaxim 13:6a6225690c2e 547 }
IanBenzMaxim 13:6a6225690c2e 548 return result;
IanBenzMaxim 0:33d4e66780c0 549 }
IanBenzMaxim 0:33d4e66780c0 550
IanBenzMaxim 13:6a6225690c2e 551 int CC3100::socket_set_cert_path(nsapi_socket_t handle, const char * certPath) {
IanBenzMaxim 13:6a6225690c2e 552 // Set CA certificate.
IanBenzMaxim 13:6a6225690c2e 553 return sl_SetSockOpt(*static_cast<int16_t *>(handle), SL_SOL_SOCKET,
IanBenzMaxim 13:6a6225690c2e 554 SL_SO_SECURE_FILES_CA_FILE_NAME, certPath,
IanBenzMaxim 13:6a6225690c2e 555 strlen(certPath));
IanBenzMaxim 0:33d4e66780c0 556 }
IanBenzMaxim 0:33d4e66780c0 557
IanBenzMaxim 13:6a6225690c2e 558 int CC3100::socket_close(nsapi_socket_t handle) {
IanBenzMaxim 13:6a6225690c2e 559 int16_t * castedHandle = static_cast<int16_t *>(handle);
IanBenzMaxim 16:a004191a79ab 560 const int result = sl_Close(*castedHandle);
IanBenzMaxim 13:6a6225690c2e 561 delete castedHandle;
IanBenzMaxim 13:6a6225690c2e 562 return result;
IanBenzMaxim 0:33d4e66780c0 563 }
IanBenzMaxim 0:33d4e66780c0 564
IanBenzMaxim 13:6a6225690c2e 565 int CC3100::socket_bind(nsapi_socket_t handle, const SocketAddress & address) {
IanBenzMaxim 13:6a6225690c2e 566 // TODO: Add IPv6 support
IanBenzMaxim 16:a004191a79ab 567 if (address.get_addr().version != NSAPI_IPv4) {
IanBenzMaxim 13:6a6225690c2e 568 return SL_SOC_ERROR;
IanBenzMaxim 16:a004191a79ab 569 }
IanBenzMaxim 13:6a6225690c2e 570
IanBenzMaxim 13:6a6225690c2e 571 SlSockAddrIn_t localAddr = {AF_INET, // sin_family
IanBenzMaxim 13:6a6225690c2e 572 sl_Htons(address.get_port()), // sin_port
IanBenzMaxim 13:6a6225690c2e 573 { // sin_addr
IanBenzMaxim 13:6a6225690c2e 574 0 // s_addr
IanBenzMaxim 13:6a6225690c2e 575 }};
IanBenzMaxim 16:a004191a79ab 576 for (int i = 4; i > 0; --i) {
IanBenzMaxim 13:6a6225690c2e 577 localAddr.sin_addr.s_addr <<= 8;
IanBenzMaxim 13:6a6225690c2e 578 localAddr.sin_addr.s_addr |= address.get_addr().bytes[i - 1];
IanBenzMaxim 13:6a6225690c2e 579 }
IanBenzMaxim 13:6a6225690c2e 580 return sl_Bind(*static_cast<int16_t *>(handle),
IanBenzMaxim 13:6a6225690c2e 581 reinterpret_cast<SlSockAddr_t *>(&localAddr),
IanBenzMaxim 13:6a6225690c2e 582 sizeof(localAddr));
IanBenzMaxim 0:33d4e66780c0 583 }
IanBenzMaxim 0:33d4e66780c0 584
IanBenzMaxim 13:6a6225690c2e 585 int CC3100::socket_listen(nsapi_socket_t handle, int backlog) {
IanBenzMaxim 13:6a6225690c2e 586 return sl_Listen(*static_cast<int16_t *>(handle), backlog);
IanBenzMaxim 0:33d4e66780c0 587 }
IanBenzMaxim 0:33d4e66780c0 588
IanBenzMaxim 13:6a6225690c2e 589 int CC3100::socket_connect(nsapi_socket_t handle,
IanBenzMaxim 13:6a6225690c2e 590 const SocketAddress & address) {
IanBenzMaxim 13:6a6225690c2e 591 // TODO: Add IPv6 support
IanBenzMaxim 16:a004191a79ab 592 if (address.get_addr().version != NSAPI_IPv4) {
IanBenzMaxim 13:6a6225690c2e 593 return SL_SOC_ERROR;
IanBenzMaxim 16:a004191a79ab 594 }
IanBenzMaxim 13:6a6225690c2e 595
IanBenzMaxim 13:6a6225690c2e 596 SlSockAddrIn_t addr = {AF_INET, // sin_family
IanBenzMaxim 13:6a6225690c2e 597 sl_Htons(address.get_port()), // sin_port
IanBenzMaxim 13:6a6225690c2e 598 { // sin_addr
IanBenzMaxim 13:6a6225690c2e 599 0 // s_addr
IanBenzMaxim 13:6a6225690c2e 600 }};
IanBenzMaxim 16:a004191a79ab 601 for (int i = 4; i > 0; --i) {
IanBenzMaxim 13:6a6225690c2e 602 addr.sin_addr.s_addr <<= 8;
IanBenzMaxim 13:6a6225690c2e 603 addr.sin_addr.s_addr |= address.get_addr().bytes[i - 1];
IanBenzMaxim 13:6a6225690c2e 604 }
IanBenzMaxim 13:6a6225690c2e 605 int result;
IanBenzMaxim 13:6a6225690c2e 606 int attempts = 1000;
IanBenzMaxim 13:6a6225690c2e 607 do {
IanBenzMaxim 13:6a6225690c2e 608 wait_ms(10);
IanBenzMaxim 13:6a6225690c2e 609 result = sl_Connect(*static_cast<int16_t *>(handle),
IanBenzMaxim 13:6a6225690c2e 610 reinterpret_cast<SlSockAddr_t *>(&addr), sizeof(addr));
IanBenzMaxim 13:6a6225690c2e 611 } while ((result == SL_EALREADY) && (--attempts > 0));
IanBenzMaxim 16:a004191a79ab 612 if (result > 0) {
IanBenzMaxim 13:6a6225690c2e 613 result = 0;
IanBenzMaxim 16:a004191a79ab 614 }
IanBenzMaxim 13:6a6225690c2e 615 return result;
IanBenzMaxim 0:33d4e66780c0 616 }
IanBenzMaxim 0:33d4e66780c0 617
IanBenzMaxim 13:6a6225690c2e 618 int CC3100::socket_send(nsapi_socket_t handle, const void * data,
IanBenzMaxim 13:6a6225690c2e 619 unsigned size) {
IanBenzMaxim 13:6a6225690c2e 620 return sl_Send(*static_cast<int16_t *>(handle), data, size, 0);
IanBenzMaxim 0:33d4e66780c0 621 }
IanBenzMaxim 0:33d4e66780c0 622
IanBenzMaxim 13:6a6225690c2e 623 int CC3100::socket_recv(nsapi_socket_t handle, void * data, unsigned size) {
IanBenzMaxim 13:6a6225690c2e 624 int result = sl_Recv(*static_cast<int16_t *>(handle), data, size, 0);
IanBenzMaxim 16:a004191a79ab 625 if (result == SL_EAGAIN) {
IanBenzMaxim 13:6a6225690c2e 626 result = NSAPI_ERROR_WOULD_BLOCK;
IanBenzMaxim 16:a004191a79ab 627 }
IanBenzMaxim 13:6a6225690c2e 628 return result;
IanBenzMaxim 0:33d4e66780c0 629 }