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:31:11 2016 +0000
Revision:
2:fd1c5fac2380
Parent:
1:7099d4432b41
Child:
3:1bd18e82d943
Improving readme file

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 0:10b4212318d4 71 static void blinkAll(int fast)
wini 0:10b4212318d4 72 {
wini 0:10b4212318d4 73 int i;
wini 1:7099d4432b41 74 for(i = 0 ; i < LEDSLEN ; i++) setLed(ledInfo[i].id, FALSE);
wini 1:7099d4432b41 75 for(i = 0 ; i < LEDSLEN ; i++)
wini 0:10b4212318d4 76 {
wini 1:7099d4432b41 77 setLed(ledInfo[i].id, TRUE);
wini 0:10b4212318d4 78 wait_ms(fast ? 120: 400);
wini 0:10b4212318d4 79 }
wini 1:7099d4432b41 80 for(i = 0 ; i < LEDSLEN ; i++)
wini 0:10b4212318d4 81 {
wini 1:7099d4432b41 82 setLed(ledInfo[i].id, FALSE);
wini 0:10b4212318d4 83 wait_ms(fast ? 120: 400);
wini 0:10b4212318d4 84 }
wini 0:10b4212318d4 85 }
wini 0:10b4212318d4 86
wini 0:10b4212318d4 87
wini 0:10b4212318d4 88 static void blink(int led)
wini 0:10b4212318d4 89 {
wini 0:10b4212318d4 90 int i;
wini 0:10b4212318d4 91 for(i = 0 ; i < 30; i++)
wini 0:10b4212318d4 92 {
wini 0:10b4212318d4 93 setLed(led, 1);
wini 0:10b4212318d4 94 wait_ms(120);
wini 0:10b4212318d4 95 setLed(led, 0);
wini 0:10b4212318d4 96 wait_ms(120);
wini 0:10b4212318d4 97 }
wini 0:10b4212318d4 98 }
wini 0:10b4212318d4 99
wini 0:10b4212318d4 100 /* Command sent by UI client to turn LED with ID on or off. This
wini 0:10b4212318d4 101 function must set the LED to on if 'on' is TRUE and off if 'on' is FALSE.
wini 0:10b4212318d4 102 */
wini 0:10b4212318d4 103 extern "C" int setLed(int ledId, int on)
wini 0:10b4212318d4 104 {
wini 1:7099d4432b41 105 if(ledId >= 1 && ledId <= LEDSLEN)
wini 0:10b4212318d4 106 {
wini 1:7099d4432b41 107 leds[ledId-1] = on;
wini 1:7099d4432b41 108 on = on ? 0 : 1; /* Invert */
wini 1:7099d4432b41 109 switch(ledId)
wini 1:7099d4432b41 110 {
wini 1:7099d4432b41 111 case 1: led1 = on; break;
wini 1:7099d4432b41 112 case 2: led2 = on; break;
wini 1:7099d4432b41 113 case 3: led3 = on; break;
wini 1:7099d4432b41 114 case 4: led4 = on; break;
wini 1:7099d4432b41 115 }
wini 1:7099d4432b41 116 return 0;
wini 0:10b4212318d4 117 }
wini 1:7099d4432b41 118 return -1;
wini 0:10b4212318d4 119 }
wini 0:10b4212318d4 120
wini 0:10b4212318d4 121
wini 0:10b4212318d4 122 /*
wini 0:10b4212318d4 123 An optional function that enables LEDs to be set directly by the
wini 0:10b4212318d4 124 device. This function is typically used by devices that include one
wini 0:10b4212318d4 125 or more buttons. A button click may for example turn on a specific
wini 0:10b4212318d4 126 LED. The function is called at intervals (polled) by the LED device
wini 0:10b4212318d4 127 code. The function may for example detect a button click and return
wini 0:10b4212318d4 128 the information to the caller. Arguments 'ledId' and 'on' are out
wini 0:10b4212318d4 129 arguments, where 'ledId' is set to the LED ID and 'on' is set to
wini 0:10b4212318d4 130 TRUE for on and FALSE for off. The function must return TRUE (a non
wini 0:10b4212318d4 131 zero value) if the LED is to be set on/off and zero on no
wini 0:10b4212318d4 132 change. Create an empty function returning zero if you do not plan
wini 0:10b4212318d4 133 on implementing this feature.
wini 0:10b4212318d4 134 */
wini 0:10b4212318d4 135 extern "C" int setLedFromDevice(int* ledId, int* on)
wini 0:10b4212318d4 136 {
wini 0:10b4212318d4 137 return FALSE;
wini 0:10b4212318d4 138 }
wini 0:10b4212318d4 139
wini 0:10b4212318d4 140 extern "C" void setProgramStatus(ProgramStatus s)
wini 0:10b4212318d4 141 {
wini 1:7099d4432b41 142 int i;
wini 1:7099d4432b41 143 for(i = 0 ; i < LEDSLEN ; i++) setLed(ledInfo[i].id, FALSE);
wini 0:10b4212318d4 144 switch(s)
wini 0:10b4212318d4 145 {
wini 0:10b4212318d4 146 case ProgramStatus_Restarting:
wini 0:10b4212318d4 147 blinkAll(FALSE);
wini 0:10b4212318d4 148 case ProgramStatus_Starting:
wini 0:10b4212318d4 149 blinkAll(TRUE);
wini 0:10b4212318d4 150 break;
wini 0:10b4212318d4 151
wini 0:10b4212318d4 152 case ProgramStatus_Connecting:
wini 1:7099d4432b41 153 setLed(ledInfo[1].id, TRUE);
wini 0:10b4212318d4 154 break;
wini 0:10b4212318d4 155
wini 0:10b4212318d4 156 case ProgramStatus_SslHandshake:
wini 1:7099d4432b41 157 setLed(ledInfo[2].id, TRUE);
wini 0:10b4212318d4 158 break;
wini 0:10b4212318d4 159
wini 0:10b4212318d4 160 case ProgramStatus_DeviceReady:
wini 1:7099d4432b41 161 for(i = 0 ; i < LEDSLEN ; i++) setLed(ledInfo[i].id, TRUE);
wini 0:10b4212318d4 162 wait(1);
wini 1:7099d4432b41 163 for(i = 0 ; i < LEDSLEN ; i++) setLed(ledInfo[i].id, FALSE);
wini 0:10b4212318d4 164 break;
wini 0:10b4212318d4 165
wini 0:10b4212318d4 166 case ProgramStatus_CloseCommandReceived:
wini 1:7099d4432b41 167 blink(ledInfo[3].id);
wini 0:10b4212318d4 168 break;
wini 0:10b4212318d4 169
wini 0:10b4212318d4 170 default:
wini 0:10b4212318d4 171 blinkAll(FALSE);
wini 0:10b4212318d4 172 switch(s)
wini 0:10b4212318d4 173 {
wini 0:10b4212318d4 174 case ProgramStatus_SocketError:
wini 0:10b4212318d4 175 case ProgramStatus_DnsError:
wini 0:10b4212318d4 176 case ProgramStatus_WebServiceNotAvailError:
wini 0:10b4212318d4 177 case ProgramStatus_InvalidCommandError:
wini 0:10b4212318d4 178 case ProgramStatus_PongResponseError:
wini 1:7099d4432b41 179 blink(ledInfo[1].id);
wini 0:10b4212318d4 180 break;
wini 0:10b4212318d4 181
wini 0:10b4212318d4 182 case ProgramStatus_ConnectionError:
wini 1:7099d4432b41 183 blink(ledInfo[2].id);
wini 0:10b4212318d4 184 break;
wini 0:10b4212318d4 185
wini 0:10b4212318d4 186 case ProgramStatus_CertificateNotTrustedError:
wini 0:10b4212318d4 187 case ProgramStatus_SslHandshakeError:
wini 1:7099d4432b41 188 blink(ledInfo[3].id);
wini 0:10b4212318d4 189 break;
wini 0:10b4212318d4 190
wini 0:10b4212318d4 191 case ProgramStatus_MemoryError:
wini 1:7099d4432b41 192 for(i = 0 ; i < LEDSLEN ; i++) blink(ledInfo[i].id);
wini 0:10b4212318d4 193 break;
wini 0:10b4212318d4 194 }
wini 0:10b4212318d4 195 }
wini 0:10b4212318d4 196 }
wini 0:10b4212318d4 197
wini 0:10b4212318d4 198
wini 0:10b4212318d4 199 static EthernetInterface eth;
wini 0:10b4212318d4 200
wini 0:10b4212318d4 201
wini 0:10b4212318d4 202 /* Required by SMQ examples.
wini 0:10b4212318d4 203 The unique ID is used when calling the SMQ constructor. The
wini 0:10b4212318d4 204 unique ID is typically set to the MAC address. See the SMQ
wini 0:10b4212318d4 205 documentation for details:
wini 0:10b4212318d4 206 https://realtimelogic.com/ba/doc/en/C/shark/structSharkMQ.html
wini 0:10b4212318d4 207 */
wini 0:10b4212318d4 208 int getUniqueId(const char** id)
wini 0:10b4212318d4 209 {
wini 0:10b4212318d4 210 *id=eth.getMACAddress();
wini 0:10b4212318d4 211 return strlen(*id);
wini 0:10b4212318d4 212 }
wini 0:10b4212318d4 213
wini 0:10b4212318d4 214 int main()
wini 0:10b4212318d4 215 {
wini 0:10b4212318d4 216 xprintf(("\n\n\nIn main\n"));
wini 0:10b4212318d4 217 eth.init(); //Use DHCP
wini 0:10b4212318d4 218 xprintf(("EthernetInterface connect\n"));
wini 0:10b4212318d4 219 blinkAll(FALSE);
wini 0:10b4212318d4 220 eth.connect();
wini 0:10b4212318d4 221 xprintf(("IP Address is %s\n", eth.getIPAddress()));
wini 0:10b4212318d4 222 mainTask(0);
wini 0:10b4212318d4 223 error("mainTask returned");
wini 0:10b4212318d4 224 }