terence zhang / Mbed OS mbed-os-example-wakaama

Dependencies:   C12832 LM75B

Committer:
terence zhang
Date:
Fri Apr 28 18:13:27 2017 +0800
Revision:
3:a280069151ac
Parent:
0:f9d13e09cf11
Child:
14:ec9e195830ff
update and merge wakaama to the latest version.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
terencez 0:f9d13e09cf11 1 /*******************************************************************************
terencez 0:f9d13e09cf11 2 *
terencez 0:f9d13e09cf11 3 * Copyright (c) 2013, 2014 Intel Corporation and others.
terencez 0:f9d13e09cf11 4 * All rights reserved. This program and the accompanying materials
terencez 0:f9d13e09cf11 5 * are made available under the terms of the Eclipse Public License v1.0
terencez 0:f9d13e09cf11 6 * and Eclipse Distribution License v1.0 which accompany this distribution.
terencez 0:f9d13e09cf11 7 *
terencez 0:f9d13e09cf11 8 * The Eclipse Public License is available at
terencez 0:f9d13e09cf11 9 * http://www.eclipse.org/legal/epl-v10.html
terencez 0:f9d13e09cf11 10 * The Eclipse Distribution License is available at
terencez 0:f9d13e09cf11 11 * http://www.eclipse.org/org/documents/edl-v10.php.
terencez 0:f9d13e09cf11 12 *
terencez 0:f9d13e09cf11 13 * Contributors:
terencez 0:f9d13e09cf11 14 * David Navarro, Intel Corporation - initial API and implementation
terencez 0:f9d13e09cf11 15 * domedambrosio - Please refer to git log
terencez 0:f9d13e09cf11 16 * Fabien Fleutot - Please refer to git log
terencez 0:f9d13e09cf11 17 * Simon Bernard - Please refer to git log
terencez 0:f9d13e09cf11 18 * Toby Jaffey - Please refer to git log
terencez 0:f9d13e09cf11 19 * Manuel Sangoi - Please refer to git log
terencez 0:f9d13e09cf11 20 * Julien Vermillard - Please refer to git log
terence zhang 3:a280069151ac 21 * Bosch Software Innovations GmbH - Please refer to git log
terence zhang 3:a280069151ac 22 * Pascal Rieux - Please refer to git log
terencez 0:f9d13e09cf11 23 *
terencez 0:f9d13e09cf11 24 *******************************************************************************/
terencez 0:f9d13e09cf11 25
terencez 0:f9d13e09cf11 26 /*
terencez 0:f9d13e09cf11 27 Copyright (c) 2013, 2014 Intel Corporation
terencez 0:f9d13e09cf11 28
terencez 0:f9d13e09cf11 29 Redistribution and use in source and binary forms, with or without modification,
terencez 0:f9d13e09cf11 30 are permitted provided that the following conditions are met:
terencez 0:f9d13e09cf11 31
terencez 0:f9d13e09cf11 32 * Redistributions of source code must retain the above copyright notice,
terencez 0:f9d13e09cf11 33 this list of conditions and the following disclaimer.
terencez 0:f9d13e09cf11 34 * Redistributions in binary form must reproduce the above copyright notice,
terencez 0:f9d13e09cf11 35 this list of conditions and the following disclaimer in the documentation
terencez 0:f9d13e09cf11 36 and/or other materials provided with the distribution.
terencez 0:f9d13e09cf11 37 * Neither the name of Intel Corporation nor the names of its contributors
terencez 0:f9d13e09cf11 38 may be used to endorse or promote products derived from this software
terencez 0:f9d13e09cf11 39 without specific prior written permission.
terencez 0:f9d13e09cf11 40
terencez 0:f9d13e09cf11 41 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
terencez 0:f9d13e09cf11 42 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
terencez 0:f9d13e09cf11 43 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
terencez 0:f9d13e09cf11 44 IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
terencez 0:f9d13e09cf11 45 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
terencez 0:f9d13e09cf11 46 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
terencez 0:f9d13e09cf11 47 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
terencez 0:f9d13e09cf11 48 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
terencez 0:f9d13e09cf11 49 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
terencez 0:f9d13e09cf11 50 THE POSSIBILITY OF SUCH DAMAGE.
terencez 0:f9d13e09cf11 51
terencez 0:f9d13e09cf11 52 David Navarro <david.navarro@intel.com>
terencez 0:f9d13e09cf11 53
terencez 0:f9d13e09cf11 54 */
terencez 0:f9d13e09cf11 55
terencez 0:f9d13e09cf11 56 #include "internals.h"
terencez 0:f9d13e09cf11 57
terencez 0:f9d13e09cf11 58 #include <stdlib.h>
terencez 0:f9d13e09cf11 59 #include <string.h>
terencez 0:f9d13e09cf11 60 #include <stdio.h>
terencez 0:f9d13e09cf11 61
terencez 0:f9d13e09cf11 62 #define MAX_LOCATION_LENGTH 10 // strlen("/rd/65534") + 1
terencez 0:f9d13e09cf11 63
terencez 0:f9d13e09cf11 64 #ifdef LWM2M_CLIENT_MODE
terence zhang 3:a280069151ac 65
terence zhang 3:a280069151ac 66 static int prv_getRegistrationQuery(lwm2m_context_t * contextP,
terence zhang 3:a280069151ac 67 lwm2m_server_t * server,
terence zhang 3:a280069151ac 68 char * buffer,
terence zhang 3:a280069151ac 69 size_t length)
terence zhang 3:a280069151ac 70 {
terence zhang 3:a280069151ac 71 int index;
terence zhang 3:a280069151ac 72 int res;
terence zhang 3:a280069151ac 73
terence zhang 3:a280069151ac 74 index = utils_stringCopy(buffer, length, QUERY_STARTER QUERY_VERSION_FULL QUERY_DELIMITER QUERY_NAME);
terence zhang 3:a280069151ac 75 if (index < 0) return 0;
terence zhang 3:a280069151ac 76 res = utils_stringCopy(buffer + index, length - index, contextP->endpointName);
terence zhang 3:a280069151ac 77 if (res < 0) return 0;
terence zhang 3:a280069151ac 78 index += res;
terence zhang 3:a280069151ac 79
terence zhang 3:a280069151ac 80 if (NULL != contextP->msisdn)
terence zhang 3:a280069151ac 81 {
terence zhang 3:a280069151ac 82 res = utils_stringCopy(buffer + index, length - index, QUERY_DELIMITER QUERY_SMS);
terence zhang 3:a280069151ac 83 if (res < 0) return 0;
terence zhang 3:a280069151ac 84 index += res;
terence zhang 3:a280069151ac 85 res = utils_stringCopy(buffer + index, length - index, contextP->msisdn);
terence zhang 3:a280069151ac 86 if (res < 0) return 0;
terence zhang 3:a280069151ac 87 index += res;
terence zhang 3:a280069151ac 88 }
terence zhang 3:a280069151ac 89
terence zhang 3:a280069151ac 90 switch (server->binding)
terence zhang 3:a280069151ac 91 {
terence zhang 3:a280069151ac 92 case BINDING_U:
terence zhang 3:a280069151ac 93 res = utils_stringCopy(buffer + index, length - index, "&b=U");
terence zhang 3:a280069151ac 94 break;
terence zhang 3:a280069151ac 95 case BINDING_UQ:
terence zhang 3:a280069151ac 96 res = utils_stringCopy(buffer + index, length - index, "&b=UQ");
terence zhang 3:a280069151ac 97 break;
terence zhang 3:a280069151ac 98 case BINDING_S:
terence zhang 3:a280069151ac 99 res = utils_stringCopy(buffer + index, length - index, "&b=S");
terence zhang 3:a280069151ac 100 break;
terence zhang 3:a280069151ac 101 case BINDING_SQ:
terence zhang 3:a280069151ac 102 res = utils_stringCopy(buffer + index, length - index, "&b=SQ");
terence zhang 3:a280069151ac 103 break;
terence zhang 3:a280069151ac 104 case BINDING_US:
terence zhang 3:a280069151ac 105 res = utils_stringCopy(buffer + index, length - index, "&b=US");
terence zhang 3:a280069151ac 106 break;
terence zhang 3:a280069151ac 107 case BINDING_UQS:
terence zhang 3:a280069151ac 108 res = utils_stringCopy(buffer + index, length - index, "&b=UQS");
terence zhang 3:a280069151ac 109 break;
terence zhang 3:a280069151ac 110 default:
terence zhang 3:a280069151ac 111 res = -1;
terence zhang 3:a280069151ac 112 }
terence zhang 3:a280069151ac 113 if (res < 0) return 0;
terence zhang 3:a280069151ac 114
terence zhang 3:a280069151ac 115 return index + res;
terence zhang 3:a280069151ac 116 }
terence zhang 3:a280069151ac 117
terencez 0:f9d13e09cf11 118 static void prv_handleRegistrationReply(lwm2m_transaction_t * transacP,
terencez 0:f9d13e09cf11 119 void * message)
terencez 0:f9d13e09cf11 120 {
terencez 0:f9d13e09cf11 121 coap_packet_t * packet = (coap_packet_t *)message;
terence zhang 3:a280069151ac 122 lwm2m_server_t * targetP = (lwm2m_server_t *)(transacP->userData);
terencez 0:f9d13e09cf11 123
terence zhang 3:a280069151ac 124 if (targetP->status == STATE_REG_PENDING)
terencez 0:f9d13e09cf11 125 {
terence zhang 3:a280069151ac 126 time_t tv_sec = lwm2m_gettime();
terence zhang 3:a280069151ac 127 if (tv_sec >= 0)
terencez 0:f9d13e09cf11 128 {
terence zhang 3:a280069151ac 129 targetP->registration = tv_sec;
terencez 0:f9d13e09cf11 130 }
terence zhang 3:a280069151ac 131 if (packet != NULL && packet->code == COAP_201_CREATED)
terencez 0:f9d13e09cf11 132 {
terence zhang 3:a280069151ac 133 targetP->status = STATE_REGISTERED;
terence zhang 3:a280069151ac 134 if (NULL != targetP->location)
terencez 0:f9d13e09cf11 135 {
terence zhang 3:a280069151ac 136 lwm2m_free(targetP->location);
terencez 0:f9d13e09cf11 137 }
terence zhang 3:a280069151ac 138 targetP->location = coap_get_multi_option_as_string(packet->location_path);
terence zhang 3:a280069151ac 139
terence zhang 3:a280069151ac 140 LOG("Registration successful");
terence zhang 3:a280069151ac 141 }
terence zhang 3:a280069151ac 142 else
terence zhang 3:a280069151ac 143 {
terence zhang 3:a280069151ac 144 targetP->status = STATE_REG_FAILED;
terence zhang 3:a280069151ac 145 LOG("Registration failed");
terencez 0:f9d13e09cf11 146 }
terencez 0:f9d13e09cf11 147 }
terence zhang 3:a280069151ac 148 }
terence zhang 3:a280069151ac 149
terence zhang 3:a280069151ac 150 #define PRV_QUERY_BUFFER_LENGTH 200
terence zhang 3:a280069151ac 151
terence zhang 3:a280069151ac 152 // send the registration for a single server
terence zhang 3:a280069151ac 153 static uint8_t prv_register(lwm2m_context_t * contextP,
terence zhang 3:a280069151ac 154 lwm2m_server_t * server)
terence zhang 3:a280069151ac 155 {
terence zhang 3:a280069151ac 156 char query[200];
terence zhang 3:a280069151ac 157 int query_length;
terence zhang 3:a280069151ac 158 uint8_t payload[512];
terence zhang 3:a280069151ac 159 int payload_length;
terence zhang 3:a280069151ac 160 lwm2m_transaction_t * transaction;
terence zhang 3:a280069151ac 161
terence zhang 3:a280069151ac 162 payload_length = object_getRegisterPayload(contextP, payload, sizeof(payload));
terence zhang 3:a280069151ac 163 if (payload_length == 0) return COAP_500_INTERNAL_SERVER_ERROR;
terence zhang 3:a280069151ac 164
terence zhang 3:a280069151ac 165 query_length = prv_getRegistrationQuery(contextP, server, query, sizeof(query));
terence zhang 3:a280069151ac 166
terence zhang 3:a280069151ac 167 if (query_length == 0) return COAP_500_INTERNAL_SERVER_ERROR;
terence zhang 3:a280069151ac 168
terence zhang 3:a280069151ac 169 if (0 != server->lifetime)
terence zhang 3:a280069151ac 170 {
terence zhang 3:a280069151ac 171 int res;
terence zhang 3:a280069151ac 172
terence zhang 3:a280069151ac 173 res = utils_stringCopy(query + query_length, PRV_QUERY_BUFFER_LENGTH - query_length, QUERY_DELIMITER QUERY_LIFETIME);
terence zhang 3:a280069151ac 174 if (res < 0) return COAP_500_INTERNAL_SERVER_ERROR;
terence zhang 3:a280069151ac 175 query_length += res;
terence zhang 3:a280069151ac 176 res = utils_intCopy(query + query_length, PRV_QUERY_BUFFER_LENGTH - query_length, server->lifetime);
terence zhang 3:a280069151ac 177 if (res < 0) return COAP_500_INTERNAL_SERVER_ERROR;
terence zhang 3:a280069151ac 178 query_length += res;
terence zhang 3:a280069151ac 179 }
terence zhang 3:a280069151ac 180
terence zhang 3:a280069151ac 181 if (server->sessionH == NULL)
terence zhang 3:a280069151ac 182 {
terence zhang 3:a280069151ac 183 server->sessionH = lwm2m_connect_server(server->secObjInstID, contextP->userData);
terence zhang 3:a280069151ac 184 }
terence zhang 3:a280069151ac 185
terence zhang 3:a280069151ac 186 if (NULL == server->sessionH) return COAP_503_SERVICE_UNAVAILABLE;
terence zhang 3:a280069151ac 187
terence zhang 3:a280069151ac 188 transaction = transaction_new(server->sessionH, COAP_POST, NULL, NULL, contextP->nextMID++, 4, NULL);
terence zhang 3:a280069151ac 189 if (transaction == NULL) return COAP_500_INTERNAL_SERVER_ERROR;
terence zhang 3:a280069151ac 190
terence zhang 3:a280069151ac 191 coap_set_header_uri_path(transaction->message, "/"URI_REGISTRATION_SEGMENT);
terence zhang 3:a280069151ac 192 coap_set_header_uri_query(transaction->message, query);
terence zhang 3:a280069151ac 193 coap_set_header_content_type(transaction->message, LWM2M_CONTENT_LINK);
terence zhang 3:a280069151ac 194 coap_set_payload(transaction->message, payload, payload_length);
terence zhang 3:a280069151ac 195
terence zhang 3:a280069151ac 196 transaction->callback = prv_handleRegistrationReply;
terence zhang 3:a280069151ac 197 transaction->userData = (void *) server;
terence zhang 3:a280069151ac 198
terence zhang 3:a280069151ac 199 contextP->transactionList = (lwm2m_transaction_t *)LWM2M_LIST_ADD(contextP->transactionList, transaction);
terence zhang 3:a280069151ac 200 if (transaction_send(contextP, transaction) != 0) return COAP_500_INTERNAL_SERVER_ERROR;
terence zhang 3:a280069151ac 201
terence zhang 3:a280069151ac 202 server->status = STATE_REG_PENDING;
terence zhang 3:a280069151ac 203
terence zhang 3:a280069151ac 204 return COAP_NO_ERROR;
terence zhang 3:a280069151ac 205 }
terence zhang 3:a280069151ac 206
terence zhang 3:a280069151ac 207 static void prv_handleRegistrationUpdateReply(lwm2m_transaction_t * transacP,
terence zhang 3:a280069151ac 208 void * message)
terence zhang 3:a280069151ac 209 {
terence zhang 3:a280069151ac 210 coap_packet_t * packet = (coap_packet_t *)message;
terence zhang 3:a280069151ac 211 lwm2m_server_t * targetP = (lwm2m_server_t *)(transacP->userData);
terence zhang 3:a280069151ac 212
terence zhang 3:a280069151ac 213 if (targetP->status == STATE_REG_UPDATE_PENDING)
terence zhang 3:a280069151ac 214 {
terence zhang 3:a280069151ac 215 time_t tv_sec = lwm2m_gettime();
terence zhang 3:a280069151ac 216 if (tv_sec >= 0)
terence zhang 3:a280069151ac 217 {
terence zhang 3:a280069151ac 218 targetP->registration = tv_sec;
terence zhang 3:a280069151ac 219 }
terence zhang 3:a280069151ac 220 if (packet != NULL && packet->code == COAP_204_CHANGED)
terence zhang 3:a280069151ac 221 {
terence zhang 3:a280069151ac 222 targetP->status = STATE_REGISTERED;
terence zhang 3:a280069151ac 223 LOG("Registration update successful");
terence zhang 3:a280069151ac 224 }
terence zhang 3:a280069151ac 225 else
terence zhang 3:a280069151ac 226 {
terence zhang 3:a280069151ac 227 targetP->status = STATE_REG_FAILED;
terence zhang 3:a280069151ac 228 LOG("Registration update failed");
terence zhang 3:a280069151ac 229 }
terencez 0:f9d13e09cf11 230 }
terencez 0:f9d13e09cf11 231 }
terencez 0:f9d13e09cf11 232
terence zhang 3:a280069151ac 233 static int prv_updateRegistration(lwm2m_context_t * contextP,
terence zhang 3:a280069151ac 234 lwm2m_server_t * server,
terence zhang 3:a280069151ac 235 bool withObjects)
terencez 0:f9d13e09cf11 236 {
terence zhang 3:a280069151ac 237 lwm2m_transaction_t * transaction;
terence zhang 3:a280069151ac 238 uint8_t payload[512];
terencez 0:f9d13e09cf11 239 int payload_length;
terence zhang 3:a280069151ac 240
terence zhang 3:a280069151ac 241 transaction = transaction_new(server->sessionH, COAP_POST, NULL, NULL, contextP->nextMID++, 4, NULL);
terence zhang 3:a280069151ac 242 if (transaction == NULL) return COAP_500_INTERNAL_SERVER_ERROR;
terence zhang 3:a280069151ac 243
terence zhang 3:a280069151ac 244 coap_set_header_uri_path(transaction->message, server->location);
terence zhang 3:a280069151ac 245
terence zhang 3:a280069151ac 246 if (withObjects == true)
terence zhang 3:a280069151ac 247 {
terence zhang 3:a280069151ac 248 payload_length = object_getRegisterPayload(contextP, payload, sizeof(payload));
terence zhang 3:a280069151ac 249 if (payload_length == 0)
terence zhang 3:a280069151ac 250 {
terence zhang 3:a280069151ac 251 transaction_free(transaction);
terence zhang 3:a280069151ac 252 return COAP_500_INTERNAL_SERVER_ERROR;
terence zhang 3:a280069151ac 253 }
terence zhang 3:a280069151ac 254 coap_set_payload(transaction->message, payload, payload_length);
terence zhang 3:a280069151ac 255 }
terence zhang 3:a280069151ac 256
terence zhang 3:a280069151ac 257 transaction->callback = prv_handleRegistrationUpdateReply;
terence zhang 3:a280069151ac 258 transaction->userData = (void *) server;
terencez 0:f9d13e09cf11 259
terence zhang 3:a280069151ac 260 contextP->transactionList = (lwm2m_transaction_t *)LWM2M_LIST_ADD(contextP->transactionList, transaction);
terence zhang 3:a280069151ac 261
terence zhang 3:a280069151ac 262 if (transaction_send(contextP, transaction) == 0)
terence zhang 3:a280069151ac 263 {
terence zhang 3:a280069151ac 264 server->status = STATE_REG_UPDATE_PENDING;
terence zhang 3:a280069151ac 265 }
terence zhang 3:a280069151ac 266
terence zhang 3:a280069151ac 267 return COAP_NO_ERROR;
terence zhang 3:a280069151ac 268 }
terence zhang 3:a280069151ac 269
terence zhang 3:a280069151ac 270 // update the registration of a given server
terence zhang 3:a280069151ac 271 int lwm2m_update_registration(lwm2m_context_t * contextP,
terence zhang 3:a280069151ac 272 uint16_t shortServerID,
terence zhang 3:a280069151ac 273 bool withObjects)
terence zhang 3:a280069151ac 274 {
terence zhang 3:a280069151ac 275 lwm2m_server_t * targetP;
terence zhang 3:a280069151ac 276 uint8_t result;
terence zhang 3:a280069151ac 277
terence zhang 3:a280069151ac 278 LOG_ARG("State: %s, shortServerID: %d", STR_STATE(contextP->state), shortServerID);
terence zhang 3:a280069151ac 279
terence zhang 3:a280069151ac 280 result = COAP_NO_ERROR;
terencez 0:f9d13e09cf11 281
terencez 0:f9d13e09cf11 282 targetP = contextP->serverList;
terence zhang 3:a280069151ac 283 if (targetP == NULL)
terence zhang 3:a280069151ac 284 {
terence zhang 3:a280069151ac 285 if (object_getServers(contextP) == -1)
terence zhang 3:a280069151ac 286 {
terence zhang 3:a280069151ac 287 LOG("No server found");
terence zhang 3:a280069151ac 288 return COAP_404_NOT_FOUND;
terence zhang 3:a280069151ac 289 }
terence zhang 3:a280069151ac 290 }
terence zhang 3:a280069151ac 291 while (targetP != NULL && result == COAP_NO_ERROR)
terence zhang 3:a280069151ac 292 {
terence zhang 3:a280069151ac 293 if (shortServerID != 0)
terence zhang 3:a280069151ac 294 {
terence zhang 3:a280069151ac 295 if (targetP->shortID == shortServerID)
terence zhang 3:a280069151ac 296 {
terence zhang 3:a280069151ac 297 // found the server, trigger the update transaction
terence zhang 3:a280069151ac 298 if (targetP->status == STATE_REGISTERED
terence zhang 3:a280069151ac 299 || targetP->status == STATE_REG_UPDATE_PENDING)
terence zhang 3:a280069151ac 300 {
terence zhang 3:a280069151ac 301 if (withObjects == true)
terence zhang 3:a280069151ac 302 {
terence zhang 3:a280069151ac 303 targetP->status = STATE_REG_FULL_UPDATE_NEEDED;
terence zhang 3:a280069151ac 304 }
terence zhang 3:a280069151ac 305 else
terence zhang 3:a280069151ac 306 {
terence zhang 3:a280069151ac 307 targetP->status = STATE_REG_UPDATE_NEEDED;
terence zhang 3:a280069151ac 308 }
terence zhang 3:a280069151ac 309 return COAP_NO_ERROR;
terence zhang 3:a280069151ac 310 }
terence zhang 3:a280069151ac 311 else if ((targetP->status == STATE_REG_FULL_UPDATE_NEEDED)
terence zhang 3:a280069151ac 312 || (targetP->status == STATE_REG_UPDATE_NEEDED))
terence zhang 3:a280069151ac 313 {
terence zhang 3:a280069151ac 314 // if REG (FULL) UPDATE is already set, returns COAP_NO_ERROR
terence zhang 3:a280069151ac 315 if (withObjects == true)
terence zhang 3:a280069151ac 316 {
terence zhang 3:a280069151ac 317 targetP->status = STATE_REG_FULL_UPDATE_NEEDED;
terence zhang 3:a280069151ac 318 }
terence zhang 3:a280069151ac 319 return COAP_NO_ERROR;
terence zhang 3:a280069151ac 320 }
terence zhang 3:a280069151ac 321 else
terence zhang 3:a280069151ac 322 {
terence zhang 3:a280069151ac 323 return COAP_400_BAD_REQUEST;
terence zhang 3:a280069151ac 324 }
terence zhang 3:a280069151ac 325 }
terence zhang 3:a280069151ac 326 }
terence zhang 3:a280069151ac 327 else
terence zhang 3:a280069151ac 328 {
terence zhang 3:a280069151ac 329 if (targetP->status == STATE_REGISTERED
terence zhang 3:a280069151ac 330 || targetP->status == STATE_REG_UPDATE_PENDING)
terence zhang 3:a280069151ac 331 {
terence zhang 3:a280069151ac 332 if (withObjects == true)
terence zhang 3:a280069151ac 333 {
terence zhang 3:a280069151ac 334 targetP->status = STATE_REG_FULL_UPDATE_NEEDED;
terence zhang 3:a280069151ac 335 }
terence zhang 3:a280069151ac 336 else
terence zhang 3:a280069151ac 337 {
terence zhang 3:a280069151ac 338 targetP->status = STATE_REG_UPDATE_NEEDED;
terence zhang 3:a280069151ac 339 }
terence zhang 3:a280069151ac 340 }
terence zhang 3:a280069151ac 341 }
terence zhang 3:a280069151ac 342 targetP = targetP->next;
terence zhang 3:a280069151ac 343 }
terence zhang 3:a280069151ac 344
terence zhang 3:a280069151ac 345 if (shortServerID != 0
terence zhang 3:a280069151ac 346 && targetP == NULL)
terence zhang 3:a280069151ac 347 {
terence zhang 3:a280069151ac 348 // no server found
terence zhang 3:a280069151ac 349 result = COAP_404_NOT_FOUND;
terence zhang 3:a280069151ac 350 }
terence zhang 3:a280069151ac 351
terence zhang 3:a280069151ac 352 return result;
terence zhang 3:a280069151ac 353 }
terence zhang 3:a280069151ac 354
terence zhang 3:a280069151ac 355 uint8_t registration_start(lwm2m_context_t * contextP)
terence zhang 3:a280069151ac 356 {
terence zhang 3:a280069151ac 357 lwm2m_server_t * targetP;
terence zhang 3:a280069151ac 358 uint8_t result;
terence zhang 3:a280069151ac 359
terence zhang 3:a280069151ac 360 LOG_ARG("State: %s", STR_STATE(contextP->state));
terence zhang 3:a280069151ac 361
terence zhang 3:a280069151ac 362 result = COAP_NO_ERROR;
terence zhang 3:a280069151ac 363
terence zhang 3:a280069151ac 364 targetP = contextP->serverList;
terence zhang 3:a280069151ac 365 while (targetP != NULL && result == COAP_NO_ERROR)
terence zhang 3:a280069151ac 366 {
terence zhang 3:a280069151ac 367 if (targetP->status == STATE_DEREGISTERED
terence zhang 3:a280069151ac 368 || targetP->status == STATE_REG_FAILED)
terence zhang 3:a280069151ac 369 {
terence zhang 3:a280069151ac 370 result = prv_register(contextP, targetP);
terence zhang 3:a280069151ac 371 }
terence zhang 3:a280069151ac 372 targetP = targetP->next;
terence zhang 3:a280069151ac 373 }
terence zhang 3:a280069151ac 374
terence zhang 3:a280069151ac 375 return result;
terence zhang 3:a280069151ac 376 }
terence zhang 3:a280069151ac 377
terence zhang 3:a280069151ac 378
terence zhang 3:a280069151ac 379 /*
terence zhang 3:a280069151ac 380 * Returns STATE_REG_PENDING if at least one registration is still pending
terence zhang 3:a280069151ac 381 * Returns STATE_REGISTERED if no registration is pending and there is at least one server the client is registered to
terence zhang 3:a280069151ac 382 * Returns STATE_REG_FAILED if all registration failed.
terence zhang 3:a280069151ac 383 */
terence zhang 3:a280069151ac 384 lwm2m_status_t registration_getStatus(lwm2m_context_t * contextP)
terence zhang 3:a280069151ac 385 {
terence zhang 3:a280069151ac 386 lwm2m_server_t * targetP;
terence zhang 3:a280069151ac 387 lwm2m_status_t reg_status;
terence zhang 3:a280069151ac 388
terence zhang 3:a280069151ac 389 LOG_ARG("State: %s", STR_STATE(contextP->state));
terence zhang 3:a280069151ac 390
terence zhang 3:a280069151ac 391 targetP = contextP->serverList;
terence zhang 3:a280069151ac 392 reg_status = STATE_REG_FAILED;
terence zhang 3:a280069151ac 393
terencez 0:f9d13e09cf11 394 while (targetP != NULL)
terencez 0:f9d13e09cf11 395 {
terence zhang 3:a280069151ac 396 LOG_ARG("targetP->status: %s", STR_STATUS(targetP->status));
terence zhang 3:a280069151ac 397 switch (targetP->status)
terence zhang 3:a280069151ac 398 {
terence zhang 3:a280069151ac 399 case STATE_REGISTERED:
terence zhang 3:a280069151ac 400 case STATE_REG_UPDATE_NEEDED:
terence zhang 3:a280069151ac 401 case STATE_REG_FULL_UPDATE_NEEDED:
terence zhang 3:a280069151ac 402 case STATE_REG_UPDATE_PENDING:
terence zhang 3:a280069151ac 403 if (reg_status == STATE_REG_FAILED)
terence zhang 3:a280069151ac 404 {
terence zhang 3:a280069151ac 405 reg_status = STATE_REGISTERED;
terence zhang 3:a280069151ac 406 }
terence zhang 3:a280069151ac 407 break;
terencez 0:f9d13e09cf11 408
terence zhang 3:a280069151ac 409 case STATE_REG_PENDING:
terence zhang 3:a280069151ac 410 reg_status = STATE_REG_PENDING;
terence zhang 3:a280069151ac 411 break;
terence zhang 3:a280069151ac 412
terence zhang 3:a280069151ac 413 case STATE_REG_FAILED:
terence zhang 3:a280069151ac 414 case STATE_DEREG_PENDING:
terence zhang 3:a280069151ac 415 case STATE_DEREGISTERED:
terence zhang 3:a280069151ac 416 default:
terence zhang 3:a280069151ac 417 break;
terencez 0:f9d13e09cf11 418 }
terence zhang 3:a280069151ac 419 LOG_ARG("reg_status: %s", STR_STATUS(reg_status));
terencez 0:f9d13e09cf11 420
terencez 0:f9d13e09cf11 421 targetP = targetP->next;
terencez 0:f9d13e09cf11 422 }
terencez 0:f9d13e09cf11 423
terence zhang 3:a280069151ac 424 return reg_status;
terencez 0:f9d13e09cf11 425 }
terencez 0:f9d13e09cf11 426
terencez 0:f9d13e09cf11 427 static void prv_handleDeregistrationReply(lwm2m_transaction_t * transacP,
terence zhang 3:a280069151ac 428 void * message)
terencez 0:f9d13e09cf11 429 {
terencez 0:f9d13e09cf11 430 lwm2m_server_t * targetP;
terencez 0:f9d13e09cf11 431
terence zhang 3:a280069151ac 432 targetP = (lwm2m_server_t *)(transacP->userData);
terence zhang 3:a280069151ac 433 if (NULL != targetP)
terencez 0:f9d13e09cf11 434 {
terence zhang 3:a280069151ac 435 if (targetP->status == STATE_DEREG_PENDING)
terencez 0:f9d13e09cf11 436 {
terence zhang 3:a280069151ac 437 targetP->status = STATE_DEREGISTERED;
terencez 0:f9d13e09cf11 438 }
terencez 0:f9d13e09cf11 439 }
terencez 0:f9d13e09cf11 440 }
terencez 0:f9d13e09cf11 441
terencez 0:f9d13e09cf11 442 void registration_deregister(lwm2m_context_t * contextP,
terencez 0:f9d13e09cf11 443 lwm2m_server_t * serverP)
terencez 0:f9d13e09cf11 444 {
terence zhang 3:a280069151ac 445 lwm2m_transaction_t * transaction;
terence zhang 3:a280069151ac 446
terence zhang 3:a280069151ac 447 LOG_ARG("State: %s, serverP->status: %s", STR_STATE(contextP->state), STR_STATUS(serverP->status));
terencez 0:f9d13e09cf11 448
terence zhang 3:a280069151ac 449 if (serverP->status == STATE_DEREGISTERED
terence zhang 3:a280069151ac 450 || serverP->status == STATE_REG_PENDING
terence zhang 3:a280069151ac 451 || serverP->status == STATE_DEREG_PENDING
terence zhang 3:a280069151ac 452 || serverP->status == STATE_REG_FAILED
terence zhang 3:a280069151ac 453 || serverP->location == NULL)
terence zhang 3:a280069151ac 454 {
terence zhang 3:a280069151ac 455 return;
terence zhang 3:a280069151ac 456 }
terencez 0:f9d13e09cf11 457
terence zhang 3:a280069151ac 458 transaction = transaction_new(serverP->sessionH, COAP_DELETE, NULL, NULL, contextP->nextMID++, 4, NULL);
terencez 0:f9d13e09cf11 459 if (transaction == NULL) return;
terencez 0:f9d13e09cf11 460
terencez 0:f9d13e09cf11 461 coap_set_header_uri_path(transaction->message, serverP->location);
terencez 0:f9d13e09cf11 462
terencez 0:f9d13e09cf11 463 transaction->callback = prv_handleDeregistrationReply;
terencez 0:f9d13e09cf11 464 transaction->userData = (void *) contextP;
terencez 0:f9d13e09cf11 465
terencez 0:f9d13e09cf11 466 contextP->transactionList = (lwm2m_transaction_t *)LWM2M_LIST_ADD(contextP->transactionList, transaction);
terencez 0:f9d13e09cf11 467 if (transaction_send(contextP, transaction) == 0)
terencez 0:f9d13e09cf11 468 {
terence zhang 3:a280069151ac 469 serverP->status = STATE_DEREG_PENDING;
terencez 0:f9d13e09cf11 470 }
terencez 0:f9d13e09cf11 471 }
terencez 0:f9d13e09cf11 472 #endif
terencez 0:f9d13e09cf11 473
terencez 0:f9d13e09cf11 474 #ifdef LWM2M_SERVER_MODE
terencez 0:f9d13e09cf11 475 static void prv_freeClientObjectList(lwm2m_client_object_t * objects)
terencez 0:f9d13e09cf11 476 {
terencez 0:f9d13e09cf11 477 while (objects != NULL)
terencez 0:f9d13e09cf11 478 {
terencez 0:f9d13e09cf11 479 lwm2m_client_object_t * objP;
terencez 0:f9d13e09cf11 480
terencez 0:f9d13e09cf11 481 while (objects->instanceList != NULL)
terencez 0:f9d13e09cf11 482 {
terencez 0:f9d13e09cf11 483 lwm2m_list_t * target;
terencez 0:f9d13e09cf11 484
terencez 0:f9d13e09cf11 485 target = objects->instanceList;
terencez 0:f9d13e09cf11 486 objects->instanceList = objects->instanceList->next;
terencez 0:f9d13e09cf11 487 lwm2m_free(target);
terencez 0:f9d13e09cf11 488 }
terencez 0:f9d13e09cf11 489
terencez 0:f9d13e09cf11 490 objP = objects;
terencez 0:f9d13e09cf11 491 objects = objects->next;
terencez 0:f9d13e09cf11 492 lwm2m_free(objP);
terencez 0:f9d13e09cf11 493 }
terencez 0:f9d13e09cf11 494 }
terencez 0:f9d13e09cf11 495
terence zhang 3:a280069151ac 496 static int prv_getParameters(multi_option_t * query,
terence zhang 3:a280069151ac 497 char ** nameP,
terence zhang 3:a280069151ac 498 uint32_t * lifetimeP,
terence zhang 3:a280069151ac 499 char ** msisdnP,
terence zhang 3:a280069151ac 500 lwm2m_binding_t * bindingP,
terence zhang 3:a280069151ac 501 char ** versionP)
terence zhang 3:a280069151ac 502 {
terence zhang 3:a280069151ac 503 *nameP = NULL;
terence zhang 3:a280069151ac 504 *lifetimeP = 0;
terence zhang 3:a280069151ac 505 *msisdnP = NULL;
terence zhang 3:a280069151ac 506 *bindingP = BINDING_UNKNOWN;
terence zhang 3:a280069151ac 507 *versionP = NULL;
terence zhang 3:a280069151ac 508
terence zhang 3:a280069151ac 509 while (query != NULL)
terence zhang 3:a280069151ac 510 {
terence zhang 3:a280069151ac 511 if (lwm2m_strncmp((char *)query->data, QUERY_NAME, QUERY_NAME_LEN) == 0)
terence zhang 3:a280069151ac 512 {
terence zhang 3:a280069151ac 513 if (*nameP != NULL) goto error;
terence zhang 3:a280069151ac 514 if (query->len == QUERY_NAME_LEN) goto error;
terence zhang 3:a280069151ac 515
terence zhang 3:a280069151ac 516 *nameP = (char *)lwm2m_malloc(query->len - QUERY_NAME_LEN + 1);
terence zhang 3:a280069151ac 517 if (*nameP != NULL)
terence zhang 3:a280069151ac 518 {
terence zhang 3:a280069151ac 519 memcpy(*nameP, query->data + QUERY_NAME_LEN, query->len - QUERY_NAME_LEN);
terence zhang 3:a280069151ac 520 (*nameP)[query->len - QUERY_NAME_LEN] = 0;
terence zhang 3:a280069151ac 521 }
terence zhang 3:a280069151ac 522 }
terence zhang 3:a280069151ac 523 else if (lwm2m_strncmp((char *)query->data, QUERY_SMS, QUERY_SMS_LEN) == 0)
terence zhang 3:a280069151ac 524 {
terence zhang 3:a280069151ac 525 if (*msisdnP != NULL) goto error;
terence zhang 3:a280069151ac 526 if (query->len == QUERY_SMS_LEN) goto error;
terence zhang 3:a280069151ac 527
terence zhang 3:a280069151ac 528 *msisdnP = (char *)lwm2m_malloc(query->len - QUERY_SMS_LEN + 1);
terence zhang 3:a280069151ac 529 if (*msisdnP != NULL)
terence zhang 3:a280069151ac 530 {
terence zhang 3:a280069151ac 531 memcpy(*msisdnP, query->data + QUERY_SMS_LEN, query->len - QUERY_SMS_LEN);
terence zhang 3:a280069151ac 532 (*msisdnP)[query->len - QUERY_SMS_LEN] = 0;
terence zhang 3:a280069151ac 533 }
terence zhang 3:a280069151ac 534 }
terence zhang 3:a280069151ac 535 else if (lwm2m_strncmp((char *)query->data, QUERY_LIFETIME, QUERY_LIFETIME_LEN) == 0)
terence zhang 3:a280069151ac 536 {
terence zhang 3:a280069151ac 537 int i;
terence zhang 3:a280069151ac 538
terence zhang 3:a280069151ac 539 if (*lifetimeP != 0) goto error;
terence zhang 3:a280069151ac 540 if (query->len == QUERY_LIFETIME_LEN) goto error;
terence zhang 3:a280069151ac 541
terence zhang 3:a280069151ac 542 for (i = QUERY_LIFETIME_LEN ; i < query->len ; i++)
terence zhang 3:a280069151ac 543 {
terence zhang 3:a280069151ac 544 if (query->data[i] < '0' || query->data[i] > '9') goto error;
terence zhang 3:a280069151ac 545 *lifetimeP = (*lifetimeP * 10) + (query->data[i] - '0');
terence zhang 3:a280069151ac 546 }
terence zhang 3:a280069151ac 547 }
terence zhang 3:a280069151ac 548 else if (lwm2m_strncmp((char *)query->data, QUERY_VERSION, QUERY_VERSION_LEN) == 0)
terence zhang 3:a280069151ac 549 {
terence zhang 3:a280069151ac 550 if (*versionP != NULL) goto error;
terence zhang 3:a280069151ac 551 if (query->len == QUERY_VERSION_LEN) goto error;
terence zhang 3:a280069151ac 552
terence zhang 3:a280069151ac 553 *versionP = (char *)lwm2m_malloc(query->len - QUERY_VERSION_LEN + 1);
terence zhang 3:a280069151ac 554 if (*versionP != NULL)
terence zhang 3:a280069151ac 555 {
terence zhang 3:a280069151ac 556 memcpy(*versionP, query->data + QUERY_VERSION_LEN, query->len - QUERY_VERSION_LEN);
terence zhang 3:a280069151ac 557 (*versionP)[query->len - QUERY_VERSION_LEN] = 0;
terence zhang 3:a280069151ac 558 }
terence zhang 3:a280069151ac 559 }
terence zhang 3:a280069151ac 560 else if (lwm2m_strncmp((char *)query->data, QUERY_BINDING, QUERY_BINDING_LEN) == 0)
terence zhang 3:a280069151ac 561 {
terence zhang 3:a280069151ac 562 if (*bindingP != BINDING_UNKNOWN) goto error;
terence zhang 3:a280069151ac 563 if (query->len == QUERY_BINDING_LEN) goto error;
terence zhang 3:a280069151ac 564
terence zhang 3:a280069151ac 565 *bindingP = utils_stringToBinding(query->data + QUERY_BINDING_LEN, query->len - QUERY_BINDING_LEN);
terence zhang 3:a280069151ac 566 }
terence zhang 3:a280069151ac 567 query = query->next;
terence zhang 3:a280069151ac 568 }
terence zhang 3:a280069151ac 569
terence zhang 3:a280069151ac 570 return 0;
terence zhang 3:a280069151ac 571
terence zhang 3:a280069151ac 572 error:
terence zhang 3:a280069151ac 573 if (*nameP != NULL) lwm2m_free(*nameP);
terence zhang 3:a280069151ac 574 if (*msisdnP != NULL) lwm2m_free(*msisdnP);
terence zhang 3:a280069151ac 575 if (*versionP != NULL) lwm2m_free(*versionP);
terence zhang 3:a280069151ac 576
terence zhang 3:a280069151ac 577 return -1;
terence zhang 3:a280069151ac 578 }
terence zhang 3:a280069151ac 579
terence zhang 3:a280069151ac 580 static uint16_t prv_splitLinkAttribute(uint8_t * data,
terence zhang 3:a280069151ac 581 uint16_t length,
terence zhang 3:a280069151ac 582 uint16_t * keyStart,
terence zhang 3:a280069151ac 583 uint16_t * keyLength,
terence zhang 3:a280069151ac 584 uint16_t * valueStart,
terence zhang 3:a280069151ac 585 uint16_t * valueLength)
terence zhang 3:a280069151ac 586 {
terence zhang 3:a280069151ac 587 uint16_t index;
terence zhang 3:a280069151ac 588 uint16_t end;
terence zhang 3:a280069151ac 589
terence zhang 3:a280069151ac 590 index = 0;
terence zhang 3:a280069151ac 591 while (index < length && data[index] == ' ') index++;
terence zhang 3:a280069151ac 592 if (index == length) return 0;
terence zhang 3:a280069151ac 593
terence zhang 3:a280069151ac 594 if (data[index] == REG_ATTR_SEPARATOR)
terence zhang 3:a280069151ac 595 {
terence zhang 3:a280069151ac 596 index++;
terence zhang 3:a280069151ac 597 }
terence zhang 3:a280069151ac 598 if (index == length) return 0;
terence zhang 3:a280069151ac 599
terence zhang 3:a280069151ac 600 *keyStart = index;
terence zhang 3:a280069151ac 601
terence zhang 3:a280069151ac 602 while (index < length && data[index] != REG_ATTR_EQUALS) index++;
terence zhang 3:a280069151ac 603 if (index == *keyStart || index == length) return 0;
terence zhang 3:a280069151ac 604
terence zhang 3:a280069151ac 605 *keyLength = index - *keyStart;
terence zhang 3:a280069151ac 606
terence zhang 3:a280069151ac 607 index++;
terence zhang 3:a280069151ac 608 while (index < length && data[index] == ' ') index++;
terence zhang 3:a280069151ac 609 if (index == length) return 0;
terence zhang 3:a280069151ac 610
terence zhang 3:a280069151ac 611 *valueStart = index;
terence zhang 3:a280069151ac 612
terence zhang 3:a280069151ac 613 while (index < length && data[index] != REG_ATTR_SEPARATOR) index++;
terence zhang 3:a280069151ac 614 end = index;
terence zhang 3:a280069151ac 615
terence zhang 3:a280069151ac 616 index--;
terence zhang 3:a280069151ac 617 while (index > *valueStart && data[index] == ' ') index--;
terence zhang 3:a280069151ac 618 if (index == *valueStart) return 0;
terence zhang 3:a280069151ac 619
terence zhang 3:a280069151ac 620 *valueLength = index - *valueStart + 1;
terence zhang 3:a280069151ac 621
terence zhang 3:a280069151ac 622 return end;
terence zhang 3:a280069151ac 623 }
terence zhang 3:a280069151ac 624
terence zhang 3:a280069151ac 625 static int prv_parseLinkAttributes(uint8_t * data,
terence zhang 3:a280069151ac 626 uint16_t length,
terence zhang 3:a280069151ac 627 bool * supportJSON,
terence zhang 3:a280069151ac 628 char ** altPath)
terencez 0:f9d13e09cf11 629 {
terence zhang 3:a280069151ac 630 uint16_t index;
terence zhang 3:a280069151ac 631 uint16_t pathStart;
terence zhang 3:a280069151ac 632 uint16_t pathLength;
terence zhang 3:a280069151ac 633 bool isValid;
terence zhang 3:a280069151ac 634
terence zhang 3:a280069151ac 635 isValid = false;
terence zhang 3:a280069151ac 636
terence zhang 3:a280069151ac 637 // Expecting application/link-format (RFC6690)
terence zhang 3:a280069151ac 638 // leading space were removed before. Remove trailing spaces.
terence zhang 3:a280069151ac 639 while (length > 0 && data[length-1] == ' ') length--;
terence zhang 3:a280069151ac 640
terence zhang 3:a280069151ac 641 // strip open tag
terence zhang 3:a280069151ac 642 if (length >= 2 && data[0] == REG_URI_START)
terence zhang 3:a280069151ac 643 {
terence zhang 3:a280069151ac 644 data += 1;
terence zhang 3:a280069151ac 645 length -= 1;
terence zhang 3:a280069151ac 646 }
terence zhang 3:a280069151ac 647 else
terence zhang 3:a280069151ac 648 {
terence zhang 3:a280069151ac 649 return 0;
terence zhang 3:a280069151ac 650 }
terence zhang 3:a280069151ac 651
terence zhang 3:a280069151ac 652 pathStart = 0;
terence zhang 3:a280069151ac 653 index = length - 1;
terence zhang 3:a280069151ac 654 while (index > 0 && data[index] != REG_URI_END) index--;
terence zhang 3:a280069151ac 655 // link attributes are required
terence zhang 3:a280069151ac 656 if (index == 0 || index == length - 1) return 0;
terence zhang 3:a280069151ac 657
terence zhang 3:a280069151ac 658 // If there is a preceding /, remove it
terence zhang 3:a280069151ac 659 if (data[pathStart] == '/')
terence zhang 3:a280069151ac 660 {
terence zhang 3:a280069151ac 661 pathStart += 1;
terence zhang 3:a280069151ac 662 }
terence zhang 3:a280069151ac 663 pathLength = index - pathStart;
terence zhang 3:a280069151ac 664
terence zhang 3:a280069151ac 665 index++;
terence zhang 3:a280069151ac 666 if (index >= length || data[index] != REG_ATTR_SEPARATOR) return 0;
terence zhang 3:a280069151ac 667 index++;
terence zhang 3:a280069151ac 668
terence zhang 3:a280069151ac 669 while (index < length)
terence zhang 3:a280069151ac 670 {
terence zhang 3:a280069151ac 671 uint16_t result;
terence zhang 3:a280069151ac 672 uint16_t keyStart;
terence zhang 3:a280069151ac 673 uint16_t keyLength;
terence zhang 3:a280069151ac 674 uint16_t valueStart;
terence zhang 3:a280069151ac 675 uint16_t valueLength;
terence zhang 3:a280069151ac 676
terence zhang 3:a280069151ac 677 result = prv_splitLinkAttribute(data + index, length - index, &keyStart, &keyLength, &valueStart, &valueLength);
terence zhang 3:a280069151ac 678 if (result == 0) return 0;
terence zhang 3:a280069151ac 679
terence zhang 3:a280069151ac 680 if (keyLength == REG_ATTR_TYPE_KEY_LEN
terence zhang 3:a280069151ac 681 && 0 == lwm2m_strncmp(REG_ATTR_TYPE_KEY, data + index + keyStart, keyLength))
terence zhang 3:a280069151ac 682 {
terence zhang 3:a280069151ac 683 if (isValid == true) return 0; // declared twice
terence zhang 3:a280069151ac 684 if (valueLength != REG_ATTR_TYPE_VALUE_LEN
terence zhang 3:a280069151ac 685 || 0 != lwm2m_strncmp(REG_ATTR_TYPE_VALUE, data + index + valueStart, valueLength))
terence zhang 3:a280069151ac 686 {
terence zhang 3:a280069151ac 687 return 0;
terence zhang 3:a280069151ac 688 }
terence zhang 3:a280069151ac 689 isValid = true;
terence zhang 3:a280069151ac 690 }
terence zhang 3:a280069151ac 691 else if (keyLength == REG_ATTR_CONTENT_KEY_LEN
terence zhang 3:a280069151ac 692 && 0 == lwm2m_strncmp(REG_ATTR_CONTENT_KEY, data + index + keyStart, keyLength))
terence zhang 3:a280069151ac 693 {
terence zhang 3:a280069151ac 694 if (*supportJSON == true) return 0; // declared twice
terence zhang 3:a280069151ac 695 if (valueLength == REG_ATTR_CONTENT_JSON_LEN
terence zhang 3:a280069151ac 696 && 0 == lwm2m_strncmp(REG_ATTR_CONTENT_JSON, data + index + valueStart, valueLength))
terence zhang 3:a280069151ac 697 {
terence zhang 3:a280069151ac 698 *supportJSON = true;
terence zhang 3:a280069151ac 699 }
terence zhang 3:a280069151ac 700 else
terence zhang 3:a280069151ac 701 {
terence zhang 3:a280069151ac 702 return 0;
terence zhang 3:a280069151ac 703 }
terence zhang 3:a280069151ac 704 }
terence zhang 3:a280069151ac 705 // else ignore this one
terence zhang 3:a280069151ac 706
terence zhang 3:a280069151ac 707 index += result;
terence zhang 3:a280069151ac 708 }
terence zhang 3:a280069151ac 709
terence zhang 3:a280069151ac 710 if (isValid == false) return 0;
terence zhang 3:a280069151ac 711
terence zhang 3:a280069151ac 712 if (pathLength != 0)
terence zhang 3:a280069151ac 713 {
terence zhang 3:a280069151ac 714 *altPath = (char *)lwm2m_malloc(pathLength + 1);
terence zhang 3:a280069151ac 715 if (*altPath == NULL) return 0;
terence zhang 3:a280069151ac 716 memcpy(*altPath, data + pathStart, pathLength);
terence zhang 3:a280069151ac 717 (*altPath)[pathLength] = 0;
terence zhang 3:a280069151ac 718 }
terence zhang 3:a280069151ac 719
terence zhang 3:a280069151ac 720 return 1;
terence zhang 3:a280069151ac 721 }
terence zhang 3:a280069151ac 722
terence zhang 3:a280069151ac 723 static int prv_getId(uint8_t * data,
terence zhang 3:a280069151ac 724 uint16_t length,
terence zhang 3:a280069151ac 725 uint16_t * objId,
terence zhang 3:a280069151ac 726 uint16_t * instanceId)
terence zhang 3:a280069151ac 727 {
terence zhang 3:a280069151ac 728 int value;
terence zhang 3:a280069151ac 729 uint16_t limit;
terence zhang 3:a280069151ac 730
terence zhang 3:a280069151ac 731 // Expecting application/link-format (RFC6690)
terence zhang 3:a280069151ac 732 // leading space were removed before. Remove trailing spaces.
terence zhang 3:a280069151ac 733 while (length > 0 && data[length-1] == ' ') length--;
terence zhang 3:a280069151ac 734
terence zhang 3:a280069151ac 735 // strip open and close tags
terence zhang 3:a280069151ac 736 if (length >= 1 && data[0] == REG_URI_START && data[length-1] == REG_URI_END)
terence zhang 3:a280069151ac 737 {
terence zhang 3:a280069151ac 738 data += 1;
terence zhang 3:a280069151ac 739 length -= 2;
terence zhang 3:a280069151ac 740 }
terence zhang 3:a280069151ac 741 else
terence zhang 3:a280069151ac 742 {
terence zhang 3:a280069151ac 743 return 0;
terence zhang 3:a280069151ac 744 }
terence zhang 3:a280069151ac 745
terence zhang 3:a280069151ac 746 // If there is a preceding /, remove it
terence zhang 3:a280069151ac 747 if (length >= 1 && data[0] == '/')
terence zhang 3:a280069151ac 748 {
terence zhang 3:a280069151ac 749 data += 1;
terence zhang 3:a280069151ac 750 length -= 1;
terence zhang 3:a280069151ac 751 }
terence zhang 3:a280069151ac 752
terence zhang 3:a280069151ac 753 limit = 0;
terence zhang 3:a280069151ac 754 while (limit < length && data[limit] != '/') limit++;
terence zhang 3:a280069151ac 755 value = uri_getNumber(data, limit);
terence zhang 3:a280069151ac 756 if (value < 0 || value >= LWM2M_MAX_ID) return 0;
terence zhang 3:a280069151ac 757 *objId = value;
terence zhang 3:a280069151ac 758
terence zhang 3:a280069151ac 759 if (limit < length)
terence zhang 3:a280069151ac 760 {
terence zhang 3:a280069151ac 761 limit += 1;
terence zhang 3:a280069151ac 762 data += limit;
terence zhang 3:a280069151ac 763 length -= limit;
terence zhang 3:a280069151ac 764
terence zhang 3:a280069151ac 765 if (length > 0)
terence zhang 3:a280069151ac 766 {
terence zhang 3:a280069151ac 767 value = uri_getNumber(data, length);
terence zhang 3:a280069151ac 768 if (value >= 0 && value < LWM2M_MAX_ID)
terence zhang 3:a280069151ac 769 {
terence zhang 3:a280069151ac 770 *instanceId = value;
terence zhang 3:a280069151ac 771 return 2;
terence zhang 3:a280069151ac 772 }
terence zhang 3:a280069151ac 773 else
terence zhang 3:a280069151ac 774 {
terence zhang 3:a280069151ac 775 return 0;
terence zhang 3:a280069151ac 776 }
terence zhang 3:a280069151ac 777 }
terence zhang 3:a280069151ac 778 }
terence zhang 3:a280069151ac 779
terence zhang 3:a280069151ac 780 return 1;
terence zhang 3:a280069151ac 781 }
terence zhang 3:a280069151ac 782
terence zhang 3:a280069151ac 783 static lwm2m_client_object_t * prv_decodeRegisterPayload(uint8_t * payload,
terence zhang 3:a280069151ac 784 uint16_t payloadLength,
terence zhang 3:a280069151ac 785 bool * supportJSON,
terence zhang 3:a280069151ac 786 char ** altPath)
terence zhang 3:a280069151ac 787 {
terence zhang 3:a280069151ac 788 uint16_t index;
terence zhang 3:a280069151ac 789 lwm2m_client_object_t * objList;
terence zhang 3:a280069151ac 790 bool linkAttrFound;
terence zhang 3:a280069151ac 791
terence zhang 3:a280069151ac 792 *altPath = NULL;
terence zhang 3:a280069151ac 793 *supportJSON = false;
terence zhang 3:a280069151ac 794 objList = NULL;
terence zhang 3:a280069151ac 795 linkAttrFound = false;
terence zhang 3:a280069151ac 796 index = 0;
terence zhang 3:a280069151ac 797
terence zhang 3:a280069151ac 798 while (index <= payloadLength)
terence zhang 3:a280069151ac 799 {
terence zhang 3:a280069151ac 800 uint16_t start;
terence zhang 3:a280069151ac 801 uint16_t length;
terence zhang 3:a280069151ac 802 int result;
terence zhang 3:a280069151ac 803 uint16_t id;
terence zhang 3:a280069151ac 804 uint16_t instance;
terence zhang 3:a280069151ac 805
terence zhang 3:a280069151ac 806 while (index < payloadLength && payload[index] == ' ') index++;
terence zhang 3:a280069151ac 807 if (index == payloadLength) break;
terence zhang 3:a280069151ac 808
terence zhang 3:a280069151ac 809 start = index;
terence zhang 3:a280069151ac 810 while (index < payloadLength && payload[index] != REG_DELIMITER) index++;
terence zhang 3:a280069151ac 811 length = index - start;
terence zhang 3:a280069151ac 812
terence zhang 3:a280069151ac 813 result = prv_getId(payload + start, length, &id, &instance);
terence zhang 3:a280069151ac 814 if (result != 0)
terence zhang 3:a280069151ac 815 {
terence zhang 3:a280069151ac 816 lwm2m_client_object_t * objectP;
terence zhang 3:a280069151ac 817
terence zhang 3:a280069151ac 818 objectP = (lwm2m_client_object_t *)lwm2m_list_find((lwm2m_list_t *)objList, id);
terence zhang 3:a280069151ac 819 if (objectP == NULL)
terence zhang 3:a280069151ac 820 {
terence zhang 3:a280069151ac 821 objectP = (lwm2m_client_object_t *)lwm2m_malloc(sizeof(lwm2m_client_object_t));
terence zhang 3:a280069151ac 822 memset(objectP, 0, sizeof(lwm2m_client_object_t));
terence zhang 3:a280069151ac 823 if (objectP == NULL) goto error;
terence zhang 3:a280069151ac 824 objectP->id = id;
terence zhang 3:a280069151ac 825 objList = (lwm2m_client_object_t *)LWM2M_LIST_ADD(objList, objectP);
terence zhang 3:a280069151ac 826 }
terence zhang 3:a280069151ac 827 if (result == 2)
terence zhang 3:a280069151ac 828 {
terence zhang 3:a280069151ac 829 lwm2m_list_t * instanceP;
terence zhang 3:a280069151ac 830
terence zhang 3:a280069151ac 831 instanceP = lwm2m_list_find(objectP->instanceList, instance);
terence zhang 3:a280069151ac 832 if (instanceP == NULL)
terence zhang 3:a280069151ac 833 {
terence zhang 3:a280069151ac 834 instanceP = (lwm2m_list_t *)lwm2m_malloc(sizeof(lwm2m_list_t));
terence zhang 3:a280069151ac 835 memset(instanceP, 0, sizeof(lwm2m_list_t));
terence zhang 3:a280069151ac 836 instanceP->id = instance;
terence zhang 3:a280069151ac 837 objectP->instanceList = LWM2M_LIST_ADD(objectP->instanceList, instanceP);
terence zhang 3:a280069151ac 838 }
terence zhang 3:a280069151ac 839 }
terence zhang 3:a280069151ac 840 }
terence zhang 3:a280069151ac 841 else if (linkAttrFound == false)
terence zhang 3:a280069151ac 842 {
terence zhang 3:a280069151ac 843 result = prv_parseLinkAttributes(payload + start, length, supportJSON, altPath);
terence zhang 3:a280069151ac 844 if (result == 0) goto error;
terence zhang 3:a280069151ac 845
terence zhang 3:a280069151ac 846 linkAttrFound = true;
terence zhang 3:a280069151ac 847 }
terence zhang 3:a280069151ac 848 else goto error;
terence zhang 3:a280069151ac 849
terence zhang 3:a280069151ac 850 index++;
terence zhang 3:a280069151ac 851 }
terence zhang 3:a280069151ac 852
terence zhang 3:a280069151ac 853 return objList;
terence zhang 3:a280069151ac 854
terence zhang 3:a280069151ac 855 error:
terence zhang 3:a280069151ac 856 if (*altPath != NULL)
terence zhang 3:a280069151ac 857 {
terence zhang 3:a280069151ac 858 lwm2m_free(*altPath);
terence zhang 3:a280069151ac 859 *altPath = NULL;
terence zhang 3:a280069151ac 860 }
terence zhang 3:a280069151ac 861 prv_freeClientObjectList(objList);
terence zhang 3:a280069151ac 862
terence zhang 3:a280069151ac 863 return NULL;
terence zhang 3:a280069151ac 864 }
terence zhang 3:a280069151ac 865
terence zhang 3:a280069151ac 866 static lwm2m_client_t * prv_getClientByName(lwm2m_context_t * contextP,
terence zhang 3:a280069151ac 867 char * name)
terence zhang 3:a280069151ac 868 {
terence zhang 3:a280069151ac 869 lwm2m_client_t * targetP;
terence zhang 3:a280069151ac 870
terence zhang 3:a280069151ac 871 targetP = contextP->clientList;
terence zhang 3:a280069151ac 872 while (targetP != NULL && strcmp(name, targetP->name) != 0)
terence zhang 3:a280069151ac 873 {
terence zhang 3:a280069151ac 874 targetP = targetP->next;
terence zhang 3:a280069151ac 875 }
terence zhang 3:a280069151ac 876
terence zhang 3:a280069151ac 877 return targetP;
terence zhang 3:a280069151ac 878 }
terence zhang 3:a280069151ac 879
terence zhang 3:a280069151ac 880 void registration_freeClient(lwm2m_client_t * clientP)
terence zhang 3:a280069151ac 881 {
terence zhang 3:a280069151ac 882 LOG("Entering");
terencez 0:f9d13e09cf11 883 if (clientP->name != NULL) lwm2m_free(clientP->name);
terencez 0:f9d13e09cf11 884 if (clientP->msisdn != NULL) lwm2m_free(clientP->msisdn);
terence zhang 3:a280069151ac 885 if (clientP->altPath != NULL) lwm2m_free(clientP->altPath);
terencez 0:f9d13e09cf11 886 prv_freeClientObjectList(clientP->objectList);
terencez 0:f9d13e09cf11 887 while(clientP->observationList != NULL)
terencez 0:f9d13e09cf11 888 {
terencez 0:f9d13e09cf11 889 lwm2m_observation_t * targetP;
terencez 0:f9d13e09cf11 890
terencez 0:f9d13e09cf11 891 targetP = clientP->observationList;
terencez 0:f9d13e09cf11 892 clientP->observationList = clientP->observationList->next;
terencez 0:f9d13e09cf11 893 lwm2m_free(targetP);
terencez 0:f9d13e09cf11 894 }
terencez 0:f9d13e09cf11 895 lwm2m_free(clientP);
terencez 0:f9d13e09cf11 896 }
terencez 0:f9d13e09cf11 897
terencez 0:f9d13e09cf11 898 static int prv_getLocationString(uint16_t id,
terencez 0:f9d13e09cf11 899 char location[MAX_LOCATION_LENGTH])
terencez 0:f9d13e09cf11 900 {
terence zhang 3:a280069151ac 901 int index;
terencez 0:f9d13e09cf11 902 int result;
terencez 0:f9d13e09cf11 903
terencez 0:f9d13e09cf11 904 memset(location, 0, MAX_LOCATION_LENGTH);
terencez 0:f9d13e09cf11 905
terence zhang 3:a280069151ac 906 result = utils_stringCopy(location, MAX_LOCATION_LENGTH, "/"URI_REGISTRATION_SEGMENT"/");
terence zhang 3:a280069151ac 907 if (result < 0) return 0;
terence zhang 3:a280069151ac 908 index = result;
terencez 0:f9d13e09cf11 909
terence zhang 3:a280069151ac 910 result = utils_intCopy(location + index, MAX_LOCATION_LENGTH - index, id);
terence zhang 3:a280069151ac 911 if (result < 0) return 0;
terence zhang 3:a280069151ac 912
terence zhang 3:a280069151ac 913 return index + result;
terencez 0:f9d13e09cf11 914 }
terencez 0:f9d13e09cf11 915
terence zhang 3:a280069151ac 916 coap_status_t registration_handleRequest(lwm2m_context_t * contextP,
terencez 0:f9d13e09cf11 917 lwm2m_uri_t * uriP,
terencez 0:f9d13e09cf11 918 void * fromSessionH,
terencez 0:f9d13e09cf11 919 coap_packet_t * message,
terencez 0:f9d13e09cf11 920 coap_packet_t * response)
terencez 0:f9d13e09cf11 921 {
terencez 0:f9d13e09cf11 922 coap_status_t result;
terence zhang 3:a280069151ac 923 time_t tv_sec;
terencez 0:f9d13e09cf11 924
terence zhang 3:a280069151ac 925 LOG_URI(uriP);
terence zhang 3:a280069151ac 926 tv_sec = lwm2m_gettime();
terence zhang 3:a280069151ac 927 if (tv_sec < 0) return COAP_500_INTERNAL_SERVER_ERROR;
terencez 0:f9d13e09cf11 928
terencez 0:f9d13e09cf11 929 switch(message->code)
terencez 0:f9d13e09cf11 930 {
terencez 0:f9d13e09cf11 931 case COAP_POST:
terencez 0:f9d13e09cf11 932 {
terencez 0:f9d13e09cf11 933 char * name = NULL;
terencez 0:f9d13e09cf11 934 uint32_t lifetime;
terencez 0:f9d13e09cf11 935 char * msisdn;
terence zhang 3:a280069151ac 936 char * altPath;
terence zhang 3:a280069151ac 937 char * version;
terencez 0:f9d13e09cf11 938 lwm2m_binding_t binding;
terencez 0:f9d13e09cf11 939 lwm2m_client_object_t * objects;
terence zhang 3:a280069151ac 940 bool supportJSON;
terencez 0:f9d13e09cf11 941 lwm2m_client_t * clientP;
terencez 0:f9d13e09cf11 942 char location[MAX_LOCATION_LENGTH];
terencez 0:f9d13e09cf11 943
terence zhang 3:a280069151ac 944 if (0 != prv_getParameters(message->uri_query, &name, &lifetime, &msisdn, &binding, &version))
terence zhang 3:a280069151ac 945 {
terence zhang 3:a280069151ac 946 return COAP_400_BAD_REQUEST;
terence zhang 3:a280069151ac 947 }
terence zhang 3:a280069151ac 948 if (message->content_type != LWM2M_CONTENT_LINK
terence zhang 3:a280069151ac 949 && message->content_type != LWM2M_CONTENT_TEXT)
terencez 0:f9d13e09cf11 950 {
terencez 0:f9d13e09cf11 951 return COAP_400_BAD_REQUEST;
terencez 0:f9d13e09cf11 952 }
terence zhang 3:a280069151ac 953
terence zhang 3:a280069151ac 954 objects = prv_decodeRegisterPayload(message->payload, message->payload_len, &supportJSON, &altPath);
terence zhang 3:a280069151ac 955
terence zhang 3:a280069151ac 956 switch (uriP->flag & LWM2M_URI_MASK_ID)
terencez 0:f9d13e09cf11 957 {
terence zhang 3:a280069151ac 958 case 0:
terence zhang 3:a280069151ac 959 // Register operation
terence zhang 3:a280069151ac 960 // Version is mandatory
terence zhang 3:a280069151ac 961 if (version == NULL)
terence zhang 3:a280069151ac 962 {
terence zhang 3:a280069151ac 963 if (name != NULL) lwm2m_free(name);
terence zhang 3:a280069151ac 964 if (msisdn != NULL) lwm2m_free(msisdn);
terence zhang 3:a280069151ac 965 return COAP_400_BAD_REQUEST;
terence zhang 3:a280069151ac 966 }
terence zhang 3:a280069151ac 967 // Endpoint client name is mandatory
terence zhang 3:a280069151ac 968 if (name == NULL)
terence zhang 3:a280069151ac 969 {
terence zhang 3:a280069151ac 970 lwm2m_free(version);
terence zhang 3:a280069151ac 971 if (msisdn != NULL) lwm2m_free(msisdn);
terence zhang 3:a280069151ac 972 return COAP_400_BAD_REQUEST;
terence zhang 3:a280069151ac 973 }
terence zhang 3:a280069151ac 974 // Object list is mandatory
terence zhang 3:a280069151ac 975 if (objects == NULL)
terence zhang 3:a280069151ac 976 {
terence zhang 3:a280069151ac 977 lwm2m_free(version);
terence zhang 3:a280069151ac 978 lwm2m_free(name);
terence zhang 3:a280069151ac 979 if (msisdn != NULL) lwm2m_free(msisdn);
terence zhang 3:a280069151ac 980 return COAP_400_BAD_REQUEST;
terence zhang 3:a280069151ac 981 }
terence zhang 3:a280069151ac 982 // version must be 1.0
terence zhang 3:a280069151ac 983 if (strlen(version) != LWM2M_VERSION_LEN
terence zhang 3:a280069151ac 984 || lwm2m_strncmp(version, LWM2M_VERSION, LWM2M_VERSION_LEN))
terence zhang 3:a280069151ac 985 {
terence zhang 3:a280069151ac 986 lwm2m_free(version);
terence zhang 3:a280069151ac 987 lwm2m_free(name);
terence zhang 3:a280069151ac 988 if (msisdn != NULL) lwm2m_free(msisdn);
terence zhang 3:a280069151ac 989 return COAP_412_PRECONDITION_FAILED;
terence zhang 3:a280069151ac 990 }
terence zhang 3:a280069151ac 991
terence zhang 3:a280069151ac 992 if (lifetime == 0)
terence zhang 3:a280069151ac 993 {
terence zhang 3:a280069151ac 994 lifetime = LWM2M_DEFAULT_LIFETIME;
terence zhang 3:a280069151ac 995 }
terencez 0:f9d13e09cf11 996
terence zhang 3:a280069151ac 997 clientP = prv_getClientByName(contextP, name);
terence zhang 3:a280069151ac 998 if (clientP != NULL)
terence zhang 3:a280069151ac 999 {
terence zhang 3:a280069151ac 1000 // we reset this registration
terence zhang 3:a280069151ac 1001 lwm2m_free(clientP->name);
terence zhang 3:a280069151ac 1002 if (clientP->msisdn != NULL) lwm2m_free(clientP->msisdn);
terence zhang 3:a280069151ac 1003 if (clientP->altPath != NULL) lwm2m_free(clientP->altPath);
terence zhang 3:a280069151ac 1004 prv_freeClientObjectList(clientP->objectList);
terence zhang 3:a280069151ac 1005 clientP->objectList = NULL;
terence zhang 3:a280069151ac 1006 }
terence zhang 3:a280069151ac 1007 else
terence zhang 3:a280069151ac 1008 {
terence zhang 3:a280069151ac 1009 clientP = (lwm2m_client_t *)lwm2m_malloc(sizeof(lwm2m_client_t));
terence zhang 3:a280069151ac 1010 if (clientP == NULL)
terence zhang 3:a280069151ac 1011 {
terence zhang 3:a280069151ac 1012 lwm2m_free(name);
terence zhang 3:a280069151ac 1013 lwm2m_free(altPath);
terence zhang 3:a280069151ac 1014 if (msisdn != NULL) lwm2m_free(msisdn);
terence zhang 3:a280069151ac 1015 prv_freeClientObjectList(objects);
terence zhang 3:a280069151ac 1016 return COAP_500_INTERNAL_SERVER_ERROR;
terence zhang 3:a280069151ac 1017 }
terence zhang 3:a280069151ac 1018 memset(clientP, 0, sizeof(lwm2m_client_t));
terence zhang 3:a280069151ac 1019 clientP->internalID = lwm2m_list_newId((lwm2m_list_t *)contextP->clientList);
terence zhang 3:a280069151ac 1020 contextP->clientList = (lwm2m_client_t *)LWM2M_LIST_ADD(contextP->clientList, clientP);
terence zhang 3:a280069151ac 1021 }
terence zhang 3:a280069151ac 1022 clientP->name = name;
terence zhang 3:a280069151ac 1023 clientP->binding = binding;
terence zhang 3:a280069151ac 1024 clientP->msisdn = msisdn;
terence zhang 3:a280069151ac 1025 clientP->altPath = altPath;
terence zhang 3:a280069151ac 1026 clientP->supportJSON = supportJSON;
terence zhang 3:a280069151ac 1027 clientP->lifetime = lifetime;
terence zhang 3:a280069151ac 1028 clientP->endOfLife = tv_sec + lifetime;
terence zhang 3:a280069151ac 1029 clientP->objectList = objects;
terence zhang 3:a280069151ac 1030 clientP->sessionH = fromSessionH;
terence zhang 3:a280069151ac 1031
terence zhang 3:a280069151ac 1032 if (prv_getLocationString(clientP->internalID, location) == 0)
terence zhang 3:a280069151ac 1033 {
terence zhang 3:a280069151ac 1034 registration_freeClient(clientP);
terence zhang 3:a280069151ac 1035 return COAP_500_INTERNAL_SERVER_ERROR;
terence zhang 3:a280069151ac 1036 }
terence zhang 3:a280069151ac 1037 if (coap_set_header_location_path(response, location) == 0)
terence zhang 3:a280069151ac 1038 {
terence zhang 3:a280069151ac 1039 registration_freeClient(clientP);
terence zhang 3:a280069151ac 1040 return COAP_500_INTERNAL_SERVER_ERROR;
terence zhang 3:a280069151ac 1041 }
terence zhang 3:a280069151ac 1042
terence zhang 3:a280069151ac 1043 if (contextP->monitorCallback != NULL)
terence zhang 3:a280069151ac 1044 {
terence zhang 3:a280069151ac 1045 contextP->monitorCallback(clientP->internalID, NULL, COAP_201_CREATED, LWM2M_CONTENT_TEXT, NULL, 0, contextP->monitorUserData);
terence zhang 3:a280069151ac 1046 }
terence zhang 3:a280069151ac 1047 result = COAP_201_CREATED;
terence zhang 3:a280069151ac 1048 break;
terence zhang 3:a280069151ac 1049
terence zhang 3:a280069151ac 1050 case LWM2M_URI_FLAG_OBJECT_ID:
terence zhang 3:a280069151ac 1051 clientP = (lwm2m_client_t *)lwm2m_list_find((lwm2m_list_t *)contextP->clientList, uriP->objectId);
terence zhang 3:a280069151ac 1052 if (clientP == NULL) return COAP_404_NOT_FOUND;
terence zhang 3:a280069151ac 1053
terence zhang 3:a280069151ac 1054 // Endpoint client name MUST NOT be present
terence zhang 3:a280069151ac 1055 if (name != NULL)
terencez 0:f9d13e09cf11 1056 {
terencez 0:f9d13e09cf11 1057 lwm2m_free(name);
terencez 0:f9d13e09cf11 1058 if (msisdn != NULL) lwm2m_free(msisdn);
terence zhang 3:a280069151ac 1059 return COAP_400_BAD_REQUEST;
terencez 0:f9d13e09cf11 1060 }
terencez 0:f9d13e09cf11 1061
terence zhang 3:a280069151ac 1062 if (binding != BINDING_UNKNOWN)
terence zhang 3:a280069151ac 1063 {
terence zhang 3:a280069151ac 1064 clientP->binding = binding;
terence zhang 3:a280069151ac 1065 }
terence zhang 3:a280069151ac 1066 if (msisdn != NULL)
terence zhang 3:a280069151ac 1067 {
terence zhang 3:a280069151ac 1068 if (clientP->msisdn != NULL) lwm2m_free(clientP->msisdn);
terence zhang 3:a280069151ac 1069 clientP->msisdn = msisdn;
terence zhang 3:a280069151ac 1070 }
terence zhang 3:a280069151ac 1071 if (lifetime != 0)
terence zhang 3:a280069151ac 1072 {
terence zhang 3:a280069151ac 1073 clientP->lifetime = lifetime;
terence zhang 3:a280069151ac 1074 }
terence zhang 3:a280069151ac 1075 // client IP address, port or MSISDN may have changed
terence zhang 3:a280069151ac 1076 clientP->sessionH = fromSessionH;
terencez 0:f9d13e09cf11 1077
terence zhang 3:a280069151ac 1078 if (objects != NULL)
terence zhang 3:a280069151ac 1079 {
terence zhang 3:a280069151ac 1080 lwm2m_observation_t * observationP;
terencez 0:f9d13e09cf11 1081
terence zhang 3:a280069151ac 1082 // remove observations on object/instance no longer existing
terence zhang 3:a280069151ac 1083 observationP = clientP->observationList;
terence zhang 3:a280069151ac 1084 while (observationP != NULL)
terence zhang 3:a280069151ac 1085 {
terence zhang 3:a280069151ac 1086 lwm2m_client_object_t * objP;
terence zhang 3:a280069151ac 1087 lwm2m_observation_t * nextP;
terencez 0:f9d13e09cf11 1088
terence zhang 3:a280069151ac 1089 nextP = observationP->next;
terencez 0:f9d13e09cf11 1090
terence zhang 3:a280069151ac 1091 objP = (lwm2m_client_object_t *)lwm2m_list_find((lwm2m_list_t *)objects, observationP->uri.objectId);
terence zhang 3:a280069151ac 1092 if (objP == NULL)
terence zhang 3:a280069151ac 1093 {
terence zhang 3:a280069151ac 1094 observationP->callback(clientP->internalID,
terence zhang 3:a280069151ac 1095 &observationP->uri,
terence zhang 3:a280069151ac 1096 COAP_202_DELETED,
terence zhang 3:a280069151ac 1097 LWM2M_CONTENT_TEXT, NULL, 0,
terence zhang 3:a280069151ac 1098 observationP->userData);
terence zhang 3:a280069151ac 1099 observe_remove(observationP);
terence zhang 3:a280069151ac 1100 }
terence zhang 3:a280069151ac 1101 else
terencez 0:f9d13e09cf11 1102 {
terence zhang 3:a280069151ac 1103 if ((observationP->uri.flag & LWM2M_URI_FLAG_INSTANCE_ID) != 0)
terencez 0:f9d13e09cf11 1104 {
terence zhang 3:a280069151ac 1105 if (lwm2m_list_find((lwm2m_list_t *)objP->instanceList, observationP->uri.instanceId) == NULL)
terence zhang 3:a280069151ac 1106 {
terence zhang 3:a280069151ac 1107 observationP->callback(clientP->internalID,
terence zhang 3:a280069151ac 1108 &observationP->uri,
terence zhang 3:a280069151ac 1109 COAP_202_DELETED,
terence zhang 3:a280069151ac 1110 LWM2M_CONTENT_TEXT, NULL, 0,
terence zhang 3:a280069151ac 1111 observationP->userData);
terence zhang 3:a280069151ac 1112 observe_remove(observationP);
terence zhang 3:a280069151ac 1113 }
terencez 0:f9d13e09cf11 1114 }
terencez 0:f9d13e09cf11 1115 }
terence zhang 3:a280069151ac 1116
terence zhang 3:a280069151ac 1117 observationP = nextP;
terencez 0:f9d13e09cf11 1118 }
terencez 0:f9d13e09cf11 1119
terence zhang 3:a280069151ac 1120 prv_freeClientObjectList(clientP->objectList);
terence zhang 3:a280069151ac 1121 clientP->objectList = objects;
terencez 0:f9d13e09cf11 1122 }
terencez 0:f9d13e09cf11 1123
terence zhang 3:a280069151ac 1124 clientP->endOfLife = tv_sec + clientP->lifetime;
terencez 0:f9d13e09cf11 1125
terence zhang 3:a280069151ac 1126 if (contextP->monitorCallback != NULL)
terence zhang 3:a280069151ac 1127 {
terence zhang 3:a280069151ac 1128 contextP->monitorCallback(clientP->internalID, NULL, COAP_204_CHANGED, LWM2M_CONTENT_TEXT, NULL, 0, contextP->monitorUserData);
terence zhang 3:a280069151ac 1129 }
terence zhang 3:a280069151ac 1130 result = COAP_204_CHANGED;
terence zhang 3:a280069151ac 1131 break;
terence zhang 3:a280069151ac 1132
terence zhang 3:a280069151ac 1133 default:
terence zhang 3:a280069151ac 1134 return COAP_400_BAD_REQUEST;
terencez 0:f9d13e09cf11 1135 }
terencez 0:f9d13e09cf11 1136 }
terencez 0:f9d13e09cf11 1137 break;
terencez 0:f9d13e09cf11 1138
terencez 0:f9d13e09cf11 1139 case COAP_DELETE:
terencez 0:f9d13e09cf11 1140 {
terencez 0:f9d13e09cf11 1141 lwm2m_client_t * clientP;
terencez 0:f9d13e09cf11 1142
terencez 0:f9d13e09cf11 1143 if ((uriP->flag & LWM2M_URI_MASK_ID) != LWM2M_URI_FLAG_OBJECT_ID) return COAP_400_BAD_REQUEST;
terencez 0:f9d13e09cf11 1144
terencez 0:f9d13e09cf11 1145 contextP->clientList = (lwm2m_client_t *)LWM2M_LIST_RM(contextP->clientList, uriP->objectId, &clientP);
terencez 0:f9d13e09cf11 1146 if (clientP == NULL) return COAP_400_BAD_REQUEST;
terencez 0:f9d13e09cf11 1147 if (contextP->monitorCallback != NULL)
terencez 0:f9d13e09cf11 1148 {
terence zhang 3:a280069151ac 1149 contextP->monitorCallback(clientP->internalID, NULL, COAP_202_DELETED, LWM2M_CONTENT_TEXT, NULL, 0, contextP->monitorUserData);
terencez 0:f9d13e09cf11 1150 }
terence zhang 3:a280069151ac 1151 registration_freeClient(clientP);
terencez 0:f9d13e09cf11 1152 result = COAP_202_DELETED;
terencez 0:f9d13e09cf11 1153 }
terencez 0:f9d13e09cf11 1154 break;
terencez 0:f9d13e09cf11 1155
terencez 0:f9d13e09cf11 1156 default:
terencez 0:f9d13e09cf11 1157 return COAP_400_BAD_REQUEST;
terencez 0:f9d13e09cf11 1158 }
terencez 0:f9d13e09cf11 1159
terencez 0:f9d13e09cf11 1160 return result;
terencez 0:f9d13e09cf11 1161 }
terencez 0:f9d13e09cf11 1162
terencez 0:f9d13e09cf11 1163 void lwm2m_set_monitoring_callback(lwm2m_context_t * contextP,
terencez 0:f9d13e09cf11 1164 lwm2m_result_callback_t callback,
terencez 0:f9d13e09cf11 1165 void * userData)
terencez 0:f9d13e09cf11 1166 {
terence zhang 3:a280069151ac 1167 LOG("Entering");
terencez 0:f9d13e09cf11 1168 contextP->monitorCallback = callback;
terencez 0:f9d13e09cf11 1169 contextP->monitorUserData = userData;
terencez 0:f9d13e09cf11 1170 }
terence zhang 3:a280069151ac 1171 #endif
terencez 0:f9d13e09cf11 1172
terence zhang 3:a280069151ac 1173 // for each server update the registration if needed
terence zhang 3:a280069151ac 1174 // for each client check if the registration expired
terence zhang 3:a280069151ac 1175 void registration_step(lwm2m_context_t * contextP,
terence zhang 3:a280069151ac 1176 time_t currentTime,
terence zhang 3:a280069151ac 1177 time_t * timeoutP)
terence zhang 3:a280069151ac 1178 {
terence zhang 3:a280069151ac 1179 #ifdef LWM2M_CLIENT_MODE
terence zhang 3:a280069151ac 1180 lwm2m_server_t * targetP = contextP->serverList;
terence zhang 3:a280069151ac 1181
terence zhang 3:a280069151ac 1182 LOG_ARG("State: %s", STR_STATE(contextP->state));
terence zhang 3:a280069151ac 1183
terence zhang 3:a280069151ac 1184 targetP = contextP->serverList;
terence zhang 3:a280069151ac 1185 while (targetP != NULL)
terence zhang 3:a280069151ac 1186 {
terence zhang 3:a280069151ac 1187 switch (targetP->status)
terence zhang 3:a280069151ac 1188 {
terence zhang 3:a280069151ac 1189 case STATE_REGISTERED:
terence zhang 3:a280069151ac 1190 {
terence zhang 3:a280069151ac 1191 time_t nextUpdate;
terence zhang 3:a280069151ac 1192 time_t interval;
terence zhang 3:a280069151ac 1193
terence zhang 3:a280069151ac 1194 nextUpdate = targetP->lifetime;
terence zhang 3:a280069151ac 1195 if (COAP_MAX_TRANSMIT_WAIT < nextUpdate)
terence zhang 3:a280069151ac 1196 {
terence zhang 3:a280069151ac 1197 nextUpdate -= COAP_MAX_TRANSMIT_WAIT;
terence zhang 3:a280069151ac 1198 }
terence zhang 3:a280069151ac 1199 else
terence zhang 3:a280069151ac 1200 {
terence zhang 3:a280069151ac 1201 nextUpdate = nextUpdate >> 1;
terence zhang 3:a280069151ac 1202 }
terence zhang 3:a280069151ac 1203
terence zhang 3:a280069151ac 1204 interval = targetP->registration + nextUpdate - currentTime;
terence zhang 3:a280069151ac 1205 if (0 >= interval)
terence zhang 3:a280069151ac 1206 {
terence zhang 3:a280069151ac 1207 LOG("Updating registration");
terence zhang 3:a280069151ac 1208 prv_updateRegistration(contextP, targetP, false);
terence zhang 3:a280069151ac 1209 }
terence zhang 3:a280069151ac 1210 else if (interval < *timeoutP)
terence zhang 3:a280069151ac 1211 {
terence zhang 3:a280069151ac 1212 *timeoutP = interval;
terence zhang 3:a280069151ac 1213 }
terence zhang 3:a280069151ac 1214 }
terence zhang 3:a280069151ac 1215 break;
terence zhang 3:a280069151ac 1216
terence zhang 3:a280069151ac 1217 case STATE_REG_UPDATE_NEEDED:
terence zhang 3:a280069151ac 1218 prv_updateRegistration(contextP, targetP, false);
terence zhang 3:a280069151ac 1219 break;
terence zhang 3:a280069151ac 1220
terence zhang 3:a280069151ac 1221 case STATE_REG_FULL_UPDATE_NEEDED:
terence zhang 3:a280069151ac 1222 prv_updateRegistration(contextP, targetP, true);
terence zhang 3:a280069151ac 1223 break;
terence zhang 3:a280069151ac 1224
terence zhang 3:a280069151ac 1225 case STATE_REG_FAILED:
terence zhang 3:a280069151ac 1226 if (targetP->sessionH != NULL)
terence zhang 3:a280069151ac 1227 {
terence zhang 3:a280069151ac 1228 lwm2m_close_connection(targetP->sessionH, contextP->userData);
terence zhang 3:a280069151ac 1229 targetP->sessionH = NULL;
terence zhang 3:a280069151ac 1230 }
terence zhang 3:a280069151ac 1231 break;
terence zhang 3:a280069151ac 1232
terence zhang 3:a280069151ac 1233 default:
terence zhang 3:a280069151ac 1234 break;
terence zhang 3:a280069151ac 1235 }
terence zhang 3:a280069151ac 1236 targetP = targetP->next;
terence zhang 3:a280069151ac 1237 }
terencez 0:f9d13e09cf11 1238
terencez 0:f9d13e09cf11 1239 #endif
terence zhang 3:a280069151ac 1240 #ifdef LWM2M_SERVER_MODE
terence zhang 3:a280069151ac 1241 lwm2m_client_t * clientP;
terence zhang 3:a280069151ac 1242
terence zhang 3:a280069151ac 1243 LOG("Entering");
terence zhang 3:a280069151ac 1244 // monitor clients lifetime
terence zhang 3:a280069151ac 1245 clientP = contextP->clientList;
terence zhang 3:a280069151ac 1246 while (clientP != NULL)
terence zhang 3:a280069151ac 1247 {
terence zhang 3:a280069151ac 1248 lwm2m_client_t * nextP = clientP->next;
terence zhang 3:a280069151ac 1249
terence zhang 3:a280069151ac 1250 if (clientP->endOfLife <= currentTime)
terence zhang 3:a280069151ac 1251 {
terence zhang 3:a280069151ac 1252 contextP->clientList = (lwm2m_client_t *)LWM2M_LIST_RM(contextP->clientList, clientP->internalID, NULL);
terence zhang 3:a280069151ac 1253 if (contextP->monitorCallback != NULL)
terence zhang 3:a280069151ac 1254 {
terence zhang 3:a280069151ac 1255 contextP->monitorCallback(clientP->internalID, NULL, COAP_202_DELETED, LWM2M_CONTENT_TEXT, NULL, 0, contextP->monitorUserData);
terence zhang 3:a280069151ac 1256 }
terence zhang 3:a280069151ac 1257 registration_freeClient(clientP);
terence zhang 3:a280069151ac 1258 }
terence zhang 3:a280069151ac 1259 else
terence zhang 3:a280069151ac 1260 {
terence zhang 3:a280069151ac 1261 time_t interval;
terence zhang 3:a280069151ac 1262
terence zhang 3:a280069151ac 1263 interval = clientP->endOfLife - currentTime;
terence zhang 3:a280069151ac 1264
terence zhang 3:a280069151ac 1265 if (*timeoutP > interval)
terence zhang 3:a280069151ac 1266 {
terence zhang 3:a280069151ac 1267 *timeoutP = interval;
terence zhang 3:a280069151ac 1268 }
terence zhang 3:a280069151ac 1269 }
terence zhang 3:a280069151ac 1270 clientP = nextP;
terence zhang 3:a280069151ac 1271 }
terence zhang 3:a280069151ac 1272 #endif
terence zhang 3:a280069151ac 1273
terence zhang 3:a280069151ac 1274 }
terence zhang 3:a280069151ac 1275