MQTT and TLS using Simplelink API
Answer
7/5/18 10:35 PM

Hi everyone!

I've just finished a code that uses HTTPS post request; I only modified the HTTPS get request example, now, I want to do the same but using MQTTS protocol: Is it possible to use this similar approach using the Simplelink API to accomplish it or do I need to use other API? Have anyone tried to do the same by this way?

Thanks in advanced!

0 (0 Votes)
RE: MQTT and TLS using Simplelink API
Answer
7/6/18 3:04 PM as a reply to Rolando Gonzalez.
Hello Ronaldo,

That is in general possible.

Unfortunately, the implementation for HTTPS in the HTTPS guide is already implemented from scratch by using the simplelink API. Therefore such a small modification is enough to build a POST request instead of a GET request.

For the MQTT protocol there is an additional MQTT implementation API that is based on the ServalStack. This API currently do not cover an implementation of secure MQTT requests.

As such, only a slight modification will not be enough to achieve a secure request.

The possibility that I have in mind is that you use a third party library such as MQTT paho from eclipse and add it to your SDK of the XDK and then implement a connection between simplelink TCP and MQTT paho.

For adding a static library to the XDK, I recommend taking a look at the library guide in the learning section of the XDK community.

Please let me know if that was helpful and feel free to ask if you have further questions.

Kind regards,
Franjo
0 (0 Votes)
RE: MQTT and TLS using Simplelink API
Answer
7/10/18 4:10 AM as a reply to Franjo Stjepandic.

Hi Franjo, thanks for your advice.

I've just developed a publish message with MQTT over TLS (I used a lot of examples and replies from the XDK community, thanks to everyone). I used the HTPPS GET as a base code and I proved it in a public broker page, here is the page.

I subscribed to that broker using mosquito mqtt.fx to see the messages, the download link is here. On this reply is the code I tried, as you can see, I hardcoded a lot, I just wanted to figure out if using the socket.h functions I could send MQTT messages over TLS.

I saw some people in the community that are looking for an MQTT/TLS example, well, maybe this could be a point where to start, but there are many steps to achieve before to have a complete solution, for example,  functions like connack, subscribe, and puback are needed and this example does not have it, and of course, make the code easy to put the topics, payloads, user ID and so on.

I used the MQTT documentation from this page, and some explanations from this one.

Maybe, instead of developing an API again, I'll try now the MQTT paho as you said.

If I get stuck at some point I will request your help and of all community again, thank you!

Code XDK Workbench v.3.3.1 Windows x64:

/*
* Licensee agrees that the example code provided to Licensee has been developed and released by Bosch solely as an example to be used as a potential reference for Licensee�s application development. 
* Fitness and suitability of the example code for any use within Licensee�s applications need to be verified by Licensee on its own authority by taking appropriate state of the art actions and measures (e.g. by means of quality assurance measures).
* Licensee shall be responsible for conducting the development of its applications as well as integration of parts of the example code into such applications, taking into account the state of the art of technology and any statutory regulations and provisions applicable for such applications. Compliance with the functional system requirements and testing there of (including validation of information/data security aspects and functional safety) and release shall be solely incumbent upon Licensee. 
* For the avoidance of doubt, Licensee shall be responsible and fully liable for the applications and any distribution of such applications into the market.
* 
* 
* Redistribution and use in source and binary forms, with or without 
* modification, are permitted provided that the following conditions are 
* met:
* 
*     (1) Redistributions of source code must retain the above copyright
*     notice, this list of conditions and the following disclaimer. 
* 
*     (2) Redistributions in binary form must reproduce the above copyright
*     notice, this list of conditions and the following disclaimer in
*     the documentation and/or other materials provided with the
*     distribution.  
*     
*     (3)The name of the author may not be used to
*     endorse or promote products derived from this software without
*     specific prior written permission.
* 
*  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 
*  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
*  DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
*  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
*  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
*  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
*  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
*  STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
*  IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
*  POSSIBILITY OF SUCH DAMAGE.
*/
/*----------------------------------------------------------------------------*/
/**
* @ingroup APPS_LIST
*
* @defgroup XDK_APPLICATION_TEMPLATE XDK Application Template
* @{
*
* @brief XDK Application Template
*
* @details Empty XDK Application Template without any functionality. Should be used as a template to start new projects.
*
* @file
**/
/* module includes ********************************************************** */

/* system header files */
#include <stdio.h>
#include <stdbool.h>
#include <simplelink.h> // Simple Link API

/* additional interface header files */
#include "FreeRTOS.h"
#include "timers.h"

