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:
Wed Apr 06 01:19:36 2016 +0000
Revision:
0:10b4212318d4
Child:
1:7099d4432b41
Example program that shows how to use the secure (TLS) SharkMQ library included in SharkSSL-Lite

Who changed what in which revision?

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