CoAP server ported from Arduino microcoap
Dependencies: EthernetInterface Socket mbed-rtos mbed
Diff: coap.h
- Revision:
- 0:64df7fc091da
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/coap.h Thu Mar 23 16:29:41 2017 +0000 @@ -0,0 +1,179 @@ +#ifndef COAP_H +#define COAP_H 1 + +#ifdef __cplusplus +extern "C" { +#endif + +#include <stdint.h> +#include <stdbool.h> +#include <stddef.h> + +#define MAXOPT 16 + +//http://tools.ietf.org/html/rfc7252#section-3 +typedef struct +{ + uint8_t ver; /* CoAP version number */ + uint8_t t; /* CoAP Message Type */ + uint8_t tkl; /* Token length: indicates length of the Token field */ + uint8_t code; /* CoAP status code. Can be request (0.xx), success reponse (2.xx), + * client error response (4.xx), or rever error response (5.xx) + * For possible values, see http://tools.ietf.org/html/rfc7252#section-12.1 */ + uint8_t id[2]; +} coap_header_t; + +typedef struct +{ + const uint8_t *p; + size_t len; +} coap_buffer_t; + +typedef struct +{ + uint8_t *p; + size_t len; +} coap_rw_buffer_t; + +typedef struct +{ + uint8_t num; /* Option number. See http://tools.ietf.org/html/rfc7252#section-5.10 */ + coap_buffer_t buf; /* Option value */ +} coap_option_t; + +typedef struct +{ + coap_header_t hdr; /* Header of the packet */ + coap_buffer_t tok; /* Token value, size as specified by hdr.tkl */ + uint8_t numopts; /* Number of options */ + coap_option_t opts[MAXOPT]; /* Options of the packet. For possible entries see + * http://tools.ietf.org/html/rfc7252#section-5.10 */ + coap_buffer_t payload; /* Payload carried by the packet */ +} coap_packet_t; + +///////////////////////////////////////// + +//http://tools.ietf.org/html/rfc7252#section-12.2 +typedef enum +{ + COAP_OPTION_IF_MATCH = 1, + COAP_OPTION_URI_HOST = 3, + COAP_OPTION_ETAG = 4, + COAP_OPTION_IF_NONE_MATCH = 5, + COAP_OPTION_OBSERVE = 6, + COAP_OPTION_URI_PORT = 7, + COAP_OPTION_LOCATION_PATH = 8, + COAP_OPTION_URI_PATH = 11, + COAP_OPTION_CONTENT_FORMAT = 12, + COAP_OPTION_MAX_AGE = 14, + COAP_OPTION_URI_QUERY = 15, + COAP_OPTION_ACCEPT = 17, + COAP_OPTION_LOCATION_QUERY = 20, + COAP_OPTION_PROXY_URI = 35, + COAP_OPTION_PROXY_SCHEME = 39 +} coap_option_num_t; + +//http://tools.ietf.org/html/rfc7252#section-12.1.1 +typedef enum +{ + COAP_METHOD_GET = 1, + COAP_METHOD_POST = 2, + COAP_METHOD_PUT = 3, + COAP_METHOD_DELETE = 4 +} coap_method_t; + +//http://tools.ietf.org/html/rfc7252#section-12.1.1 +typedef enum +{ + COAP_TYPE_CON = 0, + COAP_TYPE_NONCON = 1, + COAP_TYPE_ACK = 2, + COAP_TYPE_RESET = 3 +} coap_msgtype_t; + +//http://tools.ietf.org/html/rfc7252#section-5.2 +//http://tools.ietf.org/html/rfc7252#section-12.1.2 +#define MAKE_RSPCODE(clas, det) ((clas << 5) | (det)) +typedef enum +{ + COAP_RSPCODE_CONTENT = MAKE_RSPCODE(2, 5), + COAP_RSPCODE_NOT_FOUND = MAKE_RSPCODE(4, 4), + COAP_RSPCODE_BAD_REQUEST = MAKE_RSPCODE(4, 0), + COAP_RSPCODE_CHANGED = MAKE_RSPCODE(2, 4) +} coap_responsecode_t; + +//http://tools.ietf.org/html/rfc7252#section-12.3 +typedef enum +{ + COAP_CONTENTTYPE_NONE = -1, // bodge to allow us not to send option block + COAP_CONTENTTYPE_TEXT_PLAIN = 0, + COAP_CONTENTTYPE_APPLICATION_LINKFORMAT = 40, + COAP_CONTENTTYPE_APPLICATION_XML = 41, + COAP_CONTENTTYPE_APPLICATION_OCTECT_STREAM = 42, + COAP_CONTENTTYPE_APPLICATION_EXI = 47, + COAP_CONTENTTYPE_APPLICATION_JSON = 50, +} coap_content_type_t; + +/////////////////////// + +typedef enum +{ + COAP_ERR_NONE = 0, + COAP_ERR_HEADER_TOO_SHORT = 1, + COAP_ERR_VERSION_NOT_1 = 2, + COAP_ERR_TOKEN_TOO_SHORT = 3, + COAP_ERR_OPTION_TOO_SHORT_FOR_HEADER = 4, + COAP_ERR_OPTION_TOO_SHORT = 5, + COAP_ERR_OPTION_OVERRUNS_PACKET = 6, + COAP_ERR_OPTION_TOO_BIG = 7, + COAP_ERR_OPTION_LEN_INVALID = 8, + COAP_ERR_BUFFER_TOO_SMALL = 9, + COAP_ERR_UNSUPPORTED = 10, + COAP_ERR_OPTION_DELTA_INVALID = 11, +} coap_error_t; + +/////////////////////// + +typedef int (*coap_endpoint_func)(coap_rw_buffer_t *scratch, const coap_packet_t *inpkt, coap_packet_t *outpkt, uint8_t id_hi, uint8_t id_lo); +#define MAX_SEGMENTS 2 // 2 = /foo/bar, 3 = /foo/bar/baz +typedef struct +{ + int count; + const char *elems[MAX_SEGMENTS]; +} coap_endpoint_path_t; + +typedef struct +{ + coap_method_t method; /* (i.e. POST, PUT or GET) */ + coap_endpoint_func handler; /* callback function which handles this + * type of endpoint (and calls + * coap_make_response() at some point) */ + const coap_endpoint_path_t *path; /* path towards a resource (i.e. foo/bar/) */ + const char *core_attr; /* the 'ct' attribute, as defined in RFC7252, section 7.2.1.: + * "The Content-Format code "ct" attribute + * provides a hint about the + * Content-Formats this resource returns." + * (Section 12.3. lists possible ct values.) */ +} coap_endpoint_t; + + +/////////////////////// +void coap_dumpPacket(coap_packet_t *pkt); +int coap_parse(coap_packet_t *pkt, const uint8_t *buf, size_t buflen); +int coap_buffer_to_string(char *strbuf, size_t strbuflen, const coap_buffer_t *buf); +const coap_option_t *coap_findOptions(const coap_packet_t *pkt, uint8_t num, uint8_t *count); +int coap_build(uint8_t *buf, size_t *buflen, const coap_packet_t *pkt); +void coap_dump(const uint8_t *buf, size_t buflen, bool bare); +int coap_make_response(coap_rw_buffer_t *scratch, coap_packet_t *pkt, const uint8_t *content, size_t content_len, uint8_t msgid_hi, uint8_t msgid_lo, const coap_buffer_t* tok, coap_responsecode_t rspcode, coap_content_type_t content_type); +int coap_handle_req(coap_rw_buffer_t *scratch, const coap_packet_t *inpkt, coap_packet_t *outpkt); +void coap_option_nibble(uint32_t value, uint8_t *nibble); +void coap_setup(void); +void endpoint_setup(void); + +#ifdef __cplusplus +} +#endif + +#endif + +extern const coap_endpoint_t endpoints[]; \ No newline at end of file