mbed 5.4 with sleep mode

Dependencies:  

Revision:
39:4f3f7463e55f
Parent:
38:f1bc6e867fcf
diff -r f1bc6e867fcf -r 4f3f7463e55f Coap/coap_client.c
--- a/Coap/coap_client.c	Wed May 24 07:51:33 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1021 +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_client.c
- *
- *  @brief Source file for the FreeCoAP client library
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdint.h>
-#include <errno.h>
-
-#include "coap_client.h"
-#include "main.h"
-
-#define COAP_CLIENT_ACK_TIMEOUT_SEC   2                                         /**< Minimum delay to wait before retransmitting a confirmable message */
-#define COAP_CLIENT_MAX_RETRANSMIT    4                                         /**< Maximum number of times a confirmable message can be retransmitted */
-#define COAP_CLIENT_RESP_TIMEOUT_SEC  30                                        /**< Maximum amount of time to wait for a response */
-
-/****************************************************************************************************
- *                                           coap_client                                            *
- ****************************************************************************************************/
-void coap_client_destroy(coap_client_t *client)
-{
-    memset(client, 0, sizeof(coap_client_t));
-}
-
-/**
- *  @brief Send a message to the server
- *
- *  @param[in,out] client Pointer to a client structure
- *  @param[in] msg Pointer to a message structure
- *
- *  @returns Number of bytes sent or error code
- *  @retval >0 Number of bytes sent
- *  @retval <0 Error
- */
-static int coap_client_send(coap_client_t *client, coap_msg_t *msg)
-{
-    int num = 0;
-    char buf[COAP_MSG_MAX_BUF_LEN] = {0};
-
-    num = coap_msg_format(msg, buf, sizeof(buf));
-    if (num < 0)
-    {
-        return num;
-    }
-    num = send(client->sd, buf, num);
-    if (num < 0)
-    {
-        printf("send error\n");
-        return -errno;
-    }
-
-    return num;
-}
-
-/**
- *  @brief Handle a format error in a received message
- *
- *  Special handling for the case where a received
- *  message could not be parsed due to a format error.
- *  Extract enough information from the received message
- *  to form a reset message.
- *
- *  @param[in,out] client Pointer to a client structure
- *  @param[in] buf Buffer containing the message
- *  @param[in] len length of the buffer
- */
-static void coap_client_handle_format_error(coap_client_t *client, char *buf, size_t len)
-{
-    coap_msg_t msg = {0};
-    unsigned msg_id = 0;
-    unsigned type = 0;
-    int ret = 0;
-
-    ret = coap_msg_parse_type_msg_id(buf, len, &type, &msg_id);
-    if ((ret == 0) && (type == COAP_MSG_CON))
-    {
-        coap_msg_create(&msg);
-        ret = coap_msg_set_type(&msg, COAP_MSG_RST);
-        if (ret < 0)
-        {
-            coap_msg_destroy(&msg);
-            return;
-        }
-        ret = coap_msg_set_msg_id(&msg, msg_id);
-        if (ret < 0)
-        {
-            coap_msg_destroy(&msg);
-            return;
-        }
-        coap_client_send(client, &msg);
-        coap_msg_destroy(&msg);
-    }
-}
-
-/**
- *  @brief Receive a message from the server
- *
- *  @param[in,out] client Pointer to a client structure
- *  @param[in] msg Pointer to a message structure
- *
- *  @returns Number of bytes received or error code
- *  @retval >0 Number of bytes received
- *  @retval <0 Error
- */
-static int coap_client_recv(coap_client_t *client, coap_msg_t *msg)
-{
-    int num = 0;
-    int ret = 0;
-    char buf[COAP_MSG_MAX_BUF_LEN] = {0};
-
-    num = recv(client->sd, buf, sizeof(buf));
-    if (num < 0)
-    {
-        return -errno;
-    }
-
-    ret = coap_msg_parse(msg, buf, num);
-    if (ret < 0)
-    {
-        if (ret == -EBADMSG)
-        {
-            coap_client_handle_format_error(client, buf, num);
-        }
-        return ret;
-    }
-    return num;
-}
-
-/**
- *  @brief Reject a received confirmable message
- *
- *  Send a reset message to the server.
- *
- *  @param[in,out] client Pointer to a client structure
- *  @param[in] msg Pointer to a message structure
- *
- *  @returns Operation status
- *  @retval 0 Success
- *  @retval <0 Error
- */
-static int coap_client_reject_con(coap_client_t *client, coap_msg_t *msg)
-{
-    coap_msg_t rej = {0};
-    int num = 0;
-    int ret = 0;
-
-    printf("Rejecting confirmable message from host %s and port %s\n", client->server_host, client->server_port);
-    coap_msg_create(&rej);
-    ret = coap_msg_set_type(&rej, COAP_MSG_RST);
-    if (ret < 0)
-    {
-        coap_msg_destroy(&rej);
-        return ret;
-    }
-    ret = coap_msg_set_msg_id(&rej, coap_msg_get_msg_id(msg));
-    if (ret < 0)
-    {
-        coap_msg_destroy(&rej);
-        return ret;
-    }
-    num = coap_client_send(client, &rej);
-    coap_msg_destroy(&rej);
-    if (num < 0)
-    {
-        return num;
-    }
-    return 0;
-}
-
-/**
- *  @brief Reject a received non-confirmable message
- *
- *  @param[in] client Pointer to a client structure
- *  @param[in] msg Pointer to a message structure
- *
- *  @returns Operation status
- *  @retval 0 Success
- */
-static int coap_client_reject_non(coap_client_t *client, coap_msg_t *msg)
-{
-    printf("Rejecting non-confirmable message from host %s and port %s\n", client->server_host, client->server_port);
-    return 0;
-}
-
-/**
- *  @brief Reject a received acknowledgement message
- *
- *  @param[in] client Pointer to a client structure
- *  @param[in] msg Pointer to a message structure
- *
- *  @returns Operation status
- *  @retval 0 Success
- */
-static int coap_client_reject_ack(coap_client_t *client, coap_msg_t *msg)
-{
-    printf("Rejecting acknowledgement message from host %s and port %s\n", client->server_host, client->server_port);
-    return 0;
-}
-
-/**
- *  @brief Reject a received reset message
- *
- *  @param[in] client Pointer to a client structure
- *  @param[in] msg Pointer to a message structure
- *
- *  @returns Operation status
- *  @retval 0 Success
- */
-static int coap_client_reject_reset(coap_client_t *client, coap_msg_t *msg)
-{
-    printf("Rejecting reset message from host %s and port %s\n", client->server_host, client->server_port);
-    return 0;
-}
-
-/**
- *  @brief Reject a received message
- *
- *  @param[in,out] client Pointer to a client structure
- *  @param[in] msg Pointer to a message structure
- *
- *  @returns Operation status
- *  @retval 0 Success
- *  @retval <0 Error
- */
-static int coap_client_reject(coap_client_t *client, coap_msg_t *msg)
-{
-    if (coap_msg_get_type(msg) == COAP_MSG_CON)
-    {
-        return coap_client_reject_con(client, msg);
-    }
-    else if (coap_msg_get_type(msg) == COAP_MSG_NON)
-    {
-        return coap_client_reject_non(client, msg);
-    }
-    else if (coap_msg_get_type(msg) == COAP_MSG_ACK)
-    {
-        return coap_client_reject_ack(client, msg);
-    }
-    else if (coap_msg_get_type(msg) == COAP_MSG_RST)
-    {
-        return coap_client_reject_reset(client, msg);
-    }
-    return 0;  /* should never arrive here */
-}
-
-/**
- *  @brief Send an acknowledgement message to the server
- *
- *  @param[in,out] client Pointer to a client structure
- *  @param[in] msg Pointer to a message structure
- *
- *  @returns Operation status
- *  @retval 0 Success
- *  @retval <0 Error
- */
-static int coap_client_send_ack(coap_client_t *client, coap_msg_t *msg)
-{
-    coap_msg_t ack = {0};
-    int num = 0;
-    int ret = 0;
-
-    printf("Acknowledging confirmable message from host %s and port %s\n", client->server_host, client->server_port);
-    coap_msg_create(&ack);
-    ret = coap_msg_set_type(&ack, COAP_MSG_ACK);
-    if (ret < 0)
-    {
-        coap_msg_destroy(&ack);
-        return ret;
-    }
-    ret = coap_msg_set_msg_id(&ack, coap_msg_get_msg_id(msg));
-    if (ret < 0)
-    {
-        coap_msg_destroy(&ack);
-        return ret;
-    }
-    num = coap_client_send(client, &ack);
-    coap_msg_destroy(&ack);
-    if (num < 0)
-    {
-        return num;
-    }
-    return 0;
-}
-
-/**
- *  @brief Compare the token values in a request message and a response message
- *
- *  @param[in] req Pointer to the request message
- *  @param[in] resp Pointer to the response message
- *
- *  @returns Comparison value
- *  @retval 0 the tokens are not equal
- *  @retval 1 the tokens are equal
- */
-static int coap_client_match_token(coap_msg_t *req, coap_msg_t *resp)
-{
-    return ((coap_msg_get_token_len(resp) == coap_msg_get_token_len(req))
-         && (memcmp(coap_msg_get_token(resp), coap_msg_get_token(req), coap_msg_get_token_len(req)) == 0));
-}
-
-/**
- *  @brief Check that all of the options in a message are acceptable
- *
- *  For a proxy, options are acceptable if they are safe to forward or recognized or both.
- *  For a server, options are acceptable if they are elective or recognized or both.
- *
- *  @param[in] msg Pointer to message structure
- *
- *  @returns Operation status or bad option number
- *  @retval 0 Success
- *  @retval >0 Bad option number
- */
-static unsigned coap_client_check_options(coap_msg_t *msg)
-{
-#ifdef COAP_PROXY
-    return coap_msg_check_unsafe_ops(msg);
-#else  /* !COAP_PROXY */
-    return coap_msg_check_critical_ops(msg);
-#endif  /* COAP_PROXY */
-}
-
-/**
- *  @brief Handle a received piggy-backed response message
- *
- *  An acknowledgement has been received that contains
- *  the same token as the request. Check the response
- *  contained within it.
- *
- *  @param[in,out] client Pointer to a client structure
- *  @param[in] resp Pointer to the response message
- *
- *  @returns Operation status
- *  @retval 0 Success
- *  @retval <0 Error
- */
-static int coap_client_handle_piggybacked_response(coap_client_t *client, coap_msg_t *resp)
-{
-    unsigned op_num = 0;
-
-    op_num = coap_client_check_options(resp);
-    if (op_num != 0)
-    {
-        printf("Found bad option number %u in message from host %s and port %s\n", op_num, client->server_host, client->server_port);
-        coap_client_reject(client, resp);
-        return -EBADMSG;
-    }
-    printf("Received acknowledgement and response from Server\n");
-    return 0;
-}
-
-/**
- *  @brief Handle a received separate response message
- *
- *  A separate response has been received that contains
- *  the same token as the request. Check the response
- *  and send an acknowledgement if necessary.
- *
- *  @param[in,out] client Pointer to a client structure
- *  @param[in] resp Pointer to the response message
- *
- *  @returns Operation status
- *  @retval 0 Success
- *  @retval <0 Error
- */
-static int coap_client_handle_sep_response(coap_client_t *client, coap_msg_t *resp)
-{
-    unsigned op_num = 0;
-
-    if (coap_msg_get_type(resp) == COAP_MSG_CON)
-    {
-        printf("Received confirmable response from host %s and port %s\n", client->server_host, client->server_port);
-        op_num = coap_client_check_options(resp);
-        if (op_num != 0)
-        {
-            printf("Found bad option number %u in message from host %s and port %s\n", op_num, client->server_host, client->server_port);
-            coap_client_reject(client, resp);
-            return -EBADMSG;
-        }
-        return coap_client_send_ack(client, resp);
-    }
-    else if (coap_msg_get_type(resp) == COAP_MSG_NON)
-    {
-        printf("Received non-confirmable response from host %s and port %s\n", client->server_host, client->server_port);
-        op_num = coap_client_check_options(resp);
-        if (op_num != 0)
-        {
-            printf("Found bad option number %u in message from host %s and port %s\n", op_num, client->server_host, client->server_port);
-            coap_client_reject(client, resp);
-            return -EBADMSG;
-        }
-        return 0;
-    }
-    coap_client_reject(client, resp);
-    return -EBADMSG;
-}
-
-/**
- *  @brief Handle a separate response to a confirmable request
- *
- *  An acknowledgement has been received. Receive the
- *  response and send an acknowledgement back to the server.
- *
- *  @param[in,out] client Pointer to a client structure
- *  @param[in] req Pointer to the request message
- *  @param[out] resp Pointer to the response message
- *
- *  @returns Operation status
- *  @retval 0 Success
- *  @retval <0 Error
- */
-static int coap_client_exchange_sep(coap_client_t *client, coap_msg_t *req, coap_msg_t *resp)
-{
-    int num = 0;
-    int ret = 0;
-    int starttimeout,endtimeout;
-
-    /* wait for a separate response to a confirmable request */
-    printf("Expecting response from host %s and port %s\n", client->server_host, client->server_port);
-    while (1)
-    {
-        starttimeout = readseconds();
-        while(1)
-        {
-            num = coap_client_recv(client, resp);
-            if (num < 0)
-            {
-                return num;
-            }
-            else if(num > 0)
-            {
-                break;    
-            }
-            endtimeout = readseconds();
-            if((endtimeout - starttimeout) > COAP_CLIENT_RESP_TIMEOUT_SEC)
-            {
-                printf("Timeout no data received\n");  
-                return -1;  
-            }
-        }
-        
-        if (coap_msg_get_msg_id(resp) == coap_msg_get_msg_id(req))
-        {
-            if (coap_msg_get_type(resp) == COAP_MSG_ACK)
-            {
-                /* message deduplication */
-                printf("Received duplicate acknowledgement from host %s and port %s\n", client->server_host, client->server_port);
-                continue;
-            }
-            else if (coap_msg_get_type(resp) == COAP_MSG_RST)
-            {
-                return -ECONNRESET;
-            }
-            coap_client_reject(client, resp);
-            return -EBADMSG;
-        }
-        if (coap_client_match_token(req, resp))
-        {
-             return coap_client_handle_sep_response(client, resp);
-        }
-        /* message deduplication */
-        /* we might have received a duplicate message that was already received from the same server */
-        /* reject the message and continue listening */
-        ret = coap_client_reject(client, resp);
-        if (ret < 0 )
-        {
-            return ret;
-        }
-    }
-    return 0;
-}
-
-/**
- *  @brief Handle the response to a confirmable request
- *
- *  A confirmable request has been sent to the server.
- *  Receive the acknowledgement and response. Send an
- *  acknowledgement if necessary.
- *
- *  @param[in,out] client Pointer to a client structure
- *  @param[in] req Pointer to the request message
- *  @param[out] resp Pointer to the response message
- *
- *  @returns Operation status
- *  @retval 0 Success
- *  @retval <0 Error
- */
-static int coap_client_exchange_con(coap_client_t *client, coap_msg_t *req, coap_msg_t *resp)
-{
-    int num = 0;
-    int ret = 0;
-    int starttimeout,endtimeout;
-    /*  wait for piggy-backed response in ack message
-     *  or ack message and separate response message
-     */
-    //printf("Expecting acknowledgement from server\r\n");
-    client->num_retrans = 0;
-    while (1)
-    {
-        int doubletimeout = COAP_CLIENT_ACK_TIMEOUT_SEC;
-        starttimeout = readseconds();
-        while(1)
-        {
-            num = coap_client_recv(client, resp);
-            if (num < 0)
-            {
-                //return num;
-            }
-            else if(num > 0)
-            {
-                break;    
-            }
-            endtimeout = readseconds();
-            if((endtimeout - starttimeout) > doubletimeout)
-            {
-                printf("Timeout no data received after %d seconds\n",endtimeout - starttimeout);
-
-                if (client->num_retrans >= COAP_CLIENT_MAX_RETRANSMIT)
-                {
-                    printf("Maximum retries reached no ack from server!\r\n");
-                    return -ETIMEDOUT;
-                }
-                
-                doubletimeout = 2 * doubletimeout;
-                starttimeout = readseconds();
-                client->num_retrans++;
-
-                printf("Retransmitting to server...\r\n");
-                num = coap_client_send(client, req);
-                if (num < 0)
-                {
-                    printf("Resending Failed to server...\r\n");
-                    return num;
-                } 
-            }
-        }
-         
-        if (coap_msg_get_msg_id(resp) == coap_msg_get_msg_id(req))
-        {
-            if (coap_msg_get_type(resp) == COAP_MSG_ACK)
-            {
-                if (coap_msg_is_empty(resp))
-                {
-                    /* received ack message, wait for separate response message */
-                    printf("Received acknowledgement from host %s and port %s\n", client->server_host, client->server_port);
-                    return coap_client_exchange_sep(client, req, resp);
-                }
-                else if (coap_client_match_token(req, resp))
-                {
-                    return coap_client_handle_piggybacked_response(client, resp);
-                }
-            }
-            else if (coap_msg_get_type(resp) == COAP_MSG_RST)
-            {
-                return -ECONNRESET;
-            }
-            coap_client_reject(client, resp);
-            return -EBADMSG;
-        }
-        else if (coap_client_match_token(req, resp))
-        {
-            /* RFC7252
-             * as the underlying datagram transport may not be sequence-preserving,
-             * the Confirmable message carrying the response may actually arrive
-             * before or after the Acknowledgement message for the request; for
-             * the purposes of terminating the retransmission sequence, this also
-             * serves as an acknowledgement.
-             */
-             return coap_client_handle_sep_response(client, resp);
-        }
-        /* message deduplication */
-        /* we might have received a duplicate message that was already received from the same server */
-        /* reject the message and continue listening */
-        ret = coap_client_reject(client, resp);
-        if (ret < 0 )
-        {
-            return ret;
-        }
-    }
-    return 0;
-}
-
-/**
- *  @brief Handle the response to a non-confirmable request
- *
- *  A non-confirmable request has been sent to the server.
- *  Receive the response.
- *
- *  @param[in,out] client Pointer to a client structure
- *  @param[in] req Pointer to the request message
- *  @param[out] resp Pointer to the response message
- *
- *  @returns Operation status
- *  @retval 0 Success
- *  @retval <0 Error
- **/
-static int coap_client_exchange_non(coap_client_t *client, coap_msg_t *req, coap_msg_t *resp)
-{
-    int num = 0;
-    int ret = 0;
-    int starttimeout,endtimeout;
-
-    printf("Expecting response from host %s and port %s\n", client->server_host, client->server_port);
-    while (1)
-    {
-        starttimeout = readseconds();
-        while(1)
-        {
-            num = coap_client_recv(client, resp);
-            if (num < 0)
-            {
-                return num;
-            }
-            else if(num > 0)
-            {
-                break;    
-            }
-            endtimeout = readseconds();
-            if((endtimeout - starttimeout) > COAP_CLIENT_RESP_TIMEOUT_SEC)
-            {
-                printf("Timeout no data received\n");    
-                return -1;
-            }
-        }
- 
-        if (coap_msg_get_msg_id(resp) == coap_msg_get_msg_id(req))
-        {
-            if (coap_msg_get_type(resp) == COAP_MSG_RST)
-            {
-                return -ECONNRESET;
-            }
-            coap_client_reject(client, resp);
-            return -EBADMSG;
-        }
-        if (coap_client_match_token(req, resp))
-        {
-             return coap_client_handle_sep_response(client, resp);
-        }
-        /* message deduplication */
-        /* we might have received a duplicate message that was already received from the same server */
-        /* reject the message and continue listening */
-        ret = coap_client_reject(client, resp);
-        if (ret < 0 )
-        {
-            return ret;
-        }
-    }
-    return 0;
-}
-
-int coap_client_exchange(coap_client_t *client, coap_msg_t *req, coap_msg_t *resp)
-{
-    unsigned char msg_id_buf[2] = {0};
-    unsigned msg_id = 0;
-    int num = 0;
-    char token[4] = {0};
-    int ret = 0;
-
-    /* check for a valid request */
-    if ((coap_msg_get_type(req) == COAP_MSG_ACK)
-     || (coap_msg_get_type(req) == COAP_MSG_RST)
-     || (coap_msg_get_code_class(req) != COAP_MSG_REQ))
-    {
-        return -EINVAL;
-    }
-
-    /* generate the message ID */
-    coap_msg_gen_rand_str((char *)msg_id_buf, sizeof(msg_id_buf));
-    msg_id = (((unsigned)msg_id_buf[1]) << 8) | (unsigned)msg_id_buf[0];
-    ret = coap_msg_set_msg_id(req, msg_id);
-    if (ret < 0)
-    {
-        return ret;
-    }
-
-    /* generate the token */
-    coap_msg_gen_rand_str(token, sizeof(token));
-    ret = coap_msg_set_token(req, token, sizeof(token));
-    if (ret < 0)
-    {
-        return ret;
-    }
-
-    num = coap_client_send(client, req);
-    if (num < 0)
-    {
-        return num;
-    }
-
-    if (coap_msg_get_type(req) == COAP_MSG_CON)
-    {
-        return coap_client_exchange_con(client, req, resp);
-    }
-    else if (coap_msg_get_type(req) == COAP_MSG_NON)
-    {
-        return coap_client_exchange_non(client, req, resp);
-    }
-    return -EINVAL;
-}
-//----------------------------------------------------------------------------------------------------------------------
-//----------------------------------------------------------------------------------------------------------------------
-/**
- *  @brief Test an exchange with the server
- *
- *  @param[in] data Pointer to a client test data structure
- *
- *  @returns Test result
- */
-test_result_t test_exchange_func(char* buf,int buf_len)
-{
-    printf("----------------------------------------\n");
-    test_result_t result = PASS;
-    coap_client_t client = {0};
-    coap_msg_t resp = {0};
-    coap_msg_t req = {0};
-    int ret = 0;
-
-    test_coap_client_msg_op_t req_ops;
-        req_ops.num = COAP_MSG_URI_PATH;
-        req_ops.len = 8;
-        req_ops.val = (char*)"resource";
-        
-    test_coap_client_msg_op_t resp_ops;
-        resp_ops.num = 0;
-        resp_ops.len = 0;
-        resp_ops.val = 0;
-
-    test_coap_client_msg_t test1_req;
-        test1_req.type = COAP_MSG_CON;
-        test1_req.code_class = COAP_MSG_REQ;
-        test1_req.code_detail = COAP_MSG_GET;
-        test1_req.ops = req_ops;
-        test1_req.num_ops = 1;
-        test1_req.payload = buf;
-        test1_req.payload_len = buf_len;
-
-    test_coap_client_msg_t test1_resp;
-        test1_resp.type = COAP_MSG_ACK;
-        test1_resp.code_class = COAP_MSG_SUCCESS;
-        test1_resp.code_detail = COAP_MSG_CONTENT;
-        test1_resp.ops = resp_ops;
-        test1_resp.num_ops = 0;
-        test1_resp.payload = (char*)"Hello Client!";
-        test1_resp.payload_len = 13;
-
-    test_coap_client_data_t test1_data; 
-        test1_data.desc = "Send a confirmable request to server and expect a piggy-backed response";
-        test1_data.host = HOST;
-        test1_data.port = PORT;
-        test1_data.common_name = (char*)"dummy/server";
-        test1_data.test_req = test1_req;
-        test1_data.test_resp = test1_resp;
-        test1_data.num_msg = 1;
-
-    //printf("%s\n", test1_data.desc);
-
-    if (ret < 0)
-    {
-        printf("Error  : %s\n",strerror(-ret));
-        return FAIL;
-    }
-
-        coap_msg_create(&req);
-        coap_msg_create(&resp);
-        
-        ret = exchange(&client, &test1_data.test_req, &req, &resp);
-        //printf("exchange function\n");
-        if (ret != PASS)
-        {
-            printf("exchange function fail\n");
-            coap_msg_destroy(&resp);
-            coap_msg_destroy(&req);
-            coap_client_destroy(&client);
-            return FAIL;
-        }
-
-        ret = compare_ver_token(&req, &resp);
-        if (ret != PASS)
-        {
-            coap_msg_destroy(&resp);
-            coap_msg_destroy(&req);
-            coap_client_destroy(&client);
-            return FAIL;
-        }
-
-        ret = check_resp(&test1_data.test_resp, &resp);
-        if (ret != PASS)
-        {
-            coap_msg_destroy(&resp);
-            coap_msg_destroy(&req);
-            coap_client_destroy(&client);
-            return FAIL;
-        }
-
-    coap_msg_destroy(&resp);
-    coap_msg_destroy(&req);
-    coap_client_destroy(&client);
-
-    return result;
-}
-//----------------------------------------------------------------------------------------------------------------------
-//----------------------------------------------------------------------------------------------------------------------
-/**
- *  @brief Print a CoAP message
- *
- *  @param[in] str String to be printed before the message
- *  @param[in] msg Pointer to a message structure
- */
-void print_coap_msg(const char *str, coap_msg_t *msg)
-{
-    //coap_msg_op_t *op = NULL;
-    //unsigned num = 0;
-    //unsigned len = 0;
-    unsigned i = 0;
-    //unsigned j = 0;
-    char *payload = NULL;
-    char *token = NULL;
-    //char *val = NULL;
-
-    printf("%s\n", str);
-    printf("ver:         0x%02x\n", coap_msg_get_ver(msg));
-    printf("type:        0x%02x\n", coap_msg_get_type(msg));
-    printf("token_len:   %d\n", coap_msg_get_token_len(msg));
-    printf("code_class:  %d\n", coap_msg_get_code_class(msg));
-    printf("code_detail: %d\n", coap_msg_get_code_detail(msg));
-    printf("msg_id:      0x%04x\n", coap_msg_get_msg_id(msg));
-    printf("token:      ");
-    token = coap_msg_get_token(msg);
-    for (i = 0; i < coap_msg_get_token_len(msg); i++)
-    {
-        printf(" 0x%02x", (unsigned char)token[i]);
-    }
-    printf("\n");
-    /*op = coap_msg_get_first_op(msg);
-    while (op != NULL)
-    {
-        num = coap_msg_op_get_num(op);
-        len = coap_msg_op_get_len(op);
-        val = coap_msg_op_get_val(op);
-        printf("op[%u].num:   %u\n", j, num);
-        printf("op[%u].len:   %u\n", j, len);
-        printf("op[%u].val:  ", j);
-        for (i = 0; i < len; i++)
-        {
-            printf(" 0x%02x", (unsigned char)val[i]);
-        }
-        printf("\n");
-        op = coap_msg_op_get_next(op);
-        j++;
-    }*/
-    printf("payload:     ");
-    payload = coap_msg_get_payload(msg);
-    for (i = 0; i < coap_msg_get_payload_len(msg); i++)
-    {
-        printf("%c", payload[i]);
-    //ucReturnCode[i] = payload[i];
-    }
-    //ucReturnCode[i] = '\0';
-    printf("\n");
-    printf("payload_len: %zu\n", coap_msg_get_payload_len(msg));
-}
-//----------------------------------------------------------------------------------------------------------------------
-//----------------------------------------------------------------------------------------------------------------------
-/**
- *  @brief Populate a request message with details from a test request message structure
- *
- *  @param[in] test_req Pointer to a test request message structure
- *  @param[out] req Pointer to a request message structure
- *
- *  @returns Test result
- */
-test_result_t populate_req(test_coap_client_msg_t *test_req, coap_msg_t *req)
-{
-    int ret = 0;
-
-    ret = coap_msg_set_type(req, test_req->type);
-    if (ret < 0)
-    {
-        printf("Error  : %s\n",strerror(-ret));
-        return FAIL;
-    }
-    ret = coap_msg_set_code(req, test_req->code_class, test_req->code_detail);
-    if (ret < 0)
-    {
-        printf("Error  : %s\n",strerror(-ret));
-        return FAIL;
-    }
-    ret = coap_msg_add_op(req, test_req->ops.num, test_req->ops.len, test_req->ops.val);
-    if (ret < 0)
-    {
-        printf("Error  : %s\n",strerror(-ret));
-        return FAIL;
-    }
-    if (test_req->payload)
-    {
-        ret = coap_msg_set_payload(req, test_req->payload, test_req->payload_len);
-        if (ret < 0)
-        {
-            printf("Error  : %s\n",strerror(-ret));
-            return FAIL;
-        }
-    }
-    return PASS;
-}
-//----------------------------------------------------------------------------------------------------------------------
-//----------------------------------------------------------------------------------------------------------------------
-/**
- *  @brief Send a request to the server and receive the response
- *
- *  @param[in,out] client Pointer to a client structure
- *  @param[in] test_req Pointer to a test request message structure
- *  @param[out] req Pointer to a request message structure
- *  @param[out] resp Pointer to a response message structure
- *
- *  @returns Test result
- */
-test_result_t exchange(coap_client_t *client, test_coap_client_msg_t *test_req, coap_msg_t *req, coap_msg_t *resp)
-{
-    test_result_t result = PASS;
-    int ret = 0;
-
-    result = populate_req(test_req, req);
-    if (result != PASS)
-    {
-        printf("populate_req FAIL\n");
-        return result;
-    }
-    ret = coap_client_exchange(client, req, resp);
-    if (ret < 0)
-    {
-        printf("coap_client_exchange FAIL\n");
-        printf("Error  : %s\n",strerror(-ret));
-        return FAIL;
-    }
-    //printf("coap_client_exchange PASS\n");
-    print_coap_msg("Sent:", req);
-    print_coap_msg("Received:", resp);
-
-    return PASS;
-}
-//----------------------------------------------------------------------------------------------------------------------
-//----------------------------------------------------------------------------------------------------------------------
-/**
- *  @brief Compare the version and token fields in a request message and a response message
- *
- *  @param[out] req Pointer to a request message structure
- *  @param[out] resp Pointer to a response message structure
- *
- *  @returns Test result
- */
-test_result_t compare_ver_token(coap_msg_t *req, coap_msg_t *resp)
-{
-    if (coap_msg_get_ver(req) != coap_msg_get_ver(resp))
-    {
-        return FAIL;
-    }
-    if (coap_msg_get_token_len(req) != coap_msg_get_token_len(resp))
-    {
-        return FAIL;
-    }
-    else if (memcmp(coap_msg_get_token(req), coap_msg_get_token(resp), coap_msg_get_token_len(req)) != 0)
-    {
-        return FAIL;
-    }
-    return PASS;
-}
-//----------------------------------------------------------------------------------------------------------------------
-//----------------------------------------------------------------------------------------------------------------------
-/**
- *  @brief Check the fields in a response message against the expected values
- *
- *  @param[out] test_resp Pointer to a test response message structure
- *  @param[out] resp Pointer to a response message structure
- *
- *  @returns Test result
- */
-test_result_t check_resp(test_coap_client_msg_t *test_resp, coap_msg_t *resp)
-{
-    if (test_resp->type != coap_msg_get_type(resp))
-    {
-        return FAIL;
-    }
-    if (test_resp->code_class != coap_msg_get_code_class(resp))
-    {
-        return FAIL;
-    }
-    if (test_resp->code_detail != coap_msg_get_code_detail(resp))
-    {
-        return FAIL;
-    }
-    return PASS;
-}