diff --git a/Makefile b/Makefile index 3f4f3fc..e9b55cb 100644 --- a/Makefile +++ b/Makefile @@ -53,4 +53,11 @@ DEVELHELP ?= 1 # Change this to 0 show compiler invocation lines by default: QUIET ?= 1 +# Include tinycbor for data representation +USEPKG += tinycbor +INCLUDE += $(RIOTPKG)/tinycbor/cbor.h + +CFLAGS += -DGNRC_IPV6_NIB_CONF_SLAAC=1 + +# Include RIOT Base makefile include $(RIOTBASE)/Makefile.include diff --git a/README.md b/README.md index 8dadc3e..42b1aa8 100644 --- a/README.md +++ b/README.md @@ -76,6 +76,9 @@ interpreted. [list of cbor implementations]: http://cbor.io/impls.html ## Build and Execute + +Directory: X/riot-saul-coap/RIOT/examples/gcoap/ + Enter shell with board command (Phytec) SERIAL=... BOARD=pba-d-01-kw2x BUILD_IN_DOCKER=1 make all flash term @@ -83,3 +86,11 @@ Enter shell with board command (Phytec) To distinguish multiple boards using SERIAL number make list-ttys + +To test get command + + coap get 5683 + +With DTLS, port number is 5684 + + diff --git a/saul_coap.c b/saul_coap.c index 31e7995..9581489 100644 --- a/saul_coap.c +++ b/saul_coap.c @@ -13,7 +13,8 @@ * @file * @brief CoAP endpoint for the SAUL registry * - * @author Micha Rosenbaum + * @author Seojeong Moon + @author Micha Rosenbaum * * @} */ @@ -25,10 +26,20 @@ #include "fmt.h" #include "net/gcoap.h" #include "cbor.h" +#include "phydat.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); static ssize_t _saul_sensortype_handler(coap_pkt_t* pdu, uint8_t *buf, size_t len, void *ctx); +static ssize_t _saul_atr_handler(coap_pkt_t* pdu, uint8_t *buf, size_t len, void *ctx); +static ssize_t _atr_type_responder(coap_pkt_t* pdu, uint8_t *buf, size_t len, uint8_t type); + +/* specific sense type handlers, shortcut via enum in saul.h */ +static ssize_t _sense_temp_handler(coap_pkt_t* pdu, uint8_t *buf, size_t len, void *ctx); +static ssize_t _sense_hum_handler(coap_pkt_t* pdu, uint8_t *buf, size_t len, void *ctx); +static ssize_t _sense_servo_handler(coap_pkt_t* pdu, uint8_t *buf, size_t len, void *ctx); +static ssize_t _sense_press_handler(coap_pkt_t* pdu, uint8_t *buf, size_t len, void *ctx); +static ssize_t _sense_voltage_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, phydat_t data, int dim); @@ -46,6 +57,7 @@ static const coap_resource_t _resources[] = { { "/press", COAP_GET, _saul_type_handler, &class_press }, { "/saul/cnt", COAP_GET, _saul_cnt_handler, NULL }, { "/saul/dev", COAP_POST, _saul_dev_handler, NULL }, + {"/saul/atr", COAP_PUT, _saul_atr_handler, NULL}, { "/sensor", COAP_GET, _saul_sensortype_handler, NULL }, { "/servo", COAP_GET, _saul_type_handler, &class_servo }, { "/temp", COAP_GET, _saul_type_handler, &class_temp }, @@ -172,8 +184,10 @@ static ssize_t _saul_type_handler(coap_pkt_t* pdu, uint8_t *buf, size_t len, voi uint8_t type = *((uint8_t *)ctx); saul_reg_t *dev = saul_reg_find_type(type); phydat_t res; - int dim; + + int dim = 0; size_t resp_len, buf_size = 0; + CborEncoder encoder, aryEncoder; CborError cbor_err = CborNoError; @@ -290,3 +304,162 @@ void saul_coap_init(void) { gcoap_register_listener(&_listener); } + +static ssize_t _saul_atr_handler(coap_pkt_t* pdu, uint8_t *buf, size_t len, void *ctx) +{ + uint8_t type; + + (void)ctx; + + //payload length has to be bigger - edit according to expected size + if (pdu->payload_len <= 5) { + char req_payl[6] = { 0 }; + memcpy(req_payl, (char *)pdu->payload, pdu->payload_len); + type = atoi(req_payl); + } + else { + return gcoap_response(pdu, buf, len, COAP_CODE_BAD_REQUEST); + } + + return _atr_type_responder(pdu, buf, len, type); +} + +static ssize_t _atr_type_responder(coap_pkt_t* pdu, uint8_t *buf, size_t len, uint8_t type) +{ + saul_reg_t *dev = saul_reg_find_type(type); + phydat_t res; + int dim = 0; + size_t resp_len; + gcoap_resp_init(pdu, buf, len, COAP_CODE_CONTENT); + coap_opt_add_format(pdu, COAP_FORMAT_TEXT); + 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 { + phydat_dump(&res, type);//phydat.h + dim = saul_reg_write(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); + } + } + /* write the response buffer with the request device value */ + resp_len += fmt_u16_dec((char *)pdu->payload, res.val[0]); + return resp_len; +} + + +CborError export_cbor_to_phydat(CborParser *parser, uint8_t *cbor_buf, size_t buf_len, phydat_t data, int dim) +{ + //CborParser parser; + CborValue value, r; + bool resultbool; + CborError err = CborNoError; + + //initialize Cbor parser + err = cbor_parser_init(cbor_buf, buf_len, 0, parser, &value); + if (err != CborNoError) { + return err; + } + + //check if map exists + if(!cbor_value_is_map(&value) || cbor_value_is_null(&value)){ + return 0; + } + + //enter container if map exists + //CborError cbor_value_enter_container ( const CborValue * it,CborValue * recursed ) + err = cbor_value_enter_container(&value, &r) ; + if (err != CborNoError) { + return err; + } + + //check for values + if(!cbor_value_is_text_string(&r)){ + return 0; + } + + cbor_value_text_string_equals(&r, "values", &resultbool); + + if(!resultbool){ + return 0; + } + cbor_value_advance(&r); + + if(!cbor_value_is_array(&r)){ + return 0; + } + /***************************************** check ******************************/ + for (uint8_t i = 0; i < dim; i++) { + int16_t *p; + p = data.val; + int temp = *p++; + err = cbor_value_get_int_checked(&r, &temp); + if (err != CborNoError) { + return err; + } + } + + //check for unit + + if(!cbor_value_is_text_string(&r)){ + return 0; + } + + cbor_value_text_string_equals(&r, "unit", &resultbool); + + if(!resultbool){ + return 0; + } + cbor_value_advance(&r); + if(!cbor_value_is_array(&r)){ + return 0; + } + +/* uint8_t unit; */ + int unit = data.unit; + err = cbor_value_get_int_checked(&r, &unit); + if (err != CborNoError) { + return err; + } + + //check for scale + + if(!cbor_value_is_text_string(&r)){ + return 0; + } + + cbor_value_text_string_equals(&r, "scale", &resultbool); + + if(!resultbool){ + return 0; + } + cbor_value_advance(&r); + if(!cbor_value_is_array(&r)){ + return 0; + } + + // int8_t scale; + int scale = data.scale; + err = cbor_value_get_int_checked(&r, &scale); + if (err != CborNoError) { + return err; + } + + return CborNoError; +} + diff --git a/winch.txt b/winch.txt new file mode 100644 index 0000000..4f58714 --- /dev/null +++ b/winch.txt @@ -0,0 +1,78 @@ + + +static int set(const void *dev, phydat_t *data) +{ + const winch_saul_driver *w = (const _saul_driver *) dev; + winch_set(); + return 1; +} + +const saul_driver_t winch_saul_driver = { + .read = saul_notsup, + .write = set, + .type = SAUL_ACT_SERVO +}; + +static ssize_t _saul_winch_handler(coap_pkt_t* pdu, uint8_t *buf, size_t len, void *ctx) +{ + uint8_t type; + + (void)ctx; + + //change payload size - according to expected parameters etc. + if (pdu->payload_len <= 5) { + char req_payl[6] = { 0 }; + memcpy(req_payl, (char *)pdu->payload, pdu->payload_len); + type = atoi(req_payl); + } + else { + return gcoap_response(pdu, buf, len, COAP_CODE_BAD_REQUEST); + } + + return _servo_type_responder(pdu, buf, len, type); +} + +static ssize_t _winch_type_responder(coap_pkt_t* pdu, uint8_t *buf, size_t len, uint8_t type) +{ + saul_reg_t *dev = saul_reg_find_type(type); + phydat_t res; + phydat_t data; + int dim; + size_t resp_len; + gcoap_resp_init(pdu, buf, len, COAP_CODE_CONTENT); + /* option of text and cbor format*/ + 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) { + 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 { + //parse!*** + //parse whatever to phydat + //CborError export_cbor_to_phydat(CborParser *parser, uint8_t *cbor_buf, size_t buf_len, phydat_t data, int dim) + //functions to set phydat_t data to winch actuator: winch_set(dev, &data); + //functions to execute : winch_control (winch_t *winch, int l_ges) + return gcoap_response(pdu, buf, len, COAP_CODE_404); + } + } + 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); + } + } + /* write the response buffer with the request device value */ + resp_len += fmt_u16_dec((char *)pdu->payload, res.val[0]); + return resp_len; +}