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 <net/buf.h>
/** Identifiers of the signature supported by the RPC */
enum {
@ -39,16 +40,15 @@ enum {
* @return Pointer to the allocated buffer, the allocation shall not fail,
* 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.
*
* @param p_buf Pointer to the buffer allocated for transmission
* @param buf Pointer to the buffer allocated for transmission
* 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

View file

@ -133,9 +133,9 @@ LIST_FN_SIG_S_B_B_P
#define FN_INDEX_SIZE 1
#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)
@ -143,14 +143,11 @@ static uint16_t encoded_structlen(uint8_t structlen)
return 1 + structlen;
}
static uint8_t *serialize_struct(uint8_t *p, const uint8_t *struct_data,
uint8_t struct_length)
static void serialize_struct(struct net_buf *buf, const uint8_t *struct_data,
uint8_t struct_length)
{
*p++ = struct_length;
memcpy(p, struct_data, struct_length);
p += struct_length;
return p;
net_buf_add_u8(buf, struct_length);
memcpy(net_buf_add(buf, struct_length), struct_data, struct_length);
}
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;
uint8_t *p;
if (!buf) {
buflen = 0;
if (!data) {
len = 0;
}
varint = buflen;
varint = len;
*p = varint & 0x7F;
p = net_buf_add_u8(buf, (varint & 0x7f));
if (varint >= (1 << 7)) {
*p |= 0x80;
p++;
*p = varint >> 7;
net_buf_add_u8(buf, (varint >> 7));
}
p++;
memcpy(p, buf, buflen);
p += buflen;
return p;
memcpy(net_buf_add(buf, len), data, len);
}
static uint8_t *serialize_p(uint8_t *p, uintptr_t priv)
static void serialize_p(struct net_buf *buf, void *ptr)
{
*p++ = priv;
*p++ = (priv >> 8);
*p++ = (priv >> 16);
*p++ = (priv >> 24);
uintptr_t val = (uintptr_t)ptr;
return p;
memcpy(net_buf_add(buf, sizeof(val)), &val, sizeof(val));
}
void rpc_serialize_none(uint8_t fn_index)
{
uint16_t length;
uint8_t *buf;
uint8_t *p;
struct net_buf *buf;
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;
*p = fn_index;
_send(buf, length);
_send(buf);
}
void rpc_serialize_s(uint8_t fn_index, const void *struct_data,
uint8_t struct_length)
{
uint16_t length;
uint8_t *buf;
uint8_t *p;
struct net_buf *buf;
length = SIG_TYPE_SIZE + FN_INDEX_SIZE +
encoded_structlen(struct_length);
buf = rpc_alloc_cb(SIG_TYPE_SIZE + FN_INDEX_SIZE +
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;
*p++ = fn_index;
p = serialize_struct(p, struct_data, struct_length);
serialize_struct(buf, struct_data, struct_length);
_send(buf, length);
_send(buf);
}
void rpc_serialize_p(uint8_t fn_index, void *p_priv)
void rpc_serialize_p(uint8_t fn_index, void *priv)
{
uint16_t length;
uint8_t *buf;
uint8_t *p;
uintptr_t priv = (uintptr_t) p_priv;
struct net_buf *buf;
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;
*p++ = fn_index;
p = serialize_p(p, priv);
_send(buf, length);
_send(buf);
}
void rpc_serialize_s_b(uint8_t fn_index, const void *struct_data,
uint8_t struct_length, const void *vbuf,
uint16_t vbuf_length)
{
uint16_t length;
uint8_t *buf;
uint8_t *p;
struct net_buf *buf;
length = SIG_TYPE_SIZE + FN_INDEX_SIZE +
encoded_structlen(struct_length) +
encoded_buflen(vbuf, vbuf_length);
buf = rpc_alloc_cb(SIG_TYPE_SIZE + FN_INDEX_SIZE +
encoded_structlen(struct_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;
*p++ = fn_index;
p = serialize_struct(p, struct_data, struct_length);
p = serialize_buf(p, vbuf, vbuf_length);
serialize_struct(buf, struct_data, struct_length);
serialize_buf(buf, vbuf, vbuf_length);
_send(buf, length);
_send(buf);
}
void rpc_serialize_b_b_p(uint8_t fn_index, const void *vbuf1,
uint16_t vbuf1_length, const void *vbuf2,
uint16_t vbuf2_length, void *p_priv)
uint16_t vbuf2_length, void *priv)
{
uint16_t length;
uint8_t *buf;
uint8_t *p;
uintptr_t priv = (uintptr_t) p_priv;
struct net_buf *buf;
length = SIG_TYPE_SIZE + FN_INDEX_SIZE +
encoded_buflen(vbuf1, vbuf1_length) +
encoded_buflen(vbuf2, vbuf2_length) + POINTER_SIZE;
buf = rpc_alloc_cb(SIG_TYPE_SIZE + FN_INDEX_SIZE +
encoded_buflen(vbuf1, vbuf1_length) +
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;
*p++ = fn_index;
p = serialize_buf(p, vbuf1, vbuf1_length);
p = serialize_buf(p, vbuf2, vbuf2_length);
p = serialize_p(p, priv);
serialize_buf(buf, vbuf1, vbuf1_length);
serialize_buf(buf, vbuf2, vbuf2_length);
serialize_p(buf, priv);
_send(buf, length);
_send(buf);
}
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;
uint8_t *buf;
uint8_t *p;
uintptr_t priv = (uintptr_t) p_priv;
struct net_buf *buf;
length = SIG_TYPE_SIZE +
FN_INDEX_SIZE + encoded_structlen(struct_length) +
POINTER_SIZE;
buf = rpc_alloc_cb(SIG_TYPE_SIZE + FN_INDEX_SIZE +
encoded_structlen(struct_length) + 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;
*p++ = fn_index;
p = serialize_struct(p, struct_data, struct_length);
p = serialize_p(p, priv);
serialize_struct(buf, struct_data, struct_length);
serialize_p(buf, priv);
_send(buf, length);
_send(buf);
}
void rpc_serialize_s_b_p(uint8_t fn_index, const void *struct_data,
uint8_t struct_length, const void *vbuf,
uint16_t vbuf_length, void *p_priv)
uint16_t vbuf_length, void *priv)
{
uint16_t length;
uint8_t *buf;
uint8_t *p;
uintptr_t priv = (uintptr_t) p_priv;
struct net_buf *buf;
length = SIG_TYPE_SIZE + FN_INDEX_SIZE +
encoded_structlen(struct_length) +
encoded_buflen(vbuf, vbuf_length) + POINTER_SIZE;
buf = rpc_alloc_cb(SIG_TYPE_SIZE + FN_INDEX_SIZE +
encoded_structlen(struct_length) +
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;
*p++ = fn_index;
p = serialize_struct(p, struct_data, struct_length);
p = serialize_buf(p, vbuf, vbuf_length);
p = serialize_p(p, priv);
serialize_struct(buf, struct_data, struct_length);
serialize_buf(buf, vbuf, vbuf_length);
serialize_p(buf, priv);
_send(buf, length);
_send(buf);
}
void rpc_serialize_s_b_b_p(uint8_t fn_index, const void *struct_data,
uint8_t struct_length, const void *vbuf1,
uint16_t vbuf1_length, const void *vbuf2,
uint16_t vbuf2_length, void *p_priv)
uint16_t vbuf2_length, void *priv)
{
uint16_t length;
uint8_t *buf;
uint8_t *p;
uintptr_t priv = (uintptr_t) p_priv;
struct net_buf *buf;
length = SIG_TYPE_SIZE + FN_INDEX_SIZE +
encoded_structlen(struct_length) +
encoded_buflen(vbuf1, vbuf1_length) +
encoded_buflen(vbuf2, vbuf2_length) + POINTER_SIZE;
buf = rpc_alloc_cb(SIG_TYPE_SIZE + FN_INDEX_SIZE +
encoded_structlen(struct_length) +
encoded_buflen(vbuf1, vbuf1_length) +
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;
*p++ = fn_index;
p = serialize_struct(p, struct_data, struct_length);
p = serialize_buf(p, vbuf1, vbuf1_length);
p = serialize_buf(p, vbuf2, vbuf2_length);
p = serialize_p(p, priv);
serialize_struct(buf, struct_data, struct_length);
serialize_buf(buf, vbuf1, vbuf1_length);
serialize_buf(buf, vbuf2, vbuf2_length);
serialize_p(buf, 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;
@ -82,7 +82,7 @@ uint8_t *rpc_alloc_cb(uint16_t length)
return NULL;
}
return buf->__buf;
return buf;
}
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;
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.src_cpu_id = 0;
@ -109,7 +108,7 @@ void rpc_transmit_cb(uint8_t *data, uint16_t length)
poll_out(&hdr, sizeof(hdr));
/* Send data */
poll_out(buf->data, length);
poll_out(buf->data, buf->len);
net_buf_unref(buf);
}