improve GEX_Poll() to wait for the correct response, not only "one frame rx'd"
This commit is contained in:
+19
-6
@@ -8,7 +8,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <utils/hexdump.h>
|
||||
|
||||
#include "TinyFrame.h"
|
||||
|
||||
#define GEX_H // to allow including other headers
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "gex_internal.h"
|
||||
#include "gex_message_types.h"
|
||||
#include "utils/payload_parser.h"
|
||||
#include "utils/hexdump.h"
|
||||
|
||||
|
||||
/** Delete recursively all GEX callsign look-up table entries */
|
||||
@@ -112,6 +113,8 @@ static TF_Result list_units_lst(TinyFrame *tf, TF_Msg *msg)
|
||||
tail = lu;
|
||||
}
|
||||
|
||||
gex->units_loaded = true;
|
||||
|
||||
return TF_CLOSE;
|
||||
}
|
||||
|
||||
@@ -195,7 +198,7 @@ GexClient *GEX_Init(const char *device, uint32_t timeout_ms)
|
||||
TF_QuerySimple(gex->tf, MSG_PING,
|
||||
NULL, 0,
|
||||
connectivity_check_lst, 0);
|
||||
GEX_Poll(gex);
|
||||
GEX_Poll(gex, &gex->connected);
|
||||
|
||||
if (!gex->connected) {
|
||||
fprintf(stderr, "GEX doesn't respond to ping!\n");
|
||||
@@ -208,7 +211,7 @@ GexClient *GEX_Init(const char *device, uint32_t timeout_ms)
|
||||
TF_QuerySimple(gex->tf, MSG_LIST_UNITS,
|
||||
NULL, 0,
|
||||
list_units_lst, 0);
|
||||
GEX_Poll(gex);
|
||||
GEX_Poll(gex, &gex->units_loaded);
|
||||
|
||||
// Bind the catch-all event handler. Will be re-distributed to individual unit listeners if needed.
|
||||
TF_AddTypeListener(gex->tf, MSG_UNIT_REPORT, unit_report_lst);
|
||||
@@ -220,7 +223,7 @@ GexClient *GEX_Init(const char *device, uint32_t timeout_ms)
|
||||
}
|
||||
|
||||
/** Try to read from the serial port and process any received bytes with TF */
|
||||
void GEX_Poll(GexClient *gex)
|
||||
void GEX_Poll(GexClient *gex, const volatile bool *done_flag)
|
||||
{
|
||||
static uint8_t pollbuffer[TF_MAX_PAYLOAD_RX];
|
||||
|
||||
@@ -228,7 +231,7 @@ void GEX_Poll(GexClient *gex)
|
||||
|
||||
bool first = true;
|
||||
|
||||
#define MAX_RETRIES 10
|
||||
#define MAX_RETRIES 15
|
||||
|
||||
int cycle = 0;
|
||||
do {
|
||||
@@ -261,7 +264,17 @@ void GEX_Poll(GexClient *gex)
|
||||
}
|
||||
} else {
|
||||
// nothing more received and TF is in the base state, we're done.
|
||||
break;
|
||||
if (done_flag != NULL) {
|
||||
if (*done_flag == true) {
|
||||
break;
|
||||
} else {
|
||||
cycle++;
|
||||
first=true;
|
||||
if (cycle >= MAX_RETRIES) break;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
+2
-1
@@ -70,8 +70,9 @@ GexClient *GEX_Init(const char *device, uint32_t timeout_ms);
|
||||
/**
|
||||
* Poll for new messages
|
||||
* @param gex - client
|
||||
* @param done_flag - if given (not NULL), checks flag for true before quitting. Flag should be set in the callback.
|
||||
*/
|
||||
void GEX_Poll(GexClient *gex);
|
||||
void GEX_Poll(GexClient *gex, const volatile bool *done_flag);
|
||||
|
||||
/**
|
||||
* Safely release all resources used up by GEX_Init()
|
||||
|
||||
@@ -21,6 +21,7 @@ struct gex_client {
|
||||
const char *acm_device; //!< Comport device name, might be used to reconnect (?)
|
||||
int acm_fd; //!< Open comport file descriptor
|
||||
bool connected; //!< Flag that we're currently connected to the comport
|
||||
bool units_loaded; //!< Units loaded flag for poll
|
||||
uint32_t ser_timeout; //!< Timeout for read()/write()
|
||||
|
||||
// synchronous query "hacks"
|
||||
|
||||
+1
-1
@@ -144,7 +144,7 @@ GexMsg GEX_QueryEx(GexUnit *unit, uint8_t cmd,
|
||||
session, is_reply, sync_query_lst,
|
||||
NULL /*userdata2*/, raw_pld);
|
||||
|
||||
GEX_Poll(gex);
|
||||
GEX_Poll(gex, &gex->squery_ok);
|
||||
|
||||
if (!gex->squery_ok) {
|
||||
fprintf(stderr, "No response to query of unit %s!\n", unit->name);
|
||||
|
||||
@@ -343,8 +343,7 @@ static void _TF_FN TF_HandleReceivedMessage(TinyFrame *tf)
|
||||
TF_Result res;
|
||||
|
||||
// Prepare message object
|
||||
TF_Msg msg;
|
||||
TF_ClearMsg(&msg);
|
||||
TF_Msg msg = {};
|
||||
msg.frame_id = tf->id;
|
||||
msg.is_response = false;
|
||||
msg.type = tf->type;
|
||||
@@ -801,8 +800,7 @@ bool _TF_FN TF_Send(TinyFrame *tf, TF_Msg *msg)
|
||||
/** send without listener and struct */
|
||||
bool _TF_FN TF_SendSimple(TinyFrame *tf, TF_TYPE type, const uint8_t *data, TF_LEN len)
|
||||
{
|
||||
TF_Msg msg;
|
||||
TF_ClearMsg(&msg);
|
||||
TF_Msg msg = {};
|
||||
msg.type = type;
|
||||
msg.data = data;
|
||||
msg.len = len;
|
||||
@@ -812,8 +810,7 @@ bool _TF_FN TF_SendSimple(TinyFrame *tf, TF_TYPE type, const uint8_t *data, TF_L
|
||||
/** send with a listener waiting for a reply, without the struct */
|
||||
bool _TF_FN TF_QuerySimple(TinyFrame *tf, TF_TYPE type, const uint8_t *data, TF_LEN len, TF_Listener listener, TF_TICKS timeout)
|
||||
{
|
||||
TF_Msg msg;
|
||||
TF_ClearMsg(&msg);
|
||||
TF_Msg msg = {};
|
||||
msg.type = type;
|
||||
msg.data = data;
|
||||
msg.len = len;
|
||||
|
||||
Reference in New Issue
Block a user