/* own header files */
#include "MQTToverTLSprobe.h"
#include "XDKAppInfo.h"
#include "BCDS_CmdProcessor.h"
#include "BCDS_Assert.h"
#include "BCDS_ServalPalWiFi.h" //For ServalPalSetup
#include "BCDS_WlanConnect.h"   //For WlanConnection
#include "BCDS_NetworkConfig.h" //For WlanConnection
#include "PAL_initialize_ih.h"  // ???
#include "PAL_socketMonitor_ih.h" // ???

/* constant definitions ***************************************************** */

/* local variables ********************************************************** */

/* global variables ********************************************************* */
static CmdProcessor_T CommandProcessorHandle;

/* inline functions ********************************************************* */

/* local functions ********************************************************** */

/* global functions ********************************************************* */

_u8 digicert_root_crt[] = // DER binary for http://www.dioty.co, just copy this
{
	0x30, 0x82, 0x04, 0x01, 0x30, 0x82, 0x02, 0xE9, 0xA0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x09, 0x00,
	0xB9, 0x45, 0x05, 0xE8, 0x9E, 0x96, 0xA6, 0x73, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86,
	0xF7, 0x0D, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x81, 0x96, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03,
	0x55, 0x04, 0x06, 0x13, 0x02, 0x47, 0x42, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x08,
	0x0C, 0x0E, 0x47, 0x72, 0x65, 0x61, 0x74, 0x65, 0x72, 0x20, 0x4C, 0x6F, 0x6E, 0x64, 0x6F, 0x6E,
	0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0C, 0x06, 0x4C, 0x6F, 0x6E, 0x64, 0x6F,
	0x6E, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x0E, 0x53, 0x74, 0x61, 0x72,
	0x74, 0x20, 0x4C, 0x65, 0x61, 0x6E, 0x20, 0x4C, 0x74, 0x64, 0x31, 0x0E, 0x30, 0x0C, 0x06, 0x03,
	0x55, 0x04, 0x0B, 0x0C, 0x05, 0x44, 0x49, 0x6F, 0x54, 0x59, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03,
	0x55, 0x04, 0x03, 0x0C, 0x0C, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x6F, 0x74, 0x79, 0x2E, 0x63,
	0x6F, 0x31, 0x1D, 0x30, 0x1B, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x01,
	0x16, 0x0E, 0x61, 0x64, 0x6D, 0x69, 0x6E, 0x40, 0x64, 0x69, 0x6F, 0x74, 0x79, 0x2E, 0x63, 0x6F,
	0x30, 0x1E, 0x17, 0x0D, 0x31, 0x34, 0x30, 0x36, 0x32, 0x35, 0x31, 0x33, 0x34, 0x39, 0x35, 0x37,
	0x5A, 0x17, 0x0D, 0x32, 0x34, 0x30, 0x36, 0x32, 0x32, 0x31, 0x33, 0x34, 0x39, 0x35, 0x37, 0x5A,
	0x30, 0x81, 0x96, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x47, 0x42,
	0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0C, 0x0E, 0x47, 0x72, 0x65, 0x61, 0x74,
	0x65, 0x72, 0x20, 0x4C, 0x6F, 0x6E, 0x64, 0x6F, 0x6E, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55,
	0x04, 0x07, 0x0C, 0x06, 0x4C, 0x6F, 0x6E, 0x64, 0x6F, 0x6E, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03,
	0x55, 0x04, 0x0A, 0x0C, 0x0E, 0x53, 0x74, 0x61, 0x72, 0x74, 0x20, 0x4C, 0x65, 0x61, 0x6E, 0x20,
	0x4C, 0x74, 0x64, 0x31, 0x0E, 0x30, 0x0C, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x05, 0x44, 0x49,
	0x6F, 0x54, 0x59, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x0C, 0x77, 0x77,
	0x77, 0x2E, 0x64, 0x69, 0x6F, 0x74, 0x79, 0x2E, 0x63, 0x6F, 0x31, 0x1D, 0x30, 0x1B, 0x06, 0x09,
	0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x01, 0x16, 0x0E, 0x61, 0x64, 0x6D, 0x69, 0x6E,
	0x40, 0x64, 0x69, 0x6F, 0x74, 0x79, 0x2E, 0x63, 0x6F, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0D, 0x06,
	0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0F,
	0x00, 0x30, 0x82, 0x01, 0x0A, 0x02, 0x82, 0x01, 0x01, 0x00, 0xD3, 0x9B, 0xE4, 0xDC, 0x30, 0xBC,
	0x96, 0x26, 0x62, 0xA4, 0x03, 0x3F, 0x83, 0x8B, 0x80, 0xB7, 0xD9, 0x32, 0x0C, 0x5F, 0x75, 0x23,
	0x8B, 0xD8, 0xAA, 0xE5, 0x2D, 0xE1, 0xB8, 0x80, 0xAB, 0x5A, 0x26, 0xE8, 0xF3, 0x2E, 0x5B, 0x16,
	0x16, 0xEE, 0x59, 0x54, 0xBF, 0xD1, 0xD3, 0xF5, 0x1C, 0xB4, 0xD9, 0x54, 0x26, 0xB3, 0x4B, 0xD0,
	0xCB, 0x01, 0xCB, 0xD2, 0xD7, 0x92, 0xA7, 0x3F, 0xA8, 0x22, 0xD7, 0xD8, 0xC0, 0x35, 0x31, 0x2E,
	0x98, 0xB3, 0xC5, 0xC0, 0x91, 0x41, 0x46, 0xCC, 0x6B, 0x74, 0xBC, 0x7B, 0xDB, 0x20, 0x10, 0x8C,
	0x75, 0x33, 0x11, 0x2C, 0xF1, 0xFC, 0x8C, 0xAF, 0x4C, 0x4D, 0x8C, 0xB1, 0xDA, 0x5C, 0x61, 0x21,
	0x72, 0x5A, 0x68, 0x57, 0xF8, 0x59, 0x77, 0x57, 0x7A, 0xE3, 0xE5, 0x36, 0x3E, 0x50, 0x96, 0x66,
	0x7C, 0xC1, 0x0A, 0x9C, 0xFB, 0xA1, 0xAB, 0x96, 0x68, 0x4A, 0x8F, 0x1E, 0x45, 0xCC, 0x35, 0xCD,
	0x3C, 0xA1, 0x32, 0x1B, 0xD5, 0xBA, 0x9F, 0x88, 0x6D, 0x23, 0x9C, 0xA7, 0x7A, 0xDC, 0x03, 0x33,
	0x2C, 0x96, 0x5B, 0x7F, 0xAB, 0xDA, 0x31, 0x0B, 0xB0, 0x6A, 0x6C, 0x6C, 0xD9, 0x81, 0x21, 0xF6,
	0x61, 0x58, 0x34, 0x7F, 0x6D, 0xD0, 0xED, 0xC3, 0x45, 0x33, 0x36, 0x89, 0x3E, 0xE1, 0x9F, 0x85,
	0xE5, 0xAF, 0x61, 0x07, 0x68, 0x9D, 0xD6, 0x5A, 0x8B, 0x08, 0xCD, 0xE7, 0xAF, 0x06, 0x98, 0x36,
	0xA9, 0x7D, 0x9B, 0xD3, 0x75, 0x7D, 0xB5, 0x01, 0x5B, 0xFD, 0x28, 0xDD, 0x38, 0xB4, 0xA4, 0xC6,
	0xA6, 0x5B, 0x62, 0xD4, 0x0E, 0xBD, 0x77, 0xE9, 0x15, 0xCC, 0x64, 0xD7, 0x55, 0x1C, 0x90, 0x5C,
	0x0B, 0xD8, 0x1A, 0x01, 0x07, 0xBD, 0xFB, 0x6E, 0xD0, 0x10, 0x5D, 0x1A, 0xF8, 0xA0, 0x6A, 0xB1,
	0x23, 0x1A, 0xF0, 0x49, 0x76, 0xA8, 0x59, 0xB2, 0x7F, 0xD1, 0x02, 0x03, 0x01, 0x00, 0x01, 0xA3,
	0x50, 0x30, 0x4E, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x1D, 0x0E, 0x04, 0x16, 0x04, 0x14, 0x9E, 0x90,
	0x0F, 0xBB, 0x30, 0x38, 0x8C, 0xBA, 0xEF, 0xC8, 0xBE, 0xCB, 0xFB, 0xAE, 0xAE, 0x1C, 0x1D, 0xA4,
	0x39, 0x77, 0x30, 0x1F, 0x06, 0x03, 0x55, 0x1D, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x9E,
	0x90, 0x0F, 0xBB, 0x30, 0x38, 0x8C, 0xBA, 0xEF, 0xC8, 0xBE, 0xCB, 0xFB, 0xAE, 0xAE, 0x1C, 0x1D,
	0xA4, 0x39, 0x77, 0x30, 0x0C, 0x06, 0x03, 0x55, 0x1D, 0x13, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01,
	0xFF, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x05, 0x05, 0x00,
	0x03, 0x82, 0x01, 0x01, 0x00, 0x38, 0x42, 0xFF, 0x4C, 0x4C, 0xB1, 0xCF, 0x3E, 0x52, 0x61, 0x4C,
	0x3B, 0x13, 0x89, 0xAB, 0xAF, 0x27, 0xC9, 0xC2, 0x44, 0x0E, 0x52, 0xAE, 0x30, 0x02, 0x2D, 0x3D,
	0x11, 0x2F, 0x59, 0x05, 0x01, 0x58, 0x59, 0xEE, 0x0C, 0x0C, 0x91, 0x4B, 0xF5, 0x64, 0x6E, 0x84,
	0x9A, 0xED, 0x2A, 0xAE, 0x38, 0x6C, 0xC7, 0x29, 0x90, 0x34, 0xF1, 0x6B, 0x4E, 0xA2, 0x23, 0x56,
	0xD7, 0x30, 0x6D, 0x21, 0xA6, 0x12, 0x8C, 0xE5, 0xE4, 0xE2, 0x49, 0x68, 0xB5, 0xB7, 0x41, 0x20,
	0x41, 0x2A, 0xE4, 0x78, 0xB9, 0xC7, 0x4C, 0x65, 0x06, 0x90, 0xDB, 0xA2, 0x7E, 0xE8, 0x23, 0x60,
	0x93, 0x30, 0x15, 0xC4, 0xDF, 0x40, 0x17, 0x51, 0x77, 0x56, 0x4F, 0x60, 0xF5, 0xC5, 0x56, 0x46,
	0x82, 0x67, 0xEE, 0xDC, 0x32, 0xCC, 0x1E, 0xF2, 0xF1, 0x60, 0x12, 0x5D, 0x03, 0xA2, 0xB9, 0x9A,
	0xD7, 0xFC, 0x60, 0x40, 0x9E, 0x83, 0x94, 0x1B, 0x42, 0xE7, 0x3A, 0x16, 0x53, 0xF6, 0xD1, 0x38,
	0xB1, 0xDA, 0xEA, 0x31, 0xF0, 0x8A, 0xD3, 0x4A, 0xE8, 0x22, 0xDD, 0x3C, 0x84, 0x12, 0x2D, 0x69,
	0x52, 0x88, 0x5F, 0xD8, 0x51, 0x70, 0x44, 0xB8, 0xAD, 0x77, 0xD9, 0xB2, 0x9C, 0x77, 0x6E, 0xBD,
	0xEA, 0x00, 0xCA, 0x61, 0x70, 0x20, 0x78, 0x3C, 0x8C, 0x61, 0x71, 0x65, 0xAD, 0xD5, 0xC3, 0x5D,
	0x74, 0x75, 0x16, 0xE8, 0x11, 0x1E, 0x46, 0x3B, 0x88, 0x65, 0x0A, 0xDB, 0x79, 0x63, 0xC0, 0xC0,
	0xE9, 0xBE, 0xFC, 0x33, 0x0F, 0xF7, 0xE8, 0x7D, 0xF9, 0x8F, 0x8A, 0xA7, 0x44, 0x5E, 0xBB, 0x54,
	0x3D, 0xF2, 0x18, 0xA8, 0xFE, 0xC0, 0xB2, 0x33, 0xAC, 0xB8, 0xA8, 0x01, 0x3F, 0x7F, 0x6A, 0x62,
	0x32, 0x99, 0x4D, 0x4A, 0x0C, 0x8F, 0x34, 0xC0, 0xDC, 0xA4, 0xEC, 0x8E, 0x6C, 0xC3, 0xAF, 0x2F,
	0xD8, 0x11, 0x4B, 0x01, 0xC6
};

