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

Changes to el-client to cope with REST replies longer than 100 bytes #37

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions ELClient/ELClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,26 @@ ELClientPacket* ELClient::protoCompletedCb(void) {
_debug->print("RESP_V: ");
_debug->println(packet->value);
}
_longPacket = 0;
return packet;
case CMD_RESP_CB_CONTINUE:
// response callback, but one of the parts of a long packet --> just prepare assembly
// Currently just a copy (without notes) of the code below...

{
// Serial.print("CMD_RESP_CB_CONTINUE\n");
_longPacket = 1;
FP<void, void*> *fp;
fp = (FP<void, void*>*)packet->value;
if (fp->attached()) {
ELClientResponse resp(packet);
(*fp)(&resp);
}
return NULL;
}

case CMD_RESP_CB: // response callback: perform the callback!
{
FP<void, void*> *fp;
// callback reponse
if (_debugEn) {
Expand All @@ -75,12 +93,15 @@ ELClientPacket* ELClient::protoCompletedCb(void) {
_debug->print(" ");
_debug->println(packet->argc);
}

_longPacket = 0;
fp = (FP<void, void*>*)packet->value;
if (fp->attached()) {
ELClientResponse resp(packet);
(*fp)(&resp);
}
return NULL;
}
case CMD_SYNC: // esp-link is not in sync, it may have reset, signal up the stack
_debug->println("NEED_SYNC!");
if (resetCb != NULL) (*resetCb)();
Expand Down
4 changes: 4 additions & 0 deletions ELClient/ELClient.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ typedef enum {

CMD_SOCKET_SETUP = 40, /**< Setup socket connection */
CMD_SOCKET_SEND, /**< Send socket packet */

CMD_RESP_CB_CONTINUE = 70, // RESP_CB for a long packet

} CmdName; /**< Enumeration of commands supported by esp-link, this needs to match the definition in esp-link! */

enum WIFI_STATUS {
Expand Down Expand Up @@ -126,6 +129,7 @@ class ELClient {
uint16_t crc; /**< CRC checksum */
ELClientProtocol _proto; /**< Protocol structure */
uint8_t _protoBuf[128]; /**< Protocol buffer */
uint16_t _longPacket; /**< Packet length in case of long packet */

void init();
void DBG(const char* info);
Expand Down
85 changes: 79 additions & 6 deletions ELClient/ELClientRest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,26 @@ void ELClientRest::restCallback(void *res)

ELClientResponse *resp = (ELClientResponse *)res;

resp->popArg(&_status, sizeof(_status));
if (_elc->_debugEn) {
_elc->_debug->print("REST code ");
_elc->_debug->println(_status);
}
if (_elc->_longPacket == 0) {
resp->popArg(&_status, sizeof(_status));

if (_elc->_debugEn) {
_elc->_debug->print("REST code ");
_elc->_debug->println(_status);
}

_len = resp->popArgPtr(&_data);

_len = resp->popArgPtr(&_data);
// Serial.print("restCallback status "); Serial.print(_status); Serial.print(", len "); Serial.println(_len);
} else {
int16_t lp;
resp->popArg(&lp, sizeof(lp));
_elc->_longPacket = lp;
_status = 200; // Hack
_len = resp->popArgPtr(&_data);

// Serial.print("restCallback LONG totalLength "); Serial.print(_elc->_longPacket); Serial.print(", len "); Serial.println(_len);
}
}

/*! begin(const char* host, uint16_t port, boolean security)
Expand Down Expand Up @@ -379,3 +392,63 @@ uint16_t ELClientRest::waitResponse(char* data, uint16_t maxLen, uint32_t timeou
}
return getResponse(data, maxLen);
}

/*! waitResponse2(char* data, uint16_t maxLen, uint32_t timeout, uint16_t *totalLength, uint16_t packetLength)
@brief Wait for the response, cope with long packets
@details Wait for the response from the remote server for <code>time_out</code>,
returns the HTTP status code, 0 if no response (may need to wait longer)
@warning Blocks the Arduino code for 5 seconds! not recommended to use.
Received packet is NOT null-terminated
@param data
Pointer to buffer for received packet
@param maxLen
Size of buffer for received packet. If the received packet is larger than the buffer, the received packet will be truncated.
@param timeout
Timout in milli seconds to wait for a response.
@param totalLength
if non-NULL, used to return the total length of the multi-packet data
@param packetLength
if non-NULL, used to return the length of this chunk of data (typically 100 if not the last packet)
@return <code>uint16_t</code>
Size of received packet or number of sent bytes or 0 if no response
@par Example
@code
static char *buf = 0;
static int bufsiz = 700;
buf = (char *)malloc(bufsiz);
uint16_t datalen = 0, packetlen = 0;
memset(buf, 0, bufsiz);
char *ptr = buf;
err = rest->waitResponse2(ptr, bufsiz-1, DEFAULT_REST_TIMEOUT, &datalen, &packetlen);
while (datalen) {
ptr += packetlen;
err = rest->waitResponse2(ptr, bufsiz-1, DEFAULT_REST_TIMEOUT, &datalen, &packetlen);
}
...
free(buf);
buf = 0;
@endcode
*/
uint16_t ELClientRest::waitResponse2(char* data, uint16_t maxLen, uint16_t *totalLength, uint16_t *packetLength, uint32_t timeout)
{
uint32_t wait = millis();
while (_status == 0 && (millis() - wait < timeout)) {
_elc->Process();
}
return getResponse2(data, maxLen, totalLength, packetLength);
}

uint16_t ELClientRest::getResponse2(char* data, uint16_t maxLen, uint16_t *totalLength, uint16_t *packetLength)
{
if (_status == 0)
return 0;
if (totalLength != 0)
*totalLength = _elc->_longPacket;
if (packetLength != 0)
*packetLength = _len;
memcpy(data, _data, _len>maxLen?maxLen:_len);
int16_t s = _status;
_status = 0;
return s;
}

2 changes: 2 additions & 0 deletions ELClient/ELClientRest.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,13 @@ class ELClientRest {
// Retrieve the response from the remote server, returns the HTTP status code, 0 if no
// response (may need to wait longer)
uint16_t getResponse(char* data, uint16_t maxLen);
uint16_t getResponse2(char* data, uint16_t maxLen, uint16_t *totalLength, uint16_t *packetLength);

// Wait for the response from the remote server, returns the HTTP status code, 0 if no
// response (timeout occurred). This is not recommended except for quick demos, use
// getResponse periodically instead.
uint16_t waitResponse(char* data, uint16_t maxLen, uint32_t timeout=DEFAULT_REST_TIMEOUT);
uint16_t waitResponse2(char* data, uint16_t maxLen, uint16_t *totalLength, uint16_t *packetLength, uint32_t timeout = DEFAULT_REST_TIMEOUT);

// Set the user-agent for all subsequent requests
void setUserAgent(const char* value);
Expand Down