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 * Toby Jaffey - Please refer to git log
terencez 0:c2dff8cbb91a 16 * Bosch Software Innovations GmbH - Please refer to git log
terencez 0:c2dff8cbb91a 17 *
terencez 0:c2dff8cbb91a 18 *******************************************************************************/
terencez 0:c2dff8cbb91a 19
terencez 0:c2dff8cbb91a 20 /*
terencez 0:c2dff8cbb91a 21 Copyright (c) 2013, 2014 Intel Corporation
terencez 0:c2dff8cbb91a 22
terencez 0:c2dff8cbb91a 23 Redistribution and use in source and binary forms, with or without modification,
terencez 0:c2dff8cbb91a 24 are permitted provided that the following conditions are met:
terencez 0:c2dff8cbb91a 25
terencez 0:c2dff8cbb91a 26 * Redistributions of source code must retain the above copyright notice,
terencez 0:c2dff8cbb91a 27 this list of conditions and the following disclaimer.
terencez 0:c2dff8cbb91a 28 * Redistributions in binary form must reproduce the above copyright notice,
terencez 0:c2dff8cbb91a 29 this list of conditions and the following disclaimer in the documentation
terencez 0:c2dff8cbb91a 30 and/or other materials provided with the distribution.
terencez 0:c2dff8cbb91a 31 * Neither the name of Intel Corporation nor the names of its contributors
terencez 0:c2dff8cbb91a 32 may be used to endorse or promote products derived from this software
terencez 0:c2dff8cbb91a 33 without specific prior written permission.
terencez 0:c2dff8cbb91a 34
terencez 0:c2dff8cbb91a 35 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
terencez 0:c2dff8cbb91a 36 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
terencez 0:c2dff8cbb91a 37 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
terencez 0:c2dff8cbb91a 38 IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
terencez 0:c2dff8cbb91a 39 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
terencez 0:c2dff8cbb91a 40 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
terencez 0:c2dff8cbb91a 41 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
terencez 0:c2dff8cbb91a 42 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
terencez 0:c2dff8cbb91a 43 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
terencez 0:c2dff8cbb91a 44 THE POSSIBILITY OF SUCH DAMAGE.
terencez 0:c2dff8cbb91a 45
terencez 0:c2dff8cbb91a 46 David Navarro <david.navarro@intel.com>
terencez 0:c2dff8cbb91a 47
terencez 0:c2dff8cbb91a 48 */
terencez 0:c2dff8cbb91a 49
terencez 0:c2dff8cbb91a 50 #include "internals.h"
terencez 0:c2dff8cbb91a 51 #include <stdio.h>
terencez 0:c2dff8cbb91a 52
terencez 0:c2dff8cbb91a 53
terencez 0:c2dff8cbb91a 54 #ifdef LWM2M_CLIENT_MODE
terencez 0:c2dff8cbb91a 55 static lwm2m_observed_t * prv_findObserved(lwm2m_context_t * contextP,
terencez 0:c2dff8cbb91a 56 lwm2m_uri_t * uriP)
terencez 0:c2dff8cbb91a 57 {
terencez 0:c2dff8cbb91a 58 lwm2m_observed_t * targetP;
terencez 0:c2dff8cbb91a 59
terencez 0:c2dff8cbb91a 60 targetP = contextP->observedList;
terencez 0:c2dff8cbb91a 61 while (targetP != NULL
terencez 0:c2dff8cbb91a 62 && (targetP->uri.objectId != uriP->objectId
terencez 0:c2dff8cbb91a 63 || targetP->uri.flag != uriP->flag
terencez 0:c2dff8cbb91a 64 || (LWM2M_URI_IS_SET_INSTANCE(uriP) && targetP->uri.instanceId != uriP->instanceId)
terencez 0:c2dff8cbb91a 65 || (LWM2M_URI_IS_SET_RESOURCE(uriP) && targetP->uri.resourceId != uriP->resourceId)))
terencez 0:c2dff8cbb91a 66 {
terencez 0:c2dff8cbb91a 67 targetP = targetP->next;
terencez 0:c2dff8cbb91a 68 }
terencez 0:c2dff8cbb91a 69
terencez 0:c2dff8cbb91a 70 return targetP;
terencez 0:c2dff8cbb91a 71 }
terencez 0:c2dff8cbb91a 72
terencez 0:c2dff8cbb91a 73 static void prv_unlinkObserved(lwm2m_context_t * contextP,
terencez 0:c2dff8cbb91a 74 lwm2m_observed_t * observedP)
terencez 0:c2dff8cbb91a 75 {
terencez 0:c2dff8cbb91a 76 if (contextP->observedList == observedP)
terencez 0:c2dff8cbb91a 77 {
terencez 0:c2dff8cbb91a 78 contextP->observedList = contextP->observedList->next;
terencez 0:c2dff8cbb91a 79 }
terencez 0:c2dff8cbb91a 80 else
terencez 0:c2dff8cbb91a 81 {
terencez 0:c2dff8cbb91a 82 lwm2m_observed_t * parentP;
terencez 0:c2dff8cbb91a 83
terencez 0:c2dff8cbb91a 84 parentP = contextP->observedList;
terencez 0:c2dff8cbb91a 85 while (parentP->next != NULL
terencez 0:c2dff8cbb91a 86 && parentP->next != observedP)
terencez 0:c2dff8cbb91a 87 {
terencez 0:c2dff8cbb91a 88 parentP = parentP->next;
terencez 0:c2dff8cbb91a 89 }
terencez 0:c2dff8cbb91a 90 if (parentP->next != NULL)
terencez 0:c2dff8cbb91a 91 {
terencez 0:c2dff8cbb91a 92 parentP->next = parentP->next->next;
terencez 0:c2dff8cbb91a 93 }
terencez 0:c2dff8cbb91a 94 }
terencez 0:c2dff8cbb91a 95 }
terencez 0:c2dff8cbb91a 96
terencez 0:c2dff8cbb91a 97 static lwm2m_watcher_t * prv_findWatcher(lwm2m_observed_t * observedP,
terencez 0:c2dff8cbb91a 98 lwm2m_server_t * serverP)
terencez 0:c2dff8cbb91a 99 {
terencez 0:c2dff8cbb91a 100 lwm2m_watcher_t * targetP;
terencez 0:c2dff8cbb91a 101
terencez 0:c2dff8cbb91a 102 targetP = observedP->watcherList;
terencez 0:c2dff8cbb91a 103 while (targetP != NULL
terencez 0:c2dff8cbb91a 104 && targetP->server != serverP)
terencez 0:c2dff8cbb91a 105 {
terencez 0:c2dff8cbb91a 106 targetP = targetP->next;
terencez 0:c2dff8cbb91a 107 }
terencez 0:c2dff8cbb91a 108
terencez 0:c2dff8cbb91a 109 return targetP;
terencez 0:c2dff8cbb91a 110 }
terencez 0:c2dff8cbb91a 111
terencez 0:c2dff8cbb91a 112 static lwm2m_watcher_t * prv_getWatcher(lwm2m_context_t * contextP,
terencez 0:c2dff8cbb91a 113 lwm2m_uri_t * uriP,
terencez 0:c2dff8cbb91a 114 lwm2m_server_t * serverP)
terencez 0:c2dff8cbb91a 115 {
terencez 0:c2dff8cbb91a 116 lwm2m_observed_t * observedP;
terencez 0:c2dff8cbb91a 117 bool allocatedObserver;
terencez 0:c2dff8cbb91a 118 lwm2m_watcher_t * watcherP;
terencez 0:c2dff8cbb91a 119
terencez 0:c2dff8cbb91a 120 allocatedObserver = false;
terencez 0:c2dff8cbb91a 121
terencez 0:c2dff8cbb91a 122 observedP = prv_findObserved(contextP, uriP);
terencez 0:c2dff8cbb91a 123 if (observedP == NULL)
terencez 0:c2dff8cbb91a 124 {
terencez 0:c2dff8cbb91a 125 observedP = (lwm2m_observed_t *)lwm2m_malloc(sizeof(lwm2m_observed_t));
terencez 0:c2dff8cbb91a 126 if (observedP == NULL) return NULL;
terencez 0:c2dff8cbb91a 127 allocatedObserver = true;
terencez 0:c2dff8cbb91a 128 memset(observedP, 0, sizeof(lwm2m_observed_t));
terencez 0:c2dff8cbb91a 129 memcpy(&(observedP->uri), uriP, sizeof(lwm2m_uri_t));
terencez 0:c2dff8cbb91a 130 observedP->next = contextP->observedList;
terencez 0:c2dff8cbb91a 131 contextP->observedList = observedP;
terencez 0:c2dff8cbb91a 132 }
terencez 0:c2dff8cbb91a 133
terencez 0:c2dff8cbb91a 134 watcherP = prv_findWatcher(observedP, serverP);
terencez 0:c2dff8cbb91a 135 if (watcherP == NULL)
terencez 0:c2dff8cbb91a 136 {
terencez 0:c2dff8cbb91a 137 watcherP = (lwm2m_watcher_t *)lwm2m_malloc(sizeof(lwm2m_watcher_t));
terencez 0:c2dff8cbb91a 138 if (watcherP == NULL)
terencez 0:c2dff8cbb91a 139 {
terencez 0:c2dff8cbb91a 140 if (allocatedObserver == true)
terencez 0:c2dff8cbb91a 141 {
terencez 0:c2dff8cbb91a 142 lwm2m_free(observedP);
terencez 0:c2dff8cbb91a 143 }
terencez 0:c2dff8cbb91a 144 return NULL;
terencez 0:c2dff8cbb91a 145 }
terencez 0:c2dff8cbb91a 146 memset(watcherP, 0, sizeof(lwm2m_watcher_t));
terencez 0:c2dff8cbb91a 147 watcherP->active = false;
terencez 0:c2dff8cbb91a 148 watcherP->server = serverP;
terencez 0:c2dff8cbb91a 149 watcherP->next = observedP->watcherList;
terencez 0:c2dff8cbb91a 150 observedP->watcherList = watcherP;
terencez 0:c2dff8cbb91a 151 }
terencez 0:c2dff8cbb91a 152
terencez 0:c2dff8cbb91a 153 return watcherP;
terencez 0:c2dff8cbb91a 154 }
terencez 0:c2dff8cbb91a 155
terencez 0:c2dff8cbb91a 156 coap_status_t observe_handleRequest(lwm2m_context_t * contextP,
terencez 0:c2dff8cbb91a 157 lwm2m_uri_t * uriP,
terencez 0:c2dff8cbb91a 158 lwm2m_server_t * serverP,
terencez 0:c2dff8cbb91a 159 int size,
terencez 0:c2dff8cbb91a 160 lwm2m_data_t * dataP,
terencez 0:c2dff8cbb91a 161 coap_packet_t * message,
terencez 0:c2dff8cbb91a 162 coap_packet_t * response)
terencez 0:c2dff8cbb91a 163 {
terencez 0:c2dff8cbb91a 164 lwm2m_watcher_t * watcherP;
terencez 0:c2dff8cbb91a 165 uint32_t count;
terencez 0:c2dff8cbb91a 166
terencez 0:c2dff8cbb91a 167 LOG_ARG("Code: %02X, server status: %s", message->code, STR_STATUS(serverP->status));
terencez 0:c2dff8cbb91a 168 LOG_URI(uriP);
terencez 0:c2dff8cbb91a 169
terencez 0:c2dff8cbb91a 170 coap_get_header_observe(message, &count);
terencez 0:c2dff8cbb91a 171
terencez 0:c2dff8cbb91a 172 switch (count)
terencez 0:c2dff8cbb91a 173 {
terencez 0:c2dff8cbb91a 174 case 0:
terencez 0:c2dff8cbb91a 175 if (!LWM2M_URI_IS_SET_INSTANCE(uriP) && LWM2M_URI_IS_SET_RESOURCE(uriP)) return COAP_400_BAD_REQUEST;
terencez 0:c2dff8cbb91a 176 if (message->token_len == 0) return COAP_400_BAD_REQUEST;
terencez 0:c2dff8cbb91a 177
terencez 0:c2dff8cbb91a 178 watcherP = prv_getWatcher(contextP, uriP, serverP);
terencez 0:c2dff8cbb91a 179 if (watcherP == NULL) return COAP_500_INTERNAL_SERVER_ERROR;
terencez 0:c2dff8cbb91a 180
terencez 0:c2dff8cbb91a 181 watcherP->tokenLen = message->token_len;
terencez 0:c2dff8cbb91a 182 memcpy(watcherP->token, message->token, message->token_len);
terencez 0:c2dff8cbb91a 183 watcherP->active = true;
terencez 0:c2dff8cbb91a 184 watcherP->lastTime = lwm2m_gettime();
terencez 0:c2dff8cbb91a 185
terencez 0:c2dff8cbb91a 186 if (LWM2M_URI_IS_SET_RESOURCE(uriP))
terencez 0:c2dff8cbb91a 187 {
terencez 0:c2dff8cbb91a 188 switch (dataP->type)
terencez 0:c2dff8cbb91a 189 {
terencez 0:c2dff8cbb91a 190 case LWM2M_TYPE_INTEGER:
terencez 0:c2dff8cbb91a 191 if (1 != lwm2m_data_decode_int(dataP, &(watcherP->lastValue.asInteger))) return COAP_500_INTERNAL_SERVER_ERROR;
terencez 0:c2dff8cbb91a 192 break;
terencez 0:c2dff8cbb91a 193 case LWM2M_TYPE_FLOAT:
terencez 0:c2dff8cbb91a 194 if (1 != lwm2m_data_decode_float(dataP, &(watcherP->lastValue.asFloat))) return COAP_500_INTERNAL_SERVER_ERROR;
terencez 0:c2dff8cbb91a 195 break;
terencez 0:c2dff8cbb91a 196 default:
terencez 0:c2dff8cbb91a 197 break;
terencez 0:c2dff8cbb91a 198 }
terencez 0:c2dff8cbb91a 199 }
terencez 0:c2dff8cbb91a 200
terencez 0:c2dff8cbb91a 201 coap_set_header_observe(response, watcherP->counter++);
terencez 0:c2dff8cbb91a 202
terencez 0:c2dff8cbb91a 203 return COAP_205_CONTENT;
terencez 0:c2dff8cbb91a 204
terencez 0:c2dff8cbb91a 205 case 1:
terencez 0:c2dff8cbb91a 206 // cancellation
terencez 0:c2dff8cbb91a 207 observe_cancel(contextP, LWM2M_MAX_ID, serverP->sessionH);
terencez 0:c2dff8cbb91a 208 return COAP_205_CONTENT;
terencez 0:c2dff8cbb91a 209
terencez 0:c2dff8cbb91a 210 default:
terencez 0:c2dff8cbb91a 211 return COAP_400_BAD_REQUEST;
terencez 0:c2dff8cbb91a 212 }
terencez 0:c2dff8cbb91a 213 }
terencez 0:c2dff8cbb91a 214
terencez 0:c2dff8cbb91a 215 void observe_cancel(lwm2m_context_t * contextP,
terencez 0:c2dff8cbb91a 216 uint16_t mid,
terencez 0:c2dff8cbb91a 217 void * fromSessionH)
terencez 0:c2dff8cbb91a 218 {
terencez 0:c2dff8cbb91a 219 lwm2m_observed_t * observedP;
terencez 0:c2dff8cbb91a 220
terencez 0:c2dff8cbb91a 221 LOG_ARG("mid: %d", mid);
terencez 0:c2dff8cbb91a 222
terencez 0:c2dff8cbb91a 223 for (observedP = contextP->observedList;
terencez 0:c2dff8cbb91a 224 observedP != NULL;
terencez 0:c2dff8cbb91a 225 observedP = observedP->next)
terencez 0:c2dff8cbb91a 226 {
terencez 0:c2dff8cbb91a 227 lwm2m_watcher_t * targetP = NULL;
terencez 0:c2dff8cbb91a 228
terencez 0:c2dff8cbb91a 229 if ((LWM2M_MAX_ID == mid || observedP->watcherList->lastMid == mid)
terencez 0:c2dff8cbb91a 230 && lwm2m_session_is_equal(observedP->watcherList->server->sessionH, fromSessionH, contextP->userData))
terencez 0:c2dff8cbb91a 231 {
terencez 0:c2dff8cbb91a 232 targetP = observedP->watcherList;
terencez 0:c2dff8cbb91a 233 observedP->watcherList = observedP->watcherList->next;
terencez 0:c2dff8cbb91a 234 }
terencez 0:c2dff8cbb91a 235 else
terencez 0:c2dff8cbb91a 236 {
terencez 0:c2dff8cbb91a 237 lwm2m_watcher_t * parentP;
terencez 0:c2dff8cbb91a 238
terencez 0:c2dff8cbb91a 239 parentP = observedP->watcherList;
terencez 0:c2dff8cbb91a 240 while (parentP->next != NULL
terencez 0:c2dff8cbb91a 241 && (parentP->next->lastMid != mid
terencez 0:c2dff8cbb91a 242 || lwm2m_session_is_equal(parentP->next->server->sessionH, fromSessionH, contextP->userData)))
terencez 0:c2dff8cbb91a 243 {
terencez 0:c2dff8cbb91a 244 parentP = parentP->next;
terencez 0:c2dff8cbb91a 245 }
terencez 0:c2dff8cbb91a 246 if (parentP->next != NULL)
terencez 0:c2dff8cbb91a 247 {
terencez 0:c2dff8cbb91a 248 targetP = parentP->next;
terencez 0:c2dff8cbb91a 249 parentP->next = parentP->next->next;
terencez 0:c2dff8cbb91a 250 }
terencez 0:c2dff8cbb91a 251 }
terencez 0:c2dff8cbb91a 252 if (targetP != NULL)
terencez 0:c2dff8cbb91a 253 {
terencez 0:c2dff8cbb91a 254 lwm2m_free(targetP);
terencez 0:c2dff8cbb91a 255 if (observedP->watcherList == NULL)
terencez 0:c2dff8cbb91a 256 {
terencez 0:c2dff8cbb91a 257 prv_unlinkObserved(contextP, observedP);
terencez 0:c2dff8cbb91a 258 lwm2m_free(observedP);
terencez 0:c2dff8cbb91a 259 }
terencez 0:c2dff8cbb91a 260 return;
terencez 0:c2dff8cbb91a 261 }
terencez 0:c2dff8cbb91a 262 }
terencez 0:c2dff8cbb91a 263 }
terencez 0:c2dff8cbb91a 264
terencez 0:c2dff8cbb91a 265 coap_status_t observe_setParameters(lwm2m_context_t * contextP,
terencez 0:c2dff8cbb91a 266 lwm2m_uri_t * uriP,
terencez 0:c2dff8cbb91a 267 lwm2m_server_t * serverP,
terencez 0:c2dff8cbb91a 268 lwm2m_attributes_t * attrP)
terencez 0:c2dff8cbb91a 269 {
terencez 0:c2dff8cbb91a 270 uint8_t result;
terencez 0:c2dff8cbb91a 271 lwm2m_watcher_t * watcherP;
terencez 0:c2dff8cbb91a 272
terencez 0:c2dff8cbb91a 273 LOG_URI(uriP);
terencez 0:c2dff8cbb91a 274 LOG_ARG("toSet: %08X, toClear: %08X, minPeriod: %d, maxPeriod: %d, greaterThan: %f, lessThan: %f, step: %f",
terencez 0:c2dff8cbb91a 275 attrP->toSet, attrP->toClear, attrP->minPeriod, attrP->maxPeriod, attrP->greaterThan, attrP->lessThan, attrP->step);
terencez 0:c2dff8cbb91a 276
terencez 0:c2dff8cbb91a 277 if (!LWM2M_URI_IS_SET_INSTANCE(uriP) && LWM2M_URI_IS_SET_RESOURCE(uriP)) return COAP_400_BAD_REQUEST;
terencez 0:c2dff8cbb91a 278
terencez 0:c2dff8cbb91a 279 result = object_checkReadable(contextP, uriP);
terencez 0:c2dff8cbb91a 280 if (COAP_205_CONTENT != result) return result;
terencez 0:c2dff8cbb91a 281
terencez 0:c2dff8cbb91a 282 if (0 != (attrP->toSet & ATTR_FLAG_NUMERIC))
terencez 0:c2dff8cbb91a 283 {
terencez 0:c2dff8cbb91a 284 result = object_checkNumeric(contextP, uriP);
terencez 0:c2dff8cbb91a 285 if (COAP_205_CONTENT != result) return result;
terencez 0:c2dff8cbb91a 286 }
terencez 0:c2dff8cbb91a 287
terencez 0:c2dff8cbb91a 288 watcherP = prv_getWatcher(contextP, uriP, serverP);
terencez 0:c2dff8cbb91a 289 if (watcherP == NULL) return COAP_500_INTERNAL_SERVER_ERROR;
terencez 0:c2dff8cbb91a 290
terencez 0:c2dff8cbb91a 291 // Check rule “lt” value + 2*”stp” values < “gt” value
terencez 0:c2dff8cbb91a 292 if ((((attrP->toSet | (watcherP->parameters?watcherP->parameters->toSet:0)) & ~attrP->toClear) & ATTR_FLAG_NUMERIC) == ATTR_FLAG_NUMERIC)
terencez 0:c2dff8cbb91a 293 {
terencez 0:c2dff8cbb91a 294 float gt;
terencez 0:c2dff8cbb91a 295 float lt;
terencez 0:c2dff8cbb91a 296 float stp;
terencez 0:c2dff8cbb91a 297
terencez 0:c2dff8cbb91a 298 if (0 != (attrP->toSet & LWM2M_ATTR_FLAG_GREATER_THAN))
terencez 0:c2dff8cbb91a 299 {
terencez 0:c2dff8cbb91a 300 gt = attrP->greaterThan;
terencez 0:c2dff8cbb91a 301 }
terencez 0:c2dff8cbb91a 302 else
terencez 0:c2dff8cbb91a 303 {
terencez 0:c2dff8cbb91a 304 gt = watcherP->parameters->greaterThan;
terencez 0:c2dff8cbb91a 305 }
terencez 0:c2dff8cbb91a 306 if (0 != (attrP->toSet & LWM2M_ATTR_FLAG_LESS_THAN))
terencez 0:c2dff8cbb91a 307 {
terencez 0:c2dff8cbb91a 308 lt = attrP->lessThan;
terencez 0:c2dff8cbb91a 309 }
terencez 0:c2dff8cbb91a 310 else
terencez 0:c2dff8cbb91a 311 {
terencez 0:c2dff8cbb91a 312 lt = watcherP->parameters->lessThan;
terencez 0:c2dff8cbb91a 313 }
terencez 0:c2dff8cbb91a 314 if (0 != (attrP->toSet & LWM2M_ATTR_FLAG_STEP))
terencez 0:c2dff8cbb91a 315 {
terencez 0:c2dff8cbb91a 316 stp = attrP->step;
terencez 0:c2dff8cbb91a 317 }
terencez 0:c2dff8cbb91a 318 else
terencez 0:c2dff8cbb91a 319 {
terencez 0:c2dff8cbb91a 320 stp = watcherP->parameters->step;
terencez 0:c2dff8cbb91a 321 }
terencez 0:c2dff8cbb91a 322
terencez 0:c2dff8cbb91a 323 if (lt + (2 * stp) >= gt) return COAP_400_BAD_REQUEST;
terencez 0:c2dff8cbb91a 324 }
terencez 0:c2dff8cbb91a 325
terencez 0:c2dff8cbb91a 326 if (watcherP->parameters == NULL)
terencez 0:c2dff8cbb91a 327 {
terencez 0:c2dff8cbb91a 328 if (attrP->toSet != 0)
terencez 0:c2dff8cbb91a 329 {
terencez 0:c2dff8cbb91a 330 watcherP->parameters = (lwm2m_attributes_t *)lwm2m_malloc(sizeof(lwm2m_attributes_t));
terencez 0:c2dff8cbb91a 331 if (watcherP->parameters == NULL) return COAP_500_INTERNAL_SERVER_ERROR;
terencez 0:c2dff8cbb91a 332 memcpy(watcherP->parameters, attrP, sizeof(lwm2m_attributes_t));
terencez 0:c2dff8cbb91a 333 }
terencez 0:c2dff8cbb91a 334 }
terencez 0:c2dff8cbb91a 335 else
terencez 0:c2dff8cbb91a 336 {
terencez 0:c2dff8cbb91a 337 watcherP->parameters->toSet &= ~attrP->toClear;
terencez 0:c2dff8cbb91a 338 if (attrP->toSet & LWM2M_ATTR_FLAG_MIN_PERIOD)
terencez 0:c2dff8cbb91a 339 {
terencez 0:c2dff8cbb91a 340 watcherP->parameters->minPeriod = attrP->minPeriod;
terencez 0:c2dff8cbb91a 341 }
terencez 0:c2dff8cbb91a 342 if (attrP->toSet & LWM2M_ATTR_FLAG_MAX_PERIOD)
terencez 0:c2dff8cbb91a 343 {
terencez 0:c2dff8cbb91a 344 watcherP->parameters->maxPeriod = attrP->maxPeriod;
terencez 0:c2dff8cbb91a 345 }
terencez 0:c2dff8cbb91a 346 if (attrP->toSet & LWM2M_ATTR_FLAG_GREATER_THAN)
terencez 0:c2dff8cbb91a 347 {
terencez 0:c2dff8cbb91a 348 watcherP->parameters->greaterThan = attrP->greaterThan;
terencez 0:c2dff8cbb91a 349 }
terencez 0:c2dff8cbb91a 350 if (attrP->toSet & LWM2M_ATTR_FLAG_LESS_THAN)
terencez 0:c2dff8cbb91a 351 {
terencez 0:c2dff8cbb91a 352 watcherP->parameters->lessThan = attrP->lessThan;
terencez 0:c2dff8cbb91a 353 }
terencez 0:c2dff8cbb91a 354 if (attrP->toSet & LWM2M_ATTR_FLAG_STEP)
terencez 0:c2dff8cbb91a 355 {
terencez 0:c2dff8cbb91a 356 watcherP->parameters->step = attrP->step;
terencez 0:c2dff8cbb91a 357 }
terencez 0:c2dff8cbb91a 358 }
terencez 0:c2dff8cbb91a 359
terencez 0:c2dff8cbb91a 360 LOG_ARG("Final toSet: %08X, minPeriod: %d, maxPeriod: %d, greaterThan: %f, lessThan: %f, step: %f",
terencez 0:c2dff8cbb91a 361 watcherP->parameters->toSet, watcherP->parameters->minPeriod, watcherP->parameters->maxPeriod, watcherP->parameters->greaterThan, watcherP->parameters->lessThan, watcherP->parameters->step);
terencez 0:c2dff8cbb91a 362
terencez 0:c2dff8cbb91a 363 return COAP_204_CHANGED;
terencez 0:c2dff8cbb91a 364 }
terencez 0:c2dff8cbb91a 365
terencez 0:c2dff8cbb91a 366 lwm2m_observed_t * observe_findByUri(lwm2m_context_t * contextP,
terencez 0:c2dff8cbb91a 367 lwm2m_uri_t * uriP)
terencez 0:c2dff8cbb91a 368 {
terencez 0:c2dff8cbb91a 369 lwm2m_observed_t * targetP;
terencez 0:c2dff8cbb91a 370
terencez 0:c2dff8cbb91a 371 LOG_URI(uriP);
terencez 0:c2dff8cbb91a 372 targetP = contextP->observedList;
terencez 0:c2dff8cbb91a 373 while (targetP != NULL)
terencez 0:c2dff8cbb91a 374 {
terencez 0:c2dff8cbb91a 375 if (targetP->uri.objectId == uriP->objectId)
terencez 0:c2dff8cbb91a 376 {
terencez 0:c2dff8cbb91a 377 if ((!LWM2M_URI_IS_SET_INSTANCE(uriP) && !LWM2M_URI_IS_SET_INSTANCE(&(targetP->uri)))
terencez 0:c2dff8cbb91a 378 || (LWM2M_URI_IS_SET_INSTANCE(uriP) && LWM2M_URI_IS_SET_INSTANCE(&(targetP->uri)) && (uriP->instanceId == targetP->uri.instanceId)))
terencez 0:c2dff8cbb91a 379 {
terencez 0:c2dff8cbb91a 380 if ((!LWM2M_URI_IS_SET_RESOURCE(uriP) && !LWM2M_URI_IS_SET_RESOURCE(&(targetP->uri)))
terencez 0:c2dff8cbb91a 381 || (LWM2M_URI_IS_SET_RESOURCE(uriP) && LWM2M_URI_IS_SET_RESOURCE(&(targetP->uri)) && (uriP->resourceId == targetP->uri.resourceId)))
terencez 0:c2dff8cbb91a 382 {
terencez 0:c2dff8cbb91a 383 LOG_ARG("Found one with%s observers.", targetP->watcherList ? "" : " no");
terencez 0:c2dff8cbb91a 384 LOG_URI(&(targetP->uri));
terencez 0:c2dff8cbb91a 385 return targetP;
terencez 0:c2dff8cbb91a 386 }
terencez 0:c2dff8cbb91a 387 }
terencez 0:c2dff8cbb91a 388 }
terencez 0:c2dff8cbb91a 389 targetP = targetP->next;
terencez 0:c2dff8cbb91a 390 }
terencez 0:c2dff8cbb91a 391
terencez 0:c2dff8cbb91a 392 LOG("Found nothing");
terencez 0:c2dff8cbb91a 393 return NULL;
terencez 0:c2dff8cbb91a 394 }
terencez 0:c2dff8cbb91a 395
terencez 0:c2dff8cbb91a 396 void lwm2m_resource_value_changed(lwm2m_context_t * contextP,
terencez 0:c2dff8cbb91a 397 lwm2m_uri_t * uriP)
terencez 0:c2dff8cbb91a 398 {
terencez 0:c2dff8cbb91a 399 lwm2m_observed_t * targetP;
terencez 0:c2dff8cbb91a 400
terencez 0:c2dff8cbb91a 401 LOG_URI(uriP);
terencez 0:c2dff8cbb91a 402 targetP = contextP->observedList;
terencez 0:c2dff8cbb91a 403 while (targetP != NULL)
terencez 0:c2dff8cbb91a 404 {
terencez 0:c2dff8cbb91a 405 if (targetP->uri.objectId == uriP->objectId)
terencez 0:c2dff8cbb91a 406 {
terencez 0:c2dff8cbb91a 407 if (!LWM2M_URI_IS_SET_INSTANCE(uriP)
terencez 0:c2dff8cbb91a 408 || (targetP->uri.flag & LWM2M_URI_FLAG_INSTANCE_ID) == 0
terencez 0:c2dff8cbb91a 409 || uriP->instanceId == targetP->uri.instanceId)
terencez 0:c2dff8cbb91a 410 {
terencez 0:c2dff8cbb91a 411 if (!LWM2M_URI_IS_SET_RESOURCE(uriP)
terencez 0:c2dff8cbb91a 412 || (targetP->uri.flag & LWM2M_URI_FLAG_RESOURCE_ID) == 0
terencez 0:c2dff8cbb91a 413 || uriP->resourceId == targetP->uri.resourceId)
terencez 0:c2dff8cbb91a 414 {
terencez 0:c2dff8cbb91a 415 lwm2m_watcher_t * watcherP;
terencez 0:c2dff8cbb91a 416
terencez 0:c2dff8cbb91a 417 LOG("Found an observation");
terencez 0:c2dff8cbb91a 418 LOG_URI(&(targetP->uri));
terencez 0:c2dff8cbb91a 419
terencez 0:c2dff8cbb91a 420 for (watcherP = targetP->watcherList ; watcherP != NULL ; watcherP = watcherP->next)
terencez 0:c2dff8cbb91a 421 {
terencez 0:c2dff8cbb91a 422 if (watcherP->active == true)
terencez 0:c2dff8cbb91a 423 {
terencez 0:c2dff8cbb91a 424 LOG("Tagging a watcher");
terencez 0:c2dff8cbb91a 425 watcherP->update = true;
terencez 0:c2dff8cbb91a 426 }
terencez 0:c2dff8cbb91a 427 }
terencez 0:c2dff8cbb91a 428 }
terencez 0:c2dff8cbb91a 429 }
terencez 0:c2dff8cbb91a 430 }
terencez 0:c2dff8cbb91a 431 targetP = targetP->next;
terencez 0:c2dff8cbb91a 432 }
terencez 0:c2dff8cbb91a 433 }
terencez 0:c2dff8cbb91a 434
terencez 0:c2dff8cbb91a 435 void observe_step(lwm2m_context_t * contextP,
terencez 0:c2dff8cbb91a 436 time_t currentTime,
terencez 0:c2dff8cbb91a 437 time_t * timeoutP)
terencez 0:c2dff8cbb91a 438 {
terencez 0:c2dff8cbb91a 439 lwm2m_observed_t * targetP;
terencez 0:c2dff8cbb91a 440
terencez 0:c2dff8cbb91a 441 LOG("Entering");
terencez 0:c2dff8cbb91a 442 for (targetP = contextP->observedList ; targetP != NULL ; targetP = targetP->next)
terencez 0:c2dff8cbb91a 443 {
terencez 0:c2dff8cbb91a 444 lwm2m_watcher_t * watcherP;
terencez 0:c2dff8cbb91a 445 uint8_t * buffer = NULL;
terencez 0:c2dff8cbb91a 446 size_t length = 0;
terencez 0:c2dff8cbb91a 447 lwm2m_data_t * dataP = NULL;
terencez 0:c2dff8cbb91a 448 int size = 0;
terencez 0:c2dff8cbb91a 449 double floatValue = 0;
terencez 0:c2dff8cbb91a 450 int64_t integerValue = 0;
terencez 0:c2dff8cbb91a 451 bool storeValue = false;
terencez 0:c2dff8cbb91a 452 lwm2m_media_type_t format = LWM2M_CONTENT_TEXT;
terencez 0:c2dff8cbb91a 453 coap_packet_t message[1];
terencez 0:c2dff8cbb91a 454 time_t interval;
terencez 0:c2dff8cbb91a 455
terencez 0:c2dff8cbb91a 456 LOG_URI(&(targetP->uri));
terencez 0:c2dff8cbb91a 457 if (LWM2M_URI_IS_SET_RESOURCE(&targetP->uri))
terencez 0:c2dff8cbb91a 458 {
terencez 0:c2dff8cbb91a 459 if (COAP_205_CONTENT != object_readData(contextP, &targetP->uri, &size, &dataP)) continue;
terencez 0:c2dff8cbb91a 460 switch (dataP->type)
terencez 0:c2dff8cbb91a 461 {
terencez 0:c2dff8cbb91a 462 case LWM2M_TYPE_INTEGER:
terencez 0:c2dff8cbb91a 463 if (1 != lwm2m_data_decode_int(dataP, &integerValue)) continue;
terencez 0:c2dff8cbb91a 464 storeValue = true;
terencez 0:c2dff8cbb91a 465 break;
terencez 0:c2dff8cbb91a 466 case LWM2M_TYPE_FLOAT:
terencez 0:c2dff8cbb91a 467 if (1 != lwm2m_data_decode_float(dataP, &floatValue)) continue;
terencez 0:c2dff8cbb91a 468 storeValue = true;
terencez 0:c2dff8cbb91a 469 break;
terencez 0:c2dff8cbb91a 470 default:
terencez 0:c2dff8cbb91a 471 break;
terencez 0:c2dff8cbb91a 472 }
terencez 0:c2dff8cbb91a 473 }
terencez 0:c2dff8cbb91a 474 for (watcherP = targetP->watcherList ; watcherP != NULL ; watcherP = watcherP->next)
terencez 0:c2dff8cbb91a 475 {
terencez 0:c2dff8cbb91a 476 if (watcherP->active == true)
terencez 0:c2dff8cbb91a 477 {
terencez 0:c2dff8cbb91a 478 bool notify = false;
terencez 0:c2dff8cbb91a 479
terencez 0:c2dff8cbb91a 480 if (watcherP->update == true)
terencez 0:c2dff8cbb91a 481 {
terencez 0:c2dff8cbb91a 482 // value changed, should we notify the server ?
terencez 0:c2dff8cbb91a 483
terencez 0:c2dff8cbb91a 484 if (watcherP->parameters == NULL || watcherP->parameters->toSet == 0)
terencez 0:c2dff8cbb91a 485 {
terencez 0:c2dff8cbb91a 486 // no conditions
terencez 0:c2dff8cbb91a 487 notify = true;
terencez 0:c2dff8cbb91a 488 LOG("Notify with no conditions");
terencez 0:c2dff8cbb91a 489 LOG_URI(&(targetP->uri));
terencez 0:c2dff8cbb91a 490 }
terencez 0:c2dff8cbb91a 491
terencez 0:c2dff8cbb91a 492 if (notify == false
terencez 0:c2dff8cbb91a 493 && watcherP->parameters != NULL
terencez 0:c2dff8cbb91a 494 && (watcherP->parameters->toSet & ATTR_FLAG_NUMERIC) != 0)
terencez 0:c2dff8cbb91a 495 {
terencez 0:c2dff8cbb91a 496 if ((watcherP->parameters->toSet & LWM2M_ATTR_FLAG_LESS_THAN) != 0)
terencez 0:c2dff8cbb91a 497 {
terencez 0:c2dff8cbb91a 498 LOG("Checking lower treshold");
terencez 0:c2dff8cbb91a 499 // Did we cross the lower treshold ?
terencez 0:c2dff8cbb91a 500 switch (dataP->type)
terencez 0:c2dff8cbb91a 501 {
terencez 0:c2dff8cbb91a 502 case LWM2M_TYPE_INTEGER:
terencez 0:c2dff8cbb91a 503 if ((integerValue <= watcherP->parameters->lessThan
terencez 0:c2dff8cbb91a 504 && watcherP->lastValue.asInteger > watcherP->parameters->lessThan)
terencez 0:c2dff8cbb91a 505 || (integerValue >= watcherP->parameters->lessThan
terencez 0:c2dff8cbb91a 506 && watcherP->lastValue.asInteger < watcherP->parameters->lessThan))
terencez 0:c2dff8cbb91a 507 {
terencez 0:c2dff8cbb91a 508 LOG("Notify on lower treshold crossing");
terencez 0:c2dff8cbb91a 509 notify = true;
terencez 0:c2dff8cbb91a 510 }
terencez 0:c2dff8cbb91a 511 break;
terencez 0:c2dff8cbb91a 512 case LWM2M_TYPE_FLOAT:
terencez 0:c2dff8cbb91a 513 if ((floatValue <= watcherP->parameters->lessThan
terencez 0:c2dff8cbb91a 514 && watcherP->lastValue.asFloat > watcherP->parameters->lessThan)
terencez 0:c2dff8cbb91a 515 || (floatValue >= watcherP->parameters->lessThan
terencez 0:c2dff8cbb91a 516 && watcherP->lastValue.asFloat < watcherP->parameters->lessThan))
terencez 0:c2dff8cbb91a 517 {
terencez 0:c2dff8cbb91a 518 LOG("Notify on lower treshold crossing");
terencez 0:c2dff8cbb91a 519 notify = true;
terencez 0:c2dff8cbb91a 520 }
terencez 0:c2dff8cbb91a 521 break;
terencez 0:c2dff8cbb91a 522 default:
terencez 0:c2dff8cbb91a 523 break;
terencez 0:c2dff8cbb91a 524 }
terencez 0:c2dff8cbb91a 525 }
terencez 0:c2dff8cbb91a 526 if ((watcherP->parameters->toSet & LWM2M_ATTR_FLAG_GREATER_THAN) != 0)
terencez 0:c2dff8cbb91a 527 {
terencez 0:c2dff8cbb91a 528 LOG("Checking upper treshold");
terencez 0:c2dff8cbb91a 529 // Did we cross the upper treshold ?
terencez 0:c2dff8cbb91a 530 switch (dataP->type)
terencez 0:c2dff8cbb91a 531 {
terencez 0:c2dff8cbb91a 532 case LWM2M_TYPE_INTEGER:
terencez 0:c2dff8cbb91a 533 if ((integerValue <= watcherP->parameters->greaterThan
terencez 0:c2dff8cbb91a 534 && watcherP->lastValue.asInteger > watcherP->parameters->greaterThan)
terencez 0:c2dff8cbb91a 535 || (integerValue >= watcherP->parameters->greaterThan
terencez 0:c2dff8cbb91a 536 && watcherP->lastValue.asInteger < watcherP->parameters->greaterThan))
terencez 0:c2dff8cbb91a 537 {
terencez 0:c2dff8cbb91a 538 LOG("Notify on lower upper crossing");
terencez 0:c2dff8cbb91a 539 notify = true;
terencez 0:c2dff8cbb91a 540 }
terencez 0:c2dff8cbb91a 541 break;
terencez 0:c2dff8cbb91a 542 case LWM2M_TYPE_FLOAT:
terencez 0:c2dff8cbb91a 543 if ((floatValue <= watcherP->parameters->greaterThan
terencez 0:c2dff8cbb91a 544 && watcherP->lastValue.asFloat > watcherP->parameters->greaterThan)
terencez 0:c2dff8cbb91a 545 || (floatValue >= watcherP->parameters->greaterThan
terencez 0:c2dff8cbb91a 546 && watcherP->lastValue.asFloat < watcherP->parameters->greaterThan))
terencez 0:c2dff8cbb91a 547 {
terencez 0:c2dff8cbb91a 548 LOG("Notify on lower upper crossing");
terencez 0:c2dff8cbb91a 549 notify = true;
terencez 0:c2dff8cbb91a 550 }
terencez 0:c2dff8cbb91a 551 break;
terencez 0:c2dff8cbb91a 552 default:
terencez 0:c2dff8cbb91a 553 break;
terencez 0:c2dff8cbb91a 554 }
terencez 0:c2dff8cbb91a 555 }
terencez 0:c2dff8cbb91a 556 if ((watcherP->parameters->toSet & LWM2M_ATTR_FLAG_STEP) != 0)
terencez 0:c2dff8cbb91a 557 {
terencez 0:c2dff8cbb91a 558 LOG("Checking step");
terencez 0:c2dff8cbb91a 559
terencez 0:c2dff8cbb91a 560 switch (dataP->type)
terencez 0:c2dff8cbb91a 561 {
terencez 0:c2dff8cbb91a 562 case LWM2M_TYPE_INTEGER:
terencez 0:c2dff8cbb91a 563 {
terencez 0:c2dff8cbb91a 564 int64_t diff;
terencez 0:c2dff8cbb91a 565
terencez 0:c2dff8cbb91a 566 diff = integerValue - watcherP->lastValue.asInteger;
terencez 0:c2dff8cbb91a 567 if ((diff < 0 && (0 - diff) >= watcherP->parameters->step)
terencez 0:c2dff8cbb91a 568 || (diff >= 0 && diff >= watcherP->parameters->step))
terencez 0:c2dff8cbb91a 569 {
terencez 0:c2dff8cbb91a 570 LOG("Notify on step condition");
terencez 0:c2dff8cbb91a 571 notify = true;
terencez 0:c2dff8cbb91a 572 }
terencez 0:c2dff8cbb91a 573 }
terencez 0:c2dff8cbb91a 574 break;
terencez 0:c2dff8cbb91a 575 case LWM2M_TYPE_FLOAT:
terencez 0:c2dff8cbb91a 576 {
terencez 0:c2dff8cbb91a 577 double diff;
terencez 0:c2dff8cbb91a 578
terencez 0:c2dff8cbb91a 579 diff = floatValue - watcherP->lastValue.asFloat;
terencez 0:c2dff8cbb91a 580 if ((diff < 0 && (0 - diff) >= watcherP->parameters->step)
terencez 0:c2dff8cbb91a 581 || (diff >= 0 && diff >= watcherP->parameters->step))
terencez 0:c2dff8cbb91a 582 {
terencez 0:c2dff8cbb91a 583 LOG("Notify on step condition");
terencez 0:c2dff8cbb91a 584 notify = true;
terencez 0:c2dff8cbb91a 585 }
terencez 0:c2dff8cbb91a 586 }
terencez 0:c2dff8cbb91a 587 break;
terencez 0:c2dff8cbb91a 588 default:
terencez 0:c2dff8cbb91a 589 break;
terencez 0:c2dff8cbb91a 590 }
terencez 0:c2dff8cbb91a 591 }
terencez 0:c2dff8cbb91a 592 }
terencez 0:c2dff8cbb91a 593
terencez 0:c2dff8cbb91a 594 if (watcherP->parameters != NULL
terencez 0:c2dff8cbb91a 595 && (watcherP->parameters->toSet & LWM2M_ATTR_FLAG_MIN_PERIOD) != 0)
terencez 0:c2dff8cbb91a 596 {
terencez 0:c2dff8cbb91a 597 LOG_ARG("Checking minimal period (%d s)", watcherP->parameters->minPeriod);
terencez 0:c2dff8cbb91a 598
terencez 0:c2dff8cbb91a 599 if (watcherP->lastTime + watcherP->parameters->minPeriod > currentTime)
terencez 0:c2dff8cbb91a 600 {
terencez 0:c2dff8cbb91a 601 // Minimum Period did not elapse yet
terencez 0:c2dff8cbb91a 602 interval = watcherP->lastTime + watcherP->parameters->minPeriod - currentTime;
terencez 0:c2dff8cbb91a 603 if (*timeoutP > interval) *timeoutP = interval;
terencez 0:c2dff8cbb91a 604 notify = false;
terencez 0:c2dff8cbb91a 605 }
terencez 0:c2dff8cbb91a 606 else
terencez 0:c2dff8cbb91a 607 {
terencez 0:c2dff8cbb91a 608 LOG("Notify on minimal period");
terencez 0:c2dff8cbb91a 609 notify = true;
terencez 0:c2dff8cbb91a 610 }
terencez 0:c2dff8cbb91a 611 }
terencez 0:c2dff8cbb91a 612 }
terencez 0:c2dff8cbb91a 613
terencez 0:c2dff8cbb91a 614 // Is the Maximum Period reached ?
terencez 0:c2dff8cbb91a 615 if (notify == false
terencez 0:c2dff8cbb91a 616 && watcherP->parameters != NULL
terencez 0:c2dff8cbb91a 617 && (watcherP->parameters->toSet & LWM2M_ATTR_FLAG_MAX_PERIOD) != 0)
terencez 0:c2dff8cbb91a 618 {
terencez 0:c2dff8cbb91a 619 LOG_ARG("Checking maximal period (%d s)", watcherP->parameters->minPeriod);
terencez 0:c2dff8cbb91a 620
terencez 0:c2dff8cbb91a 621 if (watcherP->lastTime + watcherP->parameters->maxPeriod <= currentTime)
terencez 0:c2dff8cbb91a 622 {
terencez 0:c2dff8cbb91a 623 LOG("Notify on maximal period");
terencez 0:c2dff8cbb91a 624 notify = true;
terencez 0:c2dff8cbb91a 625 }
terencez 0:c2dff8cbb91a 626 }
terencez 0:c2dff8cbb91a 627
terencez 0:c2dff8cbb91a 628 if (notify == true)
terencez 0:c2dff8cbb91a 629 {
terencez 0:c2dff8cbb91a 630 if (buffer == NULL)
terencez 0:c2dff8cbb91a 631 {
terencez 0:c2dff8cbb91a 632 if (dataP != NULL)
terencez 0:c2dff8cbb91a 633 {
terencez 0:c2dff8cbb91a 634 int res;
terencez 0:c2dff8cbb91a 635
terencez 0:c2dff8cbb91a 636 res = lwm2m_data_serialize(&targetP->uri, size, dataP, &format, &buffer);
terencez 0:c2dff8cbb91a 637 if (res < 0)
terencez 0:c2dff8cbb91a 638 {
terencez 0:c2dff8cbb91a 639 break;
terencez 0:c2dff8cbb91a 640 }
terencez 0:c2dff8cbb91a 641 else
terencez 0:c2dff8cbb91a 642 {
terencez 0:c2dff8cbb91a 643 length = (size_t)res;
terencez 0:c2dff8cbb91a 644 }
terencez 0:c2dff8cbb91a 645
terencez 0:c2dff8cbb91a 646 }
terencez 0:c2dff8cbb91a 647 else
terencez 0:c2dff8cbb91a 648 {
terencez 0:c2dff8cbb91a 649 if (COAP_205_CONTENT != object_read(contextP, &targetP->uri, &format, &buffer, &length))
terencez 0:c2dff8cbb91a 650 {
terencez 0:c2dff8cbb91a 651 buffer = NULL;
terencez 0:c2dff8cbb91a 652 break;
terencez 0:c2dff8cbb91a 653 }
terencez 0:c2dff8cbb91a 654 }
terencez 0:c2dff8cbb91a 655 coap_init_message(message, COAP_TYPE_NON, COAP_205_CONTENT, 0);
terencez 0:c2dff8cbb91a 656 coap_set_header_content_type(message, format);
terencez 0:c2dff8cbb91a 657 coap_set_payload(message, buffer, length);
terencez 0:c2dff8cbb91a 658 }
terencez 0:c2dff8cbb91a 659 watcherP->lastTime = currentTime;
terencez 0:c2dff8cbb91a 660 watcherP->lastMid = contextP->nextMID++;
terencez 0:c2dff8cbb91a 661 message->mid = watcherP->lastMid;
terencez 0:c2dff8cbb91a 662 coap_set_header_token(message, watcherP->token, watcherP->tokenLen);
terencez 0:c2dff8cbb91a 663 coap_set_header_observe(message, watcherP->counter++);
terencez 0:c2dff8cbb91a 664 (void)message_send(contextP, message, watcherP->server->sessionH);
terencez 0:c2dff8cbb91a 665 watcherP->update = false;
terencez 0:c2dff8cbb91a 666 }
terencez 0:c2dff8cbb91a 667
terencez 0:c2dff8cbb91a 668 // Store this value
terencez 0:c2dff8cbb91a 669 if (notify == true && storeValue == true)
terencez 0:c2dff8cbb91a 670 {
terencez 0:c2dff8cbb91a 671 switch (dataP->type)
terencez 0:c2dff8cbb91a 672 {
terencez 0:c2dff8cbb91a 673 case LWM2M_TYPE_INTEGER:
terencez 0:c2dff8cbb91a 674 watcherP->lastValue.asInteger = integerValue;
terencez 0:c2dff8cbb91a 675 break;
terencez 0:c2dff8cbb91a 676 case LWM2M_TYPE_FLOAT:
terencez 0:c2dff8cbb91a 677 watcherP->lastValue.asFloat = floatValue;
terencez 0:c2dff8cbb91a 678 break;
terencez 0:c2dff8cbb91a 679 default:
terencez 0:c2dff8cbb91a 680 break;
terencez 0:c2dff8cbb91a 681 }
terencez 0:c2dff8cbb91a 682 }
terencez 0:c2dff8cbb91a 683
terencez 0:c2dff8cbb91a 684 if (watcherP->parameters != NULL && (watcherP->parameters->toSet & LWM2M_ATTR_FLAG_MAX_PERIOD) != 0)
terencez 0:c2dff8cbb91a 685 {
terencez 0:c2dff8cbb91a 686 // update timers
terencez 0:c2dff8cbb91a 687 interval = watcherP->lastTime + watcherP->parameters->maxPeriod - currentTime;
terencez 0:c2dff8cbb91a 688 if (*timeoutP > interval) *timeoutP = interval;
terencez 0:c2dff8cbb91a 689 }
terencez 0:c2dff8cbb91a 690 }
terencez 0:c2dff8cbb91a 691 }
terencez 0:c2dff8cbb91a 692 if (dataP != NULL) lwm2m_data_free(size, dataP);
terencez 0:c2dff8cbb91a 693 if (buffer != NULL) lwm2m_free(buffer);
terencez 0:c2dff8cbb91a 694 }
terencez 0:c2dff8cbb91a 695 }
terencez 0:c2dff8cbb91a 696
terencez 0:c2dff8cbb91a 697 #endif
terencez 0:c2dff8cbb91a 698
terencez 0:c2dff8cbb91a 699 #ifdef LWM2M_SERVER_MODE
terencez 0:c2dff8cbb91a 700
terencez 0:c2dff8cbb91a 701 typedef struct
terencez 0:c2dff8cbb91a 702 {
terencez 0:c2dff8cbb91a 703 lwm2m_observation_t * observationP;
terencez 0:c2dff8cbb91a 704 lwm2m_result_callback_t callbackP;
terencez 0:c2dff8cbb91a 705 void * userDataP;
terencez 0:c2dff8cbb91a 706 } cancellation_data_t;
terencez 0:c2dff8cbb91a 707
terencez 0:c2dff8cbb91a 708 static lwm2m_observation_t * prv_findObservationByURI(lwm2m_client_t * clientP,
terencez 0:c2dff8cbb91a 709 lwm2m_uri_t * uriP)
terencez 0:c2dff8cbb91a 710 {
terencez 0:c2dff8cbb91a 711 lwm2m_observation_t * targetP;
terencez 0:c2dff8cbb91a 712
terencez 0:c2dff8cbb91a 713 targetP = clientP->observationList;
terencez 0:c2dff8cbb91a 714 while (targetP != NULL)
terencez 0:c2dff8cbb91a 715 {
terencez 0:c2dff8cbb91a 716 if (targetP->uri.objectId == uriP->objectId
terencez 0:c2dff8cbb91a 717 && targetP->uri.flag == uriP->flag
terencez 0:c2dff8cbb91a 718 && targetP->uri.instanceId == uriP->instanceId
terencez 0:c2dff8cbb91a 719 && targetP->uri.resourceId == uriP->resourceId)
terencez 0:c2dff8cbb91a 720 {
terencez 0:c2dff8cbb91a 721 return targetP;
terencez 0:c2dff8cbb91a 722 }
terencez 0:c2dff8cbb91a 723
terencez 0:c2dff8cbb91a 724 targetP = targetP->next;
terencez 0:c2dff8cbb91a 725 }
terencez 0:c2dff8cbb91a 726
terencez 0:c2dff8cbb91a 727 return targetP;
terencez 0:c2dff8cbb91a 728 }
terencez 0:c2dff8cbb91a 729
terencez 0:c2dff8cbb91a 730 void observe_remove(lwm2m_observation_t * observationP)
terencez 0:c2dff8cbb91a 731 {
terencez 0:c2dff8cbb91a 732 LOG("Entering");
terencez 0:c2dff8cbb91a 733 observationP->clientP->observationList = (lwm2m_observation_t *) LWM2M_LIST_RM(observationP->clientP->observationList, observationP->id, NULL);
terencez 0:c2dff8cbb91a 734 lwm2m_free(observationP);
terencez 0:c2dff8cbb91a 735 }
terencez 0:c2dff8cbb91a 736
terencez 0:c2dff8cbb91a 737 static void prv_obsRequestCallback(lwm2m_transaction_t * transacP,
terencez 0:c2dff8cbb91a 738 void * message)
terencez 0:c2dff8cbb91a 739 {
terencez 0:c2dff8cbb91a 740 lwm2m_observation_t * observationP = (lwm2m_observation_t *)transacP->userData;
terencez 0:c2dff8cbb91a 741 coap_packet_t * packet = (coap_packet_t *)message;
terencez 0:c2dff8cbb91a 742 uint8_t code;
terencez 0:c2dff8cbb91a 743
terencez 0:c2dff8cbb91a 744 switch (observationP->status)
terencez 0:c2dff8cbb91a 745 {
terencez 0:c2dff8cbb91a 746 case STATE_DEREG_PENDING:
terencez 0:c2dff8cbb91a 747 // Observation was canceled by the user.
terencez 0:c2dff8cbb91a 748 observe_remove(observationP);
terencez 0:c2dff8cbb91a 749 return;
terencez 0:c2dff8cbb91a 750
terencez 0:c2dff8cbb91a 751 case STATE_REG_PENDING:
terencez 0:c2dff8cbb91a 752 observationP->status = STATE_REGISTERED;
terencez 0:c2dff8cbb91a 753 break;
terencez 0:c2dff8cbb91a 754
terencez 0:c2dff8cbb91a 755 default:
terencez 0:c2dff8cbb91a 756 break;
terencez 0:c2dff8cbb91a 757 }
terencez 0:c2dff8cbb91a 758
terencez 0:c2dff8cbb91a 759 if (message == NULL)
terencez 0:c2dff8cbb91a 760 {
terencez 0:c2dff8cbb91a 761 code = COAP_503_SERVICE_UNAVAILABLE;
terencez 0:c2dff8cbb91a 762 }
terencez 0:c2dff8cbb91a 763 else if (packet->code == COAP_205_CONTENT
terencez 0:c2dff8cbb91a 764 && !IS_OPTION(packet, COAP_OPTION_OBSERVE))
terencez 0:c2dff8cbb91a 765 {
terencez 0:c2dff8cbb91a 766 code = COAP_405_METHOD_NOT_ALLOWED;
terencez 0:c2dff8cbb91a 767 }
terencez 0:c2dff8cbb91a 768 else
terencez 0:c2dff8cbb91a 769 {
terencez 0:c2dff8cbb91a 770 code = packet->code;
terencez 0:c2dff8cbb91a 771 }
terencez 0:c2dff8cbb91a 772
terencez 0:c2dff8cbb91a 773 if (code != COAP_205_CONTENT)
terencez 0:c2dff8cbb91a 774 {
terencez 0:c2dff8cbb91a 775 observationP->callback(observationP->clientP->internalID,
terencez 0:c2dff8cbb91a 776 &observationP->uri,
terencez 0:c2dff8cbb91a 777 code,
terencez 0:c2dff8cbb91a 778 LWM2M_CONTENT_TEXT, NULL, 0,
terencez 0:c2dff8cbb91a 779 observationP->userData);
terencez 0:c2dff8cbb91a 780 observe_remove(observationP);
terencez 0:c2dff8cbb91a 781 }
terencez 0:c2dff8cbb91a 782 else
terencez 0:c2dff8cbb91a 783 {
terencez 0:c2dff8cbb91a 784 observationP->callback(observationP->clientP->internalID,
terencez 0:c2dff8cbb91a 785 &observationP->uri,
terencez 0:c2dff8cbb91a 786 0,
terencez 0:c2dff8cbb91a 787 packet->content_type, packet->payload, packet->payload_len,
terencez 0:c2dff8cbb91a 788 observationP->userData);
terencez 0:c2dff8cbb91a 789 }
terencez 0:c2dff8cbb91a 790 }
terencez 0:c2dff8cbb91a 791
terencez 0:c2dff8cbb91a 792
terencez 0:c2dff8cbb91a 793 static void prv_obsCancelRequestCallback(lwm2m_transaction_t * transacP,
terencez 0:c2dff8cbb91a 794 void * message)
terencez 0:c2dff8cbb91a 795 {
terencez 0:c2dff8cbb91a 796 cancellation_data_t * cancelP = (cancellation_data_t *)transacP->userData;
terencez 0:c2dff8cbb91a 797 coap_packet_t * packet = (coap_packet_t *)message;
terencez 0:c2dff8cbb91a 798 uint8_t code;
terencez 0:c2dff8cbb91a 799
terencez 0:c2dff8cbb91a 800 if (message == NULL)
terencez 0:c2dff8cbb91a 801 {
terencez 0:c2dff8cbb91a 802 code = COAP_503_SERVICE_UNAVAILABLE;
terencez 0:c2dff8cbb91a 803 }
terencez 0:c2dff8cbb91a 804 else
terencez 0:c2dff8cbb91a 805 {
terencez 0:c2dff8cbb91a 806 code = packet->code;
terencez 0:c2dff8cbb91a 807 }
terencez 0:c2dff8cbb91a 808
terencez 0:c2dff8cbb91a 809 if (code != COAP_205_CONTENT)
terencez 0:c2dff8cbb91a 810 {
terencez 0:c2dff8cbb91a 811 cancelP->callbackP(cancelP->observationP->clientP->internalID,
terencez 0:c2dff8cbb91a 812 &cancelP->observationP->uri,
terencez 0:c2dff8cbb91a 813 code,
terencez 0:c2dff8cbb91a 814 LWM2M_CONTENT_TEXT, NULL, 0,
terencez 0:c2dff8cbb91a 815 cancelP->userDataP);
terencez 0:c2dff8cbb91a 816 }
terencez 0:c2dff8cbb91a 817 else
terencez 0:c2dff8cbb91a 818 {
terencez 0:c2dff8cbb91a 819 cancelP->callbackP(cancelP->observationP->clientP->internalID,
terencez 0:c2dff8cbb91a 820 &cancelP->observationP->uri,
terencez 0:c2dff8cbb91a 821 0,
terencez 0:c2dff8cbb91a 822 packet->content_type, packet->payload, packet->payload_len,
terencez 0:c2dff8cbb91a 823 cancelP->userDataP);
terencez 0:c2dff8cbb91a 824 }
terencez 0:c2dff8cbb91a 825
terencez 0:c2dff8cbb91a 826 observe_remove(cancelP->observationP);
terencez 0:c2dff8cbb91a 827
terencez 0:c2dff8cbb91a 828 lwm2m_free(cancelP);
terencez 0:c2dff8cbb91a 829 }
terencez 0:c2dff8cbb91a 830
terencez 0:c2dff8cbb91a 831
terencez 0:c2dff8cbb91a 832 int lwm2m_observe(lwm2m_context_t * contextP,
terencez 0:c2dff8cbb91a 833 uint16_t clientID,
terencez 0:c2dff8cbb91a 834 lwm2m_uri_t * uriP,
terencez 0:c2dff8cbb91a 835 lwm2m_result_callback_t callback,
terencez 0:c2dff8cbb91a 836 void * userData)
terencez 0:c2dff8cbb91a 837 {
terencez 0:c2dff8cbb91a 838 lwm2m_client_t * clientP;
terencez 0:c2dff8cbb91a 839 lwm2m_transaction_t * transactionP;
terencez 0:c2dff8cbb91a 840 lwm2m_observation_t * observationP;
terencez 0:c2dff8cbb91a 841 uint8_t token[4];
terencez 0:c2dff8cbb91a 842
terencez 0:c2dff8cbb91a 843 LOG_ARG("clientID: %d", clientID);
terencez 0:c2dff8cbb91a 844 LOG_URI(uriP);
terencez 0:c2dff8cbb91a 845
terencez 0:c2dff8cbb91a 846 if (!LWM2M_URI_IS_SET_INSTANCE(uriP) && LWM2M_URI_IS_SET_RESOURCE(uriP)) return COAP_400_BAD_REQUEST;
terencez 0:c2dff8cbb91a 847
terencez 0:c2dff8cbb91a 848 clientP = (lwm2m_client_t *)lwm2m_list_find((lwm2m_list_t *)contextP->clientList, clientID);
terencez 0:c2dff8cbb91a 849 if (clientP == NULL) return COAP_404_NOT_FOUND;
terencez 0:c2dff8cbb91a 850
terencez 0:c2dff8cbb91a 851 observationP = (lwm2m_observation_t *)lwm2m_malloc(sizeof(lwm2m_observation_t));
terencez 0:c2dff8cbb91a 852 if (observationP == NULL) return COAP_500_INTERNAL_SERVER_ERROR;
terencez 0:c2dff8cbb91a 853 memset(observationP, 0, sizeof(lwm2m_observation_t));
terencez 0:c2dff8cbb91a 854
terencez 0:c2dff8cbb91a 855 observationP->id = lwm2m_list_newId((lwm2m_list_t *)clientP->observationList);
terencez 0:c2dff8cbb91a 856 memcpy(&observationP->uri, uriP, sizeof(lwm2m_uri_t));
terencez 0:c2dff8cbb91a 857 observationP->clientP = clientP;
terencez 0:c2dff8cbb91a 858 observationP->status = STATE_REG_PENDING;
terencez 0:c2dff8cbb91a 859 observationP->callback = callback;
terencez 0:c2dff8cbb91a 860 observationP->userData = userData;
terencez 0:c2dff8cbb91a 861
terencez 0:c2dff8cbb91a 862 token[0] = clientP->internalID >> 8;
terencez 0:c2dff8cbb91a 863 token[1] = clientP->internalID & 0xFF;
terencez 0:c2dff8cbb91a 864 token[2] = observationP->id >> 8;
terencez 0:c2dff8cbb91a 865 token[3] = observationP->id & 0xFF;
terencez 0:c2dff8cbb91a 866
terencez 0:c2dff8cbb91a 867 transactionP = transaction_new(clientP->sessionH, COAP_GET, clientP->altPath, uriP, contextP->nextMID++, 4, token);
terencez 0:c2dff8cbb91a 868 if (transactionP == NULL)
terencez 0:c2dff8cbb91a 869 {
terencez 0:c2dff8cbb91a 870 lwm2m_free(observationP);
terencez 0:c2dff8cbb91a 871 return COAP_500_INTERNAL_SERVER_ERROR;
terencez 0:c2dff8cbb91a 872 }
terencez 0:c2dff8cbb91a 873
terencez 0:c2dff8cbb91a 874 observationP->clientP->observationList = (lwm2m_observation_t *)LWM2M_LIST_ADD(observationP->clientP->observationList, observationP);
terencez 0:c2dff8cbb91a 875
terencez 0:c2dff8cbb91a 876 coap_set_header_observe(transactionP->message, 0);
terencez 0:c2dff8cbb91a 877 coap_set_header_token(transactionP->message, token, sizeof(token));
terencez 0:c2dff8cbb91a 878
terencez 0:c2dff8cbb91a 879 transactionP->callback = prv_obsRequestCallback;
terencez 0:c2dff8cbb91a 880 transactionP->userData = (void *)observationP;
terencez 0:c2dff8cbb91a 881
terencez 0:c2dff8cbb91a 882 contextP->transactionList = (lwm2m_transaction_t *)LWM2M_LIST_ADD(contextP->transactionList, transactionP);
terencez 0:c2dff8cbb91a 883
terencez 0:c2dff8cbb91a 884 return transaction_send(contextP, transactionP);
terencez 0:c2dff8cbb91a 885 }
terencez 0:c2dff8cbb91a 886
terencez 0:c2dff8cbb91a 887 int lwm2m_observe_cancel(lwm2m_context_t * contextP,
terencez 0:c2dff8cbb91a 888 uint16_t clientID,
terencez 0:c2dff8cbb91a 889 lwm2m_uri_t * uriP,
terencez 0:c2dff8cbb91a 890 lwm2m_result_callback_t callback,
terencez 0:c2dff8cbb91a 891 void * userData)
terencez 0:c2dff8cbb91a 892 {
terencez 0:c2dff8cbb91a 893 lwm2m_client_t * clientP;
terencez 0:c2dff8cbb91a 894 lwm2m_observation_t * observationP;
terencez 0:c2dff8cbb91a 895
terencez 0:c2dff8cbb91a 896 LOG_ARG("clientID: %d", clientID);
terencez 0:c2dff8cbb91a 897 LOG_URI(uriP);
terencez 0:c2dff8cbb91a 898
terencez 0:c2dff8cbb91a 899 clientP = (lwm2m_client_t *)lwm2m_list_find((lwm2m_list_t *)contextP->clientList, clientID);
terencez 0:c2dff8cbb91a 900 if (clientP == NULL) return COAP_404_NOT_FOUND;
terencez 0:c2dff8cbb91a 901
terencez 0:c2dff8cbb91a 902 observationP = prv_findObservationByURI(clientP, uriP);
terencez 0:c2dff8cbb91a 903 if (observationP == NULL) return COAP_404_NOT_FOUND;
terencez 0:c2dff8cbb91a 904
terencez 0:c2dff8cbb91a 905 switch (observationP->status)
terencez 0:c2dff8cbb91a 906 {
terencez 0:c2dff8cbb91a 907 case STATE_REGISTERED:
terencez 0:c2dff8cbb91a 908 {
terencez 0:c2dff8cbb91a 909 lwm2m_transaction_t * transactionP;
terencez 0:c2dff8cbb91a 910 cancellation_data_t * cancelP;
terencez 0:c2dff8cbb91a 911
terencez 0:c2dff8cbb91a 912 transactionP = transaction_new(clientP->sessionH, COAP_GET, clientP->altPath, uriP, contextP->nextMID++, 0, NULL);
terencez 0:c2dff8cbb91a 913 if (transactionP == NULL)
terencez 0:c2dff8cbb91a 914 {
terencez 0:c2dff8cbb91a 915 return COAP_500_INTERNAL_SERVER_ERROR;
terencez 0:c2dff8cbb91a 916 }
terencez 0:c2dff8cbb91a 917 cancelP = (cancellation_data_t *)lwm2m_malloc(sizeof(cancellation_data_t));
terencez 0:c2dff8cbb91a 918 if (cancelP == NULL)
terencez 0:c2dff8cbb91a 919 {
terencez 0:c2dff8cbb91a 920 lwm2m_free(transactionP);
terencez 0:c2dff8cbb91a 921 return COAP_500_INTERNAL_SERVER_ERROR;
terencez 0:c2dff8cbb91a 922 }
terencez 0:c2dff8cbb91a 923
terencez 0:c2dff8cbb91a 924 coap_set_header_observe(transactionP->message, 1);
terencez 0:c2dff8cbb91a 925
terencez 0:c2dff8cbb91a 926 cancelP->observationP = observationP;
terencez 0:c2dff8cbb91a 927 cancelP->callbackP = callback;
terencez 0:c2dff8cbb91a 928 cancelP->userDataP = userData;
terencez 0:c2dff8cbb91a 929
terencez 0:c2dff8cbb91a 930 transactionP->callback = prv_obsCancelRequestCallback;
terencez 0:c2dff8cbb91a 931 transactionP->userData = (void *)cancelP;
terencez 0:c2dff8cbb91a 932
terencez 0:c2dff8cbb91a 933 contextP->transactionList = (lwm2m_transaction_t *)LWM2M_LIST_ADD(contextP->transactionList, transactionP);
terencez 0:c2dff8cbb91a 934
terencez 0:c2dff8cbb91a 935 return transaction_send(contextP, transactionP);
terencez 0:c2dff8cbb91a 936 }
terencez 0:c2dff8cbb91a 937
terencez 0:c2dff8cbb91a 938 case STATE_REG_PENDING:
terencez 0:c2dff8cbb91a 939 observationP->status = STATE_DEREG_PENDING;
terencez 0:c2dff8cbb91a 940 break;
terencez 0:c2dff8cbb91a 941
terencez 0:c2dff8cbb91a 942 default:
terencez 0:c2dff8cbb91a 943 // Should not happen
terencez 0:c2dff8cbb91a 944 break;
terencez 0:c2dff8cbb91a 945 }
terencez 0:c2dff8cbb91a 946
terencez 0:c2dff8cbb91a 947 return COAP_NO_ERROR;
terencez 0:c2dff8cbb91a 948 }
terencez 0:c2dff8cbb91a 949
terencez 0:c2dff8cbb91a 950 bool observe_handleNotify(lwm2m_context_t * contextP,
terencez 0:c2dff8cbb91a 951 void * fromSessionH,
terencez 0:c2dff8cbb91a 952 coap_packet_t * message,
terencez 0:c2dff8cbb91a 953 coap_packet_t * response)
terencez 0:c2dff8cbb91a 954 {
terencez 0:c2dff8cbb91a 955 uint8_t * tokenP;
terencez 0:c2dff8cbb91a 956 int token_len;
terencez 0:c2dff8cbb91a 957 uint16_t clientID;
terencez 0:c2dff8cbb91a 958 uint16_t obsID;
terencez 0:c2dff8cbb91a 959 lwm2m_client_t * clientP;
terencez 0:c2dff8cbb91a 960 lwm2m_observation_t * observationP;
terencez 0:c2dff8cbb91a 961 uint32_t count;
terencez 0:c2dff8cbb91a 962
terencez 0:c2dff8cbb91a 963 LOG("Entering");
terencez 0:c2dff8cbb91a 964 token_len = coap_get_header_token(message, (const uint8_t **)&tokenP);
terencez 0:c2dff8cbb91a 965 if (token_len != sizeof(uint32_t)) return false;
terencez 0:c2dff8cbb91a 966
terencez 0:c2dff8cbb91a 967 if (1 != coap_get_header_observe(message, &count)) return false;
terencez 0:c2dff8cbb91a 968
terencez 0:c2dff8cbb91a 969 clientID = (tokenP[0] << 8) | tokenP[1];
terencez 0:c2dff8cbb91a 970 obsID = (tokenP[2] << 8) | tokenP[3];
terencez 0:c2dff8cbb91a 971
terencez 0:c2dff8cbb91a 972 clientP = (lwm2m_client_t *)lwm2m_list_find((lwm2m_list_t *)contextP->clientList, clientID);
terencez 0:c2dff8cbb91a 973 if (clientP == NULL) return false;
terencez 0:c2dff8cbb91a 974
terencez 0:c2dff8cbb91a 975 observationP = (lwm2m_observation_t *)lwm2m_list_find((lwm2m_list_t *)clientP->observationList, obsID);
terencez 0:c2dff8cbb91a 976 if (observationP == NULL)
terencez 0:c2dff8cbb91a 977 {
terencez 0:c2dff8cbb91a 978 coap_init_message(response, COAP_TYPE_RST, 0, message->mid);
terencez 0:c2dff8cbb91a 979 message_send(contextP, response, fromSessionH);
terencez 0:c2dff8cbb91a 980 }
terencez 0:c2dff8cbb91a 981 else
terencez 0:c2dff8cbb91a 982 {
terencez 0:c2dff8cbb91a 983 if (message->type == COAP_TYPE_CON ) {
terencez 0:c2dff8cbb91a 984 coap_init_message(response, COAP_TYPE_ACK, 0, message->mid);
terencez 0:c2dff8cbb91a 985 message_send(contextP, response, fromSessionH);
terencez 0:c2dff8cbb91a 986 }
terencez 0:c2dff8cbb91a 987 observationP->callback(clientID,
terencez 0:c2dff8cbb91a 988 &observationP->uri,
terencez 0:c2dff8cbb91a 989 (int)count,
terencez 0:c2dff8cbb91a 990 message->content_type, message->payload, message->payload_len,
terencez 0:c2dff8cbb91a 991 observationP->userData);
terencez 0:c2dff8cbb91a 992 }
terencez 0:c2dff8cbb91a 993 return true;
terencez 0:c2dff8cbb91a 994 }
terencez 0:c2dff8cbb91a 995 #endif