Skip to content

Commit

Permalink
Merge branch 'master' of github.com:MightyPork/sbmp
Browse files Browse the repository at this point in the history
  • Loading branch information
MightyPork committed Apr 24, 2016
2 parents aadaab8 + 843e1b6 commit a31ba38
Show file tree
Hide file tree
Showing 10 changed files with 191 additions and 37 deletions.
67 changes: 67 additions & 0 deletions library/payload_builder.c
@@ -0,0 +1,67 @@
#include "sbmp_config.h"
#include "payload_builder.h"
#include "type_coerce.h"

#define check_capacity(pb_p, needed) \
if ((pb_p)->ptr + (needed) > (pb_p)->capacity) { \
pb_overflow(); \
return false; \
}


static void pb_overflow(void)
{
sbmp_error("PayloadBuilder overflow.");
}

/** Write uint8_t to the buffer */
bool pb_u8(PayloadBuilder *pb, uint8_t byte)
{
check_capacity(pb, sizeof(uint8_t));
pb->buf[pb->ptr++] = byte;
return true;
}

/** Write uint16_t to the buffer. */
bool pb_u16(PayloadBuilder *pb, uint16_t word)
{
check_capacity(pb, sizeof(uint16_t));
pb->buf[pb->ptr++] = word & 0xFF;
pb->buf[pb->ptr++] = (word >> 8) & 0xFF;
return true;
}

/** Write uint32_t to the buffer. */
bool pb_u32(PayloadBuilder *pb, uint32_t word)
{
check_capacity(pb, sizeof(uint32_t));
pb->buf[pb->ptr++] = word & 0xFF;
pb->buf[pb->ptr++] = (word >> 8) & 0xFF;
pb->buf[pb->ptr++] = (word >> 16) & 0xFF;
pb->buf[pb->ptr++] = (word >> 24) & 0xFF;
return true;
}

/** Write int8_t to the buffer. */
bool pb_i8(PayloadBuilder *pb, int8_t byte)
{
return pb_u8(pb, ((union conv8){.i8 = byte}).u8);
}

/** Write int16_t to the buffer. */
bool pb_i16(PayloadBuilder *pb, int16_t word)
{
return pb_u16(pb, ((union conv16){.i16 = word}).u16);
}

/** Write int32_t to the buffer. */
bool pb_i32(PayloadBuilder *pb, int32_t word)
{
return pb_u32(pb, ((union conv32){.i32 = word}).u32);
}

/** Write 4-byte float to the buffer. */
bool pb_float(PayloadBuilder *pb, float f)
{
return pb_u32(pb, ((union conv32){.f32 = f}).u32);
}
48 changes: 48 additions & 0 deletions library/payload_builder.h
@@ -0,0 +1,48 @@
#ifndef PAYLOAD_BUILDER_H
#define PAYLOAD_BUILDER_H

#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>

/**
* This module can help you build payload arrays
*
* The builder performs bounds checking and prints error
* message on overflow for easy debugging.
*/

typedef struct {
uint8_t *buf;
size_t ptr;
size_t capacity;
} PayloadBuilder;

#define pb_start(buf, capacity) ((PayloadBuilder){buf, 0, capacity})
#define pb_length(pb_p) ((pb_p)->ptr)

/** Write uint8_t to the buffer */
bool pb_u8(PayloadBuilder *pb, uint8_t byte);

/** Write uint16_t to the buffer. */
bool pb_u16(PayloadBuilder *pb, uint16_t word);

/** Write uint32_t to the buffer. */
bool pb_u32(PayloadBuilder *pb, uint32_t word);

/** Write char (int8_t) to the buffer. */
#define pb_char(pb, c) pb_i8(pb, c)

/** Write int8_t to the buffer. */
bool pb_i8(PayloadBuilder *pb, int8_t byte);

/** Write int16_t to the buffer. */
bool pb_i16(PayloadBuilder *pb, int16_t word);

/** Write int32_t to the buffer. */
bool pb_i32(PayloadBuilder *pb, int32_t word);

/** Write 4-byte float to the buffer. */
bool pb_float(PayloadBuilder *pb, float f);

#endif // PAYLOAD_BUILDER_H
35 changes: 30 additions & 5 deletions library/payload_parser.c
@@ -1,19 +1,38 @@
#include "sbmp_config.h"
#include "payload_parser.h"

#define check_capacity(pp_p, needed) \
if ((pp_p)->ptr + (needed) > (pp_p)->len) { \
pp_overflow(); \
return 0; \
}

static void pp_overflow(void)
{
sbmp_error("PayloadParser out of range.");
}


