mbed 5.4 with sleep mode

Dependencies:  

Committer:
ranaumarnaeem
Date:
Thu May 25 11:53:45 2017 +0000
Revision:
39:4f3f7463e55f
mbed 5.4 with sleep mode

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ranaumarnaeem 39:4f3f7463e55f 1 /*
ranaumarnaeem 39:4f3f7463e55f 2 * Copyright (c) 2015 Keith Cullen.
ranaumarnaeem 39:4f3f7463e55f 3 * All Rights Reserved.
ranaumarnaeem 39:4f3f7463e55f 4 *
ranaumarnaeem 39:4f3f7463e55f 5 * Redistribution and use in source and binary forms, with or without
ranaumarnaeem 39:4f3f7463e55f 6 * modification, are permitted provided that the following conditions
ranaumarnaeem 39:4f3f7463e55f 7 * are met:
ranaumarnaeem 39:4f3f7463e55f 8 * 1. Redistributions of source code must retain the above copyright
ranaumarnaeem 39:4f3f7463e55f 9 * notice, this list of conditions and the following disclaimer.
ranaumarnaeem 39:4f3f7463e55f 10 * 2. Redistributions in binary form must reproduce the above copyright
ranaumarnaeem 39:4f3f7463e55f 11 * notice, this list of conditions and the following disclaimer in the
ranaumarnaeem 39:4f3f7463e55f 12 * documentation and/or other materials provided with the distribution.
ranaumarnaeem 39:4f3f7463e55f 13 * 3. The name of the author may not be used to endorse or promote products
ranaumarnaeem 39:4f3f7463e55f 14 * derived from this software without specific prior written permission.
ranaumarnaeem 39:4f3f7463e55f 15 *
ranaumarnaeem 39:4f3f7463e55f 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
ranaumarnaeem 39:4f3f7463e55f 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
ranaumarnaeem 39:4f3f7463e55f 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
ranaumarnaeem 39:4f3f7463e55f 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
ranaumarnaeem 39:4f3f7463e55f 20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
ranaumarnaeem 39:4f3f7463e55f 21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
ranaumarnaeem 39:4f3f7463e55f 22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
ranaumarnaeem 39:4f3f7463e55f 23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
ranaumarnaeem 39:4f3f7463e55f 24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ranaumarnaeem 39:4f3f7463e55f 25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
ranaumarnaeem 39:4f3f7463e55f 26 */
ranaumarnaeem 39:4f3f7463e55f 27
ranaumarnaeem 39:4f3f7463e55f 28 /**
ranaumarnaeem 39:4f3f7463e55f 29 * @file coap_client.c
ranaumarnaeem 39:4f3f7463e55f 30 *
ranaumarnaeem 39:4f3f7463e55f 31 * @brief Source file for the FreeCoAP client library
ranaumarnaeem 39:4f3f7463e55f 32 */
ranaumarnaeem 39:4f3f7463e55f 33
ranaumarnaeem 39:4f3f7463e55f 34 #include <stdlib.h>
ranaumarnaeem 39:4f3f7463e55f 35 #include <stdio.h>
ranaumarnaeem 39:4f3f7463e55f 36 #include <string.h>
ranaumarnaeem 39:4f3f7463e55f 37 #include <stdint.h>
ranaumarnaeem 39:4f3f7463e55f 38 #include <errno.h>
ranaumarnaeem 39:4f3f7463e55f 39
ranaumarnaeem 39:4f3f7463e55f 40 #include "coap_client.h"
ranaumarnaeem 39:4f3f7463e55f 41 #include "main.h"
ranaumarnaeem 39:4f3f7463e55f 42
ranaumarnaeem 39:4f3f7463e55f 43 #define COAP_CLIENT_ACK_TIMEOUT_SEC 2 /**< Minimum delay to wait before retransmitting a confirmable message */
ranaumarnaeem 39:4f3f7463e55f 44 #define COAP_CLIENT_MAX_RETRANSMIT 4 /**< Maximum number of times a confirmable message can be retransmitted */
ranaumarnaeem 39:4f3f7463e55f 45 #define COAP_CLIENT_RESP_TIMEOUT_SEC 30 /**< Maximum amount of time to wait for a response */
ranaumarnaeem 39:4f3f7463e55f 46
ranaumarnaeem 39:4f3f7463e55f 47 /****************************************************************************************************
ranaumarnaeem 39:4f3f7463e55f 48 * coap_client *
ranaumarnaeem 39:4f3f7463e55f 49 ****************************************************************************************************/
ranaumarnaeem 39:4f3f7463e55f 50 void coap_client_destroy(coap_client_t *client)
ranaumarnaeem 39:4f3f7463e55f 51 {
ranaumarnaeem 39:4f3f7463e55f 52 memset(client, 0, sizeof(coap_client_t));
ranaumarnaeem 39:4f3f7463e55f 53 }
ranaumarnaeem 39:4f3f7463e55f 54
ranaumarnaeem 39:4f3f7463e55f 55 /**
ranaumarnaeem 39:4f3f7463e55f 56 * @brief Send a message to the server
ranaumarnaeem 39:4f3f7463e55f 57 *
ranaumarnaeem 39:4f3f7463e55f 58 * @param[in,out] client Pointer to a client structure
ranaumarnaeem 39:4f3f7463e55f 59 * @param[in] msg Pointer to a message structure
ranaumarnaeem 39:4f3f7463e55f 60 *
ranaumarnaeem 39:4f3f7463e55f 61 * @returns Number of bytes sent or error code
ranaumarnaeem 39:4f3f7463e55f 62 * @retval >0 Number of bytes sent
ranaumarnaeem 39:4f3f7463e55f 63 * @retval <0 Error
ranaumarnaeem 39:4f3f7463e55f 64 */
ranaumarnaeem 39:4f3f7463e55f 65 static int coap_client_send(coap_client_t *client, coap_msg_t *msg)
ranaumarnaeem 39:4f3f7463e55f 66 {
ranaumarnaeem 39:4f3f7463e55f 67 int num = 0;
ranaumarnaeem 39:4f3f7463e55f 68 char buf[COAP_MSG_MAX_BUF_LEN] = {0};
ranaumarnaeem 39:4f3f7463e55f 69
ranaumarnaeem 39:4f3f7463e55f 70 num = coap_msg_format(msg, buf, sizeof(buf));
ranaumarnaeem 39:4f3f7463e55f 71 if (num < 0)
ranaumarnaeem 39:4f3f7463e55f 72 {
ranaumarnaeem 39:4f3f7463e55f 73 return num;
ranaumarnaeem 39:4f3f7463e55f 74 }
ranaumarnaeem 39:4f3f7463e55f 75 num = send(client->sd, buf, num);
ranaumarnaeem 39:4f3f7463e55f 76 if (num < 0)
ranaumarnaeem 39:4f3f7463e55f 77 {
ranaumarnaeem 39:4f3f7463e55f 78 printf("send error\n");
ranaumarnaeem 39:4f3f7463e55f 79 return -errno;
ranaumarnaeem 39:4f3f7463e55f 80 }
ranaumarnaeem 39:4f3f7463e55f 81
ranaumarnaeem 39:4f3f7463e55f 82 return num;
ranaumarnaeem 39:4f3f7463e55f 83 }
ranaumarnaeem 39:4f3f7463e55f 84
ranaumarnaeem 39:4f3f7463e55f 85 /**
ranaumarnaeem 39:4f3f7463e55f 86 * @brief Handle a format error in a received message
ranaumarnaeem 39:4f3f7463e55f 87 *
ranaumarnaeem 39:4f3f7463e55f 88 * Special handling for the case where a received
ranaumarnaeem 39:4f3f7463e55f 89 * message could not be parsed due to a format error.
ranaumarnaeem 39:4f3f7463e55f 90 * Extract enough information from the received message
ranaumarnaeem 39:4f3f7463e55f 91 * to form a reset message.
ranaumarnaeem 39:4f3f7463e55f 92 *
ranaumarnaeem 39:4f3f7463e55f 93 * @param[in,out] client Pointer to a client structure
ranaumarnaeem 39:4f3f7463e55f 94 * @param[in] buf Buffer containing the message
ranaumarnaeem 39:4f3f7463e55f 95 * @param[in] len length of the buffer
ranaumarnaeem 39:4f3f7463e55f 96 */
ranaumarnaeem 39:4f3f7463e55f 97 static void coap_client_handle_format_error(coap_client_t *client, char *buf, size_t len)
ranaumarnaeem 39:4f3f7463e55f 98 {
ranaumarnaeem 39:4f3f7463e55f 99 coap_msg_t msg = {0};
ranaumarnaeem 39:4f3f7463e55f 100 unsigned msg_id = 0;
ranaumarnaeem 39:4f3f7463e55f 101 unsigned type = 0;
ranaumarnaeem 39:4f3f7463e55f 102 int ret = 0;
ranaumarnaeem 39:4f3f7463e55f 103
ranaumarnaeem 39:4f3f7463e55f 104 ret = coap_msg_parse_type_msg_id(buf, len, &type, &msg_id);
ranaumarnaeem 39:4f3f7463e55f 105 if ((ret == 0) && (type == COAP_MSG_CON))
ranaumarnaeem 39:4f3f7463e55f 106 {
ranaumarnaeem 39:4f3f7463e55f 107 coap_msg_create(&msg);
ranaumarnaeem 39:4f3f7463e55f 108 ret = coap_msg_set_type(&msg, COAP_MSG_RST);
ranaumarnaeem 39:4f3f7463e55f 109 if (ret < 0)
ranaumarnaeem 39:4f3f7463e55f 110 {
ranaumarnaeem 39:4f3f7463e55f 111 coap_msg_destroy(&msg);
ranaumarnaeem 39:4f3f7463e55f 112 return;
ranaumarnaeem 39:4f3f7463e55f 113 }
ranaumarnaeem 39:4f3f7463e55f 114 ret = coap_msg_set_msg_id(&msg, msg_id);
ranaumarnaeem 39:4f3f7463e55f 115 if (ret < 0)
ranaumarnaeem 39:4f3f7463e55f 116 {
ranaumarnaeem 39:4f3f7463e55f 117 coap_msg_destroy(&msg);
ranaumarnaeem 39:4f3f7463e55f 118 return;
ranaumarnaeem 39:4f3f7463e55f 119 }
ranaumarnaeem 39:4f3f7463e55f 120 coap_client_send(client, &msg);
ranaumarnaeem 39:4f3f7463e55f 121 coap_msg_destroy(&msg);
ranaumarnaeem 39:4f3f7463e55f 122 }
ranaumarnaeem 39:4f3f7463e55f 123 }
ranaumarnaeem 39:4f3f7463e55f 124
ranaumarnaeem 39:4f3f7463e55f 125 /**
ranaumarnaeem 39:4f3f7463e55f 126 * @brief Receive a message from the server
ranaumarnaeem 39:4f3f7463e55f 127 *
ranaumarnaeem 39:4f3f7463e55f 128 * @param[in,out] client Pointer to a client structure
ranaumarnaeem 39:4f3f7463e55f 129 * @param[in] msg Pointer to a message structure
ranaumarnaeem 39:4f3f7463e55f 130 *
ranaumarnaeem 39:4f3f7463e55f 131 * @returns Number of bytes received or error code
ranaumarnaeem 39:4f3f7463e55f 132 * @retval >0 Number of bytes received
ranaumarnaeem 39:4f3f7463e55f 133 * @retval <0 Error
ranaumarnaeem 39:4f3f7463e55f 134 */
ranaumarnaeem 39:4f3f7463e55f 135 static int coap_client_recv(coap_client_t *client, coap_msg_t *msg)
ranaumarnaeem 39:4f3f7463e55f 136 {
ranaumarnaeem 39:4f3f7463e55f 137 int num = 0;
ranaumarnaeem 39:4f3f7463e55f 138 int ret = 0;
ranaumarnaeem 39:4f3f7463e55f 139 char buf[COAP_MSG_MAX_BUF_LEN] = {0};
ranaumarnaeem 39:4f3f7463e55f 140
ranaumarnaeem 39:4f3f7463e55f 141 num = recv(client->sd, buf, sizeof(buf));
ranaumarnaeem 39:4f3f7463e55f 142 if (num < 0)
ranaumarnaeem 39:4f3f7463e55f 143 {
ranaumarnaeem 39:4f3f7463e55f 144 return -errno;
ranaumarnaeem 39:4f3f7463e55f 145 }
ranaumarnaeem 39:4f3f7463e55f 146
ranaumarnaeem 39:4f3f7463e55f 147 ret = coap_msg_parse(msg, buf, num);
ranaumarnaeem 39:4f3f7463e55f 148 if (ret < 0)
ranaumarnaeem 39:4f3f7463e55f 149 {
ranaumarnaeem 39:4f3f7463e55f 150 if (ret == -EBADMSG)
ranaumarnaeem 39:4f3f7463e55f 151 {
ranaumarnaeem 39:4f3f7463e55f 152 coap_client_handle_format_error(client, buf, num);
ranaumarnaeem 39:4f3f7463e55f 153 }
ranaumarnaeem 39:4f3f7463e55f 154 return ret;
ranaumarnaeem 39:4f3f7463e55f 155 }
ranaumarnaeem 39:4f3f7463e55f 156 return num;
ranaumarnaeem 39:4f3f7463e55f 157 }
ranaumarnaeem 39:4f3f7463e55f 158
ranaumarnaeem 39:4f3f7463e55f 159 /**
ranaumarnaeem 39:4f3f7463e55f 160 * @brief Reject a received confirmable message
ranaumarnaeem 39:4f3f7463e55f 161 *
ranaumarnaeem 39:4f3f7463e55f 162 * Send a reset message to the server.
ranaumarnaeem 39:4f3f7463e55f 163 *
ranaumarnaeem 39:4f3f7463e55f 164 * @param[in,out] client Pointer to a client structure
ranaumarnaeem 39:4f3f7463e55f 165 * @param[in] msg Pointer to a message structure
ranaumarnaeem 39:4f3f7463e55f 166 *
ranaumarnaeem 39:4f3f7463e55f 167 * @returns Operation status
ranaumarnaeem 39:4f3f7463e55f 168 * @retval 0 Success
ranaumarnaeem 39:4f3f7463e55f 169 * @retval <0 Error
ranaumarnaeem 39:4f3f7463e55f 170 */
ranaumarnaeem 39:4f3f7463e55f 171 static int coap_client_reject_con(coap_client_t *client, coap_msg_t *msg)
ranaumarnaeem 39:4f3f7463e55f 172 {
ranaumarnaeem 39:4f3f7463e55f 173 coap_msg_t rej = {0};
ranaumarnaeem 39:4f3f7463e55f 174 int num = 0;
ranaumarnaeem 39:4f3f7463e55f 175 int ret = 0;
ranaumarnaeem 39:4f3f7463e55f 176
ranaumarnaeem 39:4f3f7463e55f 177 printf("Rejecting confirmable message from host %s and port %s\n", client->server_host, client->server_port);
ranaumarnaeem 39:4f3f7463e55f 178 coap_msg_create(&rej);
ranaumarnaeem 39:4f3f7463e55f 179 ret = coap_msg_set_type(&rej, COAP_MSG_RST);
ranaumarnaeem 39:4f3f7463e55f 180 if (ret < 0)
ranaumarnaeem 39:4f3f7463e55f 181 {
ranaumarnaeem 39:4f3f7463e55f 182 coap_msg_destroy(&rej);
ranaumarnaeem 39:4f3f7463e55f 183 return ret;
ranaumarnaeem 39:4f3f7463e55f 184 }
ranaumarnaeem 39:4f3f7463e55f 185 ret = coap_msg_set_msg_id(&rej, coap_msg_get_msg_id(msg));
ranaumarnaeem 39:4f3f7463e55f 186 if (ret < 0)
ranaumarnaeem 39:4f3f7463e55f 187 {
ranaumarnaeem 39:4f3f7463e55f 188 coap_msg_destroy(&rej);
ranaumarnaeem 39:4f3f7463e55f 189 return ret;
ranaumarnaeem 39:4f3f7463e55f 190 }
ranaumarnaeem 39:4f3f7463e55f 191 num = coap_client_send(client, &rej);
ranaumarnaeem 39:4f3f7463e55f 192 coap_msg_destroy(&rej);
ranaumarnaeem 39:4f3f7463e55f 193 if (num < 0)
ranaumarnaeem 39:4f3f7463e55f 194 {
ranaumarnaeem 39:4f3f7463e55f 195 return num;
ranaumarnaeem 39:4f3f7463e55f 196 }
ranaumarnaeem 39:4f3f7463e55f 197 return 0;
ranaumarnaeem 39:4f3f7463e55f 198 }
ranaumarnaeem 39:4f3f7463e55f 199
ranaumarnaeem 39:4f3f7463e55f 200 /**
ranaumarnaeem 39:4f3f7463e55f 201 * @brief Reject a received non-confirmable message
ranaumarnaeem 39:4f3f7463e55f 202 *
ranaumarnaeem 39:4f3f7463e55f 203 * @param[in] client Pointer to a client structure
ranaumarnaeem 39:4f3f7463e55f 204 * @param[in] msg Pointer to a message structure
ranaumarnaeem 39:4f3f7463e55f 205 *
ranaumarnaeem 39:4f3f7463e55f 206 * @returns Operation status
ranaumarnaeem 39:4f3f7463e55f 207 * @retval 0 Success
ranaumarnaeem 39:4f3f7463e55f 208 */
ranaumarnaeem 39:4f3f7463e55f 209 static int coap_client_reject_non(coap_client_t *client, coap_msg_t *msg)
ranaumarnaeem 39:4f3f7463e55f 210 {
ranaumarnaeem 39:4f3f7463e55f 211 printf("Rejecting non-confirmable message from host %s and port %s\n", client->server_host, client->server_port);
ranaumarnaeem 39:4f3f7463e55f 212 return 0;
ranaumarnaeem 39:4f3f7463e55f 213 }
ranaumarnaeem 39:4f3f7463e55f 214
ranaumarnaeem 39:4f3f7463e55f 215 /**
ranaumarnaeem 39:4f3f7463e55f 216 * @brief Reject a received acknowledgement message
ranaumarnaeem 39:4f3f7463e55f 217 *
ranaumarnaeem 39:4f3f7463e55f 218 * @param[in] client Pointer to a client structure
ranaumarnaeem 39:4f3f7463e55f 219 * @param[in] msg Pointer to a message structure
ranaumarnaeem 39:4f3f7463e55f 220 *
ranaumarnaeem 39:4f3f7463e55f 221 * @returns Operation status
ranaumarnaeem 39:4f3f7463e55f 222 * @retval 0 Success
ranaumarnaeem 39:4f3f7463e55f 223 */
ranaumarnaeem 39:4f3f7463e55f 224 static int coap_client_reject_ack(coap_client_t *client, coap_msg_t *msg)
ranaumarnaeem 39:4f3f7463e55f 225 {
ranaumarnaeem 39:4f3f7463e55f 226 printf("Rejecting acknowledgement message from host %s and port %s\n", client->server_host, client->server_port);
ranaumarnaeem 39:4f3f7463e55f 227 return 0;
ranaumarnaeem 39:4f3f7463e55f 228 }
ranaumarnaeem 39:4f3f7463e55f 229
ranaumarnaeem 39:4f3f7463e55f 230 /**
ranaumarnaeem 39:4f3f7463e55f 231 * @brief Reject a received reset message
ranaumarnaeem 39:4f3f7463e55f 232 *
ranaumarnaeem 39:4f3f7463e55f 233 * @param[in] client Pointer to a client structure
ranaumarnaeem 39:4f3f7463e55f 234 * @param[in] msg Pointer to a message structure
ranaumarnaeem 39:4f3f7463e55f 235 *
ranaumarnaeem 39:4f3f7463e55f 236 * @returns Operation status
ranaumarnaeem 39:4f3f7463e55f 237 * @retval 0 Success
ranaumarnaeem 39:4f3f7463e55f 238 */
ranaumarnaeem 39:4f3f7463e55f 239 static int coap_client_reject_reset(coap_client_t *client, coap_msg_t *msg)
ranaumarnaeem 39:4f3f7463e55f 240 {
ranaumarnaeem 39:4f3f7463e55f 241 printf("Rejecting reset message from host %s and port %s\n", client->server_host, client->server_port);
ranaumarnaeem 39:4f3f7463e55f 242 return 0;
ranaumarnaeem 39:4f3f7463e55f 243 }
ranaumarnaeem 39:4f3f7463e55f 244
ranaumarnaeem 39:4f3f7463e55f 245 /**
ranaumarnaeem 39:4f3f7463e55f 246 * @brief Reject a received message
ranaumarnaeem 39:4f3f7463e55f 247 *
ranaumarnaeem 39:4f3f7463e55f 248 * @param[in,out] client Pointer to a client structure
ranaumarnaeem 39:4f3f7463e55f 249 * @param[in] msg Pointer to a message structure
ranaumarnaeem 39:4f3f7463e55f 250 *
ranaumarnaeem 39:4f3f7463e55f 251 * @returns Operation status
ranaumarnaeem 39:4f3f7463e55f 252 * @retval 0 Success
ranaumarnaeem 39:4f3f7463e55f 253 * @retval <0 Error
ranaumarnaeem 39:4f3f7463e55f 254 */
ranaumarnaeem 39:4f3f7463e55f 255 static int coap_client_reject(coap_client_t *client, coap_msg_t *msg)
ranaumarnaeem 39:4f3f7463e55f 256 {
ranaumarnaeem 39:4f3f7463e55f 257 if (coap_msg_get_type(msg) == COAP_MSG_CON)
ranaumarnaeem 39:4f3f7463e55f 258 {
ranaumarnaeem 39:4f3f7463e55f 259 return coap_client_reject_con(client, msg);
ranaumarnaeem 39:4f3f7463e55f 260 }
ranaumarnaeem 39:4f3f7463e55f 261 else if (coap_msg_get_type(msg) == COAP_MSG_NON)
ranaumarnaeem 39:4f3f7463e55f 262 {
ranaumarnaeem 39:4f3f7463e55f 263 return coap_client_reject_non(client, msg);
ranaumarnaeem 39:4f3f7463e55f 264 }
ranaumarnaeem 39:4f3f7463e55f 265 else if (coap_msg_get_type(msg) == COAP_MSG_ACK)
ranaumarnaeem 39:4f3f7463e55f 266 {
ranaumarnaeem 39:4f3f7463e55f 267 return coap_client_reject_ack(client, msg);
ranaumarnaeem 39:4f3f7463e55f 268 }
ranaumarnaeem 39:4f3f7463e55f 269 else if (coap_msg_get_type(msg) == COAP_MSG_RST)
ranaumarnaeem 39:4f3f7463e55f 270 {
ranaumarnaeem 39:4f3f7463e55f 271 return coap_client_reject_reset(client, msg);
ranaumarnaeem 39:4f3f7463e55f 272 }
ranaumarnaeem 39:4f3f7463e55f 273 return 0; /* should never arrive here */
ranaumarnaeem 39:4f3f7463e55f 274 }
ranaumarnaeem 39:4f3f7463e55f 275
ranaumarnaeem 39:4f3f7463e55f 276 /**
ranaumarnaeem 39:4f3f7463e55f 277 * @brief Send an acknowledgement message to the server
ranaumarnaeem 39:4f3f7463e55f 278 *
ranaumarnaeem 39:4f3f7463e55f 279 * @param[in,out] client Pointer to a client structure
ranaumarnaeem 39:4f3f7463e55f 280 * @param[in] msg Pointer to a message structure
ranaumarnaeem 39:4f3f7463e55f 281 *
ranaumarnaeem 39:4f3f7463e55f 282 * @returns Operation status
ranaumarnaeem 39:4f3f7463e55f 283 * @retval 0 Success
ranaumarnaeem 39:4f3f7463e55f 284 * @retval <0 Error
ranaumarnaeem 39:4f3f7463e55f 285 */
ranaumarnaeem 39:4f3f7463e55f 286 static int coap_client_send_ack(coap_client_t *client, coap_msg_t *msg)
ranaumarnaeem 39:4f3f7463e55f 287 {
ranaumarnaeem 39:4f3f7463e55f 288 coap_msg_t ack = {0};
ranaumarnaeem 39:4f3f7463e55f 289 int num = 0;
ranaumarnaeem 39:4f3f7463e55f 290 int ret = 0;
ranaumarnaeem 39:4f3f7463e55f 291
ranaumarnaeem 39:4f3f7463e55f 292 printf("Acknowledging confirmable message from host %s and port %s\n", client->server_host, client->server_port);
ranaumarnaeem 39:4f3f7463e55f 293 coap_msg_create(&ack);
ranaumarnaeem 39:4f3f7463e55f 294 ret = coap_msg_set_type(&ack, COAP_MSG_ACK);
ranaumarnaeem 39:4f3f7463e55f 295 if (ret < 0)
ranaumarnaeem 39:4f3f7463e55f 296 {
ranaumarnaeem 39:4f3f7463e55f 297 coap_msg_destroy(&ack);
ranaumarnaeem 39:4f3f7463e55f 298 return ret;
ranaumarnaeem 39:4f3f7463e55f 299 }
ranaumarnaeem 39:4f3f7463e55f 300 ret = coap_msg_set_msg_id(&ack, coap_msg_get_msg_id(msg));
ranaumarnaeem 39:4f3f7463e55f 301 if (ret < 0)
ranaumarnaeem 39:4f3f7463e55f 302 {
ranaumarnaeem 39:4f3f7463e55f 303 coap_msg_destroy(&ack);
ranaumarnaeem 39:4f3f7463e55f 304 return ret;
ranaumarnaeem 39:4f3f7463e55f 305 }
ranaumarnaeem 39:4f3f7463e55f 306 num = coap_client_send(client, &ack);
ranaumarnaeem 39:4f3f7463e55f 307 coap_msg_destroy(&ack);
ranaumarnaeem 39:4f3f7463e55f 308 if (num < 0)
ranaumarnaeem 39:4f3f7463e55f 309 {
ranaumarnaeem 39:4f3f7463e55f 310 return num;
ranaumarnaeem 39:4f3f7463e55f 311 }
ranaumarnaeem 39:4f3f7463e55f 312 return 0;
ranaumarnaeem 39:4f3f7463e55f 313 }
ranaumarnaeem 39:4f3f7463e55f 314
ranaumarnaeem 39:4f3f7463e55f 315 /**
ranaumarnaeem 39:4f3f7463e55f 316 * @brief Compare the token values in a request message and a response message
ranaumarnaeem 39:4f3f7463e55f 317 *
ranaumarnaeem 39:4f3f7463e55f 318 * @param[in] req Pointer to the request message
ranaumarnaeem 39:4f3f7463e55f 319 * @param[in] resp Pointer to the response message
ranaumarnaeem 39:4f3f7463e55f 320 *
ranaumarnaeem 39:4f3f7463e55f 321 * @returns Comparison value
ranaumarnaeem 39:4f3f7463e55f 322 * @retval 0 the tokens are not equal
ranaumarnaeem 39:4f3f7463e55f 323 * @retval 1 the tokens are equal
ranaumarnaeem 39:4f3f7463e55f 324 */
ranaumarnaeem 39:4f3f7463e55f 325 static int coap_client_match_token(coap_msg_t *req, coap_msg_t *resp)
ranaumarnaeem 39:4f3f7463e55f 326 {
ranaumarnaeem 39:4f3f7463e55f 327 return ((coap_msg_get_token_len(resp) == coap_msg_get_token_len(req))
ranaumarnaeem 39:4f3f7463e55f 328 && (memcmp(coap_msg_get_token(resp), coap_msg_get_token(req), coap_msg_get_token_len(req)) == 0));
ranaumarnaeem 39:4f3f7463e55f 329 }
ranaumarnaeem 39:4f3f7463e55f 330
ranaumarnaeem 39:4f3f7463e55f 331 /**
ranaumarnaeem 39:4f3f7463e55f 332 * @brief Check that all of the options in a message are acceptable
ranaumarnaeem 39:4f3f7463e55f 333 *
ranaumarnaeem 39:4f3f7463e55f 334 * For a proxy, options are acceptable if they are safe to forward or recognized or both.
ranaumarnaeem 39:4f3f7463e55f 335 * For a server, options are acceptable if they are elective or recognized or both.
ranaumarnaeem 39:4f3f7463e55f 336 *
ranaumarnaeem 39:4f3f7463e55f 337 * @param[in] msg Pointer to message structure
ranaumarnaeem 39:4f3f7463e55f 338 *
ranaumarnaeem 39:4f3f7463e55f 339 * @returns Operation status or bad option number
ranaumarnaeem 39:4f3f7463e55f 340 * @retval 0 Success
ranaumarnaeem 39:4f3f7463e55f 341 * @retval >0 Bad option number
ranaumarnaeem 39:4f3f7463e55f 342 */
ranaumarnaeem 39:4f3f7463e55f 343 static unsigned coap_client_check_options(coap_msg_t *msg)
ranaumarnaeem 39:4f3f7463e55f 344 {
ranaumarnaeem 39:4f3f7463e55f 345 #ifdef COAP_PROXY
ranaumarnaeem 39:4f3f7463e55f 346 return coap_msg_check_unsafe_ops(msg);
ranaumarnaeem 39:4f3f7463e55f 347 #else /* !COAP_PROXY */
ranaumarnaeem 39:4f3f7463e55f 348 return coap_msg_check_critical_ops(msg);
ranaumarnaeem 39:4f3f7463e55f 349 #endif /* COAP_PROXY */
ranaumarnaeem 39:4f3f7463e55f 350 }
ranaumarnaeem 39:4f3f7463e55f 351
ranaumarnaeem 39:4f3f7463e55f 352 /**
ranaumarnaeem 39:4f3f7463e55f 353 * @brief Handle a received piggy-backed response message
ranaumarnaeem 39:4f3f7463e55f 354 *
ranaumarnaeem 39:4f3f7463e55f 355 * An acknowledgement has been received that contains
ranaumarnaeem 39:4f3f7463e55f 356 * the same token as the request. Check the response
ranaumarnaeem 39:4f3f7463e55f 357 * contained within it.
ranaumarnaeem 39:4f3f7463e55f 358 *
ranaumarnaeem 39:4f3f7463e55f 359 * @param[in,out] client Pointer to a client structure
ranaumarnaeem 39:4f3f7463e55f 360 * @param[in] resp Pointer to the response message
ranaumarnaeem 39:4f3f7463e55f 361 *
ranaumarnaeem 39:4f3f7463e55f 362 * @returns Operation status
ranaumarnaeem 39:4f3f7463e55f 363 * @retval 0 Success
ranaumarnaeem 39:4f3f7463e55f 364 * @retval <0 Error
ranaumarnaeem 39:4f3f7463e55f 365 */
ranaumarnaeem 39:4f3f7463e55f 366 static int coap_client_handle_piggybacked_response(coap_client_t *client, coap_msg_t *resp)
ranaumarnaeem 39:4f3f7463e55f 367 {
ranaumarnaeem 39:4f3f7463e55f 368 unsigned op_num = 0;
ranaumarnaeem 39:4f3f7463e55f 369
ranaumarnaeem 39:4f3f7463e55f 370 op_num = coap_client_check_options(resp);
ranaumarnaeem 39:4f3f7463e55f 371 if (op_num != 0)
ranaumarnaeem 39:4f3f7463e55f 372 {
ranaumarnaeem 39:4f3f7463e55f 373 printf("Found bad option number %u in message from host %s and port %s\n", op_num, client->server_host, client->server_port);
ranaumarnaeem 39:4f3f7463e55f 374 coap_client_reject(client, resp);
ranaumarnaeem 39:4f3f7463e55f 375 return -EBADMSG;
ranaumarnaeem 39:4f3f7463e55f 376 }
ranaumarnaeem 39:4f3f7463e55f 377 printf("Received acknowledgement and response from Server\n");
ranaumarnaeem 39:4f3f7463e55f 378 return 0;
ranaumarnaeem 39:4f3f7463e55f 379 }
ranaumarnaeem 39:4f3f7463e55f 380
ranaumarnaeem 39:4f3f7463e55f 381 /**
ranaumarnaeem 39:4f3f7463e55f 382 * @brief Handle a received separate response message
ranaumarnaeem 39:4f3f7463e55f 383 *
ranaumarnaeem 39:4f3f7463e55f 384 * A separate response has been received that contains
ranaumarnaeem 39:4f3f7463e55f 385 * the same token as the request. Check the response
ranaumarnaeem 39:4f3f7463e55f 386 * and send an acknowledgement if necessary.
ranaumarnaeem 39:4f3f7463e55f 387 *
ranaumarnaeem 39:4f3f7463e55f 388 * @param[in,out] client Pointer to a client structure
ranaumarnaeem 39:4f3f7463e55f 389 * @param[in] resp Pointer to the response message
ranaumarnaeem 39:4f3f7463e55f 390 *
ranaumarnaeem 39:4f3f7463e55f 391 * @returns Operation status
ranaumarnaeem 39:4f3f7463e55f 392 * @retval 0 Success
ranaumarnaeem 39:4f3f7463e55f 393 * @retval <0 Error
ranaumarnaeem 39:4f3f7463e55f 394 */
ranaumarnaeem 39:4f3f7463e55f 395 static int coap_client_handle_sep_response(coap_client_t *client, coap_msg_t *resp)
ranaumarnaeem 39:4f3f7463e55f 396 {
ranaumarnaeem 39:4f3f7463e55f 397 unsigned op_num = 0;
ranaumarnaeem 39:4f3f7463e55f 398
ranaumarnaeem 39:4f3f7463e55f 399 if (coap_msg_get_type(resp) == COAP_MSG_CON)
ranaumarnaeem 39:4f3f7463e55f 400 {
ranaumarnaeem 39:4f3f7463e55f 401 printf("Received confirmable response from host %s and port %s\n", client->server_host, client->server_port);
ranaumarnaeem 39:4f3f7463e55f 402 op_num = coap_client_check_options(resp);
ranaumarnaeem 39:4f3f7463e55f 403 if (op_num != 0)
ranaumarnaeem 39:4f3f7463e55f 404 {
ranaumarnaeem 39:4f3f7463e55f 405 printf("Found bad option number %u in message from host %s and port %s\n", op_num, client->server_host, client->server_port);
ranaumarnaeem 39:4f3f7463e55f 406 coap_client_reject(client, resp);
ranaumarnaeem 39:4f3f7463e55f 407 return -EBADMSG;
ranaumarnaeem 39:4f3f7463e55f 408 }
ranaumarnaeem 39:4f3f7463e55f 409 return coap_client_send_ack(client, resp);
ranaumarnaeem 39:4f3f7463e55f 410 }
ranaumarnaeem 39:4f3f7463e55f 411 else if (coap_msg_get_type(resp) == COAP_MSG_NON)
ranaumarnaeem 39:4f3f7463e55f 412 {
ranaumarnaeem 39:4f3f7463e55f 413 printf("Received non-confirmable response from host %s and port %s\n", client->server_host, client->server_port);
ranaumarnaeem 39:4f3f7463e55f 414 op_num = coap_client_check_options(resp);
ranaumarnaeem 39:4f3f7463e55f 415 if (op_num != 0)
ranaumarnaeem 39:4f3f7463e55f 416 {
ranaumarnaeem 39:4f3f7463e55f 417 printf("Found bad option number %u in message from host %s and port %s\n", op_num, client->server_host, client->server_port);
ranaumarnaeem 39:4f3f7463e55f 418 coap_client_reject(client, resp);
ranaumarnaeem 39:4f3f7463e55f 419 return -EBADMSG;
ranaumarnaeem 39:4f3f7463e55f 420 }
ranaumarnaeem 39:4f3f7463e55f 421 return 0;
ranaumarnaeem 39:4f3f7463e55f 422 }
ranaumarnaeem 39:4f3f7463e55f 423 coap_client_reject(client, resp);
ranaumarnaeem 39:4f3f7463e55f 424 return -EBADMSG;
ranaumarnaeem 39:4f3f7463e55f 425 }
ranaumarnaeem 39:4f3f7463e55f 426
ranaumarnaeem 39:4f3f7463e55f 427 /**
ranaumarnaeem 39:4f3f7463e55f 428 * @brief Handle a separate response to a confirmable request
ranaumarnaeem 39:4f3f7463e55f 429 *
ranaumarnaeem 39:4f3f7463e55f 430 * An acknowledgement has been received. Receive the
ranaumarnaeem 39:4f3f7463e55f 431 * response and send an acknowledgement back to the server.
ranaumarnaeem 39:4f3f7463e55f 432 *
ranaumarnaeem 39:4f3f7463e55f 433 * @param[in,out] client Pointer to a client structure
ranaumarnaeem 39:4f3f7463e55f 434 * @param[in] req Pointer to the request message
ranaumarnaeem 39:4f3f7463e55f 435 * @param[out] resp Pointer to the response message
ranaumarnaeem 39:4f3f7463e55f 436 *
ranaumarnaeem 39:4f3f7463e55f 437 * @returns Operation status
ranaumarnaeem 39:4f3f7463e55f 438 * @retval 0 Success
ranaumarnaeem 39:4f3f7463e55f 439 * @retval <0 Error
ranaumarnaeem 39:4f3f7463e55f 440 */
ranaumarnaeem 39:4f3f7463e55f 441 static int coap_client_exchange_sep(coap_client_t *client, coap_msg_t *req, coap_msg_t *resp)
ranaumarnaeem 39:4f3f7463e55f 442 {
ranaumarnaeem 39:4f3f7463e55f 443 int num = 0;
ranaumarnaeem 39:4f3f7463e55f 444 int ret = 0;
ranaumarnaeem 39:4f3f7463e55f 445 int starttimeout,endtimeout;
ranaumarnaeem 39:4f3f7463e55f 446
ranaumarnaeem 39:4f3f7463e55f 447 /* wait for a separate response to a confirmable request */
ranaumarnaeem 39:4f3f7463e55f 448 printf("Expecting response from host %s and port %s\n", client->server_host, client->server_port);
ranaumarnaeem 39:4f3f7463e55f 449 while (1)
ranaumarnaeem 39:4f3f7463e55f 450 {
ranaumarnaeem 39:4f3f7463e55f 451 starttimeout = readseconds();
ranaumarnaeem 39:4f3f7463e55f 452 while(1)
ranaumarnaeem 39:4f3f7463e55f 453 {
ranaumarnaeem 39:4f3f7463e55f 454 num = coap_client_recv(client, resp);
ranaumarnaeem 39:4f3f7463e55f 455 if (num < 0)
ranaumarnaeem 39:4f3f7463e55f 456 {
ranaumarnaeem 39:4f3f7463e55f 457 return num;
ranaumarnaeem 39:4f3f7463e55f 458 }
ranaumarnaeem 39:4f3f7463e55f 459 else if(num > 0)
ranaumarnaeem 39:4f3f7463e55f 460 {
ranaumarnaeem 39:4f3f7463e55f 461 break;
ranaumarnaeem 39:4f3f7463e55f 462 }
ranaumarnaeem 39:4f3f7463e55f 463 endtimeout = readseconds();
ranaumarnaeem 39:4f3f7463e55f 464 if((endtimeout - starttimeout) > COAP_CLIENT_RESP_TIMEOUT_SEC)
ranaumarnaeem 39:4f3f7463e55f 465 {
ranaumarnaeem 39:4f3f7463e55f 466 printf("Timeout no data received\n");
ranaumarnaeem 39:4f3f7463e55f 467 return -1;
ranaumarnaeem 39:4f3f7463e55f 468 }
ranaumarnaeem 39:4f3f7463e55f 469 }
ranaumarnaeem 39:4f3f7463e55f 470
ranaumarnaeem 39:4f3f7463e55f 471 if (coap_msg_get_msg_id(resp) == coap_msg_get_msg_id(req))
ranaumarnaeem 39:4f3f7463e55f 472 {
ranaumarnaeem 39:4f3f7463e55f 473 if (coap_msg_get_type(resp) == COAP_MSG_ACK)
ranaumarnaeem 39:4f3f7463e55f 474 {
ranaumarnaeem 39:4f3f7463e55f 475 /* message deduplication */
ranaumarnaeem 39:4f3f7463e55f 476 printf("Received duplicate acknowledgement from host %s and port %s\n", client->server_host, client->server_port);
ranaumarnaeem 39:4f3f7463e55f 477 continue;
ranaumarnaeem 39:4f3f7463e55f 478 }
ranaumarnaeem 39:4f3f7463e55f 479 else if (coap_msg_get_type(resp) == COAP_MSG_RST)
ranaumarnaeem 39:4f3f7463e55f 480 {
ranaumarnaeem 39:4f3f7463e55f 481 return -ECONNRESET;
ranaumarnaeem 39:4f3f7463e55f 482 }
ranaumarnaeem 39:4f3f7463e55f 483 coap_client_reject(client, resp);
ranaumarnaeem 39:4f3f7463e55f 484 return -EBADMSG;
ranaumarnaeem 39:4f3f7463e55f 485 }
ranaumarnaeem 39:4f3f7463e55f 486 if (coap_client_match_token(req, resp))
ranaumarnaeem 39:4f3f7463e55f 487 {
ranaumarnaeem 39:4f3f7463e55f 488 return coap_client_handle_sep_response(client, resp);
ranaumarnaeem 39:4f3f7463e55f 489 }
ranaumarnaeem 39:4f3f7463e55f 490 /* message deduplication */
ranaumarnaeem 39:4f3f7463e55f 491 /* we might have received a duplicate message that was already received from the same server */
ranaumarnaeem 39:4f3f7463e55f 492 /* reject the message and continue listening */
ranaumarnaeem 39:4f3f7463e55f 493 ret = coap_client_reject(client, resp);
ranaumarnaeem 39:4f3f7463e55f 494 if (ret < 0 )
ranaumarnaeem 39:4f3f7463e55f 495 {
ranaumarnaeem 39:4f3f7463e55f 496 return ret;
ranaumarnaeem 39:4f3f7463e55f 497 }
ranaumarnaeem 39:4f3f7463e55f 498 }
ranaumarnaeem 39:4f3f7463e55f 499 return 0;
ranaumarnaeem 39:4f3f7463e55f 500 }
ranaumarnaeem 39:4f3f7463e55f 501
ranaumarnaeem 39:4f3f7463e55f 502 /**
ranaumarnaeem 39:4f3f7463e55f 503 * @brief Handle the response to a confirmable request
ranaumarnaeem 39:4f3f7463e55f 504 *
ranaumarnaeem 39:4f3f7463e55f 505 * A confirmable request has been sent to the server.
ranaumarnaeem 39:4f3f7463e55f 506 * Receive the acknowledgement and response. Send an
ranaumarnaeem 39:4f3f7463e55f 507 * acknowledgement if necessary.
ranaumarnaeem 39:4f3f7463e55f 508 *
ranaumarnaeem 39:4f3f7463e55f 509 * @param[in,out] client Pointer to a client structure
ranaumarnaeem 39:4f3f7463e55f 510 * @param[in] req Pointer to the request message
ranaumarnaeem 39:4f3f7463e55f 511 * @param[out] resp Pointer to the response message
ranaumarnaeem 39:4f3f7463e55f 512 *
ranaumarnaeem 39:4f3f7463e55f 513 * @returns Operation status
ranaumarnaeem 39:4f3f7463e55f 514 * @retval 0 Success
ranaumarnaeem 39:4f3f7463e55f 515 * @retval <0 Error
ranaumarnaeem 39:4f3f7463e55f 516 */
ranaumarnaeem 39:4f3f7463e55f 517 static int coap_client_exchange_con(coap_client_t *client, coap_msg_t *req, coap_msg_t *resp)
ranaumarnaeem 39:4f3f7463e55f 518 {
ranaumarnaeem 39:4f3f7463e55f 519 int num = 0;
ranaumarnaeem 39:4f3f7463e55f 520 int ret = 0;
ranaumarnaeem 39:4f3f7463e55f 521 int starttimeout,endtimeout;
ranaumarnaeem 39:4f3f7463e55f 522 /* wait for piggy-backed response in ack message
ranaumarnaeem 39:4f3f7463e55f 523 * or ack message and separate response message
ranaumarnaeem 39:4f3f7463e55f 524 */
ranaumarnaeem 39:4f3f7463e55f 525 //printf("Expecting acknowledgement from server\r\n");
ranaumarnaeem 39:4f3f7463e55f 526 client->num_retrans = 0;
ranaumarnaeem 39:4f3f7463e55f 527 while (1)
ranaumarnaeem 39:4f3f7463e55f 528 {
ranaumarnaeem 39:4f3f7463e55f 529 int doubletimeout = COAP_CLIENT_ACK_TIMEOUT_SEC;
ranaumarnaeem 39:4f3f7463e55f 530 starttimeout = readseconds();
ranaumarnaeem 39:4f3f7463e55f 531 while(1)
ranaumarnaeem 39:4f3f7463e55f 532 {
ranaumarnaeem 39:4f3f7463e55f 533 num = coap_client_recv(client, resp);
ranaumarnaeem 39:4f3f7463e55f 534 if (num < 0)
ranaumarnaeem 39:4f3f7463e55f 535 {
ranaumarnaeem 39:4f3f7463e55f 536 //return num;
ranaumarnaeem 39:4f3f7463e55f 537 }
ranaumarnaeem 39:4f3f7463e55f 538 else if(num > 0)
ranaumarnaeem 39:4f3f7463e55f 539 {
ranaumarnaeem 39:4f3f7463e55f 540 break;
ranaumarnaeem 39:4f3f7463e55f 541 }
ranaumarnaeem 39:4f3f7463e55f 542 endtimeout = readseconds();
ranaumarnaeem 39:4f3f7463e55f 543 if((endtimeout - starttimeout) > doubletimeout)
ranaumarnaeem 39:4f3f7463e55f 544 {
ranaumarnaeem 39:4f3f7463e55f 545 printf("Timeout no data received after %d seconds\n",endtimeout - starttimeout);
ranaumarnaeem 39:4f3f7463e55f 546
ranaumarnaeem 39:4f3f7463e55f 547 if (client->num_retrans >= COAP_CLIENT_MAX_RETRANSMIT)
ranaumarnaeem 39:4f3f7463e55f 548 {
ranaumarnaeem 39:4f3f7463e55f 549 printf("Maximum retries reached no ack from server!\r\n");
ranaumarnaeem 39:4f3f7463e55f 550 return -ETIMEDOUT;
ranaumarnaeem 39:4f3f7463e55f 551 }
ranaumarnaeem 39:4f3f7463e55f 552
ranaumarnaeem 39:4f3f7463e55f 553 doubletimeout = 2 * doubletimeout;
ranaumarnaeem 39:4f3f7463e55f 554 starttimeout = readseconds();
ranaumarnaeem 39:4f3f7463e55f 555 client->num_retrans++;
ranaumarnaeem 39:4f3f7463e55f 556
ranaumarnaeem 39:4f3f7463e55f 557 printf("Retransmitting to server...\r\n");
ranaumarnaeem 39:4f3f7463e55f 558 num = coap_client_send(client, req);
ranaumarnaeem 39:4f3f7463e55f 559 if (num < 0)
ranaumarnaeem 39:4f3f7463e55f 560 {
ranaumarnaeem 39:4f3f7463e55f 561 printf("Resending Failed to server...\r\n");
ranaumarnaeem 39:4f3f7463e55f 562 return num;
ranaumarnaeem 39:4f3f7463e55f 563 }
ranaumarnaeem 39:4f3f7463e55f 564 }
ranaumarnaeem 39:4f3f7463e55f 565 }
ranaumarnaeem 39:4f3f7463e55f 566
ranaumarnaeem 39:4f3f7463e55f 567 if (coap_msg_get_msg_id(resp) == coap_msg_get_msg_id(req))
ranaumarnaeem 39:4f3f7463e55f 568 {
ranaumarnaeem 39:4f3f7463e55f 569 if (coap_msg_get_type(resp) == COAP_MSG_ACK)
ranaumarnaeem 39:4f3f7463e55f 570 {
ranaumarnaeem 39:4f3f7463e55f 571 if (coap_msg_is_empty(resp))
ranaumarnaeem 39:4f3f7463e55f 572 {
ranaumarnaeem 39:4f3f7463e55f 573 /* received ack message, wait for separate response message */
ranaumarnaeem 39:4f3f7463e55f 574 printf("Received acknowledgement from host %s and port %s\n", client->server_host, client->server_port);
ranaumarnaeem 39:4f3f7463e55f 575 return coap_client_exchange_sep(client, req, resp);
ranaumarnaeem 39:4f3f7463e55f 576 }
ranaumarnaeem 39:4f3f7463e55f 577 else if (coap_client_match_token(req, resp))
ranaumarnaeem 39:4f3f7463e55f 578 {
ranaumarnaeem 39:4f3f7463e55f 579 return coap_client_handle_piggybacked_response(client, resp);
ranaumarnaeem 39:4f3f7463e55f 580 }
ranaumarnaeem 39:4f3f7463e55f 581 }
ranaumarnaeem 39:4f3f7463e55f 582 else if (coap_msg_get_type(resp) == COAP_MSG_RST)
ranaumarnaeem 39:4f3f7463e55f 583 {
ranaumarnaeem 39:4f3f7463e55f 584 return -ECONNRESET;
ranaumarnaeem 39:4f3f7463e55f 585 }
ranaumarnaeem 39:4f3f7463e55f 586 coap_client_reject(client, resp);
ranaumarnaeem 39:4f3f7463e55f 587 return -EBADMSG;
ranaumarnaeem 39:4f3f7463e55f 588 }
ranaumarnaeem 39:4f3f7463e55f 589 else if (coap_client_match_token(req, resp))
ranaumarnaeem 39:4f3f7463e55f 590 {
ranaumarnaeem 39:4f3f7463e55f 591 /* RFC7252
ranaumarnaeem 39:4f3f7463e55f 592 * as the underlying datagram transport may not be sequence-preserving,
ranaumarnaeem 39:4f3f7463e55f 593 * the Confirmable message carrying the response may actually arrive
ranaumarnaeem 39:4f3f7463e55f 594 * before or after the Acknowledgement message for the request; for
ranaumarnaeem 39:4f3f7463e55f 595 * the purposes of terminating the retransmission sequence, this also
ranaumarnaeem 39:4f3f7463e55f 596 * serves as an acknowledgement.
ranaumarnaeem 39:4f3f7463e55f 597 */
ranaumarnaeem 39:4f3f7463e55f 598 return coap_client_handle_sep_response(client, resp);
ranaumarnaeem 39:4f3f7463e55f 599 }
ranaumarnaeem 39:4f3f7463e55f 600 /* message deduplication */
ranaumarnaeem 39:4f3f7463e55f 601 /* we might have received a duplicate message that was already received from the same server */
ranaumarnaeem 39:4f3f7463e55f 602 /* reject the message and continue listening */
ranaumarnaeem 39:4f3f7463e55f 603 ret = coap_client_reject(client, resp);
ranaumarnaeem 39:4f3f7463e55f 604 if (ret < 0 )
ranaumarnaeem 39:4f3f7463e55f 605 {
ranaumarnaeem 39:4f3f7463e55f 606 return ret;
ranaumarnaeem 39:4f3f7463e55f 607 }
ranaumarnaeem 39:4f3f7463e55f 608 }
ranaumarnaeem 39:4f3f7463e55f 609 return 0;
ranaumarnaeem 39:4f3f7463e55f 610 }
ranaumarnaeem 39:4f3f7463e55f 611
ranaumarnaeem 39:4f3f7463e55f 612 /**
ranaumarnaeem 39:4f3f7463e55f 613 * @brief Handle the response to a non-confirmable request
ranaumarnaeem 39:4f3f7463e55f 614 *
ranaumarnaeem 39:4f3f7463e55f 615 * A non-confirmable request has been sent to the server.
ranaumarnaeem 39:4f3f7463e55f 616 * Receive the response.
ranaumarnaeem 39:4f3f7463e55f 617 *
ranaumarnaeem 39:4f3f7463e55f 618 * @param[in,out] client Pointer to a client structure
ranaumarnaeem 39:4f3f7463e55f 619 * @param[in] req Pointer to the request message
ranaumarnaeem 39:4f3f7463e55f 620 * @param[out] resp Pointer to the response message
ranaumarnaeem 39:4f3f7463e55f 621 *
ranaumarnaeem 39:4f3f7463e55f 622 * @returns Operation status
ranaumarnaeem 39:4f3f7463e55f 623 * @retval 0 Success
ranaumarnaeem 39:4f3f7463e55f 624 * @retval <0 Error
ranaumarnaeem 39:4f3f7463e55f 625 **/
ranaumarnaeem 39:4f3f7463e55f 626 static int coap_client_exchange_non(coap_client_t *client, coap_msg_t *req, coap_msg_t *resp)
ranaumarnaeem 39:4f3f7463e55f 627 {
ranaumarnaeem 39:4f3f7463e55f 628 int num = 0;
ranaumarnaeem 39:4f3f7463e55f 629 int ret = 0;
ranaumarnaeem 39:4f3f7463e55f 630 int starttimeout,endtimeout;
ranaumarnaeem 39:4f3f7463e55f 631
ranaumarnaeem 39:4f3f7463e55f 632 printf("Expecting response from host %s and port %s\n", client->server_host, client->server_port);
ranaumarnaeem 39:4f3f7463e55f 633 while (1)
ranaumarnaeem 39:4f3f7463e55f 634 {
ranaumarnaeem 39:4f3f7463e55f 635 starttimeout = readseconds();
ranaumarnaeem 39:4f3f7463e55f 636 while(1)
ranaumarnaeem 39:4f3f7463e55f 637 {
ranaumarnaeem 39:4f3f7463e55f 638 num = coap_client_recv(client, resp);
ranaumarnaeem 39:4f3f7463e55f 639 if (num < 0)
ranaumarnaeem 39:4f3f7463e55f 640 {
ranaumarnaeem 39:4f3f7463e55f 641 return num;
ranaumarnaeem 39:4f3f7463e55f 642 }
ranaumarnaeem 39:4f3f7463e55f 643 else if(num > 0)
ranaumarnaeem 39:4f3f7463e55f 644 {
ranaumarnaeem 39:4f3f7463e55f 645 break;
ranaumarnaeem 39:4f3f7463e55f 646 }
ranaumarnaeem 39:4f3f7463e55f 647 endtimeout = readseconds();
ranaumarnaeem 39:4f3f7463e55f 648 if((endtimeout - starttimeout) > COAP_CLIENT_RESP_TIMEOUT_SEC)
ranaumarnaeem 39:4f3f7463e55f 649 {
ranaumarnaeem 39:4f3f7463e55f 650 printf("Timeout no data received\n");
ranaumarnaeem 39:4f3f7463e55f 651 return -1;
ranaumarnaeem 39:4f3f7463e55f 652 }
ranaumarnaeem 39:4f3f7463e55f 653 }
ranaumarnaeem 39:4f3f7463e55f 654
ranaumarnaeem 39:4f3f7463e55f 655 if (coap_msg_get_msg_id(resp) == coap_msg_get_msg_id(req))
ranaumarnaeem 39:4f3f7463e55f 656 {
ranaumarnaeem 39:4f3f7463e55f 657 if (coap_msg_get_type(resp) == COAP_MSG_RST)
ranaumarnaeem 39:4f3f7463e55f 658 {
ranaumarnaeem 39:4f3f7463e55f 659 return -ECONNRESET;
ranaumarnaeem 39:4f3f7463e55f 660 }
ranaumarnaeem 39:4f3f7463e55f 661 coap_client_reject(client, resp);
ranaumarnaeem 39:4f3f7463e55f 662 return -EBADMSG;
ranaumarnaeem 39:4f3f7463e55f 663 }
ranaumarnaeem 39:4f3f7463e55f 664 if (coap_client_match_token(req, resp))
ranaumarnaeem 39:4f3f7463e55f 665 {
ranaumarnaeem 39:4f3f7463e55f 666 return coap_client_handle_sep_response(client, resp);
ranaumarnaeem 39:4f3f7463e55f 667 }
ranaumarnaeem 39:4f3f7463e55f 668 /* message deduplication */
ranaumarnaeem 39:4f3f7463e55f 669 /* we might have received a duplicate message that was already received from the same server */
ranaumarnaeem 39:4f3f7463e55f 670 /* reject the message and continue listening */
ranaumarnaeem 39:4f3f7463e55f 671 ret = coap_client_reject(client, resp);
ranaumarnaeem 39:4f3f7463e55f 672 if (ret < 0 )
ranaumarnaeem 39:4f3f7463e55f 673 {
ranaumarnaeem 39:4f3f7463e55f 674 return ret;
ranaumarnaeem 39:4f3f7463e55f 675 }
ranaumarnaeem 39:4f3f7463e55f 676 }
ranaumarnaeem 39:4f3f7463e55f 677 return 0;
ranaumarnaeem 39:4f3f7463e55f 678 }
ranaumarnaeem 39:4f3f7463e55f 679
ranaumarnaeem 39:4f3f7463e55f 680 int coap_client_exchange(coap_client_t *client, coap_msg_t *req, coap_msg_t *resp)
ranaumarnaeem 39:4f3f7463e55f 681 {
ranaumarnaeem 39:4f3f7463e55f 682 unsigned char msg_id_buf[2] = {0};
ranaumarnaeem 39:4f3f7463e55f 683 unsigned msg_id = 0;
ranaumarnaeem 39:4f3f7463e55f 684 int num = 0;
ranaumarnaeem 39:4f3f7463e55f 685 char token[4] = {0};
ranaumarnaeem 39:4f3f7463e55f 686 int ret = 0;
ranaumarnaeem 39:4f3f7463e55f 687
ranaumarnaeem 39:4f3f7463e55f 688 /* check for a valid request */
ranaumarnaeem 39:4f3f7463e55f 689 if ((coap_msg_get_type(req) == COAP_MSG_ACK)
ranaumarnaeem 39:4f3f7463e55f 690 || (coap_msg_get_type(req) == COAP_MSG_RST)
ranaumarnaeem 39:4f3f7463e55f 691 || (coap_msg_get_code_class(req) != COAP_MSG_REQ))
ranaumarnaeem 39:4f3f7463e55f 692 {
ranaumarnaeem 39:4f3f7463e55f 693 return -EINVAL;
ranaumarnaeem 39:4f3f7463e55f 694 }
ranaumarnaeem 39:4f3f7463e55f 695
ranaumarnaeem 39:4f3f7463e55f 696 /* generate the message ID */
ranaumarnaeem 39:4f3f7463e55f 697 coap_msg_gen_rand_str((char *)msg_id_buf, sizeof(msg_id_buf));
ranaumarnaeem 39:4f3f7463e55f 698 msg_id = (((unsigned)msg_id_buf[1]) << 8) | (unsigned)msg_id_buf[0];
ranaumarnaeem 39:4f3f7463e55f 699 ret = coap_msg_set_msg_id(req, msg_id);
ranaumarnaeem 39:4f3f7463e55f 700 if (ret < 0)
ranaumarnaeem 39:4f3f7463e55f 701 {
ranaumarnaeem 39:4f3f7463e55f 702 return ret;
ranaumarnaeem 39:4f3f7463e55f 703 }
ranaumarnaeem 39:4f3f7463e55f 704
ranaumarnaeem 39:4f3f7463e55f 705 /* generate the token */
ranaumarnaeem 39:4f3f7463e55f 706 coap_msg_gen_rand_str(token, sizeof(token));
ranaumarnaeem 39:4f3f7463e55f 707 ret = coap_msg_set_token(req, token, sizeof(token));
ranaumarnaeem 39:4f3f7463e55f 708 if (ret < 0)
ranaumarnaeem 39:4f3f7463e55f 709 {
ranaumarnaeem 39:4f3f7463e55f 710 return ret;
ranaumarnaeem 39:4f3f7463e55f 711 }
ranaumarnaeem 39:4f3f7463e55f 712
ranaumarnaeem 39:4f3f7463e55f 713 num = coap_client_send(client, req);
ranaumarnaeem 39:4f3f7463e55f 714 if (num < 0)
ranaumarnaeem 39:4f3f7463e55f 715 {
ranaumarnaeem 39:4f3f7463e55f 716 return num;
ranaumarnaeem 39:4f3f7463e55f 717 }
ranaumarnaeem 39:4f3f7463e55f 718
ranaumarnaeem 39:4f3f7463e55f 719 if (coap_msg_get_type(req) == COAP_MSG_CON)
ranaumarnaeem 39:4f3f7463e55f 720 {
ranaumarnaeem 39:4f3f7463e55f 721 return coap_client_exchange_con(client, req, resp);
ranaumarnaeem 39:4f3f7463e55f 722 }
ranaumarnaeem 39:4f3f7463e55f 723 else if (coap_msg_get_type(req) == COAP_MSG_NON)
ranaumarnaeem 39:4f3f7463e55f 724 {
ranaumarnaeem 39:4f3f7463e55f 725 return coap_client_exchange_non(client, req, resp);
ranaumarnaeem 39:4f3f7463e55f 726 }
ranaumarnaeem 39:4f3f7463e55f 727 return -EINVAL;
ranaumarnaeem 39:4f3f7463e55f 728 }
ranaumarnaeem 39:4f3f7463e55f 729 //----------------------------------------------------------------------------------------------------------------------
ranaumarnaeem 39:4f3f7463e55f 730 //----------------------------------------------------------------------------------------------------------------------
ranaumarnaeem 39:4f3f7463e55f 731 /**
ranaumarnaeem 39:4f3f7463e55f 732 * @brief Test an exchange with the server
ranaumarnaeem 39:4f3f7463e55f 733 *
ranaumarnaeem 39:4f3f7463e55f 734 * @param[in] data Pointer to a client test data structure
ranaumarnaeem 39:4f3f7463e55f 735 *
ranaumarnaeem 39:4f3f7463e55f 736 * @returns Test result
ranaumarnaeem 39:4f3f7463e55f 737 */
ranaumarnaeem 39:4f3f7463e55f 738 test_result_t test_exchange_func(char* buf,int buf_len,char* returncode)
ranaumarnaeem 39:4f3f7463e55f 739 {
ranaumarnaeem 39:4f3f7463e55f 740 printf("----------------------------------------\n");
ranaumarnaeem 39:4f3f7463e55f 741 test_result_t result = PASS;
ranaumarnaeem 39:4f3f7463e55f 742 coap_client_t client = {0};
ranaumarnaeem 39:4f3f7463e55f 743 coap_msg_t resp = {0};
ranaumarnaeem 39:4f3f7463e55f 744 coap_msg_t req = {0};
ranaumarnaeem 39:4f3f7463e55f 745 int ret = 0;
ranaumarnaeem 39:4f3f7463e55f 746
ranaumarnaeem 39:4f3f7463e55f 747 test_coap_client_msg_op_t req_ops;
ranaumarnaeem 39:4f3f7463e55f 748 req_ops.num = COAP_MSG_URI_PATH;
ranaumarnaeem 39:4f3f7463e55f 749 req_ops.len = 8;
ranaumarnaeem 39:4f3f7463e55f 750 req_ops.val = (char*)"resource";
ranaumarnaeem 39:4f3f7463e55f 751
ranaumarnaeem 39:4f3f7463e55f 752 test_coap_client_msg_op_t resp_ops;
ranaumarnaeem 39:4f3f7463e55f 753 resp_ops.num = 0;
ranaumarnaeem 39:4f3f7463e55f 754 resp_ops.len = 0;
ranaumarnaeem 39:4f3f7463e55f 755 resp_ops.val = 0;
ranaumarnaeem 39:4f3f7463e55f 756
ranaumarnaeem 39:4f3f7463e55f 757 test_coap_client_msg_t test1_req;
ranaumarnaeem 39:4f3f7463e55f 758 test1_req.type = COAP_MSG_CON;
ranaumarnaeem 39:4f3f7463e55f 759 test1_req.code_class = COAP_MSG_REQ;
ranaumarnaeem 39:4f3f7463e55f 760 test1_req.code_detail = COAP_MSG_GET;
ranaumarnaeem 39:4f3f7463e55f 761 test1_req.ops = req_ops;
ranaumarnaeem 39:4f3f7463e55f 762 test1_req.num_ops = 1;
ranaumarnaeem 39:4f3f7463e55f 763 test1_req.payload = buf;
ranaumarnaeem 39:4f3f7463e55f 764 test1_req.payload_len = buf_len;
ranaumarnaeem 39:4f3f7463e55f 765
ranaumarnaeem 39:4f3f7463e55f 766 test_coap_client_msg_t test1_resp;
ranaumarnaeem 39:4f3f7463e55f 767 test1_resp.type = COAP_MSG_ACK;
ranaumarnaeem 39:4f3f7463e55f 768 test1_resp.code_class = COAP_MSG_SUCCESS;
ranaumarnaeem 39:4f3f7463e55f 769 test1_resp.code_detail = COAP_MSG_CONTENT;
ranaumarnaeem 39:4f3f7463e55f 770 test1_resp.ops = resp_ops;
ranaumarnaeem 39:4f3f7463e55f 771 test1_resp.num_ops = 0;
ranaumarnaeem 39:4f3f7463e55f 772 test1_resp.payload = (char*)"Hello Client!";
ranaumarnaeem 39:4f3f7463e55f 773 test1_resp.payload_len = 13;
ranaumarnaeem 39:4f3f7463e55f 774
ranaumarnaeem 39:4f3f7463e55f 775 test_coap_client_data_t test1_data;
ranaumarnaeem 39:4f3f7463e55f 776 test1_data.desc = "Send a confirmable request to server and expect a piggy-backed response";
ranaumarnaeem 39:4f3f7463e55f 777 test1_data.host = HOST;
ranaumarnaeem 39:4f3f7463e55f 778 test1_data.port = PORT;
ranaumarnaeem 39:4f3f7463e55f 779 test1_data.common_name = (char*)"dummy/server";
ranaumarnaeem 39:4f3f7463e55f 780 test1_data.test_req = test1_req;
ranaumarnaeem 39:4f3f7463e55f 781 test1_data.test_resp = test1_resp;
ranaumarnaeem 39:4f3f7463e55f 782 test1_data.num_msg = 1;
ranaumarnaeem 39:4f3f7463e55f 783
ranaumarnaeem 39:4f3f7463e55f 784 //printf("%s\n", test1_data.desc);
ranaumarnaeem 39:4f3f7463e55f 785
ranaumarnaeem 39:4f3f7463e55f 786 if (ret < 0)
ranaumarnaeem 39:4f3f7463e55f 787 {
ranaumarnaeem 39:4f3f7463e55f 788 printf("Error : %s\n",strerror(-ret));
ranaumarnaeem 39:4f3f7463e55f 789 return FAIL;
ranaumarnaeem 39:4f3f7463e55f 790 }
ranaumarnaeem 39:4f3f7463e55f 791
ranaumarnaeem 39:4f3f7463e55f 792 coap_msg_create(&req);
ranaumarnaeem 39:4f3f7463e55f 793 coap_msg_create(&resp);
ranaumarnaeem 39:4f3f7463e55f 794
ranaumarnaeem 39:4f3f7463e55f 795 ret = exchange(&client, &test1_data.test_req, &req, &resp,returncode);
ranaumarnaeem 39:4f3f7463e55f 796 //printf("exchange function\n");
ranaumarnaeem 39:4f3f7463e55f 797 if (ret != PASS)
ranaumarnaeem 39:4f3f7463e55f 798 {
ranaumarnaeem 39:4f3f7463e55f 799 printf("exchange function fail\n");
ranaumarnaeem 39:4f3f7463e55f 800 coap_msg_destroy(&resp);
ranaumarnaeem 39:4f3f7463e55f 801 coap_msg_destroy(&req);
ranaumarnaeem 39:4f3f7463e55f 802 coap_client_destroy(&client);
ranaumarnaeem 39:4f3f7463e55f 803 return FAIL;
ranaumarnaeem 39:4f3f7463e55f 804 }
ranaumarnaeem 39:4f3f7463e55f 805
ranaumarnaeem 39:4f3f7463e55f 806 ret = compare_ver_token(&req, &resp);
ranaumarnaeem 39:4f3f7463e55f 807 if (ret != PASS)
ranaumarnaeem 39:4f3f7463e55f 808 {
ranaumarnaeem 39:4f3f7463e55f 809 coap_msg_destroy(&resp);
ranaumarnaeem 39:4f3f7463e55f 810 coap_msg_destroy(&req);
ranaumarnaeem 39:4f3f7463e55f 811 coap_client_destroy(&client);
ranaumarnaeem 39:4f3f7463e55f 812 return FAIL;
ranaumarnaeem 39:4f3f7463e55f 813 }
ranaumarnaeem 39:4f3f7463e55f 814
ranaumarnaeem 39:4f3f7463e55f 815 ret = check_resp(&test1_data.test_resp, &resp);
ranaumarnaeem 39:4f3f7463e55f 816 if (ret != PASS)
ranaumarnaeem 39:4f3f7463e55f 817 {
ranaumarnaeem 39:4f3f7463e55f 818 coap_msg_destroy(&resp);
ranaumarnaeem 39:4f3f7463e55f 819 coap_msg_destroy(&req);
ranaumarnaeem 39:4f3f7463e55f 820 coap_client_destroy(&client);
ranaumarnaeem 39:4f3f7463e55f 821 return FAIL;
ranaumarnaeem 39:4f3f7463e55f 822 }
ranaumarnaeem 39:4f3f7463e55f 823
ranaumarnaeem 39:4f3f7463e55f 824 coap_msg_destroy(&resp);
ranaumarnaeem 39:4f3f7463e55f 825 coap_msg_destroy(&req);
ranaumarnaeem 39:4f3f7463e55f 826 coap_client_destroy(&client);
ranaumarnaeem 39:4f3f7463e55f 827
ranaumarnaeem 39:4f3f7463e55f 828 return result;
ranaumarnaeem 39:4f3f7463e55f 829 }
ranaumarnaeem 39:4f3f7463e55f 830 //----------------------------------------------------------------------------------------------------------------------
ranaumarnaeem 39:4f3f7463e55f 831 //----------------------------------------------------------------------------------------------------------------------
ranaumarnaeem 39:4f3f7463e55f 832 /**
ranaumarnaeem 39:4f3f7463e55f 833 * @brief Print a CoAP message
ranaumarnaeem 39:4f3f7463e55f 834 *
ranaumarnaeem 39:4f3f7463e55f 835 * @param[in] str String to be printed before the message
ranaumarnaeem 39:4f3f7463e55f 836 * @param[in] msg Pointer to a message structure
ranaumarnaeem 39:4f3f7463e55f 837 */
ranaumarnaeem 39:4f3f7463e55f 838 void print_coap_msg(const char *str, coap_msg_t *msg,char* returncode)
ranaumarnaeem 39:4f3f7463e55f 839 {
ranaumarnaeem 39:4f3f7463e55f 840 //coap_msg_op_t *op = NULL;
ranaumarnaeem 39:4f3f7463e55f 841 //unsigned num = 0;
ranaumarnaeem 39:4f3f7463e55f 842 //unsigned len = 0;
ranaumarnaeem 39:4f3f7463e55f 843 unsigned i = 0;
ranaumarnaeem 39:4f3f7463e55f 844 //unsigned j = 0;
ranaumarnaeem 39:4f3f7463e55f 845 char *payload = NULL;
ranaumarnaeem 39:4f3f7463e55f 846 char *token = NULL;
ranaumarnaeem 39:4f3f7463e55f 847 //char *val = NULL;
ranaumarnaeem 39:4f3f7463e55f 848
ranaumarnaeem 39:4f3f7463e55f 849 printf("%s\n", str);
ranaumarnaeem 39:4f3f7463e55f 850 printf("ver: 0x%02x\n", coap_msg_get_ver(msg));
ranaumarnaeem 39:4f3f7463e55f 851 printf("type: 0x%02x\n", coap_msg_get_type(msg));
ranaumarnaeem 39:4f3f7463e55f 852 printf("token_len: %d\n", coap_msg_get_token_len(msg));
ranaumarnaeem 39:4f3f7463e55f 853 printf("code_class: %d\n", coap_msg_get_code_class(msg));
ranaumarnaeem 39:4f3f7463e55f 854 printf("code_detail: %d\n", coap_msg_get_code_detail(msg));
ranaumarnaeem 39:4f3f7463e55f 855 printf("msg_id: 0x%04x\n", coap_msg_get_msg_id(msg));
ranaumarnaeem 39:4f3f7463e55f 856 printf("token: ");
ranaumarnaeem 39:4f3f7463e55f 857 token = coap_msg_get_token(msg);
ranaumarnaeem 39:4f3f7463e55f 858 for (i = 0; i < coap_msg_get_token_len(msg); i++)
ranaumarnaeem 39:4f3f7463e55f 859 {
ranaumarnaeem 39:4f3f7463e55f 860 printf(" 0x%02x", (unsigned char)token[i]);
ranaumarnaeem 39:4f3f7463e55f 861 }
ranaumarnaeem 39:4f3f7463e55f 862 printf("\n");
ranaumarnaeem 39:4f3f7463e55f 863 /*op = coap_msg_get_first_op(msg);
ranaumarnaeem 39:4f3f7463e55f 864 while (op != NULL)
ranaumarnaeem 39:4f3f7463e55f 865 {
ranaumarnaeem 39:4f3f7463e55f 866 num = coap_msg_op_get_num(op);
ranaumarnaeem 39:4f3f7463e55f 867 len = coap_msg_op_get_len(op);
ranaumarnaeem 39:4f3f7463e55f 868 val = coap_msg_op_get_val(op);
ranaumarnaeem 39:4f3f7463e55f 869 printf("op[%u].num: %u\n", j, num);
ranaumarnaeem 39:4f3f7463e55f 870 printf("op[%u].len: %u\n", j, len);
ranaumarnaeem 39:4f3f7463e55f 871 printf("op[%u].val: ", j);
ranaumarnaeem 39:4f3f7463e55f 872 for (i = 0; i < len; i++)
ranaumarnaeem 39:4f3f7463e55f 873 {
ranaumarnaeem 39:4f3f7463e55f 874 printf(" 0x%02x", (unsigned char)val[i]);
ranaumarnaeem 39:4f3f7463e55f 875 }
ranaumarnaeem 39:4f3f7463e55f 876 printf("\n");
ranaumarnaeem 39:4f3f7463e55f 877 op = coap_msg_op_get_next(op);
ranaumarnaeem 39:4f3f7463e55f 878 j++;
ranaumarnaeem 39:4f3f7463e55f 879 }*/
ranaumarnaeem 39:4f3f7463e55f 880 printf("payload: ");
ranaumarnaeem 39:4f3f7463e55f 881 payload = coap_msg_get_payload(msg);
ranaumarnaeem 39:4f3f7463e55f 882
ranaumarnaeem 39:4f3f7463e55f 883 if(strcmp(str,"Received:") == 0)
ranaumarnaeem 39:4f3f7463e55f 884 {
ranaumarnaeem 39:4f3f7463e55f 885 for (i = 0; i < coap_msg_get_payload_len(msg); i++)
ranaumarnaeem 39:4f3f7463e55f 886 {
ranaumarnaeem 39:4f3f7463e55f 887 printf("%c", payload[i]);
ranaumarnaeem 39:4f3f7463e55f 888 returncode[i] = payload[i];
ranaumarnaeem 39:4f3f7463e55f 889 }
ranaumarnaeem 39:4f3f7463e55f 890 returncode[i] = '\0';
ranaumarnaeem 39:4f3f7463e55f 891 }
ranaumarnaeem 39:4f3f7463e55f 892 printf("\n");
ranaumarnaeem 39:4f3f7463e55f 893
ranaumarnaeem 39:4f3f7463e55f 894 printf("payload_len: %zu\n", coap_msg_get_payload_len(msg));
ranaumarnaeem 39:4f3f7463e55f 895 }
ranaumarnaeem 39:4f3f7463e55f 896 //----------------------------------------------------------------------------------------------------------------------
ranaumarnaeem 39:4f3f7463e55f 897 //----------------------------------------------------------------------------------------------------------------------
ranaumarnaeem 39:4f3f7463e55f 898 /**
ranaumarnaeem 39:4f3f7463e55f 899 * @brief Populate a request message with details from a test request message structure
ranaumarnaeem 39:4f3f7463e55f 900 *
ranaumarnaeem 39:4f3f7463e55f 901 * @param[in] test_req Pointer to a test request message structure
ranaumarnaeem 39:4f3f7463e55f 902 * @param[out] req Pointer to a request message structure
ranaumarnaeem 39:4f3f7463e55f 903 *
ranaumarnaeem 39:4f3f7463e55f 904 * @returns Test result
ranaumarnaeem 39:4f3f7463e55f 905 */
ranaumarnaeem 39:4f3f7463e55f 906 test_result_t populate_req(test_coap_client_msg_t *test_req, coap_msg_t *req)
ranaumarnaeem 39:4f3f7463e55f 907 {
ranaumarnaeem 39:4f3f7463e55f 908 int ret = 0;
ranaumarnaeem 39:4f3f7463e55f 909
ranaumarnaeem 39:4f3f7463e55f 910 ret = coap_msg_set_type(req, test_req->type);
ranaumarnaeem 39:4f3f7463e55f 911 if (ret < 0)
ranaumarnaeem 39:4f3f7463e55f 912 {
ranaumarnaeem 39:4f3f7463e55f 913 printf("Error : %s\n",strerror(-ret));
ranaumarnaeem 39:4f3f7463e55f 914 return FAIL;
ranaumarnaeem 39:4f3f7463e55f 915 }
ranaumarnaeem 39:4f3f7463e55f 916 ret = coap_msg_set_code(req, test_req->code_class, test_req->code_detail);
ranaumarnaeem 39:4f3f7463e55f 917 if (ret < 0)
ranaumarnaeem 39:4f3f7463e55f 918 {
ranaumarnaeem 39:4f3f7463e55f 919 printf("Error : %s\n",strerror(-ret));
ranaumarnaeem 39:4f3f7463e55f 920 return FAIL;
ranaumarnaeem 39:4f3f7463e55f 921 }
ranaumarnaeem 39:4f3f7463e55f 922 ret = coap_msg_add_op(req, test_req->ops.num, test_req->ops.len, test_req->ops.val);
ranaumarnaeem 39:4f3f7463e55f 923 if (ret < 0)
ranaumarnaeem 39:4f3f7463e55f 924 {
ranaumarnaeem 39:4f3f7463e55f 925 printf("Error : %s\n",strerror(-ret));
ranaumarnaeem 39:4f3f7463e55f 926 return FAIL;
ranaumarnaeem 39:4f3f7463e55f 927 }
ranaumarnaeem 39:4f3f7463e55f 928 if (test_req->payload)
ranaumarnaeem 39:4f3f7463e55f 929 {
ranaumarnaeem 39:4f3f7463e55f 930 ret = coap_msg_set_payload(req, test_req->payload, test_req->payload_len);
ranaumarnaeem 39:4f3f7463e55f 931 if (ret < 0)
ranaumarnaeem 39:4f3f7463e55f 932 {
ranaumarnaeem 39:4f3f7463e55f 933 printf("Error : %s\n",strerror(-ret));
ranaumarnaeem 39:4f3f7463e55f 934 return FAIL;
ranaumarnaeem 39:4f3f7463e55f 935 }
ranaumarnaeem 39:4f3f7463e55f 936 }
ranaumarnaeem 39:4f3f7463e55f 937 return PASS;
ranaumarnaeem 39:4f3f7463e55f 938 }
ranaumarnaeem 39:4f3f7463e55f 939 //----------------------------------------------------------------------------------------------------------------------
ranaumarnaeem 39:4f3f7463e55f 940 //----------------------------------------------------------------------------------------------------------------------
ranaumarnaeem 39:4f3f7463e55f 941 /**
ranaumarnaeem 39:4f3f7463e55f 942 * @brief Send a request to the server and receive the response
ranaumarnaeem 39:4f3f7463e55f 943 *
ranaumarnaeem 39:4f3f7463e55f 944 * @param[in,out] client Pointer to a client structure
ranaumarnaeem 39:4f3f7463e55f 945 * @param[in] test_req Pointer to a test request message structure
ranaumarnaeem 39:4f3f7463e55f 946 * @param[out] req Pointer to a request message structure
ranaumarnaeem 39:4f3f7463e55f 947 * @param[out] resp Pointer to a response message structure
ranaumarnaeem 39:4f3f7463e55f 948 *
ranaumarnaeem 39:4f3f7463e55f 949 * @returns Test result
ranaumarnaeem 39:4f3f7463e55f 950 */
ranaumarnaeem 39:4f3f7463e55f 951 test_result_t exchange(coap_client_t *client, test_coap_client_msg_t *test_req, coap_msg_t *req, coap_msg_t *resp,char* returncode)
ranaumarnaeem 39:4f3f7463e55f 952 {
ranaumarnaeem 39:4f3f7463e55f 953 test_result_t result = PASS;
ranaumarnaeem 39:4f3f7463e55f 954 int ret = 0;
ranaumarnaeem 39:4f3f7463e55f 955
ranaumarnaeem 39:4f3f7463e55f 956 result = populate_req(test_req, req);
ranaumarnaeem 39:4f3f7463e55f 957 if (result != PASS)
ranaumarnaeem 39:4f3f7463e55f 958 {
ranaumarnaeem 39:4f3f7463e55f 959 printf("populate_req FAIL\n");
ranaumarnaeem 39:4f3f7463e55f 960 return result;
ranaumarnaeem 39:4f3f7463e55f 961 }
ranaumarnaeem 39:4f3f7463e55f 962 ret = coap_client_exchange(client, req, resp);
ranaumarnaeem 39:4f3f7463e55f 963 if (ret < 0)
ranaumarnaeem 39:4f3f7463e55f 964 {
ranaumarnaeem 39:4f3f7463e55f 965 printf("coap_client_exchange FAIL\n");
ranaumarnaeem 39:4f3f7463e55f 966 printf("Error : %s\n",strerror(-ret));
ranaumarnaeem 39:4f3f7463e55f 967 return FAIL;
ranaumarnaeem 39:4f3f7463e55f 968 }
ranaumarnaeem 39:4f3f7463e55f 969 //printf("coap_client_exchange PASS\n");
ranaumarnaeem 39:4f3f7463e55f 970 print_coap_msg("Sent:", req,returncode);
ranaumarnaeem 39:4f3f7463e55f 971 print_coap_msg("Received:", resp,returncode);
ranaumarnaeem 39:4f3f7463e55f 972
ranaumarnaeem 39:4f3f7463e55f 973 return PASS;
ranaumarnaeem 39:4f3f7463e55f 974 }
ranaumarnaeem 39:4f3f7463e55f 975 //----------------------------------------------------------------------------------------------------------------------
ranaumarnaeem 39:4f3f7463e55f 976 //----------------------------------------------------------------------------------------------------------------------
ranaumarnaeem 39:4f3f7463e55f 977 /**
ranaumarnaeem 39:4f3f7463e55f 978 * @brief Compare the version and token fields in a request message and a response message
ranaumarnaeem 39:4f3f7463e55f 979 *
ranaumarnaeem 39:4f3f7463e55f 980 * @param[out] req Pointer to a request message structure
ranaumarnaeem 39:4f3f7463e55f 981 * @param[out] resp Pointer to a response message structure
ranaumarnaeem 39:4f3f7463e55f 982 *
ranaumarnaeem 39:4f3f7463e55f 983 * @returns Test result
ranaumarnaeem 39:4f3f7463e55f 984 */
ranaumarnaeem 39:4f3f7463e55f 985 test_result_t compare_ver_token(coap_msg_t *req, coap_msg_t *resp)
ranaumarnaeem 39:4f3f7463e55f 986 {
ranaumarnaeem 39:4f3f7463e55f 987 if (coap_msg_get_ver(req) != coap_msg_get_ver(resp))
ranaumarnaeem 39:4f3f7463e55f 988 {
ranaumarnaeem 39:4f3f7463e55f 989 return FAIL;
ranaumarnaeem 39:4f3f7463e55f 990 }
ranaumarnaeem 39:4f3f7463e55f 991 if (coap_msg_get_token_len(req) != coap_msg_get_token_len(resp))
ranaumarnaeem 39:4f3f7463e55f 992 {
ranaumarnaeem 39:4f3f7463e55f 993 return FAIL;
ranaumarnaeem 39:4f3f7463e55f 994 }
ranaumarnaeem 39:4f3f7463e55f 995 else if (memcmp(coap_msg_get_token(req), coap_msg_get_token(resp), coap_msg_get_token_len(req)) != 0)
ranaumarnaeem 39:4f3f7463e55f 996 {
ranaumarnaeem 39:4f3f7463e55f 997 return FAIL;
ranaumarnaeem 39:4f3f7463e55f 998 }
ranaumarnaeem 39:4f3f7463e55f 999 return PASS;
ranaumarnaeem 39:4f3f7463e55f 1000 }
ranaumarnaeem 39:4f3f7463e55f 1001 //----------------------------------------------------------------------------------------------------------------------
ranaumarnaeem 39:4f3f7463e55f 1002 //----------------------------------------------------------------------------------------------------------------------
ranaumarnaeem 39:4f3f7463e55f 1003 /**
ranaumarnaeem 39:4f3f7463e55f 1004 * @brief Check the fields in a response message against the expected values
ranaumarnaeem 39:4f3f7463e55f 1005 *
ranaumarnaeem 39:4f3f7463e55f 1006 * @param[out] test_resp Pointer to a test response message structure
ranaumarnaeem 39:4f3f7463e55f 1007 * @param[out] resp Pointer to a response message structure
ranaumarnaeem 39:4f3f7463e55f 1008 *
ranaumarnaeem 39:4f3f7463e55f 1009 * @returns Test result
ranaumarnaeem 39:4f3f7463e55f 1010 */
ranaumarnaeem 39:4f3f7463e55f 1011 test_result_t check_resp(test_coap_client_msg_t *test_resp, coap_msg_t *resp)
ranaumarnaeem 39:4f3f7463e55f 1012 {
ranaumarnaeem 39:4f3f7463e55f 1013 if (test_resp->type != coap_msg_get_type(resp))
ranaumarnaeem 39:4f3f7463e55f 1014 {
ranaumarnaeem 39:4f3f7463e55f 1015 return FAIL;
ranaumarnaeem 39:4f3f7463e55f 1016 }
ranaumarnaeem 39:4f3f7463e55f 1017 if (test_resp->code_class != coap_msg_get_code_class(resp))
ranaumarnaeem 39:4f3f7463e55f 1018 {
ranaumarnaeem 39:4f3f7463e55f 1019 return FAIL;
ranaumarnaeem 39:4f3f7463e55f 1020 }
ranaumarnaeem 39:4f3f7463e55f 1021 if (test_resp->code_detail != coap_msg_get_code_detail(resp))
ranaumarnaeem 39:4f3f7463e55f 1022 {
ranaumarnaeem 39:4f3f7463e55f 1023 return FAIL;
ranaumarnaeem 39:4f3f7463e55f 1024 }
ranaumarnaeem 39:4f3f7463e55f 1025 return PASS;
ranaumarnaeem 39:4f3f7463e55f 1026 }