Introduction
This workshop shows how to use the SimpleLink™ Wi-Fi® MQTT library, which enables you to connect as a MQTT Client to a cloud MQTT broker and/or create a local MQTT broker that can serve as a gateway for local MQTT clients.
This workshop will provide a brief overview of the MQTT protocol and then walk through some fundamental MQTT demos:
- MQTT Client Example
- MQTT Client-Server Example
- MQTT Client Example with secure connection
Prerequisites
Software
- Code Composer Studio v9.1 or newer
- SimpleLink Wi-Fi CC32xx Wireless MCUs support installed
- Make sure that CCS is using the latest updates: Help → Check for Updates
- CC32xx SDK v3.20.00.06 or newer OR
- SimpleLink SDK Wi-Fi Plugin v2.40.00.22 (if you are using a CC31xx BoosterPack)
- UniFlash v5.0.0 or newer
- Terminal emulator program such as TeraTerm or PuTTY
- MQTT client application on an internet-connected smartphone/computer (e.g. MyMQTT for Android, ICPDAS MQTT for iOS)
Hardware
- 2x CC32xx LaunchPads
- CC3235S LaunchPad (LAUNCHXL-CC3235S)
- CC3235SF LaunchPad (LAUNCHXL-CC3235SF)
- CC3220S LaunchPad (CC3220S-LAUNCHXL)
- CC3220SF LaunchPad (CC3220SF-LAUNCHXL)
- 2x Micro-USB cable (included with LaunchPad)
- 802.11b/g/n Wireless Access Point (AP)
Instead of using a CC32xx LaunchPad, the following hardware can also be used:
- 2x CC31xx BoosterPacks (BOOSTXL-CC3135 or CC3120-BOOST)
- 2x LaunchPads of supported host devices including any combination of the following:
- MSP432P401R LaunchPad (MSP-EXP432P401R)
- MSP432P4111 LaunchPad (MSP-MSP432P4111)
- MSP432E401Y LaunchPad (MSP-MSP432E401Y)
- CC26X2R1 LaunchPad ([LAUNCHXL-CC26X2R1](http://www.ti.com/tool/LAUNCHXL-CC26X2R
Note
The MQTT Client-Server exercise in this lab requires two LaunchPads. The MQTT Client exercise can be completed with one LaunchPad.
MQTT Overview
MQTT Protocol
MQTT (Message Queue Telemetry Transport) protocol is a light-weight machine-to-machine connectivity protocol. It is based on a publish/subscribe messaging model and is designed to be used on the top of TCP/IP protocol. Key benefits of this protocol include small code footprint and a low network bandwidth requirement. Other features include faster response time, low power requirement, and ease of scalability. All of these advantages make it an ideal candidate for a communication protocol in embedded devices intended to implement IOT (Internet of Things) applications.
A Simple MQTT infrastructure contains a broker (like a central hub) connected to multiple clients, each of which has the capability of publishing on any topic (token). The broker has the responsibility of sending the message published on any topic to all the subscribers of that topic. A typical MQTT network has many more features and configuration parameters.
SimpleLink MQTT Library
The MQTT library abstracts the underlying intricacies of a MQTT network and provides the user application with an intuitive and easy to use API to implement the MQTT protocol on the CC32xx device. Separate modules and APIs are used for the MQTT Server and the MQTT Client functionality.
The Client API includes the following:
- Create (or delete) a client instance
- Connect to an MQTT server (based on URL or IP Address)
- Subscribe (or unsubscribe) to a topic
- Publish a topic and a message
- Run the client main task loop
The Server has a similar interface excluding the Connect
command. The source for the MQTT library can be found under simplelink_cc32xx_sdk_x_xx_xx_xx\source\ti\net\mqtt
MQTT Client Demo
This application uses the MQTT Client API to communicate with an Eclipse M2M broker. Three LEDs on the Launchpad can be controlled from a remote MQTT client by publishing messages on appropriate topics. Similarly, a message can be published on pre-configured topics (defined in the code) by pressing a button on the host platform.
Task 1: Preparing the MQTT Client application
- In CCS, go to the menu Project → Import CCS Projects...
Follow the appropriate step below to import the
mqtt_client
example depending on which device you are using.- Be sure you select your desired project "flavor" (CC3235S-LAUNCHXL, MSP432P401R, TI-RTOS, Free-RTOS, CCS, GCC, etc.).
This lab will be demonstrate the CC3220 TI-RTOS CCS example:
mqtt_client_CC32xxSF_LAUNCHXL_tirtos_ccs
Browse to the SimpleLink CC32xx SDK on your local hard drive and select the mqtt_client example:
simplelink_cc32xx_sdk_x_xx_xx_xx\examples\rtos\CC3220SF_LAUNCHXL\demos\mqtt_client
Browse to the SimpleLink SDK Wi-Fi Plugin on your local hard drive and select the mqtt_client example:
simplelink_sdk_wifi_plugin_x_xx_xx_xx\examples\rtos\<supported host>\demos\mqtt_client
Set the local access point parameters (
SSID_NAME
,SECURITY_TYPE
andSECURITY_KEY
) defined innetwork_if.h
so they are configured according to your local access point.Take a look at your MQTT settings. They can be found in the macros at the beginning of
mqtt_client_app.c
. The important ones are:SERVER_ADDRESS
PORT_NUMBER
- Subscription topics:
SUBSCRIPTION_TOPIC0
SUBSCRIPTION_TOPIC1
- etc.
ClientId
(must be unique)- If
ClientId
is not specified, it is by default set to the local MAC Address inSetClientIdNamefromMacAddress()
- Publishing topics:
publish_topic
publish_data
In this example, the client subscribes to 4 topics and publishes to 1 topic.
Task 2: Setting up the MQTT Client demo
- Download the correct certificates depending on your device.
Open the UniFlash ImageCreator tool and add the entire "dummy" certificate chain as user files. You should also be sure you have flashed the latest servicepack. When you have all the files added correctly, your user file view in UniFlash ImageCreator will look as follows:
Open the UniFlash ImageCreator tool and add the
dummy-root-ca-cert
as user files . You should also be sure you have flashed the latest servicepack. When you have the files added correctly, your user file view in UniFlash ImageCreator will look as follows: Flash and reset the LaunchPad to start the application, or start a CCS Debug session to load and run the application.
Open a terminal emulation program such as TeraTerm and select the XDS110 Class Application/User UART port.
UART Configuration
Baud rate: 115200
Data: 8 bit
Parity: None
Stop: 1 bit
Flow control: NoneOn a device connected to the internet, use your installed MQTT client (see lab prerequisites) to connect to the MQTT broker used by the CC32xx: m2m.eclipse.org
- Verify that the port is 1883.
Leave all other settings as default, and Connect.
Note
Ensure that the Username and Password fields are left blank. By default, the MQTT client application does not set the Client Username and Client Password. However, this can be enabled by uncommenting the
CLNT_USR_PWD
macro inmqtt_client_app.c
.
Task 3: Running the MQTT Client application
Send a message from the Eclipse M2M client to the SimpleLink device by publishing the
/cc3200/ToggleLEDCmdL<x>
topic (thex
should be between 1 and 3). You should see the corresponding LED toggle on the MCU device.Use
/Broker/To/cc32xx
topic to send a text message that will be printed on the console.Using the MQTT client app, subscribe to the topic published by the SimpleLink client (
/cc32xx/ButtonPressEvtSw2
).Send a message from the SimpleLink device to the Eclipse client by pressing the SW2 button on the Launchpad (or the corresponding button in your setup).
Buttons on the LaunchPad
Press the button listed below for your device.
CC32xx Rev A LaunchPad: SW2
CC3220S/SF Rev B LaunchPad: SW3
MSP432P4 LaunchPad: S1
MSP432E4 LaunchPad: SW1
For more information on CC3220 LaunchPad revisions, refer to the CC3220 LaunchPad Development Kit Hardware User's Guide.
MQTT Client-Server Demo
In this example, the SimpleLink Wi-Fi device is running a MQTT server (“local broker”) which allows local MQTT clients to communicate with each other. Simultaneously, it is also running a client which is connected to a cloud broker. This operation mode is also called “bridge mode.” The interface between the on-board client and the server is such that the local clients can also communicate with the remote MQTT clients, which are connected to the same cloud broker as the on-board client.
MQTT allows remote control of an IOT device through a cloud-based broker. Every transaction through the external broker has a fee. The Client-Server demo demonstrates a solution for the local network that will eliminate the need for cloud broker access.
Within the local (home) network, the controlling device (typically a mobile phone) should connect to a local server rather than the cloud broker. The sample application demonstrates a working setup where multiple local MQTT clients can communicate with each other as well as talk to a remote client via an external broker.
For simplicity, the following abbreviations are used:
- LC: MQTT Client (Local Client)
- This can be the SimpleLink platform(s) running the MQTT Client application or a smartphone
- LS: One SimpleLink platform running MQTT Server/Bridge (Local Server)
- RC: Remote MQTT Client (mobile MQTT app connected to the Eclipse MQTT Broker)
- BR: External MQTT Broker (Eclipse MQTT Server, http://m2m.eclipse.org)
- AP: The access point with internet connection
LC1, LC2, and LS are all connected to the same AP. The server address configuration for LC(s) is the local address of LS.
Task 4: Setting up the MQTT Server/Bridge
In this task, we are setting up the local MQTT server (LS) on a CC32xx LaunchPad.
Import the correct
mqtt_client_server
example for your device. For this lab, we will be demonstrating themqtt_client_server_CC3220SF_LAUNCHXL_tirtos_ccs
example (simplelink_cc32xx_sdk_x_xx_xx_xx/examples/rtos/CC3220SF_LAUNCHXL/demos/mqtt_client_server/tirtos/ccs
).Take a look at your settings for the MQTT Server/Bridge. They can be found in the macros at the beginning of
mqtt_server_app.c
. The important ones are:SERVER_ADDRESS
ClientId
publish_topic
SUBSCRIPTION_TOPIC0
ENROLL_TOPIC
: These events received by the local MQTT server, will be distributed (published) to the cloud server
In
network_if.h
, update theSSID_NAME
,SECURITY_TYPE
, andSECURITY_KEY
to connect to your own Access Point (like a router).Recompile the MQTT Client-Server application and flash it to your LS (Local Server) device.
Task 5: Setting up the MQTT Clients
In this task, we are setting up the local MQTT clients. We will set up the second CC32xx LaunchPad as LC1 and use a mobile app for LC2.
For additional instructions on CCS debugger, see task 2 of the Wi-Fi Fundamentals lab.
We need to find the server IP address in order to set up the local client. To find the server IP address, start by running the MQTT Client-Server application on the target device with CCS debugger. This is your LS (Local Server).
Open a terminal emulation program such as TeraTerm and select the XDS110 Class Application/User UART port.
UART Configuration
Baud rate: 115200
Data: 8 bit
Parity: None
Stop: 1 bit
Flow control: NoneOnce the terminal is connected, run the Client-Server application and record the IP address. Enter this address in the
SERVER_IP_ADDRESS
definition inside themqtt_client_app.c
of themqtt_client
application.Use the rest of settings from the MQTT Client example we completed earlier (task 1).
Search for the
Mqtt_ClientCtx
structure inmqtt_client_app.c
in the Variables section. Set the flags and address to the local broker address (shown below). We need the Local Clients to be linked to the Local Server by IP address instead of the example's default URL.MQTTClient_ConnParams Mqtt_ClientCtx = { // MQTTCLIENT_NETCONN_URL, // SERVER_ADDRESS, // PORT_NUMBER, 0, 0, 0, // NULL 0, SERVER_IP_ADDRESS, PORT_NUMBER, 0, 0, 0, NULL };
mqtt_client_app.c :: Mqtt_ClientCtx
Check that the three LEDs are being configured in the board files (
Board.h
,CC3220SF_LAUNCHXL.h
andCC3220SF_LAUNCHXL.c
). If missing, add the following code:#define Board_GPIO_LED0 CC3220SF_LAUNCHXL_GPIO_LED_D7 #define Board_GPIO_LED1 CC3220SF_LAUNCHXL_GPIO_LED_D6 #define Board_GPIO_LED2 CC3220SF_LAUNCHXL_GPIO_LED_D5
Board.h
typedef enum CC3220SF_LAUNCHXL_GPIOName { CC3220SF_LAUNCHXL_GPIO_SW2 = 0, CC3220SF_LAUNCHXL_GPIO_SW3, CC3220SF_LAUNCHXL_GPIO_LED_D7, CC3220SF_LAUNCHXL_GPIO_LED_D6, CC3220SF_LAUNCHXL_GPIO_LED_D5, CC3220SF_LAUNCHXL_GPIOCOUNT } CC3220SF_LAUNCHXL_GPIOName;
CC3220SF_LAUNCHXL.h
GPIO_PinConfig gpioPinConfigs[] = { /* input pins with callbacks */ /* CC3220SF_LAUNCHXL_GPIO_SW2 */ GPIOCC32XX_GPIO_22 | GPIO_CFG_INPUT | GPIO_CFG_IN_INT_RISING, /* CC3220SF_LAUNCHXL_GPIO_SW3 */ GPIOCC32XX_GPIO_13 | GPIO_CFG_INPUT | GPIO_CFG_IN_INT_RISING, /* output pins */ /* CC3220SF_LAUNCHXL_GPIO_LED_D7 */ GPIOCC32XX_GPIO_09 | GPIO_CFG_OUT_STD | GPIO_CFG_OUT_STR_HIGH | GPIO_CFG_OUT_LOW, /* CC3220SF_LAUNCHXL_GPIO_LED_D6 */ GPIOCC32XX_GPIO_10 | GPIO_CFG_OUT_STD | GPIO_CFG_OUT_STR_HIGH | GPIO_CFG_OUT_LOW, /* CC3220SF_LAUNCHXL_GPIO_LED_D5 */ GPIOCC32XX_GPIO_11 | GPIO_CFG_OUT_STD | GPIO_CFG_OUT_STR_HIGH | GPIO_CFG_OUT_LOW, };
CC3220SF_LAUNCHXL.c
If you are using a different device (CC3235x, MSP432P401R, etc.), adapt the code as needed.
Recompile the
mqtt_client
application and program this to another LaunchPad. This is your LC1 (Local Client #1). LC1 should connect to LS.On your mobile app (LC2), connect to the same IP address you found with the MQTT server (task 5, step 3).
Task 6: Demo Local Communication (LC to LC)
This sequence demonstrates local communication, which is between two clients on a local network. LC1 -> LS -> LC2
In this demo, /cc32xx/ButtonPressEvtSw2
is the text for PUBLISH_TOPIC0
. This message is triggered by pressing the SW2 on the CC32xx LaunchPad.
Connect both local clients (LC1 and LC2) to the local server (LS).
LC2 subscribes to
PUBLISH_TOPIC0
. (Use the text:/cc32xx/ButtonPressEvtSw2
.)Press SW2 to publish
PUBLISH_TOPIC0
from LC1.Buttons on the LaunchPad
Press the button listed below for your device.
CC32xx Rev A LaunchPad: SW2
CC3220S/SF Rev B LaunchPad: SW3
MSP432P4 LaunchPad: S1
MSP432E4 LaunchPad: SW1
For more information on CC3220 LaunchPad revisions, refer to the CC3220 LaunchPad Development Kit Hardware User's Guide.
Results
- LC2 receives the event (message will be printed through the terminal).
- Note that LS did not subscribe to the PUBLISH_TOPIC0, so LS shows nothing.
- RC (Remote Client) and BR (external broker) show nothing.
Task 7: Demo Remote Control (RC to LC)
This sequence demonstrates communication between a remote client (through the cloud) and an IOT device. RC -> BR -> LS -> LC1
In this demo, /Broker/To/cc32xx
will be the text for SUBSCRIPTION_TOPIC0
. This message is triggered by entering text on RC.
Note
For rest of the lab, RC will be the same mobile app that we previously used as LC2. Instead of communicating over the local network, you can connect your mobile device to the internet via another AP or cellular network to demonstrate a remote client.
LC1 subscribes to
SUBSCRIPTION_TOPIC0
. (Use the text:/Broker/To/cc32xx
.)LS (as a client of the BR) also subscribes to the same topic. LS will forward any message it receives from BR to the local network.
Publish the same text of
SUBSCRIPTION_TOPIC0
(/Broker/To/cc32xx
) from the Remote Client (RC).
Results
- LS receives
SUBSCRIPTION_TOPIC0
(see terminal), because topic is subscribed by LS. - LS will publish the message in the local network.
- LC1 receives
SUBSCRIPTION_TOPIC0
(see terminal) as a client on the local network. - Note LC2 shows nothing because it did not subscribe to
SUBSCRIPTION_TOPIC0
.
Task 8: Add a New Publish Function to MQTT Client
All the following modifications for this task are done within mqtt_client_CC3220SF_LAUNCHXL_tirtos_ccs/mqtt_client_app.c
. We will be using this function later in the demos.
Add the function below to
mqtt_client_app.c
. This publishes the status of the three LEDs.#include "stdio.h" #define PUBLISH_TOPIC1 "/cc32xx/To/Broker" const char *publish_topic1 = { PUBLISH_TOPIC1 }; static void PublishLedStatusReport() { char pubMsg[20]; /* retreive status of LEDs */ sprintf(pubMsg, "L1=%d, L2=%d, L3=%d", GPIO_read(Board_GPIO_LED0), GPIO_read(Board_GPIO_LED1), GPIO_read(Board_GPIO_LED2)); /* send publish message */ MQTTClient_publish(gMqttClient, (char *)publish_topic1, strlen((char *)publish_topic1), pubMsg, 16, MQTT_QOS_2 | MQTT_PUBLISH_RETAIN); UART_PRINT("\n\r CC3220 Publishes the following message \n\r"); UART_PRINT("Topic: %s\n\r", publish_topic1); UART_PRINT("Data: %s\n\r", pubMsg); }
mqtt_client_app.c
Add the
PublishLedStatusReport()
function call to the publish message casePUBLISH_PUSH_BUTTON_PRESSED
inMqttClient()
as shown below.PublishLedStatusReport();
mqtt_client_app.c :: MqttClient()
Recompile the
mqtt_client
application and program this to another CC32xx. This is still your LC1 (Local Client #1).
Task 9: Demo Remote Notification (LC to RC)
This sequence demonstrates an IOT device sending a notification to a remote client (through the local server and the cloud broker). LC1 -> LS -> BR -> RC
In this demo, /cc32xx/To/Broker
will be the text for PUBLISH_TOPIC1
and ENROLLED_TOPIC
.
Subscribe RC to
PUBLISH_TOPIC1
. (Use the text:/cc32xx/To/Broker
.)Enroll LS to topic
ENROLLED_TOPIC
which has the same string asPUBLISH_TOPIC1
(/cc32xx/To/Broker
).- LS subscribes on an
ENROLLED_TOPIC
within the local network (as any other client). Whenever it will receive an enrolled message, LS will publish it to BR.
- LS subscribes on an
Press SW2 to publish
PUBLISH_TOPIC1
(/cc32xx/To/Broker
) from LC1.Buttons on the LaunchPad
Press the button listed below for your device.
CC32xx Rev A LaunchPad: SW2
CC3220S/SF Rev B LaunchPad: SW3
MSP432P4 LaunchPad: S1
MSP432E4 LaunchPad: SW1
For more information on CC3220 LaunchPad revisions, refer to the CC3220 LaunchPad Development Kit Hardware User's Guide.
Results
- LS receives
PUBLISH_TOPIC1
(prints to terminal) and passes onto BR. - RC receives
PUBLISH_TOPIC1
(prints to terminal). - LC2 shows nothing because it did not subscribe to
PUBLISH_TOPIC1
.
MQTT Secure Client Demo
These tasks will demonstrate the MQTT Client demo with a secure connection to the Eclipse broker. This will be done by using a TLS socket to communicate with the MQTT server. For more information on secure sockets, check out the Wi-Fi Secure Socket training.
Task 10: Enabling the Secured Client
Find the
SECURE_CLIENT
define in the macros section ofmqtt_client_app.c
. Uncomment this to enable the secured client.Find the
Mqtt_Client_secure_files
array inmqtt_client_app.c
, which by default has a size of 1 (as defined byCLIENT_NUM_SECURE_FILES
). Change the string in this array fromca-cert.pem
to a name of your choosing. In this example, we will name it todstcert.cer
.The final change needed to be made to
mqtt_client_app.c
is to update theMQTTClient_ConnParams
struct. To connect sucessfully to the broker, the connection parameters need to be updated. Select the code below and replace theMQTTClient_ConnParams
struct.MQTTClient_ConnParams Mqtt_ClientCtx = { MQTTCLIENT_NETCONN_URL | MQTTCLIENT_NETCONN_SEC | MQTTCLIENT_NETCONN_SKIP_CERTIFICATE_CATALOG_VERIFICATION | MQTTCLIENT_NETCONN_SKIP_DOMAIN_NAME_VERIFICATION, SERVER_ADDRESS, SECURED_PORT_NUMBER, SLNETSOCK_SEC_METHOD_SSLv3_TLSV1_2, SLNETSOCK_SEC_CIPHER_FULL_LIST, CLIENT_NUM_SECURE_FILES, Mqtt_Client_secure_files };
mqtt_client_app.c
What are the other MQTT connection parameters?
These paramaters indicate that we want a secure connection, but we are skipping certificate catalog verification and domain name verification. For information on all of the MQTT library configurations, please see the Network Services API Reference Guide available in the SDK.
To create a secure connection with the the Eclipse broker, we need to obtain the correct certificate. One way to do this is to obtain the certificate directly from the website. In this example, we will demonstrate this with Chrome as our browser.
In your browser, go to https://iot.eclipse.org
Next to the URL (in Chrome), click on the Lock symbol and then select on View Certificates to view the certificate for this website.
In the Certificate window, click on the Certfication Path tab which will display the chain of certificates for this website. We are interested in the root certificate, which in this case is issued by DST ROOT CA X3. Double-click on this certificate.
This will open up the Certificate tab for the root certificate. To download this certificate, click on Details → Copy to File....
Can't download the certificate?
If the Copy to File button is grayed out for you, run your browser as an Administrator, and then try again.
On the Certificate Export Wizard page, click Next, ensure that DER encoded binary X.509 is selected and click Next, and then save the certificate to your file system with the certificate name you picked earlier. In our example, it is
dstcert.cer
.
Now that you have obtained the root certificate, use Uniflash ImageCreator to add it to the file system.
Run tasks 2 and 3 from the MQTT Client Demo section and verify that you are able to successfully connect to the MQTT broker.
Want to test the security?
Do this task but flash the LaunchPad without the certificate we just added. It should fail to connect to the MQTT broker!
Technical support
For any questions, please search on the SimpleLink Wi-Fi E2E Forum
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License.