uint8_t pp_u8(PayloadParser *pp)
{
check_capacity(pp, sizeof(uint8_t));

return pp->buf[pp->ptr++];
}

uint16_t pp_u16(PayloadParser *pp)
{
check_capacity(pp, sizeof(uint16_t));

uint16_t x = pp->buf[pp->ptr++];
x |= (uint16_t)(pp->buf[pp->ptr++] << 8);
return x;
}

uint32_t pp_u32(PayloadParser *pp)
{
check_capacity(pp, sizeof(uint32_t));

uint32_t x = pp->buf[pp->ptr++];
x |= (uint32_t)(pp->buf[pp->ptr++] << 8);
x |= (uint32_t)(pp->buf[pp->ptr++] << 16);
Expand All @@ -23,8 +42,14 @@ uint32_t pp_u32(PayloadParser *pp)

const uint8_t *pp_rest(PayloadParser *pp, size_t *length)
{
int len = (int)(pp->len - pp->ptr);
if (len <= 0) {
if (length != NULL) *length = 0;
return NULL;
}

if (length != NULL) {
*length = pp->len - pp->ptr;
*length = (size_t)len;
}

return pp->buf + pp->ptr; // pointer arith
Expand All @@ -33,23 +58,23 @@ const uint8_t *pp_rest(PayloadParser *pp, size_t *length)
/** Read int8_t from the payload. */
int8_t pp_i8(PayloadParser *pp)
{
return ((union pp8){.u8 = pp_u8(pp)}).i8;
return ((union conv8){.u8 = pp_u8(pp)}).i8;
}

/** Read int16_t from the payload. */
int16_t pp_i16(PayloadParser *pp)
{
return ((union pp16){.u16 = pp_u16(pp)}).i16;
return ((union conv16){.u16 = pp_u16(pp)}).i16;
}

/** Read int32_t from the payload. */
int32_t pp_i32(PayloadParser *pp)
{
return ((union pp32){.u32 = pp_u32(pp)}).i32;
return ((union conv32){.u32 = pp_u32(pp)}).i32;
}

/** Read 4-byte float from the payload. */
float pp_float(PayloadParser *pp)
{
return ((union pp32){.u32 = pp_u32(pp)}).f32;
return ((union conv32){.u32 = pp_u32(pp)}).f32;
}
29 changes: 7 additions & 22 deletions library/payload_parser.h
Expand Up @@ -6,13 +6,15 @@
*
* It's a set of simple routines that help you extract data from
* a SBMP datagram payload. The payload parser should take care
* of endianness of the SBMP encoding.
* of endianness of the SBMP encoding.
*
* The functions don't do any bounds checking, so be careful.
* The parser functions will print an error if you reach the end of data,
* and return zero. This can help you with debugging.
*/

#include <stdint.h>
#include <stddef.h>
#include "type_coerce.h"

typedef struct {
const uint8_t *buf;
Expand All @@ -21,31 +23,14 @@ typedef struct {
} PayloadParser;


// Structs for conversion between types

union pp8 {
uint8_t u8;
int8_t i8;
};

union pp16 {
uint16_t u16;
int16_t i16;
};

union pp32 {
uint32_t u32;
int32_t i32;
float f32;
};


/** Start the parser. This is assigned to a local variable. */
#define pp_start(buffer, length) ((PayloadParser){.buf = (buffer), .ptr = 0, .len = (length)})
#define pp_start(buffer, length) ((PayloadParser){buffer, 0, length})

/**
* @brief Get the remainder of the buffer.
*
* Returns NULL and sets 'length' to 0 if there are no bytes left.
*
* @param pp
* @param length : here the buffer length will be stored. NULL to do not store.
* @return the remaining portion of the input buffer
Expand Down
1 change: 1 addition & 0 deletions library/sbmp.h
Expand Up @@ -23,5 +23,6 @@
#include "sbmp_bulk.h"

#include "payload_parser.h"
#include "payload_builder.h"

#endif /* SBMP_H */
6 changes: 3 additions & 3 deletions library/sbmp_bulk.c
Expand Up @@ -9,13 +9,13 @@


/** Offer a bulk data transfer. */
bool sbmp_bulk_offer(SBMP_Endpoint *ep, uint32_t bulk_length, const uint8_t *xtra_data, uint16_t xtra_data_len, uint16_t sesn)
bool sbmp_bulk_offer(SBMP_Endpoint *ep, uint32_t bulk_len_bytes, const uint8_t *xtra_data, uint16_t xtra_data_len, uint16_t sesn)
{
bool suc = sbmp_ep_start_response(ep, DG_BULK_OFFER, xtra_data_len + sizeof(uint32_t), sesn) // using response because it allows to use a custom sesn
&& sbmp_ep_send_u32(ep, bulk_length)
&& sbmp_ep_send_u32(ep, bulk_len_bytes)
&& sbmp_ep_send_buffer(ep, xtra_data, xtra_data_len, NULL);

if (suc) sbmp_dbg("Bulk OFFER sent, len %"PRIu32"; sesn %"PRIu16, bulk_length, sesn);
if (suc) sbmp_dbg("Bulk OFFER sent, len %"PRIu32"; sesn %"PRIu16, bulk_len_bytes, sesn);
return suc;
}

Expand Down
4 changes: 2 additions & 2 deletions library/sbmp_bulk.h
Expand Up @@ -13,13 +13,13 @@
/**
* @brief Offer a bulk data transfer.
* @param ep
* @param bulk_length : total bulk data length
* @param bulk_len_bytes : total bulk data length
* @param xtra : extra data in the datagram
* @param xtra_len : extra data length
* @param sesn : session number to use
* @return send success
*/
bool sbmp_bulk_offer(SBMP_Endpoint *ep, uint32_t bulk_length, const uint8_t *xtra, uint16_t xtra_len, uint16_t sesn);
bool sbmp_bulk_offer(SBMP_Endpoint *ep, uint32_t bulk_len_bytes, const uint8_t *xtra, uint16_t xtra_len, uint16_t sesn);

/**
* @brief Request a chunk of the bulk data.
Expand Down
5 changes: 4 additions & 1 deletion library/sbmp_session.c
Expand Up @@ -121,6 +121,8 @@ bool sbmp_ep_init_listeners(SBMP_Endpoint *ep, SBMP_SessionListenerSlot *listene
ep->listeners = listener_slots;
ep->listener_count = slot_count;

sbmp_dbg("Initialized %"PRIu16" session listener slots.", slot_count);

return true;
}

Expand Down Expand Up @@ -481,7 +483,8 @@ bool sbmp_ep_add_listener(SBMP_Endpoint *ep, uint16_t session, SBMP_SessionListe
return true;
}

sbmp_error("Failed to add session listener.");
sbmp_error("Failed to add session listener - all full?");

return false;
}

Expand Down
8 changes: 4 additions & 4 deletions library/sbmp_session.h
Expand Up @@ -179,7 +179,7 @@ bool sbmp_ep_send_u32(SBMP_Endpoint *ep, uint32_t word);
static inline
bool sbmp_ep_send_i8(SBMP_Endpoint *ep, int8_t byte)
{
return sbmp_ep_send_u8(ep, ((union pp8){.i8 = byte}).u8);
return sbmp_ep_send_u8(ep, ((union conv8){.i8 = byte}).u8);
}

/** send char (just alias) */
Expand All @@ -193,21 +193,21 @@ bool sbmp_ep_send_char(SBMP_Endpoint *ep, int8_t byte)
static inline
bool sbmp_ep_send_i16(SBMP_Endpoint *ep, int16_t word)
{
return sbmp_ep_send_u16(ep, ((union pp16){.i16 = word}).u16);
return sbmp_ep_send_u16(ep, ((union conv16){.i16 = word}).u16);
}

/** Send one 32-bit word in the current message */
static inline
bool sbmp_ep_send_i32(SBMP_Endpoint *ep, int32_t word)
{
return sbmp_ep_send_u32(ep, ((union pp32){.i32 = word}).u32);
return sbmp_ep_send_u32(ep, ((union conv32){.i32 = word}).u32);
}

/** Send one float word in the current message */
static inline
bool sbmp_ep_send_float(SBMP_Endpoint *ep, float word)
{
return sbmp_ep_send_u32(ep, ((union pp32){.f32 = word}).u32);
return sbmp_ep_send_u32(ep, ((union conv32){.f32 = word}).u32);
}

/**
Expand Down
25 changes: 25 additions & 0 deletions library/type_coerce.h
@@ -0,0 +1,25 @@
#ifndef TYPE_COERCE_H
#define TYPE_COERCE_H

#include <stdint.h>
#include <stddef.h>

// Structs for conversion between types

union conv8 {
uint8_t u8;
int8_t i8;
};

union conv16 {
uint16_t u16;
int16_t i16;
};

union conv32 {
uint32_t u32;
int32_t i32;
float f32;
};

#endif // TYPE_COERCE_H

0 comments on commit a31ba38

Please sign in to comment.