diff --git a/CMakeLists.txt b/CMakeLists.txt index 47d41f7..ac88997 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,7 +11,7 @@ set(SOURCE_FILES gex/gex_client.h gex/utils/hexdump.c gex/utils/hexdump.h - gex/protocol/TF_Integration.c + gex/TF_Integration.c gex/utils/payload_builder.c gex/utils/payload_builder.h gex/utils/payload_parser.c diff --git a/gex/protocol/TF_Integration.c b/gex/TF_Integration.c similarity index 82% rename from gex/protocol/TF_Integration.c rename to gex/TF_Integration.c index a14580b..fd0ee09 100644 --- a/gex/protocol/TF_Integration.c +++ b/gex/TF_Integration.c @@ -8,9 +8,10 @@ void TF_WriteImpl(TinyFrame *tf, const uint8_t *buff, size_t len) { - assert(gex_serial_fd != 0); // TODO update after TF has instances + GexClient *gc = tf->userdata; + assert(gc->acm_fd != 0); - ssize_t rv = write(gex_serial_fd, buff, len); + ssize_t rv = write(gc->acm_fd, buff, len); if (rv != len) { fprintf(stderr, "ERROR %d in TF write: %s\n", errno, strerror(errno)); } diff --git a/gex/gex_client.c b/gex/gex_client.c index 66a7f8e..052e13f 100644 --- a/gex/gex_client.c +++ b/gex/gex_client.c @@ -5,7 +5,6 @@ #include #include #include -#include #include #include #include @@ -14,88 +13,71 @@ #include "gex_client.h" #include "serial.h" -int gex_serial_fd = -1; - -/** ^C handler to close it gracefully */ -static void sigintHandler(int sig) +TF_Result connectivityCheckCb(TinyFrame *tf, TF_Msg *msg) { - if (gex_serial_fd != -1) { - close(gex_serial_fd); - } - exit(0); -} - -TF_Result connectivityCheckCb(TF_Msg *msg) -{ - GexClient *gc = msg->userdata; - gc->connected = true; - fprintf(stderr, "GEX connected! Version string: %.*s\n", msg->len, msg->data); - - msg->userdata = NULL; - return TF_CLOSE; + GexClient *gex = tf->userdata; + gex->connected = true; + fprintf(stderr, "GEX connected! Version string: %.*s\n", msg->len, msg->data); + return TF_CLOSE; } GexClient *GEX_Init(const char *device, int timeout_ms) { - assert(device != NULL); - - GexClient *gc = calloc(1, sizeof(GexClient)); - assert(gc != NULL); - - // Bind ^C handler for safe shutdown - signal(SIGINT, sigintHandler); - - // Open the device - gc->acm_device = device; - gc->acm_fd = serial_open(device, false, (timeout_ms+50)/100); - if (gc->acm_fd == -1) { - free(gc); - return NULL; - } - - gex_serial_fd = gc->acm_fd; - - // Test connectivity - TF_Msg msg; - TF_ClearMsg(&msg); - msg.type = 0x01; // TODO use constant - msg.userdata = gc; - TF_Query(&msg, connectivityCheckCb, 0); - GEX_Poll(gc); - - if (!gc->connected) { - fprintf(stderr, "GEX doesn't respond to ping!\n"); - GEX_DeInit(gc); - return NULL; - } - - // TODO load and store unit callsigns + names - - return gc; + assert(device != NULL); + + GexClient *gex = calloc(1, sizeof(GexClient)); + assert(gex != NULL); + + // Open the device + gex->acm_device = device; + gex->acm_fd = serial_open(device, false, (timeout_ms + 50) / 100); + if (gex->acm_fd == -1) { + free(gex); + return NULL; + } + + gex->tf = TF_Init(TF_MASTER); + gex->tf->userdata = gex; + + // Test connectivity + TF_Msg msg; + TF_ClearMsg(&msg); + msg.type = 0x01; // TODO use constant + TF_Query(gex->tf, &msg, connectivityCheckCb, 0); + GEX_Poll(gex); + + if (!gex->connected) { + fprintf(stderr, "GEX doesn't respond to ping!\n"); + GEX_DeInit(gex); + return NULL; + } + + // TODO load and store unit callsigns + names + + return gex; } -void GEX_Poll(GexClient *gc) +void GEX_Poll(GexClient *gex) { - static uint8_t pollbuffer[4096]; + uint8_t pollbuffer[1024]; - assert(gc != NULL); + assert(gex != NULL); - ssize_t len = read(gc->acm_fd, pollbuffer, 4096); - if (len < 0) { - fprintf(stderr, "ERROR %d in GEX Poll: %s\n", errno, strerror(errno)); - } else { -// hexDump("Received", pollbuffer, (uint32_t) len); - TF_Accept(pollbuffer, (size_t) len); - } + ssize_t len = read(gex->acm_fd, pollbuffer, 1024); + if (len < 0) { + fprintf(stderr, "ERROR %d in GEX Poll: %s\n", errno, strerror(errno)); + } else { + //hexDump("Received", pollbuffer, (uint32_t) len); + TF_Accept(gex->tf, pollbuffer, (size_t) len); + } } void GEX_DeInit(GexClient *gc) { - if (gc == NULL) return; - - close(gc->acm_fd); - gex_serial_fd = -1; - free(gc); + if (gc == NULL) return; + close(gc->acm_fd); + TF_DeInit(gc->tf); + free(gc); } diff --git a/gex/gex_client.h b/gex/gex_client.h index 057b057..1009c80 100644 --- a/gex/gex_client.h +++ b/gex/gex_client.h @@ -8,11 +8,13 @@ #include #include #include +#include "TinyFrame.h" struct gex_client_ { - const char *acm_device; - int acm_fd; - bool connected; + TinyFrame *tf; + const char *acm_device; + int acm_fd; + bool connected; }; typedef struct gex_client_ GexClient; @@ -28,9 +30,9 @@ GexClient *GEX_Init(const char *device, int timeout_ms); /** * Poll for new messages - * @param gc - client + * @param gex - client */ -void GEX_Poll(GexClient *gc); +void GEX_Poll(GexClient *gex); /** * Safely release all resources used up by GEX_Init() diff --git a/gex/protocol/TinyFrame.c b/gex/protocol/TinyFrame.c index 42c05d1..4ad41e7 100644 --- a/gex/protocol/TinyFrame.c +++ b/gex/protocol/TinyFrame.c @@ -169,6 +169,13 @@ TinyFrame * _TF_FN TF_Init(TF_Peer peer_bit) return tf; } +/** Release the struct */ +void TF_DeInit(TinyFrame *tf) +{ + if (tf == NULL) return; + free(tf); +} + //region Listeners /** Reset ID listener's timeout to the original value */ @@ -696,7 +703,7 @@ static size_t _TF_FN TF_ComposeBody(uint8_t *outbuff, * @param cksum - checksum variable used for the body * @return nr of bytes in outbuff used */ -static size_t _TF_FN TF_ComposeTail(uint8_t *outbuff, const TF_CKSUM *cksum) +static size_t _TF_FN TF_ComposeTail(uint8_t *outbuff, TF_CKSUM *cksum) { int8_t si = 0; // signed small int uint8_t b = 0; diff --git a/gex/protocol/TinyFrame.h b/gex/protocol/TinyFrame.h index 43eb016..a4d92df 100644 --- a/gex/protocol/TinyFrame.h +++ b/gex/protocol/TinyFrame.h @@ -10,7 +10,7 @@ * Upstream URL: https://github.com/MightyPork/TinyFrame */ -#define TF_VERSION "2.0.0" +#define TF_VERSION "2.0.1" //--------------------------------------------------------------------------- #include // for uint8_t etc @@ -235,6 +235,13 @@ TinyFrame *TF_Init(TF_Peer peer_bit); */ void TF_InitStatic(TinyFrame *tf, TF_Peer peer_bit); +/** + * De-init the dynamically allocated TF instance + * + * @param tf + */ +void TF_DeInit(TinyFrame *tf); + /** * Reset the frame parser state machine. * This does not affect registered listeners. diff --git a/main.c b/main.c index a4e2f6a..bf81c32 100644 --- a/main.c +++ b/main.c @@ -1,10 +1,25 @@ #include #include #include "gex_client.h" +#include + +static GexClient *gex; + +/** ^C handler to close it gracefully */ +static void sigintHandler(int sig) +{ + if (gex != NULL) { + GEX_DeInit(gex); + } + exit(0); +} int main() { - GexClient *gex = GEX_Init("/dev/ttyACM0", 200); + // Bind ^C handler for safe shutdown + signal(SIGINT, sigintHandler); + + gex = GEX_Init("/dev/ttyACM0", 200); if (!gex) { fprintf(stderr, "FAILED TO CONNECT, ABORTING!\n"); exit(1);