Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Question: Use of Optional Argument in asyncHTTPRequest::onReadyStateChange() #26

Closed
lbussy opened this issue Sep 14, 2020 · 1 comment
Closed

Comments

@lbussy
Copy link

lbussy commented Sep 14, 2020

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

@lbussy
Copy link
Author

lbussy commented Sep 18, 2020

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.

@lbussy lbussy closed this as completed Sep 18, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant