Example program that shows how to use the Secure (TLS) SharkMQ library included in SharkSSL-Lite

Dependencies:   EthernetInterface SharkSSL-Lite mbed-rtos mbed

Introduction

The SMQ Architecture is an Internet of Things (IoT) publish subscribe end-to-end solution that is optimized for embedded systems to provide instantaneous Device Edge Node connectivity, 1 to 1 Communications, and Ease of Transcending Firewalls. The solution is ideal for resource constrained devices that require real-time dynamic control, analytic information, and firmware updates in both LAN and WAN environments.

Architecture Component List

  • SMQ C Client (Non-secure)
  • SharkMQ Secure C Client (this mbed example)
  • SMQjs (Javascript)
  • SMQ JAVA
  • SMQ Broker

/media/uploads/wini/smq_architecture.png

SharkMQ-LED-Demo

An example of (Secure) device control via a Browser interface. It includes the LED demonstration example code, SharkMQ, and SharkSSL SSL|TLS stack for authentication and encryption.

Video Tutorials

How to setup your own secure SMQ IoT cloud server

Most IoT cloud server solutions, whether they provide ready-to-use hosted services or not, are based on a standard Virtual Private Server (VPS). Most developers probably think of Amazon or Microsoft Azure's services when considering the server side of their IoT solution. These high-end services are great if you need to scale up to millions of connected devices. However, for most small-scale operations and DIY projects, a low-cost VPS is more than adequate.

SMQ LED Demo

See Also

Committer:
wini
Date:
Fri Apr 08 15:38:20 2016 +0000
Revision:
3:1bd18e82d943
Parent:
2:fd1c5fac2380
More code comments in main.cpp

Who changed what in which revision?

