103 if (out == NULL || (*index) < 0 || (*hw) < 0 || buf == NULL) {
return false; }
110 if (errno != EAGAIN) {
111 fprintf(stderr,
"Unexpected error while reading from serial port (handle ID: 0x%02x)\n",
113 fprintf(stderr,
"read returned \"%s\" in readMessage\n", strerror(errno));
122 while (!(buf[(*index)] ==
MP_SYNC_BYTE1) && (*index) < (*hw)) {
125 if ((*index) == (*hw)) {
126 if ((*hw) > 0 && (*index) > 0) {
139 if (((*hw) - (*index)) < 8) {
157 msgpack_unpacker unpack;
158 if (!msgpack_unpacker_init(&unpack, 64 + (*hw) - (*index))) {
161 fprintf(stderr,
"Unable to initialise msgpack unpacker\n");
164 const size_t upInitialOffset = unpack.off;
165 memcpy(msgpack_unpacker_buffer(&unpack), &(buf[(*index)]), (*hw) - (*index));
166 msgpack_unpacker_buffer_consumed(&unpack, (*hw) - (*index));
168 msgpack_unpacked mpupd = {0};
170 msgpack_unpack_return rs = msgpack_unpacker_next(&unpack, &mpupd);
172 case MSGPACK_UNPACK_SUCCESS:
175 case MSGPACK_UNPACK_CONTINUE:
179 msgpack_unpacker_destroy(&unpack);
183 case MSGPACK_UNPACK_PARSE_ERROR:
188 msgpack_unpacker_destroy(&unpack);
194 if (mpupd.data.type != MSGPACK_OBJECT_ARRAY || mpupd.data.via.array.size != 4) {
195 msgpack_unpacked_destroy(&mpupd);
198 msgpack_unpacker_destroy(&unpack);
209 msgpack_object *inArr = mpupd.data.via.array.ptr;
212 if (inArr[0].type != MSGPACK_OBJECT_POSITIVE_INTEGER || inArr[0].via.u64 !=
MP_SYNC_BYTE2) {
213 msgpack_unpacked_destroy(&mpupd);
216 msgpack_unpacker_destroy(&unpack);
222 if (inArr[1].type != MSGPACK_OBJECT_POSITIVE_INTEGER || inArr[1].via.u64 >= 128) {
223 msgpack_unpacked_destroy(&mpupd);
226 msgpack_unpacker_destroy(&unpack);
230 out->
source = inArr[1].via.u64;
233 if (inArr[2].type != MSGPACK_OBJECT_POSITIVE_INTEGER || inArr[2].via.u64 >= 128) {
234 msgpack_unpacked_destroy(&mpupd);
237 msgpack_unpacker_destroy(&unpack);
241 out->
type = inArr[2].via.u64;
251 switch (inArr[3].type) {
252 case MSGPACK_OBJECT_FLOAT32:
253 case MSGPACK_OBJECT_FLOAT64:
258 case MSGPACK_OBJECT_POSITIVE_INTEGER:
263 case MSGPACK_OBJECT_STR:
265 out->
length = inArr[3].via.str.size;
268 case MSGPACK_OBJECT_ARRAY:
270 switch (inArr[3].via.array.ptr[0].type) {
271 case MSGPACK_OBJECT_STR:
275 case MSGPACK_OBJECT_FLOAT32:
276 case MSGPACK_OBJECT_FLOAT64:
279 if (out->
length > 0) { valid =
true; }
286 case MSGPACK_OBJECT_BIN:
288 out->
length = inArr[3].via.bin.size;
302 (*index) += (unpack.off - upInitialOffset);
303 msgpack_unpacked_destroy(&mpupd);
304 msgpack_unpacker_destroy(&unpack);
312 if (valid ==
false) {
331 msgpack_packer pack = {0};
332 msgpack_sbuffer_init(sbuf);
333 msgpack_packer_init(&pack, sbuf, msgpack_sbuffer_write);
334 msgpack_pack_array(&pack, 4);
336 msgpack_pack_int(&pack, out->
source);
337 msgpack_pack_int(&pack, out->
type);
339 switch (out->
dtype) {
341 msgpack_pack_float(&pack, out->
data.
value);
349 msgpack_pack_bin(&pack, out->
length);
356 msgpack_pack_str(&pack, sl);
369 msgpack_sbuffer_destroy(sbuf);
383 msgpack_sbuffer sbuf;
385 int ret = write(handle, sbuf.data, sbuf.size);
386 msgpack_sbuffer_destroy(&sbuf);
387 return (ret == (ssize_t) sbuf.size);
399 switch (out->
dtype) {
413 return (write(handle, &(out->
data.
string.
data), sl) == (ssize_t) sl);
427 return (write(handle, out->
data.
farray, sl) == ((ssize_t) sl));
447 msgpack_pack_array(pack, sa->
entries);
448 for (
int ix = 0; ix < sa->
entries; ix++) {
449 string *s = &(sa->
strings[ix]);
451 if (sl > 0 && strlen(s->
data) < sl) { sl = strlen(s->
data); }
452 msgpack_pack_str(pack, sl);
453 msgpack_pack_str_body(pack, s->
data, sl);
467 msgpack_pack_array(pack, entries);
468 for (
unsigned int ix = 0; ix < entries; ix++) {
469 msgpack_pack_float(pack, fa[ix]);
484 const int nEntries = obj->size;
487 sa->
strings = calloc(nEntries,
sizeof(
string));
489 if (sa->
strings == NULL) {
return false; }
491 for (
int ix = 0; ix < nEntries; ix++) {
492 if (obj->ptr[ix].type != MSGPACK_OBJECT_STR) {
496 if (!
sa_create_entry(sa, ix, obj->ptr[ix].via.str.size, obj->ptr[ix].via.str.ptr)) {
515 const int nEntries = obj->size;
516 (*fa) = calloc(nEntries,
sizeof(
float));
518 if ((*fa) == NULL) {
return -1; }
520 for (
int ix = 0; ix < nEntries; ix++) {
521 if (!((obj->ptr[ix].type == MSGPACK_OBJECT_FLOAT32) || (obj->ptr[ix].type == MSGPACK_OBJECT_FLOAT64))) {
526 (*fa)[ix] = obj->ptr[ix].via.f64;
@ MSG_NUMARRAY
Array of floating point values.
@ MSG_ERROR
An error code is returned in data.value.
@ MSG_FLOAT
Generic numerical data.
@ MSG_BYTES
Raw binary data.
@ MSG_STRING
Single string.
@ MSG_UNDEF
Undefined/Uninitialised message.
@ MSG_STRARRAY
Array of strings.
@ MSG_TIMESTAMP
Timestamp (milliseconds since defined epoch/event)
int openSerialConnection(const char *port, const int baudRate)
Open a serial connection at a given baud rate.
void mp_pack_numarray(msgpack_packer *pack, const size_t entries, const float *fa)
Pack numeric/floating point array.
void mp_pack_strarray(msgpack_packer *pack, const strarray *sa)
Pack string array.
#define MP_SYNC_BYTE2
MP Serial synchronisation byte 2.
int mp_openConnection(const char *port, const int baudRate)
Set up a connection to the specified port.
bool mp_readMessage_buf(int handle, msg_t *out, uint8_t buf[MP_SERIAL_BUFF], int *index, int *hw)
Read data from handle, and parse message if able.
bool mp_readMessage(int handle, msg_t *out)
Static wrapper around mp_readMessage_buf.
bool mp_unpack_strarray(strarray *sa, msgpack_object_array *obj)
Unpack msgpack array into string array.
#define MP_SERIAL_BUFF
Default serial buffer allocation size.
void mp_closeConnection(int handle)
Close existing connection.
#define MP_SYNC_BYTE1
MP Serial synchronisation byte 1.
bool mp_writeData(int handle, const msg_t *out)
Send message data (only!) to attached device.
bool mp_packMessage(msgpack_sbuffer *sbuf, const msg_t *out)
Pack a message into a buffer.
bool mp_writeMessage(int handle, const msg_t *out)
Send message to attached device.
size_t mp_unpack_numarray(float **fa, msgpack_object_array *obj)
Allocate array of floats and unpack a msgpack array into it.
void sa_destroy(strarray *sa)
Destroy array and contents.
bool str_update(string *str, const size_t len, const char *src)
Update an existing string from a character array of given length.
bool sa_create_entry(strarray *array, const int index, const size_t len, const char *src)
Create an string in a given position from a character array and length.
size_t length
Data type dependent, see the msg_new functions.
msg_data_t data
Embedded data.
uint8_t type
Message type. Common types to be documented.
uint8_t source
Maps to a specific sensor unit or data source.
msg_dtype_t dtype
Embedded data type.
int entries
Maximum number of strings in array, set when calling sa_new()
string * strings
Simple array of string structures.
char * data
Character array, should be null terminated.
size_t length
This should include a terminating null byte where possible.
float * farray
Array of floats.
string string
Single character array with length.
uint32_t timestamp
Intended to represent millisecond level clock.
float value
Generic numerical data.
strarray names
Array of strings, intended for use to provide channel names.
uint8_t * bytes
Our "raw" binary type.