pick up wakaama files from https://github.com/eclipse/wakaama

Committer:
terencez
Date:
Wed Apr 19 11:27:34 2017 +0000
Revision:
0:c2dff8cbb91a
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
terencez 0:c2dff8cbb91a 1 /*******************************************************************************
terencez 0:c2dff8cbb91a 2 *
terencez 0:c2dff8cbb91a 3 * Copyright (c) 2013, 2014 Intel Corporation and others.
terencez 0:c2dff8cbb91a 4 * All rights reserved. This program and the accompanying materials
terencez 0:c2dff8cbb91a 5 * are made available under the terms of the Eclipse Public License v1.0
terencez 0:c2dff8cbb91a 6 * and Eclipse Distribution License v1.0 which accompany this distribution.
terencez 0:c2dff8cbb91a 7 *
terencez 0:c2dff8cbb91a 8 * The Eclipse Public License is available at
terencez 0:c2dff8cbb91a 9 * http://www.eclipse.org/legal/epl-v10.html
terencez 0:c2dff8cbb91a 10 * The Eclipse Distribution License is available at
terencez 0:c2dff8cbb91a 11 * http://www.eclipse.org/org/documents/edl-v10.php.
terencez 0:c2dff8cbb91a 12 *
terencez 0:c2dff8cbb91a 13 * Contributors:
terencez 0:c2dff8cbb91a 14 * David Navarro, Intel Corporation - initial API and implementation
terencez 0:c2dff8cbb91a 15 * Simon Bernard - Please refer to git log
terencez 0:c2dff8cbb91a 16 * Toby Jaffey - Please refer to git log
terencez 0:c2dff8cbb91a 17 * Pascal Rieux - Please refer to git log
terencez 0:c2dff8cbb91a 18 * Bosch Software Innovations GmbH - Please refer to git log
terencez 0:c2dff8cbb91a 19 *
terencez 0:c2dff8cbb91a 20 *******************************************************************************/
terencez 0:c2dff8cbb91a 21
terencez 0:c2dff8cbb91a 22 /*
terencez 0:c2dff8cbb91a 23 Copyright (c) 2013, 2014 Intel Corporation
terencez 0:c2dff8cbb91a 24
terencez 0:c2dff8cbb91a 25 Redistribution and use in source and binary forms, with or without modification,
terencez 0:c2dff8cbb91a 26 are permitted provided that the following conditions are met:
terencez 0:c2dff8cbb91a 27
terencez 0:c2dff8cbb91a 28 * Redistributions of source code must retain the above copyright notice,
terencez 0:c2dff8cbb91a 29 this list of conditions and the following disclaimer.
terencez 0:c2dff8cbb91a 30 * Redistributions in binary form must reproduce the above copyright notice,
terencez 0:c2dff8cbb91a 31 this list of conditions and the following disclaimer in the documentation
terencez 0:c2dff8cbb91a 32 and/or other materials provided with the distribution.
terencez 0:c2dff8cbb91a 33 * Neither the name of Intel Corporation nor the names of its contributors
terencez 0:c2dff8cbb91a 34 may be used to endorse or promote products derived from this software
terencez 0:c2dff8cbb91a 35 without specific prior written permission.
terencez 0:c2dff8cbb91a 36
terencez 0:c2dff8cbb91a 37 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
terencez 0:c2dff8cbb91a 38 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
terencez 0:c2dff8cbb91a 39 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
terencez 0:c2dff8cbb91a 40 IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
terencez 0:c2dff8cbb91a 41 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
terencez 0:c2dff8cbb91a 42 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
terencez 0:c2dff8cbb91a 43 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
terencez 0:c2dff8cbb91a 44 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
terencez 0:c2dff8cbb91a 45 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
terencez 0:c2dff8cbb91a 46 THE POSSIBILITY OF SUCH DAMAGE.
terencez 0:c2dff8cbb91a 47
terencez 0:c2dff8cbb91a 48 David Navarro <david.navarro@intel.com>
terencez 0:c2dff8cbb91a 49
terencez 0:c2dff8cbb91a 50 */
terencez 0:c2dff8cbb91a 51
terencez 0:c2dff8cbb91a 52 /*
terencez 0:c2dff8cbb91a 53 Contains code snippets which are:
terencez 0:c2dff8cbb91a 54
terencez 0:c2dff8cbb91a 55 * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich
terencez 0:c2dff8cbb91a 56 * All rights reserved.
terencez 0:c2dff8cbb91a 57 *
terencez 0:c2dff8cbb91a 58 * Redistribution and use in source and binary forms, with or without
terencez 0:c2dff8cbb91a 59 * modification, are permitted provided that the following conditions
terencez 0:c2dff8cbb91a 60 * are met:
terencez 0:c2dff8cbb91a 61 * 1. Redistributions of source code must retain the above copyright
terencez 0:c2dff8cbb91a 62 * notice, this list of conditions and the following disclaimer.
terencez 0:c2dff8cbb91a 63 * 2. Redistributions in binary form must reproduce the above copyright
terencez 0:c2dff8cbb91a 64 * notice, this list of conditions and the following disclaimer in the
terencez 0:c2dff8cbb91a 65 * documentation and/or other materials provided with the distribution.
terencez 0:c2dff8cbb91a 66 * 3. Neither the name of the Institute nor the names of its contributors
terencez 0:c2dff8cbb91a 67 * may be used to endorse or promote products derived from this software
terencez 0:c2dff8cbb91a 68 * without specific prior written permission.
terencez 0:c2dff8cbb91a 69 *
terencez 0:c2dff8cbb91a 70 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
terencez 0:c2dff8cbb91a 71 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
terencez 0:c2dff8cbb91a 72 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
terencez 0:c2dff8cbb91a 73 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
terencez 0:c2dff8cbb91a 74 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
terencez 0:c2dff8cbb91a 75 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
terencez 0:c2dff8cbb91a 76 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
terencez 0:c2dff8cbb91a 77 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
terencez 0:c2dff8cbb91a 78 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
terencez 0:c2dff8cbb91a 79 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
terencez 0:c2dff8cbb91a 80 * SUCH DAMAGE.
terencez 0:c2dff8cbb91a 81
terencez 0:c2dff8cbb91a 82 */
terencez 0:c2dff8cbb91a 83
terencez 0:c2dff8cbb91a 84 /************************************************************************
terencez 0:c2dff8cbb91a 85 * Function for communications transactions.
terencez 0:c2dff8cbb91a 86 *
terencez 0:c2dff8cbb91a 87 * Basic specification: rfc7252
terencez 0:c2dff8cbb91a 88 *
terencez 0:c2dff8cbb91a 89 * Transaction implements processing of piggybacked and separate response communication
terencez 0:c2dff8cbb91a 90 * dialogs specified in section 2.2 of the above specification.
terencez 0:c2dff8cbb91a 91 * The caller registers a callback function, which is called, when either the result is
terencez 0:c2dff8cbb91a 92 * received or a timeout occurs.
terencez 0:c2dff8cbb91a 93 *
terencez 0:c2dff8cbb91a 94 * Supported dialogs:
terencez 0:c2dff8cbb91a 95 * Requests (GET - DELETE):
terencez 0:c2dff8cbb91a 96 * - CON with mid, without token => regular finished with corresponding ACK.MID
terencez 0:c2dff8cbb91a 97 * - CON with mid, with token => regular finished with corresponding ACK.MID and response containing
terencez 0:c2dff8cbb91a 98 * the token. Supports both versions, with piggybacked ACK and separate ACK/response.
terencez 0:c2dff8cbb91a 99 * Though the ACK.MID may be lost in the separate version, a matching response may
terencez 0:c2dff8cbb91a 100 * finish the transaction even without the ACK.MID.
terencez 0:c2dff8cbb91a 101 * - NON without token => no transaction, no result expected!
terencez 0:c2dff8cbb91a 102 * - NON with token => regular finished with response containing the token.
terencez 0:c2dff8cbb91a 103 * Responses (COAP_201_CREATED - ?):
terencez 0:c2dff8cbb91a 104 * - CON with mid => regular finished with corresponding ACK.MID
terencez 0:c2dff8cbb91a 105 */
terencez 0:c2dff8cbb91a 106
terencez 0:c2dff8cbb91a 107 #include "internals.h"
terencez 0:c2dff8cbb91a 108
terencez 0:c2dff8cbb91a 109
terencez 0:c2dff8cbb91a 110 /*
terencez 0:c2dff8cbb91a 111 * Modulo mask (+1 and +0.5 for rounding) for a random number to get the tick number for the random
terencez 0:c2dff8cbb91a 112 * retransmission time between COAP_RESPONSE_TIMEOUT and COAP_RESPONSE_TIMEOUT*COAP_RESPONSE_RANDOM_FACTOR.
terencez 0:c2dff8cbb91a 113 */
terencez 0:c2dff8cbb91a 114 #define COAP_RESPONSE_TIMEOUT_TICKS (CLOCK_SECOND * COAP_RESPONSE_TIMEOUT)
terencez 0:c2dff8cbb91a 115 #define COAP_RESPONSE_TIMEOUT_BACKOFF_MASK ((CLOCK_SECOND * COAP_RESPONSE_TIMEOUT * (COAP_RESPONSE_RANDOM_FACTOR - 1)) + 1.5)
terencez 0:c2dff8cbb91a 116
terencez 0:c2dff8cbb91a 117 static int prv_checkFinished(lwm2m_transaction_t * transacP,
terencez 0:c2dff8cbb91a 118 coap_packet_t * receivedMessage)
terencez 0:c2dff8cbb91a 119 {
terencez 0:c2dff8cbb91a 120 int len;
terencez 0:c2dff8cbb91a 121 const uint8_t* token;
terencez 0:c2dff8cbb91a 122 coap_packet_t * transactionMessage = transacP->message;
terencez 0:c2dff8cbb91a 123
terencez 0:c2dff8cbb91a 124 if (COAP_DELETE < transactionMessage->code)
terencez 0:c2dff8cbb91a 125 {
terencez 0:c2dff8cbb91a 126 // response
terencez 0:c2dff8cbb91a 127 return transacP->ack_received ? 1 : 0;
terencez 0:c2dff8cbb91a 128 }
terencez 0:c2dff8cbb91a 129 if (!IS_OPTION(transactionMessage, COAP_OPTION_TOKEN))
terencez 0:c2dff8cbb91a 130 {
terencez 0:c2dff8cbb91a 131 // request without token
terencez 0:c2dff8cbb91a 132 return transacP->ack_received ? 1 : 0;
terencez 0:c2dff8cbb91a 133 }
terencez 0:c2dff8cbb91a 134
terencez 0:c2dff8cbb91a 135 len = coap_get_header_token(receivedMessage, &token);
terencez 0:c2dff8cbb91a 136 if (transactionMessage->token_len == len)
terencez 0:c2dff8cbb91a 137 {
terencez 0:c2dff8cbb91a 138 if (memcmp(transactionMessage->token, token, len)==0) return 1;
terencez 0:c2dff8cbb91a 139 }
terencez 0:c2dff8cbb91a 140
terencez 0:c2dff8cbb91a 141 return 0;
terencez 0:c2dff8cbb91a 142 }
terencez 0:c2dff8cbb91a 143
terencez 0:c2dff8cbb91a 144 lwm2m_transaction_t * transaction_new(void * sessionH,
terencez 0:c2dff8cbb91a 145 coap_method_t method,
terencez 0:c2dff8cbb91a 146 char * altPath,
terencez 0:c2dff8cbb91a 147 lwm2m_uri_t * uriP,
terencez 0:c2dff8cbb91a 148 uint16_t mID,
terencez 0:c2dff8cbb91a 149 uint8_t token_len,
terencez 0:c2dff8cbb91a 150 uint8_t* token)
terencez 0:c2dff8cbb91a 151 {
terencez 0:c2dff8cbb91a 152 lwm2m_transaction_t * transacP;
terencez 0:c2dff8cbb91a 153 int result;
terencez 0:c2dff8cbb91a 154
terencez 0:c2dff8cbb91a 155 LOG_ARG("method: %d, altPath: \"%s\", mID: %d, token_len: %d",
terencez 0:c2dff8cbb91a 156 method, altPath, mID, token_len);
terencez 0:c2dff8cbb91a 157 LOG_URI(uriP);
terencez 0:c2dff8cbb91a 158
terencez 0:c2dff8cbb91a 159 // no transactions without peer
terencez 0:c2dff8cbb91a 160 if (NULL == sessionH) return NULL;
terencez 0:c2dff8cbb91a 161
terencez 0:c2dff8cbb91a 162 transacP = (lwm2m_transaction_t *)lwm2m_malloc(sizeof(lwm2m_transaction_t));
terencez 0:c2dff8cbb91a 163
terencez 0:c2dff8cbb91a 164 if (NULL == transacP) return NULL;
terencez 0:c2dff8cbb91a 165 memset(transacP, 0, sizeof(lwm2m_transaction_t));
terencez 0:c2dff8cbb91a 166
terencez 0:c2dff8cbb91a 167 transacP->message = lwm2m_malloc(sizeof(coap_packet_t));
terencez 0:c2dff8cbb91a 168 if (NULL == transacP->message) goto error;
terencez 0:c2dff8cbb91a 169
terencez 0:c2dff8cbb91a 170 coap_init_message(transacP->message, COAP_TYPE_CON, method, mID);
terencez 0:c2dff8cbb91a 171
terencez 0:c2dff8cbb91a 172 transacP->peerH = sessionH;
terencez 0:c2dff8cbb91a 173
terencez 0:c2dff8cbb91a 174 transacP->mID = mID;
terencez 0:c2dff8cbb91a 175
terencez 0:c2dff8cbb91a 176 if (altPath != NULL)
terencez 0:c2dff8cbb91a 177 {
terencez 0:c2dff8cbb91a 178 // TODO: Support multi-segment alternative path
terencez 0:c2dff8cbb91a 179 coap_set_header_uri_path_segment(transacP->message, altPath + 1);
terencez 0:c2dff8cbb91a 180 }
terencez 0:c2dff8cbb91a 181 if (NULL != uriP)
terencez 0:c2dff8cbb91a 182 {
terencez 0:c2dff8cbb91a 183 result = utils_intCopy(transacP->objStringID, LWM2M_STRING_ID_MAX_LEN, uriP->objectId);
terencez 0:c2dff8cbb91a 184 if (result < 0) goto error;
terencez 0:c2dff8cbb91a 185
terencez 0:c2dff8cbb91a 186 coap_set_header_uri_path_segment(transacP->message, transacP->objStringID);
terencez 0:c2dff8cbb91a 187
terencez 0:c2dff8cbb91a 188 if (LWM2M_URI_IS_SET_INSTANCE(uriP))
terencez 0:c2dff8cbb91a 189 {
terencez 0:c2dff8cbb91a 190 result = utils_intCopy(transacP->instanceStringID, LWM2M_STRING_ID_MAX_LEN, uriP->instanceId);
terencez 0:c2dff8cbb91a 191 if (result < 0) goto error;
terencez 0:c2dff8cbb91a 192 coap_set_header_uri_path_segment(transacP->message, transacP->instanceStringID);
terencez 0:c2dff8cbb91a 193 }
terencez 0:c2dff8cbb91a 194 else
terencez 0:c2dff8cbb91a 195 {
terencez 0:c2dff8cbb91a 196 if (LWM2M_URI_IS_SET_RESOURCE(uriP))
terencez 0:c2dff8cbb91a 197 {
terencez 0:c2dff8cbb91a 198 coap_set_header_uri_path_segment(transacP->message, NULL);
terencez 0:c2dff8cbb91a 199 }
terencez 0:c2dff8cbb91a 200 }
terencez 0:c2dff8cbb91a 201 if (LWM2M_URI_IS_SET_RESOURCE(uriP))
terencez 0:c2dff8cbb91a 202 {
terencez 0:c2dff8cbb91a 203 result = utils_intCopy(transacP->resourceStringID, LWM2M_STRING_ID_MAX_LEN, uriP->resourceId);
terencez 0:c2dff8cbb91a 204 if (result < 0) goto error;
terencez 0:c2dff8cbb91a 205 coap_set_header_uri_path_segment(transacP->message, transacP->resourceStringID);
terencez 0:c2dff8cbb91a 206 }
terencez 0:c2dff8cbb91a 207 }
terencez 0:c2dff8cbb91a 208 if (0 < token_len)
terencez 0:c2dff8cbb91a 209 {
terencez 0:c2dff8cbb91a 210 if (NULL != token)
terencez 0:c2dff8cbb91a 211 {
terencez 0:c2dff8cbb91a 212 coap_set_header_token(transacP->message, token, token_len);
terencez 0:c2dff8cbb91a 213 }
terencez 0:c2dff8cbb91a 214 else {
terencez 0:c2dff8cbb91a 215 // generate a token
terencez 0:c2dff8cbb91a 216 uint8_t temp_token[COAP_TOKEN_LEN];
terencez 0:c2dff8cbb91a 217 time_t tv_sec = lwm2m_gettime();
terencez 0:c2dff8cbb91a 218
terencez 0:c2dff8cbb91a 219 // initialize first 6 bytes, leave the last 2 random
terencez 0:c2dff8cbb91a 220 temp_token[0] = mID;
terencez 0:c2dff8cbb91a 221 temp_token[1] = mID >> 8;
terencez 0:c2dff8cbb91a 222 temp_token[2] = tv_sec;
terencez 0:c2dff8cbb91a 223 temp_token[3] = tv_sec >> 8;
terencez 0:c2dff8cbb91a 224 temp_token[4] = tv_sec >> 16;
terencez 0:c2dff8cbb91a 225 temp_token[5] = tv_sec >> 24;
terencez 0:c2dff8cbb91a 226 // use just the provided amount of bytes
terencez 0:c2dff8cbb91a 227 coap_set_header_token(transacP->message, temp_token, token_len);
terencez 0:c2dff8cbb91a 228 }
terencez 0:c2dff8cbb91a 229 }
terencez 0:c2dff8cbb91a 230
terencez 0:c2dff8cbb91a 231 LOG("Exiting on success");
terencez 0:c2dff8cbb91a 232 return transacP;
terencez 0:c2dff8cbb91a 233
terencez 0:c2dff8cbb91a 234 error:
terencez 0:c2dff8cbb91a 235 LOG("Exiting on failure");
terencez 0:c2dff8cbb91a 236 lwm2m_free(transacP);
terencez 0:c2dff8cbb91a 237 return NULL;
terencez 0:c2dff8cbb91a 238 }
terencez 0:c2dff8cbb91a 239
terencez 0:c2dff8cbb91a 240 void transaction_free(lwm2m_transaction_t * transacP)
terencez 0:c2dff8cbb91a 241 {
terencez 0:c2dff8cbb91a 242 LOG("Entering");
terencez 0:c2dff8cbb91a 243 if (transacP->message) lwm2m_free(transacP->message);
terencez 0:c2dff8cbb91a 244 if (transacP->buffer) lwm2m_free(transacP->buffer);
terencez 0:c2dff8cbb91a 245 lwm2m_free(transacP);
terencez 0:c2dff8cbb91a 246 }
terencez 0:c2dff8cbb91a 247
terencez 0:c2dff8cbb91a 248 void transaction_remove(lwm2m_context_t * contextP,
terencez 0:c2dff8cbb91a 249 lwm2m_transaction_t * transacP)
terencez 0:c2dff8cbb91a 250 {
terencez 0:c2dff8cbb91a 251 LOG("Entering");
terencez 0:c2dff8cbb91a 252 contextP->transactionList = (lwm2m_transaction_t *) LWM2M_LIST_RM(contextP->transactionList, transacP->mID, NULL);
terencez 0:c2dff8cbb91a 253 transaction_free(transacP);
terencez 0:c2dff8cbb91a 254 }
terencez 0:c2dff8cbb91a 255
terencez 0:c2dff8cbb91a 256 bool transaction_handleResponse(lwm2m_context_t * contextP,
terencez 0:c2dff8cbb91a 257 void * fromSessionH,
terencez 0:c2dff8cbb91a 258 coap_packet_t * message,
terencez 0:c2dff8cbb91a 259 coap_packet_t * response)
terencez 0:c2dff8cbb91a 260 {
terencez 0:c2dff8cbb91a 261 bool found = false;
terencez 0:c2dff8cbb91a 262 bool reset = false;
terencez 0:c2dff8cbb91a 263 lwm2m_transaction_t * transacP;
terencez 0:c2dff8cbb91a 264
terencez 0:c2dff8cbb91a 265 LOG("Entering");
terencez 0:c2dff8cbb91a 266 transacP = contextP->transactionList;
terencez 0:c2dff8cbb91a 267
terencez 0:c2dff8cbb91a 268 while (NULL != transacP)
terencez 0:c2dff8cbb91a 269 {
terencez 0:c2dff8cbb91a 270 if (lwm2m_session_is_equal(fromSessionH, transacP->peerH, contextP->userData) == true)
terencez 0:c2dff8cbb91a 271 {
terencez 0:c2dff8cbb91a 272 if (!transacP->ack_received)
terencez 0:c2dff8cbb91a 273 {
terencez 0:c2dff8cbb91a 274 if ((COAP_TYPE_ACK == message->type) || (COAP_TYPE_RST == message->type))
terencez 0:c2dff8cbb91a 275 {
terencez 0:c2dff8cbb91a 276 if (transacP->mID == message->mid)
terencez 0:c2dff8cbb91a 277 {
terencez 0:c2dff8cbb91a 278 found = true;
terencez 0:c2dff8cbb91a 279 transacP->ack_received = true;
terencez 0:c2dff8cbb91a 280 reset = COAP_TYPE_RST == message->type;
terencez 0:c2dff8cbb91a 281 }
terencez 0:c2dff8cbb91a 282 }
terencez 0:c2dff8cbb91a 283 }
terencez 0:c2dff8cbb91a 284
terencez 0:c2dff8cbb91a 285 if (reset || prv_checkFinished(transacP, message))
terencez 0:c2dff8cbb91a 286 {
terencez 0:c2dff8cbb91a 287 // HACK: If a message is sent from the monitor callback,
terencez 0:c2dff8cbb91a 288 // it will arrive before the registration ACK.
terencez 0:c2dff8cbb91a 289 // So we resend transaction that were denied for authentication reason.
terencez 0:c2dff8cbb91a 290 if (!reset)
terencez 0:c2dff8cbb91a 291 {
terencez 0:c2dff8cbb91a 292 if (COAP_TYPE_CON == message->type && NULL != response)
terencez 0:c2dff8cbb91a 293 {
terencez 0:c2dff8cbb91a 294 coap_init_message(response, COAP_TYPE_ACK, 0, message->mid);
terencez 0:c2dff8cbb91a 295 message_send(contextP, response, fromSessionH);
terencez 0:c2dff8cbb91a 296 }
terencez 0:c2dff8cbb91a 297
terencez 0:c2dff8cbb91a 298 if ((COAP_401_UNAUTHORIZED == message->code) && (COAP_MAX_RETRANSMIT > transacP->retrans_counter))
terencez 0:c2dff8cbb91a 299 {
terencez 0:c2dff8cbb91a 300 transacP->ack_received = false;
terencez 0:c2dff8cbb91a 301 transacP->retrans_time += COAP_RESPONSE_TIMEOUT;
terencez 0:c2dff8cbb91a 302 return true;
terencez 0:c2dff8cbb91a 303 }
terencez 0:c2dff8cbb91a 304 }
terencez 0:c2dff8cbb91a 305 if (transacP->callback != NULL)
terencez 0:c2dff8cbb91a 306 {
terencez 0:c2dff8cbb91a 307 transacP->callback(transacP, message);
terencez 0:c2dff8cbb91a 308 }
terencez 0:c2dff8cbb91a 309 transaction_remove(contextP, transacP);
terencez 0:c2dff8cbb91a 310 return true;
terencez 0:c2dff8cbb91a 311 }
terencez 0:c2dff8cbb91a 312 // if we found our guy, exit
terencez 0:c2dff8cbb91a 313 if (found)
terencez 0:c2dff8cbb91a 314 {
terencez 0:c2dff8cbb91a 315 time_t tv_sec = lwm2m_gettime();
terencez 0:c2dff8cbb91a 316 if (0 <= tv_sec)
terencez 0:c2dff8cbb91a 317 {
terencez 0:c2dff8cbb91a 318 transacP->retrans_time = tv_sec;
terencez 0:c2dff8cbb91a 319 }
terencez 0:c2dff8cbb91a 320 if (transacP->response_timeout)
terencez 0:c2dff8cbb91a 321 {
terencez 0:c2dff8cbb91a 322 transacP->retrans_time += transacP->response_timeout;
terencez 0:c2dff8cbb91a 323 }
terencez 0:c2dff8cbb91a 324 else
terencez 0:c2dff8cbb91a 325 {
terencez 0:c2dff8cbb91a 326 transacP->retrans_time += COAP_RESPONSE_TIMEOUT * transacP->retrans_counter;
terencez 0:c2dff8cbb91a 327 }
terencez 0:c2dff8cbb91a 328 return true;
terencez 0:c2dff8cbb91a 329 }
terencez 0:c2dff8cbb91a 330 }
terencez 0:c2dff8cbb91a 331
terencez 0:c2dff8cbb91a 332 transacP = transacP->next;
terencez 0:c2dff8cbb91a 333 }
terencez 0:c2dff8cbb91a 334 return false;
terencez 0:c2dff8cbb91a 335 }
terencez 0:c2dff8cbb91a 336
terencez 0:c2dff8cbb91a 337 int transaction_send(lwm2m_context_t * contextP,
terencez 0:c2dff8cbb91a 338 lwm2m_transaction_t * transacP)
terencez 0:c2dff8cbb91a 339 {
terencez 0:c2dff8cbb91a 340 bool maxRetriesReached = false;
terencez 0:c2dff8cbb91a 341
terencez 0:c2dff8cbb91a 342 LOG("Entering");
terencez 0:c2dff8cbb91a 343 if (transacP->buffer == NULL)
terencez 0:c2dff8cbb91a 344 {
terencez 0:c2dff8cbb91a 345 transacP->buffer_len = coap_serialize_get_size(transacP->message);
terencez 0:c2dff8cbb91a 346 if (transacP->buffer_len == 0) return COAP_500_INTERNAL_SERVER_ERROR;
terencez 0:c2dff8cbb91a 347
terencez 0:c2dff8cbb91a 348 transacP->buffer = (uint8_t*)lwm2m_malloc(transacP->buffer_len);
terencez 0:c2dff8cbb91a 349 if (transacP->buffer == NULL) return COAP_500_INTERNAL_SERVER_ERROR;
terencez 0:c2dff8cbb91a 350
terencez 0:c2dff8cbb91a 351 transacP->buffer_len = coap_serialize_message(transacP->message, transacP->buffer);
terencez 0:c2dff8cbb91a 352 if (transacP->buffer_len == 0)
terencez 0:c2dff8cbb91a 353 {
terencez 0:c2dff8cbb91a 354 lwm2m_free(transacP->buffer);
terencez 0:c2dff8cbb91a 355 transacP->buffer = NULL;
terencez 0:c2dff8cbb91a 356 transaction_remove(contextP, transacP);
terencez 0:c2dff8cbb91a 357 return COAP_500_INTERNAL_SERVER_ERROR;
terencez 0:c2dff8cbb91a 358 }
terencez 0:c2dff8cbb91a 359 }
terencez 0:c2dff8cbb91a 360
terencez 0:c2dff8cbb91a 361 if (!transacP->ack_received)
terencez 0:c2dff8cbb91a 362 {
terencez 0:c2dff8cbb91a 363 long unsigned timeout;
terencez 0:c2dff8cbb91a 364
terencez 0:c2dff8cbb91a 365 if (0 == transacP->retrans_counter)
terencez 0:c2dff8cbb91a 366 {
terencez 0:c2dff8cbb91a 367 time_t tv_sec = lwm2m_gettime();
terencez 0:c2dff8cbb91a 368 if (0 <= tv_sec)
terencez 0:c2dff8cbb91a 369 {
terencez 0:c2dff8cbb91a 370 transacP->retrans_time = tv_sec + COAP_RESPONSE_TIMEOUT;
terencez 0:c2dff8cbb91a 371 transacP->retrans_counter = 1;
terencez 0:c2dff8cbb91a 372 timeout = 0;
terencez 0:c2dff8cbb91a 373 }
terencez 0:c2dff8cbb91a 374 else
terencez 0:c2dff8cbb91a 375 {
terencez 0:c2dff8cbb91a 376 maxRetriesReached = true;
terencez 0:c2dff8cbb91a 377 }
terencez 0:c2dff8cbb91a 378 }
terencez 0:c2dff8cbb91a 379 else
terencez 0:c2dff8cbb91a 380 {
terencez 0:c2dff8cbb91a 381 timeout = COAP_RESPONSE_TIMEOUT << (transacP->retrans_counter - 1);
terencez 0:c2dff8cbb91a 382 }
terencez 0:c2dff8cbb91a 383
terencez 0:c2dff8cbb91a 384 if (COAP_MAX_RETRANSMIT + 1 >= transacP->retrans_counter)
terencez 0:c2dff8cbb91a 385 {
terencez 0:c2dff8cbb91a 386 (void)lwm2m_buffer_send(transacP->peerH, transacP->buffer, transacP->buffer_len, contextP->userData);
terencez 0:c2dff8cbb91a 387
terencez 0:c2dff8cbb91a 388 transacP->retrans_time += timeout;
terencez 0:c2dff8cbb91a 389 transacP->retrans_counter += 1;
terencez 0:c2dff8cbb91a 390 }
terencez 0:c2dff8cbb91a 391 else
terencez 0:c2dff8cbb91a 392 {
terencez 0:c2dff8cbb91a 393 maxRetriesReached = true;
terencez 0:c2dff8cbb91a 394 }
terencez 0:c2dff8cbb91a 395 }
terencez 0:c2dff8cbb91a 396
terencez 0:c2dff8cbb91a 397 if (transacP->ack_received || maxRetriesReached)
terencez 0:c2dff8cbb91a 398 {
terencez 0:c2dff8cbb91a 399 if (transacP->callback)
terencez 0:c2dff8cbb91a 400 {
terencez 0:c2dff8cbb91a 401 transacP->callback(transacP, NULL);
terencez 0:c2dff8cbb91a 402 }
terencez 0:c2dff8cbb91a 403 transaction_remove(contextP, transacP);
terencez 0:c2dff8cbb91a 404 return -1;
terencez 0:c2dff8cbb91a 405 }
terencez 0:c2dff8cbb91a 406
terencez 0:c2dff8cbb91a 407 return 0;
terencez 0:c2dff8cbb91a 408 }
terencez 0:c2dff8cbb91a 409
terencez 0:c2dff8cbb91a 410 void transaction_step(lwm2m_context_t * contextP,
terencez 0:c2dff8cbb91a 411 time_t currentTime,
terencez 0:c2dff8cbb91a 412 time_t * timeoutP)
terencez 0:c2dff8cbb91a 413 {
terencez 0:c2dff8cbb91a 414 lwm2m_transaction_t * transacP;
terencez 0:c2dff8cbb91a 415
terencez 0:c2dff8cbb91a 416 LOG("Entering");
terencez 0:c2dff8cbb91a 417 transacP = contextP->transactionList;
terencez 0:c2dff8cbb91a 418 while (transacP != NULL)
terencez 0:c2dff8cbb91a 419 {
terencez 0:c2dff8cbb91a 420 // transaction_send() may remove transaction from the linked list
terencez 0:c2dff8cbb91a 421 lwm2m_transaction_t * nextP = transacP->next;
terencez 0:c2dff8cbb91a 422 int removed = 0;
terencez 0:c2dff8cbb91a 423
terencez 0:c2dff8cbb91a 424 if (transacP->retrans_time <= currentTime)
terencez 0:c2dff8cbb91a 425 {
terencez 0:c2dff8cbb91a 426 removed = transaction_send(contextP, transacP);
terencez 0:c2dff8cbb91a 427 }
terencez 0:c2dff8cbb91a 428
terencez 0:c2dff8cbb91a 429 if (0 == removed)
terencez 0:c2dff8cbb91a 430 {
terencez 0:c2dff8cbb91a 431 time_t interval;
terencez 0:c2dff8cbb91a 432
terencez 0:c2dff8cbb91a 433 if (transacP->retrans_time > currentTime)
terencez 0:c2dff8cbb91a 434 {
terencez 0:c2dff8cbb91a 435 interval = transacP->retrans_time - currentTime;
terencez 0:c2dff8cbb91a 436 }
terencez 0:c2dff8cbb91a 437 else
terencez 0:c2dff8cbb91a 438 {
terencez 0:c2dff8cbb91a 439 interval = 1;
terencez 0:c2dff8cbb91a 440 }
terencez 0:c2dff8cbb91a 441
terencez 0:c2dff8cbb91a 442 if (*timeoutP > interval)
terencez 0:c2dff8cbb91a 443 {
terencez 0:c2dff8cbb91a 444 *timeoutP = interval;
terencez 0:c2dff8cbb91a 445 }
terencez 0:c2dff8cbb91a 446 }
terencez 0:c2dff8cbb91a 447 else
terencez 0:c2dff8cbb91a 448 {
terencez 0:c2dff8cbb91a 449 *timeoutP = 1;
terencez 0:c2dff8cbb91a 450 }
terencez 0:c2dff8cbb91a 451
terencez 0:c2dff8cbb91a 452 transacP = nextP;
terencez 0:c2dff8cbb91a 453 }
terencez 0:c2dff8cbb91a 454 }