I am doing some HTTP and HTTPS GET requests and I find that with one site that I am accessing that the code hangs while negotiating the Secure connection regardless of setting the timeouts. I have tried several libraries for doing this without success so I tried to put the code in a task and then check completion or kill the task. The problem is that the code works fine outside of the task but the task crashes when trying to return with an illegal instruction panic. At first this looks like it was occcuring in the String library so I rewrote the code to not use any Strings but it still crashed and implicated the string library so I think the traceback is junk and not really indicating the failure. The entry point I am calling is near the bottom => String HTTPget()
Here is the code with the tasking commented out. If I switch it to use the task it will crash. The code is a little cluttered with debug prints but I commented them all out to get the bare minimum. Any ideas on what I am doing wrong?
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include "ArduinoTimer.h"
struct TaskParameters {
const char* param1;
const char* param2;
const char* param3;
uint16_t param4;
int param5;
int param6;
HTTPClient* param7; // Add an additional parameter for the client instance
};
String payload = ""; // response string from GET
void taskHTTPget(void* parameters) {
TaskParameters* taskParams = reinterpret_cast<TaskParameters*>(parameters);
const char* callerName = taskParams->param1;
const char* request = taskParams->param2;
const char* server = taskParams->param3;
uint16_t port = taskParams->param4;
int connectionTimeout = taskParams->param5;
int responseTimeout = taskParams->param6;
HTTPClient* http = taskParams->param7; // Add an additional parameter for the client instance
//logDebug("HTTPget debugWDT");
// HTTPClient http;
payload = ""; // response string from GET
String Request = String(server) + ":" + String(port) + String(request);
//Serial.println(Request); // debug print
//Serial.print(" http->begin ");
unsigned long httpStart = millis(); // time how long the GET takes
http->setConnectTimeout(connectionTimeout); // set times out to fix issues with NINA timeout
http->begin(Request);
//logDebug("HTTPget debugWDT http->begin");
http->setTimeout(responseTimeout); // set timeout on GET
//logDebug("HTTPget debugWDT http->setTimeout");
int httpCode = http->GET(); // start connection and send HTTP header
//logDebug("HTTPget debugWDT http->GET complete");
//Serial.printf("GET %s Finished %dms ", Request.c_str(), millis() - httpStart);
if (httpCode > 0) { // httpCode will be negative on error
//Serial.printf("[HTTP] GET... code: %7d \n", httpCode); // HTTP header has been send and Server response header has been handled
if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_ACCEPTED) { // file found at server
//Serial.println("HTTPget called by " + String(callerName) + " " + Request + " " + "OK"); // GET OK
//logError("HTTPget called by " + String(callerName) + " " + Request + " " + "OK");
payload = http->getString(); // Get the JSON String
//Serial.println(payload); // Print the JSON String
} else {
//Serial.printf("HTTPget called by %s %s failed code=%d, error: %s \n", callerName, Request.c_str(), httpCode, http->errorToString(httpCode).c_str());
//logError("HTTPget called by " + String(callerName) + " " + Request + " " + http->errorToString(httpCode));
}
} else {
//Serial.printf("HTTPget called by %s [HTTP] GET... failed code=%d, error: %s \n", callerName, httpCode, http->errorToString(httpCode).c_str());
//logError("HTTPget called by " + String(callerName) + " " + Request + " " + http->errorToString(httpCode));
}
http->end(); // close the connection
//Serial.println("EXIT taskHTTPget");
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
String HTTPget(const char* callerName, const char* request, const char* server, uint16_t port, int connectionTimeout, int responseTimeout) {
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
ArduinoTimer getTimer;
TaskParameters taskParams;
TaskHandle_t taskHandle;
HTTPClient client; // Create the WiFiClient instance
taskParams.param1 = callerName;
taskParams.param2 = request;
taskParams.param3 = server;
taskParams.param4 = port;
taskParams.param5 = connectionTimeout;
taskParams.param6 = responseTimeout + 200;
taskParams.param7 = &client;
// Rest of the code remains the same
// Pass the client instance to the task parameters
taskParams.param7 = &client;
payload = "";
Serial.printf("HTTPSget called by %s %s%s port %d %d\n", callerName, server, request, port, connectionTimeout, responseTimeout);
getTimer.Reset();
// esp_task_wdt_init(responseTimeout, true); // Initialize the watchdog timer
// BaseType_t taskCreationResult = xTaskCreate( // Create the task and pass the parameters
// taskHTTPget, // Task function
// "taskHTTPget", // Task name (for debugging)
// 5000, // Stack size (in words) 20,000 bytes
// &taskParams, // Task parameters
// 1, // Task priority
// &taskHandle // Task handle (optional)
// );
// if (taskCreationResult == pdPASS) Serial.println("Task Creation Succeeded");
// else Serial.println("Task Creation Failed");
taskHTTPget(&taskParams);
// while (payload.isEmpty() && !getTimer.TimePassed_Milliseconds(responseTimeout)) {
// Serial.print(".");
// esp_task_wdt_reset(); // feed the dog
// waitMilliseconds(100);
// }
Serial.printf("exit HTTPget payload == "".isEmpty= %d getTimer.TimePassed_Milliseconds(responseTimeout)=%d getTimer.EllapsedMilliseconds()=%d\n payload=%s\n", payload == "",
getTimer.TimePassed_Milliseconds(responseTimeout), getTimer.EllapsedMilliseconds(),payload.c_str());
// if (uxTaskGetNumberOfTasks() > 0 && eTaskGetState(taskHandle) != eDeleted) vTaskDelete(taskHandle); // Check if the task is still running
return String(payload);
}