mbed 5.4 with sleep mode

Dependencies:  

Coap/coap_msg.h

Committer:
ranaumarnaeem
Date:
2017-05-25
Revision:
39:4f3f7463e55f
Parent:
34:d6ce8f961b8b

File content as of revision 39:4f3f7463e55f:

/*
 * 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