Question: Use of Optional Argument in asyncHTTPRequest::onReadyStateChange()
lbussy opened this issue · 1 comments
Bob,
I need to say I understand that this is my problem, not yours - I'm just hoping you have time to give me a pointer. This is sort of a follow-up to Question: Identifying Caller in Callback #25. Basically, I have 1-N request types which I might be using and hope to re-use a function that actually sends the data. The callback needs to know the calling function's context in order to meet my needs.
The plan was to pass a variable to the callback, and thereby identify which report it is that's being handled. The only way I am able to do this is by &reference
. When I do that, the original variable goes out of scope from the caller. I can prove that by adding a delay()
in my calling function so that it's still "alive" when the callback fires.
Here's my header:
#ifndef _MYASYNC_H
#define _MYASYNC_H
#include <asyncHTTPrequest.h>
#include <AsyncTCP.h>
#include <ArduinoLog.h>
#include <Arduino.h>
enum ReportKey
{
MY_REPORT0,
MY_REPORT1,
MY_REPORT2,
MY_REPORT3,
MY_REPORT4
};
void sendRequest();
void requestCB(void *, asyncHTTPrequest *, int);
#endif // _MYASYNC_H
And the code:
#include "myAsync.h"
asyncHTTPrequest
request0,
request1,
request2,
request3,
request4;
asyncHTTPrequest reports[5] = {
request0,
request1,
request2,
request3,
request4
};
const char *reporttype[5] = {
"request0",
"request1",
"request2",
"request3",
"request4"
};
const char *reportname[5] = {
"Request 0",
"Request 1",
"Request 2",
"Request 3",
"Request 4"
};
void sendRequest()
{
ReportKey reportkey = MY_REPORT0;
//reports[reportkey].setDebug(true);
Log.verbose(F("DEBUG: Sending: '%s' report (%d)." CR), reportname[reportkey], reportkey);
reports[reportkey].onReadyStateChange(requestCB, &reportkey);
if (reports[reportkey].readyState() == 0 || reports[reportkey].readyState() == 4)
{
reports[reportkey].open("GET", "http://1.1.1.1/");
reports[reportkey].send();
}
}
void requestCB(void *optParm, asyncHTTPrequest *request, int readyState)
{
if (readyState == 4)
{
ReportKey reportkey = *(ReportKey*)optParm;
// const int *__attribute__((unused)) reportkey = static_cast<const int *>(optParm);
//const char *__attribute__((unused)) thisReport = (reportkey >= 0 && reportkey <= 4) ? reportname[reportkey] : "";
const int __attribute__((unused)) code = (request->responseHTTPcode() >= 0 && request->responseHTTPcode() <= 599) ? request->responseHTTPcode() : 0;
const int __attribute__((unused)) elapsed = (request->elapsedTime() >= 0) ? request->elapsedTime() : 0;
const char *__attribute__((unused)) response = (request->responseText()) ? request->responseText().c_str(): "";
Log.verbose(F("DEBUG: Return Code: %d, Elapsed: %d, reportkey: '%d'." CR), code, elapsed, reportkey);
}
}
The results are (predictably) inconsistent:
428858 V: DEBUG: Return Code: 301, Elapsed: 26, reportkey: '0'.
433831 V: DEBUG: Sending: 'Request 0' report (0).
433860 V: DEBUG: Return Code: 301, Elapsed: 27, reportkey: '397088'.
438831 V: DEBUG: Sending: 'Request 0' report (0).
438854 V: DEBUG: Return Code: 301, Elapsed: 22, reportkey: '1073431156'.
443831 V: DEBUG: Sending: 'Request 0' report (0).
443851 V: DEBUG: Return Code: 301, Elapsed: 19, reportkey: '0'.
I understand why, but since you have this functionality there I'm relatively certain what I need is possible and I'm just too dense to get it. Any assistance would be appreciated.
- Lee
Well, I got around this by using a pointer function to the callbacks and then having the callbacks in turn call the handler. Seems inelegant but it is working.