_u32 digicert_root_crt_len = sizeof(digicert_root_crt); // Lenght of HEX certificate needed in MQTT with TLS .der 1029

/**
 * @brief This will initialize the ServalPAL module and its necessary resources.
 *
 * @return Status of initialization
 */
static Retcode_T ServalPalSetup(void)
{
    Retcode_T returnValue = RETCODE_OK;
    returnValue = CmdProcessor_Initialize(&CommandProcessorHandle, "Serval PAL", TASK_PRIORITY_SERVALPAL_CMD_PROC, TASK_STACK_SIZE_SERVALPAL_CMD_PROC, TASK_QUEUE_LEN_SERVALPAL_CMD_PROC);
    /* serval pal common init */
    if (RETCODE_OK == returnValue)
    {
        returnValue = ServalPal_Initialize(&CommandProcessorHandle);
    }
    if (RETCODE_OK == returnValue)
    {
        returnValue = ServalPalWiFi_Init();
    }
    if (RETCODE_OK == returnValue)
    {
        ServalPalWiFi_StateChangeInfo_T stateChangeInfo = { SERVALPALWIFI_OPEN, INT16_C(0) };
        returnValue = ServalPalWiFi_NotifyWiFiEvent(SERVALPALWIFI_STATE_CHANGE, &stateChangeInfo);
    }
    return returnValue;
}

