Skip to content

Commit 979cc4a

Browse files
Add XBeeWithCallbacks::waitForStatus()
This method loops until a status response is received (e.g. a AtCommandResponse, TxResponse, etc.) to greatly simplify getting the result of a command sent. While waiting, any other responses are processed by the callbacks as normal, so no response gets lost while waiting. A matchStatus() helper method is introduced, preparing to reuse it in a future commit.
1 parent 5963bea commit 979cc4a

File tree

2 files changed

+78
-0
lines changed

2 files changed

+78
-0
lines changed

XBee.cpp

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1671,3 +1671,44 @@ void XBeeWithCallbacks::loopBottom() {
16711671
if (!called)
16721672
_onOtherResponse.call(getResponse());
16731673
}
1674+
1675+
uint8_t XBeeWithCallbacks::matchStatus(uint8_t frameId) {
1676+
uint8_t id = getResponse().getApiId();
1677+
uint8_t *data = getResponse().getFrameData();
1678+
uint8_t len = getResponse().getFrameDataLength();
1679+
uint8_t offset = 0;
1680+
1681+
// Figure out if this frame has a frameId and if so, where the
1682+
// status byte to return is located
1683+
if (id == AT_COMMAND_RESPONSE)
1684+
offset = 3;
1685+
else if (id == REMOTE_AT_COMMAND_RESPONSE)
1686+
offset = 13;
1687+
else if (id == TX_STATUS_RESPONSE)
1688+
offset = 1;
1689+
else if (id == ZB_TX_STATUS_RESPONSE)
1690+
offset = 4;
1691+
1692+
// If this is an API frame that contains a status, the frame is
1693+
// long enough to contain it and the frameId matches the one
1694+
// given, return the status byte
1695+
if (offset && offset < len && data[0] == frameId)
1696+
return data[offset];
1697+
return 0xff;
1698+
}
1699+
1700+
uint8_t XBeeWithCallbacks::waitForStatus(uint8_t frameId, uint16_t timeout) {
1701+
unsigned long start = millis();
1702+
do {
1703+
if (loopTop()) {
1704+
uint8_t status = matchStatus(frameId);
1705+
if (status != 0xff)
1706+
return status;
1707+
1708+
// Call regular callbacks
1709+
loopBottom();
1710+
}
1711+
} while (millis() - start < timeout);
1712+
return XBEE_WAIT_TIMEOUT ;
1713+
}
1714+

XBee.h

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,8 @@
123123
#define ADDRESS_NOT_FOUND 0x24
124124
#define ROUTE_NOT_FOUND 0x25
125125
#define PAYLOAD_TOO_LARGE 0x74
126+
// Returned by XBeeWithCallbacks::waitForStatus on timeout
127+
#define XBEE_WAIT_TIMEOUT 0xff
126128

127129
// modem status
128130
#define HARDWARE_RESET 0
@@ -884,7 +886,42 @@ class XBeeWithCallbacks : public XBee {
884886
* buffer is processed and the appropriate callbacks are called.
885887
*/
886888
void loop();
889+
890+
/**
891+
* Wait for a status API response with the given frameId and
892+
* return the status from the packet (for ZB_TX_STATUS_RESPONSE,
893+
* this returns just the delivery status, not the routing
894+
* status). If the timeout is reached before reading the
895+
* response, XBEE_WAIT_TIMEOUT is returned instead.
896+
*
897+
* While waiting, any other responses received are passed to the
898+
* relevant callbacks, just as if calling loop() continuously
899+
* (except for the status response sought, that one is only
900+
* passed to the OnResponse handler and no others).
901+
*
902+
* After this method returns, the response itself can still be
903+
* retrieved using getResponse() as normal.
904+
*/
905+
uint8_t waitForStatus(uint8_t frameId, uint16_t timeout);
887906
private:
907+
/**
908+
* Internal version of waitFor that does not need to be
909+
* templated (to prevent duplication the implementation for
910+
* every response type you might want to wait for). Instead of
911+
* using templates, this accepts the apiId to wait for and will
912+
* cast the given response object and the argument to the given
913+
* function to the corresponding type. This means that the
914+
* void* given must match the api id!
915+
*/
916+
bool waitForInternal(uint8_t apiId, void *response, uint16_t timeout, void *func, uintptr_t data);
917+
918+
/**
919+
* Helper that checks if the current response is a status
920+
* response with the given frame id. If so, returns the status
921+
* byte from the response, otherwise returns 0xff.
922+
*/
923+
uint8_t matchStatus(uint8_t frameId);
924+
888925
/**
889926
* Top half of a typical loop(). Calls readPacket(), calls
890927
* onPacketError on error, calls onResponse when a response is

0 commit comments

Comments
 (0)