4#ifndef PROTOCORE_THREAD_H
5#define PROTOCORE_THREAD_H
46#define HDLC_ESCAPE 0x7D
49#define SPINEL_CMD_NOOP 0
50#define SPINEL_CMD_RESET 1
51#define SPINEL_CMD_PROP_VALUE_GET 2
52#define SPINEL_CMD_PROP_VALUE_SET 3
53#define SPINEL_CMD_PROP_VALUE_INSERT 4
54#define SPINEL_CMD_PROP_VALUE_REMOVE 5
55#define SPINEL_CMD_PROP_VALUE_IS 6
56#define SPINEL_CMD_PROP_VALUE_INSERTED 7
57#define SPINEL_CMD_PROP_VALUE_REMOVED 8
64#define SPINEL_PROP_LAST_STATUS 0
65#define SPINEL_PROP_PROTOCOL_VERSION 1
66#define SPINEL_PROP_NCP_VERSION 2
67#define SPINEL_PROP_INTERFACE_TYPE 3
68#define SPINEL_PROP_VENDOR_ID 4
69#define SPINEL_PROP_CAPS 5
70#define SPINEL_PROP_INTERFACE_COUNT 6
71#define SPINEL_PROP_HWADDR 8
72#define SPINEL_PROP_LOCK 9
75#define SPINEL_PROP_PHY_ENABLED 0x20
76#define SPINEL_PROP_PHY_CHAN 0x21
77#define SPINEL_PROP_PHY_CHAN_SUPPORTED 0x22
78#define SPINEL_PROP_PHY_FREQ 0x23
79#define SPINEL_PROP_PHY_TX_POWER 0x25
80#define SPINEL_PROP_PHY_RSSI 0x26
83#define SPINEL_PROP_MAC_SCAN_STATE 0x30
84#define SPINEL_PROP_MAC_SCAN_MASK 0x31
85#define SPINEL_PROP_MAC_SCAN_PERIOD 0x32
86#define SPINEL_PROP_MAC_15_4_LADDR 0x34
87#define SPINEL_PROP_MAC_15_4_SADDR 0x35
88#define SPINEL_PROP_MAC_15_4_PANID 0x36
91#define SPINEL_PROP_NET_SAVED 0x40
92#define SPINEL_PROP_NET_IF_UP 0x41
93#define SPINEL_PROP_NET_STACK_UP 0x42
94#define SPINEL_PROP_NET_ROLE 0x43
95#define SPINEL_PROP_NET_NETWORK_NAME 0x44
96#define SPINEL_PROP_NET_XPANID 0x45
97#define SPINEL_PROP_NET_NETWORK_KEY 0x46
100#define SPINEL_PROP_IPV6_LL_ADDR 0x60
101#define SPINEL_PROP_IPV6_ML_ADDR 0x61
104#define SPINEL_PROP_STREAM_DEBUG 0x70
105#define SPINEL_PROP_STREAM_RAW 0x71
106#define SPINEL_PROP_STREAM_NET 0x72
109#define SPINEL_STATUS_OK 0
110#define SPINEL_STATUS_FAILURE 1
111#define SPINEL_STATUS_UNIMPLEMENTED 2
112#define SPINEL_STATUS_INVALID_ARGUMENT 3
113#define SPINEL_STATUS_INVALID_STATE 4
114#define SPINEL_STATUS_INVALID_COMMAND 5
115#define SPINEL_STATUS_INVALID_INTERFACE 6
116#define SPINEL_STATUS_INTERNAL_ERROR 7
117#define SPINEL_STATUS_SECURITY_ERROR 8
118#define SPINEL_STATUS_PARSE_ERROR 9
119#define SPINEL_STATUS_IN_PROGRESS 10
120#define SPINEL_STATUS_NOMEM 11
121#define SPINEL_STATUS_BUSY 12
122#define SPINEL_STATUS_PROP_NOT_FOUND 13
123#define SPINEL_STATUS_DROPPED 14
124#define SPINEL_STATUS_EMPTY 15
125#define SPINEL_STATUS_RESET_POWER_ON 112
126#define SPINEL_STATUS_RESET_END 128
155static inline uint8_t protocore_spinel_header(uint8_t iid, uint8_t tid)
157 return (uint8_t)(0x80 | ((iid & 0x03) << 4) | (tid & 0x0F));
161static inline uint8_t protocore_spinel_header_tid(uint8_t h)
163 return (uint8_t)(h & 0x0F);
167static inline uint8_t protocore_spinel_header_iid(uint8_t h)
169 return (uint8_t)((h >> 4) & 0x03);
175 uint16_t (*spinel_fcs)(uint8_t *,
const uint8_t *, uint16_t);
176 uint8_t (*spinel_pack_uint)(uint8_t *, uint32_t, uint8_t *, uint8_t);
177 int (*spinel_unpack_uint)(uint8_t *,
const uint8_t *, uint8_t, uint32_t *);
178 uint16_t (*spinel_command_build)(uint8_t *, uint8_t, uint32_t, uint32_t,
const uint8_t *, uint16_t, uint8_t *,
180 int (*spinel_command_parse)(uint8_t *,
const uint8_t *, uint16_t, uint8_t *, uint32_t *, uint32_t *,
181 const uint8_t **, uint16_t *);
182 void (*spinel_reader_init)(uint8_t *,
SpinelReader *,
const uint8_t *, uint16_t);
197 void (*spinel_writer_init)(uint8_t *,
SpinelWriter *, uint8_t *, uint16_t);
213 const char *(*spinel_prop_name)(uint8_t *, uint32_t);
214 const char *(*spinel_status_name)(uint8_t *, uint32_t);
215 uint16_t (*spinel_frame_encode)(uint8_t *,
const uint8_t *, uint16_t, uint8_t *, uint16_t);
216 int (*spinel_frame_decode)(uint8_t *,
const uint8_t *, uint16_t, uint8_t *, uint16_t, uint16_t *);
219 spinel_command_parse, spinel_reader_init, spinel_get_bool, spinel_get_u8, spinel_get_i8,
220 spinel_get_u16, spinel_get_i16, spinel_get_u32, spinel_get_i32, spinel_get_uint, spinel_get_eui64,
221 spinel_get_ipv6, spinel_get_utf8, spinel_get_data, spinel_get_data_wlen, spinel_reader_ok,
222 spinel_writer_init, spinel_put_bool, spinel_put_u8, spinel_put_i8, spinel_put_u16, spinel_put_i16,
223 spinel_put_u32, spinel_put_i32, spinel_put_uint, spinel_put_eui64, spinel_put_ipv6, spinel_put_utf8,
224 spinel_put_data, spinel_put_data_wlen, spinel_writer_len, spinel_prop_lookup, spinel_prop_name,
225 spinel_status_name, spinel_frame_encode, spinel_frame_decode);
266 const uint8_t *value, uint16_t value_len, uint8_t *out, uint16_t cap);
280 uint32_t *cmd, uint32_t *prop,
const uint8_t **value, uint16_t *value_len);
565 uint16_t pay_cap, uint16_t *pay_len);
#define PROTOCORE_NS_LAYOUT(T,...)
Pin every dispatch slot of a table that is nothing but function pointers.
#define PROTOCORE_NS
Storage for a dispatch table. The const is load bearing.
A registry entry: a property id, its human name, and its primary spinel datatype char.
char type
the leading spinel datatype ('U','i','C','c','S','E','6','b','D', or '.')
A read cursor over a spinel property value.
proto_bool err
set once any read runs past the end / is malformed
uint16_t off
next unread offset
const uint8_t * buf
the value bytes
A write cursor building a spinel property value into a caller buffer.
proto_bool err
set once any write would overflow cap
uint16_t off
bytes written so far
uint16_t cap
output capacity
uint8_t * buf
output buffer
Dispatch table. Addressed by offset, so the layout is asserted below.
uint16_t(* spinel_fcs)(uint8_t *, const uint8_t *, uint16_t)
void protocore_thread_spinel_writer_init(uint8_t *work, SpinelWriter *w, uint8_t *out, uint16_t cap)
Spinel_writer_init.
proto_bool protocore_thread_spinel_put_u16(uint8_t *work, SpinelWriter *w, uint16_t v)
Spinel_put_u16.
proto_bool protocore_thread_spinel_get_u8(uint8_t *work, SpinelReader *r, uint8_t *out)
Spinel_get_u8.
proto_bool protocore_thread_spinel_get_utf8(uint8_t *work, SpinelReader *r, const char **out, uint16_t *out_len)
UTF8 'U': out points into the value, out_len excludes the NUL; .
proto_bool protocore_thread_spinel_get_data_wlen(uint8_t *work, SpinelReader *r, const uint8_t **out, uint16_t *out_len)
Data 'd' (uint16-LE length prefix): reads the count, then that many .
PROTOCORE_NS ThreadNs Thread PROTOCORE_UNUSED
Module namespace.
proto_bool protocore_thread_spinel_put_uint(uint8_t *work, SpinelWriter *w, uint32_t v)
Spinel_put_uint.
const SpinelPropInfo * protocore_thread_spinel_prop_lookup(uint8_t *work, uint32_t id)
Look up a property's registry entry, or nullptr if it is not in the .
proto_bool protocore_thread_spinel_get_i16(uint8_t *work, SpinelReader *r, int16_t *out)
Spinel_get_i16.
const char * protocore_thread_spinel_status_name(uint8_t *work, uint32_t status)
A LAST_STATUS code's human name, or "UNKNOWN" if unregistered.
proto_bool protocore_thread_spinel_put_u32(uint8_t *work, SpinelWriter *w, uint32_t v)
Spinel_put_u32.
void protocore_thread_spinel_put_i8(uint8_t *work, SpinelWriter *w, int8_t v)
Spinel_put_i8.
uint8_t protocore_thread_spinel_pack_uint(uint8_t *work, uint32_t value, uint8_t *out, uint8_t cap)
Encode a spinel packed unsigned integer (7 bits/byte, .
void protocore_thread_spinel_put_i16(uint8_t *work, SpinelWriter *w, int16_t v)
Spinel_put_i16.
const char * protocore_thread_spinel_prop_name(uint8_t *work, uint32_t id)
A property's human name, or "UNKNOWN" if unregistered.
uint16_t protocore_thread_spinel_command_build(uint8_t *work, uint8_t header, uint32_t cmd, uint32_t prop, const uint8_t *value, uint16_t value_len, uint8_t *out, uint16_t cap)
Build a spinel property-command payload (`header | CMD | PROP | .
proto_bool protocore_thread_spinel_get_i8(uint8_t *work, SpinelReader *r, int8_t *out)
Spinel_get_i8.
int protocore_thread_spinel_command_parse(uint8_t *work, const uint8_t *payload, uint16_t len, uint8_t *header, uint32_t *cmd, uint32_t *prop, const uint8_t **value, uint16_t *value_len)
Parse a spinel property-command payload (from a decoded HDLC frame).
proto_bool protocore_thread_spinel_put_eui64(uint8_t *work, SpinelWriter *w, const uint8_t *v8)
Spinel_put_eui64.
proto_bool protocore_thread_spinel_put_ipv6(uint8_t *work, SpinelWriter *w, const uint8_t *v16)
Spinel_put_ipv6.
proto_bool protocore_thread_spinel_put_u8(uint8_t *work, SpinelWriter *w, uint8_t v)
Spinel_put_u8.
proto_bool protocore_thread_spinel_get_i32(uint8_t *work, SpinelReader *r, int32_t *out)
Spinel_get_i32.
proto_bool protocore_thread_spinel_put_data_wlen(uint8_t *work, SpinelWriter *w, const uint8_t *d, uint16_t n)
Spinel_put_data_wlen.
int protocore_thread_spinel_unpack_uint(uint8_t *work, const uint8_t *raw, uint8_t len, uint32_t *value)
Decode a spinel packed unsigned integer from the front of raw.
proto_bool protocore_thread_spinel_get_data(uint8_t *work, SpinelReader *r, const uint8_t **out, uint16_t *out_len)
Data 'D' (to end of value): out points into the value, out_len is .
uint16_t protocore_thread_spinel_frame_encode(uint8_t *work, const uint8_t *payload, uint16_t len, uint8_t *out, uint16_t cap)
Encode an HDLC-lite frame: payload + FCS, byte-stuffed, .
proto_bool protocore_thread_spinel_get_bool(uint8_t *work, SpinelReader *r, proto_bool *out)
Spinel_get_bool.
proto_bool protocore_thread_spinel_get_uint(uint8_t *work, SpinelReader *r, uint32_t *out)
Spinel_get_uint.
proto_bool protocore_thread_spinel_get_eui64(uint8_t *work, SpinelReader *r, const uint8_t **out8)
Spinel_get_eui64.
int protocore_thread_spinel_frame_decode(uint8_t *work, const uint8_t *raw, uint16_t len, uint8_t *payload, uint16_t pay_cap, uint16_t *pay_len)
Decode one HDLC-lite frame from the front of raw: find the flag, .
proto_bool protocore_thread_spinel_put_data(uint8_t *work, SpinelWriter *w, const uint8_t *d, uint16_t n)
Spinel_put_data.
proto_bool protocore_thread_spinel_put_utf8(uint8_t *work, SpinelWriter *w, const char *s)
Spinel_put_utf8.
void protocore_thread_spinel_reader_init(uint8_t *work, SpinelReader *r, const uint8_t *value, uint16_t len)
Spinel_reader_init.
uint16_t protocore_thread_spinel_fcs(uint8_t *work, const uint8_t *buf, uint16_t len)
HDLC frame check sequence: CRC-16/X-25 over buf.
proto_bool protocore_thread_spinel_get_u16(uint8_t *work, SpinelReader *r, uint16_t *out)
Spinel_get_u16.
proto_bool protocore_thread_spinel_reader_ok(uint8_t *work, const SpinelReader *r)
True if every read so far stayed in bounds.
uint16_t protocore_thread_spinel_writer_len(uint8_t *work, const SpinelWriter *w)
The finished value length, or 0 if any write overflowed.
void protocore_thread_spinel_put_i32(uint8_t *work, SpinelWriter *w, int32_t v)
Spinel_put_i32.
proto_bool protocore_thread_spinel_put_bool(uint8_t *work, SpinelWriter *w, proto_bool v)
Spinel_put_bool.
proto_bool protocore_thread_spinel_get_u32(uint8_t *work, SpinelReader *r, uint32_t *out)
Spinel_get_u32.
proto_bool protocore_thread_spinel_get_ipv6(uint8_t *work, SpinelReader *r, const uint8_t **out16)
Spinel_get_ipv6.
#define PROTOCORE_BEGIN_DECLS
Give a header's declarations C linkage, so their symbol names carry no parameter types.
_Bool proto_bool
The truth value.
#define PROTOCORE_END_DECLS