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.

20 REPLIES 20

MEM_SIZE  configured in the device is 2000. should I increase it? the data which I am sending is "Hello World", only 11 bytes.

I am compiling in keil and heap size is 0x4000

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)

The PBUF_POOL_BUFSIZE is also adjusted automatically by default:

#define PBUF_POOL_BUFSIZE               LWIP_MEM_ALIGN_SIZE(TCP_MSS+40+PBUF_LINK_ENCAPSULATION_HLEN+PBUF_LINK_HLEN)

Also take a note that if MEM_USE_POOLS (recommended) or MEM_LIBC_MALLOC (rarely) is enabled, then lwIP integrated heap is not used and MEM_SIZE value doesn't matter.

https://lwip.fandom.com/wiki/Custom_memory_pools

.

Thank you @Vangelis Fortounas​ I defined buffer length as you suggested and now the OUT of memory error is gone. It goes ahead and shows that it is sending tcp data but I doubt if its actually sending coz I am not observing the data on my server.

MX_LWIP_Init

netif: netmask of interface set to 255.255.255.0

netif: GW address of interface set to 192.168.1.1

netif_set_ipaddr: netif address being changed

netif: IP address of interface set to 192.168.1.120

netif: added interface st IP addr 192.168.1.120 netmask 255.255.255.0 gw 192.168.1.1

netif: setting default interface st

netlink is up

tcp_bind: bind to port 80

httpd_init

myCGIinit

IP resolved is 43.61.0.8

inside example_do_connect

tcp_bind: bind to port 49153

mqtt_client_connect: Connecting to host: 43.61.0.8 at port:18973

tcp_connect to port 18973

tcp_enqueue_flags: queueing 6509:6510 (0x2)

tcp_output_segment: 6509:6509

mqtt_publish: Publish with payload length 15 to topic "aeplIN/sidabc/test2"

mqtt_output_send

ringbuf_lin_len 88... send_len 2920

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

wrap

tcp_write(pcb=20008640, data=200045c0, len=88, apiflags=1)

tcp_pbuf_prealloc

tcp_write: queueing 6510:6598

tcp_output flush

Publish Success.

@Piranha​  I guess increasing MEM size solved the issue. Thank you 🙂

.

Hello @sne_123​ I am having DNS problem in my code. Could you please share What steps you followed to resolve DNS problem.

I can not get proporly resolved DNS address in callback function.

@voyvoda .​  Hello... As the above mentors suggested LWIP_DNS need to be be defined as 1 inside lwipopts.h to use DNS functionality. (#define LWIP_DNS 1)

Have you set the dns server ip address?? Even I had this issue but dns got resolved after I added proper dns server address...I am using code below:-

dns_init();

ip_addr_t primaryDnsServer;

    ip4_addr_set_u32(&primaryDnsServer, ipaddr_addr("192.168.0.1")); // here set your dns server address

   dns_setserver(0, &primaryDnsServer);

char* dnsname = "www.freertos.com";

ip_addr_t dnsresp;

dns_gethostbyname(dnsname, &dnsresp, dns_found, 0);

 dns_found(dnsname, &dnsresp, 0);

and my dns_found is callback here:-

void dns_found(const char *name, ip_addr_t *addr, void *arg)

{

char ip_string[20];char* token1;

  LWIP_UNUSED_ARG(arg);

  printf("%s: %s\n", name, addr ? ip_ntoa(addr) : "<not found>");

sprintf(ip_string,"%s",addr ? ip_ntoa(addr): "<not found>");

printf("ip_string is %s\n\r",ip_string);

}