cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F767 MQTT USING LWIP

sne_123
Associate III

I am new to LWIP and MQTT. I am trying to use MQTT using LWIP in stm32f767 . I am able to get ethernet connection up and ping also works. I use mqtt_client_connect to connect to the server. The function is as follows:-

mqtt_client_connect(mqtt_client_t *client, const ip_addr_t *ip_addr, u16_t port, mqtt_connection_cb_t cb, void *arg,const struct mqtt_connect_client_info_t *client_info)

{{

 err_t err;

 size_t len;

 u16_t client_id_length;

 /* Length is the sum of 2+"MQTT", protocol level, flags and keep alive */

 u16_t remaining_length = 2 + 4 + 1 + 1 + 2;

 u8_t flags = 0, will_topic_len = 0, will_msg_len = 0;

 LWIP_ASSERT("mqtt_client_connect: client != NULL", client != NULL);

 LWIP_ASSERT("mqtt_client_connect: ip_addr != NULL", ip_addr != NULL);

 LWIP_ASSERT("mqtt_client_connect: client_info != NULL", client_info != NULL);

 LWIP_ASSERT("mqtt_client_connect: client_info->client_id != NULL", client_info->client_id != NULL);

 if (client->conn_state != TCP_DISCONNECTED) {

  LWIP_DEBUGF(MQTT_DEBUG_WARN,("mqtt_client_connect: Already connected\n\r"));

  return ERR_ISCONN;

 }

 /* Wipe clean */

 memset(client, 0, sizeof(mqtt_client_t));

 client->connect_arg = arg;

 client->connect_cb = cb;

 client->keep_alive = client_info->keep_alive;

 mqtt_init_requests(client->req_list);

 /* Build connect message */

 if (client_info->will_topic != NULL && client_info->will_msg != NULL) {

  flags |= MQTT_CONNECT_FLAG_WILL;

  flags |= (client_info->will_qos & 3) << 3;

  if (client_info->will_retain) {

   flags |= MQTT_CONNECT_FLAG_WILL_RETAIN;

  }

  len = strlen(client_info->will_topic);

  LWIP_ERROR("mqtt_client_connect: client_info->will_topic length overflow", len <= 0xFF, return ERR_VAL);

  LWIP_ERROR("mqtt_client_connect: client_info->will_topic length must be > 0", len > 0, return ERR_VAL);

  will_topic_len = (u8_t)len;

  len = strlen(client_info->will_msg);

  LWIP_ERROR("mqtt_client_connect: client_info->will_msg length overflow", len <= 0xFF, return ERR_VAL);

  will_msg_len = (u8_t)len;

  len = remaining_length + 2 + will_topic_len + 2 + will_msg_len;

  LWIP_ERROR("mqtt_client_connect: remaining_length overflow", len <= 0xFFFF, return ERR_VAL);

  remaining_length = (u16_t)len;

 }

 /* Don't complicate things, always connect using clean session */

 flags |= MQTT_CONNECT_FLAG_CLEAN_SESSION;

 len = strlen(client_info->client_id);

 LWIP_ERROR("mqtt_client_connect: client_info->client_id length overflow", len <= 0xFFFF, return ERR_VAL);

 client_id_length = (u16_t)len;

 len = remaining_length + 2 + client_id_length;

 LWIP_ERROR("mqtt_client_connect: remaining_length overflow", len <= 0xFFFF, return ERR_VAL);

 remaining_length = (u16_t)len;

 if (mqtt_output_check_space(&client->output, remaining_length) == 0) {

  return ERR_MEM;

 }

 client->conn = tcp_new();

 if (client->conn == NULL) {

  return ERR_MEM;

 }

 /* Set arg pointer for callbacks */

 tcp_arg(client->conn, client);

 /* Any local address, pick random local port number */

 err = tcp_bind(client->conn, IP_ADDR_ANY, 0);

 if (err != ERR_OK) {

  LWIP_DEBUGF(MQTT_DEBUG_WARN,("mqtt_client_connect: Error binding to local ip/port, %d\n\r", err));

  goto tcp_fail;

 }

 LWIP_DEBUGF(MQTT_DEBUG_TRACE,("mqtt_client_connect: Connecting to host: %s at port:%"U16_F"\n\r", ipaddr_ntoa(ip_addr), port));

 /* Connect to server */

 err = tcp_connect(client->conn, ip_addr, port, mqtt_tcp_connect_cb);

 if (err != ERR_OK) {

  LWIP_DEBUGF(MQTT_DEBUG_TRACE,("mqtt_client_connect: Error connecting to remote ip/port, %d\n\r", err));

  goto tcp_fail;

 }

 /* Set error callback */

 tcp_err(client->conn, mqtt_tcp_err_cb);

 client->conn_state = TCP_CONNECTING;

 /* Append fixed header */

 mqtt_output_append_fixed_header(&client->output, MQTT_MSG_TYPE_CONNECT, 0, 0, 0, remaining_length);

 /* Append Protocol string */

 mqtt_output_append_string(&client->output, "MQTT", 4);

 /* Append Protocol level */

 mqtt_output_append_u8(&client->output, 4);

 /* Append connect flags */

 mqtt_output_append_u8(&client->output, flags);

 /* Append keep-alive */

 mqtt_output_append_u16(&client->output, client_info->keep_alive);

 /* Append client id */

 mqtt_output_append_string(&client->output, client_info->client_id, client_id_length);

 /* Append will message if used */

 if ((flags & MQTT_CONNECT_FLAG_WILL) != 0) {

  mqtt_output_append_string(&client->output, client_info->will_topic, will_topic_len);

  mqtt_output_append_string(&client->output, client_info->will_msg, will_msg_len);

 }

 return ERR_OK;

tcp_fail:

 tcp_abort(client->conn);

 client->conn = NULL;

 return err;

}

Here we need to pass IP address of the server to which we want to connect. I want to use hostname instead of IP address. What changes will i need to do so that it takes the hostname like "broker.mqttdashboard.com" ??

Thank you for the help.

1 ACCEPTED SOLUTION

Accepted Solutions

Hello

cubemx memory settings are very conservative and guarantee the min functionality (ICMP and small tcp/udp packets)

Try, as an emergency workaround, not optimized: (assuming that use CUBEMX)

increase segment size TCP_MSS to 1460 (this is max for ethernet)

increase PBUF_POOL_BUFSIZE to 1600 (mss+headers+etc) Send buffer (TCP_SND_BUF) will increase automatically.

and MEM_SIZE to 16000 (it seems too high but trimming is a time consuming procedure. Make it after, when project is operative)

View solution in original post

20 REPLIES 20

Hello

LWIP_DNS need to be be defined as 1 inside lwipopts.h to use DNS functionality. (#define LWIP_DNS 1)

The function dns_gethostbyname(..) or dns_gethostbyname_addrtype(...) functions resolve hostnames to addresses, V4 ,V6

Theese functions teturn imediately and use callbacks when succeed or have errors.

Inside dns.c module will find how to use theese functions

Suggest also to set DNS_TABLE_SIZE above zero , so the resolved addresses will keep in local database until some internal timeout expiration. Then any requst for name resolving will be handled localy.

@Vangelis Fortounas​  Thank you Sir, will try this today and get back.

For a DNS_TABLE_SIZE the default value is 4, which is a rather good choice for most uses.

sne_123
Associate III

@Vangelis Fortounas​ @Piranha​ Hello Sir, As you said I am able to resolve the DNS properly. Using the IP I try to connect to the MQTT server but my data is not being posted. Seems like my device is not getting connected to MQTT server. Here's the log

netif: netmask of interface set to 255.255.255.0

netif: GW address of interface set to 192.168.0.1

netif_set_ipaddr: netif address being changed

netif: IP address of interface set to 192.168.0.155

netif: added interface st IP addr 192.168.0.155 netmask 255.255.255.0 gw 192.168.0.1

netif: setting default interface st

m15.cloudmqtt.com: 115.23.0.5

               ip_string is 115.23.0.5

115.23.0.5

inside example_do_connect

mqtt_client_connect: Connecting to host: 115.23.0.5 at port:1883

mqtt_publish: Publish with payload length 576 to topic "aeplIN/sidabc12/test"

Publish err: -1.

mqtt_tcp_err_cb: TCP error callback: error -13, arg: 20000150

mqtt_connection_cb entered

status is 256

mqtt_connection_cb: Disconnected, reason: 256

inside example_do_connect

mqtt_client_connect: Connecting to host: 115.23.0.5 at port:18973

mqtt_tcp_err_cb: TCP error callback: error -13, arg: 20000150

mqtt_connection_cb entered

status is 256

mqtt_connection_cb: Disconnected, reason: 256

inside example_do_connect

mqtt_client_connect: Connecting to host: 115.23.0.5 at port:18973

mqtt_tcp_err_cb: TCP error callback: error -13, arg: 20000150

mqtt_connection_cb entered

status is 256

what might be the issue? The above log was for payload of 576 length.

 when I try to send a small payload like "hello world" I get the following output.

netif: netmask of interface set to 255.255.255.0

netif: GW address of interface set to 192.168.0.1

netif_set_ipaddr: netif address being changed

netif: IP address of interface set to 192.168.0.155

netif: added interface st IP addr 192.168.0.155 netmask 255.255.255.0 gw 192.168.0.1

netif: setting default interface st

m15.cloudmqtt.com: 115.23.0.5

               ip_string is 115.23.0.5

115.23.0.5

inside example_do_connect

mqtt_client_connect: Connecting to host: 115.23.0.5 at port:1883

mqtt_publish: Publish with payload length 15 to topic "aeplIN/sidabc12/test"

mqtt_output_send: tcp_sndbuf: 1072 bytes, ringbuf_linear_available: 88, get 0, put 88

Publish Success.

mqtt_tcp_err_cb: TCP error callback: error -13, arg: 20000150

mqtt_connection_cb entered

status is 256

mqtt_connection_cb: Disconnected, reason: 256

inside example_do_connect

mqtt_client_connect: Connecting to host: 115.23.0.5 at port:1883

mqtt_tcp_err_cb: TCP error callback: error -13, arg: 20000150

mqtt_connection_cb entered

status is 256

mqtt_connection_cb: Disconnected, reason: 256

Seems like "mqtt_output_send" is not getting called. Dont know for what reason.

sne_123
Associate III

OK I got it it was issue of the buffer size,changed MQTT_OUTPUT_RINGBUF_SIZE from 256 to 1024 and now its going ahead and showing me publish success. But I am not able to view data on the server.

sne_123
Associate III

@Vangelis Fortounas​  When publishing message I get an error as follows:-

tcp_write : could not allocate memory for pbuf copy size 88

mqtt_output_send: Send failed with err -1 ("Out of memory error.")

Why am I getting this error?

sne_123
Associate III

can anyone help me solve the issue please??

What are you compiling with?

How large is the Heap?​

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..

Hello

seems that memory is exhausted .

possible causes are

small MEM_SIZE -> increase it generously

not freed buffers inside receive callbacks . It is programmers responsibility under certain conditions to frees (pbuf_free(p)) the buffers (struct pbuf p) that passed to receive callbacks (udp_recv_fn and tcp_recv_fn) functions.