pick up wakaama files from https://github.com/eclipse/wakaama
core/er-coap-13/er-coap-13.h@0:c2dff8cbb91a, 2017-04-19 (annotated)
- Committer:
- terencez
- Date:
- Wed Apr 19 11:27:34 2017 +0000
- Revision:
- 0:c2dff8cbb91a
Initial commit
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
terencez | 0:c2dff8cbb91a | 1 | /* |
terencez | 0:c2dff8cbb91a | 2 | * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich |
terencez | 0:c2dff8cbb91a | 3 | * All rights reserved. |
terencez | 0:c2dff8cbb91a | 4 | * |
terencez | 0:c2dff8cbb91a | 5 | * Redistribution and use in source and binary forms, with or without |
terencez | 0:c2dff8cbb91a | 6 | * modification, are permitted provided that the following conditions |
terencez | 0:c2dff8cbb91a | 7 | * are met: |
terencez | 0:c2dff8cbb91a | 8 | * 1. Redistributions of source code must retain the above copyright |
terencez | 0:c2dff8cbb91a | 9 | * notice, this list of conditions and the following disclaimer. |
terencez | 0:c2dff8cbb91a | 10 | * 2. Redistributions in binary form must reproduce the above copyright |
terencez | 0:c2dff8cbb91a | 11 | * notice, this list of conditions and the following disclaimer in the |
terencez | 0:c2dff8cbb91a | 12 | * documentation and/or other materials provided with the distribution. |
terencez | 0:c2dff8cbb91a | 13 | * 3. Neither the name of the Institute nor the names of its contributors |
terencez | 0:c2dff8cbb91a | 14 | * may be used to endorse or promote products derived from this software |
terencez | 0:c2dff8cbb91a | 15 | * without specific prior written permission. |
terencez | 0:c2dff8cbb91a | 16 | * |
terencez | 0:c2dff8cbb91a | 17 | * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND |
terencez | 0:c2dff8cbb91a | 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
terencez | 0:c2dff8cbb91a | 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
terencez | 0:c2dff8cbb91a | 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE |
terencez | 0:c2dff8cbb91a | 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
terencez | 0:c2dff8cbb91a | 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
terencez | 0:c2dff8cbb91a | 23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
terencez | 0:c2dff8cbb91a | 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
terencez | 0:c2dff8cbb91a | 25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
terencez | 0:c2dff8cbb91a | 26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
terencez | 0:c2dff8cbb91a | 27 | * SUCH DAMAGE. |
terencez | 0:c2dff8cbb91a | 28 | * |
terencez | 0:c2dff8cbb91a | 29 | * This file is part of the Contiki operating system. |
terencez | 0:c2dff8cbb91a | 30 | */ |
terencez | 0:c2dff8cbb91a | 31 | |
terencez | 0:c2dff8cbb91a | 32 | /** |
terencez | 0:c2dff8cbb91a | 33 | * \file |
terencez | 0:c2dff8cbb91a | 34 | * An implementation of the Constrained Application Protocol (draft 12) |
terencez | 0:c2dff8cbb91a | 35 | * \author |
terencez | 0:c2dff8cbb91a | 36 | * Matthias Kovatsch <kovatsch@inf.ethz.ch> |
terencez | 0:c2dff8cbb91a | 37 | * \contributors |
terencez | 0:c2dff8cbb91a | 38 | * David Navarro, Intel Corporation - Adapt to usage in liblwm2m |
terencez | 0:c2dff8cbb91a | 39 | */ |
terencez | 0:c2dff8cbb91a | 40 | |
terencez | 0:c2dff8cbb91a | 41 | |
terencez | 0:c2dff8cbb91a | 42 | #ifndef COAP_13_H_ |
terencez | 0:c2dff8cbb91a | 43 | #define COAP_13_H_ |
terencez | 0:c2dff8cbb91a | 44 | |
terencez | 0:c2dff8cbb91a | 45 | #include <stdint.h> |
terencez | 0:c2dff8cbb91a | 46 | #include <stddef.h> /* for size_t */ |
terencez | 0:c2dff8cbb91a | 47 | |
terencez | 0:c2dff8cbb91a | 48 | /* |
terencez | 0:c2dff8cbb91a | 49 | * The maximum buffer size that is provided for resource responses and must be respected due to the limited IP buffer. |
terencez | 0:c2dff8cbb91a | 50 | * Larger data must be handled by the resource and will be sent chunk-wise through a TCP stream or CoAP blocks. |
terencez | 0:c2dff8cbb91a | 51 | */ |
terencez | 0:c2dff8cbb91a | 52 | #ifndef REST_MAX_CHUNK_SIZE |
terencez | 0:c2dff8cbb91a | 53 | #define REST_MAX_CHUNK_SIZE 128 |
terencez | 0:c2dff8cbb91a | 54 | #endif |
terencez | 0:c2dff8cbb91a | 55 | |
terencez | 0:c2dff8cbb91a | 56 | #define COAP_DEFAULT_MAX_AGE 60 |
terencez | 0:c2dff8cbb91a | 57 | #define COAP_RESPONSE_TIMEOUT 2 |
terencez | 0:c2dff8cbb91a | 58 | #define COAP_MAX_RETRANSMIT 4 |
terencez | 0:c2dff8cbb91a | 59 | #define COAP_ACK_RANDOM_FACTOR 1.5 |
terencez | 0:c2dff8cbb91a | 60 | |
terencez | 0:c2dff8cbb91a | 61 | #define COAP_MAX_TRANSMIT_WAIT ((COAP_RESPONSE_TIMEOUT * ( (1 << (COAP_MAX_RETRANSMIT + 1) ) - 1) * COAP_ACK_RANDOM_FACTOR)) |
terencez | 0:c2dff8cbb91a | 62 | |
terencez | 0:c2dff8cbb91a | 63 | #define COAP_HEADER_LEN 4 /* | version:0x03 type:0x0C tkl:0xF0 | code | mid:0x00FF | mid:0xFF00 | */ |
terencez | 0:c2dff8cbb91a | 64 | #define COAP_ETAG_LEN 8 /* The maximum number of bytes for the ETag */ |
terencez | 0:c2dff8cbb91a | 65 | #define COAP_TOKEN_LEN 8 /* The maximum number of bytes for the Token */ |
terencez | 0:c2dff8cbb91a | 66 | #define COAP_MAX_ACCEPT_NUM 2 /* The maximum number of accept preferences to parse/store */ |
terencez | 0:c2dff8cbb91a | 67 | |
terencez | 0:c2dff8cbb91a | 68 | #define COAP_MAX_OPTION_HEADER_LEN 5 |
terencez | 0:c2dff8cbb91a | 69 | |
terencez | 0:c2dff8cbb91a | 70 | #define COAP_HEADER_VERSION_MASK 0xC0 |
terencez | 0:c2dff8cbb91a | 71 | #define COAP_HEADER_VERSION_POSITION 6 |
terencez | 0:c2dff8cbb91a | 72 | #define COAP_HEADER_TYPE_MASK 0x30 |
terencez | 0:c2dff8cbb91a | 73 | #define COAP_HEADER_TYPE_POSITION 4 |
terencez | 0:c2dff8cbb91a | 74 | #define COAP_HEADER_TOKEN_LEN_MASK 0x0F |
terencez | 0:c2dff8cbb91a | 75 | #define COAP_HEADER_TOKEN_LEN_POSITION 0 |
terencez | 0:c2dff8cbb91a | 76 | |
terencez | 0:c2dff8cbb91a | 77 | #define COAP_HEADER_OPTION_DELTA_MASK 0xF0 |
terencez | 0:c2dff8cbb91a | 78 | #define COAP_HEADER_OPTION_SHORT_LENGTH_MASK 0x0F |
terencez | 0:c2dff8cbb91a | 79 | |
terencez | 0:c2dff8cbb91a | 80 | /* |
terencez | 0:c2dff8cbb91a | 81 | * Conservative size limit, as not all options have to be set at the same time. |
terencez | 0:c2dff8cbb91a | 82 | */ |
terencez | 0:c2dff8cbb91a | 83 | #ifndef COAP_MAX_HEADER_SIZE |
terencez | 0:c2dff8cbb91a | 84 | /* Hdr CoT Age Tag Obs Tok Blo strings */ |
terencez | 0:c2dff8cbb91a | 85 | #define COAP_MAX_HEADER_SIZE (4 + 3 + 5 + 1+COAP_ETAG_LEN + 3 + 1+COAP_TOKEN_LEN + 4 + 30) /* 70 */ |
terencez | 0:c2dff8cbb91a | 86 | #endif /* COAP_MAX_HEADER_SIZE */ |
terencez | 0:c2dff8cbb91a | 87 | |
terencez | 0:c2dff8cbb91a | 88 | #define COAP_MAX_PACKET_SIZE (COAP_MAX_HEADER_SIZE + REST_MAX_CHUNK_SIZE) |
terencez | 0:c2dff8cbb91a | 89 | /* 0/14 48 for IPv6 (28 for IPv4) */ |
terencez | 0:c2dff8cbb91a | 90 | #if COAP_MAX_PACKET_SIZE > (UIP_BUFSIZE - UIP_LLH_LEN - UIP_IPUDPH_LEN) |
terencez | 0:c2dff8cbb91a | 91 | //#error "UIP_CONF_BUFFER_SIZE too small for REST_MAX_CHUNK_SIZE" |
terencez | 0:c2dff8cbb91a | 92 | #endif |
terencez | 0:c2dff8cbb91a | 93 | |
terencez | 0:c2dff8cbb91a | 94 | |
terencez | 0:c2dff8cbb91a | 95 | /* Bitmap for set options */ |
terencez | 0:c2dff8cbb91a | 96 | enum { OPTION_MAP_SIZE = sizeof(uint8_t) * 8 }; |
terencez | 0:c2dff8cbb91a | 97 | #define SET_OPTION(packet, opt) ((packet)->options[opt / OPTION_MAP_SIZE] |= 1 << (opt % OPTION_MAP_SIZE)) |
terencez | 0:c2dff8cbb91a | 98 | #define IS_OPTION(packet, opt) ((packet)->options[opt / OPTION_MAP_SIZE] & (1 << (opt % OPTION_MAP_SIZE))) |
terencez | 0:c2dff8cbb91a | 99 | |
terencez | 0:c2dff8cbb91a | 100 | #ifndef MIN |
terencez | 0:c2dff8cbb91a | 101 | #define MIN(a, b) ((a) < (b)? (a) : (b)) |
terencez | 0:c2dff8cbb91a | 102 | #endif /* MIN */ |
terencez | 0:c2dff8cbb91a | 103 | |
terencez | 0:c2dff8cbb91a | 104 | /* CoAP message types */ |
terencez | 0:c2dff8cbb91a | 105 | typedef enum { |
terencez | 0:c2dff8cbb91a | 106 | COAP_TYPE_CON, /* confirmables */ |
terencez | 0:c2dff8cbb91a | 107 | COAP_TYPE_NON, /* non-confirmables */ |
terencez | 0:c2dff8cbb91a | 108 | COAP_TYPE_ACK, /* acknowledgements */ |
terencez | 0:c2dff8cbb91a | 109 | COAP_TYPE_RST /* reset */ |
terencez | 0:c2dff8cbb91a | 110 | } coap_message_type_t; |
terencez | 0:c2dff8cbb91a | 111 | |
terencez | 0:c2dff8cbb91a | 112 | /* CoAP request method codes */ |
terencez | 0:c2dff8cbb91a | 113 | typedef enum { |
terencez | 0:c2dff8cbb91a | 114 | COAP_GET = 1, |
terencez | 0:c2dff8cbb91a | 115 | COAP_POST, |
terencez | 0:c2dff8cbb91a | 116 | COAP_PUT, |
terencez | 0:c2dff8cbb91a | 117 | COAP_DELETE |
terencez | 0:c2dff8cbb91a | 118 | } coap_method_t; |
terencez | 0:c2dff8cbb91a | 119 | |
terencez | 0:c2dff8cbb91a | 120 | /* CoAP response codes */ |
terencez | 0:c2dff8cbb91a | 121 | typedef enum { |
terencez | 0:c2dff8cbb91a | 122 | NO_ERROR = 0, |
terencez | 0:c2dff8cbb91a | 123 | |
terencez | 0:c2dff8cbb91a | 124 | CREATED_2_01 = 65, /* CREATED */ |
terencez | 0:c2dff8cbb91a | 125 | DELETED_2_02 = 66, /* DELETED */ |
terencez | 0:c2dff8cbb91a | 126 | VALID_2_03 = 67, /* NOT_MODIFIED */ |
terencez | 0:c2dff8cbb91a | 127 | CHANGED_2_04 = 68, /* CHANGED */ |
terencez | 0:c2dff8cbb91a | 128 | CONTENT_2_05 = 69, /* OK */ |
terencez | 0:c2dff8cbb91a | 129 | |
terencez | 0:c2dff8cbb91a | 130 | BAD_REQUEST_4_00 = 128, /* BAD_REQUEST */ |
terencez | 0:c2dff8cbb91a | 131 | UNAUTHORIZED_4_01 = 129, /* UNAUTHORIZED */ |
terencez | 0:c2dff8cbb91a | 132 | BAD_OPTION_4_02 = 130, /* BAD_OPTION */ |
terencez | 0:c2dff8cbb91a | 133 | FORBIDDEN_4_03 = 131, /* FORBIDDEN */ |
terencez | 0:c2dff8cbb91a | 134 | NOT_FOUND_4_04 = 132, /* NOT_FOUND */ |
terencez | 0:c2dff8cbb91a | 135 | METHOD_NOT_ALLOWED_4_05 = 133, /* METHOD_NOT_ALLOWED */ |
terencez | 0:c2dff8cbb91a | 136 | NOT_ACCEPTABLE_4_06 = 134, /* NOT_ACCEPTABLE */ |
terencez | 0:c2dff8cbb91a | 137 | PRECONDITION_FAILED_4_12 = 140, /* BAD_REQUEST */ |
terencez | 0:c2dff8cbb91a | 138 | REQUEST_ENTITY_TOO_LARGE_4_13 = 141, /* REQUEST_ENTITY_TOO_LARGE */ |
terencez | 0:c2dff8cbb91a | 139 | UNSUPPORTED_MEDIA_TYPE_4_15 = 143, /* UNSUPPORTED_MEDIA_TYPE */ |
terencez | 0:c2dff8cbb91a | 140 | |
terencez | 0:c2dff8cbb91a | 141 | INTERNAL_SERVER_ERROR_5_00 = 160, /* INTERNAL_SERVER_ERROR */ |
terencez | 0:c2dff8cbb91a | 142 | NOT_IMPLEMENTED_5_01 = 161, /* NOT_IMPLEMENTED */ |
terencez | 0:c2dff8cbb91a | 143 | BAD_GATEWAY_5_02 = 162, /* BAD_GATEWAY */ |
terencez | 0:c2dff8cbb91a | 144 | SERVICE_UNAVAILABLE_5_03 = 163, /* SERVICE_UNAVAILABLE */ |
terencez | 0:c2dff8cbb91a | 145 | GATEWAY_TIMEOUT_5_04 = 164, /* GATEWAY_TIMEOUT */ |
terencez | 0:c2dff8cbb91a | 146 | PROXYING_NOT_SUPPORTED_5_05 = 165, /* PROXYING_NOT_SUPPORTED */ |
terencez | 0:c2dff8cbb91a | 147 | |
terencez | 0:c2dff8cbb91a | 148 | /* Erbium errors */ |
terencez | 0:c2dff8cbb91a | 149 | MEMORY_ALLOCATION_ERROR = 192, |
terencez | 0:c2dff8cbb91a | 150 | PACKET_SERIALIZATION_ERROR, |
terencez | 0:c2dff8cbb91a | 151 | |
terencez | 0:c2dff8cbb91a | 152 | /* Erbium hooks */ |
terencez | 0:c2dff8cbb91a | 153 | MANUAL_RESPONSE |
terencez | 0:c2dff8cbb91a | 154 | |
terencez | 0:c2dff8cbb91a | 155 | } coap_status_t; |
terencez | 0:c2dff8cbb91a | 156 | |
terencez | 0:c2dff8cbb91a | 157 | /* CoAP header options */ |
terencez | 0:c2dff8cbb91a | 158 | typedef enum { |
terencez | 0:c2dff8cbb91a | 159 | COAP_OPTION_IF_MATCH = 1, /* 0-8 B */ |
terencez | 0:c2dff8cbb91a | 160 | COAP_OPTION_URI_HOST = 3, /* 1-255 B */ |
terencez | 0:c2dff8cbb91a | 161 | COAP_OPTION_ETAG = 4, /* 1-8 B */ |
terencez | 0:c2dff8cbb91a | 162 | COAP_OPTION_IF_NONE_MATCH = 5, /* 0 B */ |
terencez | 0:c2dff8cbb91a | 163 | COAP_OPTION_OBSERVE = 6, /* 0-3 B */ |
terencez | 0:c2dff8cbb91a | 164 | COAP_OPTION_URI_PORT = 7, /* 0-2 B */ |
terencez | 0:c2dff8cbb91a | 165 | COAP_OPTION_LOCATION_PATH = 8, /* 0-255 B */ |
terencez | 0:c2dff8cbb91a | 166 | COAP_OPTION_URI_PATH = 11, /* 0-255 B */ |
terencez | 0:c2dff8cbb91a | 167 | COAP_OPTION_CONTENT_TYPE = 12, /* 0-2 B */ |
terencez | 0:c2dff8cbb91a | 168 | COAP_OPTION_MAX_AGE = 14, /* 0-4 B */ |
terencez | 0:c2dff8cbb91a | 169 | COAP_OPTION_URI_QUERY = 15, /* 0-270 B */ |
terencez | 0:c2dff8cbb91a | 170 | COAP_OPTION_ACCEPT = 17, /* 0-2 B */ |
terencez | 0:c2dff8cbb91a | 171 | COAP_OPTION_TOKEN = 19, /* 1-8 B */ |
terencez | 0:c2dff8cbb91a | 172 | COAP_OPTION_LOCATION_QUERY = 20, /* 1-270 B */ |
terencez | 0:c2dff8cbb91a | 173 | COAP_OPTION_BLOCK2 = 23, /* 1-3 B */ |
terencez | 0:c2dff8cbb91a | 174 | COAP_OPTION_BLOCK1 = 27, /* 1-3 B */ |
terencez | 0:c2dff8cbb91a | 175 | COAP_OPTION_SIZE = 28, /* 0-4 B */ |
terencez | 0:c2dff8cbb91a | 176 | COAP_OPTION_PROXY_URI = 35, /* 1-270 B */ |
terencez | 0:c2dff8cbb91a | 177 | OPTION_MAX_VALUE = 0xFFFF |
terencez | 0:c2dff8cbb91a | 178 | } coap_option_t; |
terencez | 0:c2dff8cbb91a | 179 | |
terencez | 0:c2dff8cbb91a | 180 | /* CoAP Content-Types */ |
terencez | 0:c2dff8cbb91a | 181 | typedef enum { |
terencez | 0:c2dff8cbb91a | 182 | TEXT_PLAIN = 0, |
terencez | 0:c2dff8cbb91a | 183 | TEXT_XML = 1, /* Indented types are not in the initial registry. */ |
terencez | 0:c2dff8cbb91a | 184 | TEXT_CSV = 2, |
terencez | 0:c2dff8cbb91a | 185 | TEXT_HTML = 3, |
terencez | 0:c2dff8cbb91a | 186 | IMAGE_GIF = 21, |
terencez | 0:c2dff8cbb91a | 187 | IMAGE_JPEG = 22, |
terencez | 0:c2dff8cbb91a | 188 | IMAGE_PNG = 23, |
terencez | 0:c2dff8cbb91a | 189 | IMAGE_TIFF = 24, |
terencez | 0:c2dff8cbb91a | 190 | AUDIO_RAW = 25, |
terencez | 0:c2dff8cbb91a | 191 | VIDEO_RAW = 26, |
terencez | 0:c2dff8cbb91a | 192 | APPLICATION_LINK_FORMAT = 40, |
terencez | 0:c2dff8cbb91a | 193 | APPLICATION_XML = 41, |
terencez | 0:c2dff8cbb91a | 194 | APPLICATION_OCTET_STREAM = 42, |
terencez | 0:c2dff8cbb91a | 195 | APPLICATION_RDF_XML = 43, |
terencez | 0:c2dff8cbb91a | 196 | APPLICATION_SOAP_XML = 44, |
terencez | 0:c2dff8cbb91a | 197 | APPLICATION_ATOM_XML = 45, |
terencez | 0:c2dff8cbb91a | 198 | APPLICATION_XMPP_XML = 46, |
terencez | 0:c2dff8cbb91a | 199 | APPLICATION_EXI = 47, |
terencez | 0:c2dff8cbb91a | 200 | APPLICATION_FASTINFOSET = 48, |
terencez | 0:c2dff8cbb91a | 201 | APPLICATION_SOAP_FASTINFOSET = 49, |
terencez | 0:c2dff8cbb91a | 202 | APPLICATION_JSON = 50, |
terencez | 0:c2dff8cbb91a | 203 | APPLICATION_X_OBIX_BINARY = 51, |
terencez | 0:c2dff8cbb91a | 204 | CONTENT_MAX_VALUE = 0xFFFF |
terencez | 0:c2dff8cbb91a | 205 | } coap_content_type_t; |
terencez | 0:c2dff8cbb91a | 206 | |
terencez | 0:c2dff8cbb91a | 207 | typedef struct _multi_option_t { |
terencez | 0:c2dff8cbb91a | 208 | struct _multi_option_t *next; |
terencez | 0:c2dff8cbb91a | 209 | uint8_t is_static; |
terencez | 0:c2dff8cbb91a | 210 | uint8_t len; |
terencez | 0:c2dff8cbb91a | 211 | uint8_t *data; |
terencez | 0:c2dff8cbb91a | 212 | } multi_option_t; |
terencez | 0:c2dff8cbb91a | 213 | |
terencez | 0:c2dff8cbb91a | 214 | /* Parsed message struct */ |
terencez | 0:c2dff8cbb91a | 215 | typedef struct { |
terencez | 0:c2dff8cbb91a | 216 | uint8_t *buffer; /* pointer to CoAP header / incoming packet buffer / memory to serialize packet */ |
terencez | 0:c2dff8cbb91a | 217 | |
terencez | 0:c2dff8cbb91a | 218 | uint8_t version; |
terencez | 0:c2dff8cbb91a | 219 | coap_message_type_t type; |
terencez | 0:c2dff8cbb91a | 220 | uint8_t code; |
terencez | 0:c2dff8cbb91a | 221 | uint16_t mid; |
terencez | 0:c2dff8cbb91a | 222 | |
terencez | 0:c2dff8cbb91a | 223 | uint8_t options[COAP_OPTION_PROXY_URI / OPTION_MAP_SIZE + 1]; /* Bitmap to check if option is set */ |
terencez | 0:c2dff8cbb91a | 224 | |
terencez | 0:c2dff8cbb91a | 225 | coap_content_type_t content_type; /* Parse options once and store; allows setting options in random order */ |
terencez | 0:c2dff8cbb91a | 226 | uint32_t max_age; |
terencez | 0:c2dff8cbb91a | 227 | size_t proxy_uri_len; |
terencez | 0:c2dff8cbb91a | 228 | const uint8_t *proxy_uri; |
terencez | 0:c2dff8cbb91a | 229 | uint8_t etag_len; |
terencez | 0:c2dff8cbb91a | 230 | uint8_t etag[COAP_ETAG_LEN]; |
terencez | 0:c2dff8cbb91a | 231 | size_t uri_host_len; |
terencez | 0:c2dff8cbb91a | 232 | const uint8_t *uri_host; |
terencez | 0:c2dff8cbb91a | 233 | multi_option_t *location_path; |
terencez | 0:c2dff8cbb91a | 234 | uint16_t uri_port; |
terencez | 0:c2dff8cbb91a | 235 | size_t location_query_len; |
terencez | 0:c2dff8cbb91a | 236 | uint8_t *location_query; |
terencez | 0:c2dff8cbb91a | 237 | multi_option_t *uri_path; |
terencez | 0:c2dff8cbb91a | 238 | uint32_t observe; |
terencez | 0:c2dff8cbb91a | 239 | uint8_t token_len; |
terencez | 0:c2dff8cbb91a | 240 | uint8_t token[COAP_TOKEN_LEN]; |
terencez | 0:c2dff8cbb91a | 241 | uint8_t accept_num; |
terencez | 0:c2dff8cbb91a | 242 | uint16_t accept[COAP_MAX_ACCEPT_NUM]; |
terencez | 0:c2dff8cbb91a | 243 | uint8_t if_match_len; |
terencez | 0:c2dff8cbb91a | 244 | uint8_t if_match[COAP_ETAG_LEN]; |
terencez | 0:c2dff8cbb91a | 245 | uint32_t block2_num; |
terencez | 0:c2dff8cbb91a | 246 | uint8_t block2_more; |
terencez | 0:c2dff8cbb91a | 247 | uint16_t block2_size; |
terencez | 0:c2dff8cbb91a | 248 | uint32_t block2_offset; |
terencez | 0:c2dff8cbb91a | 249 | uint32_t block1_num; |
terencez | 0:c2dff8cbb91a | 250 | uint8_t block1_more; |
terencez | 0:c2dff8cbb91a | 251 | uint16_t block1_size; |
terencez | 0:c2dff8cbb91a | 252 | uint32_t block1_offset; |
terencez | 0:c2dff8cbb91a | 253 | uint32_t size; |
terencez | 0:c2dff8cbb91a | 254 | multi_option_t *uri_query; |
terencez | 0:c2dff8cbb91a | 255 | uint8_t if_none_match; |
terencez | 0:c2dff8cbb91a | 256 | |
terencez | 0:c2dff8cbb91a | 257 | uint16_t payload_len; |
terencez | 0:c2dff8cbb91a | 258 | uint8_t *payload; |
terencez | 0:c2dff8cbb91a | 259 | |
terencez | 0:c2dff8cbb91a | 260 | } coap_packet_t; |
terencez | 0:c2dff8cbb91a | 261 | |
terencez | 0:c2dff8cbb91a | 262 | /* Option format serialization*/ |
terencez | 0:c2dff8cbb91a | 263 | #define COAP_SERIALIZE_INT_OPTION(number, field, text) \ |
terencez | 0:c2dff8cbb91a | 264 | if (IS_OPTION(coap_pkt, number)) { \ |
terencez | 0:c2dff8cbb91a | 265 | PRINTF(text" [%u]\n", coap_pkt->field); \ |
terencez | 0:c2dff8cbb91a | 266 | option += coap_serialize_int_option(number, current_number, option, coap_pkt->field); \ |
terencez | 0:c2dff8cbb91a | 267 | current_number = number; \ |
terencez | 0:c2dff8cbb91a | 268 | } |
terencez | 0:c2dff8cbb91a | 269 | #define COAP_SERIALIZE_BYTE_OPTION(number, field, text) \ |
terencez | 0:c2dff8cbb91a | 270 | if (IS_OPTION(coap_pkt, number)) { \ |
terencez | 0:c2dff8cbb91a | 271 | PRINTF(text" %u [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n", coap_pkt->field##_len, \ |
terencez | 0:c2dff8cbb91a | 272 | coap_pkt->field[0], \ |
terencez | 0:c2dff8cbb91a | 273 | coap_pkt->field[1], \ |
terencez | 0:c2dff8cbb91a | 274 | coap_pkt->field[2], \ |
terencez | 0:c2dff8cbb91a | 275 | coap_pkt->field[3], \ |
terencez | 0:c2dff8cbb91a | 276 | coap_pkt->field[4], \ |
terencez | 0:c2dff8cbb91a | 277 | coap_pkt->field[5], \ |
terencez | 0:c2dff8cbb91a | 278 | coap_pkt->field[6], \ |
terencez | 0:c2dff8cbb91a | 279 | coap_pkt->field[7] \ |
terencez | 0:c2dff8cbb91a | 280 | ); /*FIXME always prints 8 bytes */ \ |
terencez | 0:c2dff8cbb91a | 281 | option += coap_serialize_array_option(number, current_number, option, coap_pkt->field, coap_pkt->field##_len, '\0'); \ |
terencez | 0:c2dff8cbb91a | 282 | current_number = number; \ |
terencez | 0:c2dff8cbb91a | 283 | } |
terencez | 0:c2dff8cbb91a | 284 | #define COAP_SERIALIZE_STRING_OPTION(number, field, splitter, text) \ |
terencez | 0:c2dff8cbb91a | 285 | if (IS_OPTION(coap_pkt, number)) { \ |
terencez | 0:c2dff8cbb91a | 286 | PRINTF(text" [%.*s]\n", coap_pkt->field##_len, coap_pkt->field); \ |
terencez | 0:c2dff8cbb91a | 287 | option += coap_serialize_array_option(number, current_number, option, (uint8_t *) coap_pkt->field, coap_pkt->field##_len, splitter); \ |
terencez | 0:c2dff8cbb91a | 288 | current_number = number; \ |
terencez | 0:c2dff8cbb91a | 289 | } |
terencez | 0:c2dff8cbb91a | 290 | #define COAP_SERIALIZE_MULTI_OPTION(number, field, text) \ |
terencez | 0:c2dff8cbb91a | 291 | if (IS_OPTION(coap_pkt, number)) { \ |
terencez | 0:c2dff8cbb91a | 292 | PRINTF(text); \ |
terencez | 0:c2dff8cbb91a | 293 | option += coap_serialize_multi_option(number, current_number, option, coap_pkt->field); \ |
terencez | 0:c2dff8cbb91a | 294 | current_number = number; \ |
terencez | 0:c2dff8cbb91a | 295 | } |
terencez | 0:c2dff8cbb91a | 296 | #define COAP_SERIALIZE_ACCEPT_OPTION(number, field, text) \ |
terencez | 0:c2dff8cbb91a | 297 | if (IS_OPTION(coap_pkt, number)) { \ |
terencez | 0:c2dff8cbb91a | 298 | int i; \ |
terencez | 0:c2dff8cbb91a | 299 | for (i=0; i<coap_pkt->field##_num; ++i) \ |
terencez | 0:c2dff8cbb91a | 300 | { \ |
terencez | 0:c2dff8cbb91a | 301 | PRINTF(text" [%u]\n", coap_pkt->field[i]); \ |
terencez | 0:c2dff8cbb91a | 302 | option += coap_serialize_int_option(number, current_number, option, coap_pkt->field[i]); \ |
terencez | 0:c2dff8cbb91a | 303 | current_number = number; \ |
terencez | 0:c2dff8cbb91a | 304 | } \ |
terencez | 0:c2dff8cbb91a | 305 | } |
terencez | 0:c2dff8cbb91a | 306 | #define COAP_SERIALIZE_BLOCK_OPTION(number, field, text) \ |
terencez | 0:c2dff8cbb91a | 307 | if (IS_OPTION(coap_pkt, number)) \ |
terencez | 0:c2dff8cbb91a | 308 | { \ |
terencez | 0:c2dff8cbb91a | 309 | uint32_t block = coap_pkt->field##_num << 4; \ |
terencez | 0:c2dff8cbb91a | 310 | PRINTF(text" [%lu%s (%u B/blk)]\n", coap_pkt->field##_num, coap_pkt->field##_more ? "+" : "", coap_pkt->field##_size); \ |
terencez | 0:c2dff8cbb91a | 311 | if (coap_pkt->field##_more) block |= 0x8; \ |
terencez | 0:c2dff8cbb91a | 312 | block |= 0xF & coap_log_2(coap_pkt->field##_size/16); \ |
terencez | 0:c2dff8cbb91a | 313 | PRINTF(text" encoded: 0x%lX\n", block); \ |
terencez | 0:c2dff8cbb91a | 314 | option += coap_serialize_int_option(number, current_number, option, block); \ |
terencez | 0:c2dff8cbb91a | 315 | current_number = number; \ |
terencez | 0:c2dff8cbb91a | 316 | } |
terencez | 0:c2dff8cbb91a | 317 | |
terencez | 0:c2dff8cbb91a | 318 | /* To store error code and human-readable payload */ |
terencez | 0:c2dff8cbb91a | 319 | extern const char *coap_error_message; |
terencez | 0:c2dff8cbb91a | 320 | |
terencez | 0:c2dff8cbb91a | 321 | uint16_t coap_get_mid(void); |
terencez | 0:c2dff8cbb91a | 322 | |
terencez | 0:c2dff8cbb91a | 323 | void coap_init_message(void *packet, coap_message_type_t type, uint8_t code, uint16_t mid); |
terencez | 0:c2dff8cbb91a | 324 | size_t coap_serialize_get_size(void *packet); |
terencez | 0:c2dff8cbb91a | 325 | size_t coap_serialize_message(void *packet, uint8_t *buffer); |
terencez | 0:c2dff8cbb91a | 326 | coap_status_t coap_parse_message(void *request, uint8_t *data, uint16_t data_len); |
terencez | 0:c2dff8cbb91a | 327 | void coap_free_header(void *packet); |
terencez | 0:c2dff8cbb91a | 328 | |
terencez | 0:c2dff8cbb91a | 329 | char * coap_get_multi_option_as_string(multi_option_t * option); |
terencez | 0:c2dff8cbb91a | 330 | void coap_add_multi_option(multi_option_t **dst, uint8_t *option, size_t option_len, uint8_t is_static); |
terencez | 0:c2dff8cbb91a | 331 | void free_multi_option(multi_option_t *dst); |
terencez | 0:c2dff8cbb91a | 332 | |
terencez | 0:c2dff8cbb91a | 333 | int coap_get_query_variable(void *packet, const char *name, const char **output); |
terencez | 0:c2dff8cbb91a | 334 | int coap_get_post_variable(void *packet, const char *name, const char **output); |
terencez | 0:c2dff8cbb91a | 335 | |
terencez | 0:c2dff8cbb91a | 336 | /*-----------------------------------------------------------------------------------*/ |
terencez | 0:c2dff8cbb91a | 337 | |
terencez | 0:c2dff8cbb91a | 338 | int coap_set_status_code(void *packet, unsigned int code); |
terencez | 0:c2dff8cbb91a | 339 | |
terencez | 0:c2dff8cbb91a | 340 | unsigned int coap_get_header_content_type(void *packet); |
terencez | 0:c2dff8cbb91a | 341 | int coap_set_header_content_type(void *packet, unsigned int content_type); |
terencez | 0:c2dff8cbb91a | 342 | |
terencez | 0:c2dff8cbb91a | 343 | int coap_get_header_accept(void *packet, const uint16_t **accept); |
terencez | 0:c2dff8cbb91a | 344 | int coap_set_header_accept(void *packet, uint16_t accept); |
terencez | 0:c2dff8cbb91a | 345 | |
terencez | 0:c2dff8cbb91a | 346 | int coap_get_header_max_age(void *packet, uint32_t *age); |
terencez | 0:c2dff8cbb91a | 347 | int coap_set_header_max_age(void *packet, uint32_t age); |
terencez | 0:c2dff8cbb91a | 348 | |
terencez | 0:c2dff8cbb91a | 349 | int coap_get_header_etag(void *packet, const uint8_t **etag); |
terencez | 0:c2dff8cbb91a | 350 | int coap_set_header_etag(void *packet, const uint8_t *etag, size_t etag_len); |
terencez | 0:c2dff8cbb91a | 351 | |
terencez | 0:c2dff8cbb91a | 352 | int coap_get_header_if_match(void *packet, const uint8_t **etag); |
terencez | 0:c2dff8cbb91a | 353 | int coap_set_header_if_match(void *packet, const uint8_t *etag, size_t etag_len); |
terencez | 0:c2dff8cbb91a | 354 | |
terencez | 0:c2dff8cbb91a | 355 | int coap_get_header_if_none_match(void *packet); |
terencez | 0:c2dff8cbb91a | 356 | int coap_set_header_if_none_match(void *packet); |
terencez | 0:c2dff8cbb91a | 357 | |
terencez | 0:c2dff8cbb91a | 358 | int coap_get_header_token(void *packet, const uint8_t **token); |
terencez | 0:c2dff8cbb91a | 359 | int coap_set_header_token(void *packet, const uint8_t *token, size_t token_len); |
terencez | 0:c2dff8cbb91a | 360 | |
terencez | 0:c2dff8cbb91a | 361 | int coap_get_header_proxy_uri(void *packet, const char **uri); /* In-place string might not be 0-terminated. */ |
terencez | 0:c2dff8cbb91a | 362 | int coap_set_header_proxy_uri(void *packet, const char *uri); |
terencez | 0:c2dff8cbb91a | 363 | |
terencez | 0:c2dff8cbb91a | 364 | int coap_get_header_uri_host(void *packet, const char **host); /* In-place string might not be 0-terminated. */ |
terencez | 0:c2dff8cbb91a | 365 | int coap_set_header_uri_host(void *packet, const char *host); |
terencez | 0:c2dff8cbb91a | 366 | |
terencez | 0:c2dff8cbb91a | 367 | int coap_get_header_uri_path(void *packet, const char **path); /* In-place string might not be 0-terminated. */ |
terencez | 0:c2dff8cbb91a | 368 | int coap_set_header_uri_path(void *packet, const char *path); |
terencez | 0:c2dff8cbb91a | 369 | int coap_set_header_uri_path_segment(void *packet, const char *path); |
terencez | 0:c2dff8cbb91a | 370 | |
terencez | 0:c2dff8cbb91a | 371 | int coap_get_header_uri_query(void *packet, const char **query); /* In-place string might not be 0-terminated. */ |
terencez | 0:c2dff8cbb91a | 372 | int coap_set_header_uri_query(void *packet, const char *query); |
terencez | 0:c2dff8cbb91a | 373 | |
terencez | 0:c2dff8cbb91a | 374 | int coap_get_header_location_path(void *packet, const char **path); /* In-place string might not be 0-terminated. */ |
terencez | 0:c2dff8cbb91a | 375 | int coap_set_header_location_path(void *packet, const char *path); /* Also splits optional query into Location-Query option. */ |
terencez | 0:c2dff8cbb91a | 376 | |
terencez | 0:c2dff8cbb91a | 377 | int coap_get_header_location_query(void *packet, const char **query); /* In-place string might not be 0-terminated. */ |
terencez | 0:c2dff8cbb91a | 378 | int coap_set_header_location_query(void *packet, char *query); |
terencez | 0:c2dff8cbb91a | 379 | |
terencez | 0:c2dff8cbb91a | 380 | int coap_get_header_observe(void *packet, uint32_t *observe); |
terencez | 0:c2dff8cbb91a | 381 | int coap_set_header_observe(void *packet, uint32_t observe); |
terencez | 0:c2dff8cbb91a | 382 | |
terencez | 0:c2dff8cbb91a | 383 | int coap_get_header_block2(void *packet, uint32_t *num, uint8_t *more, uint16_t *size, uint32_t *offset); |
terencez | 0:c2dff8cbb91a | 384 | int coap_set_header_block2(void *packet, uint32_t num, uint8_t more, uint16_t size); |
terencez | 0:c2dff8cbb91a | 385 | |
terencez | 0:c2dff8cbb91a | 386 | int coap_get_header_block1(void *packet, uint32_t *num, uint8_t *more, uint16_t *size, uint32_t *offset); |
terencez | 0:c2dff8cbb91a | 387 | int coap_set_header_block1(void *packet, uint32_t num, uint8_t more, uint16_t size); |
terencez | 0:c2dff8cbb91a | 388 | |
terencez | 0:c2dff8cbb91a | 389 | int coap_get_header_size(void *packet, uint32_t *size); |
terencez | 0:c2dff8cbb91a | 390 | int coap_set_header_size(void *packet, uint32_t size); |
terencez | 0:c2dff8cbb91a | 391 | |
terencez | 0:c2dff8cbb91a | 392 | int coap_get_payload(void *packet, const uint8_t **payload); |
terencez | 0:c2dff8cbb91a | 393 | int coap_set_payload(void *packet, const void *payload, size_t length); |
terencez | 0:c2dff8cbb91a | 394 | |
terencez | 0:c2dff8cbb91a | 395 | #endif /* COAP_13_H_ */ |