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

Dependencies:   C12832 LM75B

Committer:
terencez
Date:
Mon Apr 24 23:03:31 2017 +0000
Revision:
0:f9d13e09cf11
Child:
3:a280069151ac
The first compiled submit.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
terencez 0:f9d13e09cf11 1 /*******************************************************************************
terencez 0:f9d13e09cf11 2 *
terencez 0:f9d13e09cf11 3 * Copyright (c) 2013, 2014 Intel Corporation and others.
terencez 0:f9d13e09cf11 4 * All rights reserved. This program and the accompanying materials
terencez 0:f9d13e09cf11 5 * are made available under the terms of the Eclipse Public License v1.0
terencez 0:f9d13e09cf11 6 * and Eclipse Distribution License v1.0 which accompany this distribution.
terencez 0:f9d13e09cf11 7 *
terencez 0:f9d13e09cf11 8 * The Eclipse Public License is available at
terencez 0:f9d13e09cf11 9 * http://www.eclipse.org/legal/epl-v10.html
terencez 0:f9d13e09cf11 10 * The Eclipse Distribution License is available at
terencez 0:f9d13e09cf11 11 * http://www.eclipse.org/org/documents/edl-v10.php.
terencez 0:f9d13e09cf11 12 *
terencez 0:f9d13e09cf11 13 * Contributors:
terencez 0:f9d13e09cf11 14 * David Navarro, Intel Corporation - initial API and implementation
terencez 0:f9d13e09cf11 15 * Toby Jaffey - Please refer to git log
terencez 0:f9d13e09cf11 16 *
terencez 0:f9d13e09cf11 17 *******************************************************************************/
terencez 0:f9d13e09cf11 18
terencez 0:f9d13e09cf11 19 /*
terencez 0:f9d13e09cf11 20 Copyright (c) 2013, 2014 Intel Corporation
terencez 0:f9d13e09cf11 21
terencez 0:f9d13e09cf11 22 Redistribution and use in source and binary forms, with or without modification,
terencez 0:f9d13e09cf11 23 are permitted provided that the following conditions are met:
terencez 0:f9d13e09cf11 24
terencez 0:f9d13e09cf11 25 * Redistributions of source code must retain the above copyright notice,
terencez 0:f9d13e09cf11 26 this list of conditions and the following disclaimer.
terencez 0:f9d13e09cf11 27 * Redistributions in binary form must reproduce the above copyright notice,
terencez 0:f9d13e09cf11 28 this list of conditions and the following disclaimer in the documentation
terencez 0:f9d13e09cf11 29 and/or other materials provided with the distribution.
terencez 0:f9d13e09cf11 30 * Neither the name of Intel Corporation nor the names of its contributors
terencez 0:f9d13e09cf11 31 may be used to endorse or promote products derived from this software
terencez 0:f9d13e09cf11 32 without specific prior written permission.
terencez 0:f9d13e09cf11 33
terencez 0:f9d13e09cf11 34 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
terencez 0:f9d13e09cf11 35 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
terencez 0:f9d13e09cf11 36 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
terencez 0:f9d13e09cf11 37 IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
terencez 0:f9d13e09cf11 38 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
terencez 0:f9d13e09cf11 39 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
terencez 0:f9d13e09cf11 40 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
terencez 0:f9d13e09cf11 41 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
terencez 0:f9d13e09cf11 42 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
terencez 0:f9d13e09cf11 43 THE POSSIBILITY OF SUCH DAMAGE.
terencez 0:f9d13e09cf11 44
terencez 0:f9d13e09cf11 45 David Navarro <david.navarro@intel.com>
terencez 0:f9d13e09cf11 46
terencez 0:f9d13e09cf11 47 */
terencez 0:f9d13e09cf11 48
terencez 0:f9d13e09cf11 49 #include "internals.h"
terencez 0:f9d13e09cf11 50 #include <stdio.h>
terencez 0:f9d13e09cf11 51
terencez 0:f9d13e09cf11 52
terencez 0:f9d13e09cf11 53 #ifdef LWM2M_CLIENT_MODE
terencez 0:f9d13e09cf11 54 static lwm2m_observed_t * prv_findObserved(lwm2m_context_t * contextP,
terencez 0:f9d13e09cf11 55 lwm2m_uri_t * uriP)
terencez 0:f9d13e09cf11 56 {
terencez 0:f9d13e09cf11 57 lwm2m_observed_t * targetP;
terencez 0:f9d13e09cf11 58
terencez 0:f9d13e09cf11 59 targetP = contextP->observedList;
terencez 0:f9d13e09cf11 60 while (targetP != NULL
terencez 0:f9d13e09cf11 61 && (targetP->uri.objectId != uriP->objectId
terencez 0:f9d13e09cf11 62 || targetP->uri.flag != uriP->flag
terencez 0:f9d13e09cf11 63 || (LWM2M_URI_IS_SET_INSTANCE(uriP) && targetP->uri.instanceId != uriP->instanceId)
terencez 0:f9d13e09cf11 64 || (LWM2M_URI_IS_SET_RESOURCE(uriP) && targetP->uri.resourceId != uriP->resourceId)))
terencez 0:f9d13e09cf11 65 {
terencez 0:f9d13e09cf11 66 targetP = targetP->next;
terencez 0:f9d13e09cf11 67 }
terencez 0:f9d13e09cf11 68
terencez 0:f9d13e09cf11 69 return targetP;
terencez 0:f9d13e09cf11 70 }
terencez 0:f9d13e09cf11 71
terencez 0:f9d13e09cf11 72 static obs_list_t * prv_getObservedList(lwm2m_context_t * contextP,
terencez 0:f9d13e09cf11 73 lwm2m_uri_t * uriP)
terencez 0:f9d13e09cf11 74 {
terencez 0:f9d13e09cf11 75 obs_list_t * resultP;
terencez 0:f9d13e09cf11 76 lwm2m_observed_t * targetP;
terencez 0:f9d13e09cf11 77
terencez 0:f9d13e09cf11 78 resultP = NULL;
terencez 0:f9d13e09cf11 79
terencez 0:f9d13e09cf11 80 targetP = contextP->observedList;
terencez 0:f9d13e09cf11 81 while (targetP != NULL)
terencez 0:f9d13e09cf11 82 {
terencez 0:f9d13e09cf11 83 if (targetP->uri.objectId == uriP->objectId)
terencez 0:f9d13e09cf11 84 {
terencez 0:f9d13e09cf11 85 if (!LWM2M_URI_IS_SET_INSTANCE(uriP)
terencez 0:f9d13e09cf11 86 || (targetP->uri.flag & LWM2M_URI_FLAG_INSTANCE_ID) == 0
terencez 0:f9d13e09cf11 87 || uriP->instanceId == targetP->uri.instanceId)
terencez 0:f9d13e09cf11 88 {
terencez 0:f9d13e09cf11 89 if (!LWM2M_URI_IS_SET_RESOURCE(uriP)
terencez 0:f9d13e09cf11 90 || (targetP->uri.flag & LWM2M_URI_FLAG_RESOURCE_ID) == 0
terencez 0:f9d13e09cf11 91 || uriP->resourceId == targetP->uri.resourceId)
terencez 0:f9d13e09cf11 92 {
terencez 0:f9d13e09cf11 93 obs_list_t * newP;
terencez 0:f9d13e09cf11 94
terencez 0:f9d13e09cf11 95 newP = (obs_list_t *)lwm2m_malloc(sizeof(obs_list_t));
terencez 0:f9d13e09cf11 96 if (newP != NULL)
terencez 0:f9d13e09cf11 97 {
terencez 0:f9d13e09cf11 98 newP->item = targetP;
terencez 0:f9d13e09cf11 99 newP->next = resultP;
terencez 0:f9d13e09cf11 100 resultP = newP;
terencez 0:f9d13e09cf11 101 }
terencez 0:f9d13e09cf11 102 }
terencez 0:f9d13e09cf11 103 }
terencez 0:f9d13e09cf11 104 }
terencez 0:f9d13e09cf11 105 targetP = targetP->next;
terencez 0:f9d13e09cf11 106 }
terencez 0:f9d13e09cf11 107
terencez 0:f9d13e09cf11 108 return resultP;
terencez 0:f9d13e09cf11 109 }
terencez 0:f9d13e09cf11 110
terencez 0:f9d13e09cf11 111 static void prv_unlinkObserved(lwm2m_context_t * contextP,
terencez 0:f9d13e09cf11 112 lwm2m_observed_t * observedP)
terencez 0:f9d13e09cf11 113 {
terencez 0:f9d13e09cf11 114 if (contextP->observedList == observedP)
terencez 0:f9d13e09cf11 115 {
terencez 0:f9d13e09cf11 116 contextP->observedList = contextP->observedList->next;
terencez 0:f9d13e09cf11 117 }
terencez 0:f9d13e09cf11 118 else
terencez 0:f9d13e09cf11 119 {
terencez 0:f9d13e09cf11 120 lwm2m_observed_t * parentP;
terencez 0:f9d13e09cf11 121
terencez 0:f9d13e09cf11 122 parentP = contextP->observedList;
terencez 0:f9d13e09cf11 123 while (parentP->next != NULL
terencez 0:f9d13e09cf11 124 && parentP->next != observedP)
terencez 0:f9d13e09cf11 125 {
terencez 0:f9d13e09cf11 126 parentP = parentP->next;
terencez 0:f9d13e09cf11 127 }
terencez 0:f9d13e09cf11 128 if (parentP->next != NULL)
terencez 0:f9d13e09cf11 129 {
terencez 0:f9d13e09cf11 130 parentP->next = parentP->next->next;
terencez 0:f9d13e09cf11 131 }
terencez 0:f9d13e09cf11 132 }
terencez 0:f9d13e09cf11 133 }
terencez 0:f9d13e09cf11 134
terencez 0:f9d13e09cf11 135 static lwm2m_server_t * prv_findServer(lwm2m_context_t * contextP,
terencez 0:f9d13e09cf11 136 void * fromSessionH)
terencez 0:f9d13e09cf11 137 {
terencez 0:f9d13e09cf11 138 lwm2m_server_t * targetP;
terencez 0:f9d13e09cf11 139
terencez 0:f9d13e09cf11 140 targetP = contextP->serverList;
terencez 0:f9d13e09cf11 141 while (targetP != NULL
terencez 0:f9d13e09cf11 142 && targetP->sessionH != fromSessionH)
terencez 0:f9d13e09cf11 143 {
terencez 0:f9d13e09cf11 144 targetP = targetP->next;
terencez 0:f9d13e09cf11 145 }
terencez 0:f9d13e09cf11 146
terencez 0:f9d13e09cf11 147 return targetP;
terencez 0:f9d13e09cf11 148 }
terencez 0:f9d13e09cf11 149
terencez 0:f9d13e09cf11 150 static lwm2m_watcher_t * prv_findWatcher(lwm2m_observed_t * observedP,
terencez 0:f9d13e09cf11 151 lwm2m_server_t * serverP)
terencez 0:f9d13e09cf11 152 {
terencez 0:f9d13e09cf11 153 lwm2m_watcher_t * targetP;
terencez 0:f9d13e09cf11 154
terencez 0:f9d13e09cf11 155 targetP = observedP->watcherList;
terencez 0:f9d13e09cf11 156 while (targetP != NULL
terencez 0:f9d13e09cf11 157 && targetP->server != serverP)
terencez 0:f9d13e09cf11 158 {
terencez 0:f9d13e09cf11 159 targetP = targetP->next;
terencez 0:f9d13e09cf11 160 }
terencez 0:f9d13e09cf11 161
terencez 0:f9d13e09cf11 162 return targetP;
terencez 0:f9d13e09cf11 163 }
terencez 0:f9d13e09cf11 164
terencez 0:f9d13e09cf11 165 coap_status_t handle_observe_request(lwm2m_context_t * contextP,
terencez 0:f9d13e09cf11 166 lwm2m_uri_t * uriP,
terencez 0:f9d13e09cf11 167 void * fromSessionH,
terencez 0:f9d13e09cf11 168 coap_packet_t * message,
terencez 0:f9d13e09cf11 169 coap_packet_t * response)
terencez 0:f9d13e09cf11 170 {
terencez 0:f9d13e09cf11 171 lwm2m_observed_t * observedP;
terencez 0:f9d13e09cf11 172 lwm2m_watcher_t * watcherP;
terencez 0:f9d13e09cf11 173 lwm2m_server_t * serverP;
terencez 0:f9d13e09cf11 174
terencez 0:f9d13e09cf11 175 LOG("handle_observe_request()\r\n");
terencez 0:f9d13e09cf11 176
terencez 0:f9d13e09cf11 177 if (!LWM2M_URI_IS_SET_INSTANCE(uriP) && LWM2M_URI_IS_SET_RESOURCE(uriP)) return COAP_400_BAD_REQUEST;
terencez 0:f9d13e09cf11 178 if (message->token_len == 0) return COAP_400_BAD_REQUEST;
terencez 0:f9d13e09cf11 179
terencez 0:f9d13e09cf11 180 serverP = prv_findServer(contextP, fromSessionH);
terencez 0:f9d13e09cf11 181 if (serverP == NULL || serverP->status != STATE_REGISTERED) return COAP_401_UNAUTHORIZED;
terencez 0:f9d13e09cf11 182
terencez 0:f9d13e09cf11 183 observedP = prv_findObserved(contextP, uriP);
terencez 0:f9d13e09cf11 184 if (observedP == NULL)
terencez 0:f9d13e09cf11 185 {
terencez 0:f9d13e09cf11 186 observedP = (lwm2m_observed_t *)lwm2m_malloc(sizeof(lwm2m_observed_t));
terencez 0:f9d13e09cf11 187 if (observedP == NULL) return COAP_500_INTERNAL_SERVER_ERROR;
terencez 0:f9d13e09cf11 188 memset(observedP, 0, sizeof(lwm2m_observed_t));
terencez 0:f9d13e09cf11 189 memcpy(&(observedP->uri), uriP, sizeof(lwm2m_uri_t));
terencez 0:f9d13e09cf11 190 observedP->next = contextP->observedList;
terencez 0:f9d13e09cf11 191 contextP->observedList = observedP;
terencez 0:f9d13e09cf11 192 }
terencez 0:f9d13e09cf11 193
terencez 0:f9d13e09cf11 194 watcherP = prv_findWatcher(observedP, serverP);
terencez 0:f9d13e09cf11 195 if (watcherP == NULL)
terencez 0:f9d13e09cf11 196 {
terencez 0:f9d13e09cf11 197 watcherP = (lwm2m_watcher_t *)lwm2m_malloc(sizeof(lwm2m_watcher_t));
terencez 0:f9d13e09cf11 198 if (watcherP == NULL) return COAP_500_INTERNAL_SERVER_ERROR;
terencez 0:f9d13e09cf11 199 memset(watcherP, 0, sizeof(lwm2m_watcher_t));
terencez 0:f9d13e09cf11 200 watcherP->server = serverP;
terencez 0:f9d13e09cf11 201 watcherP->tokenLen = message->token_len;
terencez 0:f9d13e09cf11 202 memcpy(watcherP->token, message->token, message->token_len);
terencez 0:f9d13e09cf11 203 watcherP->next = observedP->watcherList;
terencez 0:f9d13e09cf11 204 observedP->watcherList = watcherP;
terencez 0:f9d13e09cf11 205 }
terencez 0:f9d13e09cf11 206
terencez 0:f9d13e09cf11 207 coap_set_header_observe(response, watcherP->counter++);
terencez 0:f9d13e09cf11 208
terencez 0:f9d13e09cf11 209 return COAP_205_CONTENT;
terencez 0:f9d13e09cf11 210 }
terencez 0:f9d13e09cf11 211
terencez 0:f9d13e09cf11 212 void cancel_observe(lwm2m_context_t * contextP,
terencez 0:f9d13e09cf11 213 uint16_t mid,
terencez 0:f9d13e09cf11 214 void * fromSessionH)
terencez 0:f9d13e09cf11 215 {
terencez 0:f9d13e09cf11 216 lwm2m_observed_t * observedP;
terencez 0:f9d13e09cf11 217
terencez 0:f9d13e09cf11 218 LOG("cancel_observe()\r\n");
terencez 0:f9d13e09cf11 219
terencez 0:f9d13e09cf11 220 for (observedP = contextP->observedList;
terencez 0:f9d13e09cf11 221 observedP != NULL;
terencez 0:f9d13e09cf11 222 observedP = observedP->next)
terencez 0:f9d13e09cf11 223 {
terencez 0:f9d13e09cf11 224 lwm2m_watcher_t * targetP = NULL;
terencez 0:f9d13e09cf11 225
terencez 0:f9d13e09cf11 226 if (observedP->watcherList->lastMid == mid
terencez 0:f9d13e09cf11 227 && observedP->watcherList->server->sessionH == fromSessionH)
terencez 0:f9d13e09cf11 228 {
terencez 0:f9d13e09cf11 229 targetP = observedP->watcherList;
terencez 0:f9d13e09cf11 230 observedP->watcherList = observedP->watcherList->next;
terencez 0:f9d13e09cf11 231 }
terencez 0:f9d13e09cf11 232 else
terencez 0:f9d13e09cf11 233 {
terencez 0:f9d13e09cf11 234 lwm2m_watcher_t * parentP;
terencez 0:f9d13e09cf11 235
terencez 0:f9d13e09cf11 236 parentP = observedP->watcherList;
terencez 0:f9d13e09cf11 237 while (parentP->next != NULL
terencez 0:f9d13e09cf11 238 && (parentP->next->lastMid != mid
terencez 0:f9d13e09cf11 239 || parentP->next->server->sessionH != fromSessionH))
terencez 0:f9d13e09cf11 240 {
terencez 0:f9d13e09cf11 241 parentP = parentP->next;
terencez 0:f9d13e09cf11 242 }
terencez 0:f9d13e09cf11 243 if (parentP->next != NULL)
terencez 0:f9d13e09cf11 244 {
terencez 0:f9d13e09cf11 245 targetP = parentP->next;
terencez 0:f9d13e09cf11 246 parentP->next = parentP->next->next;
terencez 0:f9d13e09cf11 247 }
terencez 0:f9d13e09cf11 248 }
terencez 0:f9d13e09cf11 249 if (targetP != NULL)
terencez 0:f9d13e09cf11 250 {
terencez 0:f9d13e09cf11 251 lwm2m_free(targetP);
terencez 0:f9d13e09cf11 252 if (observedP->watcherList == NULL)
terencez 0:f9d13e09cf11 253 {
terencez 0:f9d13e09cf11 254 prv_unlinkObserved(contextP, observedP);
terencez 0:f9d13e09cf11 255 lwm2m_free(observedP);
terencez 0:f9d13e09cf11 256 }
terencez 0:f9d13e09cf11 257 return;
terencez 0:f9d13e09cf11 258 }
terencez 0:f9d13e09cf11 259 }
terencez 0:f9d13e09cf11 260 }
terencez 0:f9d13e09cf11 261
terencez 0:f9d13e09cf11 262 void lwm2m_resource_value_changed(lwm2m_context_t * contextP,
terencez 0:f9d13e09cf11 263 lwm2m_uri_t * uriP)
terencez 0:f9d13e09cf11 264 {
terencez 0:f9d13e09cf11 265 int result;
terencez 0:f9d13e09cf11 266 obs_list_t * listP;
terencez 0:f9d13e09cf11 267 lwm2m_watcher_t * watcherP;
terencez 0:f9d13e09cf11 268
terencez 0:f9d13e09cf11 269 listP = prv_getObservedList(contextP, uriP);
terencez 0:f9d13e09cf11 270 while (listP != NULL)
terencez 0:f9d13e09cf11 271 {
terencez 0:f9d13e09cf11 272 obs_list_t * targetP;
terencez 0:f9d13e09cf11 273 char * buffer = NULL;
terencez 0:f9d13e09cf11 274 int length = 0;
terencez 0:f9d13e09cf11 275
terencez 0:f9d13e09cf11 276 result = object_read(contextP, &listP->item->uri, &buffer, &length);
terencez 0:f9d13e09cf11 277 if (result == COAP_205_CONTENT)
terencez 0:f9d13e09cf11 278 {
terencez 0:f9d13e09cf11 279 coap_packet_t message[1];
terencez 0:f9d13e09cf11 280
terencez 0:f9d13e09cf11 281 coap_init_message(message, COAP_TYPE_NON, COAP_204_CHANGED, 0);
terencez 0:f9d13e09cf11 282 coap_set_payload(message, buffer, length);
terencez 0:f9d13e09cf11 283
terencez 0:f9d13e09cf11 284 for (watcherP = listP->item->watcherList ; watcherP != NULL ; watcherP = watcherP->next)
terencez 0:f9d13e09cf11 285 {
terencez 0:f9d13e09cf11 286 watcherP->lastMid = contextP->nextMID++;
terencez 0:f9d13e09cf11 287 message->mid = watcherP->lastMid;
terencez 0:f9d13e09cf11 288 coap_set_header_token(message, watcherP->token, watcherP->tokenLen);
terencez 0:f9d13e09cf11 289 coap_set_header_observe(message, watcherP->counter++);
terencez 0:f9d13e09cf11 290 (void)message_send(contextP, message, watcherP->server->sessionH);
terencez 0:f9d13e09cf11 291 }
terencez 0:f9d13e09cf11 292 }
terencez 0:f9d13e09cf11 293
terencez 0:f9d13e09cf11 294 targetP = listP;
terencez 0:f9d13e09cf11 295 listP = listP->next;
terencez 0:f9d13e09cf11 296 lwm2m_free(targetP);
terencez 0:f9d13e09cf11 297 }
terencez 0:f9d13e09cf11 298
terencez 0:f9d13e09cf11 299 }
terencez 0:f9d13e09cf11 300 #endif
terencez 0:f9d13e09cf11 301
terencez 0:f9d13e09cf11 302 #ifdef LWM2M_SERVER_MODE
terencez 0:f9d13e09cf11 303 static lwm2m_observation_t * prv_findObservationByURI(lwm2m_client_t * clientP,
terencez 0:f9d13e09cf11 304 lwm2m_uri_t * uriP)
terencez 0:f9d13e09cf11 305 {
terencez 0:f9d13e09cf11 306 lwm2m_observation_t * targetP;
terencez 0:f9d13e09cf11 307
terencez 0:f9d13e09cf11 308 targetP = clientP->observationList;
terencez 0:f9d13e09cf11 309 while (targetP != NULL)
terencez 0:f9d13e09cf11 310 {
terencez 0:f9d13e09cf11 311 if (targetP->uri.objectId == uriP->objectId
terencez 0:f9d13e09cf11 312 && targetP->uri.flag == uriP->flag
terencez 0:f9d13e09cf11 313 && targetP->uri.instanceId == uriP->instanceId
terencez 0:f9d13e09cf11 314 && targetP->uri.resourceId == uriP->resourceId)
terencez 0:f9d13e09cf11 315 {
terencez 0:f9d13e09cf11 316 return targetP;
terencez 0:f9d13e09cf11 317 }
terencez 0:f9d13e09cf11 318
terencez 0:f9d13e09cf11 319 targetP = targetP->next;
terencez 0:f9d13e09cf11 320 }
terencez 0:f9d13e09cf11 321
terencez 0:f9d13e09cf11 322 return targetP;
terencez 0:f9d13e09cf11 323 }
terencez 0:f9d13e09cf11 324
terencez 0:f9d13e09cf11 325 void observation_remove(lwm2m_client_t * clientP,
terencez 0:f9d13e09cf11 326 lwm2m_observation_t * observationP)
terencez 0:f9d13e09cf11 327 {
terencez 0:f9d13e09cf11 328 if (clientP->observationList == observationP)
terencez 0:f9d13e09cf11 329 {
terencez 0:f9d13e09cf11 330 clientP->observationList = clientP->observationList->next;
terencez 0:f9d13e09cf11 331 }
terencez 0:f9d13e09cf11 332 else if (clientP->observationList != NULL)
terencez 0:f9d13e09cf11 333 {
terencez 0:f9d13e09cf11 334 lwm2m_observation_t * parentP;
terencez 0:f9d13e09cf11 335
terencez 0:f9d13e09cf11 336 parentP = clientP->observationList;
terencez 0:f9d13e09cf11 337
terencez 0:f9d13e09cf11 338 while (parentP->next != NULL
terencez 0:f9d13e09cf11 339 && parentP->next != observationP)
terencez 0:f9d13e09cf11 340 {
terencez 0:f9d13e09cf11 341 parentP = parentP->next;
terencez 0:f9d13e09cf11 342 }
terencez 0:f9d13e09cf11 343 if (parentP->next != NULL)
terencez 0:f9d13e09cf11 344 {
terencez 0:f9d13e09cf11 345 parentP->next = parentP->next->next;
terencez 0:f9d13e09cf11 346 }
terencez 0:f9d13e09cf11 347 }
terencez 0:f9d13e09cf11 348
terencez 0:f9d13e09cf11 349 lwm2m_free(observationP);
terencez 0:f9d13e09cf11 350 }
terencez 0:f9d13e09cf11 351
terencez 0:f9d13e09cf11 352 static void prv_obsRequestCallback(lwm2m_transaction_t * transacP,
terencez 0:f9d13e09cf11 353 void * message)
terencez 0:f9d13e09cf11 354 {
terencez 0:f9d13e09cf11 355 lwm2m_observation_t * observationP = (lwm2m_observation_t *)transacP->userData;
terencez 0:f9d13e09cf11 356 coap_packet_t * packet = (coap_packet_t *)message;
terencez 0:f9d13e09cf11 357 uint8_t code;
terencez 0:f9d13e09cf11 358
terencez 0:f9d13e09cf11 359 if (message == NULL)
terencez 0:f9d13e09cf11 360 {
terencez 0:f9d13e09cf11 361 code = COAP_503_SERVICE_UNAVAILABLE;
terencez 0:f9d13e09cf11 362 }
terencez 0:f9d13e09cf11 363 else if (packet->code == COAP_205_CONTENT
terencez 0:f9d13e09cf11 364 && !IS_OPTION(packet, COAP_OPTION_OBSERVE))
terencez 0:f9d13e09cf11 365 {
terencez 0:f9d13e09cf11 366 code = COAP_405_METHOD_NOT_ALLOWED;
terencez 0:f9d13e09cf11 367 }
terencez 0:f9d13e09cf11 368 else
terencez 0:f9d13e09cf11 369 {
terencez 0:f9d13e09cf11 370 code = packet->code;
terencez 0:f9d13e09cf11 371 }
terencez 0:f9d13e09cf11 372
terencez 0:f9d13e09cf11 373 if (code != COAP_205_CONTENT)
terencez 0:f9d13e09cf11 374 {
terencez 0:f9d13e09cf11 375 observationP->callback(((lwm2m_client_t*)transacP->peerP)->internalID,
terencez 0:f9d13e09cf11 376 &observationP->uri,
terencez 0:f9d13e09cf11 377 code,
terencez 0:f9d13e09cf11 378 NULL, 0,
terencez 0:f9d13e09cf11 379 observationP->userData);
terencez 0:f9d13e09cf11 380 observation_remove(((lwm2m_client_t*)transacP->peerP), observationP);
terencez 0:f9d13e09cf11 381 }
terencez 0:f9d13e09cf11 382 else
terencez 0:f9d13e09cf11 383 {
terencez 0:f9d13e09cf11 384 observationP->clientP->observationList = (lwm2m_observation_t *)LWM2M_LIST_ADD(observationP->clientP->observationList, observationP);
terencez 0:f9d13e09cf11 385 observationP->callback(((lwm2m_client_t*)transacP->peerP)->internalID,
terencez 0:f9d13e09cf11 386 &observationP->uri,
terencez 0:f9d13e09cf11 387 0,
terencez 0:f9d13e09cf11 388 packet->payload, packet->payload_len,
terencez 0:f9d13e09cf11 389 observationP->userData);
terencez 0:f9d13e09cf11 390 }
terencez 0:f9d13e09cf11 391 }
terencez 0:f9d13e09cf11 392
terencez 0:f9d13e09cf11 393 int lwm2m_observe(lwm2m_context_t * contextP,
terencez 0:f9d13e09cf11 394 uint16_t clientID,
terencez 0:f9d13e09cf11 395 lwm2m_uri_t * uriP,
terencez 0:f9d13e09cf11 396 lwm2m_result_callback_t callback,
terencez 0:f9d13e09cf11 397 void * userData)
terencez 0:f9d13e09cf11 398 {
terencez 0:f9d13e09cf11 399 lwm2m_client_t * clientP;
terencez 0:f9d13e09cf11 400 lwm2m_transaction_t * transactionP;
terencez 0:f9d13e09cf11 401 lwm2m_observation_t * observationP;
terencez 0:f9d13e09cf11 402 uint8_t token[4];
terencez 0:f9d13e09cf11 403
terencez 0:f9d13e09cf11 404 if (!LWM2M_URI_IS_SET_INSTANCE(uriP) && LWM2M_URI_IS_SET_RESOURCE(uriP)) return COAP_400_BAD_REQUEST;
terencez 0:f9d13e09cf11 405
terencez 0:f9d13e09cf11 406 clientP = (lwm2m_client_t *)lwm2m_list_find((lwm2m_list_t *)contextP->clientList, clientID);
terencez 0:f9d13e09cf11 407 if (clientP == NULL) return COAP_404_NOT_FOUND;
terencez 0:f9d13e09cf11 408
terencez 0:f9d13e09cf11 409 observationP = (lwm2m_observation_t *)lwm2m_malloc(sizeof(lwm2m_observation_t));
terencez 0:f9d13e09cf11 410 if (observationP == NULL) return COAP_500_INTERNAL_SERVER_ERROR;
terencez 0:f9d13e09cf11 411 memset(observationP, 0, sizeof(lwm2m_observation_t));
terencez 0:f9d13e09cf11 412
terencez 0:f9d13e09cf11 413 transactionP = transaction_new(COAP_GET, uriP, contextP->nextMID++, ENDPOINT_CLIENT, (void *)clientP);
terencez 0:f9d13e09cf11 414 if (transactionP == NULL)
terencez 0:f9d13e09cf11 415 {
terencez 0:f9d13e09cf11 416 lwm2m_free(observationP);
terencez 0:f9d13e09cf11 417 return COAP_500_INTERNAL_SERVER_ERROR;
terencez 0:f9d13e09cf11 418 }
terencez 0:f9d13e09cf11 419
terencez 0:f9d13e09cf11 420 observationP->id = lwm2m_list_newId((lwm2m_list_t *)clientP->observationList);
terencez 0:f9d13e09cf11 421 memcpy(&observationP->uri, uriP, sizeof(lwm2m_uri_t));
terencez 0:f9d13e09cf11 422 observationP->clientP = clientP;
terencez 0:f9d13e09cf11 423 observationP->callback = callback;
terencez 0:f9d13e09cf11 424 observationP->userData = userData;
terencez 0:f9d13e09cf11 425
terencez 0:f9d13e09cf11 426 token[0] = clientP->internalID >> 8;
terencez 0:f9d13e09cf11 427 token[1] = clientP->internalID & 0xFF;
terencez 0:f9d13e09cf11 428 token[2] = observationP->id >> 8;
terencez 0:f9d13e09cf11 429 token[3] = observationP->id & 0xFF;
terencez 0:f9d13e09cf11 430
terencez 0:f9d13e09cf11 431 coap_set_header_observe(transactionP->message, 0);
terencez 0:f9d13e09cf11 432 coap_set_header_token(transactionP->message, token, sizeof(token));
terencez 0:f9d13e09cf11 433
terencez 0:f9d13e09cf11 434 transactionP->callback = prv_obsRequestCallback;
terencez 0:f9d13e09cf11 435 transactionP->userData = (void *)observationP;
terencez 0:f9d13e09cf11 436
terencez 0:f9d13e09cf11 437 contextP->transactionList = (lwm2m_transaction_t *)LWM2M_LIST_ADD(contextP->transactionList, transactionP);
terencez 0:f9d13e09cf11 438
terencez 0:f9d13e09cf11 439 return transaction_send(contextP, transactionP);
terencez 0:f9d13e09cf11 440 }
terencez 0:f9d13e09cf11 441
terencez 0:f9d13e09cf11 442 int lwm2m_observe_cancel(lwm2m_context_t * contextP,
terencez 0:f9d13e09cf11 443 uint16_t clientID,
terencez 0:f9d13e09cf11 444 lwm2m_uri_t * uriP,
terencez 0:f9d13e09cf11 445 lwm2m_result_callback_t callback,
terencez 0:f9d13e09cf11 446 void * userData)
terencez 0:f9d13e09cf11 447 {
terencez 0:f9d13e09cf11 448 lwm2m_client_t * clientP;
terencez 0:f9d13e09cf11 449 lwm2m_observation_t * observationP;
terencez 0:f9d13e09cf11 450
terencez 0:f9d13e09cf11 451 clientP = (lwm2m_client_t *)lwm2m_list_find((lwm2m_list_t *)contextP->clientList, clientID);
terencez 0:f9d13e09cf11 452 if (clientP == NULL) return COAP_404_NOT_FOUND;
terencez 0:f9d13e09cf11 453
terencez 0:f9d13e09cf11 454 observationP = prv_findObservationByURI(clientP, uriP);
terencez 0:f9d13e09cf11 455 if (observationP == NULL) return COAP_404_NOT_FOUND;
terencez 0:f9d13e09cf11 456
terencez 0:f9d13e09cf11 457 observation_remove(clientP, observationP);
terencez 0:f9d13e09cf11 458
terencez 0:f9d13e09cf11 459 return 0;
terencez 0:f9d13e09cf11 460 }
terencez 0:f9d13e09cf11 461
terencez 0:f9d13e09cf11 462 void handle_observe_notify(lwm2m_context_t * contextP,
terencez 0:f9d13e09cf11 463 void * fromSessionH,
terencez 0:f9d13e09cf11 464 coap_packet_t * message)
terencez 0:f9d13e09cf11 465 {
terencez 0:f9d13e09cf11 466 uint8_t * tokenP;
terencez 0:f9d13e09cf11 467 int token_len;
terencez 0:f9d13e09cf11 468 uint16_t clientID;
terencez 0:f9d13e09cf11 469 uint16_t obsID;
terencez 0:f9d13e09cf11 470 lwm2m_client_t * clientP;
terencez 0:f9d13e09cf11 471 lwm2m_observation_t * observationP;
terencez 0:f9d13e09cf11 472 uint32_t count;
terencez 0:f9d13e09cf11 473
terencez 0:f9d13e09cf11 474 token_len = coap_get_header_token(message, (const uint8_t **)&tokenP);
terencez 0:f9d13e09cf11 475 if (token_len != sizeof(uint32_t)) return;
terencez 0:f9d13e09cf11 476
terencez 0:f9d13e09cf11 477 if (1 != coap_get_header_observe(message, &count)) return;
terencez 0:f9d13e09cf11 478
terencez 0:f9d13e09cf11 479 clientID = (tokenP[0] << 8) | tokenP[1];
terencez 0:f9d13e09cf11 480 obsID = (tokenP[2] << 8) | tokenP[3];
terencez 0:f9d13e09cf11 481
terencez 0:f9d13e09cf11 482 clientP = (lwm2m_client_t *)lwm2m_list_find((lwm2m_list_t *)contextP->clientList, clientID);
terencez 0:f9d13e09cf11 483 if (clientP == NULL) return;
terencez 0:f9d13e09cf11 484
terencez 0:f9d13e09cf11 485 observationP = (lwm2m_observation_t *)lwm2m_list_find((lwm2m_list_t *)clientP->observationList, obsID);
terencez 0:f9d13e09cf11 486 if (observationP == NULL)
terencez 0:f9d13e09cf11 487 {
terencez 0:f9d13e09cf11 488 coap_packet_t resetMsg;
terencez 0:f9d13e09cf11 489
terencez 0:f9d13e09cf11 490 coap_init_message(&resetMsg, COAP_TYPE_RST, 0, message->mid);
terencez 0:f9d13e09cf11 491
terencez 0:f9d13e09cf11 492 message_send(contextP, &resetMsg, fromSessionH);
terencez 0:f9d13e09cf11 493 }
terencez 0:f9d13e09cf11 494 else
terencez 0:f9d13e09cf11 495 {
terencez 0:f9d13e09cf11 496 observationP->callback(clientID,
terencez 0:f9d13e09cf11 497 &observationP->uri,
terencez 0:f9d13e09cf11 498 (int)count,
terencez 0:f9d13e09cf11 499 message->payload, message->payload_len,
terencez 0:f9d13e09cf11 500 observationP->userData);
terencez 0:f9d13e09cf11 501 }
terencez 0:f9d13e09cf11 502 }
terencez 0:f9d13e09cf11 503 #endif