modularized bulk read

This commit is contained in:
2017-12-23 18:36:44 +01:00
parent eb58fce25a
commit d8e2d016d2
7 changed files with 154 additions and 120 deletions
+3 -3
View File
@@ -33,11 +33,11 @@ enum TF_Types_ {
MSG_LIST_UNITS = 0x20, //!< Get all unit call-signs and names
};
extern TinyFrame *comm;
// Must be after the enum because it's used in the header file.
#include "msg_responses.h"
extern TinyFrame *comm;
#include "msg_bulkread.h"
/**
* Initialize TinyFrame and set up listeners
+94
View File
@@ -0,0 +1,94 @@
//
// Created by MightyPork on 2017/12/23.
//
#include "platform.h"
#include <TinyFrame.h>
#include "messages.h"
#include "utils/payload_parser.h"
#include "utils/payload_builder.h"
static uint8_t bulkread_buffer[BULKREAD_MAX_CHUNK];
TF_Result bulkread_lst(TinyFrame *tf, TF_Msg *msg)
{
// this is a final call before timeout, to clean up
if (msg->data == NULL) {
dbg("Bulk rx lst cleanup\r\n");
goto close;
}
struct bulk_read *bulk = msg->userdata;
assert_param(NULL != bulk);
if (msg->type == MSG_BULK_ABORT) {
goto close;
} else if (msg->type == MSG_BULK_READ_POLL) {
PayloadParser pp = pp_start(msg->data, msg->len, NULL);
uint32_t chunk = pp_u32(&pp);
// if past len, say we're done and close
if (bulk->offset >= bulk->len) {
TF_ClearMsg(msg);
msg->frame_id = bulk->frame_id;
msg->type = MSG_BULK_END;
TF_Respond(tf, msg);
goto close;
}
chunk = MIN(chunk, bulk->len - bulk->offset);
chunk = MIN(chunk, BULKREAD_MAX_CHUNK);
bulk->read(bulk->offset, chunk, bulkread_buffer);
TF_ClearMsg(msg);
msg->frame_id = bulk->frame_id;
msg->type = MSG_BULK_DATA;
msg->data = bulkread_buffer;
msg->len = (TF_LEN) chunk;
TF_Respond(tf, msg);
// advance the position pointer
bulk->offset += chunk;
}
msg->userdata = bulk; // We must put it back
return TF_RENEW;
close:
if (msg->userdata) {
free(msg->userdata);
msg->userdata = NULL;
}
return TF_CLOSE;
}
void bulkread_start(TinyFrame *tf, struct bulk_read *bulk)
{
assert_param(bulk);
assert_param(bulk->len);
assert_param(bulk->read);
bulk->offset = 0;
{
uint8_t buf[8];
PayloadBuilder pb = pb_start(buf, 4, NULL);
pb_u32(&pb, bulk->len);
pb_u32(&pb, BULKREAD_MAX_CHUNK);
// We use userdata1 to hold a reference to the bulk transfer
TF_Msg msg = {
.type = MSG_BULK_READ_OFFER,
.frame_id = bulk->frame_id,
.is_response = true, // this ensures the frame_id is not re-generated
.data = buf,
.len = (TF_LEN) pb_length(&pb),
.userdata = bulk,
};
TF_Query(tf, &msg, bulkread_lst, BULK_LST_TIMEOUT_MS);
}
}
+32
View File
@@ -0,0 +1,32 @@
//
// Created by MightyPork on 2017/12/23.
//
#ifndef GEX_F072_MSG_BULKREAD_H
#define GEX_F072_MSG_BULKREAD_H
#ifndef GEX_MESSAGES_H
#error "Include messages.h instead!"
#endif
#include <TinyFrame.h>
#define BULK_LST_TIMEOUT_MS 200
#define BULKREAD_MAX_CHUNK 512 // this is a static buffer
typedef void (*bulkread_data_cb)(uint32_t offset, uint32_t len, uint8_t *buffer);
struct bulk_read {
TF_ID frame_id;
bulkread_data_cb read;
uint32_t len;
uint32_t offset;
};
void bulkread_start(TinyFrame *tf, struct bulk_read *bulk);
#endif //GEX_F072_MSG_BULKREAD_H