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

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

Who changed what in which revision?

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