/**
 * @brief Connects to the wireless network configured in httpRequest.h
 *
 *   @warning
 *      If the WLAN connection fails or we don't acquire an IP address, we will be stuck in this function forever.
 *      Check whether the callback "SimpleLinkWlanEventHandler" or "SimpleLinkNetAppEventHandler" hits once the
 *      sl_WlanConnect() API called, if not check for proper GPIO pin interrupt configuration or for any other issue.
 *
 * @retval     RETCODE_OK         We connected to the WLAN successfully.
 *
 */
static Retcode_T connectToWLAN(void)
{
    Retcode_T retcode;

    retcode = WlanConnect_Init();
    if (RETCODE_OK != retcode)
    {
        return retcode;
    }

    /* The order of calls is important here. WlanConnect_init initializes the CC3100 and prepares
     * its future use. Calls to NetworkConfig_ fail if WlanConnect_Init was not called beforehand.
     */
    retcode = NetworkConfig_SetIpDhcp(NULL);
    if (RETCODE_OK != retcode)
    {
        return retcode;
    }

    printf("Connecting to %s \r\n ", WLAN_SSID);
    /* Passing NULL as onConnection callback (last parameter) makes this a blocking call, i.e. the
     * WlanConnect_WPA function will return only once a connection to the WLAN has been established,
     * or if something went wrong while trying to do so. If you wanted non-blocking behavior, pass
     * a callback instead of NULL. */
    retcode = WlanConnect_WPA((WlanConnect_SSID_T) WLAN_SSID, (WlanConnect_PassPhrase_T) WLAN_PSK, NULL);
    if (RETCODE_OK != retcode)
    {
        return retcode;
    }

    NetworkConfig_IpSettings_T currentIpSettings;
    retcode = NetworkConfig_GetIpSettings(&currentIpSettings);
    if (RETCODE_OK != retcode)
    {
        return retcode;
    }
    else
    {
        uint32_t ipAddress = Basics_htonl(currentIpSettings.ipV4);

        char humanReadbleIpAddress[SERVAL_IP_ADDR_LEN] = { 0 };
        int conversionStatus = Ip_convertAddrToString(&ipAddress, humanReadbleIpAddress);
        if (conversionStatus < 0)
        {
            printf("Couldn't convert the IP address to string format \r\n");
        }
        else
        {
            printf("Connected to WPA network successfully \r\n");
            printf(" Ip address of the device %s \r\n", humanReadbleIpAddress);
        }
    }

    return retcode;
}

