improve GEX_Poll() to wait for the correct response, not only "one frame rx'd"

master
Ondřej Hruška 7 years ago
parent bdc91c2ded
commit cf4314f1d8
Signed by: MightyPork
GPG Key ID: 2C5FD5035250423D
  1. 23
      gex/gex_client.c
  2. 3
      gex/gex_client.h
  3. 1
      gex/gex_internal.h
  4. 2
      gex/gex_unit.c
  5. 9
      gex/protocol/TinyFrame.c

@ -8,7 +8,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <utils/hexdump.h>
#include "TinyFrame.h" #include "TinyFrame.h"
#define GEX_H // to allow including other headers #define GEX_H // to allow including other headers
@ -17,6 +17,7 @@
#include "gex_internal.h" #include "gex_internal.h"
#include "gex_message_types.h" #include "gex_message_types.h"
#include "utils/payload_parser.h" #include "utils/payload_parser.h"
#include "utils/hexdump.h"
/** Delete recursively all GEX callsign look-up table entries */ /** 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; tail = lu;
} }
gex->units_loaded = true;
return TF_CLOSE; return TF_CLOSE;
} }
@ -195,7 +198,7 @@ GexClient *GEX_Init(const char *device, uint32_t timeout_ms)
TF_QuerySimple(gex->tf, MSG_PING, TF_QuerySimple(gex->tf, MSG_PING,
NULL, 0, NULL, 0,
connectivity_check_lst, 0); connectivity_check_lst, 0);
GEX_Poll(gex); GEX_Poll(gex, &gex->connected);
if (!gex->connected) { if (!gex->connected) {
fprintf(stderr, "GEX doesn't respond to ping!\n"); 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, TF_QuerySimple(gex->tf, MSG_LIST_UNITS,
NULL, 0, NULL, 0,
list_units_lst, 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. // 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); 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 */ /** 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]; static uint8_t pollbuffer[TF_MAX_PAYLOAD_RX];
@ -228,7 +231,7 @@ void GEX_Poll(GexClient *gex)
bool first = true; bool first = true;
#define MAX_RETRIES 10 #define MAX_RETRIES 15
int cycle = 0; int cycle = 0;
do { do {
@ -261,7 +264,17 @@ void GEX_Poll(GexClient *gex)
} }
} else { } else {
// nothing more received and TF is in the base state, we're done. // nothing more received and TF is in the base state, we're done.
if (done_flag != NULL) {
if (*done_flag == true) {
break; break;
} else {
cycle++;
first=true;
if (cycle >= MAX_RETRIES) break;
}
} else {
break;
}
} }
} }
else { else {

@ -70,8 +70,9 @@ GexClient *GEX_Init(const char *device, uint32_t timeout_ms);
/** /**
* Poll for new messages * Poll for new messages
* @param gex - client * @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() * 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 (?) const char *acm_device; //!< Comport device name, might be used to reconnect (?)
int acm_fd; //!< Open comport file descriptor int acm_fd; //!< Open comport file descriptor
bool connected; //!< Flag that we're currently connected to the comport 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() uint32_t ser_timeout; //!< Timeout for read()/write()
// synchronous query "hacks" // synchronous query "hacks"

@ -144,7 +144,7 @@ GexMsg GEX_QueryEx(GexUnit *unit, uint8_t cmd,
session, is_reply, sync_query_lst, session, is_reply, sync_query_lst,
NULL /*userdata2*/, raw_pld); NULL /*userdata2*/, raw_pld);
GEX_Poll(gex); GEX_Poll(gex, &gex->squery_ok);
if (!gex->squery_ok) { if (!gex->squery_ok) {
fprintf(stderr, "No response to query of unit %s!\n", unit->name); 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; TF_Result res;
// Prepare message object // Prepare message object
TF_Msg msg; TF_Msg msg = {};
TF_ClearMsg(&msg);
msg.frame_id = tf->id; msg.frame_id = tf->id;
msg.is_response = false; msg.is_response = false;
msg.type = tf->type; msg.type = tf->type;
@ -801,8 +800,7 @@ bool _TF_FN TF_Send(TinyFrame *tf, TF_Msg *msg)
/** send without listener and struct */ /** send without listener and struct */
bool _TF_FN TF_SendSimple(TinyFrame *tf, TF_TYPE type, const uint8_t *data, TF_LEN len) bool _TF_FN TF_SendSimple(TinyFrame *tf, TF_TYPE type, const uint8_t *data, TF_LEN len)
{ {
TF_Msg msg; TF_Msg msg = {};
TF_ClearMsg(&msg);
msg.type = type; msg.type = type;
msg.data = data; msg.data = data;
msg.len = len; 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 */ /** 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) 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_Msg msg = {};
TF_ClearMsg(&msg);
msg.type = type; msg.type = type;
msg.data = data; msg.data = data;
msg.len = len; msg.len = len;

Loading…
Cancel
Save