/* * Copyright (c) 2015 Cesanta Software Limited * All rights reserved * This software is dual-licensed: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. For the terms of this * license, see <http://www.gnu.org/licenses/>. * * You are free to use this software under the terms of the GNU General * Public License, 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. * * Alternatively, you can license this software under a commercial * license, as set out in <https://www.cesanta.com/license>. */ /* * === CoAP API reference * * CoAP message format: * * ``` * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- * |Ver| T | TKL | Code | Message ID | Token (if any, TKL bytes) ... * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- * | Options (if any) ... |1 1 1 1 1 1 1 1| Payload (if any) ... * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- * ``` */ #ifndef CS_MONGOOSE_SRC_COAP_H_ #define CS_MONGOOSE_SRC_COAP_H_ #if MG_ENABLE_COAP #define MG_COAP_MSG_TYPE_FIELD 0x2 #define MG_COAP_CODE_CLASS_FIELD 0x4 #define MG_COAP_CODE_DETAIL_FIELD 0x8 #define MG_COAP_MSG_ID_FIELD 0x10 #define MG_COAP_TOKEN_FIELD 0x20 #define MG_COAP_OPTIOMG_FIELD 0x40 #define MG_COAP_PAYLOAD_FIELD 0x80 #define MG_COAP_ERROR 0x10000 #define MG_COAP_FORMAT_ERROR (MG_COAP_ERROR | 0x20000) #define MG_COAP_IGNORE (MG_COAP_ERROR | 0x40000) #define MG_COAP_NOT_ENOUGH_DATA (MG_COAP_ERROR | 0x80000) #define MG_COAP_NETWORK_ERROR (MG_COAP_ERROR | 0x100000) #define MG_COAP_MSG_CON 0 #define MG_COAP_MSG_NOC 1 #define MG_COAP_MSG_ACK 2 #define MG_COAP_MSG_RST 3 #define MG_COAP_MSG_MAX 3 #define MG_COAP_CODECLASS_REQUEST 0 #define MG_COAP_CODECLASS_RESP_OK 2 #define MG_COAP_CODECLASS_CLIENT_ERR 4 #define MG_COAP_CODECLASS_SRV_ERR 5 #define MG_COAP_EVENT_BASE 300 #define MG_EV_COAP_CON (MG_COAP_EVENT_BASE + MG_COAP_MSG_CON) #define MG_EV_COAP_NOC (MG_COAP_EVENT_BASE + MG_COAP_MSG_NOC) #define MG_EV_COAP_ACK (MG_COAP_EVENT_BASE + MG_COAP_MSG_ACK) #define MG_EV_COAP_RST (MG_COAP_EVENT_BASE + MG_COAP_MSG_RST) /* * CoAP options. * Use mg_coap_add_option and mg_coap_free_options * for creation and destruction. */ struct mg_coap_option { struct mg_coap_option *next; uint32_t number; struct mg_str value; }; /* CoAP message. See RFC 7252 for details. */ struct mg_coap_message { uint32_t flags; uint8_t msg_type; uint8_t code_class; uint8_t code_detail; uint16_t msg_id; struct mg_str token; struct mg_coap_option *options; struct mg_str payload; struct mg_coap_option *optiomg_tail; }; #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /* Sets CoAP protocol handler - triggers CoAP specific events. */ int mg_set_protocol_coap(struct mg_connection *nc); /* * Adds a new option to mg_coap_message structure. * Returns pointer to the newly created option. * Note: options must be freed by using mg_coap_free_options */ struct mg_coap_option *mg_coap_add_option(struct mg_coap_message *cm, uint32_t number, char *value, size_t len); /* * Frees the memory allocated for options. * If the cm parameter doesn't contain any option it does nothing. */ void mg_coap_free_options(struct mg_coap_message *cm); /* * Composes a CoAP message from `mg_coap_message` * and sends it into `nc` connection. * Returns 0 on success. On error, it is a bitmask: * * - `#define MG_COAP_ERROR 0x10000` * - `#define MG_COAP_FORMAT_ERROR (MG_COAP_ERROR | 0x20000)` * - `#define MG_COAP_IGNORE (MG_COAP_ERROR | 0x40000)` * - `#define MG_COAP_NOT_ENOUGH_DATA (MG_COAP_ERROR | 0x80000)` * - `#define MG_COAP_NETWORK_ERROR (MG_COAP_ERROR | 0x100000)` */ uint32_t mg_coap_send_message(struct mg_connection *nc, struct mg_coap_message *cm); /* * Composes CoAP acknowledgement from `mg_coap_message` * and sends it into `nc` connection. * Return value: see `mg_coap_send_message()` */ uint32_t mg_coap_send_ack(struct mg_connection *nc, uint16_t msg_id); /* * Parses CoAP message and fills mg_coap_message and returns cm->flags. * This is a helper function. * * NOTE: usually CoAP works over UDP, so lack of data means format error. * But, in theory, it is possible to use CoAP over TCP (according to RFC) * * The caller has to check results and treat COAP_NOT_ENOUGH_DATA according to * underlying protocol: * * - in case of UDP COAP_NOT_ENOUGH_DATA means COAP_FORMAT_ERROR, * - in case of TCP client can try to receive more data * * Return value: see `mg_coap_send_message()` */ uint32_t mg_coap_parse(struct mbuf *io, struct mg_coap_message *cm); /* * Composes CoAP message from mg_coap_message structure. * This is a helper function. * Return value: see `mg_coap_send_message()` */ uint32_t mg_coap_compose(struct mg_coap_message *cm, struct mbuf *io); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* MG_ENABLE_COAP */ #endif /* CS_MONGOOSE_SRC_COAP_H_ */