parent
7f682b2dcd
commit
2f5e30b8a4
@ -0,0 +1,90 @@ |
||||
//
|
||||
// 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" |
||||
|
||||
/**
|
||||
* TF listener for the bulk write transaction |
||||
*/ |
||||
static TF_Result bulkwrite_lst(TinyFrame *tf, TF_Msg *msg) |
||||
{ |
||||
struct bulk_write *bulk = msg->userdata; |
||||
|
||||
// this is a final call before timeout, to clean up
|
||||
if (msg->data == NULL) { |
||||
dbg("Bulk rx lst cleanup\r\n"); |
||||
goto close; |
||||
} |
||||
|
||||
assert_param(NULL != bulk); |
||||
|
||||
if (msg->type == MSG_BULK_ABORT) { |
||||
goto close; |
||||
} |
||||
else if (msg->type == MSG_BULK_DATA || msg->type == MSG_BULK_END) { |
||||
// if past len, say we're done and close
|
||||
if (bulk->offset >= bulk->len) { |
||||
com_respond_err(bulk->frame_id, "WRITE OVERRUN"); |
||||
goto close; |
||||
} |
||||
|
||||
bulk->write(bulk, msg->data, msg->len); |
||||
|
||||
// Return SUCCESS
|
||||
com_respond_ok(msg->frame_id); |
||||
|
||||
// advance the position pointer (can be used by the write callback)
|
||||
bulk->offset += msg->len; |
||||
|
||||
if (msg->type == MSG_BULK_END) { |
||||
// this was the last chunk
|
||||
goto close; |
||||
} |
||||
} |
||||
|
||||
return TF_RENEW; |
||||
|
||||
close: |
||||
if (bulk) { |
||||
// Ask user to free the bulk and userdata
|
||||
bulk->write(bulk, NULL, 0); |
||||
msg->userdata = NULL; |
||||
} |
||||
return TF_CLOSE; |
||||
} |
||||
|
||||
/** Start the bulk write flow */ |
||||
void bulkwrite_start(TinyFrame *tf, struct bulk_write *bulk) |
||||
{ |
||||
assert_param(bulk); |
||||
assert_param(bulk->len); |
||||
assert_param(bulk->write); |
||||
|
||||
bulk->offset = 0; |
||||
|
||||
{ |
||||
uint8_t buf[8]; |
||||
PayloadBuilder pb = pb_start(buf, 4, NULL); |
||||
pb_u32(&pb, bulk->len); |
||||
pb_u32(&pb, TF_MAX_PAYLOAD_RX); |
||||
|
||||
// We use userdata1 to hold a reference to the bulk transfer
|
||||
TF_Msg msg = { |
||||
.type = MSG_BULK_WRITE_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, bulkwrite_lst, BULK_LST_TIMEOUT_MS); |
||||
} |
||||
} |
@ -0,0 +1,41 @@ |
||||
//
|
||||
// Created by MightyPork on 2017/12/23.
|
||||
//
|
||||
|
||||
#ifndef GEX_F072_MSG_BULKWRITE_H |
||||
#define GEX_F072_MSG_BULKWRITE_H |
||||
|
||||
#include <TinyFrame.h> |
||||
|
||||
typedef struct bulk_write BulkWrite; |
||||
|
||||
/**
|
||||
* Type of the bulk-write listener. Offset within the data can be retrieved from bulk->offset. |
||||
* |
||||
* If buffer is NULL, this is the last call and the bulk struct must be freed if it was allocated. |
||||
* |
||||
* @param bulk - a data object passed to the bulkwrite_start() function. |
||||
* @param chunk - destination buffer to fill with the data. NULL if bulk should be freed. |
||||
* @param len - size of the chunk to write |
||||
*/ |
||||
typedef void (*bulkwrite_data_cb)(BulkWrite *bulk, const uint8_t *chunk, uint32_t len); |
||||
|
||||
/** Bulk read structure */ |
||||
struct bulk_write { |
||||
TF_ID frame_id; //!< ID of the requesting frame, used for the entire bulk read session
|
||||
bulkwrite_data_cb write; //!< Write callback
|
||||
uint32_t len; //!< Total data length
|
||||
void *userdata; //!< A place for arbitrary userdata
|
||||
|
||||
uint32_t offset; //!< Internal offset counter, will be set to 0 on start.
|
||||
}; |
||||
|
||||
/**
|
||||
* Start a bulk write session |
||||
* @param tf - tinyframe instance |
||||
* @param bulk - bulk write config structure (malloc'd or static) |
||||
*/ |
||||
void bulkwrite_start(TinyFrame *tf, struct bulk_write *bulk); |
||||
|
||||
|
||||
#endif //GEX_F072_MSG_BULKWRITE_H
|
Loading…
Reference in new issue