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

main.cpp

Committer:
wini
Date:
2016-04-08
Revision:
5:6526b95442e7
Parent:
3:1bd18e82d943

File content as of revision 5:6526b95442e7:

#include "mbed.h"
#include "ledctrl.h"
#include "EthernetInterface.h"

DigitalOut  led1(LED1);
DigitalOut  led2(LED2);
DigitalOut  led3(LED3);
DigitalOut  led4(LED4);

static const LedInfo ledInfo[] = {
   {
      "LED 1",
      LedColor_yellow,
      1
   },
   {
      "LED 2",
      LedColor_red,
      2
   },
   {
      "LED 3",
      LedColor_blue,
      3
   },
   {
      "LED 4",
      LedColor_yellow,
      4
   }
};

#define LEDSLEN (sizeof(ledInfo) / sizeof(ledInfo[0]))

static int leds[LEDSLEN];

/* Returns the LED on/off state for led with ID 'ledId'.
*/
int getLedState(int ledId)
{
   if(ledId >= 1 && ledId <= LEDSLEN)
      return leds[ledId-1];
   return 0;
}

/*
  Return an array of LedInfo (struct). Each element in the array
  provides information for one LED. The 'len' argument must be set by
  function getLedInfo.  The out argument 'en' specifies the length of
  the returned array, that is, number of LEDs in the device.  Each LED
  has a name, color, and ID. The ID, which provides information about
  which LED to turn on/off, is used by control messages sent between
  device code and UI clients. The IDs for a four LED device can for
  example be 1,2,3,4.
*/
const LedInfo* getLedInfo(int* len)
{
   *len = LEDSLEN;
   return ledInfo;
}


/* Returns the name of this device. The name is presented by UI
   clients such as browsers.
 */
extern "C" const char* getDevName(void)
{
   return "mbed: Arch Pro : SharkSSL-Lite";
}

/* Blink all LEDs
*/
static void blinkAll(int fast)
{
   int i;
   for(i = 0 ; i < LEDSLEN ; i++) setLed(ledInfo[i].id, FALSE);
   for(i = 0 ; i < LEDSLEN ; i++)
   {
      setLed(ledInfo[i].id, TRUE);
      wait_ms(fast ? 120: 400);
   }
   for(i = 0 ; i < LEDSLEN ; i++)
   {
      setLed(ledInfo[i].id, FALSE);
      wait_ms(fast ? 120: 400);
   }
}

/* Blink LED with ID 'led'
*/
static void blink(int led)
{
   int i;
   for(i = 0 ; i < 30; i++)
   {
      setLed(led, 1);
      wait_ms(120);
      setLed(led, 0);
      wait_ms(120);
   }
}

/* Command sent by UI client to turn LED with ID on or off. This
   function must set the LED to on if 'on' is TRUE and off if 'on' is FALSE.
 */
extern "C" int setLed(int ledId, int on)
{
   if(ledId >= 1 && ledId <= LEDSLEN)
   {
      leds[ledId-1] = on;
      on = on ? 0 : 1; /* Invert */
      switch(ledId)
      {
         case 1: led1 = on; break;
         case 2: led2 = on; break;
         case 3: led3 = on; break;
         case 4: led4 = on; break;
      }
      return 0;
   }
   return -1;
}


/*
  An optional function that enables LEDs to be set directly by the
  device. This function is typically used by devices that include one
  or more buttons. A button click may for example turn on a specific
  LED. The function is called at intervals (polled) by the LED device
  code. The function may for example detect a button click and return
  the information to the caller. Arguments 'ledId' and 'on' are out
  arguments, where 'ledId' is set to the LED ID and 'on' is set to
  TRUE for on and FALSE for off. The function must return TRUE (a non
  zero value) if the LED is to be set on/off and zero on no
  change. Create an empty function returning zero if you do not plan
  on implementing this feature.
*/
extern "C" int setLedFromDevice(int* ledId, int* on)
{
   return FALSE;
}

extern "C" void setProgramStatus(ProgramStatus s)
{
   int i;
   for(i = 0 ; i < LEDSLEN ; i++) setLed(ledInfo[i].id, FALSE);
   switch(s)
   {
      case ProgramStatus_Restarting:
         blinkAll(FALSE);
      case ProgramStatus_Starting:
         blinkAll(TRUE);
         break;

      case ProgramStatus_Connecting:
         setLed(ledInfo[1].id, TRUE);
         break;

      case ProgramStatus_SslHandshake:
         setLed(ledInfo[2].id, TRUE);
         break;

      case ProgramStatus_DeviceReady:
         for(i = 0 ; i < LEDSLEN ; i++) setLed(ledInfo[i].id, TRUE);
         wait(1);
         for(i = 0 ; i < LEDSLEN ; i++) setLed(ledInfo[i].id, FALSE);
         break;

      case ProgramStatus_CloseCommandReceived:
         blink(ledInfo[3].id);
         break;

      default:
         blinkAll(FALSE);
         switch(s)
         {
            case ProgramStatus_SocketError:
            case ProgramStatus_DnsError:
            case ProgramStatus_WebServiceNotAvailError:
            case ProgramStatus_InvalidCommandError:
            case ProgramStatus_PongResponseError:
               blink(ledInfo[1].id);
               break;

            case ProgramStatus_ConnectionError:
               blink(ledInfo[2].id);
               break;

            case ProgramStatus_CertificateNotTrustedError:
            case ProgramStatus_SslHandshakeError:
               blink(ledInfo[3].id);
               break;

            case ProgramStatus_MemoryError:
               for(i = 0 ; i < LEDSLEN ; i++) blink(ledInfo[i].id);
               break;
         }
   }
}


static EthernetInterface eth;


/* Required by SMQ examples.
   The unique ID is used when calling the SMQ constructor. The
   unique ID is typically set to the MAC address. See the SMQ
   documentation for details:
   https://realtimelogic.com/ba/doc/en/C/shark/structSharkMQ.html
*/
int getUniqueId(const char** id)
{
    *id=eth.getMACAddress();
    return strlen(*id);
}

int main()
{
   xprintf(("\n\n\nIn main\n"));
   eth.init(); //Use DHCP
   xprintf(("EthernetInterface connect\n"));
   blinkAll(FALSE);
   eth.connect();
   xprintf(("IP Address is %s\n", eth.getIPAddress()));
   mainTask(0);
   error("mainTask returned");
}