MQTT On CC3220SF-LAUNCHXL Walkthrough

Overview

TI CC3220SF SimpleLink™ Wi-Fi® and Internet-of-Things solution The CC3220SF device is a complete platform solution including software, sample applications, tools, user and programming guides, reference designs, and the TI E2E™ support community. The device is available in a QFN package that is easy to layout.

http://www.ti.com/product/CC3220

Requirements:
References:
Versions / Date Tested:

Walkthrough

Prerequisites

It is assumed that the developer has Code Composer Studio and Simplelink CC32xx SDK installed and has successfully validated the environment. ie The developer can build a project, program the development board, and observe that the terminal serial output of the board displays according to the programed software.

Create Exosite Business Account

  1. Sign up for an account at https://exosite.io
  2. Log in to your account, and create a new product

Configure Exosite Product

We will configure the product to use the MQTT protocol, and tell the UI to support Password authentication dialogs.

  1. Open the "Settings" tab from the left menu.

  2. Select "MQTT" protocol

img1

  1. In the Provisioning box, select Password for Authentication method (Note: this is only necessary because of a limitation in the Murano UI, we won't be using device provisioning in this walk-through)

img2

  1. Leave the other settings unchanged from defaults

Add a Device

We will add a device identity "abc" and manually configure its password credentials with "abcdefABCDEF1234567890".

Important: These values must match the ClientUsername and ClientPassword respectively in the patch code.

  1. Open the "Devices" tab from the left menu

  2. Use the "New Device(s)" menu to "Add one device" img3

  3. Set the device identity to "abc", uncheck "Restrict provisioning period", then click "ADD". img4
  4. From the device listing, open the "more vert menu" (3 dots) and choose "Manually set device credentials..." img5
  5. Enter the password "abcdefABCDEF1234567890", then click "SAVE" img6

Define product resources

We will configure two string type resources "alive" and "listenup". The "listenup" resource "can be modified from the cloud".

  1. Open the "Resources" tab from the left menu img7
  2. Select "NEW RESOURCE" and specify "alive" as the resource Alias, and "string" as the resource format, then click "ADD" img8

  3. A second time, select "NEW RESOURCE" and specify "listenup" as the resource Alias, and "string" as the resource format, check "I want to be able to modify ..." then click "ADD" img9

  4. You should now have two resources configured for the product img10

Program board with Root CA Certificate

We will use UniFlash to update the board with the latest servicepack, add the root certificate authority for Exosite Product connectivity, and disable the default trusted certificate catalog.

Launch UniFlash

Note: These steps / screens are from UniFlash v4.2.2. More recent versions have updated the user interface, but the steps are still applicable.

DO NOT plug in the CC3220SF-LaunchPad yet.

Select "Wireless" filter to narrow down selection of the Device list.

img11

Choose Device

Select the CC3220SF-LAUNCHXL (serial) img12

Start Image Creator

Click "Start Image Creator" img13

Create project

From the welcome page, select "New Project". In the Start new project screen, select "CC3220SF" as Device Type and "Develop" as Device Mode, then click Create Project.

img14 img14

Configure Project

Note: In newer versions of the tool, the following screens are under the "advanced" view link.

Here, we will 1) add rootca.der to the user files, 2) select the servicepack, 3) Disable the trusted root catalog

img15

  1. To load the rootca.der onto the root file system. Click the indicated icon: img16 Browse for the rootca.der in the file selection dialog, then click "Write" from the file configuration screen. Note: The File Name specified here must match the file name given in the MQTT Client Demo source code.

img17

The file should then be displayed as below

img18

  1. Browse for the latest servicepack from the SDK folder: simplelink_cc32xx_sdk_2_40_00_05/tools/cc32xx_tools/servicepack-cc3x20

img19

  1. Unchecked "Use default Trusted Root Certificate Catalog"

img20

Connect and Burn image

Here, we will connect to the board, save the project and program the image.

  1. Click "Connect" img21
  2. Click "Save", then "Burn" icons as indicated below: img22
  3. Click "Program Image ..." as shown on the following screen: img23

When programming has completed successfully, shutdown UniFlash and launch Code Composer Studio.