UserRevisionLine numberNew contents of line
wini 0:10b4212318d4 1 #include "mbed.h"
wini 0:10b4212318d4 2 #include "ledctrl.h"
wini 0:10b4212318d4 3 #include "EthernetInterface.h"
wini 0:10b4212318d4 4
wini 0:10b4212318d4 5 DigitalOut led1(LED1);
wini 0:10b4212318d4 6 DigitalOut led2(LED2);
wini 0:10b4212318d4 7 DigitalOut led3(LED3);
wini 0:10b4212318d4 8 DigitalOut led4(LED4);
wini 0:10b4212318d4 9
wini 0:10b4212318d4 10 static const LedInfo ledInfo[] = {
wini 0:10b4212318d4 11 {
wini 0:10b4212318d4 12 "LED 1",
wini 0:10b4212318d4 13 LedColor_yellow,
wini 0:10b4212318d4 14 1
wini 0:10b4212318d4 15 },
wini 0:10b4212318d4 16 {
wini 0:10b4212318d4 17 "LED 2",
wini 0:10b4212318d4 18 LedColor_red,
wini 0:10b4212318d4 19 2
wini 0:10b4212318d4 20 },
wini 0:10b4212318d4 21 {
wini 0:10b4212318d4 22 "LED 3",
wini 0:10b4212318d4 23 LedColor_blue,
wini 0:10b4212318d4 24 3
wini 0:10b4212318d4 25 },
wini 0:10b4212318d4 26 {
wini 0:10b4212318d4 27 "LED 4",
wini 0:10b4212318d4 28 LedColor_yellow,
wini 0:10b4212318d4 29 4
wini 0:10b4212318d4 30 }
wini 0:10b4212318d4 31 };
wini 0:10b4212318d4 32
wini 1:7099d4432b41 33 #define LEDSLEN (sizeof(ledInfo) / sizeof(ledInfo[0]))
wini 1:7099d4432b41 34
wini 1:7099d4432b41 35 static int leds[LEDSLEN];
wini 0:10b4212318d4 36
wini 0:10b4212318d4 37 /* Returns the LED on/off state for led with ID 'ledId'.
wini 0:10b4212318d4 38 */
wini 0:10b4212318d4 39 int getLedState(int ledId)
wini 0:10b4212318d4 40 {
wini 1:7099d4432b41 41 if(ledId >= 1 && ledId <= LEDSLEN)
wini 1:7099d4432b41 42 return leds[ledId-1];
wini 1:7099d4432b41 43 return 0;
wini 0:10b4212318d4 44 }
wini 0:10b4212318d4 45
wini 0:10b4212318d4 46 /*
wini 0:10b4212318d4 47 Return an array of LedInfo (struct). Each element in the array
wini 0:10b4212318d4 48 provides information for one LED. The 'len' argument must be set by
wini 0:10b4212318d4 49 function getLedInfo. The out argument 'en' specifies the length of
wini 0:10b4212318d4 50 the returned array, that is, number of LEDs in the device. Each LED
wini 0:10b4212318d4 51 has a name, color, and ID. The ID, which provides information about
wini 0:10b4212318d4 52 which LED to turn on/off, is used by control messages sent between
wini 0:10b4212318d4 53 device code and UI clients. The IDs for a four LED device can for
wini 0:10b4212318d4 54 example be 1,2,3,4.
wini 0:10b4212318d4 55 */
wini 0:10b4212318d4 56 const LedInfo* getLedInfo(int* len)
wini 0:10b4212318d4 57 {
wini 1:7099d4432b41 58 *len = LEDSLEN;
wini 0:10b4212318d4 59 return ledInfo;
wini 0:10b4212318d4 60 }
wini 0:10b4212318d4 61
wini 0:10b4212318d4 62
wini 0:10b4212318d4 63 /* Returns the name of this device. The name is presented by UI
wini 0:10b4212318d4 64 clients such as browsers.
wini 0:10b4212318d4 65 */
wini 0:10b4212318d4 66 extern "C" const char* getDevName(void)
wini 0:10b4212318d4 67 {
wini 1:7099d4432b41 68 return "mbed: Arch Pro : SharkSSL-Lite";
wini 0:10b4212318d4 69 }
wini 0:10b4212318d4 70
wini 3:1bd18e82d943 71 /* Blink all LEDs
wini 3:1bd18e82d943 72 */
wini 0:10b4212318d4 73 static void blinkAll(int fast)
wini 0:10b4212318d4 74 {
wini 0:10b4212318d4 75 int i;
wini 1:7099d4432b41 76 for(i = 0 ; i < LEDSLEN ; i++) setLed(ledInfo[i].id, FALSE);
wini 1:7099d4432b41 77 for(i = 0 ; i < LEDSLEN ; i++)
wini 0:10b4212318d4 78 {
wini 1:7099d4432b41 79 setLed(ledInfo[i].id, TRUE);
wini 0:10b4212318d4 80 wait_ms(fast ? 120: 400);
wini 0:10b4212318d4 81 }
wini 1:7099d4432b41 82 for(i = 0 ; i < LEDSLEN ; i++)
wini 0:10b4212318d4 83 {
wini 1:7099d4432b41 84 setLed(ledInfo[i].id, FALSE);
wini 0:10b4212318d4 85 wait_ms(fast ? 120: 400);
wini 0:10b4212318d4 86 }
wini 0:10b4212318d4 87 }
wini 0:10b4212318d4 88
wini 3:1bd18e82d943 89 /* Blink LED with ID 'led'
wini 3:1bd18e82d943 90 */
wini 0:10b4212318d4 91 static void blink(int led)
wini 0:10b4212318d4 92 {
wini 0:10b4212318d4 93 int i;
wini 0:10b4212318d4 94 for(i = 0 ; i < 30; i++)
wini 0:10b4212318d4 95 {
wini 0:10b4212318d4 96 setLed(led, 1);
wini 0:10b4212318d4 97 wait_ms(120);
wini 0:10b4212318d4 98 setLed(led, 0);
wini 0:10b4212318d4 99 wait_ms(120);
wini 0:10b4212318d4 100 }
wini 0:10b4212318d4 101 }
wini 0:10b4212318d4 102
wini 0:10b4212318d4 103 /* Command sent by UI client to turn LED with ID on or off. This
wini 0:10b4212318d4 104 function must set the LED to on if 'on' is TRUE and off if 'on' is FALSE.
wini 0:10b4212318d4 105 */
wini 0:10b4212318d4 106 extern "C" int setLed(int ledId, int on)
wini 0:10b4212318d4 107 {
wini 1:7099d4432b41 108 if(ledId >= 1 && ledId <= LEDSLEN)
wini 0:10b4212318d4 109 {
wini 1:7099d4432b41 110 leds[ledId-1] = on;
wini 1:7099d4432b41 111 on = on ? 0 : 1; /* Invert */
wini 1:7099d4432b41 112 switch(ledId)
wini 1:7099d4432b41 113 {
wini 1:7099d4432b41 114 case 1: led1 = on; break;
wini 1:7099d4432b41 115 case 2: led2 = on; break;
wini 1:7099d4432b41 116 case 3: led3 = on; break;
wini 1:7099d4432b41 117 case 4: led4 = on; break;
wini 1:7099d4432b41 118 }
wini 1:7099d4432b41 119 return 0;
wini 0:10b4212318d4 120 }
wini 1:7099d4432b41 121 return -1;
wini 0:10b4212318d4 122 }
wini 0:10b4212318d4 123
wini 0:10b4212318d4 124
wini 0:10b4212318d4 125 /*
wini 0:10b4212318d4 126 An optional function that enables LEDs to be set directly by the
wini 0:10b4212318d4 127 device. This function is typically used by devices that include one
wini 0:10b4212318d4 128 or more buttons. A button click may for example turn on a specific
wini 0:10b4212318d4 129 LED. The function is called at intervals (polled) by the LED device
wini 0:10b4212318d4 130 code. The function may for example detect a button click and return
wini 0:10b4212318d4 131 the information to the caller. Arguments 'ledId' and 'on' are out
wini 0:10b4212318d4 132 arguments, where 'ledId' is set to the LED ID and 'on' is set to
wini 0:10b4212318d4 133 TRUE for on and FALSE for off. The function must return TRUE (a non
wini 0:10b4212318d4 134 zero value) if the LED is to be set on/off and zero on no
wini 0:10b4212318d4 135 change. Create an empty function returning zero if you do not plan
wini 0:10b4212318d4 136 on implementing this feature.
wini 0:10b4212318d4 137 */
wini 0:10b4212318d4 138 extern "C" int setLedFromDevice(int* ledId, int* on)
wini 0:10b4212318d4 139 {
wini 0:10b4212318d4 140 return FALSE;
wini 0:10b4212318d4 141 }
wini 0:10b4212318d4 142
wini 0:10b4212318d4 143 extern "C" void setProgramStatus(ProgramStatus s)
wini 0:10b4212318d4 144 {
wini 1:7099d4432b41 145 int i;
wini 1:7099d4432b41 146 for(i = 0 ; i < LEDSLEN ; i++) setLed(ledInfo[i].id, FALSE);
wini 0:10b4212318d4 147 switch(s)
wini 0:10b4212318d4 148 {
wini 0:10b4212318d4 149 case ProgramStatus_Restarting:
wini 0:10b4212318d4 150 blinkAll(FALSE);
wini 0:10b4212318d4 151 case ProgramStatus_Starting:
wini 0:10b4212318d4 152 blinkAll(TRUE);
wini 0:10b4212318d4 153 break;
wini 0:10b4212318d4 154
wini 0:10b4212318d4 155 case ProgramStatus_Connecting:
wini 1:7099d4432b41 156 setLed(ledInfo[1].id, TRUE);
wini 0:10b4212318d4 157 break;
wini 0:10b4212318d4 158
wini 0:10b4212318d4 159 case ProgramStatus_SslHandshake:
wini 1:7099d4432b41 160 setLed(ledInfo[2].id, TRUE);
wini 0:10b4212318d4 161 break;
wini 0:10b4212318d4 162
wini 0:10b4212318d4 163 case ProgramStatus_DeviceReady:
wini 1:7099d4432b41 164 for(i = 0 ; i < LEDSLEN ; i++) setLed(ledInfo[i].id, TRUE);
wini 0:10b4212318d4 165 wait(1);
wini 1:7099d4432b41 166 for(i = 0 ; i < LEDSLEN ; i++) setLed(ledInfo[i].id, FALSE);
wini 0:10b4212318d4 167 break;
wini 0:10b4212318d4 168
wini 0:10b4212318d4 169 case ProgramStatus_CloseCommandReceived:
wini 1:7099d4432b41 170 blink(ledInfo[3].id);
wini 0:10b4212318d4 171 break;
wini 0:10b4212318d4 172
wini 0:10b4212318d4 173 default:
wini 0:10b4212318d4 174 blinkAll(FALSE);
wini 0:10b4212318d4 175 switch(s)
wini 0:10b4212318d4 176 {
wini 0:10b4212318d4 177 case ProgramStatus_SocketError:
wini 0:10b4212318d4 178 case ProgramStatus_DnsError:
wini 0:10b4212318d4 179 case ProgramStatus_WebServiceNotAvailError:
wini 0:10b4212318d4 180 case ProgramStatus_InvalidCommandError:
wini 0:10b4212318d4 181 case ProgramStatus_PongResponseError:
wini 1:7099d4432b41 182 blink(ledInfo[1].id);
wini 0:10b4212318d4 183 break;
wini 0:10b4212318d4 184
wini 0:10b4212318d4 185 case ProgramStatus_ConnectionError:
wini 1:7099d4432b41 186 blink(ledInfo[2].id);
wini 0:10b4212318d4 187 break;
wini 0:10b4212318d4 188
wini 0:10b4212318d4 189 case ProgramStatus_CertificateNotTrustedError:
wini 0:10b4212318d4 190 case ProgramStatus_SslHandshakeError:
wini 1:7099d4432b41 191 blink(ledInfo[3].id);
wini 0:10b4212318d4 192 break;
wini 0:10b4212318d4 193
wini 0:10b4212318d4 194 case ProgramStatus_MemoryError:
wini 1:7099d4432b41 195 for(i = 0 ; i < LEDSLEN ; i++) blink(ledInfo[i].id);
wini 0:10b4212318d4 196 break;
wini 0:10b4212318d4 197 }
wini 0:10b4212318d4 198 }
wini 0:10b4212318d4 199 }
wini 0:10b4212318d4 200
wini 0:10b4212318d4 201
wini 0:10b4212318d4 202 static EthernetInterface eth;
wini 0:10b4212318d4 203
wini 0:10b4212318d4 204
wini 0:10b4212318d4 205 /* Required by SMQ examples.
wini 0:10b4212318d4 206 The unique ID is used when calling the SMQ constructor. The
wini 0:10b4212318d4 207 unique ID is typically set to the MAC address. See the SMQ
wini 0:10b4212318d4 208 documentation for details:
wini 0:10b4212318d4 209 https://realtimelogic.com/ba/doc/en/C/shark/structSharkMQ.html
wini 0:10b4212318d4 210 */
wini 0:10b4212318d4 211 int getUniqueId(const char** id)
wini 0:10b4212318d4 212 {
wini 0:10b4212318d4 213 *id=eth.getMACAddress();
wini 0:10b4212318d4 214 return strlen(*id);
wini 0:10b4212318d4 215 }
wini 0:10b4212318d4 216
wini 0:10b4212318d4 217 int main()
wini 0:10b4212318d4 218 {
wini 0:10b4212318d4 219 xprintf(("\n\n\nIn main\n"));
wini 0:10b4212318d4 220 eth.init(); //Use DHCP
wini 0:10b4212318d4 221 xprintf(("EthernetInterface connect\n"));
wini 0:10b4212318d4 222 blinkAll(FALSE);
wini 0:10b4212318d4 223 eth.connect();
wini 0:10b4212318d4 224 xprintf(("IP Address is %s\n", eth.getIPAddress()));
wini 0:10b4212318d4 225 mainTask(0);
wini 0:10b4212318d4 226 error("mainTask returned");
wini 0:10b4212318d4 227 }