2021-02-25 04:21 AM
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.
Solved! Go to Solution.
2021-03-16 09:59 AM
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)
2021-02-25 01:20 PM
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.
2021-02-25 08:41 PM
@Vangelis Fortounas Thank you Sir, will try this today and get back.
2021-02-27 06:59 AM
For a DNS_TABLE_SIZE the default value is 4, which is a rather good choice for most uses.
2021-03-07 11:42 PM
@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.
2021-03-08 12:15 AM
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.
2021-03-08 11:56 PM
@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?
2021-03-14 10:46 PM
can anyone help me solve the issue please??
2021-03-14 11:51 PM
What are you compiling with?
How large is the Heap?
2021-03-15 02:37 AM
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.