Sending payload to AWS IOT using MQTT causes an error

sheikhumar93
Posts: 13
Joined: Fri Aug 10, 2018 7:47 am

Sending payload to AWS IOT using MQTT causes an error

Postby sheikhumar93 » Tue Aug 14, 2018 9:38 am

I have been trying to send sensor readings that I have gathered on a spiffs file using the subscribe publish example. AWS docs say that the maximum size for the payload is 128kb. When I try to send the default message "hello from ESP32 (QOS0) : 0" in the example it gets posted just fine and I can see messages in my IoT console. But when I try to send my own chars it exits with the error

Code: Select all

I (42606) mbedtls: ssl_tls.c:2616 ssl->f_recv(_timeout)() returned -26624 (-0x6800)

W (42609) mbedtls: ssl_tls.c:4134 mbedtls_ssl_fetch_input() returned -26624 (-0x6800)

W (42618) mbedtls: ssl_tls.c:3998 mbedtls_ssl_read_record_layer() returned -26624 (-0x6800)

W (42627) mbedtls: ssl_tls.c:7205 mbedtls_ssl_read_record() returned -26624 (-0x6800)

I (42636) Example: Stack remaining for task 'aws_iot_task' is 892 bytes
Payload sent to AWS IOT: 32768, +0.00, +0.00, +0.00,  +0.00,  +0.00,  +0.00
32769, +0.00, +0.00, +0.00,  +0.00,  +0.00,  +0.00
32770, +0.00, +0.00, +0.00,  +0.00,  +0.00,  +0.00
32830, +0.42, -0.04, +0.91,  -8.97,  +3.01, -21.68
32832, +0.42, -0.04, +0.91,  -8.97,  +3.01, -21.68
32833, +0.42, -0.04, +0.91,  -8.97,  +3.01, -21.68
32836, +0.42, -0.04, +0.91,  -8.97,  +3.01, -21.68
32837, +0.42, -0.04, +0.91,  -8.97,  +3.01, -21.68
32840, +0.42, -0.04, +0.91,  -8.97,  +3.01, -21.68
32841, +0.42, -0.04, +0.91,  -8.97,  +3.01, -21.68
Size of: 4
E (43679) Example: An error occurred in the main loop.
abort() was called at PC 0x400d341b on core 0

My code for the aws_iot_task(void *param) is pretty much the same as the example with the slight variation in the payload area

Code: Select all

while((NETWORK_ATTEMPTING_RECONNECT == rc || NETWORK_RECONNECTED == rc || SUCCESS == rc)) {
        //Max time the yield function will wait for read messages
        rc = aws_iot_mqtt_yield(&client, 100);
        if(NETWORK_ATTEMPTING_RECONNECT == rc) {
            // If the client is attempting to reconnect we will skip the rest of the loop.
            continue;
        }
        ESP_LOGI(TAG, "Stack remaining for task '%s' is %d bytes", pcTaskGetTaskName(NULL), uxTaskGetStackHighWaterMark(NULL));
        vTaskDelay(1000 / portTICK_RATE_MS);
//        sprintf(cPayload, "%s : %d ", "hello from ESP32 (QOS0)", i++);
        char *payload = (char*)param;
        printf("Payload sent to AWS IOT: %s", payload);
        printf("Size of: %i/n", sizeof(payload));
        sprintf(cPayload, "%s", payload);

        paramsQOS0.payloadLen = strlen(cPayload);
        rc = aws_iot_mqtt_publish(&client, TOPIC, TOPIC_LEN, &paramsQOS0);
        if (rc == MQTT_REQUEST_TIMEOUT_ERROR) {
            ESP_LOGW(TAG, "QOS1 publish ack not received.");
            rc = SUCCESS;
        }
}
and my call to this function in app_main() is

Code: Select all

char *filename = (char*)"/spiffs/mpu_6050.txt";
char *content = readFile(filename);
xTaskCreate(&aws_iot_task, "aws_iot_task", 9216, (void*)content, 5, NULL);
What am I doing wrong here?

User avatar
kolban
Posts: 1683
Joined: Mon Nov 16, 2015 4:43 pm
Location: Texas, USA

Re: Sending payload to AWS IOT using MQTT causes an error

Postby kolban » Tue Aug 14, 2018 4:54 pm

If I were to guess, the puzzle is a memory over-run. If I am reading your code correctly, "param" is an input string which you then create an alias called "payload" to point to it. You then copy the string pointed to by "payload" into an array called "cPayload".

This is all guess work based on looking at the AWS IoT sample found here:

https://github.com/espressif/esp-idf/bl ... h_sample.c

(If I may suggest, please try and create posts that assume minimal knowledge from the readers ... I had to go find this example).

My guess is that the default value of cPayload is an array of:

char cPayload[100];

Is it possible that your string payload is > 99 bytes?
Free book on ESP32 available here: https://leanpub.com/kolban-ESP32

sheikhumar93
Posts: 13
Joined: Fri Aug 10, 2018 7:47 am

Re: Sending payload to AWS IOT using MQTT causes an error

Postby sheikhumar93 » Tue Aug 14, 2018 6:21 pm

Hi kolban, sorry for not adding the example link in my post and thank you for the reply.
You were right, cPayload was defined as

Code: Select all

char cPayload[100]
I got rid of all the C code and wrote new code to send the payload inspired by your own aws_iot cpp utility over here: https://github.com/nkolban/esp32-snippe ... ls/AWS.cpp.

Now my code looks like this:

Code: Select all

