work on bulk, not working yet

master
Ondřej Hruška 6 years ago
parent ffd95a175d
commit bc619c6139
Signed by: MightyPork
GPG Key ID: 2C5FD5035250423D
  1. 11
      gex/gex_client.c
  2. 2
      gex/gex_client.h
  3. 1
      gex/gex_helpers.c
  4. 2
      gex/gex_message_types.h
  5. 29
      gex/gex_unit.c
  6. 6
      gex/gex_unit.h
  7. 43
      main.c

@ -112,10 +112,19 @@ void GEX_OnReport(GexClient *gex, GexUnit *unit, GexEventListener lst)
}
}
TinyFrame *GEX_GetTF(GexClient *gex)
{
return gex->tf;
}
/** Find a unit */
GexUnit *GEX_Unit(GexClient *gex, const char *name)
{
return gex_find_unit_by_name(gex, name);
GexUnit *u = gex_find_unit_by_name(gex, name);
if (u == NULL) {
fprintf(stderr, "!! Unit %s not found!\n", name);
}
return u;
}
/** Create a instance and connect */

@ -26,6 +26,8 @@
*/
void GEX_OnReport(GexClient *gex, GexUnit *unit, GexEventListener lst);
TinyFrame *GEX_GetTF(GexClient *gex);
/**
* Get a unit, or NULL
*

@ -8,6 +8,7 @@
#define GEX_H // to allow including other headers
#include "gex_defines.h"
#include "gex_helpers.h"
#include "gex_internal.h"
/** Delete recursively all GEX callsign look-up table entries */
void gex_destroy_unit_lookup(GexClient *gex)

