Using mbedTLS MQTT in Tiva C series without RTOS

Hi, I am trying to implement tls/mqtt using mbedtls library. I got reference from below link: “mcuoneclipse/Examples/MCUXpresso/FRDM-K64F/FRDM-K64F_lwip_lwip_mqtt_bm/source at master · ErichStyger/mcuoneclipse · GitHub
In this, after performing “mqtt_do_connect()” step, it gives me error in “mqtt_do_tls_handshake()” step.

In mbedtls_ssl_handshake() function, ‘if( ssl == NULL || ssl->conf == NULL )’ this condition is set to true because ssl->conf is null and it returns me an error MBEDTLS_ERR_SSL_BAD_INPUT_DATA.

Here is my TLS init code:

mbedtls_entropy_init( &stentropy );
mbedtls_ctr_drbg_init( &stctr_drbg );
mbedtls_x509_crt_init( &stcacert );
mbedtls_ssl_config_init( &stconf );
mbedtls_ssl_init( &stssl );
if( ( ret = mbedtls_ssl_config_defaults( &stconf,
MBEDTLS_SSL_IS_CLIENT,
MBEDTLS_SSL_TRANSPORT_STREAM,
MBEDTLS_SSL_PRESET_DEFAULT ) ) != 0 )
{
LWIP_DEBUGF(MQTT_APP_DEBUG_TRACE,( " failed\n ! mbedtls_ssl_config_defaults returned %d\n\n", ret ));
printf( " failed\n ! mbedtls_ssl_config_defaults returned %d\n\n", ret );
return -1;
}
mbedtls_ssl_conf_authmode(&stconf, MBEDTLS_SSL_VERIFY_NONE);
mbedtls_ssl_conf_rng( &stconf, mbedtls_ctr_drbg_random, &stctr_drbg );
mbedtls_ssl_conf_dbg( &stconf, my_debug, stdout );
mbedtls_ssl_setup(&stssl, &stconf);

if(CONFIG_BROKER_HOST_NAME!=NULL && ( ret = mbedtls_ssl_set_hostname(&stssl, CONFIG_BROKER_HOST_NAME) ) != 0 )
{
LWIP_DEBUGF(MQTT_APP_DEBUG_TRACE,( " failed\n ! mbedtls_ssl_set_hostname returned %d\n\n", ret ));
printf( " failed\n ! mbedtls_ssl_set_hostname returned %d\n\n", ret );
return -1;
}
/* the SSL context needs to know the input and output functions it needs to use for sending out network traffic. */
// mbedtls_ssl_set_bio(&ssl, &mqtt_client, mbedtls_net_send, mbedtls_net_recv, NULL);
mbedtls_ssl_set_bio(&stssl, stAPP_MQTT_Msg_t->pstmqtt_client, MT_Mbedtls_Send, MT_Mbedtls_Recv, NULL);

Thanks in advance.

Hi @urvishah
Your TLS init seems to be correct.

The call to mbedtls_ssl_setup(&stssl, &stconf); should have assigned&stconf to ssl->conf, so it shouldn’t have been NULL.
Have you checked that mbedtls_ssl_config_defaults() didn’t fail?
Regards,

Mbed TLS Support
Ron

Hi Ron,
My this function ‘mbedtls_ssl_setup’ executing successfully now. Actually it was a problem with heap size memory, I increased heap memory size and now this function is working properly.

But now as I move further for initializing, I am again facing issue while tls handshaking. My

  1. TLS_Init function processed properly without error
  2. It tries to connect to mqtt broker i.e. mosquitto on my local machine using ‘mqtt_do_connect’ and it return ok
  3. It then goes for handshake using ‘mqtt_do_tls_handshake’; in this
    a. mbedtls_ssl_handshake-> mbedtls_ssl_handshake_step-> ssl_write_client_hello->
    mbedtls_ssl_write_record-> ssl_generate_random it executes this loops
    b. In ‘ssl_generate_random’ function: it executes ‘if( ( ret = ssl->conf->f_rng( ssl->conf-
    >p_rng, p, 28 ) ) != 0 )’
    (i) in this: mbedtls_ctr_drbg_random-> mbedtls_mutex_lock-> threading_mutex_fail
    THIS RETURNS ME ERROR: “MBEDTLS_ERR_THREADING_BAD_INPUT_DATA”
    i.e. -28 error code

What could be the problem and it’s relevant solution for this error?

Hi Ron,
I compared my TLS_init code with the code that I refered from internet. I checked that I have not included below lines of code:

if( ( ret = mbedtls_ctr_drbg_seed( &stctr_drbg, mbedtls_entropy_func, &stentropy,
(const unsigned char *) pers,
strlen(pers ) ) ) != 0 )
{
LWIP_DEBUGF(MQTT_APP_DEBUG_TRACE,( " failed\n ! mbedtls_ctr_drbg_seed returned %d\n", ret ));
printf( " failed\n ! mbedtls_ctr_drbg_seed returned %d\n", ret );
return -1;
}
Now I added this and got error no. -52; so i debug my code and found that the same function i.e. mbedtls_mutex_lock-> threading_mutex_fail returns me an error.
The sequence of code flow is like:

