Skip to content

Commit

Permalink
Added callback for determining buffer size
Browse files Browse the repository at this point in the history
When sending a datagram packet, we are now able to query how large the
sending buffer is.  If there is not enough space for us to send the
full datagram, we automatically send back an error message.

See: #3
  • Loading branch information
rm5248 committed Feb 25, 2024
1 parent 1dcc98a commit 99b29f6
Show file tree
Hide file tree
Showing 8 changed files with 37 additions and 8 deletions.
2 changes: 1 addition & 1 deletion GUI/lcc/lccqioconnection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ LCCQIoConnection::LCCQIoConnection(QObject *parent) : LCCConnection(parent)
m_lccGrid = lcc_gridconnect_new();

lcc_context_set_userdata(m_lcc, this);
lcc_context_set_write_function(m_lcc, LCCQIoConnection::writeLCCFrameCB);
lcc_context_set_write_function(m_lcc, LCCQIoConnection::writeLCCFrameCB, NULL);
lcc_gridconnect_set_userdata(m_lccGrid, this);
lcc_gridconnect_set_frame_parsed(m_lccGrid, LCCQIoConnection::gridconnectLCCFrameParsedCB);
}
Expand Down
1 change: 1 addition & 0 deletions LCC/lcc-common-internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ struct lcc_context{
};
int16_t node_alias;
lcc_write_fn write_function;
lcc_write_buffer_available write_buffer_avail_function;
void* user_data;

// Simple node information
Expand Down
2 changes: 2 additions & 0 deletions LCC/lcc-common.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ enum lcc_producer_state{
*/
typedef int(*lcc_write_fn)(struct lcc_context*, struct lcc_can_frame*);

typedef int(*lcc_write_buffer_available)(struct lcc_context*);

/**
* A function that will be called when an event that we are interested in comes in.
*/
Expand Down
19 changes: 19 additions & 0 deletions LCC/lcc-datagram.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,22 @@ int lcc_datagram_load_and_send(struct lcc_datagram_context* ctx,
void* data,
int data_len){
struct lcc_can_frame frame;
uint16_t buffer_size = UINT16_MAX;

if(ctx == NULL || data_len < 0 || data_len > 72){
return LCC_ERROR_INVALID_ARG;
}

if(ctx->parent->write_buffer_avail_function){
buffer_size = ctx->parent->write_buffer_avail_function(ctx->parent);
}

// A bit of a catch-22 here:
// if our buffer is not large enough, we can't actually send an error code
if(buffer_size == 0){
return LCC_ERROR_TX;
}

if(data_len <= 8){
// There's just one frame for us to send, so let's send it.
lcc_set_lcb_variable_field(&frame, ctx->parent, alias);
Expand All @@ -93,6 +104,14 @@ int lcc_datagram_load_and_send(struct lcc_datagram_context* ctx,
if(data_len % 8 != 0){
numPackets++;
}

if(buffer_size < numPackets){
// We don't have enough buffer to send this data.
// Since we know we are sending a datagram, we can automatically send a 'datagram rejected' message
// with the appropriate error code
return lcc_datagram_respond_rejected(ctx, alias, LCC_ERRCODE_BUFFER_UNAVAILABLE, NULL);
}

for(int x = 0; x < numPackets; x++){
lcc_set_lcb_variable_field(&frame, ctx->parent, alias);
if(x == 0){
Expand Down
3 changes: 2 additions & 1 deletion LCC/lcc.c
Original file line number Diff line number Diff line change
Expand Up @@ -170,12 +170,13 @@ int lcc_context_incoming_frame(struct lcc_context* ctx, struct lcc_can_frame* fr
return LCC_OK;
}

int lcc_context_set_write_function(struct lcc_context* ctx, lcc_write_fn write_fn){
int lcc_context_set_write_function(struct lcc_context* ctx, lcc_write_fn write_fn, lcc_write_buffer_available write_buffer_avail_fn){
if( !write_fn || !ctx ){
return LCC_ERROR_INVALID_ARG;
}

ctx->write_function = write_fn;
ctx->write_buffer_avail_function = write_buffer_avail_fn;

return LCC_OK;
}
Expand Down
12 changes: 9 additions & 3 deletions LCC/lcc.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,17 @@ void lcc_context_free(struct lcc_context* ctx);
int lcc_context_incoming_frame(struct lcc_context* ctx, struct lcc_can_frame* frame);

/**
* Set a function that will be called in order to write a CAN frame out on the bus
* @param write_fn
* Set functions that handle writing a CAN frame out on the bus.
*
* @param write_fn The function that will write out CAN frames to the bus
* @param write_buffer_avail_fn A function that will return how many CAN frames can be queued up to be sent.
* If there is not enough space to queue up CAN frames for a specific message, the message will not be queued.
* This parameter may be NULL, in which case the size is not checked. This is currently only relevant for datagram messages,
* as it is possible to determine how many frames we need before we try to send them.
*
* @return
*/
int lcc_context_set_write_function(struct lcc_context* ctx, lcc_write_fn write_fn);
int lcc_context_set_write_function(struct lcc_context* ctx, lcc_write_fn write_fn, lcc_write_buffer_available write_buffer_avail_fn);

/**
* Set the unique identifier of this node.
Expand Down
4 changes: 2 additions & 2 deletions LCC/test/test-alias.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ static int alias_collision(){
return 1;
}

lcc_context_set_write_function( both_ctx[0], write_fun );
lcc_context_set_write_function( both_ctx[1], write_fun );
lcc_context_set_write_function( both_ctx[0], write_fun, NULL );
lcc_context_set_write_function( both_ctx[1], write_fun, NULL );

stat = lcc_context_generate_alias( both_ctx[0] );
if(stat != LCC_OK){
Expand Down
2 changes: 1 addition & 1 deletion LCC/test/test-common.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ struct lcc_context** lcctest_create_contexts(int num){
for(int x = 0; x < num; x++){
all_ctx[x] = lcc_context_new();

lcc_context_set_write_function(all_ctx[x], write_fun);
lcc_context_set_write_function(all_ctx[x], write_fun, NULL);
lcc_context_set_unique_identifer(all_ctx[x], unique_id++);
}

Expand Down

0 comments on commit 99b29f6

Please sign in to comment.