h

Dependencies:   C027_Support mbed-dev

Fork of C027_SupportTest_coapp by Umar Naeem

Revision:
34:d6ce8f961b8b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Coap/coap_msg.h	Fri Mar 24 05:42:34 2017 +0000
@@ -0,0 +1,424 @@
+/*
+ * Copyright (c) 2015 Keith Cullen.
+ * All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ *  @file coap_msg.h
+ *
+ *  @brief Include file for the FreeCoAP message parser/formatter library
+ */
+
+#ifndef COAP_MSG_H
+#define COAP_MSG_H
+
+#include <stddef.h>
+
+#define htons(n) (((((unsigned short)(n) & 0xFF)) << 8) | (((unsigned short)(n) & 0xFF00) >> 8))
+#define ntohs(n) (((((unsigned short)(n) & 0xFF)) << 8) | (((unsigned short)(n) & 0xFF00) >> 8))
+
+#define COAP_MSG_VER                           0x01                             /**< CoAP version */
+#define COAP_MSG_MAX_TOKEN_LEN                 8                                /**< Maximum token length */
+#define COAP_MSG_MAX_CODE_CLASS                7                                /**< Maximum code class */
+#define COAP_MSG_MAX_CODE_DETAIL               31                               /**< Maximum code detail */
+#define COAP_MSG_MAX_MSG_ID                    ((1 << 16) - 1)                  /**< Maximum message ID */
+
+#define COAP_MSG_OP_URI_PATH_NUM               11                               /**< Uri-path option number */
+#define COAP_MSG_OP_URI_PATH_MAX_LEN           256                              /**< Maximum buffer length for a reconstructed URI path */
+
+#define COAP_MSG_MAX_BUF_LEN                   1152                             /**< Maximum buffer length for header and payload */
+
+#define coap_msg_op_num_is_critical(num)       ((num) & 1)                      /**< Indicate if an option is critical */
+#define coap_msg_op_num_is_unsafe(num)         ((num) & 2)                      /**< Indicate if an option is unsafe to forward */
+#define coap_msg_op_num_no_cache_key(num)      ((num & 0x1e) == 0x1c)           /**< Indicate if an option is not part of the cache key */
+
+#define coap_msg_op_get_num(op)                ((op)->num)                      /**< Get the option number from an option */
+#define coap_msg_op_set_num(op, num)           ((op)->num = (num))              /**< Set the option number in an option */
+#define coap_msg_op_get_len(op)                ((op)->len)                      /**< Get the option length from an option */
+#define coap_msg_op_set_len(op, len)           ((op)->len = (len))              /**< Set the option length in an option */
+#define coap_msg_op_get_val(op)                ((op)->val)                      /**< Get the option value from an option */
+#define coap_msg_op_set_val(op, val)           ((op)->val = (val))              /**< Set the option value in an option */
+#define coap_msg_op_get_next(op)               ((op)->next)                     /**< Get the next pointer from an option */
+#define coap_msg_op_set_next(op, next_op)      ((op)->next = (next_op))         /**< Set the next pointer in an option */
+
+#define coap_msg_get_ver(msg)                  ((msg)->ver)                     /**< Get the version from a message */
+#define coap_msg_get_type(msg)                 ((msg)->type)                    /**< Get the type from a message */
+#define coap_msg_get_token_len(msg)            ((msg)->token_len)               /**< Get the token length from a message */
+#define coap_msg_get_code_class(msg)           ((msg)->code_class)              /**< Get the code class from a message */
+#define coap_msg_get_code_detail(msg)          ((msg)->code_detail)             /**< Get the code detail from a message */
+#define coap_msg_get_msg_id(msg)               ((msg)->msg_id)                  /**< Get the message ID from message */
+#define coap_msg_get_token(msg)                ((msg)->token)                   /**< Get the token from a message */
+#define coap_msg_get_first_op(msg)             ((msg)->op_list.first)           /**< Get the first option from a message */
+#define coap_msg_get_payload(msg)              ((msg)->payload)                 /**< Get the payload from a message */
+#define coap_msg_get_payload_len(msg)          ((msg)->payload_len)             /**< Get the payload length from a message */
+#define coap_msg_is_empty(msg)                 (((msg)->code_class == 0) && ((msg)->code_detail == 0))
+                                                                                /**< Indicate if a message is empty */
+
+/**
+ *  @brief Message type enumeration
+ */
+typedef enum
+{
+    COAP_MSG_CON = 0x0,                                                         /**< Confirmable message */
+    COAP_MSG_NON = 0x1,                                                         /**< Non-confirmable message */
+    COAP_MSG_ACK = 0x2,                                                         /**< Acknowledgement message */
+    COAP_MSG_RST = 0x3                                                          /**< Reset message */
+}
+coap_msg_type_t;
+
+/**
+ *  @brief Code class enumeration
+ */
+typedef enum
+{
+    COAP_MSG_REQ = 0,                                                           /**< Request */
+    COAP_MSG_SUCCESS = 2,                                                       /**< Success response */
+    COAP_MSG_CLIENT_ERR = 4,                                                    /**< Client error response */
+    COAP_MSG_SERVER_ERR = 5,                                                    /**< Server error response */
+}
+coap_msg_class_t;
+
+/**
+ *  @brief Code detail enumeration
+ */
+typedef enum
+{
+    COAP_MSG_GET = 1,                                                           /**< Get request method */
+    COAP_MSG_POST = 2,                                                          /**< Post request method */
+    COAP_MSG_PUT = 3,                                                           /**< Put request method */
+    COAP_MSG_DELETE =4                                                          /**< Delete request method */
+}
+coap_msg_method_t;
+
+/**
+ *  @brief Success response code detail enumeration
+ */
+typedef enum
+{
+    COAP_MSG_CREATED = 1,                                                       /**< Created success response */
+    COAP_MSG_DELETED = 2,                                                       /**< Deleted success response */
+    COAP_MSG_VALID = 3,                                                         /**< Valid success response */
+    COAP_MSG_CHANGED = 4,                                                       /**< Changed success response */
+    COAP_MSG_CONTENT = 5                                                        /**< Content success response */
+}
+coap_msg_success_t;
+
+/**
+ *  @brief Client error response code detail enumeration
+ */
+typedef enum
+{
+    COAP_MSG_BAD_REQ = 0,                                                       /**< Bad request client error */
+    COAP_MSG_UNAUTHORIZED = 1,                                                  /**< Unauthorized client error */
+    COAP_MSG_BAD_OPTION = 2,                                                    /**< Bad option client error */
+    COAP_MSG_FORBIDDEN = 3,                                                     /**< Forbidden client error */
+    COAP_MSG_NOT_FOUND = 4,                                                     /**< Not found client error */
+    COAP_MSG_METHOD_NOT_ALLOWED = 5,                                            /**< Method not allowed client error */
+    COAP_MSG_NOT_ACCEPTABLE = 6,                                                /**< Not acceptable client error */
+    COAP_MSG_PRECOND_FAILED = 12,                                               /**< Precondition failed client error */
+    COAP_MSG_REQ_ENT_TOO_LARGE = 13,                                            /**< Request entity too large client error */
+    COAP_MSG_UNSUP_CONT_FMT = 15                                                /**< Unsupported content-format client error */
+}
+coap_msg_client_err_t;
+
+/**
+ *  @brief Server error response code detail enumeration
+ */
+typedef enum
+{
+    COAP_MSG_INT_SERVER_ERR = 0,                                                /**< Internal server error */
+    COAP_MSG_NOT_IMPL = 1,                                                      /**< Not implemented server error */
+    COAP_MSG_BAD_GATEWAY = 2,                                                   /**< Bad gateway server error */
+    COAP_MSG_SERV_UNAVAIL = 3,                                                  /**< Service unavailable server error */
+    COAP_MSG_GATEWAY_TIMEOUT = 4,                                               /**< Gateway timeout server error */
+    COAP_MSG_PROXY_NOT_SUP = 5                                                  /**< Proxying not supported server error */
+}
+coap_msg_server_err_t;
+
+/**
+ *  @brief Option number enumeration
+ */
+typedef enum
+{
+    COAP_MSG_IF_MATCH = 1,                                                      /**< If-Match option number */
+    COAP_MSG_URI_HOST = 3,                                                      /**< URI-Host option number */
+    COAP_MSG_ETAG = 4,                                                          /**< Entity-Tag option number */
+    COAP_MSG_IF_NONE_MATCH = 5,                                                 /**< If-None-Match option number */
+    COAP_MSG_URI_PORT = 7,                                                      /**< URI-Port option number */
+    COAP_MSG_LOCATION_PATH = 8,                                                 /**< Location-Path option number */
+    COAP_MSG_URI_PATH = 11,                                                     /**< URI-Path option number */
+    COAP_MSG_CONTENT_FORMAT = 12,                                               /**< Content-Format option number */
+    COAP_MSG_MAX_AGE = 14,                                                      /**< Max-Age option number */
+    COAP_MSG_URI_QUERY = 15,                                                    /**< URI-Query option number */
+    COAP_MSG_ACCEPT = 17,                                                       /**< Accept option number */
+    COAP_MSG_LOCATION_QUERY = 20,                                               /**< Location-Query option number */
+    COAP_MSG_PROXY_URI = 35,                                                    /**< Proxy-URI option number */
+    COAP_MSG_PROXY_SCHEME = 39,                                                 /**< Proxy-Scheme option number */
+    COAP_MSG_SIZE1 = 60                                                         /**< Size1 option number */
+}
+coap_msg_op_num_t;
+
+/**
+ *  @brief Option structure
+ */
+typedef struct coap_msg_op
+{
+    unsigned num;                                                               /**< Option number */
+    unsigned len;                                                               /**< Option length */
+    char *val;                                                                  /**< Pointer to a buffer containing the option value */
+    struct coap_msg_op *next;                                                   /**< Pointer to the next option structure in the list */
+}
+coap_msg_op_t;
+
+/**
+ *  @brief Option linked-list structure
+ */
+typedef struct
+{
+    coap_msg_op_t *first;                                                       /**< Pointer to the first option structure in the list */
+    coap_msg_op_t *last;                                                        /**< Pointer to the last option structure in the list */
+}
+coap_msg_op_list_t;
+
+/**
+ *  @brief Message structure
+ */
+typedef struct
+{
+    unsigned ver;                                                               /**< CoAP version */
+    coap_msg_type_t type;                                                       /**< Message type */
+    unsigned token_len;                                                         /**< Token length */
+    unsigned code_class;                                                        /**< Code class */
+    unsigned code_detail;                                                       /**< Code detail */
+    unsigned msg_id;                                                            /**< Message ID */
+    char token[COAP_MSG_MAX_TOKEN_LEN];                                         /**< Token value */
+    coap_msg_op_list_t op_list;                                                 /**< Option list */
+    char *payload;                                                              /**< Pointer to a buffer containing the payload */
+    size_t payload_len;                                                         /**< Length of the payload */
+}
+coap_msg_t;
+
+/**
+ *  @brief Check if option is recognized
+ *
+ *  @param[in] num Option number
+ *
+ *  @returns Operation status
+ *  @retval 1 Option is recognized
+ *  @retval 0 Option is not recognized
+ */
+int coap_msg_op_num_is_recognized(unsigned num);
+
+/**
+ *  @brief Generate a random string of bytes
+ *
+ *  @param[out] buf Pointer to the buffer to store the random string
+ *  @param[in] len Length of the buffer
+ */
+void coap_msg_gen_rand_str(char *buf, size_t len);
+
+/**
+ *  @brief Initialise a message structure
+ *
+ *  @param[out] msg Pointer to a message structure
+ */
+void coap_msg_create(coap_msg_t *msg);
+
+/**
+ *  @brief Deinitialise a message structure
+ *
+ *  @param[in,out] msg Pointer to a message structure
+ */
+void coap_msg_destroy(coap_msg_t *msg);
+
+/**
+ *  @brief Deinitialise and initialise a message structure
+ *
+ *  @param[in,out] msg Pointer to a message structure
+ */
+void coap_msg_reset(coap_msg_t *msg);
+
+/**
+ *  @brief Check that all of the critical options in a message are recognized
+ *
+ *  @param[in] msg Pointer to message structure
+ *
+ *  @returns Operation status or bad option number
+ *  @retval 0 Success
+ *  @retval >0 Bad option number
+ */
+unsigned coap_msg_check_critical_ops(coap_msg_t *msg);
+
+/**
+ *  @brief Check that all of the unsafe options in a message are recognized
+ *
+ *  @param[in] msg Pointer to message structure
+ *
+ *  @returns Operation status or bad option number
+ *  @retval 0 Success
+ *  @retval >0 Bad option number
+ */
+unsigned coap_msg_check_unsafe_ops(coap_msg_t *msg);
+
+/**
+ *  @brief Extract the type and message ID values from a message
+ *
+ *  If a message contains a format error, this function
+ *  will attempt to extract the type and message ID so
+ *  that a reset message can be returned to the sender.
+ *
+ *  @param[in] buf Pointer to a buffer containing the message
+ *  @param[in] len Length of the buffer
+ *  @param[out] type Pointer to field to store the type value
+ *  @param[out] msg_id Pointer to a field to store the message ID value
+ *
+ *  @returns Operation status
+ *  @retval 0 Success
+ *  @retval <0 Error
+ */
+int coap_msg_parse_type_msg_id(char *buf, size_t len, unsigned *type, unsigned *msg_id);
+
+/**
+ *  @brief Parse a message
+ *
+ *  @param[in,out] msg Pointer to a message structure
+ *  @param[in] buf Pointer to a buffer containing the message
+ *  @param[in] len Length of the buffer
+ *
+ *  @returns Operation status
+ *  @retval 0 Success
+ *  @retval <0 Error
+ */
+int coap_msg_parse(coap_msg_t *msg, char *buf, size_t len);
+
+/**
+ *  @brief Set the type in a message
+ *
+ *  @param[out] msg Pointer to a message structure
+ *  @param[in] type Message type
+ *
+ *  @returns Operation status
+ *  @retval 0 Success
+ *  @retval <0 Error
+ */
+int coap_msg_set_type(coap_msg_t *msg, unsigned type);
+
+/**
+ *  @brief Set the code in a message
+ *
+ *  @param[out] msg Pointer to a message structure
+ *  @param[in] code_class Code class
+ *  @param[in] code_detail Code detail
+ *
+ *  @returns Operation status
+ *  @retval 0 Success
+ *  @retval <0 Error
+ */
+int coap_msg_set_code(coap_msg_t *msg, unsigned code_class, unsigned code_detail);
+
+/**
+ *  @brief Set the message ID in a message
+ *
+ *  @param[out] msg Pointer to a message structure
+ *  @param[in] msg_id Message ID
+ *
+ *  @returns Operation status
+ *  @retval 0 Success
+ *  @retval <0 Error
+ */
+int coap_msg_set_msg_id(coap_msg_t *msg, unsigned msg_id);
+
+/**
+ *  @brief Set the token in a message
+ *
+ *  @param[out] msg Pointer to a message structure
+ *  @param[in] buf Pointer to a buffer containing the token
+ *  @param[in] len Length of the buffer
+ *
+ *  @returns Operation status
+ *  @retval 0 Success
+ *  @retval <0 Error
+ */
+int coap_msg_set_token(coap_msg_t *msg, char *buf, size_t len);
+
+/**
+ *  @brief Add a token to a message structure
+ *
+ *  @param[in,out] msg Pointer to a message structure
+ *  @param[in] num Option number
+ *  @param[in] len Option length
+ *  @param[in] val Pointer to a buffer containing the option value
+ *
+ *  @returns Operation status
+ *  @retval 0 Success
+ *  @retval <0 Error
+ */
+int coap_msg_add_op(coap_msg_t *msg, unsigned num, unsigned len, const char *val);
+
+/**
+ *  @brief Set the payload in a message
+ *
+ *  Free the buffer in the message structure containing
+ *  the current payload if there is one, allocate a buffer
+ *  to contain the new payload and copy the buffer argument
+ *  into the new payload buffer.
+ *
+ *  @param[in,out] msg Pointer to a message structure
+ *  @param[in] buf Pointer to a buffer containing the payload
+ *  @param[in] len Length of the buffer
+ *
+ *  @returns Operation status
+ *  @retval 0 Success
+ *  @retval <0 Error
+ */
+int coap_msg_set_payload(coap_msg_t *msg, char *buf, size_t len);
+
+/**
+ *  @brief Format a message
+ *
+ *  @param[in] msg Pointer to a message structure
+ *  @param[out] buf Pointer to a buffer to contain the formatted message
+ *  @param[in] len Length of the buffer
+ *
+ *  @returns Length of the formatted message or error code
+ *  @retval >0 Length of the formatted message
+ *  @retval <0 Error
+ */
+int coap_msg_format(coap_msg_t *msg, char *buf, size_t len);
+
+/**
+ *  @brief Copy a message
+ *
+ *  @param[in,out] dst Pointer to the destination message structure
+ *  @param[in] src Pointer to the source message structure
+ *
+ *  @returns Operation status
+ *  @retval 0 Success
+ *  @retval <0 Error
+ */
+int coap_msg_copy(coap_msg_t *dst, coap_msg_t *src);
+
+#endif
+