void flashCertificate(char *fileName, _u8* data, _u32 length)
{
	// For the purpose of readability this code has no error handling.
	// The simplelink API provides return codes of the type _i32 that can be
	// checked for the value SL_RET_CODE_OK
	// The datetime is required for certificate validation:

	SlDateTime_t dateTime;
	dateTime.sl_tm_day = (_u32)9;
	dateTime.sl_tm_mon = (_u32)6;
	dateTime.sl_tm_year = (_u32)2018;
	dateTime.sl_tm_hour = (_u32)0;
	dateTime.sl_tm_min = (_u32)0;
	dateTime.sl_tm_sec = (_u32)0;

	sl_DevSet
	(
		SL_DEVICE_GENERAL_CONFIGURATION,
		SL_DEVICE_GENERAL_CONFIGURATION_DATE_TIME,
		sizeof(SlDateTime_t),
		(_u8 *)(&dateTime)
	);

	// If a file with the same name already exists, call this first:
	//sl_FsDel((_u8*) CA_FILE_NAME, 0);

    // The file handle should not be 0 after a file was successfully created:
	_i32 fileHandle = 0;
    sl_FsOpen
	(
    	(_u8*) fileName,
        FS_MODE_OPEN_CREATE
		(
        	2*1024, _FS_FILE_PUBLIC_WRITE | _FS_FILE_PUBLIC_READ
        ),
        NULL,
        &fileHandle
    );

    // If the file is longer than 1024 bytes, you need to loop the writing.
    // "length" contains the length of the certificate
    // "writtenLength" contains the amount of actually written bytes.
    _u32 remainingLength = length;
    while(remainingLength > 0)
    {
         remainingLength -= (_u32) sl_FsWrite
        (
           fileHandle,
           length - remainingLength,
           data+(length - remainingLength),
           remainingLength > 1024 ? 1024 : remainingLength // equal to max(remainingLength, 1024)
         );
    }

    sl_FsClose(fileHandle, NULL, NULL, 0);
}


