CoAP server ported from Arduino microcoap
Dependencies: EthernetInterface Socket mbed-rtos mbed
coap.h@0:64df7fc091da, 2017-03-23 (annotated)
- Committer:
- rfrenken
- Date:
- Thu Mar 23 16:29:41 2017 +0000
- Revision:
- 0:64df7fc091da
Coap Server ported from Arduino microcoap
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
rfrenken | 0:64df7fc091da | 1 | #ifndef COAP_H |
rfrenken | 0:64df7fc091da | 2 | #define COAP_H 1 |
rfrenken | 0:64df7fc091da | 3 | |
rfrenken | 0:64df7fc091da | 4 | #ifdef __cplusplus |
rfrenken | 0:64df7fc091da | 5 | extern "C" { |
rfrenken | 0:64df7fc091da | 6 | #endif |
rfrenken | 0:64df7fc091da | 7 | |
rfrenken | 0:64df7fc091da | 8 | #include <stdint.h> |
rfrenken | 0:64df7fc091da | 9 | #include <stdbool.h> |
rfrenken | 0:64df7fc091da | 10 | #include <stddef.h> |
rfrenken | 0:64df7fc091da | 11 | |
rfrenken | 0:64df7fc091da | 12 | #define MAXOPT 16 |
rfrenken | 0:64df7fc091da | 13 | |
rfrenken | 0:64df7fc091da | 14 | //http://tools.ietf.org/html/rfc7252#section-3 |
rfrenken | 0:64df7fc091da | 15 | typedef struct |
rfrenken | 0:64df7fc091da | 16 | { |
rfrenken | 0:64df7fc091da | 17 | uint8_t ver; /* CoAP version number */ |
rfrenken | 0:64df7fc091da | 18 | uint8_t t; /* CoAP Message Type */ |
rfrenken | 0:64df7fc091da | 19 | uint8_t tkl; /* Token length: indicates length of the Token field */ |
rfrenken | 0:64df7fc091da | 20 | uint8_t code; /* CoAP status code. Can be request (0.xx), success reponse (2.xx), |
rfrenken | 0:64df7fc091da | 21 | * client error response (4.xx), or rever error response (5.xx) |
rfrenken | 0:64df7fc091da | 22 | * For possible values, see http://tools.ietf.org/html/rfc7252#section-12.1 */ |
rfrenken | 0:64df7fc091da | 23 | uint8_t id[2]; |
rfrenken | 0:64df7fc091da | 24 | } coap_header_t; |
rfrenken | 0:64df7fc091da | 25 | |
rfrenken | 0:64df7fc091da | 26 | typedef struct |
rfrenken | 0:64df7fc091da | 27 | { |
rfrenken | 0:64df7fc091da | 28 | const uint8_t *p; |
rfrenken | 0:64df7fc091da | 29 | size_t len; |
rfrenken | 0:64df7fc091da | 30 | } coap_buffer_t; |
rfrenken | 0:64df7fc091da | 31 | |
rfrenken | 0:64df7fc091da | 32 | typedef struct |
rfrenken | 0:64df7fc091da | 33 | { |
rfrenken | 0:64df7fc091da | 34 | uint8_t *p; |
rfrenken | 0:64df7fc091da | 35 | size_t len; |
rfrenken | 0:64df7fc091da | 36 | } coap_rw_buffer_t; |
rfrenken | 0:64df7fc091da | 37 | |
rfrenken | 0:64df7fc091da | 38 | typedef struct |
rfrenken | 0:64df7fc091da | 39 | { |
rfrenken | 0:64df7fc091da | 40 | uint8_t num; /* Option number. See http://tools.ietf.org/html/rfc7252#section-5.10 */ |
rfrenken | 0:64df7fc091da | 41 | coap_buffer_t buf; /* Option value */ |
rfrenken | 0:64df7fc091da | 42 | } coap_option_t; |
rfrenken | 0:64df7fc091da | 43 | |
rfrenken | 0:64df7fc091da | 44 | typedef struct |
rfrenken | 0:64df7fc091da | 45 | { |
rfrenken | 0:64df7fc091da | 46 | coap_header_t hdr; /* Header of the packet */ |
rfrenken | 0:64df7fc091da | 47 | coap_buffer_t tok; /* Token value, size as specified by hdr.tkl */ |
rfrenken | 0:64df7fc091da | 48 | uint8_t numopts; /* Number of options */ |
rfrenken | 0:64df7fc091da | 49 | coap_option_t opts[MAXOPT]; /* Options of the packet. For possible entries see |
rfrenken | 0:64df7fc091da | 50 | * http://tools.ietf.org/html/rfc7252#section-5.10 */ |
rfrenken | 0:64df7fc091da | 51 | coap_buffer_t payload; /* Payload carried by the packet */ |
rfrenken | 0:64df7fc091da | 52 | } coap_packet_t; |
rfrenken | 0:64df7fc091da | 53 | |
rfrenken | 0:64df7fc091da | 54 | ///////////////////////////////////////// |
rfrenken | 0:64df7fc091da | 55 | |
rfrenken | 0:64df7fc091da | 56 | //http://tools.ietf.org/html/rfc7252#section-12.2 |
rfrenken | 0:64df7fc091da | 57 | typedef enum |
rfrenken | 0:64df7fc091da | 58 | { |
rfrenken | 0:64df7fc091da | 59 | COAP_OPTION_IF_MATCH = 1, |
rfrenken | 0:64df7fc091da | 60 | COAP_OPTION_URI_HOST = 3, |
rfrenken | 0:64df7fc091da | 61 | COAP_OPTION_ETAG = 4, |
rfrenken | 0:64df7fc091da | 62 | COAP_OPTION_IF_NONE_MATCH = 5, |
rfrenken | 0:64df7fc091da | 63 | COAP_OPTION_OBSERVE = 6, |
rfrenken | 0:64df7fc091da | 64 | COAP_OPTION_URI_PORT = 7, |
rfrenken | 0:64df7fc091da | 65 | COAP_OPTION_LOCATION_PATH = 8, |
rfrenken | 0:64df7fc091da | 66 | COAP_OPTION_URI_PATH = 11, |
rfrenken | 0:64df7fc091da | 67 | COAP_OPTION_CONTENT_FORMAT = 12, |
rfrenken | 0:64df7fc091da | 68 | COAP_OPTION_MAX_AGE = 14, |
rfrenken | 0:64df7fc091da | 69 | COAP_OPTION_URI_QUERY = 15, |
rfrenken | 0:64df7fc091da | 70 | COAP_OPTION_ACCEPT = 17, |
rfrenken | 0:64df7fc091da | 71 | COAP_OPTION_LOCATION_QUERY = 20, |
rfrenken | 0:64df7fc091da | 72 | COAP_OPTION_PROXY_URI = 35, |
rfrenken | 0:64df7fc091da | 73 | COAP_OPTION_PROXY_SCHEME = 39 |
rfrenken | 0:64df7fc091da | 74 | } coap_option_num_t; |
rfrenken | 0:64df7fc091da | 75 | |
rfrenken | 0:64df7fc091da | 76 | //http://tools.ietf.org/html/rfc7252#section-12.1.1 |
rfrenken | 0:64df7fc091da | 77 | typedef enum |
rfrenken | 0:64df7fc091da | 78 | { |
rfrenken | 0:64df7fc091da | 79 | COAP_METHOD_GET = 1, |
rfrenken | 0:64df7fc091da | 80 | COAP_METHOD_POST = 2, |
rfrenken | 0:64df7fc091da | 81 | COAP_METHOD_PUT = 3, |
rfrenken | 0:64df7fc091da | 82 | COAP_METHOD_DELETE = 4 |
rfrenken | 0:64df7fc091da | 83 | } coap_method_t; |
rfrenken | 0:64df7fc091da | 84 | |
rfrenken | 0:64df7fc091da | 85 | //http://tools.ietf.org/html/rfc7252#section-12.1.1 |
rfrenken | 0:64df7fc091da | 86 | typedef enum |
rfrenken | 0:64df7fc091da | 87 | { |
rfrenken | 0:64df7fc091da | 88 | COAP_TYPE_CON = 0, |
rfrenken | 0:64df7fc091da | 89 | COAP_TYPE_NONCON = 1, |
rfrenken | 0:64df7fc091da | 90 | COAP_TYPE_ACK = 2, |
rfrenken | 0:64df7fc091da | 91 | COAP_TYPE_RESET = 3 |
rfrenken | 0:64df7fc091da | 92 | } coap_msgtype_t; |
rfrenken | 0:64df7fc091da | 93 | |
rfrenken | 0:64df7fc091da | 94 | //http://tools.ietf.org/html/rfc7252#section-5.2 |
rfrenken | 0:64df7fc091da | 95 | //http://tools.ietf.org/html/rfc7252#section-12.1.2 |
rfrenken | 0:64df7fc091da | 96 | #define MAKE_RSPCODE(clas, det) ((clas << 5) | (det)) |
rfrenken | 0:64df7fc091da | 97 | typedef enum |
rfrenken | 0:64df7fc091da | 98 | { |
rfrenken | 0:64df7fc091da | 99 | COAP_RSPCODE_CONTENT = MAKE_RSPCODE(2, 5), |
rfrenken | 0:64df7fc091da | 100 | COAP_RSPCODE_NOT_FOUND = MAKE_RSPCODE(4, 4), |
rfrenken | 0:64df7fc091da | 101 | COAP_RSPCODE_BAD_REQUEST = MAKE_RSPCODE(4, 0), |
rfrenken | 0:64df7fc091da | 102 | COAP_RSPCODE_CHANGED = MAKE_RSPCODE(2, 4) |
rfrenken | 0:64df7fc091da | 103 | } coap_responsecode_t; |
rfrenken | 0:64df7fc091da | 104 | |
rfrenken | 0:64df7fc091da | 105 | //http://tools.ietf.org/html/rfc7252#section-12.3 |
rfrenken | 0:64df7fc091da | 106 | typedef enum |
rfrenken | 0:64df7fc091da | 107 | { |
rfrenken | 0:64df7fc091da | 108 | COAP_CONTENTTYPE_NONE = -1, // bodge to allow us not to send option block |
rfrenken | 0:64df7fc091da | 109 | COAP_CONTENTTYPE_TEXT_PLAIN = 0, |
rfrenken | 0:64df7fc091da | 110 | COAP_CONTENTTYPE_APPLICATION_LINKFORMAT = 40, |
rfrenken | 0:64df7fc091da | 111 | COAP_CONTENTTYPE_APPLICATION_XML = 41, |
rfrenken | 0:64df7fc091da | 112 | COAP_CONTENTTYPE_APPLICATION_OCTECT_STREAM = 42, |
rfrenken | 0:64df7fc091da | 113 | COAP_CONTENTTYPE_APPLICATION_EXI = 47, |
rfrenken | 0:64df7fc091da | 114 | COAP_CONTENTTYPE_APPLICATION_JSON = 50, |
rfrenken | 0:64df7fc091da | 115 | } coap_content_type_t; |
rfrenken | 0:64df7fc091da | 116 | |
rfrenken | 0:64df7fc091da | 117 | /////////////////////// |
rfrenken | 0:64df7fc091da | 118 | |
rfrenken | 0:64df7fc091da | 119 | typedef enum |
rfrenken | 0:64df7fc091da | 120 | { |
rfrenken | 0:64df7fc091da | 121 | COAP_ERR_NONE = 0, |
rfrenken | 0:64df7fc091da | 122 | COAP_ERR_HEADER_TOO_SHORT = 1, |
rfrenken | 0:64df7fc091da | 123 | COAP_ERR_VERSION_NOT_1 = 2, |
rfrenken | 0:64df7fc091da | 124 | COAP_ERR_TOKEN_TOO_SHORT = 3, |
rfrenken | 0:64df7fc091da | 125 | COAP_ERR_OPTION_TOO_SHORT_FOR_HEADER = 4, |
rfrenken | 0:64df7fc091da | 126 | COAP_ERR_OPTION_TOO_SHORT = 5, |
rfrenken | 0:64df7fc091da | 127 | COAP_ERR_OPTION_OVERRUNS_PACKET = 6, |
rfrenken | 0:64df7fc091da | 128 | COAP_ERR_OPTION_TOO_BIG = 7, |
rfrenken | 0:64df7fc091da | 129 | COAP_ERR_OPTION_LEN_INVALID = 8, |
rfrenken | 0:64df7fc091da | 130 | COAP_ERR_BUFFER_TOO_SMALL = 9, |
rfrenken | 0:64df7fc091da | 131 | COAP_ERR_UNSUPPORTED = 10, |
rfrenken | 0:64df7fc091da | 132 | COAP_ERR_OPTION_DELTA_INVALID = 11, |
rfrenken | 0:64df7fc091da | 133 | } coap_error_t; |
rfrenken | 0:64df7fc091da | 134 | |
rfrenken | 0:64df7fc091da | 135 | /////////////////////// |
rfrenken | 0:64df7fc091da | 136 | |
rfrenken | 0:64df7fc091da | 137 | 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); |
rfrenken | 0:64df7fc091da | 138 | #define MAX_SEGMENTS 2 // 2 = /foo/bar, 3 = /foo/bar/baz |
rfrenken | 0:64df7fc091da | 139 | typedef struct |
rfrenken | 0:64df7fc091da | 140 | { |
rfrenken | 0:64df7fc091da | 141 | int count; |
rfrenken | 0:64df7fc091da | 142 | const char *elems[MAX_SEGMENTS]; |
rfrenken | 0:64df7fc091da | 143 | } coap_endpoint_path_t; |
rfrenken | 0:64df7fc091da | 144 | |
rfrenken | 0:64df7fc091da | 145 | typedef struct |
rfrenken | 0:64df7fc091da | 146 | { |
rfrenken | 0:64df7fc091da | 147 | coap_method_t method; /* (i.e. POST, PUT or GET) */ |
rfrenken | 0:64df7fc091da | 148 | coap_endpoint_func handler; /* callback function which handles this |
rfrenken | 0:64df7fc091da | 149 | * type of endpoint (and calls |
rfrenken | 0:64df7fc091da | 150 | * coap_make_response() at some point) */ |
rfrenken | 0:64df7fc091da | 151 | const coap_endpoint_path_t *path; /* path towards a resource (i.e. foo/bar/) */ |
rfrenken | 0:64df7fc091da | 152 | const char *core_attr; /* the 'ct' attribute, as defined in RFC7252, section 7.2.1.: |
rfrenken | 0:64df7fc091da | 153 | * "The Content-Format code "ct" attribute |
rfrenken | 0:64df7fc091da | 154 | * provides a hint about the |
rfrenken | 0:64df7fc091da | 155 | * Content-Formats this resource returns." |
rfrenken | 0:64df7fc091da | 156 | * (Section 12.3. lists possible ct values.) */ |
rfrenken | 0:64df7fc091da | 157 | } coap_endpoint_t; |
rfrenken | 0:64df7fc091da | 158 | |
rfrenken | 0:64df7fc091da | 159 | |
rfrenken | 0:64df7fc091da | 160 | /////////////////////// |
rfrenken | 0:64df7fc091da | 161 | void coap_dumpPacket(coap_packet_t *pkt); |
rfrenken | 0:64df7fc091da | 162 | int coap_parse(coap_packet_t *pkt, const uint8_t *buf, size_t buflen); |
rfrenken | 0:64df7fc091da | 163 | int coap_buffer_to_string(char *strbuf, size_t strbuflen, const coap_buffer_t *buf); |
rfrenken | 0:64df7fc091da | 164 | const coap_option_t *coap_findOptions(const coap_packet_t *pkt, uint8_t num, uint8_t *count); |
rfrenken | 0:64df7fc091da | 165 | int coap_build(uint8_t *buf, size_t *buflen, const coap_packet_t *pkt); |
rfrenken | 0:64df7fc091da | 166 | void coap_dump(const uint8_t *buf, size_t buflen, bool bare); |
rfrenken | 0:64df7fc091da | 167 | 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); |
rfrenken | 0:64df7fc091da | 168 | int coap_handle_req(coap_rw_buffer_t *scratch, const coap_packet_t *inpkt, coap_packet_t *outpkt); |
rfrenken | 0:64df7fc091da | 169 | void coap_option_nibble(uint32_t value, uint8_t *nibble); |
rfrenken | 0:64df7fc091da | 170 | void coap_setup(void); |
rfrenken | 0:64df7fc091da | 171 | void endpoint_setup(void); |
rfrenken | 0:64df7fc091da | 172 | |
rfrenken | 0:64df7fc091da | 173 | #ifdef __cplusplus |
rfrenken | 0:64df7fc091da | 174 | } |
rfrenken | 0:64df7fc091da | 175 | #endif |
rfrenken | 0:64df7fc091da | 176 | |
rfrenken | 0:64df7fc091da | 177 | #endif |
rfrenken | 0:64df7fc091da | 178 | |
rfrenken | 0:64df7fc091da | 179 | extern const coap_endpoint_t endpoints[]; |