drivers/nble: Convert RPC serialization code to use net_buf

Using net_buf helps us remove a lot of the pointer & data length
book-keeping variables and in general makes the code more readable.

Change-Id: Iec870a3bacbb63b55329ef5214b0ee0a757f5b1e
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
This commit is contained in:
Johan Hedberg 2016-02-11 11:07:25 +02:00 committed by Gerrit Code Review
commit 58ba5e8633
3 changed files with 100 additions and 143 deletions

View file

@ -15,6 +15,7 @@
*/ */
#include <stdint.h> #include <stdint.h>
#include <net/buf.h>
/** Identifiers of the signature supported by the RPC */ /** Identifiers of the signature supported by the RPC */
enum { enum {
@ -39,16 +40,15 @@ enum {
* @return Pointer to the allocated buffer, the allocation shall not fail, * @return Pointer to the allocated buffer, the allocation shall not fail,
* error must be handled internally * error must be handled internally
*/ */
uint8_t *rpc_alloc_cb(uint16_t length); struct net_buf *rpc_alloc_cb(uint16_t length);
/** /**
* RPC transmission function, must be implemented by the user of the RPC. * RPC transmission function, must be implemented by the user of the RPC.
* *
* @param p_buf Pointer to the buffer allocated for transmission * @param buf Pointer to the buffer allocated for transmission
* by @ref rpc_alloc_cb * by @ref rpc_alloc_cb
* @param length Length of the buffer to transmit
*/ */
void rpc_transmit_cb(uint8_t *p_buf, uint16_t length); void rpc_transmit_cb(struct net_buf *buf);
/** /**
* RPC serialization function to serialize a function that does not require any * RPC serialization function to serialize a function that does not require any

View file

@ -133,9 +133,9 @@ LIST_FN_SIG_S_B_B_P
#define FN_INDEX_SIZE 1 #define FN_INDEX_SIZE 1
#define POINTER_SIZE 4 #define POINTER_SIZE 4
static void _send(uint8_t *buf, uint16_t length) static void _send(struct net_buf *buf)
{ {
rpc_transmit_cb(buf, length); rpc_transmit_cb(buf);
} }
static uint16_t encoded_structlen(uint8_t structlen) static uint16_t encoded_structlen(uint8_t structlen)
@ -143,14 +143,11 @@ static uint16_t encoded_structlen(uint8_t structlen)
return 1 + structlen; return 1 + structlen;
} }
static uint8_t *serialize_struct(uint8_t *p, const uint8_t *struct_data, static void serialize_struct(struct net_buf *buf, const uint8_t *struct_data,
uint8_t struct_length) uint8_t struct_length)
{ {
*p++ = struct_length; net_buf_add_u8(buf, struct_length);
memcpy(p, struct_data, struct_length); memcpy(net_buf_add(buf, struct_length), struct_data, struct_length);
p += struct_length;
return p;
} }
static uint16_t encoded_buflen(const uint8_t *buf, uint16_t buflen) static uint16_t encoded_buflen(const uint8_t *buf, uint16_t buflen)
@ -166,209 +163,170 @@ static uint16_t encoded_buflen(const uint8_t *buf, uint16_t buflen)
} }
} }
static uint8_t *serialize_buf(uint8_t *p, const uint8_t *buf, uint16_t buflen) static void serialize_buf(struct net_buf *buf, const uint8_t *data,
uint16_t len)
{ {
uint16_t varint; uint16_t varint;
uint8_t *p;
if (!buf) { if (!data) {
buflen = 0; len = 0;
} }
varint = buflen; varint = len;
*p = varint & 0x7F; p = net_buf_add_u8(buf, (varint & 0x7f));
if (varint >= (1 << 7)) { if (varint >= (1 << 7)) {
*p |= 0x80; *p |= 0x80;
p++; net_buf_add_u8(buf, (varint >> 7));
*p = varint >> 7;
} }
p++; memcpy(net_buf_add(buf, len), data, len);
memcpy(p, buf, buflen);
p += buflen;
return p;
} }
static uint8_t *serialize_p(uint8_t *p, uintptr_t priv) static void serialize_p(struct net_buf *buf, void *ptr)
{ {
*p++ = priv; uintptr_t val = (uintptr_t)ptr;
*p++ = (priv >> 8);
*p++ = (priv >> 16);
*p++ = (priv >> 24);
return p; memcpy(net_buf_add(buf, sizeof(val)), &val, sizeof(val));
} }
void rpc_serialize_none(uint8_t fn_index) void rpc_serialize_none(uint8_t fn_index)
{ {
uint16_t length; struct net_buf *buf;
uint8_t *buf;
uint8_t *p;
length = SIG_TYPE_SIZE + FN_INDEX_SIZE; buf = rpc_alloc_cb(SIG_TYPE_SIZE + FN_INDEX_SIZE);
p = buf = rpc_alloc_cb(length); net_buf_add_u8(buf, SIG_TYPE_NONE);
net_buf_add_u8(buf, fn_index);
*p++ = SIG_TYPE_NONE; _send(buf);
*p = fn_index;
_send(buf, length);
} }
void rpc_serialize_s(uint8_t fn_index, const void *struct_data, void rpc_serialize_s(uint8_t fn_index, const void *struct_data,
uint8_t struct_length) uint8_t struct_length)
{ {
uint16_t length; struct net_buf *buf;
uint8_t *buf;
uint8_t *p;
length = SIG_TYPE_SIZE + FN_INDEX_SIZE + buf = rpc_alloc_cb(SIG_TYPE_SIZE + FN_INDEX_SIZE +
encoded_structlen(struct_length); encoded_structlen(struct_length));
p = buf = rpc_alloc_cb(length); net_buf_add_u8(buf, SIG_TYPE_S);
net_buf_add_u8(buf, fn_index);
*p++ = SIG_TYPE_S; serialize_struct(buf, struct_data, struct_length);
*p++ = fn_index;
p = serialize_struct(p, struct_data, struct_length);
_send(buf, length); _send(buf);
} }
void rpc_serialize_p(uint8_t fn_index, void *priv)
void rpc_serialize_p(uint8_t fn_index, void *p_priv)
{ {
uint16_t length; struct net_buf *buf;
uint8_t *buf;
uint8_t *p;
uintptr_t priv = (uintptr_t) p_priv;
length = SIG_TYPE_SIZE + FN_INDEX_SIZE + POINTER_SIZE; buf = rpc_alloc_cb(SIG_TYPE_SIZE + FN_INDEX_SIZE + POINTER_SIZE);
p = buf = rpc_alloc_cb(length); net_buf_add_u8(buf, SIG_TYPE_P);
net_buf_add_u8(buf, fn_index);
serialize_p(buf, priv);
*p++ = SIG_TYPE_P; _send(buf);
*p++ = fn_index;
p = serialize_p(p, priv);
_send(buf, length);
} }
void rpc_serialize_s_b(uint8_t fn_index, const void *struct_data, void rpc_serialize_s_b(uint8_t fn_index, const void *struct_data,
uint8_t struct_length, const void *vbuf, uint8_t struct_length, const void *vbuf,
uint16_t vbuf_length) uint16_t vbuf_length)
{ {
uint16_t length; struct net_buf *buf;
uint8_t *buf;
uint8_t *p;
length = SIG_TYPE_SIZE + FN_INDEX_SIZE + buf = rpc_alloc_cb(SIG_TYPE_SIZE + FN_INDEX_SIZE +
encoded_structlen(struct_length) + encoded_structlen(struct_length) +
encoded_buflen(vbuf, vbuf_length); encoded_buflen(vbuf, vbuf_length));
p = buf = rpc_alloc_cb(length); net_buf_add_u8(buf, SIG_TYPE_S_B);
net_buf_add_u8(buf, fn_index);
*p++ = SIG_TYPE_S_B; serialize_struct(buf, struct_data, struct_length);
*p++ = fn_index; serialize_buf(buf, vbuf, vbuf_length);
p = serialize_struct(p, struct_data, struct_length);
p = serialize_buf(p, vbuf, vbuf_length);
_send(buf, length); _send(buf);
} }
void rpc_serialize_b_b_p(uint8_t fn_index, const void *vbuf1, void rpc_serialize_b_b_p(uint8_t fn_index, const void *vbuf1,
uint16_t vbuf1_length, const void *vbuf2, uint16_t vbuf1_length, const void *vbuf2,
uint16_t vbuf2_length, void *p_priv) uint16_t vbuf2_length, void *priv)
{ {
uint16_t length; struct net_buf *buf;
uint8_t *buf;
uint8_t *p;
uintptr_t priv = (uintptr_t) p_priv;
length = SIG_TYPE_SIZE + FN_INDEX_SIZE + buf = rpc_alloc_cb(SIG_TYPE_SIZE + FN_INDEX_SIZE +
encoded_buflen(vbuf1, vbuf1_length) + encoded_buflen(vbuf1, vbuf1_length) +
encoded_buflen(vbuf2, vbuf2_length) + POINTER_SIZE; encoded_buflen(vbuf2, vbuf2_length) + POINTER_SIZE);
p = buf = rpc_alloc_cb(length); net_buf_add_u8(buf, SIG_TYPE_B_B_P);
net_buf_add_u8(buf, fn_index);
*p++ = SIG_TYPE_B_B_P; serialize_buf(buf, vbuf1, vbuf1_length);
*p++ = fn_index; serialize_buf(buf, vbuf2, vbuf2_length);
p = serialize_buf(p, vbuf1, vbuf1_length); serialize_p(buf, priv);
p = serialize_buf(p, vbuf2, vbuf2_length);
p = serialize_p(p, priv);
_send(buf, length); _send(buf);
} }
void rpc_serialize_s_p(uint8_t fn_index, const void *struct_data, void rpc_serialize_s_p(uint8_t fn_index, const void *struct_data,
uint8_t struct_length, void *p_priv) uint8_t struct_length, void *priv)
{ {
uint16_t length; struct net_buf *buf;
uint8_t *buf;
uint8_t *p;
uintptr_t priv = (uintptr_t) p_priv;
length = SIG_TYPE_SIZE + buf = rpc_alloc_cb(SIG_TYPE_SIZE + FN_INDEX_SIZE +
FN_INDEX_SIZE + encoded_structlen(struct_length) + encoded_structlen(struct_length) + POINTER_SIZE);
POINTER_SIZE;
p = buf = rpc_alloc_cb(length); net_buf_add_u8(buf, SIG_TYPE_S_P);
net_buf_add_u8(buf, fn_index);
*p++ = SIG_TYPE_S_P; serialize_struct(buf, struct_data, struct_length);
*p++ = fn_index; serialize_p(buf, priv);
p = serialize_struct(p, struct_data, struct_length);
p = serialize_p(p, priv);
_send(buf, length); _send(buf);
} }
void rpc_serialize_s_b_p(uint8_t fn_index, const void *struct_data, void rpc_serialize_s_b_p(uint8_t fn_index, const void *struct_data,
uint8_t struct_length, const void *vbuf, uint8_t struct_length, const void *vbuf,
uint16_t vbuf_length, void *p_priv) uint16_t vbuf_length, void *priv)
{ {
uint16_t length; struct net_buf *buf;
uint8_t *buf;
uint8_t *p;
uintptr_t priv = (uintptr_t) p_priv;
length = SIG_TYPE_SIZE + FN_INDEX_SIZE + buf = rpc_alloc_cb(SIG_TYPE_SIZE + FN_INDEX_SIZE +
encoded_structlen(struct_length) + encoded_structlen(struct_length) +
encoded_buflen(vbuf, vbuf_length) + POINTER_SIZE; encoded_buflen(vbuf, vbuf_length) + POINTER_SIZE);
p = buf = rpc_alloc_cb(length); net_buf_add_u8(buf, SIG_TYPE_S_B_P);
net_buf_add_u8(buf, fn_index);
*p++ = SIG_TYPE_S_B_P; serialize_struct(buf, struct_data, struct_length);
*p++ = fn_index; serialize_buf(buf, vbuf, vbuf_length);
p = serialize_struct(p, struct_data, struct_length); serialize_p(buf, priv);
p = serialize_buf(p, vbuf, vbuf_length);
p = serialize_p(p, priv);
_send(buf, length); _send(buf);
} }
void rpc_serialize_s_b_b_p(uint8_t fn_index, const void *struct_data, void rpc_serialize_s_b_b_p(uint8_t fn_index, const void *struct_data,
uint8_t struct_length, const void *vbuf1, uint8_t struct_length, const void *vbuf1,
uint16_t vbuf1_length, const void *vbuf2, uint16_t vbuf1_length, const void *vbuf2,
uint16_t vbuf2_length, void *p_priv) uint16_t vbuf2_length, void *priv)
{ {
uint16_t length; struct net_buf *buf;
uint8_t *buf;
uint8_t *p;
uintptr_t priv = (uintptr_t) p_priv;
length = SIG_TYPE_SIZE + FN_INDEX_SIZE + buf = rpc_alloc_cb(SIG_TYPE_SIZE + FN_INDEX_SIZE +
encoded_structlen(struct_length) + encoded_structlen(struct_length) +
encoded_buflen(vbuf1, vbuf1_length) + encoded_buflen(vbuf1, vbuf1_length) +
encoded_buflen(vbuf2, vbuf2_length) + POINTER_SIZE; encoded_buflen(vbuf2, vbuf2_length) + POINTER_SIZE);
p = buf = rpc_alloc_cb(length); net_buf_add_u8(buf, SIG_TYPE_S_B_B_P);
net_buf_add_u8(buf, fn_index);
*p++ = SIG_TYPE_S_B_B_P; serialize_struct(buf, struct_data, struct_length);
*p++ = fn_index; serialize_buf(buf, vbuf1, vbuf1_length);
p = serialize_struct(p, struct_data, struct_length); serialize_buf(buf, vbuf2, vbuf2_length);
p = serialize_buf(p, vbuf1, vbuf1_length); serialize_p(buf, priv);
p = serialize_buf(p, vbuf2, vbuf2_length);
p = serialize_p(p, priv);
_send(buf, length); _send(buf);
} }

View file

@ -64,7 +64,7 @@ static void rx_fiber(void)
} }
} }
uint8_t *rpc_alloc_cb(uint16_t length) struct net_buf *rpc_alloc_cb(uint16_t length)
{ {
struct net_buf *buf; struct net_buf *buf;
@ -82,7 +82,7 @@ uint8_t *rpc_alloc_cb(uint16_t length)
return NULL; return NULL;
} }
return buf->__buf; return buf;
} }
static void poll_out(const void *buf, size_t length) static void poll_out(const void *buf, size_t length)
@ -94,14 +94,13 @@ static void poll_out(const void *buf, size_t length)
} }
} }
void rpc_transmit_cb(uint8_t *data, uint16_t length) void rpc_transmit_cb(struct net_buf *buf)
{ {
struct net_buf *buf = CONTAINER_OF(data, struct net_buf, __buf);
struct ipc_uart_header hdr; struct ipc_uart_header hdr;
BT_DBG("buf %p length %u", data, length); BT_DBG("buf %p length %u", buf, buf->len);
hdr.len = length; hdr.len = buf->len;
hdr.channel = 0; hdr.channel = 0;
hdr.src_cpu_id = 0; hdr.src_cpu_id = 0;
@ -109,7 +108,7 @@ void rpc_transmit_cb(uint8_t *data, uint16_t length)
poll_out(&hdr, sizeof(hdr)); poll_out(&hdr, sizeof(hdr));
/* Send data */ /* Send data */
poll_out(buf->data, length); poll_out(buf->data, buf->len);
net_buf_unref(buf); net_buf_unref(buf);
} }