//// Sent GET request in short.
void publish(_i16 socketHandle, char * host, char * path)
{
	(void) path;
	(void) host;
	_i16 response;

	char messageConnect[] =
	{
		0x10, // Byte 01 -> 0001 0000 CONNECT: Client request to connect to Server
		0x37, // Byte 02 -> 19 Remaining length, counting rest of buffer from here // All this is the fixed header
		0x00, // Byte 03 -> (MSB) Protocol name length
		0x04, // Byte 04 -> (LSB) Protocol name length 4 UTF-8 characters in this case
		0x4d, // Byte 05 -> UTF-8 Code for 'M'
		0x51, // Byte 06 -> UTF-8 Code for 'Q'
		0x54, // Byte 07 -> UTF-8 Code for 'T'
		0x54, // Byte 08 -> UTF-8 Code for 'T'
		0x04, // Byte 09 -> Protocol version number = 4
		0xc2, // Byte 10 -> b1100 0010 [Connect flags] User_name/Password/retain/QoS(2-bits)/Will_flag/Clean_session/Reserved: 0
		0x00, // Byte 11 -> (MSB) Keep alive
		0x3c, // Byte 12 -> (LSB) Keep alive 60 seconds // All this part is the variable header
		0x00, // Byte 13 -> (MSB) Client ID length
		0x07, // Byte 14 -> (LSB) Client ID length
		0x58, // Byte 15 -> UTF-8 Code for 'X'
		0x44, // Byte 16 -> UTF-8 Code for 'D'
		0x4b, // Byte 17 -> UTF-8 Code for 'K'
		0x30, // Byte 18 -> UTF-8 Code for '0'
		0x5a, // Byte 19 -> UTF-8 Code for 'Z'
		0x75, // Byte 20 -> UTF-8 Code for 'u'
		0x4e, // Byte 21 -> UTF-8 Code for 'N'
		0x00, // Byte 22 -> (MSB) User name length
		0x18, // Byte 23 -> (LSB) User name length
		0x72, // Byte 24 -> UTF-8 Code for 'r'
		0x67, // Byte 25 -> UTF-8 Code for 'g'
		0x6f, // Byte 26 -> UTF-8 Code for 'o'
		0x6e, // Byte 27 -> UTF-8 Code for 'n'
		0x7a, // Byte 28 -> UTF-8 Code for 'z'
		0x61, // Byte 29 -> UTF-8 Code for 'a'
		0x6c, // Byte 30 -> UTF-8 Code for 'l'
		0x65, // Byte 31 -> UTF-8 Code for 'e'
		0x7a, // Byte 32 -> UTF-8 Code for 'z'
		0x63, // Byte 33 -> UTF-8 Code for 'c'
		0x31, // Byte 34 -> UTF-8 Code for '1'
		0x38, // Byte 35 -> UTF-8 Code for '8'
		0x31, // Byte 36 -> UTF-8 Code for '1'
		0x31, // Byte 37 -> UTF-8 Code for '1'
		0x40, // Byte 38 -> UTF-8 Code for '@'
		0x67, // Byte 39 -> UTF-8 Code for 'g'
		0x6d, // Byte 40 -> UTF-8 Code for 'm'
		0x61, // Byte 41 -> UTF-8 Code for 'a'
		0x69, // Byte 42 -> UTF-8 Code for 'i'
		0x6c, // Byte 43 -> UTF-8 Code for 'l'
		0x2e, // Byte 44 -> UTF-8 Code for '.'
		0x63, // Byte 45 -> UTF-8 Code for 'c'
		0x6f, // Byte 46 -> UTF-8 Code for 'o'
		0x6d, // Byte 47 -> UTF-8 Code for 'm' // End of User name
		0x00, // Byte 48 -> (MSB) Password length
		0x08, // Byte 49 -> (LSB) Password length
		0xXX, // Byte 50 -> UTF-8 Code for 'X'
		0xXX, // Byte 51 -> UTF-8 Code for 'X'
		0xXX, // Byte 52 -> UTF-8 Code for 'X'
		0xXX, // Byte 53 -> UTF-8 Code for 'X'
		0xXX, // Byte 54 -> UTF-8 Code for 'X'
		0xXX, // Byte 55 -> UTF-8 Code for 'X'
		0xXX, // Byte 56 -> UTF-8 Code for 'X'
		0xXX  // Byte 57 -> UTF-8 Code for 'X' // End of password
	};

	response = sl_Send(socketHandle, (const void *) messageConnect, sizeof(messageConnect), 0);
	printf("Send status of connection MQTT: %d\r\n", response);
	(void) messageConnect;

	char messagePublish[] =
	{
		0x30, // Byte 01 -> 0011 0000 PUBLISH: Client request to publish to Server 3-0 Bits stand for DUP/QoS/Retain
		0x2B, // Byte 02 -> 43 Remaining length, counting rest of buffer from here // All this is the fixed header
		0x00, // Byte 03 -> (MSB) Topic length
		0x24, // Byte 04 -> (LSB) Topic length 36 UTF-8 characters in this case
		0x2f, // Byte 05 -> UTF-8 Code for '/'
		0x72, // Byte 06 -> UTF-8 Code for 'r'
		0x67, // Byte 07 -> UTF-8 Code for 'g'
		0x6f, // Byte 08 -> UTF-8 Code for 'o'
		0x6e, // Byte 09 -> UTF-8 Code for 'n'
		0x7a, // Byte 10 -> UTF-8 Code for 'z'
		0x61, // Byte 11 -> UTF-8 Code for 'a'
		0x6c, // Byte 12 -> UTF-8 Code for 'l'
		0x65, // Byte 13 -> UTF-8 Code for 'e'
		0x7a, // Byte 14 -> UTF-8 Code for 'z'
		0x63, // Byte 15 -> UTF-8 Code for 'c'
		0x31, // Byte 16 -> UTF-8 Code for '1'
		0x38, // Byte 17 -> UTF-8 Code for '8'
		0x31, // Byte 18 -> UTF-8 Code for '1'
		0x31, // Byte 19 -> UTF-8 Code for '1'
		0x40, // Byte 20 -> UTF-8 Code for '@'
		0x67, // Byte 21 -> UTF-8 Code for 'g'
		0x6d, // Byte 22 -> UTF-8 Code for 'm'
		0x61, // Byte 23 -> UTF-8 Code for 'a'
		0x69, // Byte 24 -> UTF-8 Code for 'i'
		0x6c, // Byte 25 -> UTF-8 Code for 'l'
		0x2e, // Byte 26 -> UTF-8 Code for '.'
		0x63, // Byte 27 -> UTF-8 Code for 'c'
		0x6f, // Byte 28 -> UTF-8 Code for 'o'
		0x6d, // Byte 29 -> UTF-8 Code for 'm'
		0x2f, // Byte 30 -> UTF-8 Code for '/'
		0x74, // Byte 31 -> UTF-8 Code for 't'
		0x65, // Byte 32 -> UTF-8 Code for 'e'
		0x73, // Byte 33 -> UTF-8 Code for 's'
		0x74, // Byte 34 -> UTF-8 Code for 't'
		0x2f, // Byte 35 -> UTF-8 Code for '/'
		0x48, // Byte 36 -> UTF-8 Code for 'H'
		0x65, // Byte 37 -> UTF-8 Code for 'e'
		0x6c, // Byte 38 -> UTF-8 Code for 'l'
		0x6c, // Byte 39 -> UTF-8 Code for 'l'
		0x6f, // Byte 40 -> UTF-8 Code for 'o' // Here finish the topic
		0x48, // Byte 41 -> UTF-8 Code for 'H'
		0x65, // Byte 42 -> UTF-8 Code for 'e'
		0x6c, // Byte 43 -> UTF-8 Code for 'l'
		0x6c, // Byte 44 -> UTF-8 Code for 'l'
		0x6f  // Byte 45 -> UTF-8 Code for 'o' // Here finish the payload
	};

	for(int j = 0; j < 100; j++)
	{
		response = sl_Send(socketHandle, (const void *) messagePublish, sizeof(messagePublish), 0);
		printf("Send status of publish MQTT: %d\r\n", response);
		if(response == -1)
		{
			sl_Send(socketHandle, (const void *) messageConnect, sizeof(messageConnect), 0);
		}
		vTaskDelay((portTickType) 2000 / portTICK_RATE_MS);
	}
	(void) messagePublish;

	char messageDisconnect[] =
	{
		0xe0, // Byte 01 -> 0011 0000 DISCONNECT: Client request to disconnect from Server
		0x00  // Byte 02 -> 0 flags
	};

	response = sl_Send(socketHandle, (const void *) messageDisconnect, sizeof(messageDisconnect), 0);
	printf("Send status of desconnection: %d\r\n", response);
	(void) messageDisconnect;
} 

