I am working on a project using an STM32 microcontroller with an ESP8266 Wi-Fi modem to connect to an MQTT broker. I am using the CoreMQTT library for the MQTT protocol implementation. However, I am facing an issue where the broker does not recognize the transmitted packets as valid MQTT packets.
From my observations, the MQTT packets are being sent in fragments, like this:
Packet 1: Header flags, Message Type, Message Length, Protocol Name Length, Protocol Name, Version, and Connect Flags
Packet 2: Client ID Length
Packet 3: Client ID
When I transmit these fragments separately (packet-by-packet), the server does not detect them as a valid MQTT packet.
My question is:
Does the entire MQTT packet need to be combined into a single transmission before sending?
Is it invalid for the MQTT packet to be fragmented, or is there some configuration I am missing?
Any guidance or examples of handling this correctly with CoreMQTT would be much appreciated!
Hey @ShreyAcharya, welcome to the FreeRTOS community. Sending the MQTT packet in fragments is not an issue. Could you maybe tell us what broker are you using. Also it will be helpful for debugging if you could capture the network traffic going to and coming in from the broker and let us know about that.
I am using the test.mosquitto.org broker and am able to establish a TCP connection with it on port 1883 using the AT+CIPSTART command. However, when I send the MQTT connect command (via the MQTT_Connect API), the fragments are transmitted, but I cannot see them in Wireshark.
I verified the packet fragments during debugging, and they appear correct. Below is the implementation of my transport.send function:
int32_t network_send(NetworkContext_t *pNetworkContext, const uint8_t *pBuffer, size_t bytesToSend) {
char cmd[50];
HAL_Delay(100);
printf("Buffer contents (%zu bytes):\n", bytesToSend);
for (size_t i = 0; i < bytesToSend; i++) {
printf("0x%02X ", pBuffer[i]); // Print each byte in hexadecimal
if ((i + 1) % 16 == 0) {
printf("\n"); // New line after 16 bytes for readability
}
}
printf("\n");
snprintf(cmd, sizeof(cmd), "AT+CIPSEND=%d\r\n", bytesToSend);
HAL_UART_Transmit(&huart3, (uint8_t *)cmd, strlen(cmd), HAL_MAX_DELAY);
while(!Wait_for(">", &huart3));
// Transmit the data
HAL_StatusTypeDef status = HAL_UART_Transmit(&huart3, (uint8_t *)pBuffer, bytesToSend, HAL_MAX_DELAY);
// Return the number of bytes sent if successful, otherwise return 0
return (status == HAL_OK) ? bytesToSend : 0;
}
in :
TransportInterface_t transport;
transport.send = network_send;
The ESP32 can receive 8192 bytes and send 2920 bytes at most each time. If the data received by ESP32 reaches or exceeds 2920 bytes, the data will be immediately sent in chunks of 2920 bytes. Otherwise, it will wait for 20 milliseconds before being sent (You can configure this interval using AT+TRANSINTVL command).
So I believe there will be a transmission delay of 20 ms between each fragment sent from coreMQTT, unless you have configured it using AT+TRANSINTVL. It can be that broker might be rejecting the fragments due to this delay.
That should not happen. Where are you running Wireshark? One way can be to run the MQTT broker locally on your PC and then run Wireshark on your PC to capture traffic on port 1883.