mbedtls_ctr_drbg_seed-> mbedtls_ctr_drbg_reseed-> 0 != ctx->f_entropy( ctx->p_entropy, seed,
ctx->entropy_len ) → mbedtls_entropy_func-> mbedtls_mutex_lock-> threading_mutex_fail and error “MBEDTLS_ERR_THREADING_BAD_INPUT_DATA”

kindly guide me through this.

Hi @urvishah
AS the errors imply, these are threading issues. Does your system support pthread? How is threading configured in your system for Mbed TLS?
AS you can see, MBEDTLS_ERR_THREADING_BAD_INPUT_DATA is returned in case MBEDTLS_THREADING_PTHREAD is defined if: ( mutex == NULL || ! mutex->is_valid ) however since you call mbedtls_entropy_init() so this shouldn’t be the case.

Is it possible you have defined MBEDTLS_THREADING_ALT but forgot to set your alternative implementation of threading with mbedtls_threading_set_alt()? In this case, the defult lock functionality will always fail with the error code you received because threading_mutex_fail is set by default.

Regards,
Ron

Hi @roneld01
In my project:
#define MBEDTLS_THREADING_ALT
//#define MBEDTLS_THREADING_PTHREAD

I have not used ‘mbedtls_threading_set_alt()’ yet. But I tried to implement it as:
/* Setup the thread callbacks */
mbedtls_threading_set_alt(threading_mutex_init_pthread,
threading_mutex_free_pthread, threading_mutex_lock_pthread,
threading_mutex_unlock_pthread);

It gives me below errors:
undefined first referenced
symbol in file


threading_mutex_free_pthread ./lwip_Mqtt.obj
threading_mutex_init_pthread ./lwip_Mqtt.obj
threading_mutex_lock_pthread ./lwip_Mqtt.obj
threading_mutex_unlock_pthread ./lwip_Mqtt.obj

In threading.c file, all these functions are declared under macro definition of:
#if defined(MBEDTLS_THREADING_PTHREAD)… and in my project this macro is undefined.

Then I tried to define this macro and compile my code again. It gives me 77 error in diferent mbedtls files:
gmake: *** [Third Party/mbedtls/library/ecp_curves.obj] Error 1
“C:\ti.…\third_party\mbedtls\include\mbedtls\check_config.h”, line 616: fatal error #35: #error directive: “MBEDTLS_THREADING_ALT defined, but not all prerequisites”

Regards,
Urvi Shah

Hi @urvishah
If you define MBEDTLS_THREADING_PTHREAD, and your system has pthread, why do you need MBEDTLS_THREADING_ALT?

As you can see in the check_config.h file:

#if defined(MBEDTLS_THREADING_ALT)
#if !defined(MBEDTLS_THREADING_C) || defined(MBEDTLS_THREADING_IMPL)
#error "MBEDTLS_THREADING_ALT defined, but not all prerequisites"
#endif
#define MBEDTLS_THREADING_IMPL
#endif

#if defined(MBEDTLS_THREADING_C) && !defined(MBEDTLS_THREADING_IMPL)
#error "MBEDTLS_THREADING_C defined, single threading implementation required"
#endif
#undef MBEDTLS_THREADING_IMPL

You can’t have both MBEDTLS_THREADING_PTHREAD and MBEDTLS_THREADING_ALT defined.
If your syustem doesn’t have pthread, you will need to supply your own threading implementation which is not pthread. If your system has pthread, you don’t need MBEDTLS_THREADING_ALT defined.
Regards

Hi @roneld01,

I am unaware of mbedtls library’s detail i.e. which macro is used for which purpose. I am trying to connect to my secure mqtt broker using mbedtls over lwip, and for that I have referred internet examples i.e. github. If you have any link which explains in short and simple way that how to use mbedtls with examples then do share it. I referred below links:

  1. https://mcuoneclipse.com/2017/04/17/tutorial-secure-tls-communication-with-mqtt-using-mbedtls-on-top-of-lwip/
    2.https://github.com/ErichStyger/mcuoneclipse/tree/master/Examples/MCUXpresso/FRDM-K64F/FRDM-K64F_lwip_lwip_mqtt_bm/source
  2. https://tls.mbed.org/module-level-design-ssl-tls

Now, I have commented “MBEDTLS_THREADING_ALT” macro and uncommented “MBEDTLS_THREADING_PTHREAD” macro in config.h file. So it gives me below errors:

  1. identifier “PTHREAD_MUTEX_INITIALIZER” is undefined threading.c
  2. invalid redeclaration of type name “mbedtls_threading_mutex_t” (declared at line 49 of “C:\ti.…\third_party\mbedtls\include\mbedtls\threading.h”) external location: C:\ti.…\third_party\mbedtls\ti\port\threading_alt.h C/C++ Problem