// Call this function after flashCertificate() in appInitSystem()
void connectServerSecure(void)
{
	// For the purpose of readability this code has no error handling.
	// The simplelink API provides return codes of the type _i32 that can be
    // checked for the value SL_RET_CODE_OK

	//Getting the IP address of HOST_NAME:
	Ip_Address_T destAddr = 0;
	PAL_getIpaddress((uint8_t*) HOST_NAME, &destAddr);

	// Creating a Socket (socketHandle <= 0 indicates an error) / Creates endpoint for communication
	// MQTT: IPv4/TCP/TLS
	_i16 socketHandle = sl_Socket(SL_AF_INET, SL_SOCK_STREAM, SL_SEC_SOCKET);

	// Adding the certificate to the socket
	sl_SetSockOpt
	(
		socketHandle,
		SL_SOL_SOCKET,
		SL_SO_SECURE_FILES_CA_FILE_NAME,
		CA_FILE_NAME,
		strlen (CA_FILE_NAME)
	);

	// Configuration the connection settings (IP family, Port, Host domain, not used):
	SlSockAddrIn_t addr;
	addr.sin_family = SL_AF_INET;
	addr.sin_port= sl_Htons(8883); // MQTT secured port 8883
	addr.sin_addr.s_addr = destAddr;

	// Use this before connecting: By default secure method id TLS 1.2 SSL 3
	SlSockSecureMethod secMethod;
	secMethod.secureMethod = SL_SO_SEC_METHOD_SSLv3_TLSV1_2; // SL_SO_SEC_METHOD_SSLv3_TLSV1_2 SL_SO_SEC_METHOD_TLSV1_2
	sl_SetSockOpt
	(
		socketHandle,
		SL_SOL_SOCKET,
		SL_SO_SECMETHOD,
		(_u8 *)&secMethod,
		sizeof(secMethod)
	);

	// Connecting:
	_i16 response = sl_Connect(socketHandle, (SlSockAddr_t *) &addr, sizeof(SlSockAddrIn_t));
	printf("Response of sl_Connect: %d\r\n",response);

	// Implementation Placeholder
	// Do your request, etc. here
	publish(socketHandle, HOST_NAME, PATH); // Example

	// Closing:
	sl_Close(socketHandle);
}