Import the MQTT Demo into CCStudio

  1. Using a clean workspace in Code Composer Studio, import the project (from File menu, select Import >>> Code Composer Studio >>> CCS Projects) and browse to simplelink_cc32xx_sdk_x_xx_xx_xx/examples/rtos/CC3220SF_LAUNCHXL/demos/mqtt_client/tirtos/ccs

  2. Once imported, set the local access point parameters (SSID_NAME, SECURITY_TYPE and SECURITY_KEY) defined in network_if.h so they are configured according to your local access point. img24

Configure MQTT Demo code for Exosite connectivity

Open the file "mqtt_client_app.c". All changes will be made to this file. The changes are shown as small diff patches. Lines starting with "-" are removed. Lines starting with "+" are additions. Other lines are shown as context for where to make the change. A complete patch can be retrieved as Exosite_CC3220SF_MQTT_Demo.patch

Secure Sockets

Enable the use of secure sockets:

 //*****************************************************************************
 /* enables secured client                                                    */
-//#define SECURE_CLIENT
+#define SECURE_CLIENT
Password Authentication

Enable password authentication by the MQTT client:

 /* enables client authentication by the server                               */
-//#define CLNT_USR_PWD
+#define CLNT_USR_PWD
MQTT 3.1.1

Enable the use of MQTT protocol version 3.1.1:

 /* Operate Lib in MQTT 3.1 mode.                                             */
-#define MQTT_3_1_1               false
-#define MQTT_3_1                 true
+#define MQTT_3_1_1               true
+#define MQTT_3_1                 false
MQTT Sever Address

Set your unique Exosite Product domain as the SERVER_ADDRESS (Note: the SERVER_IP_ADDRESS will be unused and can be ignored). The server address can be copied from the Exosite product UI as shown here: img25

However, due to an inconsistency in the UI, an HTTP URL is copied, so extract the domain name only for the copied link as shown below. Replace the example m2 domain name shown with your unique domain (do not include the HTTP URL formatting):

 /* Defining Broker IP address and port Number                                */
 //#define SERVER_ADDRESS           "messagesight.demos.ibm.com"
-#define SERVER_ADDRESS           "m2m.eclipse.org"
+#define SERVER_ADDRESS           "<REPLACE_THIS_WITH_YOUR_M2_PRODUCT_DOMAIN>"
 #define SERVER_IP_ADDRESS        "192.168.178.67"
 #define PORT_NUMBER              1883
 #define SECURED_PORT_NUMBER      8883
MQTT Retain flag

Disable the MQTT Retain flag, as the Murano MQTT server retains the latest published message for all defined resources. Publishing to undefined resources can not be retained.

 /* Retain Flag. Used in publish message.                                     */
-#define RETAIN_ENABLE            1
+#define RETAIN_ENABLE            0
Define Publish Topic

Murano MQTT reserves the system "$resource" topic namespace for all defined resources. Update the MQTT topic that the SDK board's SW2 button triggers a publication for:

 /* Defining Publish Topic Values                                             */
-#define PUBLISH_TOPIC0           "/cc32xx/ButtonPressEvtSw2"
+#define PUBLISH_TOPIC0           "$resource/alive"
 #define PUBLISH_TOPIC0_DATA \
     "Push Button SW2 has been pressed on CC32xx device"
Set ballpark date and time

In order for the TLS connection to succeed, we need to place the board into the current validity period of the certificate chain. Bring the year forward to 2018. Or set all date/time fields to the current day, as you prefer.

 /* Month (MM format) in the range of 1-12                                    */
 #define MONTH                    5
 /* Year (YYYY format)                                                        */
-#define YEAR                     2017
+#define YEAR                     2018
 /* Hours in the range of 0-23                                                */
 #define HOUR                     12
Set ClientID, Username, and Password

Murano MQTT implementation requires that the MQTT ClientID and MQTT Username be the same, if provided. So we need to ensure their equality.

 /* Client ID                                                                 */
 /* If ClientId isn't set, the MAC address of the device will be copied into  */
 /* the ClientID parameter.                                                   */
-char ClientId[13] = {'\0'};
+char ClientId[13] = {'a','b','c','\0'};

 /* Client User Name and Password                                             */
