From dd9d6094f989aa8908c69548910851e2c597ccea Mon Sep 17 00:00:00 2001 From: Micha Rosenbaum Date: Mon, 11 Nov 2019 14:58:40 +0100 Subject: [PATCH 01/16] Use cbor to transport saul values over coap --- Makefile | 4 ++++ saul_coap.c | 26 +++++++++++++++++++++++--- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 90e021f..3f4f3fc 100644 --- a/Makefile +++ b/Makefile @@ -38,6 +38,10 @@ USEMODULE += ps USEMODULE += netstats_l2 +# Include tinycbor for data representation +USEPKG += tinycbor +INCLUDE += $(RIOTPKG)/tinycbor/cbor.h + CFLAGS += -DGNRC_IPV6_NIB_CONF_SLAAC=1 diff --git a/saul_coap.c b/saul_coap.c index 9da41b1..d2f4205 100644 --- a/saul_coap.c +++ b/saul_coap.c @@ -24,6 +24,7 @@ #include "saul_reg.h" #include "fmt.h" #include "net/gcoap.h" +#include "cbor.h" static ssize_t _saul_cnt_handler(coap_pkt_t* pdu, uint8_t *buf, size_t len, void *ctx); static ssize_t _saul_dev_handler(coap_pkt_t* pdu, uint8_t *buf, size_t len, void *ctx); @@ -170,8 +171,11 @@ static ssize_t _saul_type_handler(coap_pkt_t* pdu, uint8_t *buf, size_t len, voi int dim; size_t resp_len; + uint8_t cbor_buf[32]; + CborEncoder encoder, mapEncoder, aryEncoder; + gcoap_resp_init(pdu, buf, len, COAP_CODE_CONTENT); - coap_opt_add_format(pdu, COAP_FORMAT_TEXT); + coap_opt_add_format(pdu, COAP_FORMAT_CBOR); resp_len = coap_opt_finish(pdu, COAP_OPT_FINISH_PAYLOAD); if (dev == NULL) { @@ -199,13 +203,29 @@ static ssize_t _saul_type_handler(coap_pkt_t* pdu, uint8_t *buf, size_t len, voi } } + cbor_encoder_init(&encoder, cbor_buf, sizeof(cbor_buf), 0); + cbor_encoder_create_map(&encoder, &mapEncoder, CborIndefiniteLength); + cbor_encode_text_stringz(&mapEncoder, "values"); + cbor_encoder_create_array(&mapEncoder, &aryEncoder, 1); + cbor_encode_int(&aryEncoder, res.val[0]); + cbor_encoder_close_container(&mapEncoder, &aryEncoder); + cbor_encoder_close_container(&encoder, &mapEncoder); + /* TODO: Take care of all values. */ /* for (uint8_t i = 0; i < dim; i++) { } */ + if (pdu->payload_len >= strlen((char *)cbor_buf)) { + memcpy(pdu->payload, cbor_buf, strlen((char *)cbor_buf)); + resp_len += gcoap_response(pdu, buf, len, COAP_CODE_VALID); + return resp_len; + } else { + return gcoap_response(pdu, buf, len, COAP_CODE_INTERNAL_SERVER_ERROR); + } + /* write the response buffer with the request device value */ - resp_len += fmt_u16_dec((char *)pdu->payload, res.val[0]); - return resp_len; + /* resp_len += fmt_u16_dec((char *)pdu->payload, res.val[0]); + return resp_len; */ } void saul_coap_init(void) From d699d7bee7b428b24fecf82b8fcd30ea7ff66d67 Mon Sep 17 00:00:00 2001 From: Micha Rosenbaum Date: Mon, 11 Nov 2019 18:17:35 +0100 Subject: [PATCH 02/16] Add WIP / code to be debugged --- saul_coap.c | 110 +++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 92 insertions(+), 18 deletions(-) diff --git a/saul_coap.c b/saul_coap.c index d2f4205..21115c3 100644 --- a/saul_coap.c +++ b/saul_coap.c @@ -163,6 +163,86 @@ static ssize_t _saul_sensortype_handler(coap_pkt_t* pdu, uint8_t *buf, size_t le return _saul_type_handler(pdu, buf, len, &type); } +void export_phydat_to_cbor(CborEncoder *encoder, uint8_t *cbor_buf, phydat_t data, int dim) +{ + CborEncoder mapEncoder, aryEncoder; + CborError err = CborNoError; + + cbor_encoder_init(encoder, cbor_buf, sizeof(cbor_buf), 0); + if (err != CborNoError) { + printf("CborError occured: %d; %d\n", err, __LINE__); + return; + } + + err = cbor_encoder_create_map(encoder, &mapEncoder, 1); + if (err != CborNoError) { + printf("CborError occured: %d\n", err); + printf("CborError occured: %d; %d\n", err, __LINE__); + return; + } + + printf("CborError occured: %d: %s (%d); %d\n", err, cbor_error_string(err), cbor_encoder_get_buffer_size(encoder, cbor_buf), __LINE__); + printf("No CborError occured, len: %d; %d\n", cbor_encoder_get_buffer_size(&mapEncoder, cbor_buf), __LINE__); + + err = cbor_encode_text_stringz(&mapEncoder, "va"); + if (err != CborNoError) { + printf("CborError occured: %x: %s (%d); %d\n", err, cbor_error_string(err), cbor_encoder_get_extra_bytes_needed(&mapEncoder), __LINE__); + return; + } + + printf("No CborError occured, len: %d; %d\n", cbor_encoder_get_buffer_size(encoder, cbor_buf), __LINE__); + printf("No CborError occured, len: %d; %d\n", cbor_encoder_get_buffer_size(&mapEncoder, cbor_buf), __LINE__); + + err = cbor_encoder_create_array(&mapEncoder, &aryEncoder, dim); + if (err != CborNoError) { + printf("CborError occured: %x: %s (%d); %d\n", err, cbor_error_string(err), cbor_encoder_get_extra_bytes_needed(&aryEncoder), __LINE__); + return; + } + + for (uint8_t i = 0; i < dim; i++) { + err = cbor_encode_int(&aryEncoder, data.val[i]); + if (err != CborNoError) { + printf("CborError occured: %d\n", err); + printf("CborError occured: %d; %d\n", err, __LINE__); + return; + } + } + + err = cbor_encoder_close_container(&mapEncoder, &aryEncoder); + if (err != CborNoError) { + printf("CborError occured: %d\n", err); printf("CborError occured: %d; %d\n", err, __LINE__); + return; + } + + err= cbor_encode_text_stringz(&mapEncoder, "unit"); + if (err != CborNoError) { + printf("CborError occured: %d\n", err); printf("CborError occured: %d; %d\n", err, __LINE__); + return; + } + + err =cbor_encode_int(&mapEncoder, data.unit); + if (err != CborNoError) { + printf("CborError occured: %d\n", err); printf("CborError occured: %d; %d\n", err, __LINE__); + return; + } + + err=cbor_encode_text_stringz(&mapEncoder, "scale"); + if (err != CborNoError) { + printf("CborError occured: %d\n", err); printf("CborError occured: %d; %d\n", err, __LINE__); + return; + } + + err=cbor_encode_int(&mapEncoder, data.scale); + if (err != CborNoError) { + printf("CborError occured: %d\n", err); printf("CborError occured: %d; %d\n", err, __LINE__); + return; + } + + cbor_encoder_close_container(encoder, &mapEncoder); +} + +static uint8_t cbor_buf[128] = { 0 }; + static ssize_t _saul_type_handler(coap_pkt_t* pdu, uint8_t *buf, size_t len, void *ctx) { uint8_t type = *((uint8_t *)ctx); @@ -170,9 +250,7 @@ static ssize_t _saul_type_handler(coap_pkt_t* pdu, uint8_t *buf, size_t len, voi phydat_t res; int dim; size_t resp_len; - - uint8_t cbor_buf[32]; - CborEncoder encoder, mapEncoder, aryEncoder; + CborEncoder encoder; gcoap_resp_init(pdu, buf, len, COAP_CODE_CONTENT); coap_opt_add_format(pdu, COAP_FORMAT_CBOR); @@ -203,26 +281,22 @@ static ssize_t _saul_type_handler(coap_pkt_t* pdu, uint8_t *buf, size_t len, voi } } - cbor_encoder_init(&encoder, cbor_buf, sizeof(cbor_buf), 0); - cbor_encoder_create_map(&encoder, &mapEncoder, CborIndefiniteLength); - cbor_encode_text_stringz(&mapEncoder, "values"); - cbor_encoder_create_array(&mapEncoder, &aryEncoder, 1); - cbor_encode_int(&aryEncoder, res.val[0]); - cbor_encoder_close_container(&mapEncoder, &aryEncoder); - cbor_encoder_close_container(&encoder, &mapEncoder); - - /* TODO: Take care of all values. */ - /* for (uint8_t i = 0; i < dim; i++) { - } */ + export_phydat_to_cbor(&encoder, cbor_buf, res, dim); - if (pdu->payload_len >= strlen((char *)cbor_buf)) { - memcpy(pdu->payload, cbor_buf, strlen((char *)cbor_buf)); + size_t buf_size=cbor_encoder_get_buffer_size(&encoder, cbor_buf); + for(uint8_t i =0;ipayload_len >= cbor_encoder_get_buffer_size(&encoder, cbor_buf)) { + memcpy(pdu->payload, cbor_buf, cbor_encoder_get_buffer_size(&encoder, cbor_buf)); resp_len += gcoap_response(pdu, buf, len, COAP_CODE_VALID); - return resp_len; } else { - return gcoap_response(pdu, buf, len, COAP_CODE_INTERNAL_SERVER_ERROR); + resp_len = gcoap_response(pdu, buf, len, COAP_CODE_INTERNAL_SERVER_ERROR); } + memset(cbor_buf, 0, sizeof(cbor_buf)); + return resp_len; /* write the response buffer with the request device value */ /* resp_len += fmt_u16_dec((char *)pdu->payload, res.val[0]); return resp_len; */ From f9fbf2a2efca60470b20ed7bb2aca916acd19a28 Mon Sep 17 00:00:00 2001 From: Micha Rosenbaum Date: Mon, 18 Nov 2019 17:47:21 +0100 Subject: [PATCH 03/16] Add buf length parameter to export_phydat_to_cbor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This previously didn’t work, because we used sizeof an pointer, which is only 4 bytes in ARM. --- saul_coap.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/saul_coap.c b/saul_coap.c index cda5c17..aa1ca31 100644 --- a/saul_coap.c +++ b/saul_coap.c @@ -162,12 +162,12 @@ static ssize_t _saul_sensortype_handler(coap_pkt_t* pdu, uint8_t *buf, size_t le return _saul_type_handler(pdu, buf, len, &type); } -void export_phydat_to_cbor(CborEncoder *encoder, uint8_t *cbor_buf, phydat_t data, int dim) +void export_phydat_to_cbor(CborEncoder *encoder, uint8_t *cbor_buf, size_t buf_len, phydat_t data, int dim) { CborEncoder mapEncoder, aryEncoder; CborError err = CborNoError; - cbor_encoder_init(encoder, cbor_buf, sizeof(cbor_buf), 0); + cbor_encoder_init(encoder, cbor_buf, buf_len, 0); if (err != CborNoError) { printf("CborError occured: %d; %d\n", err, __LINE__); return; @@ -280,7 +280,7 @@ static ssize_t _saul_type_handler(coap_pkt_t* pdu, uint8_t *buf, size_t len, voi } } - export_phydat_to_cbor(&encoder, cbor_buf, res, dim); + export_phydat_to_cbor(&encoder, cbor_buf, sizeof(cbor_buf), res, dim); size_t buf_size=cbor_encoder_get_buffer_size(&encoder, cbor_buf); for(uint8_t i =0;i Date: Mon, 18 Nov 2019 17:49:21 +0100 Subject: [PATCH 04/16] Create the phydat cbor map with 3 elements These 3 elements are values, scale and unit. --- saul_coap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/saul_coap.c b/saul_coap.c index aa1ca31..bcc23a1 100644 --- a/saul_coap.c +++ b/saul_coap.c @@ -173,7 +173,7 @@ void export_phydat_to_cbor(CborEncoder *encoder, uint8_t *cbor_buf, size_t buf_l return; } - err = cbor_encoder_create_map(encoder, &mapEncoder, 1); + err = cbor_encoder_create_map(encoder, &mapEncoder, 3); if (err != CborNoError) { printf("CborError occured: %d\n", err); printf("CborError occured: %d; %d\n", err, __LINE__); From 48d7b160858629baccccdad437ef7f18ed0ae465 Mon Sep 17 00:00:00 2001 From: Micha Rosenbaum Date: Mon, 18 Nov 2019 17:50:50 +0100 Subject: [PATCH 05/16] Update prints of cbor_buf for debugging with cbor.me --- saul_coap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/saul_coap.c b/saul_coap.c index bcc23a1..cacf621 100644 --- a/saul_coap.c +++ b/saul_coap.c @@ -284,7 +284,7 @@ static ssize_t _saul_type_handler(coap_pkt_t* pdu, uint8_t *buf, size_t len, voi size_t buf_size=cbor_encoder_get_buffer_size(&encoder, cbor_buf); for(uint8_t i =0;ipayload_len >= cbor_encoder_get_buffer_size(&encoder, cbor_buf)) { From 03e85748b9d9eecd65a68d2633461d2e1f46910e Mon Sep 17 00:00:00 2001 From: Micha Rosenbaum Date: Mon, 18 Nov 2019 17:58:34 +0100 Subject: [PATCH 06/16] Clean up debug prints --- saul_coap.c | 33 ++++----------------------------- 1 file changed, 4 insertions(+), 29 deletions(-) diff --git a/saul_coap.c b/saul_coap.c index cacf621..5129eef 100644 --- a/saul_coap.c +++ b/saul_coap.c @@ -169,71 +169,53 @@ void export_phydat_to_cbor(CborEncoder *encoder, uint8_t *cbor_buf, size_t buf_l cbor_encoder_init(encoder, cbor_buf, buf_len, 0); if (err != CborNoError) { - printf("CborError occured: %d; %d\n", err, __LINE__); return; } err = cbor_encoder_create_map(encoder, &mapEncoder, 3); if (err != CborNoError) { - printf("CborError occured: %d\n", err); - printf("CborError occured: %d; %d\n", err, __LINE__); return; } - printf("CborError occured: %d: %s (%d); %d\n", err, cbor_error_string(err), cbor_encoder_get_buffer_size(encoder, cbor_buf), __LINE__); - printf("No CborError occured, len: %d; %d\n", cbor_encoder_get_buffer_size(&mapEncoder, cbor_buf), __LINE__); - err = cbor_encode_text_stringz(&mapEncoder, "va"); if (err != CborNoError) { - printf("CborError occured: %x: %s (%d); %d\n", err, cbor_error_string(err), cbor_encoder_get_extra_bytes_needed(&mapEncoder), __LINE__); return; } - printf("No CborError occured, len: %d; %d\n", cbor_encoder_get_buffer_size(encoder, cbor_buf), __LINE__); - printf("No CborError occured, len: %d; %d\n", cbor_encoder_get_buffer_size(&mapEncoder, cbor_buf), __LINE__); - err = cbor_encoder_create_array(&mapEncoder, &aryEncoder, dim); if (err != CborNoError) { - printf("CborError occured: %x: %s (%d); %d\n", err, cbor_error_string(err), cbor_encoder_get_extra_bytes_needed(&aryEncoder), __LINE__); return; } for (uint8_t i = 0; i < dim; i++) { err = cbor_encode_int(&aryEncoder, data.val[i]); if (err != CborNoError) { - printf("CborError occured: %d\n", err); - printf("CborError occured: %d; %d\n", err, __LINE__); return; } } err = cbor_encoder_close_container(&mapEncoder, &aryEncoder); if (err != CborNoError) { - printf("CborError occured: %d\n", err); printf("CborError occured: %d; %d\n", err, __LINE__); return; } - err= cbor_encode_text_stringz(&mapEncoder, "unit"); + err = cbor_encode_text_stringz(&mapEncoder, "unit"); if (err != CborNoError) { - printf("CborError occured: %d\n", err); printf("CborError occured: %d; %d\n", err, __LINE__); return; } - err =cbor_encode_int(&mapEncoder, data.unit); + err = cbor_encode_int(&mapEncoder, data.unit); if (err != CborNoError) { - printf("CborError occured: %d\n", err); printf("CborError occured: %d; %d\n", err, __LINE__); return; } - err=cbor_encode_text_stringz(&mapEncoder, "scale"); + err = cbor_encode_text_stringz(&mapEncoder, "scale"); if (err != CborNoError) { - printf("CborError occured: %d\n", err); printf("CborError occured: %d; %d\n", err, __LINE__); return; } - err=cbor_encode_int(&mapEncoder, data.scale); + err = cbor_encode_int(&mapEncoder, data.scale); if (err != CborNoError) { - printf("CborError occured: %d\n", err); printf("CborError occured: %d; %d\n", err, __LINE__); return; } @@ -283,10 +265,6 @@ static ssize_t _saul_type_handler(coap_pkt_t* pdu, uint8_t *buf, size_t len, voi export_phydat_to_cbor(&encoder, cbor_buf, sizeof(cbor_buf), res, dim); size_t buf_size=cbor_encoder_get_buffer_size(&encoder, cbor_buf); - for(uint8_t i =0;ipayload_len >= cbor_encoder_get_buffer_size(&encoder, cbor_buf)) { memcpy(pdu->payload, cbor_buf, cbor_encoder_get_buffer_size(&encoder, cbor_buf)); resp_len += gcoap_response(pdu, buf, len, COAP_CODE_VALID); @@ -296,9 +274,6 @@ static ssize_t _saul_type_handler(coap_pkt_t* pdu, uint8_t *buf, size_t len, voi memset(cbor_buf, 0, sizeof(cbor_buf)); return resp_len; - /* write the response buffer with the request device value */ - /* resp_len += fmt_u16_dec((char *)pdu->payload, res.val[0]); - return resp_len; */ } void saul_coap_init(void) From 22607bbb4fcc532a8aa7ded7a8747b418cfe37fb Mon Sep 17 00:00:00 2001 From: Micha Rosenbaum Date: Mon, 18 Nov 2019 18:05:40 +0100 Subject: [PATCH 07/16] Move & Resize cbor_buf at top to 64 bytes This should be more than enough; the example with one value used 21 byes. It might be possible to calculate the max size needed for this buffer, somehow. --- saul_coap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/saul_coap.c b/saul_coap.c index 5129eef..96818cd 100644 --- a/saul_coap.c +++ b/saul_coap.c @@ -56,6 +56,8 @@ static gcoap_listener_t _listener = { NULL }; +static uint8_t cbor_buf[64] = { 0 }; + static ssize_t _saul_dev_handler(coap_pkt_t* pdu, uint8_t *buf, size_t len, void *ctx) { int pos = 0; @@ -222,8 +224,6 @@ void export_phydat_to_cbor(CborEncoder *encoder, uint8_t *cbor_buf, size_t buf_l cbor_encoder_close_container(encoder, &mapEncoder); } -static uint8_t cbor_buf[128] = { 0 }; - static ssize_t _saul_type_handler(coap_pkt_t* pdu, uint8_t *buf, size_t len, void *ctx) { uint8_t type = *((uint8_t *)ctx); From 3b1bc1e4f7777c87c90fc8077b75c77cf0261cd6 Mon Sep 17 00:00:00 2001 From: Micha Rosenbaum Date: Mon, 18 Nov 2019 18:14:55 +0100 Subject: [PATCH 08/16] Return size of cbor buffer on success (or -1) --- saul_coap.c | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/saul_coap.c b/saul_coap.c index 96818cd..61706dd 100644 --- a/saul_coap.c +++ b/saul_coap.c @@ -164,64 +164,66 @@ static ssize_t _saul_sensortype_handler(coap_pkt_t* pdu, uint8_t *buf, size_t le return _saul_type_handler(pdu, buf, len, &type); } -void export_phydat_to_cbor(CborEncoder *encoder, uint8_t *cbor_buf, size_t buf_len, phydat_t data, int dim) +size_t export_phydat_to_cbor(CborEncoder *encoder, uint8_t *cbor_buf, size_t buf_len, phydat_t data, int dim) { CborEncoder mapEncoder, aryEncoder; CborError err = CborNoError; cbor_encoder_init(encoder, cbor_buf, buf_len, 0); if (err != CborNoError) { - return; + return -1; } err = cbor_encoder_create_map(encoder, &mapEncoder, 3); if (err != CborNoError) { - return; + return -1; } err = cbor_encode_text_stringz(&mapEncoder, "va"); if (err != CborNoError) { - return; + return -1; } err = cbor_encoder_create_array(&mapEncoder, &aryEncoder, dim); if (err != CborNoError) { - return; + return -1; } for (uint8_t i = 0; i < dim; i++) { err = cbor_encode_int(&aryEncoder, data.val[i]); if (err != CborNoError) { - return; + return -1; } } err = cbor_encoder_close_container(&mapEncoder, &aryEncoder); if (err != CborNoError) { - return; + return -1; } err = cbor_encode_text_stringz(&mapEncoder, "unit"); if (err != CborNoError) { - return; + return -1; } err = cbor_encode_int(&mapEncoder, data.unit); if (err != CborNoError) { - return; + return -1; } err = cbor_encode_text_stringz(&mapEncoder, "scale"); if (err != CborNoError) { - return; + return -1; } err = cbor_encode_int(&mapEncoder, data.scale); if (err != CborNoError) { - return; + return -1; } cbor_encoder_close_container(encoder, &mapEncoder); + + return cbor_encoder_get_buffer_size(encoder, cbor_buf); } static ssize_t _saul_type_handler(coap_pkt_t* pdu, uint8_t *buf, size_t len, void *ctx) @@ -262,11 +264,10 @@ static ssize_t _saul_type_handler(coap_pkt_t* pdu, uint8_t *buf, size_t len, voi } } - export_phydat_to_cbor(&encoder, cbor_buf, sizeof(cbor_buf), res, dim); + size_t buf_size = export_phydat_to_cbor(&encoder, cbor_buf, sizeof(cbor_buf), res, dim); - size_t buf_size=cbor_encoder_get_buffer_size(&encoder, cbor_buf); - if (pdu->payload_len >= cbor_encoder_get_buffer_size(&encoder, cbor_buf)) { - memcpy(pdu->payload, cbor_buf, cbor_encoder_get_buffer_size(&encoder, cbor_buf)); + if (buf_size > 0 && pdu->payload_len >= buf_size) { + memcpy(pdu->payload, cbor_buf, buf_size); resp_len += gcoap_response(pdu, buf, len, COAP_CODE_VALID); } else { resp_len = gcoap_response(pdu, buf, len, COAP_CODE_INTERNAL_SERVER_ERROR); From 0718b3117d2f0fc4e36a0778828bd450602651a6 Mon Sep 17 00:00:00 2001 From: Micha Rosenbaum Date: Mon, 25 Nov 2019 15:35:15 +0100 Subject: [PATCH 09/16] Return CborError in export_phydat_to_cbor This could be used to investigate the cause of the error. --- saul_coap.c | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/saul_coap.c b/saul_coap.c index 61706dd..e0661df 100644 --- a/saul_coap.c +++ b/saul_coap.c @@ -164,66 +164,69 @@ static ssize_t _saul_sensortype_handler(coap_pkt_t* pdu, uint8_t *buf, size_t le return _saul_type_handler(pdu, buf, len, &type); } -size_t export_phydat_to_cbor(CborEncoder *encoder, uint8_t *cbor_buf, size_t buf_len, phydat_t data, int dim) +CborError export_phydat_to_cbor(CborEncoder *encoder, uint8_t *cbor_buf, size_t buf_len, phydat_t data, int dim) { CborEncoder mapEncoder, aryEncoder; CborError err = CborNoError; cbor_encoder_init(encoder, cbor_buf, buf_len, 0); if (err != CborNoError) { - return -1; + return err; } err = cbor_encoder_create_map(encoder, &mapEncoder, 3); if (err != CborNoError) { - return -1; + return err; } err = cbor_encode_text_stringz(&mapEncoder, "va"); if (err != CborNoError) { - return -1; + return err; } err = cbor_encoder_create_array(&mapEncoder, &aryEncoder, dim); if (err != CborNoError) { - return -1; + return err; } for (uint8_t i = 0; i < dim; i++) { err = cbor_encode_int(&aryEncoder, data.val[i]); if (err != CborNoError) { - return -1; + return err; } } err = cbor_encoder_close_container(&mapEncoder, &aryEncoder); if (err != CborNoError) { - return -1; + return err; } err = cbor_encode_text_stringz(&mapEncoder, "unit"); if (err != CborNoError) { - return -1; + return err; } err = cbor_encode_int(&mapEncoder, data.unit); if (err != CborNoError) { - return -1; + return err; } err = cbor_encode_text_stringz(&mapEncoder, "scale"); if (err != CborNoError) { - return -1; + return err; } err = cbor_encode_int(&mapEncoder, data.scale); if (err != CborNoError) { - return -1; + return err; } - cbor_encoder_close_container(encoder, &mapEncoder); + err = cbor_encoder_close_container(encoder, &mapEncoder); + if (err != CborNoError) { + return err; + } - return cbor_encoder_get_buffer_size(encoder, cbor_buf); + return CborNoError; } static ssize_t _saul_type_handler(coap_pkt_t* pdu, uint8_t *buf, size_t len, void *ctx) @@ -264,9 +267,11 @@ static ssize_t _saul_type_handler(coap_pkt_t* pdu, uint8_t *buf, size_t len, voi } } - size_t buf_size = export_phydat_to_cbor(&encoder, cbor_buf, sizeof(cbor_buf), res, dim); + CborError cbor_err = export_phydat_to_cbor(&encoder, cbor_buf, sizeof(cbor_buf), res, dim); + + size_t buf_size = cbor_encoder_get_buffer_size(&encoder, cbor_buf); - if (buf_size > 0 && pdu->payload_len >= buf_size) { + if (cbor_err == CborNoError && buf_size > 0 && pdu->payload_len >= buf_size) { memcpy(pdu->payload, cbor_buf, buf_size); resp_len += gcoap_response(pdu, buf, len, COAP_CODE_VALID); } else { From 9d24276b40166813d8fd9c9bf87ad02981910c2f Mon Sep 17 00:00:00 2001 From: Micha Rosenbaum Date: Mon, 25 Nov 2019 15:56:22 +0100 Subject: [PATCH 10/16] Move _saul_type_handler about export_phydat_to_cbor --- saul_coap.c | 108 ++++++++++++++++++++++++++-------------------------- 1 file changed, 55 insertions(+), 53 deletions(-) diff --git a/saul_coap.c b/saul_coap.c index e0661df..dd32322 100644 --- a/saul_coap.c +++ b/saul_coap.c @@ -31,6 +31,8 @@ static ssize_t _saul_dev_handler(coap_pkt_t* pdu, uint8_t *buf, size_t len, void static ssize_t _saul_sensortype_handler(coap_pkt_t* pdu, uint8_t *buf, size_t len, void *ctx); static ssize_t _saul_type_handler(coap_pkt_t* pdu, uint8_t *buf, size_t len, void *ctx); +CborError export_phydat_to_cbor(CborEncoder *encoder, uint8_t *cbor_buf, size_t buf_len, phydat_t data, int dim); + /* supported sense types, used for context pointer in coap_resource_t */ uint8_t class_servo = SAUL_ACT_SERVO; uint8_t class_hum = SAUL_SENSE_HUM; @@ -164,6 +166,59 @@ static ssize_t _saul_sensortype_handler(coap_pkt_t* pdu, uint8_t *buf, size_t le return _saul_type_handler(pdu, buf, len, &type); } +static ssize_t _saul_type_handler(coap_pkt_t* pdu, uint8_t *buf, size_t len, void *ctx) +{ + uint8_t type = *((uint8_t *)ctx); + saul_reg_t *dev = saul_reg_find_type(type); + phydat_t res; + int dim; + size_t resp_len; + CborEncoder encoder; + + gcoap_resp_init(pdu, buf, len, COAP_CODE_CONTENT); + coap_opt_add_format(pdu, COAP_FORMAT_CBOR); + resp_len = coap_opt_finish(pdu, COAP_OPT_FINISH_PAYLOAD); + + if (dev == NULL) { + char *err = "device not found"; + if (pdu->payload_len >= strlen(err)) { + memcpy(pdu->payload, err, strlen(err)); + resp_len += gcoap_response(pdu, buf, len, COAP_CODE_404); + return resp_len; + } + else { + return gcoap_response(pdu, buf, len, COAP_CODE_404); + } + } + + dim = saul_reg_read(dev, &res); + if (dim <= 0) { + char *err = "no values found"; + if (pdu->payload_len >= strlen(err)) { + memcpy(pdu->payload, err, strlen(err)); + resp_len += gcoap_response(pdu, buf, len, COAP_CODE_404); + return resp_len; + } + else { + return gcoap_response(pdu, buf, len, COAP_CODE_404); + } + } + + CborError cbor_err = export_phydat_to_cbor(&encoder, cbor_buf, sizeof(cbor_buf), res, dim); + + size_t buf_size = cbor_encoder_get_buffer_size(&encoder, cbor_buf); + + if (cbor_err == CborNoError && buf_size > 0 && pdu->payload_len >= buf_size) { + memcpy(pdu->payload, cbor_buf, buf_size); + resp_len += gcoap_response(pdu, buf, len, COAP_CODE_VALID); + } else { + resp_len = gcoap_response(pdu, buf, len, COAP_CODE_INTERNAL_SERVER_ERROR); + } + + memset(cbor_buf, 0, sizeof(cbor_buf)); + return resp_len; +} + CborError export_phydat_to_cbor(CborEncoder *encoder, uint8_t *cbor_buf, size_t buf_len, phydat_t data, int dim) { CborEncoder mapEncoder, aryEncoder; @@ -229,59 +284,6 @@ CborError export_phydat_to_cbor(CborEncoder *encoder, uint8_t *cbor_buf, size_t return CborNoError; } -static ssize_t _saul_type_handler(coap_pkt_t* pdu, uint8_t *buf, size_t len, void *ctx) -{ - uint8_t type = *((uint8_t *)ctx); - saul_reg_t *dev = saul_reg_find_type(type); - phydat_t res; - int dim; - size_t resp_len; - CborEncoder encoder; - - gcoap_resp_init(pdu, buf, len, COAP_CODE_CONTENT); - coap_opt_add_format(pdu, COAP_FORMAT_CBOR); - resp_len = coap_opt_finish(pdu, COAP_OPT_FINISH_PAYLOAD); - - if (dev == NULL) { - char *err = "device not found"; - if (pdu->payload_len >= strlen(err)) { - memcpy(pdu->payload, err, strlen(err)); - resp_len += gcoap_response(pdu, buf, len, COAP_CODE_404); - return resp_len; - } - else { - return gcoap_response(pdu, buf, len, COAP_CODE_404); - } - } - - dim = saul_reg_read(dev, &res); - if (dim <= 0) { - char *err = "no values found"; - if (pdu->payload_len >= strlen(err)) { - memcpy(pdu->payload, err, strlen(err)); - resp_len += gcoap_response(pdu, buf, len, COAP_CODE_404); - return resp_len; - } - else { - return gcoap_response(pdu, buf, len, COAP_CODE_404); - } - } - - CborError cbor_err = export_phydat_to_cbor(&encoder, cbor_buf, sizeof(cbor_buf), res, dim); - - size_t buf_size = cbor_encoder_get_buffer_size(&encoder, cbor_buf); - - if (cbor_err == CborNoError && buf_size > 0 && pdu->payload_len >= buf_size) { - memcpy(pdu->payload, cbor_buf, buf_size); - resp_len += gcoap_response(pdu, buf, len, COAP_CODE_VALID); - } else { - resp_len = gcoap_response(pdu, buf, len, COAP_CODE_INTERNAL_SERVER_ERROR); - } - - memset(cbor_buf, 0, sizeof(cbor_buf)); - return resp_len; -} - void saul_coap_init(void) { gcoap_register_listener(&_listener); From 7495be87f332e99c7ac36f340f674b65be75d613 Mon Sep 17 00:00:00 2001 From: Micha Rosenbaum Date: Mon, 25 Nov 2019 16:08:03 +0100 Subject: [PATCH 11/16] Rename phydat values field --- saul_coap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/saul_coap.c b/saul_coap.c index dd32322..dcb2864 100644 --- a/saul_coap.c +++ b/saul_coap.c @@ -234,7 +234,7 @@ CborError export_phydat_to_cbor(CborEncoder *encoder, uint8_t *cbor_buf, size_t return err; } - err = cbor_encode_text_stringz(&mapEncoder, "va"); + err = cbor_encode_text_stringz(&mapEncoder, "values"); if (err != CborNoError) { return err; } From a4a7863f6a953f829a4aba183eb66daf284aa26a Mon Sep 17 00:00:00 2001 From: Micha Rosenbaum Date: Mon, 25 Nov 2019 17:49:20 +0100 Subject: [PATCH 12/16] =?UTF-8?q?Don=E2=80=99t=20try=20to=20send=20the=20r?= =?UTF-8?q?esponse=20with=20payload=20immediatly?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- saul_coap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/saul_coap.c b/saul_coap.c index dcb2864..63d8ea8 100644 --- a/saul_coap.c +++ b/saul_coap.c @@ -210,7 +210,7 @@ static ssize_t _saul_type_handler(coap_pkt_t* pdu, uint8_t *buf, size_t len, voi if (cbor_err == CborNoError && buf_size > 0 && pdu->payload_len >= buf_size) { memcpy(pdu->payload, cbor_buf, buf_size); - resp_len += gcoap_response(pdu, buf, len, COAP_CODE_VALID); + resp_len += buf_size; } else { resp_len = gcoap_response(pdu, buf, len, COAP_CODE_INTERNAL_SERVER_ERROR); } From c241c09bc43d8d50241804c7944f9c64733eecb8 Mon Sep 17 00:00:00 2001 From: Micha Rosenbaum Date: Mon, 25 Nov 2019 18:23:22 +0100 Subject: [PATCH 13/16] Add some very basic documentation to README.md --- README.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/README.md b/README.md index 7920822..5ad7274 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,34 @@ The idea of these resources is, to offer similar functionality as the - `/saul/dev` (POST) needs an ID as argument. Returns some information about the sensor for that ID (name and type). +## Phydat as CBOR + +In all resources by sensor type, we return the `phydat_t` as +[CBOR][]. + +[CBOR Example][]: + +``` +A3 # map(3) + 66 # text(6) + 76616C756573 # "values" + 81 # array(1) + 19 0959 # unsigned(2393) + 64 # text(4) + 756E6974 # "unit" + 02 # unsigned(2) + 65 # text(5) + 7363616C65 # "scale" + 21 # negative(1) +``` + +This translates to the following JSON: + + {"values": [2393], "unit": 2, "scale": -2} + +[cbor]: http://cbor.io/ + +[cbor example]: http://cbor.me/?bytes=A3(66(76616C756573)-81(19.0959)-64(756E6974)-02-65(7363616C65)-21) ## Build and Execute Enter shell with board command (Phytec) From 0f746e2880a1b1b9e1264e0e5c228feb6ccc46c0 Mon Sep 17 00:00:00 2001 From: Micha Rosenbaum Date: Mon, 2 Dec 2019 16:31:24 +0100 Subject: [PATCH 14/16] Update phydat_t as CBOR documentation in README.md --- README.md | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 5ad7274..81c7dfa 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,8 @@ sensors of the same type are ignored. More sensor types need to be manually added to the code base. These paths can be used without knowledge about the RIOT-intern type representation. +Returns `phydat_t` as CBOR; see below for more info. + ### `/sensor` The `/sensor` resource is reachable with an `GET` request. As payload it needs the ID of a saul sensor type (as they are defined in @@ -24,6 +26,8 @@ out of the box. However, the systems calling this resource, need information about the RIOT-intern saul type IDs. This could be used by other RIOT powered boards. +Returns `phydat_t` as CBOR; see below for more info. + [saul.h]: https://github.com/RIOT-OS/RIOT/blob/d42c032998e77e122380b3d270ceedb7fff48cda/drivers/include/saul.h#L74 ### `/saul/cnt` and `/saul/dev` (incomplete) @@ -38,10 +42,8 @@ The idea of these resources is, to offer similar functionality as the ## Phydat as CBOR -In all resources by sensor type, we return the `phydat_t` as -[CBOR][]. - -[CBOR Example][]: +In all resources by sensor type, we return the [`phydat_t` struct][] +as [CBOR][]. [CBOR example][] of an temperature sensor: ``` A3 # map(3) @@ -59,12 +61,22 @@ A3 # map(3) This translates to the following JSON: - {"values": [2393], "unit": 2, "scale": -2} +``` json +{"values": [2393], "unit": 2, "scale": -2} +``` + +Please see the [list of CBOR implementations][] if you want to use +this resource. The documentation of the [`phydat_t` struct][] +explains, how these values have to be interpreted. + +[`phydat_t` struct]: https://riot-os.org/api/structphydat__t.html [cbor]: http://cbor.io/ [cbor example]: http://cbor.me/?bytes=A3(66(76616C756573)-81(19.0959)-64(756E6974)-02-65(7363616C65)-21) +[list of cbor implementations]: http://cbor.io/impls.html + ## Build and Execute Enter shell with board command (Phytec) From 0246832fc96e1e7ca8919095dd89a4a270a32fe0 Mon Sep 17 00:00:00 2001 From: Micha Rosenbaum Date: Mon, 9 Dec 2019 13:15:27 +0100 Subject: [PATCH 15/16] Fix indentation (use spaces instead of tabs) --- saul_coap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/saul_coap.c b/saul_coap.c index 63d8ea8..9ba8811 100644 --- a/saul_coap.c +++ b/saul_coap.c @@ -278,7 +278,7 @@ CborError export_phydat_to_cbor(CborEncoder *encoder, uint8_t *cbor_buf, size_t err = cbor_encoder_close_container(encoder, &mapEncoder); if (err != CborNoError) { - return err; + return err; } return CborNoError; From 643319649963a74d569d6dd6ed96f18e6b287ec4 Mon Sep 17 00:00:00 2001 From: Micha Rosenbaum Date: Mon, 9 Dec 2019 13:24:44 +0100 Subject: [PATCH 16/16] Add more explanation about CBOR to the readme file As-Requested-By: https://github.com/MatthiasBraeuer --- README.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 81c7dfa..9a79526 100644 --- a/README.md +++ b/README.md @@ -40,10 +40,11 @@ The idea of these resources is, to offer similar functionality as the - `/saul/dev` (POST) needs an ID as argument. Returns some information about the sensor for that ID (name and type). -## Phydat as CBOR +## Phydat in Concise Binary Object Representation (CBOR) In all resources by sensor type, we return the [`phydat_t` struct][] -as [CBOR][]. [CBOR example][] of an temperature sensor: +in the [CBOR][] data format. In the following code block, you can see +a [CBOR example][] of what could be returned for a temperature sensor: ``` A3 # map(3) @@ -59,7 +60,8 @@ A3 # map(3) 21 # negative(1) ``` -This translates to the following JSON: +If you want to use this resource, you can parse it to JSON. The +example above translates to the following JSON object: ``` json {"values": [2393], "unit": 2, "scale": -2}