void appInitSystem(void * CmdProcessorHandle, uint32_t param2)
{
    if (CmdProcessorHandle == NULL)
    {
        printf("Command processor handle is null \n\r");
        assert(false);
    }
    BCDS_UNUSED(param2);

    /*WLAN stable connection: START*/
    Retcode_T returnValue = RETCODE_OK;
    retcode_t rc = RC_OK;
    rc = connectToWLAN();
    if (RC_OK != rc)
    {
        printf("appInitSystem: network init/connection failed. error=%d\r\n", rc);
        return;
    }
    else
    {
    	printf("Status WLAN connection: Succeed!\r\n");
    }

    printf("ServalPal Setup\r\n");
    returnValue = ServalPalSetup();
    if (RETCODE_OK != returnValue)
    {
        Retcode_RaiseError(returnValue);
        printf("ServalPal Setup failed with %d \r\n", (int) returnValue);
        return;
    }
    else
    {
    	printf("Status ServalPat Setup: Succeed!\r\n");
    }
    /*WLAN stable connection: END*/

    /*MQTT/TLS Request: Publish START*/
    flashCertificate(CA_FILE_NAME, digicert_root_crt, digicert_root_crt_len);
    int counter = 0;
    for(;;)
    {
    	connectServerSecure();
    	vTaskDelay((portTickType) 1000 / portTICK_RATE_MS);
    	printf("Attempts: %d\r\n",++counter);
    }
}

 

0 (0 Votes)
RE: MQTT and TLS using Simplelink API
Answer
7/10/18 9:08 PM as a reply to Rolando Gonzalez.
Hello Rolando,

I am glad that you were able to implement your own MQTTS solution. In addition, I really appreciate that you are sharing your experience and the source code with the XDK community. You made an amazing work by implementing it from the scratch.

I am pretty sure, this will help many other users, which want to use MQTTS in the future.

In regards to using MQTT paho, I guess you will not need any greater effort to implement a connection layer between simplelink TCP and the MQTT paho library.

Of course, if you need any help, please do not hesitate to ask if you have any further questions.

Kind regards,
Franjo
0 (0 Votes)