Patrick Barrett / libexositecoap
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers coap.h Source File

coap.h

Go to the documentation of this file.
00001 ///
00002 /// @file    coap.h
00003 /// @author  Patrick Barrett <patrickbarrett@exosite.com>
00004 /// @date    2014-07-10
00005 /// @brief   CoAP Message Parsing
00006 ///
00007 /// @details This file provides functions for parsing and building CoAP message packets
00008 ///          using only the actual binary of the message, not needing additional memory
00009 ///          for secondary data structures.
00010 ///
00011 
00012 #ifndef _COAP_H_
00013 #define _COAP_H_
00014 
00015 #ifdef __cplusplus
00016 extern "C" {
00017 #endif
00018 
00019 #include <stdint.h>
00020 
00021 
00022 ///
00023 /// CoAP Defined Parameters
00024 ///
00025 #define COAP_ACK_TIMEOUT          2
00026 #define COAP_ACK_RANDOM_FACTOR    1.5
00027 #define COAP_MAX_RETRANSMIT       4
00028 #define COAP_NSTART               1
00029 #define COAP_DEFAULT_LEISURE      5
00030 #define COAP_PROBING_RATE         1
00031 
00032 #define COAP_MAX_TRANSMIT_SPAN   45
00033 #define COAP_MAX_TRANSMIT_WAIT   93
00034 #define COAP_MAX_LATENCY        100
00035 #define COAP_PROCESSING_DELAY     2
00036 #define COAP_MAX_RTT            202
00037 #define COAP_EXCHANGE_LIFETIME  247
00038 #define COAP_NON_LIFETIME       145
00039 
00040 
00041 ///
00042 /// Status Codes
00043 ///
00044 /// These codes represent the possible errors that functions in this library can
00045 /// return.
00046 ///
00047 typedef enum coap_error {
00048     CE_NONE = 0,
00049     CE_INVALID_PACKET,
00050     CE_BAD_VERSION,
00051     CE_TOKEN_LENGTH_OUT_OF_RANGE,
00052     CE_UNKNOWN_CODE,
00053     CE_TOO_MANY_OPTIONS,
00054     CE_OUT_OF_ORDER_OPTIONS_LIST,
00055     CE_INSUFFICIENT_BUFFER,
00056     CE_FOUND_PAYLOAD_MARKER,
00057     CE_END_OF_PACKET
00058 } coap_error;
00059 
00060 ///
00061 /// Protocol Versions
00062 ///
00063 /// All known version of the protocol.
00064 ///
00065 typedef enum coap_version {
00066     COAP_V1 = 1
00067 } coap_version;
00068 
00069 ///
00070 /// Message Types
00071 ///
00072 /// The four types of messages possible.
00073 ///
00074 typedef enum coap_type {
00075     CT_CON = 0,
00076     CT_NON = 1,
00077     CT_ACK = 2,
00078     CT_RST = 3
00079 } coap_type;
00080 
00081 ///
00082 /// Message Codes
00083 ///
00084 /// All known message request/response codes.
00085 ///
00086 typedef enum coap_code {
00087     CC_EMPTY = 0,
00088     CC_GET = 1,
00089     CC_POST = 2,
00090     CC_PUT = 3,
00091     CC_DELETE = 4,
00092     CC_CREATED = 65,
00093     CC_DELETED = 66,
00094     CC_VALID = 67,
00095     CC_CHANGED = 68,
00096     CC_CONTENT = 69,
00097     CC_CONTINUE = 95,
00098     CC_BAD_REQUEST = 128,
00099     CC_UNAUTHORIZED = 129,
00100     CC_BAD_OPTION = 130,
00101     CC_FORBIDDEN = 131,
00102     CC_NOT_FOUND = 132,
00103     CC_METHOD_NOT_ALLOWED = 133,
00104     CC_NOT_ACCEPTABLE = 134,
00105     CC_REQUEST_ENTITY_INCOMPLETE = 136,
00106     CC_PRECONDITION_FAILED = 140,
00107     CC_REQUEST_ENTITY_TOO_LARGE = 141,
00108     CC_UNSUPPORTED_CONTENT  = 143,
00109     CC_INTERNAL_SERVER_ERROR = 160,
00110     CC_NOT_IMPLEMENTED = 161,
00111     CC_BAD_GATEWAY = 162,
00112     CC_SERVICE_UNAVAILABLE = 163,
00113     CC_GATEWAY_TIMEOUT = 164,
00114     CC_PROXYING_NOT_SUPPORTED = 165
00115 } coap_code;
00116 
00117 ///
00118 /// Option Numbers
00119 ///
00120 /// All known option numbers.
00121 ///
00122 typedef enum coap_option_number {
00123     CON_IF_MATCH = 1,
00124     CON_URI_HOST = 3,
00125     CON_ETAG = 4,
00126     CON_IF_NONE_MATCH = 5,
00127     CON_OBSERVE = 6,
00128     CON_URI_PORT = 7,
00129     CON_LOCATION_PATH = 8,
00130     CON_URI_PATH = 11,
00131     CON_CONTENT_FORMATt = 12,
00132     CON_MAX_AGE = 14,
00133     CON_URI_QUERY = 15,
00134     CON_ACCEPT = 17,
00135     CON_LOCATION_QUERY = 20,
00136     CON_PROXY_URI = 35,
00137     CON_PROXY_SCHEME = 39,
00138     CON_SIZE1 = 60
00139 } coap_option_number;
00140 
00141 ///
00142 /// Packet Data Unit
00143 ///
00144 /// This contains all information about the message buffer.
00145 ///
00146 typedef struct coap_pdu {
00147     uint8_t *buf;  /// pointer to buffer
00148     size_t len;    /// length of current message
00149     size_t max;    /// size of buffer
00150     uint8_t *opt_ptr; /// Internal Pointer for Option Iterator
00151 } coap_pdu;
00152 
00153 ///
00154 /// CoAP Option
00155 ///
00156 /// One option in a CoAP message.
00157 ///
00158 typedef struct coap_option {
00159     uint16_t num;   /// size of buffer
00160     size_t len; /// length of the value
00161     uint8_t *val;   /// pointer value
00162 } coap_option;
00163 
00164 ///
00165 /// CoAP Payload
00166 ///
00167 /// Payload container.
00168 ///
00169 typedef struct coap_payload {
00170     size_t len; /// length of current message
00171     uint8_t *val;   /// pointer to buffer
00172 } coap_payload;
00173 
00174 
00175 ///
00176 /// Validate Packet
00177 ///
00178 /// Parses the given packet to check if it is a valid CoAP message.
00179 /// This function (or coap_init_pdu for creating new packets) must be
00180 /// called and must return CE_NONE before you can use any of the
00181 /// getters or setter.
00182 /// @param  [in] pdu pointer to the coap message struct.
00183 /// @return error code (CE_NONE == 0 == no error).
00184 /// @see    coap_error
00185 /// @see    coap_init_pdu
00186 ///
00187 coap_error coap_validate_pkt(coap_pdu *pdu);
00188 
00189 //
00190 // Getters
00191 //
00192 
00193 ///
00194 /// Get Version
00195 ///
00196 /// Extracts the CoAP version from the given message.
00197 /// @param  [in] pdu pointer to the coap message struct.
00198 /// @return version.
00199 /// @see coap_version
00200 ///
00201 static inline coap_version  coap_get_version(coap_pdu *pdu) { return pdu->buf[0] >> 6; }
00202 
00203 ///
00204 /// Get Message Type
00205 ///
00206 /// Extracts the message type from the given message.
00207 /// @param  [in] pdu pointer to the coap message struct.
00208 /// @return type.
00209 /// @see coap_type
00210 ///
00211 static inline coap_type coap_get_type(coap_pdu *pdu) { return (pdu->buf[0] >> 4) & 0x03; }
00212 
00213 ///
00214 /// Get Token Length
00215 ///
00216 /// Extracts the token length from the given message.
00217 /// @param  [in] pdu pointer to the coap message struct.
00218 /// @return length.
00219 /// @see coap_type
00220 ///
00221 static inline uint8_t coap_get_tkl(coap_pdu *pdu) { return pdu->buf[0] & 0x0F; }
00222 
00223 ///
00224 /// Get Message Code
00225 ///
00226 /// Extracts the message code from the given message.
00227 /// @param  [in] pdu pointer to the coap message struct.
00228 /// @return code.
00229 /// @see coap_code
00230 ///
00231 static inline coap_code coap_get_code(coap_pdu *pdu) { return pdu->buf[1]; }
00232 
00233 ///
00234 /// Get Message Code Class
00235 ///
00236 /// Gets the class portion of the message code.
00237 /// @param  [in] pdu pointer to the coap message struct.
00238 /// @see    coap_get_code
00239 ///
00240 static inline uint8_t coap_get_code_class(coap_pdu *pdu) { return coap_get_code(pdu) >> 5; }
00241 
00242 ///
00243 /// Get Message Code Detail
00244 ///
00245 /// Gets the detail portion of the message code.
00246 /// @param  [in] pdu pointer to the coap message struct.
00247 /// @see    coap_get_code
00248 ///
00249 static inline uint8_t coap_get_code_detail(coap_pdu *pdu) { return coap_get_code(pdu) & 0x1F; }
00250 
00251 ///
00252 /// Get Message ID
00253 ///
00254 /// Extracts the message ID from the given message.
00255 /// @param  [in] pdu pointer to the coap message struct.
00256 /// @return mid.
00257 ///
00258 static inline uint16_t coap_get_mid(coap_pdu *pdu) { return (pdu->buf[2] << 8) | pdu->buf[3]; }
00259 
00260 ///
00261 /// Get Message Token
00262 ///
00263 /// Extracts the token from the given message.
00264 /// @param  [in] pdu pointer to the coap message struct.
00265 /// @return token.
00266 ///
00267 uint64_t  coap_get_token(coap_pdu *pdu);
00268 
00269 ///
00270 /// Get Option
00271 ///
00272 /// Iterates over the options in the given message.
00273 /// @param  [in]  pdu  pointer to the coap message struct.
00274 /// @param  [in, out]  pointer to the last/next option, pass
00275 ///                    0 for the first option.
00276 /// @return coap_option
00277 ///
00278 coap_option coap_get_option(coap_pdu *pdu, coap_option *last);
00279 
00280 ///
00281 /// Get Option by Option Number
00282 ///
00283 /// Gets a single specified by the option number and index of which occurrence
00284 /// of that option number you'd like.
00285 /// @param  [in]  pdu  pointer to the coap message struct.
00286 /// @param  [in]  num  option number to get.
00287 /// @param  [in]  occ  occurrence of to get (0th, 1st, 2nd, etc)
00288 ///                    0 for the first option.
00289 /// @return coap_option
00290 ///
00291 coap_option coap_get_option_by_num(coap_pdu *pdu, coap_option_number num, uint8_t occ);
00292 
00293 ///
00294 /// Get Option
00295 ///
00296 /// Extracts the option with the given index in the given message.
00297 /// @param  [in]  pdu    pointer to the coap message struct.
00298 /// @return coap_payload
00299 ///
00300 coap_payload coap_get_payload(coap_pdu *pdu);
00301 
00302 ///
00303 /// Internal Method
00304 ///
00305 coap_error coap_decode_option(uint8_t *pkt_ptr, size_t pkt_len,
00306                               uint16_t *option_number, size_t *option_length, uint8_t **value);
00307 
00308 //
00309 // Setters
00310 //
00311 
00312 ///
00313 /// Initialize Packet
00314 ///
00315 /// Initializes on an empty buffer for creating new CoAP packets.
00316 /// This function (or coap_validate for parsing packets) must be
00317 /// called and must return CE_NONE before you can use any of the
00318 /// getters or setter. The packet is initialized to a CoAP Ping.
00319 /// @param  [in, out] pdu pointer to the coap message struct.
00320 /// @return coap_error (0 == no error)
00321 ///
00322 coap_error coap_init_pdu(coap_pdu *pdu);
00323 
00324 ///
00325 /// Set Version
00326 ///
00327 /// Sets the version number header field.
00328 /// @param  [in, out] pdu pointer to the coap message struct.
00329 /// @param  [in]      ver      version to set. Must be COAP_V1.
00330 /// @return coap_error (0 == no error)
00331 /// @see coap_version
00332 ///
00333 coap_error coap_set_version(coap_pdu *pdu, coap_version ver);
00334 
00335 ///
00336 /// Set Message Type
00337 ///
00338 /// Sets the message type header field.
00339 /// @param  [in, out] pdu pointer to the coap message struct.
00340 /// @param  [in]      mtype    type to set.
00341 /// @return coap_error (0 == no error)
00342 /// @see coap_type
00343 ///
00344 coap_error coap_set_type(coap_pdu *pdu, coap_type mtype);
00345 
00346 ///
00347 /// Set Message Code
00348 ///
00349 /// Sets the message type header field.
00350 /// @param  [in, out] pdu pointer to the coap message struct.
00351 /// @param  [in]      code     code to set.
00352 /// @return coap_error (0 == no error)
00353 /// @see coap_code
00354 ///
00355 coap_error coap_set_code(coap_pdu *pdu, coap_code code);
00356 
00357 ///
00358 /// Set Message ID
00359 ///
00360 /// Sets the message ID header field.
00361 /// @param  [in, out] pdu pointer to the coap message struct.
00362 /// @param  [in]      mid      message ID to set.
00363 /// @return coap_error (0 == no error)
00364 ///
00365 coap_error coap_set_mid(coap_pdu *pdu, uint16_t mid);
00366 
00367 ///
00368 /// Set Message Token
00369 ///
00370 /// Sets the message token header field.
00371 /// @param  [in, out] pdu pointer to the coap message struct.
00372 /// @param  [in]      token    token value to set.
00373 /// @return coap_error (0 == no error)
00374 ///
00375 coap_error coap_set_token(coap_pdu *pdu, uint64_t token, uint8_t tkl);
00376 
00377 ///
00378 /// Add Message Option
00379 ///
00380 /// Adds an option to the existing message. Options SHOULD be added in order of
00381 /// option number. In the case of multiple options of the same type, they are 
00382 /// sorted in the order that they are added.
00383 /// @param  [in, out] pdu  pointer to the coap message struct.
00384 /// @param  [in]      opt  option container.
00385 /// @return coap_error (0 == no error)
00386 ///
00387 coap_error coap_add_option(coap_pdu *pdu, int32_t opt_num, uint8_t* value, uint16_t opt_len);
00388 
00389 ///
00390 /// Add Message Option
00391 ///
00392 /// Sets the payload of the given message to the value in `payload`.
00393 /// @param  [in, out] pdu  pointer to the coap message struct.
00394 /// @param  [in]      pl   payload container.
00395 /// @return coap_error (0 == no error)
00396 ///
00397 coap_error coap_set_payload(coap_pdu *pdu, uint8_t *payload, size_t payload_len);
00398 
00399 ///
00400 /// Build Message Code from Class and Detail
00401 ///
00402 /// Gets the class portion of the message code.
00403 /// @param  [in]  class  the code class.
00404 /// @param  [in]  detail the code detail.
00405 /// @see    coap_get_code
00406 ///
00407 static inline uint8_t coap_build_code(uint8_t _class, uint8_t detail) { return (_class << 5) | detail; }
00408 
00409 //
00410 // Internal
00411 //
00412 
00413 ///
00414 /// Internal Method
00415 ///
00416 coap_error coap_adjust_option_deltas(uint8_t *opts, size_t *opts_len, size_t max_len, int32_t offset);
00417 
00418 ///
00419 /// Internal Method
00420 ///
00421 int8_t coap_build_option_header(uint8_t *buf, size_t max_len, int32_t opt_delta, int32_t opt_len);
00422 
00423 ///
00424 /// Internal Method
00425 ///
00426 int8_t coap_compute_option_header_len(int32_t opt_delta, int32_t opt_len);
00427 
00428 #ifdef __cplusplus
00429 }
00430 #endif
00431 
00432 #endif /*_COAP_H_*/
00433