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

Dependencies:   C12832 LM75B

Committer:
terencez
Date:
Sat May 06 11:21:27 2017 +0000
Revision:
14:ec9e195830ff
Parent:
3:a280069151ac
First compile version, registration success but could not handle request.

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();
terencez 14:ec9e195830ff 127 if (tv_sec != NULL)
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 {
terencez 14:ec9e195830ff 183 //server->sessionH = lwm2m_connect_server(server->secObjInstID, contextP->userData);
terencez 14:ec9e195830ff 184 printf("server->sessionH == NULL\n");
terencez 14:ec9e195830ff 185 return COAP_500_INTERNAL_SERVER_ERROR;
terence zhang 3:a280069151ac 186 }
terence zhang 3:a280069151ac 187
terence zhang 3:a280069151ac 188 if (NULL == server->sessionH) return COAP_503_SERVICE_UNAVAILABLE;
terence zhang 3:a280069151ac 189
terence zhang 3:a280069151ac 190 transaction = transaction_new(server->sessionH, COAP_POST, NULL, NULL, contextP->nextMID++, 4, NULL);
terence zhang 3:a280069151ac 191 if (transaction == NULL) return COAP_500_INTERNAL_SERVER_ERROR;
terence zhang 3:a280069151ac 192
terence zhang 3:a280069151ac 193 coap_set_header_uri_path(transaction->message, "/"URI_REGISTRATION_SEGMENT);
terence zhang 3:a280069151ac 194 coap_set_header_uri_query(transaction->message, query);
terence zhang 3:a280069151ac 195 coap_set_header_content_type(transaction->message, LWM2M_CONTENT_LINK);
terence zhang 3:a280069151ac 196 coap_set_payload(transaction->message, payload, payload_length);
terence zhang 3:a280069151ac 197
terence zhang 3:a280069151ac 198 transaction->callback = prv_handleRegistrationReply;
terence zhang 3:a280069151ac 199 transaction->userData = (void *) server;
terence zhang 3:a280069151ac 200
terence zhang 3:a280069151ac 201 contextP->transactionList = (lwm2m_transaction_t *)LWM2M_LIST_ADD(contextP->transactionList, transaction);
terence zhang 3:a280069151ac 202 if (transaction_send(contextP, transaction) != 0) return COAP_500_INTERNAL_SERVER_ERROR;
terence zhang 3:a280069151ac 203
terence zhang 3:a280069151ac 204 server->status = STATE_REG_PENDING;
terence zhang 3:a280069151ac 205
terence zhang 3:a280069151ac 206 return COAP_NO_ERROR;
terence zhang 3:a280069151ac 207 }
terence zhang 3:a280069151ac 208
terence zhang 3:a280069151ac 209 static void prv_handleRegistrationUpdateReply(lwm2m_transaction_t * transacP,
terence zhang 3:a280069151ac 210 void * message)
terence zhang 3:a280069151ac 211 {
terence zhang 3:a280069151ac 212 coap_packet_t * packet = (coap_packet_t *)message;
terence zhang 3:a280069151ac 213 lwm2m_server_t * targetP = (lwm2m_server_t *)(transacP->userData);
terence zhang 3:a280069151ac 214
terence zhang 3:a280069151ac 215 if (targetP->status == STATE_REG_UPDATE_PENDING)
terence zhang 3:a280069151ac 216 {
terence zhang 3:a280069151ac 217 time_t tv_sec = lwm2m_gettime();
terencez 14:ec9e195830ff 218 if (tv_sec != NULL)
terence zhang 3:a280069151ac 219 {
terence zhang 3:a280069151ac 220 targetP->registration = tv_sec;
terence zhang 3:a280069151ac 221 }
terence zhang 3:a280069151ac 222 if (packet != NULL && packet->code == COAP_204_CHANGED)
terence zhang 3:a280069151ac 223 {
terence zhang 3:a280069151ac 224 targetP->status = STATE_REGISTERED;
terence zhang 3:a280069151ac 225 LOG("Registration update successful");
terence zhang 3:a280069151ac 226 }
terence zhang 3:a280069151ac 227 else
terence zhang 3:a280069151ac 228 {
terence zhang 3:a280069151ac 229 targetP->status = STATE_REG_FAILED;
terence zhang 3:a280069151ac 230 LOG("Registration update failed");
terence zhang 3:a280069151ac 231 }
terencez 0:f9d13e09cf11 232 }
terencez 0:f9d13e09cf11 233 }
terencez 0:f9d13e09cf11 234
terence zhang 3:a280069151ac 235 static int prv_updateRegistration(lwm2m_context_t * contextP,
terence zhang 3:a280069151ac 236 lwm2m_server_t * server,
terence zhang 3:a280069151ac 237 bool withObjects)
terencez 0:f9d13e09cf11 238 {
terence zhang 3:a280069151ac 239 lwm2m_transaction_t * transaction;
terence zhang 3:a280069151ac 240 uint8_t payload[512];
terencez 0:f9d13e09cf11 241 int payload_length;
terence zhang 3:a280069151ac 242
terence zhang 3:a280069151ac 243 transaction = transaction_new(server->sessionH, COAP_POST, NULL, NULL, contextP->nextMID++, 4, NULL);
terence zhang 3:a280069151ac 244 if (transaction == NULL) return COAP_500_INTERNAL_SERVER_ERROR;
terence zhang 3:a280069151ac 245
terence zhang 3:a280069151ac 246 coap_set_header_uri_path(transaction->message, server->location);
terence zhang 3:a280069151ac 247
terence zhang 3:a280069151ac 248 if (withObjects == true)
terence zhang 3:a280069151ac 249 {
terence zhang 3:a280069151ac 250 payload_length = object_getRegisterPayload(contextP, payload, sizeof(payload));
terence zhang 3:a280069151ac 251 if (payload_length == 0)
terence zhang 3:a280069151ac 252 {
terence zhang 3:a280069151ac 253 transaction_free(transaction);
terence zhang 3:a280069151ac 254 return COAP_500_INTERNAL_SERVER_ERROR;
terence zhang 3:a280069151ac 255 }
terence zhang 3:a280069151ac 256 coap_set_payload(transaction->message, payload, payload_length);
terence zhang 3:a280069151ac 257 }
terence zhang 3:a280069151ac 258
terence zhang 3:a280069151ac 259 transaction->callback = prv_handleRegistrationUpdateReply;
terence zhang 3:a280069151ac 260 transaction->userData = (void *) server;
terencez 0:f9d13e09cf11 261
terence zhang 3:a280069151ac 262 contextP->transactionList = (lwm2m_transaction_t *)LWM2M_LIST_ADD(contextP->transactionList, transaction);
terence zhang 3:a280069151ac 263
terence zhang 3:a280069151ac 264 if (transaction_send(contextP, transaction) == 0)
terence zhang 3:a280069151ac 265 {
terence zhang 3:a280069151ac 266 server->status = STATE_REG_UPDATE_PENDING;
terence zhang 3:a280069151ac 267 }
terence zhang 3:a280069151ac 268
terence zhang 3:a280069151ac 269 return COAP_NO_ERROR;
terence zhang 3:a280069151ac 270 }
terence zhang 3:a280069151ac 271
terence zhang 3:a280069151ac 272 // update the registration of a given server
terence zhang 3:a280069151ac 273 int lwm2m_update_registration(lwm2m_context_t * contextP,
terence zhang 3:a280069151ac 274 uint16_t shortServerID,
terence zhang 3:a280069151ac 275 bool withObjects)
terence zhang 3:a280069151ac 276 {
terence zhang 3:a280069151ac 277 lwm2m_server_t * targetP;
terence zhang 3:a280069151ac 278 uint8_t result;
terence zhang 3:a280069151ac 279
terence zhang 3:a280069151ac 280 LOG_ARG("State: %s, shortServerID: %d", STR_STATE(contextP->state), shortServerID);
terence zhang 3:a280069151ac 281
terence zhang 3:a280069151ac 282 result = COAP_NO_ERROR;
terencez 0:f9d13e09cf11 283
terencez 0:f9d13e09cf11 284 targetP = contextP->serverList;
terence zhang 3:a280069151ac 285 if (targetP == NULL)
terence zhang 3:a280069151ac 286 {
terence zhang 3:a280069151ac 287 if (object_getServers(contextP) == -1)
terence zhang 3:a280069151ac 288 {
terence zhang 3:a280069151ac 289 LOG("No server found");
terence zhang 3:a280069151ac 290 return COAP_404_NOT_FOUND;
terence zhang 3:a280069151ac 291 }
terence zhang 3:a280069151ac 292 }
terence zhang 3:a280069151ac 293 while (targetP != NULL && result == COAP_NO_ERROR)
terence zhang 3:a280069151ac 294 {
terence zhang 3:a280069151ac 295 if (shortServerID != 0)
terence zhang 3:a280069151ac 296 {
terence zhang 3:a280069151ac 297 if (targetP->shortID == shortServerID)
terence zhang 3:a280069151ac 298 {
terence zhang 3:a280069151ac 299 // found the server, trigger the update transaction
terence zhang 3:a280069151ac 300 if (targetP->status == STATE_REGISTERED
terence zhang 3:a280069151ac 301 || targetP->status == STATE_REG_UPDATE_PENDING)
terence zhang 3:a280069151ac 302 {
terence zhang 3:a280069151ac 303 if (withObjects == true)
terence zhang 3:a280069151ac 304 {
terence zhang 3:a280069151ac 305 targetP->status = STATE_REG_FULL_UPDATE_NEEDED;
terence zhang 3:a280069151ac 306 }
terence zhang 3:a280069151ac 307 else
terence zhang 3:a280069151ac 308 {
terence zhang 3:a280069151ac 309 targetP->status = STATE_REG_UPDATE_NEEDED;
terence zhang 3:a280069151ac 310 }
terence zhang 3:a280069151ac 311 return COAP_NO_ERROR;
terence zhang 3:a280069151ac 312 }
terence zhang 3:a280069151ac 313 else if ((targetP->status == STATE_REG_FULL_UPDATE_NEEDED)
terence zhang 3:a280069151ac 314 || (targetP->status == STATE_REG_UPDATE_NEEDED))
terence zhang 3:a280069151ac 315 {
terence zhang 3:a280069151ac 316 // if REG (FULL) UPDATE is already set, returns COAP_NO_ERROR
terence zhang 3:a280069151ac 317 if (withObjects == true)
terence zhang 3:a280069151ac 318 {
terence zhang 3:a280069151ac 319 targetP->status = STATE_REG_FULL_UPDATE_NEEDED;
terence zhang 3:a280069151ac 320 }
terence zhang 3:a280069151ac 321 return COAP_NO_ERROR;
terence zhang 3:a280069151ac 322 }
terence zhang 3:a280069151ac 323 else
terence zhang 3:a280069151ac 324 {
terence zhang 3:a280069151ac 325 return COAP_400_BAD_REQUEST;
terence zhang 3:a280069151ac 326 }
terence zhang 3:a280069151ac 327 }
terence zhang 3:a280069151ac 328 }
terence zhang 3:a280069151ac 329 else
terence zhang 3:a280069151ac 330 {
terence zhang 3:a280069151ac 331 if (targetP->status == STATE_REGISTERED
terence zhang 3:a280069151ac 332 || targetP->status == STATE_REG_UPDATE_PENDING)
terence zhang 3:a280069151ac 333 {
terence zhang 3:a280069151ac 334 if (withObjects == true)
terence zhang 3:a280069151ac 335 {
terence zhang 3:a280069151ac 336 targetP->status = STATE_REG_FULL_UPDATE_NEEDED;
terence zhang 3:a280069151ac 337 }
terence zhang 3:a280069151ac 338 else
terence zhang 3:a280069151ac 339 {
terence zhang 3:a280069151ac 340 targetP->status = STATE_REG_UPDATE_NEEDED;
terence zhang 3:a280069151ac 341 }
terence zhang 3:a280069151ac 342 }
terence zhang 3:a280069151ac 343 }
terence zhang 3:a280069151ac 344 targetP = targetP->next;
terence zhang 3:a280069151ac 345 }
terence zhang 3:a280069151ac 346
terence zhang 3:a280069151ac 347 if (shortServerID != 0
terence zhang 3:a280069151ac 348 && targetP == NULL)
terence zhang 3:a280069151ac 349 {
terence zhang 3:a280069151ac 350 // no server found
terence zhang 3:a280069151ac 351 result = COAP_404_NOT_FOUND;
terence zhang 3:a280069151ac 352 }
terence zhang 3:a280069151ac 353
terence zhang 3:a280069151ac 354 return result;
terence zhang 3:a280069151ac 355 }
terence zhang 3:a280069151ac 356
terence zhang 3:a280069151ac 357 uint8_t registration_start(lwm2m_context_t * contextP)
terence zhang 3:a280069151ac 358 {
terence zhang 3:a280069151ac 359 lwm2m_server_t * targetP;
terence zhang 3:a280069151ac 360 uint8_t result;
terence zhang 3:a280069151ac 361
terence zhang 3:a280069151ac 362 LOG_ARG("State: %s", STR_STATE(contextP->state));
terence zhang 3:a280069151ac 363
terence zhang 3:a280069151ac 364 result = COAP_NO_ERROR;
terence zhang 3:a280069151ac 365
terence zhang 3:a280069151ac 366 targetP = contextP->serverList;
terence zhang 3:a280069151ac 367 while (targetP != NULL && result == COAP_NO_ERROR)
terence zhang 3:a280069151ac 368 {
terence zhang 3:a280069151ac 369 if (targetP->status == STATE_DEREGISTERED
terence zhang 3:a280069151ac 370 || targetP->status == STATE_REG_FAILED)
terence zhang 3:a280069151ac 371 {
terence zhang 3:a280069151ac 372 result = prv_register(contextP, targetP);
terence zhang 3:a280069151ac 373 }
terence zhang 3:a280069151ac 374 targetP = targetP->next;
terence zhang 3:a280069151ac 375 }
terence zhang 3:a280069151ac 376
terence zhang 3:a280069151ac 377 return result;
terence zhang 3:a280069151ac 378 }
terence zhang 3:a280069151ac 379
terence zhang 3:a280069151ac 380
terence zhang 3:a280069151ac 381 /*
terence zhang 3:a280069151ac 382 * Returns STATE_REG_PENDING if at least one registration is still pending
terence zhang 3:a280069151ac 383 * Returns STATE_REGISTERED if no registration is pending and there is at least one server the client is registered to
terence zhang 3:a280069151ac 384 * Returns STATE_REG_FAILED if all registration failed.
terence zhang 3:a280069151ac 385 */
terence zhang 3:a280069151ac 386 lwm2m_status_t registration_getStatus(lwm2m_context_t * contextP)
terence zhang 3:a280069151ac 387 {
terence zhang 3:a280069151ac 388 lwm2m_server_t * targetP;
terence zhang 3:a280069151ac 389 lwm2m_status_t reg_status;
terence zhang 3:a280069151ac 390
terence zhang 3:a280069151ac 391 LOG_ARG("State: %s", STR_STATE(contextP->state));
terence zhang 3:a280069151ac 392
terence zhang 3:a280069151ac 393 targetP = contextP->serverList;
terence zhang 3:a280069151ac 394 reg_status = STATE_REG_FAILED;
terence zhang 3:a280069151ac 395
terencez 0:f9d13e09cf11 396 while (targetP != NULL)
terencez 0:f9d13e09cf11 397 {
terence zhang 3:a280069151ac 398 LOG_ARG("targetP->status: %s", STR_STATUS(targetP->status));
terence zhang 3:a280069151ac 399 switch (targetP->status)
terence zhang 3:a280069151ac 400 {
terence zhang 3:a280069151ac 401 case STATE_REGISTERED:
terence zhang 3:a280069151ac 402 case STATE_REG_UPDATE_NEEDED:
terence zhang 3:a280069151ac 403 case STATE_REG_FULL_UPDATE_NEEDED:
terence zhang 3:a280069151ac 404 case STATE_REG_UPDATE_PENDING:
terence zhang 3:a280069151ac 405 if (reg_status == STATE_REG_FAILED)
terence zhang 3:a280069151ac 406 {
terence zhang 3:a280069151ac 407 reg_status = STATE_REGISTERED;
terence zhang 3:a280069151ac 408 }
terence zhang 3:a280069151ac 409 break;
terencez 0:f9d13e09cf11 410
terence zhang 3:a280069151ac 411 case STATE_REG_PENDING:
terence zhang 3:a280069151ac 412 reg_status = STATE_REG_PENDING;
terence zhang 3:a280069151ac 413 break;
terence zhang 3:a280069151ac 414
terence zhang 3:a280069151ac 415 case STATE_REG_FAILED:
terence zhang 3:a280069151ac 416 case STATE_DEREG_PENDING:
terence zhang 3:a280069151ac 417 case STATE_DEREGISTERED:
terence zhang 3:a280069151ac 418 default:
terence zhang 3:a280069151ac 419 break;
terencez 0:f9d13e09cf11 420 }
terence zhang 3:a280069151ac 421 LOG_ARG("reg_status: %s", STR_STATUS(reg_status));
terencez 0:f9d13e09cf11 422
terencez 0:f9d13e09cf11 423 targetP = targetP->next;
terencez 0:f9d13e09cf11 424 }
terencez 0:f9d13e09cf11 425
terence zhang 3:a280069151ac 426 return reg_status;
terencez 0:f9d13e09cf11 427 }
terencez 0:f9d13e09cf11 428
terencez 0:f9d13e09cf11 429 static void prv_handleDeregistrationReply(lwm2m_transaction_t * transacP,
terence zhang 3:a280069151ac 430 void * message)
terencez 0:f9d13e09cf11 431 {
terencez 0:f9d13e09cf11 432 lwm2m_server_t * targetP;
terencez 0:f9d13e09cf11 433
terence zhang 3:a280069151ac 434 targetP = (lwm2m_server_t *)(transacP->userData);
terence zhang 3:a280069151ac 435 if (NULL != targetP)
terencez 0:f9d13e09cf11 436 {
terence zhang 3:a280069151ac 437 if (targetP->status == STATE_DEREG_PENDING)
terencez 0:f9d13e09cf11 438 {
terence zhang 3:a280069151ac 439 targetP->status = STATE_DEREGISTERED;
terencez 0:f9d13e09cf11 440 }
terencez 0:f9d13e09cf11 441 }
terencez 0:f9d13e09cf11 442 }
terencez 0:f9d13e09cf11 443
terencez 0:f9d13e09cf11 444 void registration_deregister(lwm2m_context_t * contextP,
terencez 0:f9d13e09cf11 445 lwm2m_server_t * serverP)
terencez 0:f9d13e09cf11 446 {
terence zhang 3:a280069151ac 447 lwm2m_transaction_t * transaction;
terence zhang 3:a280069151ac 448
terence zhang 3:a280069151ac 449 LOG_ARG("State: %s, serverP->status: %s", STR_STATE(contextP->state), STR_STATUS(serverP->status));
terencez 0:f9d13e09cf11 450
terence zhang 3:a280069151ac 451 if (serverP->status == STATE_DEREGISTERED
terence zhang 3:a280069151ac 452 || serverP->status == STATE_REG_PENDING
terence zhang 3:a280069151ac 453 || serverP->status == STATE_DEREG_PENDING
terence zhang 3:a280069151ac 454 || serverP->status == STATE_REG_FAILED
terence zhang 3:a280069151ac 455 || serverP->location == NULL)
terence zhang 3:a280069151ac 456 {
terence zhang 3:a280069151ac 457 return;
terence zhang 3:a280069151ac 458 }
terencez 0:f9d13e09cf11 459
terence zhang 3:a280069151ac 460 transaction = transaction_new(serverP->sessionH, COAP_DELETE, NULL, NULL, contextP->nextMID++, 4, NULL);
terencez 0:f9d13e09cf11 461 if (transaction == NULL) return;
terencez 0:f9d13e09cf11 462
terencez 0:f9d13e09cf11 463 coap_set_header_uri_path(transaction->message, serverP->location);
terencez 0:f9d13e09cf11 464
terencez 0:f9d13e09cf11 465 transaction->callback = prv_handleDeregistrationReply;
terencez 0:f9d13e09cf11 466 transaction->userData = (void *) contextP;
terencez 0:f9d13e09cf11 467
terencez 0:f9d13e09cf11 468 contextP->transactionList = (lwm2m_transaction_t *)LWM2M_LIST_ADD(contextP->transactionList, transaction);
terencez 0:f9d13e09cf11 469 if (transaction_send(contextP, transaction) == 0)
terencez 0:f9d13e09cf11 470 {
terence zhang 3:a280069151ac 471 serverP->status = STATE_DEREG_PENDING;
terencez 0:f9d13e09cf11 472 }
terencez 0:f9d13e09cf11 473 }
terencez 0:f9d13e09cf11 474 #endif
terencez 0:f9d13e09cf11 475
terencez 0:f9d13e09cf11 476 #ifdef LWM2M_SERVER_MODE
terencez 0:f9d13e09cf11 477 static void prv_freeClientObjectList(lwm2m_client_object_t * objects)
terencez 0:f9d13e09cf11 478 {
terencez 0:f9d13e09cf11 479 while (objects != NULL)
terencez 0:f9d13e09cf11 480 {
terencez 0:f9d13e09cf11 481 lwm2m_client_object_t * objP;
terencez 0:f9d13e09cf11 482
terencez 0:f9d13e09cf11 483 while (objects->instanceList != NULL)
terencez 0:f9d13e09cf11 484 {
terencez 0:f9d13e09cf11 485 lwm2m_list_t * target;
terencez 0:f9d13e09cf11 486
terencez 0:f9d13e09cf11 487 target = objects->instanceList;
terencez 0:f9d13e09cf11 488 objects->instanceList = objects->instanceList->next;
terencez 0:f9d13e09cf11 489 lwm2m_free(target);
terencez 0:f9d13e09cf11 490 }
terencez 0:f9d13e09cf11 491
terencez 0:f9d13e09cf11 492 objP = objects;
terencez 0:f9d13e09cf11 493 objects = objects->next;
terencez 0:f9d13e09cf11 494 lwm2m_free(objP);
terencez 0:f9d13e09cf11 495 }
terencez 0:f9d13e09cf11 496 }
terencez 0:f9d13e09cf11 497
terence zhang 3:a280069151ac 498 static int prv_getParameters(multi_option_t * query,
terence zhang 3:a280069151ac 499 char ** nameP,
terence zhang 3:a280069151ac 500 uint32_t * lifetimeP,
terence zhang 3:a280069151ac 501 char ** msisdnP,
terence zhang 3:a280069151ac 502 lwm2m_binding_t * bindingP,
terence zhang 3:a280069151ac 503 char ** versionP)
terence zhang 3:a280069151ac 504 {
terence zhang 3:a280069151ac 505 *nameP = NULL;
terence zhang 3:a280069151ac 506 *lifetimeP = 0;
terence zhang 3:a280069151ac 507 *msisdnP = NULL;
terence zhang 3:a280069151ac 508 *bindingP = BINDING_UNKNOWN;
terence zhang 3:a280069151ac 509 *versionP = NULL;
terence zhang 3:a280069151ac 510
terence zhang 3:a280069151ac 511 while (query != NULL)
terence zhang 3:a280069151ac 512 {
terence zhang 3:a280069151ac 513 if (lwm2m_strncmp((char *)query->data, QUERY_NAME, QUERY_NAME_LEN) == 0)
terence zhang 3:a280069151ac 514 {
terence zhang 3:a280069151ac 515 if (*nameP != NULL) goto error;
terence zhang 3:a280069151ac 516 if (query->len == QUERY_NAME_LEN) goto error;
terence zhang 3:a280069151ac 517
terence zhang 3:a280069151ac 518 *nameP = (char *)lwm2m_malloc(query->len - QUERY_NAME_LEN + 1);
terence zhang 3:a280069151ac 519 if (*nameP != NULL)
terence zhang 3:a280069151ac 520 {
terence zhang 3:a280069151ac 521 memcpy(*nameP, query->data + QUERY_NAME_LEN, query->len - QUERY_NAME_LEN);
terence zhang 3:a280069151ac 522 (*nameP)[query->len - QUERY_NAME_LEN] = 0;
terence zhang 3:a280069151ac 523 }
terence zhang 3:a280069151ac 524 }
terence zhang 3:a280069151ac 525 else if (lwm2m_strncmp((char *)query->data, QUERY_SMS, QUERY_SMS_LEN) == 0)
terence zhang 3:a280069151ac 526 {
terence zhang 3:a280069151ac 527 if (*msisdnP != NULL) goto error;
terence zhang 3:a280069151ac 528 if (query->len == QUERY_SMS_LEN) goto error;
terence zhang 3:a280069151ac 529
terence zhang 3:a280069151ac 530 *msisdnP = (char *)lwm2m_malloc(query->len - QUERY_SMS_LEN + 1);
terence zhang 3:a280069151ac 531 if (*msisdnP != NULL)
terence zhang 3:a280069151ac 532 {
terence zhang 3:a280069151ac 533 memcpy(*msisdnP, query->data + QUERY_SMS_LEN, query->len - QUERY_SMS_LEN);
terence zhang 3:a280069151ac 534 (*msisdnP)[query->len - QUERY_SMS_LEN] = 0;
terence zhang 3:a280069151ac 535 }
terence zhang 3:a280069151ac 536 }
terence zhang 3:a280069151ac 537 else if (lwm2m_strncmp((char *)query->data, QUERY_LIFETIME, QUERY_LIFETIME_LEN) == 0)
terence zhang 3:a280069151ac 538 {
terence zhang 3:a280069151ac 539 int i;
terence zhang 3:a280069151ac 540
terence zhang 3:a280069151ac 541 if (*lifetimeP != 0) goto error;
terence zhang 3:a280069151ac 542 if (query->len == QUERY_LIFETIME_LEN) goto error;
terence zhang 3:a280069151ac 543
terence zhang 3:a280069151ac 544 for (i = QUERY_LIFETIME_LEN ; i < query->len ; i++)
terence zhang 3:a280069151ac 545 {
terence zhang 3:a280069151ac 546 if (query->data[i] < '0' || query->data[i] > '9') goto error;
terence zhang 3:a280069151ac 547 *lifetimeP = (*lifetimeP * 10) + (query->data[i] - '0');
terence zhang 3:a280069151ac 548 }
terence zhang 3:a280069151ac 549 }
terence zhang 3:a280069151ac 550 else if (lwm2m_strncmp((char *)query->data, QUERY_VERSION, QUERY_VERSION_LEN) == 0)
terence zhang 3:a280069151ac 551 {
terence zhang 3:a280069151ac 552 if (*versionP != NULL) goto error;
terence zhang 3:a280069151ac 553 if (query->len == QUERY_VERSION_LEN) goto error;
terence zhang 3:a280069151ac 554
terence zhang 3:a280069151ac 555 *versionP = (char *)lwm2m_malloc(query->len - QUERY_VERSION_LEN + 1);
terence zhang 3:a280069151ac 556 if (*versionP != NULL)
terence zhang 3:a280069151ac 557 {
terence zhang 3:a280069151ac 558 memcpy(*versionP, query->data + QUERY_VERSION_LEN, query->len - QUERY_VERSION_LEN);
terence zhang 3:a280069151ac 559 (*versionP)[query->len - QUERY_VERSION_LEN] = 0;
terence zhang 3:a280069151ac 560 }
terence zhang 3:a280069151ac 561 }
terence zhang 3:a280069151ac 562 else if (lwm2m_strncmp((char *)query->data, QUERY_BINDING, QUERY_BINDING_LEN) == 0)
terence zhang 3:a280069151ac 563 {
terence zhang 3:a280069151ac 564 if (*bindingP != BINDING_UNKNOWN) goto error;
terence zhang 3:a280069151ac 565 if (query->len == QUERY_BINDING_LEN) goto error;
terence zhang 3:a280069151ac 566
terence zhang 3:a280069151ac 567 *bindingP = utils_stringToBinding(query->data + QUERY_BINDING_LEN, query->len - QUERY_BINDING_LEN);
terence zhang 3:a280069151ac 568 }
terence zhang 3:a280069151ac 569 query = query->next;
terence zhang 3:a280069151ac 570 }
terence zhang 3:a280069151ac 571
terence zhang 3:a280069151ac 572 return 0;
terence zhang 3:a280069151ac 573
terence zhang 3:a280069151ac 574 error:
terence zhang 3:a280069151ac 575 if (*nameP != NULL) lwm2m_free(*nameP);
terence zhang 3:a280069151ac 576 if (*msisdnP != NULL) lwm2m_free(*msisdnP);
terence zhang 3:a280069151ac 577 if (*versionP != NULL) lwm2m_free(*versionP);
terence zhang 3:a280069151ac 578
terence zhang 3:a280069151ac 579 return -1;
terence zhang 3:a280069151ac 580 }
terence zhang 3:a280069151ac 581
terence zhang 3:a280069151ac 582 static uint16_t prv_splitLinkAttribute(uint8_t * data,
terence zhang 3:a280069151ac 583 uint16_t length,
terence zhang 3:a280069151ac 584 uint16_t * keyStart,
terence zhang 3:a280069151ac 585 uint16_t * keyLength,
terence zhang 3:a280069151ac 586 uint16_t * valueStart,
terence zhang 3:a280069151ac 587 uint16_t * valueLength)
terence zhang 3:a280069151ac 588 {
terence zhang 3:a280069151ac 589 uint16_t index;
terence zhang 3:a280069151ac 590 uint16_t end;
terence zhang 3:a280069151ac 591
terence zhang 3:a280069151ac 592 index = 0;
terence zhang 3:a280069151ac 593 while (index < length && data[index] == ' ') index++;
terence zhang 3:a280069151ac 594 if (index == length) return 0;
terence zhang 3:a280069151ac 595
terence zhang 3:a280069151ac 596 if (data[index] == REG_ATTR_SEPARATOR)
terence zhang 3:a280069151ac 597 {
terence zhang 3:a280069151ac 598 index++;
terence zhang 3:a280069151ac 599 }
terence zhang 3:a280069151ac 600 if (index == length) return 0;
terence zhang 3:a280069151ac 601
terence zhang 3:a280069151ac 602 *keyStart = index;
terence zhang 3:a280069151ac 603
terence zhang 3:a280069151ac 604 while (index < length && data[index] != REG_ATTR_EQUALS) index++;
terence zhang 3:a280069151ac 605 if (index == *keyStart || index == length) return 0;
terence zhang 3:a280069151ac 606
terence zhang 3:a280069151ac 607 *keyLength = index - *keyStart;
terence zhang 3:a280069151ac 608
terence zhang 3:a280069151ac 609 index++;
terence zhang 3:a280069151ac 610 while (index < length && data[index] == ' ') index++;
terence zhang 3:a280069151ac 611 if (index == length) return 0;
terence zhang 3:a280069151ac 612
terence zhang 3:a280069151ac 613 *valueStart = index;
terence zhang 3:a280069151ac 614
terence zhang 3:a280069151ac 615 while (index < length && data[index] != REG_ATTR_SEPARATOR) index++;
terence zhang 3:a280069151ac 616 end = index;
terence zhang 3:a280069151ac 617
terence zhang 3:a280069151ac 618 index--;
terence zhang 3:a280069151ac 619 while (index > *valueStart && data[index] == ' ') index--;
terence zhang 3:a280069151ac 620 if (index == *valueStart) return 0;
terence zhang 3:a280069151ac 621
terence zhang 3:a280069151ac 622 *valueLength = index - *valueStart + 1;
terence zhang 3:a280069151ac 623
terence zhang 3:a280069151ac 624 return end;
terence zhang 3:a280069151ac 625 }
terence zhang 3:a280069151ac 626
terence zhang 3:a280069151ac 627 static int prv_parseLinkAttributes(uint8_t * data,
terence zhang 3:a280069151ac 628 uint16_t length,
terence zhang 3:a280069151ac 629 bool * supportJSON,
terence zhang 3:a280069151ac 630 char ** altPath)
terencez 0:f9d13e09cf11 631 {
terence zhang 3:a280069151ac 632 uint16_t index;
terence zhang 3:a280069151ac 633 uint16_t pathStart;
terence zhang 3:a280069151ac 634 uint16_t pathLength;
terence zhang 3:a280069151ac 635 bool isValid;
terence zhang 3:a280069151ac 636
terence zhang 3:a280069151ac 637 isValid = false;
terence zhang 3:a280069151ac 638
terence zhang 3:a280069151ac 639 // Expecting application/link-format (RFC6690)
terence zhang 3:a280069151ac 640 // leading space were removed before. Remove trailing spaces.
terence zhang 3:a280069151ac 641 while (length > 0 && data[length-1] == ' ') length--;
terence zhang 3:a280069151ac 642
terence zhang 3:a280069151ac 643 // strip open tag
terence zhang 3:a280069151ac 644 if (length >= 2 && data[0] == REG_URI_START)
terence zhang 3:a280069151ac 645 {
terence zhang 3:a280069151ac 646 data += 1;
terence zhang 3:a280069151ac 647 length -= 1;
terence zhang 3:a280069151ac 648 }
terence zhang 3:a280069151ac 649 else
terence zhang 3:a280069151ac 650 {
terence zhang 3:a280069151ac 651 return 0;
terence zhang 3:a280069151ac 652 }
terence zhang 3:a280069151ac 653
terence zhang 3:a280069151ac 654 pathStart = 0;
terence zhang 3:a280069151ac 655 index = length - 1;
terence zhang 3:a280069151ac 656 while (index > 0 && data[index] != REG_URI_END) index--;
terence zhang 3:a280069151ac 657 // link attributes are required
terence zhang 3:a280069151ac 658 if (index == 0 || index == length - 1) return 0;
terence zhang 3:a280069151ac 659
terence zhang 3:a280069151ac 660 // If there is a preceding /, remove it
terence zhang 3:a280069151ac 661 if (data[pathStart] == '/')
terence zhang 3:a280069151ac 662 {
terence zhang 3:a280069151ac 663 pathStart += 1;
terence zhang 3:a280069151ac 664 }
terence zhang 3:a280069151ac 665 pathLength = index - pathStart;
terence zhang 3:a280069151ac 666
terence zhang 3:a280069151ac 667 index++;
terence zhang 3:a280069151ac 668 if (index >= length || data[index] != REG_ATTR_SEPARATOR) return 0;
terence zhang 3:a280069151ac 669 index++;
terence zhang 3:a280069151ac 670
terence zhang 3:a280069151ac 671 while (index < length)
terence zhang 3:a280069151ac 672 {
terence zhang 3:a280069151ac 673 uint16_t result;
terence zhang 3:a280069151ac 674 uint16_t keyStart;
terence zhang 3:a280069151ac 675 uint16_t keyLength;
terence zhang 3:a280069151ac 676 uint16_t valueStart;
terence zhang 3:a280069151ac 677 uint16_t valueLength;
terence zhang 3:a280069151ac 678
terence zhang 3:a280069151ac 679 result = prv_splitLinkAttribute(data + index, length - index, &keyStart, &keyLength, &valueStart, &valueLength);
terence zhang 3:a280069151ac 680 if (result == 0) return 0;
terence zhang 3:a280069151ac 681
terence zhang 3:a280069151ac 682 if (keyLength == REG_ATTR_TYPE_KEY_LEN
terence zhang 3:a280069151ac 683 && 0 == lwm2m_strncmp(REG_ATTR_TYPE_KEY, data + index + keyStart, keyLength))
terence zhang 3:a280069151ac 684 {
terence zhang 3:a280069151ac 685 if (isValid == true) return 0; // declared twice
terence zhang 3:a280069151ac 686 if (valueLength != REG_ATTR_TYPE_VALUE_LEN
terence zhang 3:a280069151ac 687 || 0 != lwm2m_strncmp(REG_ATTR_TYPE_VALUE, data + index + valueStart, valueLength))
terence zhang 3:a280069151ac 688 {
terence zhang 3:a280069151ac 689 return 0;
terence zhang 3:a280069151ac 690 }
terence zhang 3:a280069151ac 691 isValid = true;
terence zhang 3:a280069151ac 692 }
terence zhang 3:a280069151ac 693 else if (keyLength == REG_ATTR_CONTENT_KEY_LEN
terence zhang 3:a280069151ac 694 && 0 == lwm2m_strncmp(REG_ATTR_CONTENT_KEY, data + index + keyStart, keyLength))
terence zhang 3:a280069151ac 695 {
terence zhang 3:a280069151ac 696 if (*supportJSON == true) return 0; // declared twice
terence zhang 3:a280069151ac 697 if (valueLength == REG_ATTR_CONTENT_JSON_LEN
terence zhang 3:a280069151ac 698 && 0 == lwm2m_strncmp(REG_ATTR_CONTENT_JSON, data + index + valueStart, valueLength))
terence zhang 3:a280069151ac 699 {
terence zhang 3:a280069151ac 700 *supportJSON = true;
terence zhang 3:a280069151ac 701 }
terence zhang 3:a280069151ac 702 else
terence zhang 3:a280069151ac 703 {
terence zhang 3:a280069151ac 704 return 0;
terence zhang 3:a280069151ac 705 }
terence zhang 3:a280069151ac 706 }
terence zhang 3:a280069151ac 707 // else ignore this one
terence zhang 3:a280069151ac 708
terence zhang 3:a280069151ac 709 index += result;
terence zhang 3:a280069151ac 710 }
terence zhang 3:a280069151ac 711
terence zhang 3:a280069151ac 712 if (isValid == false) return 0;
terence zhang 3:a280069151ac 713
terence zhang 3:a280069151ac 714 if (pathLength != 0)
terence zhang 3:a280069151ac 715 {
terence zhang 3:a280069151ac 716 *altPath = (char *)lwm2m_malloc(pathLength + 1);
terence zhang 3:a280069151ac 717 if (*altPath == NULL) return 0;
terence zhang 3:a280069151ac 718 memcpy(*altPath, data + pathStart, pathLength);
terence zhang 3:a280069151ac 719 (*altPath)[pathLength] = 0;
terence zhang 3:a280069151ac 720 }
terence zhang 3:a280069151ac 721
terence zhang 3:a280069151ac 722 return 1;
terence zhang 3:a280069151ac 723 }
terence zhang 3:a280069151ac 724
terence zhang 3:a280069151ac 725 static int prv_getId(uint8_t * data,
terence zhang 3:a280069151ac 726 uint16_t length,
terence zhang 3:a280069151ac 727 uint16_t * objId,
terence zhang 3:a280069151ac 728 uint16_t * instanceId)
terence zhang 3:a280069151ac 729 {
terence zhang 3:a280069151ac 730 int value;
terence zhang 3:a280069151ac 731 uint16_t limit;
terence zhang 3:a280069151ac 732
terence zhang 3:a280069151ac 733 // Expecting application/link-format (RFC6690)
terence zhang 3:a280069151ac 734 // leading space were removed before. Remove trailing spaces.
terence zhang 3:a280069151ac 735 while (length > 0 && data[length-1] == ' ') length--;
terence zhang 3:a280069151ac 736
terence zhang 3:a280069151ac 737 // strip open and close tags
terence zhang 3:a280069151ac 738 if (length >= 1 && data[0] == REG_URI_START && data[length-1] == REG_URI_END)
terence zhang 3:a280069151ac 739 {
terence zhang 3:a280069151ac 740 data += 1;
terence zhang 3:a280069151ac 741 length -= 2;
terence zhang 3:a280069151ac 742 }
terence zhang 3:a280069151ac 743 else
terence zhang 3:a280069151ac 744 {
terence zhang 3:a280069151ac 745 return 0;
terence zhang 3:a280069151ac 746 }
terence zhang 3:a280069151ac 747
terence zhang 3:a280069151ac 748 // If there is a preceding /, remove it
terence zhang 3:a280069151ac 749 if (length >= 1 && data[0] == '/')
terence zhang 3:a280069151ac 750 {
terence zhang 3:a280069151ac 751 data += 1;
terence zhang 3:a280069151ac 752 length -= 1;
terence zhang 3:a280069151ac 753 }
terence zhang 3:a280069151ac 754
terence zhang 3:a280069151ac 755 limit = 0;
terence zhang 3:a280069151ac 756 while (limit < length && data[limit] != '/') limit++;
terence zhang 3:a280069151ac 757 value = uri_getNumber(data, limit);
terence zhang 3:a280069151ac 758 if (value < 0 || value >= LWM2M_MAX_ID) return 0;
terence zhang 3:a280069151ac 759 *objId = value;
terence zhang 3:a280069151ac 760
terence zhang 3:a280069151ac 761 if (limit < length)
terence zhang 3:a280069151ac 762 {
terence zhang 3:a280069151ac 763 limit += 1;
terence zhang 3:a280069151ac 764 data += limit;
terence zhang 3:a280069151ac 765 length -= limit;
terence zhang 3:a280069151ac 766
terence zhang 3:a280069151ac 767 if (length > 0)
terence zhang 3:a280069151ac 768 {
terence zhang 3:a280069151ac 769 value = uri_getNumber(data, length);
terence zhang 3:a280069151ac 770 if (value >= 0 && value < LWM2M_MAX_ID)
terence zhang 3:a280069151ac 771 {
terence zhang 3:a280069151ac 772 *instanceId = value;
terence zhang 3:a280069151ac 773 return 2;
terence zhang 3:a280069151ac 774 }
terence zhang 3:a280069151ac 775 else
terence zhang 3:a280069151ac 776 {
terence zhang 3:a280069151ac 777 return 0;
terence zhang 3:a280069151ac 778 }
terence zhang 3:a280069151ac 779 }
terence zhang 3:a280069151ac 780 }
terence zhang 3:a280069151ac 781
terence zhang 3:a280069151ac 782 return 1;
terence zhang 3:a280069151ac 783 }
terence zhang 3:a280069151ac 784
terence zhang 3:a280069151ac 785 static lwm2m_client_object_t * prv_decodeRegisterPayload(uint8_t * payload,
terence zhang 3:a280069151ac 786 uint16_t payloadLength,
terence zhang 3:a280069151ac 787 bool * supportJSON,
terence zhang 3:a280069151ac 788 char ** altPath)
terence zhang 3:a280069151ac 789 {
terence zhang 3:a280069151ac 790 uint16_t index;
terence zhang 3:a280069151ac 791 lwm2m_client_object_t * objList;
terence zhang 3:a280069151ac 792 bool linkAttrFound;
terence zhang 3:a280069151ac 793
terence zhang 3:a280069151ac 794 *altPath = NULL;
terence zhang 3:a280069151ac 795 *supportJSON = false;
terence zhang 3:a280069151ac 796 objList = NULL;
terence zhang 3:a280069151ac 797 linkAttrFound = false;
terence zhang 3:a280069151ac 798 index = 0;
terence zhang 3:a280069151ac 799
terence zhang 3:a280069151ac 800 while (index <= payloadLength)
terence zhang 3:a280069151ac 801 {
terence zhang 3:a280069151ac 802 uint16_t start;
terence zhang 3:a280069151ac 803 uint16_t length;
terence zhang 3:a280069151ac 804 int result;
terence zhang 3:a280069151ac 805 uint16_t id;
terence zhang 3:a280069151ac 806 uint16_t instance;
terence zhang 3:a280069151ac 807
terence zhang 3:a280069151ac 808 while (index < payloadLength && payload[index] == ' ') index++;
terence zhang 3:a280069151ac 809 if (index == payloadLength) break;
terence zhang 3:a280069151ac 810
terence zhang 3:a280069151ac 811 start = index;
terence zhang 3:a280069151ac 812 while (index < payloadLength && payload[index] != REG_DELIMITER) index++;
terence zhang 3:a280069151ac 813 length = index - start;
terence zhang 3:a280069151ac 814
terence zhang 3:a280069151ac 815 result = prv_getId(payload + start, length, &id, &instance);
terence zhang 3:a280069151ac 816 if (result != 0)
terence zhang 3:a280069151ac 817 {
terence zhang 3:a280069151ac 818 lwm2m_client_object_t * objectP;
terence zhang 3:a280069151ac 819
terence zhang 3:a280069151ac 820 objectP = (lwm2m_client_object_t *)lwm2m_list_find((lwm2m_list_t *)objList, id);
terence zhang 3:a280069151ac 821 if (objectP == NULL)
terence zhang 3:a280069151ac 822 {
terence zhang 3:a280069151ac 823 objectP = (lwm2m_client_object_t *)lwm2m_malloc(sizeof(lwm2m_client_object_t));
terence zhang 3:a280069151ac 824 memset(objectP, 0, sizeof(lwm2m_client_object_t));
terence zhang 3:a280069151ac 825 if (objectP == NULL) goto error;
terence zhang 3:a280069151ac 826 objectP->id = id;
terence zhang 3:a280069151ac 827 objList = (lwm2m_client_object_t *)LWM2M_LIST_ADD(objList, objectP);
terence zhang 3:a280069151ac 828 }
terence zhang 3:a280069151ac 829 if (result == 2)
terence zhang 3:a280069151ac 830 {
terence zhang 3:a280069151ac 831 lwm2m_list_t * instanceP;
terence zhang 3:a280069151ac 832
terence zhang 3:a280069151ac 833 instanceP = lwm2m_list_find(objectP->instanceList, instance);
terence zhang 3:a280069151ac 834 if (instanceP == NULL)
terence zhang 3:a280069151ac 835 {
terence zhang 3:a280069151ac 836 instanceP = (lwm2m_list_t *)lwm2m_malloc(sizeof(lwm2m_list_t));
terence zhang 3:a280069151ac 837 memset(instanceP, 0, sizeof(lwm2m_list_t));
terence zhang 3:a280069151ac 838 instanceP->id = instance;
terence zhang 3:a280069151ac 839 objectP->instanceList = LWM2M_LIST_ADD(objectP->instanceList, instanceP);
terence zhang 3:a280069151ac 840 }
terence zhang 3:a280069151ac 841 }
terence zhang 3:a280069151ac 842 }
terence zhang 3:a280069151ac 843 else if (linkAttrFound == false)
terence zhang 3:a280069151ac 844 {
terence zhang 3:a280069151ac 845 result = prv_parseLinkAttributes(payload + start, length, supportJSON, altPath);
terence zhang 3:a280069151ac 846 if (result == 0) goto error;
terence zhang 3:a280069151ac 847
terence zhang 3:a280069151ac 848 linkAttrFound = true;
terence zhang 3:a280069151ac 849 }
terence zhang 3:a280069151ac 850 else goto error;
terence zhang 3:a280069151ac 851
terence zhang 3:a280069151ac 852 index++;
terence zhang 3:a280069151ac 853 }
terence zhang 3:a280069151ac 854
terence zhang 3:a280069151ac 855 return objList;
terence zhang 3:a280069151ac 856
terence zhang 3:a280069151ac 857 error:
terence zhang 3:a280069151ac 858 if (*altPath != NULL)
terence zhang 3:a280069151ac 859 {
terence zhang 3:a280069151ac 860 lwm2m_free(*altPath);
terence zhang 3:a280069151ac 861 *altPath = NULL;
terence zhang 3:a280069151ac 862 }
terence zhang 3:a280069151ac 863 prv_freeClientObjectList(objList);
terence zhang 3:a280069151ac 864
terence zhang 3:a280069151ac 865 return NULL;
terence zhang 3:a280069151ac 866 }
terence zhang 3:a280069151ac 867
terence zhang 3:a280069151ac 868 static lwm2m_client_t * prv_getClientByName(lwm2m_context_t * contextP,
terence zhang 3:a280069151ac 869 char * name)
terence zhang 3:a280069151ac 870 {
terence zhang 3:a280069151ac 871 lwm2m_client_t * targetP;
terence zhang 3:a280069151ac 872
terence zhang 3:a280069151ac 873 targetP = contextP->clientList;
terence zhang 3:a280069151ac 874 while (targetP != NULL && strcmp(name, targetP->name) != 0)
terence zhang 3:a280069151ac 875 {
terence zhang 3:a280069151ac 876 targetP = targetP->next;
terence zhang 3:a280069151ac 877 }
terence zhang 3:a280069151ac 878
terence zhang 3:a280069151ac 879 return targetP;
terence zhang 3:a280069151ac 880 }
terence zhang 3:a280069151ac 881
terence zhang 3:a280069151ac 882 void registration_freeClient(lwm2m_client_t * clientP)
terence zhang 3:a280069151ac 883 {
terence zhang 3:a280069151ac 884 LOG("Entering");
terencez 0:f9d13e09cf11 885 if (clientP->name != NULL) lwm2m_free(clientP->name);
terencez 0:f9d13e09cf11 886 if (clientP->msisdn != NULL) lwm2m_free(clientP->msisdn);
terence zhang 3:a280069151ac 887 if (clientP->altPath != NULL) lwm2m_free(clientP->altPath);
terencez 0:f9d13e09cf11 888 prv_freeClientObjectList(clientP->objectList);
terencez 0:f9d13e09cf11 889 while(clientP->observationList != NULL)
terencez 0:f9d13e09cf11 890 {
terencez 0:f9d13e09cf11 891 lwm2m_observation_t * targetP;
terencez 0:f9d13e09cf11 892
terencez 0:f9d13e09cf11 893 targetP = clientP->observationList;
terencez 0:f9d13e09cf11 894 clientP->observationList = clientP->observationList->next;
terencez 0:f9d13e09cf11 895 lwm2m_free(targetP);
terencez 0:f9d13e09cf11 896 }
terencez 0:f9d13e09cf11 897 lwm2m_free(clientP);
terencez 0:f9d13e09cf11 898 }
terencez 0:f9d13e09cf11 899
terencez 0:f9d13e09cf11 900 static int prv_getLocationString(uint16_t id,
terencez 0:f9d13e09cf11 901 char location[MAX_LOCATION_LENGTH])
terencez 0:f9d13e09cf11 902 {
terence zhang 3:a280069151ac 903 int index;
terencez 0:f9d13e09cf11 904 int result;
terencez 0:f9d13e09cf11 905
terencez 0:f9d13e09cf11 906 memset(location, 0, MAX_LOCATION_LENGTH);
terencez 0:f9d13e09cf11 907
terence zhang 3:a280069151ac 908 result = utils_stringCopy(location, MAX_LOCATION_LENGTH, "/"URI_REGISTRATION_SEGMENT"/");
terence zhang 3:a280069151ac 909 if (result < 0) return 0;
terence zhang 3:a280069151ac 910 index = result;
terencez 0:f9d13e09cf11 911
terence zhang 3:a280069151ac 912 result = utils_intCopy(location + index, MAX_LOCATION_LENGTH - index, id);
terence zhang 3:a280069151ac 913 if (result < 0) return 0;
terence zhang 3:a280069151ac 914
terence zhang 3:a280069151ac 915 return index + result;
terencez 0:f9d13e09cf11 916 }
terencez 0:f9d13e09cf11 917
terence zhang 3:a280069151ac 918 coap_status_t registration_handleRequest(lwm2m_context_t * contextP,
terencez 0:f9d13e09cf11 919 lwm2m_uri_t * uriP,
terencez 0:f9d13e09cf11 920 void * fromSessionH,
terencez 0:f9d13e09cf11 921 coap_packet_t * message,
terencez 0:f9d13e09cf11 922 coap_packet_t * response)
terencez 0:f9d13e09cf11 923 {
terencez 0:f9d13e09cf11 924 coap_status_t result;
terence zhang 3:a280069151ac 925 time_t tv_sec;
terencez 0:f9d13e09cf11 926
terence zhang 3:a280069151ac 927 LOG_URI(uriP);
terence zhang 3:a280069151ac 928 tv_sec = lwm2m_gettime();
terence zhang 3:a280069151ac 929 if (tv_sec < 0) return COAP_500_INTERNAL_SERVER_ERROR;
terencez 0:f9d13e09cf11 930
terencez 0:f9d13e09cf11 931 switch(message->code)
terencez 0:f9d13e09cf11 932 {
terencez 0:f9d13e09cf11 933 case COAP_POST:
terencez 0:f9d13e09cf11 934 {
terencez 0:f9d13e09cf11 935 char * name = NULL;
terencez 0:f9d13e09cf11 936 uint32_t lifetime;
terencez 0:f9d13e09cf11 937 char * msisdn;
terence zhang 3:a280069151ac 938 char * altPath;
terence zhang 3:a280069151ac 939 char * version;
terencez 0:f9d13e09cf11 940 lwm2m_binding_t binding;
terencez 0:f9d13e09cf11 941 lwm2m_client_object_t * objects;
terence zhang 3:a280069151ac 942 bool supportJSON;
terencez 0:f9d13e09cf11 943 lwm2m_client_t * clientP;
terencez 0:f9d13e09cf11 944 char location[MAX_LOCATION_LENGTH];
terencez 0:f9d13e09cf11 945
terence zhang 3:a280069151ac 946 if (0 != prv_getParameters(message->uri_query, &name, &lifetime, &msisdn, &binding, &version))
terence zhang 3:a280069151ac 947 {
terence zhang 3:a280069151ac 948 return COAP_400_BAD_REQUEST;
terence zhang 3:a280069151ac 949 }
terence zhang 3:a280069151ac 950 if (message->content_type != LWM2M_CONTENT_LINK
terence zhang 3:a280069151ac 951 && message->content_type != LWM2M_CONTENT_TEXT)
terencez 0:f9d13e09cf11 952 {
terencez 0:f9d13e09cf11 953 return COAP_400_BAD_REQUEST;
terencez 0:f9d13e09cf11 954 }
terence zhang 3:a280069151ac 955
terence zhang 3:a280069151ac 956 objects = prv_decodeRegisterPayload(message->payload, message->payload_len, &supportJSON, &altPath);
terence zhang 3:a280069151ac 957
terence zhang 3:a280069151ac 958 switch (uriP->flag & LWM2M_URI_MASK_ID)
terencez 0:f9d13e09cf11 959 {
terence zhang 3:a280069151ac 960 case 0:
terence zhang 3:a280069151ac 961 // Register operation
terence zhang 3:a280069151ac 962 // Version is mandatory
terence zhang 3:a280069151ac 963 if (version == NULL)
terence zhang 3:a280069151ac 964 {
terence zhang 3:a280069151ac 965 if (name != NULL) lwm2m_free(name);
terence zhang 3:a280069151ac 966 if (msisdn != NULL) lwm2m_free(msisdn);
terence zhang 3:a280069151ac 967 return COAP_400_BAD_REQUEST;
terence zhang 3:a280069151ac 968 }
terence zhang 3:a280069151ac 969 // Endpoint client name is mandatory
terence zhang 3:a280069151ac 970 if (name == NULL)
terence zhang 3:a280069151ac 971 {
terence zhang 3:a280069151ac 972 lwm2m_free(version);
terence zhang 3:a280069151ac 973 if (msisdn != NULL) lwm2m_free(msisdn);
terence zhang 3:a280069151ac 974 return COAP_400_BAD_REQUEST;
terence zhang 3:a280069151ac 975 }
terence zhang 3:a280069151ac 976 // Object list is mandatory
terence zhang 3:a280069151ac 977 if (objects == NULL)
terence zhang 3:a280069151ac 978 {
terence zhang 3:a280069151ac 979 lwm2m_free(version);
terence zhang 3:a280069151ac 980 lwm2m_free(name);
terence zhang 3:a280069151ac 981 if (msisdn != NULL) lwm2m_free(msisdn);
terence zhang 3:a280069151ac 982 return COAP_400_BAD_REQUEST;
terence zhang 3:a280069151ac 983 }
terence zhang 3:a280069151ac 984 // version must be 1.0
terence zhang 3:a280069151ac 985 if (strlen(version) != LWM2M_VERSION_LEN
terence zhang 3:a280069151ac 986 || lwm2m_strncmp(version, LWM2M_VERSION, LWM2M_VERSION_LEN))
terence zhang 3:a280069151ac 987 {
terence zhang 3:a280069151ac 988 lwm2m_free(version);
terence zhang 3:a280069151ac 989 lwm2m_free(name);
terence zhang 3:a280069151ac 990 if (msisdn != NULL) lwm2m_free(msisdn);
terence zhang 3:a280069151ac 991 return COAP_412_PRECONDITION_FAILED;
terence zhang 3:a280069151ac 992 }
terence zhang 3:a280069151ac 993
terence zhang 3:a280069151ac 994 if (lifetime == 0)
terence zhang 3:a280069151ac 995 {
terence zhang 3:a280069151ac 996 lifetime = LWM2M_DEFAULT_LIFETIME;
terence zhang 3:a280069151ac 997 }
terencez 0:f9d13e09cf11 998
terence zhang 3:a280069151ac 999 clientP = prv_getClientByName(contextP, name);
terence zhang 3:a280069151ac 1000 if (clientP != NULL)
terence zhang 3:a280069151ac 1001 {
terence zhang 3:a280069151ac 1002 // we reset this registration
terence zhang 3:a280069151ac 1003 lwm2m_free(clientP->name);
terence zhang 3:a280069151ac 1004 if (clientP->msisdn != NULL) lwm2m_free(clientP->msisdn);
terence zhang 3:a280069151ac 1005 if (clientP->altPath != NULL) lwm2m_free(clientP->altPath);
terence zhang 3:a280069151ac 1006 prv_freeClientObjectList(clientP->objectList);
terence zhang 3:a280069151ac 1007 clientP->objectList = NULL;
terence zhang 3:a280069151ac 1008 }
terence zhang 3:a280069151ac 1009 else
terence zhang 3:a280069151ac 1010 {
terence zhang 3:a280069151ac 1011 clientP = (lwm2m_client_t *)lwm2m_malloc(sizeof(lwm2m_client_t));
terence zhang 3:a280069151ac 1012 if (clientP == NULL)
terence zhang 3:a280069151ac 1013 {
terence zhang 3:a280069151ac 1014 lwm2m_free(name);
terence zhang 3:a280069151ac 1015 lwm2m_free(altPath);
terence zhang 3:a280069151ac 1016 if (msisdn != NULL) lwm2m_free(msisdn);
terence zhang 3:a280069151ac 1017 prv_freeClientObjectList(objects);
terence zhang 3:a280069151ac 1018 return COAP_500_INTERNAL_SERVER_ERROR;
terence zhang 3:a280069151ac 1019 }
terence zhang 3:a280069151ac 1020 memset(clientP, 0, sizeof(lwm2m_client_t));
terence zhang 3:a280069151ac 1021 clientP->internalID = lwm2m_list_newId((lwm2m_list_t *)contextP->clientList);
terence zhang 3:a280069151ac 1022 contextP->clientList = (lwm2m_client_t *)LWM2M_LIST_ADD(contextP->clientList, clientP);
terence zhang 3:a280069151ac 1023 }
terence zhang 3:a280069151ac 1024 clientP->name = name;
terence zhang 3:a280069151ac 1025 clientP->binding = binding;
terence zhang 3:a280069151ac 1026 clientP->msisdn = msisdn;
terence zhang 3:a280069151ac 1027 clientP->altPath = altPath;
terence zhang 3:a280069151ac 1028 clientP->supportJSON = supportJSON;
terence zhang 3:a280069151ac 1029 clientP->lifetime = lifetime;
terence zhang 3:a280069151ac 1030 clientP->endOfLife = tv_sec + lifetime;
terence zhang 3:a280069151ac 1031 clientP->objectList = objects;
terence zhang 3:a280069151ac 1032 clientP->sessionH = fromSessionH;
terence zhang 3:a280069151ac 1033
terence zhang 3:a280069151ac 1034 if (prv_getLocationString(clientP->internalID, location) == 0)
terence zhang 3:a280069151ac 1035 {
terence zhang 3:a280069151ac 1036 registration_freeClient(clientP);
terence zhang 3:a280069151ac 1037 return COAP_500_INTERNAL_SERVER_ERROR;
terence zhang 3:a280069151ac 1038 }
terence zhang 3:a280069151ac 1039 if (coap_set_header_location_path(response, location) == 0)
terence zhang 3:a280069151ac 1040 {
terence zhang 3:a280069151ac 1041 registration_freeClient(clientP);
terence zhang 3:a280069151ac 1042 return COAP_500_INTERNAL_SERVER_ERROR;
terence zhang 3:a280069151ac 1043 }
terence zhang 3:a280069151ac 1044
terence zhang 3:a280069151ac 1045 if (contextP->monitorCallback != NULL)
terence zhang 3:a280069151ac 1046 {
terence zhang 3:a280069151ac 1047 contextP->monitorCallback(clientP->internalID, NULL, COAP_201_CREATED, LWM2M_CONTENT_TEXT, NULL, 0, contextP->monitorUserData);
terence zhang 3:a280069151ac 1048 }
terence zhang 3:a280069151ac 1049 result = COAP_201_CREATED;
terence zhang 3:a280069151ac 1050 break;
terence zhang 3:a280069151ac 1051
terence zhang 3:a280069151ac 1052 case LWM2M_URI_FLAG_OBJECT_ID:
terence zhang 3:a280069151ac 1053 clientP = (lwm2m_client_t *)lwm2m_list_find((lwm2m_list_t *)contextP->clientList, uriP->objectId);
terence zhang 3:a280069151ac 1054 if (clientP == NULL) return COAP_404_NOT_FOUND;
terence zhang 3:a280069151ac 1055
terence zhang 3:a280069151ac 1056 // Endpoint client name MUST NOT be present
terence zhang 3:a280069151ac 1057 if (name != NULL)
terencez 0:f9d13e09cf11 1058 {
terencez 0:f9d13e09cf11 1059 lwm2m_free(name);
terencez 0:f9d13e09cf11 1060 if (msisdn != NULL) lwm2m_free(msisdn);
terence zhang 3:a280069151ac 1061 return COAP_400_BAD_REQUEST;
terencez 0:f9d13e09cf11 1062 }
terencez 0:f9d13e09cf11 1063
terence zhang 3:a280069151ac 1064 if (binding != BINDING_UNKNOWN)
terence zhang 3:a280069151ac 1065 {
terence zhang 3:a280069151ac 1066 clientP->binding = binding;
terence zhang 3:a280069151ac 1067 }
terence zhang 3:a280069151ac 1068 if (msisdn != NULL)
terence zhang 3:a280069151ac 1069 {
terence zhang 3:a280069151ac 1070 if (clientP->msisdn != NULL) lwm2m_free(clientP->msisdn);
terence zhang 3:a280069151ac 1071 clientP->msisdn = msisdn;
terence zhang 3:a280069151ac 1072 }
terence zhang 3:a280069151ac 1073 if (lifetime != 0)
terence zhang 3:a280069151ac 1074 {
terence zhang 3:a280069151ac 1075 clientP->lifetime = lifetime;
terence zhang 3:a280069151ac 1076 }
terence zhang 3:a280069151ac 1077 // client IP address, port or MSISDN may have changed
terence zhang 3:a280069151ac 1078 clientP->sessionH = fromSessionH;
terencez 0:f9d13e09cf11 1079
terence zhang 3:a280069151ac 1080 if (objects != NULL)
terence zhang 3:a280069151ac 1081 {
terence zhang 3:a280069151ac 1082 lwm2m_observation_t * observationP;
terencez 0:f9d13e09cf11 1083
terence zhang 3:a280069151ac 1084 // remove observations on object/instance no longer existing
terence zhang 3:a280069151ac 1085 observationP = clientP->observationList;
terence zhang 3:a280069151ac 1086 while (observationP != NULL)
terence zhang 3:a280069151ac 1087 {
terence zhang 3:a280069151ac 1088 lwm2m_client_object_t * objP;
terence zhang 3:a280069151ac 1089 lwm2m_observation_t * nextP;
terencez 0:f9d13e09cf11 1090
terence zhang 3:a280069151ac 1091 nextP = observationP->next;
terencez 0:f9d13e09cf11 1092
terence zhang 3:a280069151ac 1093 objP = (lwm2m_client_object_t *)lwm2m_list_find((lwm2m_list_t *)objects, observationP->uri.objectId);
terence zhang 3:a280069151ac 1094 if (objP == NULL)
terence zhang 3:a280069151ac 1095 {
terence zhang 3:a280069151ac 1096 observationP->callback(clientP->internalID,
terence zhang 3:a280069151ac 1097 &observationP->uri,
terence zhang 3:a280069151ac 1098 COAP_202_DELETED,
terence zhang 3:a280069151ac 1099 LWM2M_CONTENT_TEXT, NULL, 0,
terence zhang 3:a280069151ac 1100 observationP->userData);
terence zhang 3:a280069151ac 1101 observe_remove(observationP);
terence zhang 3:a280069151ac 1102 }
terence zhang 3:a280069151ac 1103 else
terencez 0:f9d13e09cf11 1104 {
terence zhang 3:a280069151ac 1105 if ((observationP->uri.flag & LWM2M_URI_FLAG_INSTANCE_ID) != 0)
terencez 0:f9d13e09cf11 1106 {
terence zhang 3:a280069151ac 1107 if (lwm2m_list_find((lwm2m_list_t *)objP->instanceList, observationP->uri.instanceId) == NULL)
terence zhang 3:a280069151ac 1108 {
terence zhang 3:a280069151ac 1109 observationP->callback(clientP->internalID,
terence zhang 3:a280069151ac 1110 &observationP->uri,
terence zhang 3:a280069151ac 1111 COAP_202_DELETED,
terence zhang 3:a280069151ac 1112 LWM2M_CONTENT_TEXT, NULL, 0,
terence zhang 3:a280069151ac 1113 observationP->userData);
terence zhang 3:a280069151ac 1114 observe_remove(observationP);
terence zhang 3:a280069151ac 1115 }
terencez 0:f9d13e09cf11 1116 }
terencez 0:f9d13e09cf11 1117 }
terence zhang 3:a280069151ac 1118
terence zhang 3:a280069151ac 1119 observationP = nextP;
terencez 0:f9d13e09cf11 1120 }
terencez 0:f9d13e09cf11 1121
terence zhang 3:a280069151ac 1122 prv_freeClientObjectList(clientP->objectList);
terence zhang 3:a280069151ac 1123 clientP->objectList = objects;
terencez 0:f9d13e09cf11 1124 }
terencez 0:f9d13e09cf11 1125
terence zhang 3:a280069151ac 1126 clientP->endOfLife = tv_sec + clientP->lifetime;
terencez 0:f9d13e09cf11 1127
terence zhang 3:a280069151ac 1128 if (contextP->monitorCallback != NULL)
terence zhang 3:a280069151ac 1129 {
terence zhang 3:a280069151ac 1130 contextP->monitorCallback(clientP->internalID, NULL, COAP_204_CHANGED, LWM2M_CONTENT_TEXT, NULL, 0, contextP->monitorUserData);
terence zhang 3:a280069151ac 1131 }
terence zhang 3:a280069151ac 1132 result = COAP_204_CHANGED;
terence zhang 3:a280069151ac 1133 break;
terence zhang 3:a280069151ac 1134
terence zhang 3:a280069151ac 1135 default:
terence zhang 3:a280069151ac 1136 return COAP_400_BAD_REQUEST;
terencez 0:f9d13e09cf11 1137 }
terencez 0:f9d13e09cf11 1138 }
terencez 0:f9d13e09cf11 1139 break;
terencez 0:f9d13e09cf11 1140
terencez 0:f9d13e09cf11 1141 case COAP_DELETE:
terencez 0:f9d13e09cf11 1142 {
terencez 0:f9d13e09cf11 1143 lwm2m_client_t * clientP;
terencez 0:f9d13e09cf11 1144
terencez 0:f9d13e09cf11 1145 if ((uriP->flag & LWM2M_URI_MASK_ID) != LWM2M_URI_FLAG_OBJECT_ID) return COAP_400_BAD_REQUEST;
terencez 0:f9d13e09cf11 1146
terencez 0:f9d13e09cf11 1147 contextP->clientList = (lwm2m_client_t *)LWM2M_LIST_RM(contextP->clientList, uriP->objectId, &clientP);
terencez 0:f9d13e09cf11 1148 if (clientP == NULL) return COAP_400_BAD_REQUEST;
terencez 0:f9d13e09cf11 1149 if (contextP->monitorCallback != NULL)
terencez 0:f9d13e09cf11 1150 {
terence zhang 3:a280069151ac 1151 contextP->monitorCallback(clientP->internalID, NULL, COAP_202_DELETED, LWM2M_CONTENT_TEXT, NULL, 0, contextP->monitorUserData);
terencez 0:f9d13e09cf11 1152 }
terence zhang 3:a280069151ac 1153 registration_freeClient(clientP);
terencez 0:f9d13e09cf11 1154 result = COAP_202_DELETED;
terencez 0:f9d13e09cf11 1155 }
terencez 0:f9d13e09cf11 1156 break;
terencez 0:f9d13e09cf11 1157
terencez 0:f9d13e09cf11 1158 default:
terencez 0:f9d13e09cf11 1159 return COAP_400_BAD_REQUEST;
terencez 0:f9d13e09cf11 1160 }
terencez 0:f9d13e09cf11 1161
terencez 0:f9d13e09cf11 1162 return result;
terencez 0:f9d13e09cf11 1163 }
terencez 0:f9d13e09cf11 1164
terencez 0:f9d13e09cf11 1165 void lwm2m_set_monitoring_callback(lwm2m_context_t * contextP,
terencez 0:f9d13e09cf11 1166 lwm2m_result_callback_t callback,
terencez 0:f9d13e09cf11 1167 void * userData)
terencez 0:f9d13e09cf11 1168 {
terence zhang 3:a280069151ac 1169 LOG("Entering");
terencez 0:f9d13e09cf11 1170 contextP->monitorCallback = callback;
terencez 0:f9d13e09cf11 1171 contextP->monitorUserData = userData;
terencez 0:f9d13e09cf11 1172 }
terence zhang 3:a280069151ac 1173 #endif
terencez 0:f9d13e09cf11 1174
terence zhang 3:a280069151ac 1175 // for each server update the registration if needed
terence zhang 3:a280069151ac 1176 // for each client check if the registration expired
terence zhang 3:a280069151ac 1177 void registration_step(lwm2m_context_t * contextP,
terence zhang 3:a280069151ac 1178 time_t currentTime,
terence zhang 3:a280069151ac 1179 time_t * timeoutP)
terence zhang 3:a280069151ac 1180 {
terence zhang 3:a280069151ac 1181 #ifdef LWM2M_CLIENT_MODE
terence zhang 3:a280069151ac 1182 lwm2m_server_t * targetP = contextP->serverList;
terence zhang 3:a280069151ac 1183
terence zhang 3:a280069151ac 1184 LOG_ARG("State: %s", STR_STATE(contextP->state));
terence zhang 3:a280069151ac 1185
terence zhang 3:a280069151ac 1186 targetP = contextP->serverList;
terence zhang 3:a280069151ac 1187 while (targetP != NULL)
terence zhang 3:a280069151ac 1188 {
terence zhang 3:a280069151ac 1189 switch (targetP->status)
terence zhang 3:a280069151ac 1190 {
terence zhang 3:a280069151ac 1191 case STATE_REGISTERED:
terence zhang 3:a280069151ac 1192 {
terence zhang 3:a280069151ac 1193 time_t nextUpdate;
terence zhang 3:a280069151ac 1194 time_t interval;
terence zhang 3:a280069151ac 1195
terence zhang 3:a280069151ac 1196 nextUpdate = targetP->lifetime;
terence zhang 3:a280069151ac 1197 if (COAP_MAX_TRANSMIT_WAIT < nextUpdate)
terence zhang 3:a280069151ac 1198 {
terence zhang 3:a280069151ac 1199 nextUpdate -= COAP_MAX_TRANSMIT_WAIT;
terence zhang 3:a280069151ac 1200 }
terence zhang 3:a280069151ac 1201 else
terence zhang 3:a280069151ac 1202 {
terence zhang 3:a280069151ac 1203 nextUpdate = nextUpdate >> 1;
terence zhang 3:a280069151ac 1204 }
terence zhang 3:a280069151ac 1205
terence zhang 3:a280069151ac 1206 interval = targetP->registration + nextUpdate - currentTime;
terence zhang 3:a280069151ac 1207 if (0 >= interval)
terence zhang 3:a280069151ac 1208 {
terence zhang 3:a280069151ac 1209 LOG("Updating registration");
terence zhang 3:a280069151ac 1210 prv_updateRegistration(contextP, targetP, false);
terence zhang 3:a280069151ac 1211 }
terence zhang 3:a280069151ac 1212 else if (interval < *timeoutP)
terence zhang 3:a280069151ac 1213 {
terence zhang 3:a280069151ac 1214 *timeoutP = interval;
terence zhang 3:a280069151ac 1215 }
terence zhang 3:a280069151ac 1216 }
terence zhang 3:a280069151ac 1217 break;
terence zhang 3:a280069151ac 1218
terence zhang 3:a280069151ac 1219 case STATE_REG_UPDATE_NEEDED:
terence zhang 3:a280069151ac 1220 prv_updateRegistration(contextP, targetP, false);
terence zhang 3:a280069151ac 1221 break;
terence zhang 3:a280069151ac 1222
terence zhang 3:a280069151ac 1223 case STATE_REG_FULL_UPDATE_NEEDED:
terence zhang 3:a280069151ac 1224 prv_updateRegistration(contextP, targetP, true);
terence zhang 3:a280069151ac 1225 break;
terence zhang 3:a280069151ac 1226
terence zhang 3:a280069151ac 1227 case STATE_REG_FAILED:
terence zhang 3:a280069151ac 1228 if (targetP->sessionH != NULL)
terence zhang 3:a280069151ac 1229 {
terence zhang 3:a280069151ac 1230 targetP->sessionH = NULL;
terence zhang 3:a280069151ac 1231 }
terence zhang 3:a280069151ac 1232 break;
terence zhang 3:a280069151ac 1233
terence zhang 3:a280069151ac 1234 default:
terence zhang 3:a280069151ac 1235 break;
terence zhang 3:a280069151ac 1236 }
terence zhang 3:a280069151ac 1237 targetP = targetP->next;
terence zhang 3:a280069151ac 1238 }
terencez 0:f9d13e09cf11 1239
terencez 0:f9d13e09cf11 1240 #endif
terence zhang 3:a280069151ac 1241 #ifdef LWM2M_SERVER_MODE
terence zhang 3:a280069151ac 1242 lwm2m_client_t * clientP;
terence zhang 3:a280069151ac 1243
terence zhang 3:a280069151ac 1244 LOG("Entering");
terence zhang 3:a280069151ac 1245 // monitor clients lifetime
terence zhang 3:a280069151ac 1246 clientP = contextP->clientList;
terence zhang 3:a280069151ac 1247 while (clientP != NULL)
terence zhang 3:a280069151ac 1248 {
terence zhang 3:a280069151ac 1249 lwm2m_client_t * nextP = clientP->next;
terence zhang 3:a280069151ac 1250
terence zhang 3:a280069151ac 1251 if (clientP->endOfLife <= currentTime)
terence zhang 3:a280069151ac 1252 {
terence zhang 3:a280069151ac 1253 contextP->clientList = (lwm2m_client_t *)LWM2M_LIST_RM(contextP->clientList, clientP->internalID, NULL);
terence zhang 3:a280069151ac 1254 if (contextP->monitorCallback != NULL)
terence zhang 3:a280069151ac 1255 {
terence zhang 3:a280069151ac 1256 contextP->monitorCallback(clientP->internalID, NULL, COAP_202_DELETED, LWM2M_CONTENT_TEXT, NULL, 0, contextP->monitorUserData);
terence zhang 3:a280069151ac 1257 }
terence zhang 3:a280069151ac 1258 registration_freeClient(clientP);
terence zhang 3:a280069151ac 1259 }
terence zhang 3:a280069151ac 1260 else
terence zhang 3:a280069151ac 1261 {
terence zhang 3:a280069151ac 1262 time_t interval;
terence zhang 3:a280069151ac 1263
terence zhang 3:a280069151ac 1264 interval = clientP->endOfLife - currentTime;
terence zhang 3:a280069151ac 1265
terence zhang 3:a280069151ac 1266 if (*timeoutP > interval)
terence zhang 3:a280069151ac 1267 {
terence zhang 3:a280069151ac 1268 *timeoutP = interval;
terence zhang 3:a280069151ac 1269 }
terence zhang 3:a280069151ac 1270 }
terence zhang 3:a280069151ac 1271 clientP = nextP;
terence zhang 3:a280069151ac 1272 }
terence zhang 3:a280069151ac 1273 #endif
terence zhang 3:a280069151ac 1274
terence zhang 3:a280069151ac 1275 }
terence zhang 3:a280069151ac 1276