mbed 5.4 with sleep mode

Dependencies:  

Committer:
ranaumarnaeem
Date:
Wed May 24 07:51:33 2017 +0000
Revision:
38:f1bc6e867fcf
lss

Who changed what in which revision?

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