-const char *ClientUsername = "username1";
-const char *ClientPassword = "pwd1";
+const char *ClientUsername = "abc";
+const char *ClientPassword = "abcdefABCDEF1234567890";
Secure Sockets parameters

Here, we will configure the TI MQTT library secure socket parameters. The file name must match the root certificate file name specified while burning the certificate to the device using UniFlash in the previous section.

Root Certificate

We will define the root certificate name as "rootca.der", reflecting the fact that the certificate must be in DER format.

 //*****************************************************************************
 #ifdef  SECURE_CLIENT

-char *Mqtt_Client_secure_files[CLIENT_NUM_SECURE_FILES] = {"ca-cert.pem"};
+char *Mqtt_Client_secure_files[CLIENT_NUM_SECURE_FILES] = {"rootca.der"};

 /*Initialization structure to be used with sl_ExtMqtt_Init API. In order to  */
Secure Socket Connection Flags

MQTTCLIENT_NETCONN_URL - Specifies that we will use a domain name instead of IP address. Required when using domain validation for a TLS connection.

MQTTCLIENT_NETCONN_SKIP_CERTIFICATE_CATALOG_VERIFICATION - In order to use the programmed "rootca.der" certificate instead.

Please note that the use of MQTTCLIENT_NETCONN_SKIP_DOMAIN_NAME_VERIFICATION is not supported as the library code also then disables the use of TLS Server Name Indication (SNI). The Exosite connectivity infrastructure requires the use of SNI.

