mirror of
https://github.com/obgm/libcoap.git
synced 2026-11-05 01:12:55 +03:00
* POST now returns Location header * check critical options * added option Accept from draft-bormann-coap-misc-06.txt coap-client now has option -A to take list of accepted types
285 lines
12 KiB
C
285 lines
12 KiB
C
/* pdu.h -- CoAP message structure
|
|
*
|
|
* Copyright (C) 2010 Olaf Bergmann <bergmann@tzi.org>
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*/
|
|
|
|
#ifndef _PDU_H_
|
|
#define _PDU_H_
|
|
|
|
#include "config.h"
|
|
#include "list.h"
|
|
#include "uri.h"
|
|
|
|
/* pre-defined constants that reflect defaults for CoAP */
|
|
|
|
#define COAP_DEFAULT_RESPONSE_TIMEOUT 1 /* response timeout in seconds */
|
|
#define COAP_DEFAULT_MAX_RETRANSMIT 5 /* max number of retransmissions */
|
|
#define COAP_DEFAULT_PORT 61616 /* CoAP default UDP port */
|
|
#define COAP_DEFAULT_MAX_AGE 60 /* default maximum object lifetime in seconds */
|
|
#define COAP_MAX_PDU_SIZE 1400 /* maximum size of a CoAP PDU */
|
|
|
|
#define COAP_DEFAULT_VERSION 1 /* version of CoAP supported */
|
|
#define COAP_DEFAULT_SCHEME "coap" /* the default scheme for CoAP URIs */
|
|
#define COAP_DEFAULT_URI_WELLKNOWN ".well-known/core" /* well-known resources URI */
|
|
|
|
/* CoAP message types */
|
|
|
|
#define COAP_MESSAGE_CON 0 /* confirmable message (requires ACK/RST) */
|
|
#define COAP_MESSAGE_NON 1 /* non-confirmable message (one-shot message) */
|
|
#define COAP_MESSAGE_ACK 2 /* used to acknowledge confirmable messages */
|
|
#define COAP_MESSAGE_RST 3 /* indicates error in received messages */
|
|
|
|
/* CoAP request methods */
|
|
|
|
#define COAP_REQUEST_GET 1
|
|
#define COAP_REQUEST_POST 2
|
|
#define COAP_REQUEST_PUT 3
|
|
#define COAP_REQUEST_DELETE 4
|
|
|
|
/* CoAP option types (be sure to update check_critical when adding options */
|
|
|
|
#define COAP_OPTION_CONTENT_TYPE 1 /* C, 8-bit uint, 1 B, 0 (text/plain) */
|
|
#define COAP_OPTION_MAXAGE 2 /* E, variable length, 1--4 B, 60 Seconds */
|
|
#define COAP_OPTION_URI_SCHEME 3 /* C, String, 1-270 B, "coap" */
|
|
#define COAP_OPTION_ETAG 4 /* E, sequence of bytes, 1-4 B, - */
|
|
#define COAP_OPTION_URI_AUTHORITY 5 /* C, String, 1-270 B, "" */
|
|
#define COAP_OPTION_LOCATION 6 /* E, String, 1-270 B, - */
|
|
#define COAP_OPTION_URI_PATH 9 /* C, String, 1-270 B, "" */
|
|
|
|
/* option types from draft-hartke-coap-observe-01 */
|
|
|
|
#define COAP_OPTION_SUBSCRIPTION 10 /* E, Duration, 1 B, 0 */
|
|
|
|
/* selected option types from draft-bormann-coap-misc-04 */
|
|
|
|
#define COAP_OPTION_ACCEPT 8 /* E Sequence of Bytes, 1-n B, - */
|
|
#define COAP_OPTION_TOKEN 11 /* C, Sequence of Bytes, 1-n B, - */
|
|
#define COAP_OPTION_BLOCK 13 /* C, unsigned integer, 1--3 B, 0 */
|
|
#define COAP_OPTION_NOOP 14 /* no-op for fenceposting */
|
|
|
|
/* CoAP result codes (HTTP-Code / 100 * 40 + HTTP-Code % 100) */
|
|
|
|
#define COAP_RESPONSE_100 40 /* 100 Continue */
|
|
#define COAP_RESPONSE_200 80 /* 200 OK */
|
|
#define COAP_RESPONSE_201 81 /* 201 Created */
|
|
#define COAP_RESPONSE_304 124 /* 304 Not Modified */
|
|
#define COAP_RESPONSE_400 160 /* 400 Bad Request */
|
|
#define COAP_RESPONSE_404 164 /* 404 Not Found */
|
|
#define COAP_RESPONSE_405 165 /* 405 Method Not Allowed */
|
|
#define COAP_RESPONSE_415 175 /* 415 Unsupported Media Type */
|
|
#define COAP_RESPONSE_500 200 /* 500 Internal Server Error */
|
|
#define COAP_RESPONSE_504 204 /* 504 Gateway Timeout */
|
|
|
|
/* CoAP media type encoding */
|
|
|
|
#define COAP_MEDIATYPE_TEXT_PLAIN 0 /* text/plain (UTF-8) */
|
|
#define COAP_MEDIATYPE_TEXT_XML 1 /* text/xml (UTF-8) */
|
|
#define COAP_MEDIATYPE_TEXT_CSV 2 /* text/csv (UTF-8) */
|
|
#define COAP_MEDIATYPE_TEXT_HTML 3 /* text/html (UTF-8) */
|
|
#define COAP_MEDIATYPE_IMAGE_GIF 21 /* image/gif */
|
|
#define COAP_MEDIATYPE_IMAGE_JPEG 22 /* image/jpeg */
|
|
#define COAP_MEDIATYPE_IMAGE_PNG 23 /* image/png */
|
|
#define COAP_MEDIATYPE_IMAGE_TIFF 24 /* image/tiff */
|
|
#define COAP_MEDIATYPE_AUDIO_RAW 25 /* audio/raw */
|
|
#define COAP_MEDIATYPE_VIDEO_RAW 26 /* video/raw */
|
|
#define COAP_MEDIATYPE_APPLICATION_LINK_FORMAT 40 /* application/link-format */
|
|
#define COAP_MEDIATYPE_APPLICATION_XML 41 /* application/xml */
|
|
#define COAP_MEDIATYPE_APPLICATION_OCTET_STREAM 42 /* application/octet-stream */
|
|
#define COAP_MEDIATYPE_APPLICATION_RDF_XML 43 /* application/rdf+xml */
|
|
#define COAP_MEDIATYPE_APPLICATION_SOAP_XML 44 /* application/soap+xml */
|
|
#define COAP_MEDIATYPE_APPLICATION_ATOM_XML 45 /* application/atom+xml */
|
|
#define COAP_MEDIATYPE_APPLICATION_XMPP_XML 46 /* application/xmpp+xml */
|
|
#define COAP_MEDIATYPE_APPLICATION_EXI 47 /* application/exi */
|
|
#define COAP_MEDIATYPE_APPLICATION_X_BXML 48 /* application/x-bxml */
|
|
#define COAP_MEDIATYPE_APPLICATION_FASTINFOSET 49 /* application/fastinfoset */
|
|
#define COAP_MEDIATYPE_APPLICATION_SOAP_FASTINFOSET 50 /* application/soap+fastinfoset */
|
|
#define COAP_MEDIATYPE_APPLICATION_JSON 51 /* application/json */
|
|
|
|
#define COAP_MEDIATYPE_ANY 0xff /* any media type */
|
|
|
|
/* CoAP transaction id */
|
|
/*typedef unsigned short coap_tid_t; */
|
|
typedef int coap_tid_t;
|
|
#define COAP_INVALID_TID -1
|
|
|
|
#ifdef WORDS_BIGENDIAN
|
|
typedef struct {
|
|
unsigned int version:2; /* protocol version */
|
|
unsigned int type:2; /* type flag */
|
|
unsigned int optcnt:4; /* number of options following the header */
|
|
unsigned int code:8; /* request method (value 1--10) or response code (value 40-255) */
|
|
unsigned short id; /* transaction id */
|
|
} coap_hdr_t;
|
|
#else
|
|
typedef struct {
|
|
unsigned int optcnt:4; /* number of options following the header */
|
|
unsigned int type:2; /* type flag */
|
|
unsigned int version:2; /* protocol version */
|
|
unsigned int code:8; /* request method (value 1--10) or response code (value 40-255) */
|
|
unsigned short id; /* transaction id (network byte order!) */
|
|
} coap_hdr_t;
|
|
#endif
|
|
|
|
#ifdef WORDS_BIGENDIAN
|
|
typedef union {
|
|
struct { /* short form, to be used when length < 15 */
|
|
unsigned int delta:4; /* option type (expressed as delta) */
|
|
unsigned int length:4; /* number of option bytes (15 indicates extended form) */
|
|
/* 0--14 bytes options */
|
|
} sval;
|
|
struct { /* extended form, to be used when lengt==15 */
|
|
unsigned int delta:4; /* option type (expressed as delta) */
|
|
unsigned int flag:4; /* must be 15! */
|
|
unsigned int length:8; /* length - 15 */
|
|
/* 15--270 bytes options */
|
|
} lval;
|
|
} coap_opt_t;
|
|
#else
|
|
typedef union {
|
|
struct { /* short form, to be used when length < 15 */
|
|
unsigned int length:4; /* number of option bytes (15 indicates extended form) */
|
|
unsigned int delta:4; /* option type (expressed as delta) */
|
|
/* 0--14 bytes options */
|
|
} sval;
|
|
struct { /* extended form, to be used when lengt==15 */
|
|
unsigned int flag:4; /* must be 15! */
|
|
unsigned int delta:4; /* option type (expressed as delta) */
|
|
unsigned int length:8; /* length - 15 */
|
|
/* 15--270 bytes options */
|
|
} lval;
|
|
} coap_opt_t;
|
|
#endif
|
|
|
|
#define COAP_OPT_SVAL(opt) (opt).sval
|
|
#define COAP_OPT_LVAL(opt) (opt).lval
|
|
#define COAP_OPT_ISEXTENDED(opt) (COAP_OPT_LVAL(opt).flag == 15)
|
|
|
|
/* these macros should be used to access fields from coap_opt_t */
|
|
#define COAP_OPT_DELTA(opt) COAP_OPT_SVAL(opt).delta
|
|
#define COAP_OPT_SETDELTA(opt,val) COAP_OPT_SVAL(opt).delta = (val)
|
|
|
|
#define COAP_OPT_LENGTH(opt) \
|
|
( COAP_OPT_ISEXTENDED(opt) ? COAP_OPT_LVAL(opt).length + 15 : COAP_OPT_SVAL(opt).length )
|
|
|
|
#define COAP_OPT_SETLENGTH(opt,val) \
|
|
if ( (val) < 15 ) \
|
|
COAP_OPT_SVAL(opt).length = (val) & 0x0f; \
|
|
else { \
|
|
COAP_OPT_LVAL(opt).length = ((val) - 15) & 0xff; \
|
|
COAP_OPT_LVAL(opt).flag = 15; \
|
|
}
|
|
|
|
#define COAP_OPT_VALUE(opt) \
|
|
( (unsigned char *)&(opt) + ( COAP_OPT_ISEXTENDED(opt) ? 2 : 1 ) )
|
|
|
|
/* do not forget to adjust this when coap_opt_t is changed! */
|
|
#define COAP_OPT_SIZE(opt) ( COAP_OPT_LENGTH(opt) + ( COAP_OPT_ISEXTENDED(opt) ? 2: 1 ) )
|
|
|
|
/**
|
|
* Structures for more convenient handling of options. (To be used with ordered
|
|
* coap_list_t.) The option's data will be added to the end of the coap_option
|
|
* structure (see macro COAP_OPTION_DATA).
|
|
*/
|
|
typedef struct {
|
|
unsigned short key; /* the option key (no delta coding) */
|
|
unsigned int length;
|
|
#if 0
|
|
union {
|
|
unsigned int n; /* unsigned integer (1--4 bytes) */
|
|
unsigned char fp; /* pseudo-fp (currently, only (8,4) supported */
|
|
unsigned char *d; /* date (4--6 bytes) */
|
|
unsigned char *s; /* string (or sequence of bytes) */
|
|
} value;
|
|
#endif
|
|
} coap_option;
|
|
|
|
#define COAP_OPTION_KEY(option) (option).key
|
|
#define COAP_OPTION_LENGTH(option) (option).length
|
|
#if 0
|
|
#define COAP_OPTION_UINT(option) (option).value.n
|
|
#define COAP_OPTION_PSEUDO_FP(option) (option).value.fp
|
|
#define COAP_OPTION_DATE(option) (option).value.d
|
|
#define COAP_OPTION_STRING(option) (option).value.s
|
|
#endif
|
|
#define COAP_OPTION_DATA(option) ((unsigned char *)&(option) + sizeof(coap_option))
|
|
|
|
/** Header structure for CoAP PDUs */
|
|
|
|
typedef struct {
|
|
coap_hdr_t *hdr;
|
|
unsigned short length; /* PDU length (including header, options, data) */
|
|
coap_list_t *options; /* parsed options */
|
|
unsigned char *data; /* payload */
|
|
} coap_pdu_t;
|
|
|
|
/** Options in coap_pdu_t are accessed with the macro COAP_OPTION. */
|
|
#define COAP_OPTION(node) ((coap_option *)(node)->options)
|
|
|
|
/**
|
|
* Creates a new CoAP PDU. The object is created on the heap and must be released
|
|
* using delete_pdu();
|
|
*/
|
|
|
|
coap_pdu_t *coap_new_pdu();
|
|
void coap_delete_pdu(coap_pdu_t *);
|
|
|
|
#if 0
|
|
int coap_encode_pdu(coap_pdu_t *);
|
|
#endif
|
|
|
|
/**
|
|
* Adds option of given type to pdu that is passed as first parameter. coap_add_option()
|
|
* destroys the PDU's data, so coap_add_data must be called after all options have been
|
|
* added.
|
|
*/
|
|
int coap_add_option(coap_pdu_t *pdu, unsigned char type, unsigned int len, const unsigned char *data);
|
|
coap_opt_t *coap_check_option(coap_pdu_t *pdu, unsigned char type);
|
|
|
|
/**
|
|
* Checks for critical options that we do not know, as requests
|
|
* containing unknown critical options must be discarded. The function
|
|
* returns a pointer to the first unknown critical option in the given
|
|
* pdu (hence with delta-encoded type) or NULL when no unknown critical
|
|
* option was found. The return value contains the type code of the
|
|
* rejected option, or zero if none was found.
|
|
*/
|
|
int coap_check_critical(coap_pdu_t *pdu, coap_opt_t **option);
|
|
|
|
/**
|
|
* Adds given data to the pdu that is passed as first parameter. Note that the PDU's
|
|
* data is destroyed by coap_add_option().
|
|
*/
|
|
int coap_add_data(coap_pdu_t *pdu, unsigned int len, const unsigned char *data);
|
|
|
|
/**
|
|
* Retrieves the length and data pointer of specified PDU. Returns 0 on error
|
|
* or 1 if *len and *data have correct values. Note that these values are
|
|
* destroyed with the pdu.
|
|
*/
|
|
int coap_get_data(coap_pdu_t *pdu, unsigned int *len, unsigned char **data);
|
|
|
|
/**
|
|
* Fills the given coap_uri_t object with the request URI components from
|
|
* the PDU.
|
|
* @param pdu the PDU
|
|
* @param result the URI object to update
|
|
* @return 1 if result has been updated, 0 otherwise, i.e. in case of error
|
|
*/
|
|
int coap_get_request_uri(coap_pdu_t *pdu, coap_uri_t *result);
|
|
|
|
#endif /* _PDU_H_ */
|