mbed 5.4 with sleep mode

Dependencies:   C027_Support mbed-dev

Fork of C027_SupportTest_coap by Umar Naeem

Revision:
39:4f3f7463e55f
Parent:
38:f1bc6e867fcf
--- a/Coap/coap_msg.c	Wed May 24 07:51:33 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1024 +0,0 @@
-/*
- * 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.c
- *
- *  @brief Source file for the FreeCoAP message parser/formatter library
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <stdint.h>
-#include <time.h>
-#include <errno.h>
-#include "coap_msg.h"
-#include "coap_client.h"
-
-#define coap_msg_op_list_get_first(list)       ((list)->first)                  /**< Get the first option from an option linked-list */
-#define coap_msg_op_list_get_last(list)        ((list)->last)                   /**< Get the last option in an option linked-list */
-#define coap_msg_op_list_is_empty(list)        ((list)->first == NULL)          /**< Indicate whether or not an option linked-list is empty */
-
-static int coap_msg_rand_init = 0;                                              /**< Indicates whether or not the random number generator has been initialised */
-
-void coap_msg_gen_rand_str(char *buf, size_t len)
-{
-    size_t i = 0;
-
-    if (!coap_msg_rand_init)
-    {
-        srand(time(NULL));
-        coap_msg_rand_init = 1;
-    }
-    for (i = 0; i < len; i++)
-    {
-        buf[i] = rand() & 0x000000ff;
-    }
-}
-
-int coap_msg_op_num_is_recognized(unsigned num)
-{
-    switch (num)
-    {
-    case COAP_MSG_IF_MATCH:
-    case COAP_MSG_URI_HOST:
-    case COAP_MSG_ETAG:
-    case COAP_MSG_IF_NONE_MATCH:
-    case COAP_MSG_URI_PORT:
-    case COAP_MSG_LOCATION_PATH:
-    case COAP_MSG_URI_PATH:
-    case COAP_MSG_CONTENT_FORMAT:
-    case COAP_MSG_MAX_AGE:
-    case COAP_MSG_URI_QUERY:
-    case COAP_MSG_ACCEPT:
-    case COAP_MSG_LOCATION_QUERY:
-    case COAP_MSG_PROXY_URI:
-    case COAP_MSG_PROXY_SCHEME:
-    case COAP_MSG_SIZE1:
-        return 1;
-    }
-    return 0;
-}
-
-/**
- *  @brief Allocate an option structure
- *
- *  @param[in] num Option number
- *  @param[in] len Option length
- *  @param[in] val Pointer to the option value
- *
- *  @returns Pointer to the option structure
- *  @retval NULL Out-of-memory
- */
-static coap_msg_op_t *coap_msg_op_new(unsigned num, unsigned len, const char *val)
-{
-    coap_msg_op_t *op = NULL;
-
-    op = (coap_msg_op_t *)malloc(sizeof(coap_msg_op_t));
-    if (op == NULL)
-    {
-        return NULL;
-    }
-    op->num = num;
-    op->len = len;
-    op->val = (char *)malloc(len);
-    if (op->val == NULL)
-    {
-        free(op);
-        return NULL;
-    }
-    memcpy(op->val, val, len);
-    op->next = NULL;
-    return op;
-}
-
-/**
- *  @brief Free an option structure that was allocated by coap_msg_op_new
- *
- *  @param[in,out] op Pointer to the option structure
- */
-static void coap_msg_op_delete(coap_msg_op_t *op)
-{
-    free(op->val);
-    free(op);
-}
-
-/**
- *  @brief Initialise an option linked-list structure
- *
- *  @param[out] list Pointer to an option linked-list structure
- */
-static void coap_msg_op_list_create(coap_msg_op_list_t *list)
-{
-    memset(list, 0, sizeof(coap_msg_op_list_t));
-}
-
-/**
- *  @brief Deinitialise an option linked-list structure
- *
- *  @param[in,out] list Pointer to an option linked-list structure
- */
-static void coap_msg_op_list_destroy(coap_msg_op_list_t *list)
-{
-    coap_msg_op_t *prev = NULL;
-    coap_msg_op_t *op = NULL;
-
-    op = list->first;
-    while (op != NULL)
-    {
-        prev = op;
-        op = op->next;
-        coap_msg_op_delete(prev);
-    }
-    memset(list, 0, sizeof(coap_msg_op_list_t));
-}
-
-/**
- *  @brief Allocate an option structure and add it to the end of an option linked-list structure
- *
- *  @param[in,out] list Pointer to an option linked-list 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
- */
-static int coap_msg_op_list_add_last(coap_msg_op_list_t *list, unsigned num, unsigned len, const char *val)
-{
-    coap_msg_op_t *op = NULL;
-
-    op = coap_msg_op_new(num, len, val);
-    if (op == NULL)
-    {
-        return -ENOMEM;
-    }
-    if (list->first == NULL)
-    {
-        list->first = op;
-        list->last = op;
-    }
-    else
-    {
-        list->last->next = op;
-        list->last = op;
-    }
-    return 0;
-}
-
-/**
- *  @brief Allocate an option structure and add it to an option linked-list structure
- *
- *  The option is added to the list at a position determined by the option number.
- *
- *  @param[in,out] list Pointer to an option linked-list 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
- */
-static int coap_msg_op_list_add(coap_msg_op_list_t *list, unsigned num, unsigned len, const char *val)
-{
-    coap_msg_op_t *prev = NULL;
-    coap_msg_op_t *op = NULL;
-
-    op = coap_msg_op_new(num, len, val);
-    if (op == NULL)
-    {
-        return -ENOMEM;
-    }
-    if (list->first == NULL)
-    {
-        /* empty list */
-        list->first = op;
-        list->last = op;
-        return 0;
-    }
-    if (op->num < list->first->num)
-    {
-        /* start of the list */
-        op->next = list->first;
-        list->first = op;
-        return 0;
-    }
-    prev = list->first;
-    while (prev != list->last)
-    {
-        /* middle of the list */
-        if ((prev->num <= op->num) && (op->num < prev->next->num))
-        {
-            op->next = prev->next;
-            prev->next = op;
-            return 0;
-        }
-        prev = prev->next;
-    }
-    /* end of the list */
-    list->last->next = op;
-    list->last = op;
-    return 0;
-}
-
-void coap_msg_create(coap_msg_t *msg)
-{
-    memset(msg, 0, sizeof(coap_msg_t));
-    msg->ver = COAP_MSG_VER;
-    coap_msg_op_list_create(&msg->op_list);
-}
-
-void coap_msg_destroy(coap_msg_t *msg)
-{
-    coap_msg_op_list_destroy(&msg->op_list);
-    if (msg->payload != NULL)
-    {
-        free(msg->payload);
-    }
-    memset(msg, 0, sizeof(coap_msg_t));
-}
-
-void coap_msg_reset(coap_msg_t *msg)
-{
-    coap_msg_destroy(msg);
-    coap_msg_create(msg);
-}
-
-/**
- *  @brief Check a message for correctness
- *
- *  The following checks from RFC7252 are performed:
- *
- *  An Empty message has the Code field set to 0.00. The Token Length
- *  field MUST be set to 0 and bytes of data MUST NOT be present after
- *  the Message ID field.  If there are any bytes, they MUST be processed
- *  as a message format error.
- *
- *  The Reset message MUST echo the Message ID of the Confirmable message
- *  and MUST be Empty.
- *
- *  A Non-confirmable message always carries either a request or response
- *  and MUST NOT be Empty.
- *
- *  @param[in] msg Pointer to a message structure
- *  @returns Operation status
- *  @retval 0 Success
- *  @retval <0 Error
- */
-static int coap_msg_check(coap_msg_t *msg)
-{
-    if ((msg->code_class == 0) && (msg->code_detail == 0))
-    {
-        /* empty message */
-        if ((msg->type == COAP_MSG_NON)
-         || (msg->token_len != 0)
-         || (!coap_msg_op_list_is_empty(&msg->op_list))
-         || (msg->payload_len != 0))
-        {
-            return -EBADMSG;
-        }
-    }
-    else
-    {
-        /* non-empty message */
-        if (msg->type == COAP_MSG_RST)
-        {
-            return -EBADMSG;
-        }
-    }
-    return 0;
-}
-
-unsigned coap_msg_check_critical_ops(coap_msg_t *msg)
-{
-    coap_msg_op_t *op = NULL;
-    unsigned num = 0;
-
-    op = coap_msg_get_first_op(msg);
-    while (op != NULL)
-    {
-        num = coap_msg_op_get_num(op);
-        if ((coap_msg_op_num_is_critical(num))
-         && (!coap_msg_op_num_is_recognized(num)))
-        {
-            return num;  /* fail */
-        }
-        op = coap_msg_op_get_next(op);
-    }
-    return 0;  /* pass */
-}
-
-unsigned coap_msg_check_unsafe_ops(coap_msg_t *msg)
-{
-    coap_msg_op_t *op = NULL;
-    unsigned num = 0;
-
-    op = coap_msg_get_first_op(msg);
-    while (op != NULL)
-    {
-        num = coap_msg_op_get_num(op);
-        if ((coap_msg_op_num_is_unsafe(num))
-         && (!coap_msg_op_num_is_recognized(num)))
-        {
-            return num;  /* fail */
-        }
-        op = coap_msg_op_get_next(op);
-    }
-    return 0;  /* pass */
-}
-
-int coap_msg_parse_type_msg_id(char *buf, size_t len, unsigned *type, unsigned *msg_id)
-{
-    if (len < 4)
-    {
-        return -EBADMSG;
-    }
-    *type = (buf[0] >> 4) & 0x03;
-    *msg_id = ntohs(*((uint16_t *)(&buf[2])));
-    return 0;
-}
-
-/**
- *  @brief Parse the header in a message
- *
- *  @param[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 Number of bytes parsed or error code
- *  @retval >0 Number of bytes parsed
- *  @retval <0 Error
- */
-static int coap_msg_parse_hdr(coap_msg_t *msg, char *buf, size_t len)
-{
-    char *p = buf;
-
-    if (len < 4)
-    {
-        return -EBADMSG;
-    }
-    msg->ver = (p[0] >> 6) & 0x03;
-    if (msg->ver != COAP_MSG_VER)
-    {
-        return -EINVAL;
-    }
-    msg->type = (p[0] >> 4) & 0x03;
-    msg->token_len = p[0] & 0x0f;
-    if (msg->token_len > sizeof(msg->token))
-    {
-        return -EBADMSG;
-    }
-    msg->code_detail = p[1] & 0x1f;
-    msg->code_class = (p[1] >> 5) & 0x07;
-    if ((msg->code_class != COAP_MSG_REQ)
-     && (msg->code_class != COAP_MSG_SUCCESS)
-     && (msg->code_class != COAP_MSG_CLIENT_ERR)
-     && (msg->code_class != COAP_MSG_SERVER_ERR))
-    {
-        return -EBADMSG;
-    }
-    msg->msg_id = ntohs(*((uint16_t *)(&p[2])));
-    p += 4;
-    len -= 4;
-    return p - buf;
-}
-
-/**
- *  @brief Parse the token in a message
- *
- *  @param[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 Number of bytes parsed or error code
- *  @retval >0 Number of bytes parsed
- *  @retval <0 Error
- */
-static int coap_msg_parse_token(coap_msg_t *msg, char *buf, size_t len)
-{
-    if (len < msg->token_len)
-    {
-        return -EBADMSG;
-    }
-    memcpy(msg->token, buf, msg->token_len);
-    return msg->token_len;
-}
-
-/**
- *  @brief Parse an option in 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 Number of bytes parsed or error code
- *  @retval >0 Number of bytes parsed
- *  @retval <0 Error
- */
-static int coap_msg_parse_op(coap_msg_t *msg, char *buf, size_t len)
-{
-    coap_msg_op_t *prev = NULL;
-    unsigned op_delta = 0;
-    unsigned op_len = 0;
-    unsigned op_num = 0;
-    char *p = buf;
-    int ret = 0;
-
-    if (len < 1)
-    {
-        return -EBADMSG;
-    }
-    op_delta = (p[0] >> 4) & 0x0f;
-    op_len = p[0] & 0x0f;
-    if ((op_delta == 15) || (op_len == 15))
-    {
-        return -EBADMSG;
-    }
-    p++;
-    len--;
-    if (op_delta == 13)
-    {
-        if (len < 1)
-        {
-            return -EBADMSG;
-        }
-        op_delta += p[0];
-        p++;
-        len--;
-    }
-    else if (op_delta == 14)
-    {
-        if (len < 2)
-        {
-            return -EBADMSG;
-        }
-        op_delta = 269 + ntohs(*((uint16_t *)(&p[0])));
-        p += 2;
-        len -= 2;
-    }
-    if (op_len == 13)
-    {
-        if (len < 1)
-        {
-            return -EBADMSG;
-        }
-        op_len += p[0];
-        p++;
-        len--;
-    }
-    else if (op_len == 14)
-    {
-        if (len < 2)
-        {
-            return -EBADMSG;
-        }
-        op_len = 269 + ntohs(*((uint16_t *)(&p[0])));
-        p += 2;
-        len -= 2;
-    }
-    if (len < op_len)
-    {
-        return -EBADMSG;
-    }
-    prev = coap_msg_op_list_get_last(&msg->op_list);
-    if (prev == NULL)
-    {
-        op_num = op_delta;
-    }
-    else
-    {
-        op_num = coap_msg_op_get_num(prev) + op_delta;
-    }
-    ret = coap_msg_op_list_add_last(&msg->op_list, op_num, op_len, p);
-    if (ret < 0)
-    {
-        return ret;
-    }
-    p += op_len;
-    return p - buf;
-}
-
-/**
- *  @brief Parse the options in 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 Number of bytes parsed or error code
- *  @retval >0 Number of bytes parsed
- *  @retval <0 Error
- */
-static int coap_msg_parse_ops(coap_msg_t *msg, char *buf, size_t len)
-{
-    int num = 0;
-    char *p = buf;
-
-    while (1)
-    {
-        if (((p[0] & 0xff) == 0xff) || (len == 0))
-        {
-            break;
-        }
-        num = coap_msg_parse_op(msg, p, len);
-        if (num < 0)
-        {
-            return num;
-        }
-        p += num;
-        len -= num;
-    }
-    return p - buf;
-}
-
-/**
- *  @brief Parse the payload in a message
- *
- *  @param[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 Number of bytes parsed or error code
- *  @retval >0 Number of bytes parsed
- *  @retval <0 Error
- */
-static int coap_msg_parse_payload(coap_msg_t *msg, char *buf, size_t len)
-{
-    char *p = buf;
-
-    if (len == 0)
-    {
-        return 0;
-    }
-    if ((p[0] & 0xff) != 0xff)
-    {
-        return -EBADMSG;
-    }
-    p++;
-    len--;
-    if (len == 0)
-    {
-        return -EBADMSG;
-    }
-    msg->payload = (char *)malloc(len);
-    if (msg->payload == NULL)
-    {
-        return -ENOMEM;
-    }
-    memcpy(msg->payload, p, len);
-    msg->payload_len = len;
-    p += len;
-    return p - buf;
-}
-
-int coap_msg_parse(coap_msg_t *msg, char *buf, size_t len)
-{
-    int num = 0;
-    char *p = buf;
-
-    coap_msg_reset(msg);
-    num = coap_msg_parse_hdr(msg, p, len);
-    if (num < 0)
-    {
-        coap_msg_destroy(msg);
-        return num;
-    }
-    p += num;
-    len -= num;
-    num = coap_msg_parse_token(msg, p, len);
-    if (num < 0)
-    {
-        coap_msg_destroy(msg);
-        return num;
-    }
-    p += num;
-    len -= num;
-    num = coap_msg_parse_ops(msg, p, len);
-    if (num < 0)
-    {
-        coap_msg_destroy(msg);
-        return num;
-    }
-    p += num;
-    len -= num;
-    num = coap_msg_parse_payload(msg, p, len);
-    if (num < 0)
-    {
-        coap_msg_destroy(msg);
-        return num;
-    }
-    return coap_msg_check(msg);
-}
-
-int coap_msg_set_type(coap_msg_t *msg, unsigned type)
-{
-    if ((type != COAP_MSG_CON)
-     && (type != COAP_MSG_NON)
-     && (type != COAP_MSG_ACK)
-     && (type != COAP_MSG_RST))
-    {
-        return -EINVAL;
-    }
-    msg->type = type;
-    return 0;
-}
-
-int coap_msg_set_code(coap_msg_t *msg, unsigned code_class, unsigned code_detail)
-{
-    if (code_class > COAP_MSG_MAX_CODE_CLASS)
-    {
-        return -EINVAL;
-    }
-    if (code_detail > COAP_MSG_MAX_CODE_DETAIL)
-    {
-        return -EINVAL;
-    }
-    msg->code_class = code_class;
-    msg->code_detail = code_detail;
-    return 0;
-}
-
-int coap_msg_set_msg_id(coap_msg_t *msg, unsigned msg_id)
-{
-    if (msg_id > COAP_MSG_MAX_MSG_ID)
-    {
-        return -EINVAL;
-    }
-    msg->msg_id = msg_id;
-    return 0;
-}
-
-int coap_msg_set_token(coap_msg_t *msg, char *buf, size_t len)
-{
-    if (len > COAP_MSG_MAX_TOKEN_LEN)
-    {
-        return -EINVAL;
-    }
-    memcpy(msg->token, buf, len);
-    msg->token_len = len;
-    return 0;
-}
-
-int coap_msg_add_op(coap_msg_t *msg, unsigned num, unsigned len, const char *val)
-{
-    return coap_msg_op_list_add(&msg->op_list, num, len, val);
-}
-
-int coap_msg_set_payload(coap_msg_t *msg, char *buf, size_t len)
-{
-    msg->payload_len = 0;
-    if (msg->payload != NULL)
-    {
-        free(msg->payload);
-        msg->payload = NULL;
-    }
-    if (len > 0)
-    {
-        msg->payload = (char *)malloc(len);
-        if (msg->payload == NULL)
-        {
-            return -ENOMEM;
-        }
-        memcpy(msg->payload, buf, len);
-        msg->payload_len = len;
-    }
-    return 0;
-}
-
-/**
- *  @brief Format the header in 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
- */
-static int coap_msg_format_hdr(coap_msg_t *msg, char *buf, size_t len)
-{
-    uint16_t msg_id = 0;
-
-    if (len < 4)
-    {
-        return -ENOSPC;
-    }
-    buf[0] = (char)((COAP_MSG_VER << 6)
-                  | ((msg->type & 0x03) << 4)
-                  | (msg->token_len & 0x0f));
-    buf[1] = (char)(((msg->code_class & 0x07) << 5)
-                  | (msg->code_detail & 0x1f));
-    msg_id = htons(msg->msg_id);
-    memcpy(&buf[2], &msg_id, 2);
-    return 4;
-}
-
-/**
- *  @brief Format the token in 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
- */
-static int coap_msg_format_token(coap_msg_t *msg, char *buf, size_t len)
-{
-    if (len < msg->token_len)
-    {
-        return -ENOSPC;
-    }
-    memcpy(buf, msg->token, msg->token_len);
-    return msg->token_len;
-}
-
-/**
- *  @brief Format an option in a message
- *
- *  @param[in] op Pointer to an option structure
- *  @param[in] prev_num option number of the previous option
- *  @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
- */
-static int coap_msg_format_op(coap_msg_op_t *op, unsigned prev_num, char *buf, size_t len)
-{
-    unsigned op_delta = 0;
-    unsigned num = 0;
-    uint16_t val = 0;
-    char *p = buf;
-
-    op_delta = op->num - prev_num;
-    num++;
-
-    /* option delta */
-    if (op_delta >= 269)
-    {
-        num += 2;
-    }
-    else if (op_delta >= 13)
-    {
-        num += 1;
-    }
-
-    /* option length */
-    if (op->len >= 269)
-    {
-        num += 2;
-    }
-    else if (op->num >= 13)
-    {
-        num += 1;
-    }
-
-    /* option value */
-    num += op->len;
-    if (num > len)
-    {
-        return -ENOSPC;
-    }
-
-    /* option delta */
-    if (op_delta >= 269)
-    {
-        p[0] = 14 << 4;
-    }
-    else if (op_delta >= 13)
-    {
-        p[0] = 13 << 4;
-    }
-    else
-    {
-        p[0] = op_delta << 4;
-    }
-
-    /* option length */
-    if (op->len >= 269)
-    {
-        p[0] |= 14;
-    }
-    else if (op->len >= 13)
-    {
-        p[0] |= 13;
-    }
-    else
-    {
-        p[0] |= op->len;
-    }
-    p++;
-    len--;
-
-    /* option delta extended */
-    if (op_delta >= 269)
-    {
-        val = htons(op_delta - 269);
-        memcpy(p, &val, 2);
-        p += 2;
-        len -= 2;
-    }
-    else if (op_delta >= 13)
-    {
-        p[0] = op_delta - 13;
-        p++;
-        len--;
-    }
-
-    /* option length extended */
-    if (op->len >= 269)
-    {
-        val = htons(op->len - 269);
-        memcpy(p, &val, 2);
-        p += 2;
-        len -= 2;
-    }
-    else if (op->len >= 13)
-    {
-        p[0] = op->len - 13;
-        p++;
-        len--;
-    }
-
-    /* option value */
-    memcpy(p, op->val, op->len);
-    p += op->len;
-
-    return p - buf;
-}
-
-/**
- *  @brief Format the options in 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
- */
-static int coap_msg_format_ops(coap_msg_t *msg, char *buf, size_t len)
-{
-    coap_msg_op_t *op = NULL;
-    unsigned prev_num = 0;
-    int num = 0;
-    char *p = buf;
-
-    op = coap_msg_op_list_get_first(&msg->op_list);
-    while (op != NULL)
-    {
-        num = coap_msg_format_op(op, prev_num, p, len);
-        if (num < 0)
-        {
-            return num;
-        }
-        p += num;
-        len -= num;
-        prev_num = coap_msg_op_get_num(op);
-        op = coap_msg_op_get_next(op);
-    }
-    return p - buf;
-}
-
-/**
- *  @brief Format the payload in 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
- */
-static int coap_msg_format_payload(coap_msg_t *msg, char *buf, size_t len)
-{
-    if (msg->payload_len == 0)
-    {
-        return 0;
-    }
-    if (msg->payload_len + 1 > len)
-    {
-        return -ENOSPC;
-    }
-    buf[0] = 0xff;
-    memcpy(&buf[1], msg->payload, msg->payload_len);
-    return msg->payload_len + 1;
-}
-
-int coap_msg_format(coap_msg_t *msg, char *buf, size_t len)
-{
-    int num = 0;
-    char *p = buf;
-    int ret = 0;
-
-    ret = coap_msg_check(msg);
-    if (ret != 0)
-    {
-        return ret;
-    }
-    num = coap_msg_format_hdr(msg, p, len);
-    if (num < 0)
-    {
-        return num;
-    }
-    p += num;
-    len -= num;
-    num = coap_msg_format_token(msg, p, len);
-    if (num < 0)
-    {
-        return num;
-    }
-    p += num;
-    len -= num;
-    num = coap_msg_format_ops(msg, p, len);
-    if (num < 0)
-    {
-        return num;
-    }
-    p += num;
-    len -= num;
-    num = coap_msg_format_payload(msg, p, len);
-    if (num < 0)
-    {
-        return num;
-    }
-    p += num;
-    return p - buf;
-}
-
-int coap_msg_copy(coap_msg_t *dst, coap_msg_t *src)
-{
-    coap_msg_op_t *op = NULL;
-    int ret = 0;
-
-    dst->ver = src->ver;
-    ret = coap_msg_set_type(dst, coap_msg_get_type(src));
-    if (ret < 0)
-    {
-        return ret;
-    }
-    ret = coap_msg_set_code(dst, coap_msg_get_code_class(src), coap_msg_get_code_detail(src));
-    if (ret < 0)
-    {
-        return ret;
-    }
-    ret = coap_msg_set_msg_id(dst, coap_msg_get_msg_id(src));
-    if (ret < 0)
-    {
-        return ret;
-    }
-    ret = coap_msg_set_token(dst, coap_msg_get_token(src), coap_msg_get_token_len(src));
-    if (ret < 0)
-    {
-        return ret;
-    }
-    op = coap_msg_get_first_op(src);
-    while (op != NULL)
-    {
-        ret = coap_msg_add_op(dst, coap_msg_op_get_num(op), coap_msg_op_get_len(op), coap_msg_op_get_val(op));
-        if (ret < 0)
-        {
-            return ret;
-        }
-        op = coap_msg_op_get_next(op);
-    }
-    ret = coap_msg_set_payload(dst, coap_msg_get_payload(src), coap_msg_get_payload_len(src));
-    if (ret < 0)
-    {
-        return ret;
-    }
-    return 0;
-}
-