Hi @urvishah
in the Mbed TLS Knowledge base you will find several articles that will interest you.
I would suggest you start with the following:

As for the compilation errors you are receiving:

  1. PTHREAD_MUTEX_INITIALIZER is part of the pthread library. If you don’t have it, then you probably don’t have pthread in your system, and you should keep the previous configiuration of MBEDTLS_THREADING_ALT defined and MBEDTLS_THREADING_PTHREAD undefined. You should call mbedtls_threading_set_alt with the threading functions that are relevant for your platform.
  2. This error is because you already defined mbedtls_threading_mutex_t in your threading_alt.h file ( which is not part of the Mbed TLS release), and it collides with the default structure in Mbed TLS, when MBEDTLS_THREADING_PTHREAD is defined.
    Regards

Hi @urvishah

Were you able to achieve this? I’m trying to implement the MQTT on TM4C1294NCPDT without RTOS.

I have implemented HTTPS but now we want yo have MQTT.

Can you guide me with this?

you can also email me directly at dpkrai93@gmail.com.

Thank you.

Regards,
Deepak

Hi Deepak,
For implementing MQTT on TM4C1294NCPDT you required below things:

  1. LWIP v2
  2. Latest tivaware having mqtt library support
  3. Set heap size >= 72K bytes
  4. If you want to use secure mqtt, then you must have mbedtls library

Hi @urvishah

Thank you for responding to my question.

I’m using LWIP 2.0.0

Tivaware: which version are you using? I can download the same.

Heap size shouldn’t be problem for me I think.

I have implemented mbedTLS library to support HTTPS on my board. So I can rebuild it as per my requirements.

Can you share the the function or file that is making the call and getting the subscription to the broker and getting the data to the client? basically the implementation of mqtt on tivaC. I just want to know what are the steps required and how to execute them. This will save me a lot of time. You can email me as well if you don’t want to share here.

email: dpkrai93@gmail.com

Thank you again.

Regards,
Deepak

Hi Deepak,

I am using tivaware TivaWare_C_Series-2.1.2.111.
For code/function I have used/referred below link and implemented same in my code & it worked for me:

Hi Urvi,

I have a question regarding Tivaware with MQTT support. I have downloaded tivaware 2.2.0.295 which is the latest release and I didn’t find anything related to MQTT. So what did you mean by MQTT support? As far as I know, tiva doesn’t support MQTT on tivaC.

Can you please elaborate what I need to do?

Regards,
Deepak

In tivaware 2.2.0.295 they have given lwip-1.4.1; replace it with lwip 2.0. Or else download lwip 2.0 and copy mqtt relevant files to tivaware and use it.

Hi Urvi,

By Mqtt relevant files do you mean lqip_mqtt.c, mqtt.c from mcuoneclipse/Examples/MCUXpresso/FRDM-K64F/FRDM-K64F_lwip_lwip_mqtt_bm/source at master · ErichStyger/mcuoneclipse · GitHub ??

Because as I said earlier there’s no reference of mqtt in lwip 2.0.0

Hi Deepak,

Create 1 folder namely: ‘mqtt’ in C:\ti\TivaWare_C_Series-2.2.0.295\third_party\lwip-1.4.1\apps.

Rename mqtt_new.c/.h files (from given lnik) as mqtt.c/.h and then Copy mqtt.c and mqtt.h files in this folder.
Add lwip_mqtt.c/.h files to your project.

Hi Urvi,

Thank you for the response. I did that and I have some questions regarding some missing files.

I copied the mqtt_new.c and there are few files which I cant locate anywhere.

#include “lwip/apps/mqtt_priv.h”
#include “lwip/altcp.h”
#include “lwip/altcp_tcp.h”
#include “lwip/altcp_tls.h”

and these files are not included in mqtt.c

can you tell me where I can find these and if not, is it okay to use mqtt.c instead of mqtt_new.c from that link?

Regards,
Deepak

Modify include files as below and try again:

#include “mqtt.h”
#include “lwip/timeouts.h”
#include “lwip/ip_addr.h”
#include “lwip/mem.h”
#include “lwip/err.h”
#include “lwip/pbuf.h”
#include “lwip/tcp.h”
//#include <string.h>
//#include <stdio.h>

#include “net_sockets.h”
#include “net.h”
#include “ssl.h”
// #include “rng1.h”

Hey Urvi,

Thank you for the reply. I updated my file with these change.

I have question regarding other include files, namely RNG1.c/h . I believe the code uses ring buffer to get data using mbedtls_net_recv function. If I include this file, it has various include files such as CS1.h Do i need those files?

If not then how have you implemented the data to be sent and received by TLS and MQTT layers.

Regards,
Deepak