Finally, use the SERVER_ADDRESS instead of SERVER_IP_ADDRESS.

 MQTTClient_ConnParams Mqtt_ClientCtx =
 {
-    MQTTCLIENT_NETCONN_IP4 | MQTTCLIENT_NETCONN_SEC,
-    SERVER_IP_ADDRESS,  //SERVER_ADDRESS,
+    MQTTCLIENT_NETCONN_URL | MQTTCLIENT_NETCONN_SEC | MQTTCLIENT_NETCONN_SKIP_CERTIFICATE_CATALOG_VERIFICATION,
+    SERVER_ADDRESS,
     SECURED_PORT_NUMBER, //  PORT_NUMBER
     SLNETSOCK_SEC_METHOD_SSLv3_TLSV1_2,
     SLNETSOCK_SEC_CIPHER_FULL_LIST,

Update publish QoS level

Murano MQTT supports QoS-0 and QoS-1. Update the publish call to use default QoS-0 to allow the MQTT Demo code to keep publishing additional messages.

                MQTTClient_publish(gMqttClient, (char*) publish_topic, strlen(
                                       (char*)publish_topic),
                                   (char*)publish_data,
-                                  strlen((char*) publish_data), MQTT_QOS_2 |
+                                  strlen((char*) publish_data), MQTT_QOS_0 |
                                   ((RETAIN_ENABLE) ? MQTT_PUBLISH_RETAIN : 0));
Disable unused subscription code

Finally, we will disable the use of topic Subscriptions and connection Will.

Remove local variable that becomes unused with other changes made below
 int32_t MqttClient_start()
 {
     int32_t lRetVal = -1;
-    int32_t iCount = 0;
+//    int32_t iCount = 0;

     int32_t threadArg = 100;
Disable use of MQTT Wills
     /*setting will parameters                                                */
-    MQTTClient_set(gMqttClient, MQTTClient_WILL_PARAM, &will_param,
-                   sizeof(will_param));
+//    MQTTClient_set(gMqttClient, MQTTClient_WILL_PARAM, &will_param,
+//                   sizeof(will_param));
Disable subscriptions

Note: Exosite MQTT subscriptions are configured at the product definition by defining resources that "can be modified from the cloud".

         /*Subscribe to topics when session is not stored by the server       */
-        if((gUiConnFlag == 1) && (0 == lRetVal))
-        {
-            uint8_t subIndex;
-            MQTTClient_SubscribeParams subscriptionInfo[
-                SUBSCRIPTION_TOPIC_COUNT];
-
-            for(subIndex = 0; subIndex < SUBSCRIPTION_TOPIC_COUNT; subIndex++)
-            {
-                subscriptionInfo[subIndex].topic = topic[subIndex];
-                subscriptionInfo[subIndex].qos = qos[subIndex];
-            }
-
-            if(MQTTClient_subscribe(gMqttClient, subscriptionInfo,
-                                    SUBSCRIPTION_TOPIC_COUNT) < 0)
-            {
-                UART_PRINT("\n\r Subscription Error \n\r");
-                MQTTClient_disconnect(gMqttClient);
-                gUiConnFlag = 0;
-            }
-            else
-            {
-                for(iCount = 0; iCount < SUBSCRIPTION_TOPIC_COUNT; iCount++)
-                {
-                    UART_PRINT("Client subscribed on %s\n\r,", topic[iCount]);
-                }
-            }
-        }
+//        if((gUiConnFlag == 1) && (0 == lRetVal))
+//        {
+//            uint8_t subIndex;
+//            MQTTClient_SubscribeParams subscriptionInfo[
+//                SUBSCRIPTION_TOPIC_COUNT];
+//
+//            for(subIndex = 0; subIndex < SUBSCRIPTION_TOPIC_COUNT; subIndex++)
+//            {
+//                subscriptionInfo[subIndex].topic = topic[subIndex];
+//                subscriptionInfo[subIndex].qos = qos[subIndex];
+//            }
+//
+//            if(MQTTClient_subscribe(gMqttClient, subscriptionInfo,
+//                                    SUBSCRIPTION_TOPIC_COUNT) < 0)
+//            {
+//                UART_PRINT("\n\r Subscription Error \n\r");
+//                MQTTClient_disconnect(gMqttClient);
+//                gUiConnFlag = 0;
+//            }
+//            else
+//            {
+//                for(iCount = 0; iCount < SUBSCRIPTION_TOPIC_COUNT; iCount++)
+//                {
+//                    UART_PRINT("Client subscribed on %s\n\r,", topic[iCount]);
+//                }
+//            }
+//        }
     }
Disable unsubscribe
 void Mqtt_ClientStop(uint8_t disconnect)
 {
-    uint32_t iCount;
-
-    MQTTClient_UnsubscribeParams subscriptionInfo[SUBSCRIPTION_TOPIC_COUNT];
-
-    for(iCount = 0; iCount < SUBSCRIPTION_TOPIC_COUNT; iCount++)
-    {
-        subscriptionInfo[iCount].topic = topic[iCount];
-    }
-
-    MQTTClient_unsubscribe(gMqttClient, subscriptionInfo,
-                           SUBSCRIPTION_TOPIC_COUNT);
-    for(iCount = 0; iCount < SUBSCRIPTION_TOPIC_COUNT; iCount++)
-    {
-        UART_PRINT("Unsubscribed from the topic %s\r\n", topic[iCount]);
-    }
+//    uint32_t iCount;
+//
+//    MQTTClient_UnsubscribeParams subscriptionInfo[SUBSCRIPTION_TOPIC_COUNT];
+//
+//    for(iCount = 0; iCount < SUBSCRIPTION_TOPIC_COUNT; iCount++)
+//    {
+//        subscriptionInfo[iCount].topic = topic[iCount];
+//    }
+//
+//    MQTTClient_unsubscribe(gMqttClient, subscriptionInfo,
+//                           SUBSCRIPTION_TOPIC_COUNT);
+//    for(iCount = 0; iCount < SUBSCRIPTION_TOPIC_COUNT; iCount++)
+//    {
+//        UART_PRINT("Unsubscribed from the topic %s\r\n", topic[iCount]);
+//    }
     gUiConnFlag = 0;

Run the MQTT Demo

We will connect the board to the computer, open a serial terminal, and flash the project to the board.

  1. Connect the board to the computer and open a serial terminal. Baud: 115200

  2. Open the Exosite Product Logs page: img26

  3. Flash the project to the board img27

  4. From a terminal, observe a successful connection img28

  5. From the Exosite Product Logs page, observe a successful connection img29

  6. Press the SW2 button on the board and observe the message published in the Logs img30

  7. From the Device listing page, select the "abc" device identity, and "edit" the "listenup" resource and set a message img31

  8. From the terminal, observe the device receiving the message img32

This concludes our walkthrough. If you have any questions, please don't hesitate to ask.