char *payload = (char*)param
std::string cPayload = payload;
paramsQOS0.qos = QOS0;
paramsQOS0.payload = (void *)cPayload.data();
paramsQOS0.isRetained = 0;
while((NETWORK_ATTEMPTING_RECONNECT == rc || NETWORK_RECONNECTED == rc || SUCCESS == rc)) {
  //Max time the yield function will wait for read messages
  rc = aws_iot_mqtt_yield(&client, 100);
  if(NETWORK_ATTEMPTING_RECONNECT == rc) {
    // If the client is attempting to reconnect we will skip the rest of the loop.
     continue;
   }
   ESP_LOGI(TAG, "Stack remaining for task '%s' is %d bytes", pcTaskGetTaskName(NULL), uxTaskGetStackHighWaterMark(NULL));
  vTaskDelay(1000 / portTICK_RATE_MS);
  paramsQOS0.payloadLen = cPayload.length();
  rc = aws_iot_mqtt_publish(&client, TOPIC, TOPIC_LEN, &paramsQOS0);
  if (rc == MQTT_REQUEST_TIMEOUT_ERROR) {
    ESP_LOGW(TAG, "QOS1 publish ack not received.");
    rc = SUCCESS;
  }
}
but I still get the same error as before. Any ideas?

User avatar
fly135
Posts: 606
Joined: Wed Jan 03, 2018 8:33 pm
Location: Orlando, FL

Re: Sending payload to AWS IOT using MQTT causes an error

Postby fly135 » Tue Aug 14, 2018 6:27 pm

If you look at his printout the payload is definitely over 100 bytes. Each line in his printout is almost 50 char and there are over 10 lines. His print of the size is a clue that he's not aware of what he is doing. Either that or he just screwed up and isn't paying attention. I do that a lot. :lol:

Unfortunately he makes the same mistake a lot of people do... Ask what's wrong with their code, but not provide enough code to make that determination.

John A

User avatar
fly135
Posts: 606
Joined: Wed Jan 03, 2018 8:33 pm
Location: Orlando, FL

Re: Sending payload to AWS IOT using MQTT causes an error

Postby fly135 » Tue Aug 14, 2018 6:29 pm

Change this....

printf("Size of: %i/n", sizeof(payload));

to this...

printf("Size of: %i/n", strlen(payload));

And your problem will become more obvious.

sheikhumar93
Posts: 13
Joined: Fri Aug 10, 2018 7:47 am

Re: Sending payload to AWS IOT using MQTT causes an error

Postby sheikhumar93 » Tue Aug 14, 2018 6:45 pm

Yeah I have changed this to strlen and found out the mistake, strlen returned 590, thats way over 100 bytes. But now I have updated the code where instead of using a C char[] I now use a C++ string as mentioned in my updated code. But the same problem still persists.

User avatar
kolban
Posts: 1683
Joined: Mon Nov 16, 2015 4:43 pm
Location: Texas, USA

Re: Sending payload to AWS IOT using MQTT causes an error

Postby kolban » Tue Aug 14, 2018 6:50 pm

I have always found it useful to determine the exact line where an exception is being thrown. An advanced used might use JTAG source level debugging but quick and simple debugging, I sprinkle printf() statements and flush(stdout) into the code. This means that I can see the steps executing each statement. There would be a last debug line before the failing statement and now I have good faith of where the failure was encountered. It is likely that if we can exactly which line is failing that will give us the clue as to what might be amiss.
Free book on ESP32 available here: https://leanpub.com/kolban-ESP32

sheikhumar93
Posts: 13
Joined: Fri Aug 10, 2018 7:47 am

Re: Sending payload to AWS IOT using MQTT causes an error

Postby sheikhumar93 » Tue Aug 14, 2018 8:03 pm

Hey kolban, I have narrowed down the error message that is the source of this problem, I have thrown in the printf flush(stdout) like you recommended, thanks for the tip. rc returns a value of -33 after this line:

Code: Select all

rc = aws_iot_mqtt_publish(&client, TOPIC, TOPIC_LEN, &paramsQOS0);
I looked around at the aws_iot_error.h file over here https://github.com/aws/aws-iot-device-s ... ot_error.h it says this: "The MQTT TX buffer is too short for the outgoing message. Request will fail". I then proceeded to solve this issue by increasing my "AWS_IOT_MQTT_TX_BUF_LEN" in make menuconfig. According to this file https://github.com/espressif/esp-idf/bl ... ot/Kconfig it says for AWS_IOT_MQTT_TX_BUF_LEN the range is 32-65536, I entered 1000 and it works, my sensor readings get posted to AWS Iot (Yayyyy!! :lol:). But when I enter a higher number lets say 10000 or 65536, the program crashes with the error:

Code: Select all

***ERROR*** A stack overflow in task aws_iot_task has been detected.
Is this value dependent on some other value which I am missing? How do I figure out the maximum number that is allowed for this?

User avatar
fly135
Posts: 606
Joined: Wed Jan 03, 2018 8:33 pm
Location: Orlando, FL

Re: Sending payload to AWS IOT using MQTT causes an error

Postby fly135 » Tue Aug 14, 2018 8:34 pm

Show us the code defining your client variable. I'm guessing it's on the stack. Which is where no variable should be declared unless you have a handle on it's size.

John A

User avatar
kolban
Posts: 1683
Joined: Mon Nov 16, 2015 4:43 pm
Location: Texas, USA

Re: Sending payload to AWS IOT using MQTT causes an error

Postby kolban » Tue Aug 14, 2018 9:28 pm

In the sample code that you referenced, there is a line in app_main which reads()

xTaskCreatePinnedToCore(&aws_iot_task, "aws_iot_task", 9216, NULL, 5, NULL, 1);

This says that your task (aws_iot_task) has a stack size of 9K. This is why we are breaking. The solution is to either allocate more stack space for the stack or allocate your data on the heap using functions like malloc() and free().
Free book on ESP32 available here: https://leanpub.com/kolban-ESP32

Who is online

Users browsing this forum: mike_dawes and 70 guests