@ -19,7 +19,7 @@ enum TF_Types_ {
MSG_ERROR = 0x02, //!< Generic failure response (when a request fails to execute)
MSG_BULK_READ_OFFER = 0x03, //!< Offer of data to read. Payload: u32 total len
MSG_BULK_READ_POLL = 0x04, //!< Request to read a previously announced chunk.
MSG_BULK_READ_POLL = 0x04, //!< Request to read a previously announced chunk. Payload: u32 max chunk
MSG_BULK_WRITE_OFFER = 0x05, //!< Offer to receive data in a write transaction. Payload: u32 max size, u32 max chunk
MSG_BULK_DATA = 0x06, //!< Writing a chunk, or sending a chunk to master.
MSG_BULK_END = 0x07, //!< Bulk transfer is done, no more data to read or write.

@ -134,7 +134,7 @@ static GexMsg GEX_QueryEx(GexUnit *unit, uint8_t cmd,
GEX_Poll(gex);
if (!gex->squery_ok) {
fprintf(stderr, "No response to query of unit %s!", unit->name);
fprintf(stderr, "No response to query of unit %s!\n", unit->name);
}
return gex->squery_msg;
@ -200,30 +200,37 @@ uint32_t GEX_BulkRead(GexUnit *unit, GexBulk *bulk)
GexMsg resp0 = GEX_Query(unit, bulk->req_cmd, bulk->req_data, bulk->req_len);
if (resp0.type == MSG_ERROR) {
fprintf(stderr, "Bulk read rejected! %.*s", resp0.len, (char*)resp0.payload);
fprintf(stderr, "Bulk read rejected! %.*s\n", resp0.len, (char*)resp0.payload);
return 0;
}
if (resp0.type != MSG_BULK_READ_OFFER) {
fprintf(stderr, "Bulk read failed, response not BULK_READ_OFFER!");
fprintf(stderr, "Bulk read failed, response not BULK_READ_OFFER!\n");
return 0;
}
fprintf(stderr, "BR, got offer!\n");
// Check how much data is available
PayloadParser pp = pp_start(resp0.payload, resp0.len, NULL);
uint32_t total = pp_u32(&pp);
assert(pp.ok);
total = MIN(total, bulk->capacity); // clamp...
fprintf(stderr, "Total is %d\n", total);
uint32_t at = 0;
while (at < total) {
uint8_t buf[10];
PayloadBuilder pb = pb_start(buf, 10, NULL);
pb_u32(&pb, 512);
GexMsg resp = GEX_QueryEx(unit, MSG_BULK_READ_POLL,
NULL, 0,
buf, (uint32_t) pb_length(&pb),
resp0.session, true);
if (resp.type == MSG_ERROR) {
fprintf(stderr, "Bulk read failed! %.*s", resp.len, (char *) resp.payload);
fprintf(stderr, "Bulk read failed! %.*s\n", resp.len, (char *) resp.payload);
return 0;
}
@ -236,7 +243,7 @@ uint32_t GEX_BulkRead(GexUnit *unit, GexBulk *bulk)
memcpy(bulk->buffer+at, resp.payload, resp.len);
at += resp.len;
} else {
fprintf(stderr, "Bulk read failed! Bad response type.");
fprintf(stderr, "Bulk read failed! Bad response type.\n");
return 0;
}
}
@ -258,12 +265,12 @@ bool GEX_BulkWrite(GexUnit *unit, GexBulk *bulk)
GexMsg resp0 = GEX_Query(unit, bulk->req_cmd, bulk->req_data, bulk->req_len);
if (resp0.type == MSG_ERROR) {
fprintf(stderr, "Bulk write rejected! %.*s", resp0.len, (char*)resp0.payload);
fprintf(stderr, "Bulk write rejected! %.*s\n", resp0.len, (char*)resp0.payload);
return false;
}
if (resp0.type != MSG_BULK_WRITE_OFFER) {
fprintf(stderr, "Bulk write failed, response not MSG_BULK_WRITE_OFFER!");
fprintf(stderr, "Bulk write failed, response not MSG_BULK_WRITE_OFFER!\n");
return false;
}
@ -273,7 +280,7 @@ bool GEX_BulkWrite(GexUnit *unit, GexBulk *bulk)
assert(pp.ok);
if (max_size < bulk->len) {
fprintf(stderr, "Write not possible, not enough space.");
fprintf(stderr, "Write not possible, not enough space.\n");
// Inform GEX we're not going to do it
GEX_SendEx(unit, MSG_BULK_ABORT, NULL, 0, resp0.session, true);
return false;
@ -288,12 +295,12 @@ bool GEX_BulkWrite(GexUnit *unit, GexBulk *bulk)
at += chunk;
if (resp.type == MSG_ERROR) {
fprintf(stderr, "Bulk write failed! %.*s", resp.len, (char *) resp.payload);
fprintf(stderr, "Bulk write failed! %.*s\n", resp.len, (char *) resp.payload);
return false;
}
if (resp.type != MSG_SUCCESS) {
fprintf(stderr, "Bulk write failed! Bad response type.");
fprintf(stderr, "Bulk write failed! Bad response type.\n");
return false;
}
}

@ -27,6 +27,12 @@ static inline void GEX_Send0(GexUnit *unit, uint8_t cmd)
/** Static query, send a command and wait for the response */
GexMsg GEX_Query(GexUnit *unit, uint8_t cmd, const uint8_t *payload, uint32_t len);
/** Send a query with no payload */
static inline GexMsg GEX_Query0(GexUnit *unit, uint8_t cmd)
{
return GEX_Query(unit, cmd, NULL, 0);
}
/** Asynchronous query with an async listener */
void GEX_QueryAsync(GexUnit *unit, uint8_t cmd, const uint8_t *payload, uint32_t len, GexEventListener lst);

@ -2,6 +2,7 @@
#include <stdlib.h>
#include <signal.h>
#include <assert.h>
#include <utils/hexdump.h>
#include "gex.h"
@ -20,6 +21,14 @@ static void sigintHandler(int sig)
#define LED_CMD_TOGGLE 0x02
TF_Result hdl_default(TinyFrame *tf, TF_Msg*msg)
{
(void)tf;
fprintf(stderr, "TF unhandled msg len %d, type %d, id %d", msg->len, msg->type, msg->frame_id);
hexDump("payload", msg->data, msg->len);
return TF_STAY;
}
int main(void)
{
// Bind ^C handler for safe shutdown
@ -28,11 +37,39 @@ int main(void)
gex = GEX_Init("/dev/ttyACM0", 200);
if (!gex) exit(1);
GexUnit *led = GEX_Unit(gex, "LED");
assert(led != NULL);
TF_AddGenericListener(GEX_GetTF(gex), hdl_default);
//GexUnit *led = GEX_Unit(gex, "LED");
//GEX_Send(led, LED_CMD_TOGGLE, NULL, 0);
GexUnit *test = GEX_Unit(gex, "TEST");
assert(test != NULL);
// the "PING" command
GexMsg msg;
msg = GEX_Query0(test, 0);
assert(msg.type == MSG_SUCCESS);
fprintf(stderr, "\"PING\" cmd: OK.\n");
const char *s = "BLOCKCHAIN BUT FOR COWS";
msg = GEX_Query(test, 1, (const uint8_t *) s, (uint32_t) strlen(s));
fprintf(stderr, "\"ECHO\" cmd resp: %d, len %d, pld: %.*s\n", msg.type, (int) msg.len, (int) msg.len, (char *) msg.payload);
assert(0==strncmp((char*)msg.payload, s, strlen(s)));
GEX_Send(led, LED_CMD_TOGGLE, NULL, 0);
uint8_t buffr[10000];
GexBulk br = {
.buffer = buffr,
.capacity = 10000,
.req_cmd = 2,
.req_data = NULL,
.req_len = 0,
};
uint32_t actuallyRead = GEX_BulkRead(test, &br);
fprintf(stderr, "Read %d bytes:\n", actuallyRead);
fprintf(stderr, "%*.s", actuallyRead, buffr);
fprintf(stderr, "ALL OK, ending.\n");
GEX_DeInit(gex);
return 0;
}

Loading…
Cancel
Save