diff --git a/sys/include/net/nanocoap_sock.h b/sys/include/net/nanocoap_sock.h index e7b2c98bb3..7a56581adf 100644 --- a/sys/include/net/nanocoap_sock.h +++ b/sys/include/net/nanocoap_sock.h @@ -51,12 +51,28 @@ int nanocoap_server(sock_udp_ep_t *local, uint8_t *buf, size_t bufsize); * @param[out] buf buffer to write response to * @param[in] len length of @p buffer * - * @returns length of response on success + * @returns length of response payload on success * @returns <0 on error */ ssize_t nanocoap_get(sock_udp_ep_t *remote, const char *path, uint8_t *buf, size_t len); +/** + * @brief Simple synchronous CoAP request + * + * @param[in,out] pkt Packet struct containing the request. Is reused for + * the response + * @param[in] local Local UDP endpoint, may be NULL + * @param[in] remote remote UDP endpoint + * @param[in] len Total length of the buffer associated with the + * request + * + * @returns length of response on success + * @returns <0 on error + */ +ssize_t nanocoap_request(coap_pkt_t *pkt, sock_udp_ep_t *local, + sock_udp_ep_t *remote, size_t len); + #ifdef __cplusplus } #endif diff --git a/sys/net/application_layer/nanocoap/sock.c b/sys/net/application_layer/nanocoap/sock.c index 96c651b298..3de7e104af 100644 --- a/sys/net/application_layer/nanocoap/sock.c +++ b/sys/net/application_layer/nanocoap/sock.c @@ -28,24 +28,22 @@ #define ENABLE_DEBUG (0) #include "debug.h" -ssize_t nanocoap_get(sock_udp_ep_t *remote, const char *path, uint8_t *buf, size_t len) +ssize_t nanocoap_request(coap_pkt_t *pkt, sock_udp_ep_t *local, sock_udp_ep_t *remote, size_t len) { ssize_t res; + size_t pdu_len = (pkt->payload - (uint8_t *)pkt->hdr) + pkt->payload_len; + uint8_t *buf = (uint8_t*)pkt->hdr; sock_udp_t sock; if (!remote->port) { remote->port = COAP_PORT; } - res = sock_udp_create(&sock, NULL, remote, 0); + res = sock_udp_create(&sock, local, remote, 0); if (res < 0) { return res; } - uint8_t *pktpos = buf; - pktpos += coap_build_hdr((coap_hdr_t *)pktpos, COAP_REQ, NULL, 0, COAP_METHOD_GET, 1); - pktpos += coap_put_option_uri(pktpos, 0, path, COAP_OPT_URI_PATH); - /* TODO: timeout random between between ACK_TIMEOUT and (ACK_TIMEOUT * * ACK_RANDOM_FACTOR) */ uint32_t timeout = COAP_ACK_TIMEOUT * (1000000U); @@ -57,7 +55,7 @@ ssize_t nanocoap_get(sock_udp_ep_t *remote, const char *path, uint8_t *buf, size goto out; } - res = sock_udp_send(&sock, buf, pktpos - buf, NULL); + res = sock_udp_send(&sock, buf, pdu_len, NULL); if (res <= 0) { DEBUG("nanocoap: error sending coap request\n"); goto out; @@ -74,22 +72,10 @@ ssize_t nanocoap_get(sock_udp_ep_t *remote, const char *path, uint8_t *buf, size DEBUG("nanocoap: error receiving coap request\n"); break; } - - coap_pkt_t pkt; - if (coap_parse(&pkt, (uint8_t *)buf, res) < 0) { - puts("error parsing packet"); - continue; - } else { - res = coap_get_code(&pkt); - if (res != 205) { - res = -res; - } - else { - if (pkt.payload_len) { - memcpy(buf, pkt.payload, pkt.payload_len); - } - res = pkt.payload_len; + if (coap_parse(pkt, (uint8_t *)buf, res) < 0) { + DEBUG("nanocoap: error parsing packet\n"); + res = -EBADMSG; } break; } @@ -101,6 +87,37 @@ out: return res; } +ssize_t nanocoap_get(sock_udp_ep_t *remote, const char *path, uint8_t *buf, size_t len) +{ + ssize_t res; + coap_pkt_t pkt; + uint8_t *pktpos = buf; + + pkt.hdr = (coap_hdr_t*)buf; + pktpos += coap_build_hdr(pkt.hdr, COAP_REQ, NULL, 0, COAP_METHOD_GET, 1); + pktpos += coap_put_option_uri(pktpos, 0, path, COAP_OPT_URI_PATH); + pkt.payload = pktpos; + pkt.payload_len = 0; + + res = nanocoap_request(&pkt, NULL, remote, len); + if (res < 0) { + return res; + } + else { + res = coap_get_code(&pkt); + if (res != 205) { + res = -res; + } + else { + if (pkt.payload_len) { + memmove(buf, pkt.payload, pkt.payload_len); + } + res = pkt.payload_len; + } + } + return res; +} + int nanocoap_server(sock_udp_ep_t *local, uint8_t *buf, size_t bufsize) { sock_udp_t sock;