pick up wakaama files from https://github.com/eclipse/wakaama
core/objects.c@0:c2dff8cbb91a, 2017-04-19 (annotated)
- Committer:
- terencez
- Date:
- Wed Apr 19 11:27:34 2017 +0000
- Revision:
- 0:c2dff8cbb91a
Initial commit
Who changed what in which revision?
User | Revision | Line number | New 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 | * Fabien Fleutot - Please refer to git log |
terencez | 0:c2dff8cbb91a | 16 | * Toby Jaffey - Please refer to git log |
terencez | 0:c2dff8cbb91a | 17 | * Benjamin Cabé - Please refer to git log |
terencez | 0:c2dff8cbb91a | 18 | * Bosch Software Innovations GmbH - Please refer to git log |
terencez | 0:c2dff8cbb91a | 19 | * Pascal Rieux - Please refer to git log |
terencez | 0:c2dff8cbb91a | 20 | * |
terencez | 0:c2dff8cbb91a | 21 | *******************************************************************************/ |
terencez | 0:c2dff8cbb91a | 22 | |
terencez | 0:c2dff8cbb91a | 23 | /* |
terencez | 0:c2dff8cbb91a | 24 | Copyright (c) 2013, 2014 Intel Corporation |
terencez | 0:c2dff8cbb91a | 25 | |
terencez | 0:c2dff8cbb91a | 26 | Redistribution and use in source and binary forms, with or without modification, |
terencez | 0:c2dff8cbb91a | 27 | are permitted provided that the following conditions are met: |
terencez | 0:c2dff8cbb91a | 28 | |
terencez | 0:c2dff8cbb91a | 29 | * Redistributions of source code must retain the above copyright notice, |
terencez | 0:c2dff8cbb91a | 30 | this list of conditions and the following disclaimer. |
terencez | 0:c2dff8cbb91a | 31 | * Redistributions in binary form must reproduce the above copyright notice, |
terencez | 0:c2dff8cbb91a | 32 | this list of conditions and the following disclaimer in the documentation |
terencez | 0:c2dff8cbb91a | 33 | and/or other materials provided with the distribution. |
terencez | 0:c2dff8cbb91a | 34 | * Neither the name of Intel Corporation nor the names of its contributors |
terencez | 0:c2dff8cbb91a | 35 | may be used to endorse or promote products derived from this software |
terencez | 0:c2dff8cbb91a | 36 | without specific prior written permission. |
terencez | 0:c2dff8cbb91a | 37 | |
terencez | 0:c2dff8cbb91a | 38 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
terencez | 0:c2dff8cbb91a | 39 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
terencez | 0:c2dff8cbb91a | 40 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
terencez | 0:c2dff8cbb91a | 41 | IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, |
terencez | 0:c2dff8cbb91a | 42 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
terencez | 0:c2dff8cbb91a | 43 | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
terencez | 0:c2dff8cbb91a | 44 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
terencez | 0:c2dff8cbb91a | 45 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR |
terencez | 0:c2dff8cbb91a | 46 | OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
terencez | 0:c2dff8cbb91a | 47 | THE POSSIBILITY OF SUCH DAMAGE. |
terencez | 0:c2dff8cbb91a | 48 | |
terencez | 0:c2dff8cbb91a | 49 | David Navarro <david.navarro@intel.com> |
terencez | 0:c2dff8cbb91a | 50 | |
terencez | 0:c2dff8cbb91a | 51 | */ |
terencez | 0:c2dff8cbb91a | 52 | #include "internals.h" |
terencez | 0:c2dff8cbb91a | 53 | |
terencez | 0:c2dff8cbb91a | 54 | #ifdef LWM2M_CLIENT_MODE |
terencez | 0:c2dff8cbb91a | 55 | |
terencez | 0:c2dff8cbb91a | 56 | |
terencez | 0:c2dff8cbb91a | 57 | #include <stdlib.h> |
terencez | 0:c2dff8cbb91a | 58 | #include <string.h> |
terencez | 0:c2dff8cbb91a | 59 | #include <stdio.h> |
terencez | 0:c2dff8cbb91a | 60 | |
terencez | 0:c2dff8cbb91a | 61 | |
terencez | 0:c2dff8cbb91a | 62 | uint8_t object_checkReadable(lwm2m_context_t * contextP, |
terencez | 0:c2dff8cbb91a | 63 | lwm2m_uri_t * uriP) |
terencez | 0:c2dff8cbb91a | 64 | { |
terencez | 0:c2dff8cbb91a | 65 | coap_status_t result; |
terencez | 0:c2dff8cbb91a | 66 | lwm2m_object_t * targetP; |
terencez | 0:c2dff8cbb91a | 67 | lwm2m_data_t * dataP = NULL; |
terencez | 0:c2dff8cbb91a | 68 | int size; |
terencez | 0:c2dff8cbb91a | 69 | |
terencez | 0:c2dff8cbb91a | 70 | LOG_URI(uriP); |
terencez | 0:c2dff8cbb91a | 71 | targetP = (lwm2m_object_t *)LWM2M_LIST_FIND(contextP->objectList, uriP->objectId); |
terencez | 0:c2dff8cbb91a | 72 | if (NULL == targetP) return COAP_404_NOT_FOUND; |
terencez | 0:c2dff8cbb91a | 73 | if (NULL == targetP->readFunc) return COAP_405_METHOD_NOT_ALLOWED; |
terencez | 0:c2dff8cbb91a | 74 | |
terencez | 0:c2dff8cbb91a | 75 | if (!LWM2M_URI_IS_SET_INSTANCE(uriP)) return COAP_205_CONTENT; |
terencez | 0:c2dff8cbb91a | 76 | |
terencez | 0:c2dff8cbb91a | 77 | if (NULL == lwm2m_list_find(targetP->instanceList, uriP->instanceId)) return COAP_404_NOT_FOUND; |
terencez | 0:c2dff8cbb91a | 78 | |
terencez | 0:c2dff8cbb91a | 79 | if (!LWM2M_URI_IS_SET_RESOURCE(uriP)) return COAP_205_CONTENT; |
terencez | 0:c2dff8cbb91a | 80 | |
terencez | 0:c2dff8cbb91a | 81 | size = 1; |
terencez | 0:c2dff8cbb91a | 82 | dataP = lwm2m_data_new(1); |
terencez | 0:c2dff8cbb91a | 83 | if (dataP == NULL) return COAP_500_INTERNAL_SERVER_ERROR; |
terencez | 0:c2dff8cbb91a | 84 | |
terencez | 0:c2dff8cbb91a | 85 | dataP->id = uriP->resourceId; |
terencez | 0:c2dff8cbb91a | 86 | |
terencez | 0:c2dff8cbb91a | 87 | result = targetP->readFunc(uriP->instanceId, &size, &dataP, targetP); |
terencez | 0:c2dff8cbb91a | 88 | lwm2m_data_free(1, dataP); |
terencez | 0:c2dff8cbb91a | 89 | |
terencez | 0:c2dff8cbb91a | 90 | return result; |
terencez | 0:c2dff8cbb91a | 91 | } |
terencez | 0:c2dff8cbb91a | 92 | |
terencez | 0:c2dff8cbb91a | 93 | uint8_t object_checkNumeric(lwm2m_context_t * contextP, |
terencez | 0:c2dff8cbb91a | 94 | lwm2m_uri_t * uriP) |
terencez | 0:c2dff8cbb91a | 95 | { |
terencez | 0:c2dff8cbb91a | 96 | coap_status_t result; |
terencez | 0:c2dff8cbb91a | 97 | lwm2m_object_t * targetP; |
terencez | 0:c2dff8cbb91a | 98 | lwm2m_data_t * dataP = NULL; |
terencez | 0:c2dff8cbb91a | 99 | int size; |
terencez | 0:c2dff8cbb91a | 100 | |
terencez | 0:c2dff8cbb91a | 101 | LOG_URI(uriP); |
terencez | 0:c2dff8cbb91a | 102 | if (!LWM2M_URI_IS_SET_RESOURCE(uriP)) return COAP_405_METHOD_NOT_ALLOWED; |
terencez | 0:c2dff8cbb91a | 103 | |
terencez | 0:c2dff8cbb91a | 104 | targetP = (lwm2m_object_t *)LWM2M_LIST_FIND(contextP->objectList, uriP->objectId); |
terencez | 0:c2dff8cbb91a | 105 | if (NULL == targetP) return COAP_404_NOT_FOUND; |
terencez | 0:c2dff8cbb91a | 106 | if (NULL == targetP->readFunc) return COAP_405_METHOD_NOT_ALLOWED; |
terencez | 0:c2dff8cbb91a | 107 | |
terencez | 0:c2dff8cbb91a | 108 | size = 1; |
terencez | 0:c2dff8cbb91a | 109 | dataP = lwm2m_data_new(1); |
terencez | 0:c2dff8cbb91a | 110 | if (dataP == NULL) return COAP_500_INTERNAL_SERVER_ERROR; |
terencez | 0:c2dff8cbb91a | 111 | |
terencez | 0:c2dff8cbb91a | 112 | dataP->id = uriP->resourceId; |
terencez | 0:c2dff8cbb91a | 113 | |
terencez | 0:c2dff8cbb91a | 114 | result = targetP->readFunc(uriP->instanceId, &size, &dataP, targetP); |
terencez | 0:c2dff8cbb91a | 115 | if (result == COAP_205_CONTENT) |
terencez | 0:c2dff8cbb91a | 116 | { |
terencez | 0:c2dff8cbb91a | 117 | switch (dataP->type) |
terencez | 0:c2dff8cbb91a | 118 | { |
terencez | 0:c2dff8cbb91a | 119 | case LWM2M_TYPE_INTEGER: |
terencez | 0:c2dff8cbb91a | 120 | case LWM2M_TYPE_FLOAT: |
terencez | 0:c2dff8cbb91a | 121 | break; |
terencez | 0:c2dff8cbb91a | 122 | default: |
terencez | 0:c2dff8cbb91a | 123 | result = COAP_405_METHOD_NOT_ALLOWED; |
terencez | 0:c2dff8cbb91a | 124 | } |
terencez | 0:c2dff8cbb91a | 125 | } |
terencez | 0:c2dff8cbb91a | 126 | |
terencez | 0:c2dff8cbb91a | 127 | lwm2m_data_free(1, dataP); |
terencez | 0:c2dff8cbb91a | 128 | |
terencez | 0:c2dff8cbb91a | 129 | return result; |
terencez | 0:c2dff8cbb91a | 130 | } |
terencez | 0:c2dff8cbb91a | 131 | |
terencez | 0:c2dff8cbb91a | 132 | coap_status_t object_readData(lwm2m_context_t * contextP, |
terencez | 0:c2dff8cbb91a | 133 | lwm2m_uri_t * uriP, |
terencez | 0:c2dff8cbb91a | 134 | int * sizeP, |
terencez | 0:c2dff8cbb91a | 135 | lwm2m_data_t ** dataP) |
terencez | 0:c2dff8cbb91a | 136 | { |
terencez | 0:c2dff8cbb91a | 137 | coap_status_t result; |
terencez | 0:c2dff8cbb91a | 138 | lwm2m_object_t * targetP; |
terencez | 0:c2dff8cbb91a | 139 | |
terencez | 0:c2dff8cbb91a | 140 | LOG_URI(uriP); |
terencez | 0:c2dff8cbb91a | 141 | targetP = (lwm2m_object_t *)LWM2M_LIST_FIND(contextP->objectList, uriP->objectId); |
terencez | 0:c2dff8cbb91a | 142 | if (NULL == targetP) return COAP_404_NOT_FOUND; |
terencez | 0:c2dff8cbb91a | 143 | if (NULL == targetP->readFunc) return COAP_405_METHOD_NOT_ALLOWED; |
terencez | 0:c2dff8cbb91a | 144 | |
terencez | 0:c2dff8cbb91a | 145 | if (LWM2M_URI_IS_SET_INSTANCE(uriP)) |
terencez | 0:c2dff8cbb91a | 146 | { |
terencez | 0:c2dff8cbb91a | 147 | if (NULL == lwm2m_list_find(targetP->instanceList, uriP->instanceId)) return COAP_404_NOT_FOUND; |
terencez | 0:c2dff8cbb91a | 148 | |
terencez | 0:c2dff8cbb91a | 149 | // single instance read |
terencez | 0:c2dff8cbb91a | 150 | if (LWM2M_URI_IS_SET_RESOURCE(uriP)) |
terencez | 0:c2dff8cbb91a | 151 | { |
terencez | 0:c2dff8cbb91a | 152 | *sizeP = 1; |
terencez | 0:c2dff8cbb91a | 153 | *dataP = lwm2m_data_new(*sizeP); |
terencez | 0:c2dff8cbb91a | 154 | if (*dataP == NULL) return COAP_500_INTERNAL_SERVER_ERROR; |
terencez | 0:c2dff8cbb91a | 155 | |
terencez | 0:c2dff8cbb91a | 156 | (*dataP)->id = uriP->resourceId; |
terencez | 0:c2dff8cbb91a | 157 | } |
terencez | 0:c2dff8cbb91a | 158 | |
terencez | 0:c2dff8cbb91a | 159 | result = targetP->readFunc(uriP->instanceId, sizeP, dataP, targetP); |
terencez | 0:c2dff8cbb91a | 160 | } |
terencez | 0:c2dff8cbb91a | 161 | else |
terencez | 0:c2dff8cbb91a | 162 | { |
terencez | 0:c2dff8cbb91a | 163 | // multiple object instances read |
terencez | 0:c2dff8cbb91a | 164 | lwm2m_list_t * instanceP; |
terencez | 0:c2dff8cbb91a | 165 | int i; |
terencez | 0:c2dff8cbb91a | 166 | |
terencez | 0:c2dff8cbb91a | 167 | result = COAP_205_CONTENT; |
terencez | 0:c2dff8cbb91a | 168 | |
terencez | 0:c2dff8cbb91a | 169 | *sizeP = 0; |
terencez | 0:c2dff8cbb91a | 170 | for (instanceP = targetP->instanceList; instanceP != NULL ; instanceP = instanceP->next) |
terencez | 0:c2dff8cbb91a | 171 | { |
terencez | 0:c2dff8cbb91a | 172 | (*sizeP)++; |
terencez | 0:c2dff8cbb91a | 173 | } |
terencez | 0:c2dff8cbb91a | 174 | |
terencez | 0:c2dff8cbb91a | 175 | if (*sizeP == 0) |
terencez | 0:c2dff8cbb91a | 176 | { |
terencez | 0:c2dff8cbb91a | 177 | *dataP = NULL; |
terencez | 0:c2dff8cbb91a | 178 | } |
terencez | 0:c2dff8cbb91a | 179 | else |
terencez | 0:c2dff8cbb91a | 180 | { |
terencez | 0:c2dff8cbb91a | 181 | *dataP = lwm2m_data_new(*sizeP); |
terencez | 0:c2dff8cbb91a | 182 | if (*dataP == NULL) return COAP_500_INTERNAL_SERVER_ERROR; |
terencez | 0:c2dff8cbb91a | 183 | |
terencez | 0:c2dff8cbb91a | 184 | instanceP = targetP->instanceList; |
terencez | 0:c2dff8cbb91a | 185 | i = 0; |
terencez | 0:c2dff8cbb91a | 186 | while (instanceP != NULL && result == COAP_205_CONTENT) |
terencez | 0:c2dff8cbb91a | 187 | { |
terencez | 0:c2dff8cbb91a | 188 | result = targetP->readFunc(instanceP->id, (int*)&((*dataP)[i].value.asChildren.count), &((*dataP)[i].value.asChildren.array), targetP); |
terencez | 0:c2dff8cbb91a | 189 | (*dataP)[i].type = LWM2M_TYPE_OBJECT_INSTANCE; |
terencez | 0:c2dff8cbb91a | 190 | (*dataP)[i].id = instanceP->id; |
terencez | 0:c2dff8cbb91a | 191 | i++; |
terencez | 0:c2dff8cbb91a | 192 | instanceP = instanceP->next; |
terencez | 0:c2dff8cbb91a | 193 | } |
terencez | 0:c2dff8cbb91a | 194 | } |
terencez | 0:c2dff8cbb91a | 195 | } |
terencez | 0:c2dff8cbb91a | 196 | |
terencez | 0:c2dff8cbb91a | 197 | LOG_ARG("result: %u.%2u, size: %d", (result & 0xFF) >> 5, (result & 0x1F), *sizeP); |
terencez | 0:c2dff8cbb91a | 198 | return result; |
terencez | 0:c2dff8cbb91a | 199 | } |
terencez | 0:c2dff8cbb91a | 200 | |
terencez | 0:c2dff8cbb91a | 201 | coap_status_t object_read(lwm2m_context_t * contextP, |
terencez | 0:c2dff8cbb91a | 202 | lwm2m_uri_t * uriP, |
terencez | 0:c2dff8cbb91a | 203 | lwm2m_media_type_t * formatP, |
terencez | 0:c2dff8cbb91a | 204 | uint8_t ** bufferP, |
terencez | 0:c2dff8cbb91a | 205 | size_t * lengthP) |
terencez | 0:c2dff8cbb91a | 206 | { |
terencez | 0:c2dff8cbb91a | 207 | coap_status_t result; |
terencez | 0:c2dff8cbb91a | 208 | lwm2m_data_t * dataP = NULL; |
terencez | 0:c2dff8cbb91a | 209 | int size = 0; |
terencez | 0:c2dff8cbb91a | 210 | int res; |
terencez | 0:c2dff8cbb91a | 211 | |
terencez | 0:c2dff8cbb91a | 212 | LOG_URI(uriP); |
terencez | 0:c2dff8cbb91a | 213 | result = object_readData(contextP, uriP, &size, &dataP); |
terencez | 0:c2dff8cbb91a | 214 | |
terencez | 0:c2dff8cbb91a | 215 | if (result == COAP_205_CONTENT) |
terencez | 0:c2dff8cbb91a | 216 | { |
terencez | 0:c2dff8cbb91a | 217 | res = lwm2m_data_serialize(uriP, size, dataP, formatP, bufferP); |
terencez | 0:c2dff8cbb91a | 218 | if (res < 0) |
terencez | 0:c2dff8cbb91a | 219 | { |
terencez | 0:c2dff8cbb91a | 220 | result = COAP_500_INTERNAL_SERVER_ERROR; |
terencez | 0:c2dff8cbb91a | 221 | } |
terencez | 0:c2dff8cbb91a | 222 | else |
terencez | 0:c2dff8cbb91a | 223 | { |
terencez | 0:c2dff8cbb91a | 224 | *lengthP = (size_t)res; |
terencez | 0:c2dff8cbb91a | 225 | } |
terencez | 0:c2dff8cbb91a | 226 | } |
terencez | 0:c2dff8cbb91a | 227 | lwm2m_data_free(size, dataP); |
terencez | 0:c2dff8cbb91a | 228 | |
terencez | 0:c2dff8cbb91a | 229 | LOG_ARG("result: %u.%2u, length: %d", (result & 0xFF) >> 5, (result & 0x1F), *lengthP); |
terencez | 0:c2dff8cbb91a | 230 | |
terencez | 0:c2dff8cbb91a | 231 | return result; |
terencez | 0:c2dff8cbb91a | 232 | } |
terencez | 0:c2dff8cbb91a | 233 | |
terencez | 0:c2dff8cbb91a | 234 | coap_status_t object_write(lwm2m_context_t * contextP, |
terencez | 0:c2dff8cbb91a | 235 | lwm2m_uri_t * uriP, |
terencez | 0:c2dff8cbb91a | 236 | lwm2m_media_type_t format, |
terencez | 0:c2dff8cbb91a | 237 | uint8_t * buffer, |
terencez | 0:c2dff8cbb91a | 238 | size_t length) |
terencez | 0:c2dff8cbb91a | 239 | { |
terencez | 0:c2dff8cbb91a | 240 | coap_status_t result = NO_ERROR; |
terencez | 0:c2dff8cbb91a | 241 | lwm2m_object_t * targetP; |
terencez | 0:c2dff8cbb91a | 242 | lwm2m_data_t * dataP = NULL; |
terencez | 0:c2dff8cbb91a | 243 | int size = 0; |
terencez | 0:c2dff8cbb91a | 244 | |
terencez | 0:c2dff8cbb91a | 245 | LOG_URI(uriP); |
terencez | 0:c2dff8cbb91a | 246 | targetP = (lwm2m_object_t *)LWM2M_LIST_FIND(contextP->objectList, uriP->objectId); |
terencez | 0:c2dff8cbb91a | 247 | if (NULL == targetP) |
terencez | 0:c2dff8cbb91a | 248 | { |
terencez | 0:c2dff8cbb91a | 249 | result = COAP_404_NOT_FOUND; |
terencez | 0:c2dff8cbb91a | 250 | } |
terencez | 0:c2dff8cbb91a | 251 | else if (NULL == targetP->writeFunc) |
terencez | 0:c2dff8cbb91a | 252 | { |
terencez | 0:c2dff8cbb91a | 253 | result = COAP_405_METHOD_NOT_ALLOWED; |
terencez | 0:c2dff8cbb91a | 254 | } |
terencez | 0:c2dff8cbb91a | 255 | else |
terencez | 0:c2dff8cbb91a | 256 | { |
terencez | 0:c2dff8cbb91a | 257 | size = lwm2m_data_parse(uriP, buffer, length, format, &dataP); |
terencez | 0:c2dff8cbb91a | 258 | if (size == 0) |
terencez | 0:c2dff8cbb91a | 259 | { |
terencez | 0:c2dff8cbb91a | 260 | result = COAP_406_NOT_ACCEPTABLE; |
terencez | 0:c2dff8cbb91a | 261 | } |
terencez | 0:c2dff8cbb91a | 262 | } |
terencez | 0:c2dff8cbb91a | 263 | if (result == NO_ERROR) |
terencez | 0:c2dff8cbb91a | 264 | { |
terencez | 0:c2dff8cbb91a | 265 | result = targetP->writeFunc(uriP->instanceId, size, dataP, targetP); |
terencez | 0:c2dff8cbb91a | 266 | lwm2m_data_free(size, dataP); |
terencez | 0:c2dff8cbb91a | 267 | } |
terencez | 0:c2dff8cbb91a | 268 | |
terencez | 0:c2dff8cbb91a | 269 | LOG_ARG("result: %u.%2u", (result & 0xFF) >> 5, (result & 0x1F)); |
terencez | 0:c2dff8cbb91a | 270 | |
terencez | 0:c2dff8cbb91a | 271 | return result; |
terencez | 0:c2dff8cbb91a | 272 | } |
terencez | 0:c2dff8cbb91a | 273 | |
terencez | 0:c2dff8cbb91a | 274 | coap_status_t object_execute(lwm2m_context_t * contextP, |
terencez | 0:c2dff8cbb91a | 275 | lwm2m_uri_t * uriP, |
terencez | 0:c2dff8cbb91a | 276 | uint8_t * buffer, |
terencez | 0:c2dff8cbb91a | 277 | size_t length) |
terencez | 0:c2dff8cbb91a | 278 | { |
terencez | 0:c2dff8cbb91a | 279 | lwm2m_object_t * targetP; |
terencez | 0:c2dff8cbb91a | 280 | |
terencez | 0:c2dff8cbb91a | 281 | LOG_URI(uriP); |
terencez | 0:c2dff8cbb91a | 282 | targetP = (lwm2m_object_t *)LWM2M_LIST_FIND(contextP->objectList, uriP->objectId); |
terencez | 0:c2dff8cbb91a | 283 | if (NULL == targetP) return COAP_404_NOT_FOUND; |
terencez | 0:c2dff8cbb91a | 284 | if (NULL == targetP->executeFunc) return COAP_405_METHOD_NOT_ALLOWED; |
terencez | 0:c2dff8cbb91a | 285 | if (NULL == lwm2m_list_find(targetP->instanceList, uriP->instanceId)) return COAP_404_NOT_FOUND; |
terencez | 0:c2dff8cbb91a | 286 | |
terencez | 0:c2dff8cbb91a | 287 | return targetP->executeFunc(uriP->instanceId, uriP->resourceId, buffer, length, targetP); |
terencez | 0:c2dff8cbb91a | 288 | } |
terencez | 0:c2dff8cbb91a | 289 | |
terencez | 0:c2dff8cbb91a | 290 | coap_status_t object_create(lwm2m_context_t * contextP, |
terencez | 0:c2dff8cbb91a | 291 | lwm2m_uri_t * uriP, |
terencez | 0:c2dff8cbb91a | 292 | lwm2m_media_type_t format, |
terencez | 0:c2dff8cbb91a | 293 | uint8_t * buffer, |
terencez | 0:c2dff8cbb91a | 294 | size_t length) |
terencez | 0:c2dff8cbb91a | 295 | { |
terencez | 0:c2dff8cbb91a | 296 | lwm2m_object_t * targetP; |
terencez | 0:c2dff8cbb91a | 297 | lwm2m_data_t * dataP = NULL; |
terencez | 0:c2dff8cbb91a | 298 | int size = 0; |
terencez | 0:c2dff8cbb91a | 299 | uint8_t result; |
terencez | 0:c2dff8cbb91a | 300 | |
terencez | 0:c2dff8cbb91a | 301 | LOG_URI(uriP); |
terencez | 0:c2dff8cbb91a | 302 | |
terencez | 0:c2dff8cbb91a | 303 | if (length == 0 || buffer == 0) |
terencez | 0:c2dff8cbb91a | 304 | { |
terencez | 0:c2dff8cbb91a | 305 | return COAP_400_BAD_REQUEST; |
terencez | 0:c2dff8cbb91a | 306 | } |
terencez | 0:c2dff8cbb91a | 307 | |
terencez | 0:c2dff8cbb91a | 308 | targetP = (lwm2m_object_t *)LWM2M_LIST_FIND(contextP->objectList, uriP->objectId); |
terencez | 0:c2dff8cbb91a | 309 | if (NULL == targetP) return COAP_404_NOT_FOUND; |
terencez | 0:c2dff8cbb91a | 310 | if (NULL == targetP->createFunc) return COAP_405_METHOD_NOT_ALLOWED; |
terencez | 0:c2dff8cbb91a | 311 | |
terencez | 0:c2dff8cbb91a | 312 | size = lwm2m_data_parse(uriP, buffer, length, format, &dataP); |
terencez | 0:c2dff8cbb91a | 313 | if (size <= 0) return COAP_400_BAD_REQUEST; |
terencez | 0:c2dff8cbb91a | 314 | |
terencez | 0:c2dff8cbb91a | 315 | switch (dataP[0].type) |
terencez | 0:c2dff8cbb91a | 316 | { |
terencez | 0:c2dff8cbb91a | 317 | case LWM2M_TYPE_OBJECT: |
terencez | 0:c2dff8cbb91a | 318 | result = COAP_400_BAD_REQUEST; |
terencez | 0:c2dff8cbb91a | 319 | goto exit; |
terencez | 0:c2dff8cbb91a | 320 | |
terencez | 0:c2dff8cbb91a | 321 | case LWM2M_TYPE_OBJECT_INSTANCE: |
terencez | 0:c2dff8cbb91a | 322 | if (size != 1) |
terencez | 0:c2dff8cbb91a | 323 | { |
terencez | 0:c2dff8cbb91a | 324 | result = COAP_400_BAD_REQUEST; |
terencez | 0:c2dff8cbb91a | 325 | goto exit; |
terencez | 0:c2dff8cbb91a | 326 | } |
terencez | 0:c2dff8cbb91a | 327 | if (NULL != lwm2m_list_find(targetP->instanceList, dataP[0].id)) |
terencez | 0:c2dff8cbb91a | 328 | { |
terencez | 0:c2dff8cbb91a | 329 | // Instance already exists |
terencez | 0:c2dff8cbb91a | 330 | result = COAP_406_NOT_ACCEPTABLE; |
terencez | 0:c2dff8cbb91a | 331 | goto exit; |
terencez | 0:c2dff8cbb91a | 332 | } |
terencez | 0:c2dff8cbb91a | 333 | result = targetP->createFunc(dataP[0].id, dataP[0].value.asChildren.count, dataP[0].value.asChildren.array, targetP); |
terencez | 0:c2dff8cbb91a | 334 | uriP->instanceId = dataP[0].id; |
terencez | 0:c2dff8cbb91a | 335 | uriP->flag |= LWM2M_URI_FLAG_INSTANCE_ID; |
terencez | 0:c2dff8cbb91a | 336 | break; |
terencez | 0:c2dff8cbb91a | 337 | |
terencez | 0:c2dff8cbb91a | 338 | default: |
terencez | 0:c2dff8cbb91a | 339 | if (!LWM2M_URI_IS_SET_INSTANCE(uriP)) |
terencez | 0:c2dff8cbb91a | 340 | { |
terencez | 0:c2dff8cbb91a | 341 | uriP->instanceId = lwm2m_list_newId(targetP->instanceList); |
terencez | 0:c2dff8cbb91a | 342 | uriP->flag |= LWM2M_URI_FLAG_INSTANCE_ID; |
terencez | 0:c2dff8cbb91a | 343 | } |
terencez | 0:c2dff8cbb91a | 344 | result = targetP->createFunc(uriP->instanceId, size, dataP, targetP); |
terencez | 0:c2dff8cbb91a | 345 | break; |
terencez | 0:c2dff8cbb91a | 346 | } |
terencez | 0:c2dff8cbb91a | 347 | |
terencez | 0:c2dff8cbb91a | 348 | exit: |
terencez | 0:c2dff8cbb91a | 349 | lwm2m_data_free(size, dataP); |
terencez | 0:c2dff8cbb91a | 350 | |
terencez | 0:c2dff8cbb91a | 351 | LOG_ARG("result: %u.%2u", (result & 0xFF) >> 5, (result & 0x1F)); |
terencez | 0:c2dff8cbb91a | 352 | |
terencez | 0:c2dff8cbb91a | 353 | return result; |
terencez | 0:c2dff8cbb91a | 354 | } |
terencez | 0:c2dff8cbb91a | 355 | |
terencez | 0:c2dff8cbb91a | 356 | coap_status_t object_delete(lwm2m_context_t * contextP, |
terencez | 0:c2dff8cbb91a | 357 | lwm2m_uri_t * uriP) |
terencez | 0:c2dff8cbb91a | 358 | { |
terencez | 0:c2dff8cbb91a | 359 | lwm2m_object_t * objectP; |
terencez | 0:c2dff8cbb91a | 360 | coap_status_t result; |
terencez | 0:c2dff8cbb91a | 361 | |
terencez | 0:c2dff8cbb91a | 362 | LOG_URI(uriP); |
terencez | 0:c2dff8cbb91a | 363 | objectP = (lwm2m_object_t *)LWM2M_LIST_FIND(contextP->objectList, uriP->objectId); |
terencez | 0:c2dff8cbb91a | 364 | if (NULL == objectP) return COAP_404_NOT_FOUND; |
terencez | 0:c2dff8cbb91a | 365 | if (NULL == objectP->deleteFunc) return COAP_405_METHOD_NOT_ALLOWED; |
terencez | 0:c2dff8cbb91a | 366 | |
terencez | 0:c2dff8cbb91a | 367 | LOG("Entering"); |
terencez | 0:c2dff8cbb91a | 368 | |
terencez | 0:c2dff8cbb91a | 369 | if (LWM2M_URI_IS_SET_INSTANCE(uriP)) |
terencez | 0:c2dff8cbb91a | 370 | { |
terencez | 0:c2dff8cbb91a | 371 | result = objectP->deleteFunc(uriP->instanceId, objectP); |
terencez | 0:c2dff8cbb91a | 372 | } |
terencez | 0:c2dff8cbb91a | 373 | else |
terencez | 0:c2dff8cbb91a | 374 | { |
terencez | 0:c2dff8cbb91a | 375 | lwm2m_list_t * instanceP; |
terencez | 0:c2dff8cbb91a | 376 | |
terencez | 0:c2dff8cbb91a | 377 | result = COAP_202_DELETED; |
terencez | 0:c2dff8cbb91a | 378 | instanceP = objectP->instanceList; |
terencez | 0:c2dff8cbb91a | 379 | while (NULL != instanceP |
terencez | 0:c2dff8cbb91a | 380 | && result == COAP_202_DELETED) |
terencez | 0:c2dff8cbb91a | 381 | { |
terencez | 0:c2dff8cbb91a | 382 | result = objectP->deleteFunc(instanceP->id, objectP); |
terencez | 0:c2dff8cbb91a | 383 | instanceP = objectP->instanceList; |
terencez | 0:c2dff8cbb91a | 384 | } |
terencez | 0:c2dff8cbb91a | 385 | } |
terencez | 0:c2dff8cbb91a | 386 | |
terencez | 0:c2dff8cbb91a | 387 | LOG_ARG("result: %u.%2u", (result & 0xFF) >> 5, (result & 0x1F)); |
terencez | 0:c2dff8cbb91a | 388 | |
terencez | 0:c2dff8cbb91a | 389 | return result; |
terencez | 0:c2dff8cbb91a | 390 | } |
terencez | 0:c2dff8cbb91a | 391 | |
terencez | 0:c2dff8cbb91a | 392 | coap_status_t object_discover(lwm2m_context_t * contextP, |
terencez | 0:c2dff8cbb91a | 393 | lwm2m_uri_t * uriP, |
terencez | 0:c2dff8cbb91a | 394 | lwm2m_server_t * serverP, |
terencez | 0:c2dff8cbb91a | 395 | uint8_t ** bufferP, |
terencez | 0:c2dff8cbb91a | 396 | size_t * lengthP) |
terencez | 0:c2dff8cbb91a | 397 | { |
terencez | 0:c2dff8cbb91a | 398 | coap_status_t result; |
terencez | 0:c2dff8cbb91a | 399 | lwm2m_object_t * targetP; |
terencez | 0:c2dff8cbb91a | 400 | lwm2m_data_t * dataP = NULL; |
terencez | 0:c2dff8cbb91a | 401 | int size = 0; |
terencez | 0:c2dff8cbb91a | 402 | |
terencez | 0:c2dff8cbb91a | 403 | LOG_URI(uriP); |
terencez | 0:c2dff8cbb91a | 404 | targetP = (lwm2m_object_t *)LWM2M_LIST_FIND(contextP->objectList, uriP->objectId); |
terencez | 0:c2dff8cbb91a | 405 | if (NULL == targetP) return COAP_404_NOT_FOUND; |
terencez | 0:c2dff8cbb91a | 406 | if (NULL == targetP->discoverFunc) return COAP_501_NOT_IMPLEMENTED; |
terencez | 0:c2dff8cbb91a | 407 | |
terencez | 0:c2dff8cbb91a | 408 | if (LWM2M_URI_IS_SET_INSTANCE(uriP)) |
terencez | 0:c2dff8cbb91a | 409 | { |
terencez | 0:c2dff8cbb91a | 410 | if (NULL == lwm2m_list_find(targetP->instanceList, uriP->instanceId)) return COAP_404_NOT_FOUND; |
terencez | 0:c2dff8cbb91a | 411 | |
terencez | 0:c2dff8cbb91a | 412 | // single instance read |
terencez | 0:c2dff8cbb91a | 413 | if (LWM2M_URI_IS_SET_RESOURCE(uriP)) |
terencez | 0:c2dff8cbb91a | 414 | { |
terencez | 0:c2dff8cbb91a | 415 | size = 1; |
terencez | 0:c2dff8cbb91a | 416 | dataP = lwm2m_data_new(size); |
terencez | 0:c2dff8cbb91a | 417 | if (dataP == NULL) return COAP_500_INTERNAL_SERVER_ERROR; |
terencez | 0:c2dff8cbb91a | 418 | |
terencez | 0:c2dff8cbb91a | 419 | dataP->id = uriP->resourceId; |
terencez | 0:c2dff8cbb91a | 420 | } |
terencez | 0:c2dff8cbb91a | 421 | |
terencez | 0:c2dff8cbb91a | 422 | result = targetP->discoverFunc(uriP->instanceId, &size, &dataP, targetP); |
terencez | 0:c2dff8cbb91a | 423 | } |
terencez | 0:c2dff8cbb91a | 424 | else |
terencez | 0:c2dff8cbb91a | 425 | { |
terencez | 0:c2dff8cbb91a | 426 | // multiple object instances read |
terencez | 0:c2dff8cbb91a | 427 | lwm2m_list_t * instanceP; |
terencez | 0:c2dff8cbb91a | 428 | int i; |
terencez | 0:c2dff8cbb91a | 429 | |
terencez | 0:c2dff8cbb91a | 430 | result = COAP_205_CONTENT; |
terencez | 0:c2dff8cbb91a | 431 | |
terencez | 0:c2dff8cbb91a | 432 | size = 0; |
terencez | 0:c2dff8cbb91a | 433 | for (instanceP = targetP->instanceList; instanceP != NULL ; instanceP = instanceP->next) |
terencez | 0:c2dff8cbb91a | 434 | { |
terencez | 0:c2dff8cbb91a | 435 | size++; |
terencez | 0:c2dff8cbb91a | 436 | } |
terencez | 0:c2dff8cbb91a | 437 | |
terencez | 0:c2dff8cbb91a | 438 | if (size != 0) |
terencez | 0:c2dff8cbb91a | 439 | { |
terencez | 0:c2dff8cbb91a | 440 | dataP = lwm2m_data_new(size); |
terencez | 0:c2dff8cbb91a | 441 | if (dataP == NULL) return COAP_500_INTERNAL_SERVER_ERROR; |
terencez | 0:c2dff8cbb91a | 442 | |
terencez | 0:c2dff8cbb91a | 443 | instanceP = targetP->instanceList; |
terencez | 0:c2dff8cbb91a | 444 | i = 0; |
terencez | 0:c2dff8cbb91a | 445 | while (instanceP != NULL && result == COAP_205_CONTENT) |
terencez | 0:c2dff8cbb91a | 446 | { |
terencez | 0:c2dff8cbb91a | 447 | result = targetP->discoverFunc(instanceP->id, (int*)&(dataP[i].value.asChildren.count), &(dataP[i].value.asChildren.array), targetP); |
terencez | 0:c2dff8cbb91a | 448 | dataP[i].type = LWM2M_TYPE_OBJECT_INSTANCE; |
terencez | 0:c2dff8cbb91a | 449 | dataP[i].id = instanceP->id; |
terencez | 0:c2dff8cbb91a | 450 | i++; |
terencez | 0:c2dff8cbb91a | 451 | instanceP = instanceP->next; |
terencez | 0:c2dff8cbb91a | 452 | } |
terencez | 0:c2dff8cbb91a | 453 | } |
terencez | 0:c2dff8cbb91a | 454 | } |
terencez | 0:c2dff8cbb91a | 455 | |
terencez | 0:c2dff8cbb91a | 456 | if (result == COAP_205_CONTENT) |
terencez | 0:c2dff8cbb91a | 457 | { |
terencez | 0:c2dff8cbb91a | 458 | int len; |
terencez | 0:c2dff8cbb91a | 459 | |
terencez | 0:c2dff8cbb91a | 460 | len = discover_serialize(contextP, uriP, serverP, size, dataP, bufferP); |
terencez | 0:c2dff8cbb91a | 461 | if (len <= 0) result = COAP_500_INTERNAL_SERVER_ERROR; |
terencez | 0:c2dff8cbb91a | 462 | else *lengthP = len; |
terencez | 0:c2dff8cbb91a | 463 | } |
terencez | 0:c2dff8cbb91a | 464 | lwm2m_data_free(size, dataP); |
terencez | 0:c2dff8cbb91a | 465 | |
terencez | 0:c2dff8cbb91a | 466 | LOG_ARG("result: %u.%2u", (result & 0xFF) >> 5, (result & 0x1F)); |
terencez | 0:c2dff8cbb91a | 467 | |
terencez | 0:c2dff8cbb91a | 468 | return result; |
terencez | 0:c2dff8cbb91a | 469 | } |
terencez | 0:c2dff8cbb91a | 470 | |
terencez | 0:c2dff8cbb91a | 471 | bool object_isInstanceNew(lwm2m_context_t * contextP, |
terencez | 0:c2dff8cbb91a | 472 | uint16_t objectId, |
terencez | 0:c2dff8cbb91a | 473 | uint16_t instanceId) |
terencez | 0:c2dff8cbb91a | 474 | { |
terencez | 0:c2dff8cbb91a | 475 | lwm2m_object_t * targetP; |
terencez | 0:c2dff8cbb91a | 476 | |
terencez | 0:c2dff8cbb91a | 477 | LOG("Entering"); |
terencez | 0:c2dff8cbb91a | 478 | targetP = (lwm2m_object_t *)LWM2M_LIST_FIND(contextP->objectList, objectId); |
terencez | 0:c2dff8cbb91a | 479 | if (targetP != NULL) |
terencez | 0:c2dff8cbb91a | 480 | { |
terencez | 0:c2dff8cbb91a | 481 | if (NULL != lwm2m_list_find(targetP->instanceList, instanceId)) |
terencez | 0:c2dff8cbb91a | 482 | { |
terencez | 0:c2dff8cbb91a | 483 | return false; |
terencez | 0:c2dff8cbb91a | 484 | } |
terencez | 0:c2dff8cbb91a | 485 | } |
terencez | 0:c2dff8cbb91a | 486 | |
terencez | 0:c2dff8cbb91a | 487 | return true; |
terencez | 0:c2dff8cbb91a | 488 | } |
terencez | 0:c2dff8cbb91a | 489 | |
terencez | 0:c2dff8cbb91a | 490 | static int prv_getObjectTemplate(uint8_t * buffer, |
terencez | 0:c2dff8cbb91a | 491 | size_t length, |
terencez | 0:c2dff8cbb91a | 492 | uint16_t id) |
terencez | 0:c2dff8cbb91a | 493 | { |
terencez | 0:c2dff8cbb91a | 494 | int index; |
terencez | 0:c2dff8cbb91a | 495 | int result; |
terencez | 0:c2dff8cbb91a | 496 | |
terencez | 0:c2dff8cbb91a | 497 | if (length < REG_OBJECT_MIN_LEN) return -1; |
terencez | 0:c2dff8cbb91a | 498 | |
terencez | 0:c2dff8cbb91a | 499 | buffer[0] = '<'; |
terencez | 0:c2dff8cbb91a | 500 | buffer[1] = '/'; |
terencez | 0:c2dff8cbb91a | 501 | index = 2; |
terencez | 0:c2dff8cbb91a | 502 | |
terencez | 0:c2dff8cbb91a | 503 | result = utils_intCopy((char *)buffer + index, length - index, id); |
terencez | 0:c2dff8cbb91a | 504 | if (result < 0) return -1; |
terencez | 0:c2dff8cbb91a | 505 | index += result; |
terencez | 0:c2dff8cbb91a | 506 | |
terencez | 0:c2dff8cbb91a | 507 | if (length - index < REG_OBJECT_MIN_LEN - 3) return -1; |
terencez | 0:c2dff8cbb91a | 508 | buffer[index] = '/'; |
terencez | 0:c2dff8cbb91a | 509 | index++; |
terencez | 0:c2dff8cbb91a | 510 | |
terencez | 0:c2dff8cbb91a | 511 | return index; |
terencez | 0:c2dff8cbb91a | 512 | } |
terencez | 0:c2dff8cbb91a | 513 | |
terencez | 0:c2dff8cbb91a | 514 | int object_getRegisterPayload(lwm2m_context_t * contextP, |
terencez | 0:c2dff8cbb91a | 515 | uint8_t * buffer, |
terencez | 0:c2dff8cbb91a | 516 | size_t bufferLen) |
terencez | 0:c2dff8cbb91a | 517 | { |
terencez | 0:c2dff8cbb91a | 518 | size_t index; |
terencez | 0:c2dff8cbb91a | 519 | int result; |
terencez | 0:c2dff8cbb91a | 520 | lwm2m_object_t * objectP; |
terencez | 0:c2dff8cbb91a | 521 | |
terencez | 0:c2dff8cbb91a | 522 | LOG("Entering"); |
terencez | 0:c2dff8cbb91a | 523 | // index can not be greater than bufferLen |
terencez | 0:c2dff8cbb91a | 524 | index = 0; |
terencez | 0:c2dff8cbb91a | 525 | |
terencez | 0:c2dff8cbb91a | 526 | result = utils_stringCopy((char *)buffer, bufferLen, REG_START); |
terencez | 0:c2dff8cbb91a | 527 | if (result < 0) return 0; |
terencez | 0:c2dff8cbb91a | 528 | index += result; |
terencez | 0:c2dff8cbb91a | 529 | |
terencez | 0:c2dff8cbb91a | 530 | if ((contextP->altPath != NULL) |
terencez | 0:c2dff8cbb91a | 531 | && (contextP->altPath[0] != 0)) |
terencez | 0:c2dff8cbb91a | 532 | { |
terencez | 0:c2dff8cbb91a | 533 | result = utils_stringCopy((char *)buffer + index, bufferLen - index, contextP->altPath); |
terencez | 0:c2dff8cbb91a | 534 | } |
terencez | 0:c2dff8cbb91a | 535 | else |
terencez | 0:c2dff8cbb91a | 536 | { |
terencez | 0:c2dff8cbb91a | 537 | result = utils_stringCopy((char *)buffer + index, bufferLen - index, REG_DEFAULT_PATH); |
terencez | 0:c2dff8cbb91a | 538 | } |
terencez | 0:c2dff8cbb91a | 539 | if (result < 0) return 0; |
terencez | 0:c2dff8cbb91a | 540 | index += result; |
terencez | 0:c2dff8cbb91a | 541 | |
terencez | 0:c2dff8cbb91a | 542 | result = utils_stringCopy((char *)buffer + index, bufferLen - index, REG_LWM2M_RESOURCE_TYPE); |
terencez | 0:c2dff8cbb91a | 543 | if (result < 0) return 0; |
terencez | 0:c2dff8cbb91a | 544 | index += result; |
terencez | 0:c2dff8cbb91a | 545 | |
terencez | 0:c2dff8cbb91a | 546 | for (objectP = contextP->objectList; objectP != NULL; objectP = objectP->next) |
terencez | 0:c2dff8cbb91a | 547 | { |
terencez | 0:c2dff8cbb91a | 548 | size_t start; |
terencez | 0:c2dff8cbb91a | 549 | size_t length; |
terencez | 0:c2dff8cbb91a | 550 | |
terencez | 0:c2dff8cbb91a | 551 | if (objectP->objID == LWM2M_SECURITY_OBJECT_ID) continue; |
terencez | 0:c2dff8cbb91a | 552 | |
terencez | 0:c2dff8cbb91a | 553 | start = index; |
terencez | 0:c2dff8cbb91a | 554 | result = prv_getObjectTemplate(buffer + index, bufferLen - index, objectP->objID); |
terencez | 0:c2dff8cbb91a | 555 | if (result < 0) return 0; |
terencez | 0:c2dff8cbb91a | 556 | length = result; |
terencez | 0:c2dff8cbb91a | 557 | index += length; |
terencez | 0:c2dff8cbb91a | 558 | |
terencez | 0:c2dff8cbb91a | 559 | if (objectP->instanceList == NULL) |
terencez | 0:c2dff8cbb91a | 560 | { |
terencez | 0:c2dff8cbb91a | 561 | index--; |
terencez | 0:c2dff8cbb91a | 562 | result = utils_stringCopy((char *)buffer + index, bufferLen - index, REG_PATH_END); |
terencez | 0:c2dff8cbb91a | 563 | if (result < 0) return 0; |
terencez | 0:c2dff8cbb91a | 564 | index += result; |
terencez | 0:c2dff8cbb91a | 565 | } |
terencez | 0:c2dff8cbb91a | 566 | else |
terencez | 0:c2dff8cbb91a | 567 | { |
terencez | 0:c2dff8cbb91a | 568 | lwm2m_list_t * targetP; |
terencez | 0:c2dff8cbb91a | 569 | for (targetP = objectP->instanceList ; targetP != NULL ; targetP = targetP->next) |
terencez | 0:c2dff8cbb91a | 570 | { |
terencez | 0:c2dff8cbb91a | 571 | if (bufferLen - index <= length) return 0; |
terencez | 0:c2dff8cbb91a | 572 | |
terencez | 0:c2dff8cbb91a | 573 | if (index != start + length) |
terencez | 0:c2dff8cbb91a | 574 | { |
terencez | 0:c2dff8cbb91a | 575 | memcpy(buffer + index, buffer + start, length); |
terencez | 0:c2dff8cbb91a | 576 | index += length; |
terencez | 0:c2dff8cbb91a | 577 | } |
terencez | 0:c2dff8cbb91a | 578 | |
terencez | 0:c2dff8cbb91a | 579 | result = utils_intCopy((char *)buffer + index, bufferLen - index, targetP->id); |
terencez | 0:c2dff8cbb91a | 580 | if (result < 0) return 0; |
terencez | 0:c2dff8cbb91a | 581 | index += result; |
terencez | 0:c2dff8cbb91a | 582 | |
terencez | 0:c2dff8cbb91a | 583 | result = utils_stringCopy((char *)buffer + index, bufferLen - index, REG_PATH_END); |
terencez | 0:c2dff8cbb91a | 584 | if (result < 0) return 0; |
terencez | 0:c2dff8cbb91a | 585 | index += result; |
terencez | 0:c2dff8cbb91a | 586 | } |
terencez | 0:c2dff8cbb91a | 587 | } |
terencez | 0:c2dff8cbb91a | 588 | } |
terencez | 0:c2dff8cbb91a | 589 | |
terencez | 0:c2dff8cbb91a | 590 | if (index > 0) |
terencez | 0:c2dff8cbb91a | 591 | { |
terencez | 0:c2dff8cbb91a | 592 | index = index - 1; // remove trailing ',' |
terencez | 0:c2dff8cbb91a | 593 | } |
terencez | 0:c2dff8cbb91a | 594 | |
terencez | 0:c2dff8cbb91a | 595 | buffer[index] = 0; |
terencez | 0:c2dff8cbb91a | 596 | |
terencez | 0:c2dff8cbb91a | 597 | return index; |
terencez | 0:c2dff8cbb91a | 598 | } |
terencez | 0:c2dff8cbb91a | 599 | |
terencez | 0:c2dff8cbb91a | 600 | static lwm2m_list_t * prv_findServerInstance(lwm2m_object_t * objectP, |
terencez | 0:c2dff8cbb91a | 601 | uint16_t shortID) |
terencez | 0:c2dff8cbb91a | 602 | { |
terencez | 0:c2dff8cbb91a | 603 | lwm2m_list_t * instanceP; |
terencez | 0:c2dff8cbb91a | 604 | |
terencez | 0:c2dff8cbb91a | 605 | instanceP = objectP->instanceList; |
terencez | 0:c2dff8cbb91a | 606 | while (NULL != instanceP) |
terencez | 0:c2dff8cbb91a | 607 | { |
terencez | 0:c2dff8cbb91a | 608 | int64_t value; |
terencez | 0:c2dff8cbb91a | 609 | lwm2m_data_t * dataP; |
terencez | 0:c2dff8cbb91a | 610 | int size; |
terencez | 0:c2dff8cbb91a | 611 | |
terencez | 0:c2dff8cbb91a | 612 | size = 1; |
terencez | 0:c2dff8cbb91a | 613 | dataP = lwm2m_data_new(size); |
terencez | 0:c2dff8cbb91a | 614 | if (dataP == NULL) return NULL; |
terencez | 0:c2dff8cbb91a | 615 | dataP->id = LWM2M_SERVER_SHORT_ID_ID; |
terencez | 0:c2dff8cbb91a | 616 | |
terencez | 0:c2dff8cbb91a | 617 | if (objectP->readFunc(instanceP->id, &size, &dataP, objectP) != COAP_205_CONTENT) |
terencez | 0:c2dff8cbb91a | 618 | { |
terencez | 0:c2dff8cbb91a | 619 | lwm2m_data_free(size, dataP); |
terencez | 0:c2dff8cbb91a | 620 | return NULL; |
terencez | 0:c2dff8cbb91a | 621 | } |
terencez | 0:c2dff8cbb91a | 622 | |
terencez | 0:c2dff8cbb91a | 623 | if (1 == lwm2m_data_decode_int(dataP, &value)) |
terencez | 0:c2dff8cbb91a | 624 | { |
terencez | 0:c2dff8cbb91a | 625 | if (value == shortID) |
terencez | 0:c2dff8cbb91a | 626 | { |
terencez | 0:c2dff8cbb91a | 627 | lwm2m_data_free(size, dataP); |
terencez | 0:c2dff8cbb91a | 628 | break; |
terencez | 0:c2dff8cbb91a | 629 | } |
terencez | 0:c2dff8cbb91a | 630 | } |
terencez | 0:c2dff8cbb91a | 631 | lwm2m_data_free(size, dataP); |
terencez | 0:c2dff8cbb91a | 632 | instanceP = instanceP->next; |
terencez | 0:c2dff8cbb91a | 633 | } |
terencez | 0:c2dff8cbb91a | 634 | |
terencez | 0:c2dff8cbb91a | 635 | return instanceP; |
terencez | 0:c2dff8cbb91a | 636 | } |
terencez | 0:c2dff8cbb91a | 637 | |
terencez | 0:c2dff8cbb91a | 638 | static int prv_getMandatoryInfo(lwm2m_object_t * objectP, |
terencez | 0:c2dff8cbb91a | 639 | uint16_t instanceID, |
terencez | 0:c2dff8cbb91a | 640 | lwm2m_server_t * targetP) |
terencez | 0:c2dff8cbb91a | 641 | { |
terencez | 0:c2dff8cbb91a | 642 | lwm2m_data_t * dataP; |
terencez | 0:c2dff8cbb91a | 643 | int size; |
terencez | 0:c2dff8cbb91a | 644 | int64_t value; |
terencez | 0:c2dff8cbb91a | 645 | |
terencez | 0:c2dff8cbb91a | 646 | size = 2; |
terencez | 0:c2dff8cbb91a | 647 | dataP = lwm2m_data_new(size); |
terencez | 0:c2dff8cbb91a | 648 | if (dataP == NULL) return -1; |
terencez | 0:c2dff8cbb91a | 649 | dataP[0].id = LWM2M_SERVER_LIFETIME_ID; |
terencez | 0:c2dff8cbb91a | 650 | dataP[1].id = LWM2M_SERVER_BINDING_ID; |
terencez | 0:c2dff8cbb91a | 651 | |
terencez | 0:c2dff8cbb91a | 652 | if (objectP->readFunc(instanceID, &size, &dataP, objectP) != COAP_205_CONTENT) |
terencez | 0:c2dff8cbb91a | 653 | { |
terencez | 0:c2dff8cbb91a | 654 | lwm2m_data_free(size, dataP); |
terencez | 0:c2dff8cbb91a | 655 | return -1; |
terencez | 0:c2dff8cbb91a | 656 | } |
terencez | 0:c2dff8cbb91a | 657 | |
terencez | 0:c2dff8cbb91a | 658 | if (0 == lwm2m_data_decode_int(dataP, &value) |
terencez | 0:c2dff8cbb91a | 659 | || value < 0 || value >0xFFFFFFFF) // This is an implementation limit |
terencez | 0:c2dff8cbb91a | 660 | { |
terencez | 0:c2dff8cbb91a | 661 | lwm2m_data_free(size, dataP); |
terencez | 0:c2dff8cbb91a | 662 | return -1; |
terencez | 0:c2dff8cbb91a | 663 | } |
terencez | 0:c2dff8cbb91a | 664 | targetP->lifetime = value; |
terencez | 0:c2dff8cbb91a | 665 | |
terencez | 0:c2dff8cbb91a | 666 | targetP->binding = utils_stringToBinding(dataP[1].value.asBuffer.buffer, dataP[1].value.asBuffer.length); |
terencez | 0:c2dff8cbb91a | 667 | |
terencez | 0:c2dff8cbb91a | 668 | lwm2m_data_free(size, dataP); |
terencez | 0:c2dff8cbb91a | 669 | |
terencez | 0:c2dff8cbb91a | 670 | if (targetP->binding == BINDING_UNKNOWN) |
terencez | 0:c2dff8cbb91a | 671 | { |
terencez | 0:c2dff8cbb91a | 672 | return -1; |
terencez | 0:c2dff8cbb91a | 673 | } |
terencez | 0:c2dff8cbb91a | 674 | |
terencez | 0:c2dff8cbb91a | 675 | return 0; |
terencez | 0:c2dff8cbb91a | 676 | } |
terencez | 0:c2dff8cbb91a | 677 | |
terencez | 0:c2dff8cbb91a | 678 | int object_getServers(lwm2m_context_t * contextP) |
terencez | 0:c2dff8cbb91a | 679 | { |
terencez | 0:c2dff8cbb91a | 680 | lwm2m_object_t * objectP; |
terencez | 0:c2dff8cbb91a | 681 | lwm2m_object_t * securityObjP = NULL; |
terencez | 0:c2dff8cbb91a | 682 | lwm2m_object_t * serverObjP = NULL; |
terencez | 0:c2dff8cbb91a | 683 | lwm2m_list_t * securityInstP; // instanceID of the server in the LWM2M Security Object |
terencez | 0:c2dff8cbb91a | 684 | |
terencez | 0:c2dff8cbb91a | 685 | LOG("Entering"); |
terencez | 0:c2dff8cbb91a | 686 | |
terencez | 0:c2dff8cbb91a | 687 | for (objectP = contextP->objectList; objectP != NULL; objectP = objectP->next) |
terencez | 0:c2dff8cbb91a | 688 | { |
terencez | 0:c2dff8cbb91a | 689 | if (objectP->objID == LWM2M_SECURITY_OBJECT_ID) |
terencez | 0:c2dff8cbb91a | 690 | { |
terencez | 0:c2dff8cbb91a | 691 | securityObjP = objectP; |
terencez | 0:c2dff8cbb91a | 692 | } |
terencez | 0:c2dff8cbb91a | 693 | else if (objectP->objID == LWM2M_SERVER_OBJECT_ID) |
terencez | 0:c2dff8cbb91a | 694 | { |
terencez | 0:c2dff8cbb91a | 695 | serverObjP = objectP; |
terencez | 0:c2dff8cbb91a | 696 | } |
terencez | 0:c2dff8cbb91a | 697 | } |
terencez | 0:c2dff8cbb91a | 698 | |
terencez | 0:c2dff8cbb91a | 699 | if (NULL == securityObjP) return -1; |
terencez | 0:c2dff8cbb91a | 700 | |
terencez | 0:c2dff8cbb91a | 701 | securityInstP = securityObjP->instanceList; |
terencez | 0:c2dff8cbb91a | 702 | while (securityInstP != NULL) |
terencez | 0:c2dff8cbb91a | 703 | { |
terencez | 0:c2dff8cbb91a | 704 | if (LWM2M_LIST_FIND(contextP->bootstrapServerList, securityInstP->id) == NULL |
terencez | 0:c2dff8cbb91a | 705 | && LWM2M_LIST_FIND(contextP->serverList, securityInstP->id) == NULL) |
terencez | 0:c2dff8cbb91a | 706 | { |
terencez | 0:c2dff8cbb91a | 707 | // This server is new. eg created by last bootstrap |
terencez | 0:c2dff8cbb91a | 708 | |
terencez | 0:c2dff8cbb91a | 709 | lwm2m_data_t * dataP; |
terencez | 0:c2dff8cbb91a | 710 | int size; |
terencez | 0:c2dff8cbb91a | 711 | lwm2m_server_t * targetP; |
terencez | 0:c2dff8cbb91a | 712 | bool isBootstrap; |
terencez | 0:c2dff8cbb91a | 713 | int64_t value = 0; |
terencez | 0:c2dff8cbb91a | 714 | |
terencez | 0:c2dff8cbb91a | 715 | size = 3; |
terencez | 0:c2dff8cbb91a | 716 | dataP = lwm2m_data_new(size); |
terencez | 0:c2dff8cbb91a | 717 | if (dataP == NULL) return -1; |
terencez | 0:c2dff8cbb91a | 718 | dataP[0].id = LWM2M_SECURITY_BOOTSTRAP_ID; |
terencez | 0:c2dff8cbb91a | 719 | dataP[1].id = LWM2M_SECURITY_SHORT_SERVER_ID; |
terencez | 0:c2dff8cbb91a | 720 | dataP[2].id = LWM2M_SECURITY_HOLD_OFF_ID; |
terencez | 0:c2dff8cbb91a | 721 | |
terencez | 0:c2dff8cbb91a | 722 | if (securityObjP->readFunc(securityInstP->id, &size, &dataP, securityObjP) != COAP_205_CONTENT) |
terencez | 0:c2dff8cbb91a | 723 | { |
terencez | 0:c2dff8cbb91a | 724 | lwm2m_data_free(size, dataP); |
terencez | 0:c2dff8cbb91a | 725 | return -1; |
terencez | 0:c2dff8cbb91a | 726 | } |
terencez | 0:c2dff8cbb91a | 727 | |
terencez | 0:c2dff8cbb91a | 728 | targetP = (lwm2m_server_t *)lwm2m_malloc(sizeof(lwm2m_server_t)); |
terencez | 0:c2dff8cbb91a | 729 | if (targetP == NULL) { |
terencez | 0:c2dff8cbb91a | 730 | lwm2m_data_free(size, dataP); |
terencez | 0:c2dff8cbb91a | 731 | return -1; |
terencez | 0:c2dff8cbb91a | 732 | } |
terencez | 0:c2dff8cbb91a | 733 | memset(targetP, 0, sizeof(lwm2m_server_t)); |
terencez | 0:c2dff8cbb91a | 734 | targetP->secObjInstID = securityInstP->id; |
terencez | 0:c2dff8cbb91a | 735 | |
terencez | 0:c2dff8cbb91a | 736 | if (0 == lwm2m_data_decode_bool(dataP + 0, &isBootstrap)) |
terencez | 0:c2dff8cbb91a | 737 | { |
terencez | 0:c2dff8cbb91a | 738 | lwm2m_free(targetP); |
terencez | 0:c2dff8cbb91a | 739 | lwm2m_data_free(size, dataP); |
terencez | 0:c2dff8cbb91a | 740 | return -1; |
terencez | 0:c2dff8cbb91a | 741 | } |
terencez | 0:c2dff8cbb91a | 742 | |
terencez | 0:c2dff8cbb91a | 743 | if (0 == lwm2m_data_decode_int(dataP + 1, &value) |
terencez | 0:c2dff8cbb91a | 744 | || value < (isBootstrap ? 0 : 1) || value > 0xFFFF) // 0 is forbidden as a Short Server ID |
terencez | 0:c2dff8cbb91a | 745 | { |
terencez | 0:c2dff8cbb91a | 746 | lwm2m_free(targetP); |
terencez | 0:c2dff8cbb91a | 747 | lwm2m_data_free(size, dataP); |
terencez | 0:c2dff8cbb91a | 748 | return -1; |
terencez | 0:c2dff8cbb91a | 749 | } |
terencez | 0:c2dff8cbb91a | 750 | targetP->shortID = value; |
terencez | 0:c2dff8cbb91a | 751 | |
terencez | 0:c2dff8cbb91a | 752 | if (isBootstrap == true) |
terencez | 0:c2dff8cbb91a | 753 | { |
terencez | 0:c2dff8cbb91a | 754 | if (0 == lwm2m_data_decode_int(dataP + 2, &value) |
terencez | 0:c2dff8cbb91a | 755 | || value < 0 || value > 0xFFFFFFFF) // This is an implementation limit |
terencez | 0:c2dff8cbb91a | 756 | { |
terencez | 0:c2dff8cbb91a | 757 | lwm2m_free(targetP); |
terencez | 0:c2dff8cbb91a | 758 | lwm2m_data_free(size, dataP); |
terencez | 0:c2dff8cbb91a | 759 | return -1; |
terencez | 0:c2dff8cbb91a | 760 | } |
terencez | 0:c2dff8cbb91a | 761 | // lifetime of a bootstrap server is set to ClientHoldOffTime |
terencez | 0:c2dff8cbb91a | 762 | targetP->lifetime = value; |
terencez | 0:c2dff8cbb91a | 763 | |
terencez | 0:c2dff8cbb91a | 764 | contextP->bootstrapServerList = (lwm2m_server_t*)LWM2M_LIST_ADD(contextP->bootstrapServerList, targetP); |
terencez | 0:c2dff8cbb91a | 765 | } |
terencez | 0:c2dff8cbb91a | 766 | else |
terencez | 0:c2dff8cbb91a | 767 | { |
terencez | 0:c2dff8cbb91a | 768 | lwm2m_list_t * serverInstP; // instanceID of the server in the LWM2M Server Object |
terencez | 0:c2dff8cbb91a | 769 | |
terencez | 0:c2dff8cbb91a | 770 | serverInstP = prv_findServerInstance(serverObjP, targetP->shortID); |
terencez | 0:c2dff8cbb91a | 771 | if (serverInstP == NULL) |
terencez | 0:c2dff8cbb91a | 772 | { |
terencez | 0:c2dff8cbb91a | 773 | lwm2m_free(targetP); |
terencez | 0:c2dff8cbb91a | 774 | lwm2m_data_free(size, dataP); |
terencez | 0:c2dff8cbb91a | 775 | return -1; |
terencez | 0:c2dff8cbb91a | 776 | } |
terencez | 0:c2dff8cbb91a | 777 | if (0 != prv_getMandatoryInfo(serverObjP, serverInstP->id, targetP)) |
terencez | 0:c2dff8cbb91a | 778 | { |
terencez | 0:c2dff8cbb91a | 779 | lwm2m_free(targetP); |
terencez | 0:c2dff8cbb91a | 780 | lwm2m_data_free(size, dataP); |
terencez | 0:c2dff8cbb91a | 781 | return -1; |
terencez | 0:c2dff8cbb91a | 782 | } |
terencez | 0:c2dff8cbb91a | 783 | targetP->status = STATE_DEREGISTERED; |
terencez | 0:c2dff8cbb91a | 784 | contextP->serverList = (lwm2m_server_t*)LWM2M_LIST_ADD(contextP->serverList, targetP); |
terencez | 0:c2dff8cbb91a | 785 | } |
terencez | 0:c2dff8cbb91a | 786 | lwm2m_data_free(size, dataP); |
terencez | 0:c2dff8cbb91a | 787 | } |
terencez | 0:c2dff8cbb91a | 788 | securityInstP = securityInstP->next; |
terencez | 0:c2dff8cbb91a | 789 | } |
terencez | 0:c2dff8cbb91a | 790 | |
terencez | 0:c2dff8cbb91a | 791 | return 0; |
terencez | 0:c2dff8cbb91a | 792 | } |
terencez | 0:c2dff8cbb91a | 793 | |
terencez | 0:c2dff8cbb91a | 794 | coap_status_t object_createInstance(lwm2m_context_t * contextP, |
terencez | 0:c2dff8cbb91a | 795 | lwm2m_uri_t * uriP, |
terencez | 0:c2dff8cbb91a | 796 | lwm2m_data_t * dataP) |
terencez | 0:c2dff8cbb91a | 797 | { |
terencez | 0:c2dff8cbb91a | 798 | lwm2m_object_t * targetP; |
terencez | 0:c2dff8cbb91a | 799 | |
terencez | 0:c2dff8cbb91a | 800 | LOG_URI(uriP); |
terencez | 0:c2dff8cbb91a | 801 | targetP = (lwm2m_object_t *)LWM2M_LIST_FIND(contextP->objectList, uriP->objectId); |
terencez | 0:c2dff8cbb91a | 802 | if (NULL == targetP) return COAP_404_NOT_FOUND; |
terencez | 0:c2dff8cbb91a | 803 | |
terencez | 0:c2dff8cbb91a | 804 | if (NULL == targetP->createFunc) |
terencez | 0:c2dff8cbb91a | 805 | { |
terencez | 0:c2dff8cbb91a | 806 | return COAP_405_METHOD_NOT_ALLOWED; |
terencez | 0:c2dff8cbb91a | 807 | } |
terencez | 0:c2dff8cbb91a | 808 | |
terencez | 0:c2dff8cbb91a | 809 | return targetP->createFunc(lwm2m_list_newId(targetP->instanceList), dataP->value.asChildren.count, dataP->value.asChildren.array, targetP); |
terencez | 0:c2dff8cbb91a | 810 | } |
terencez | 0:c2dff8cbb91a | 811 | |
terencez | 0:c2dff8cbb91a | 812 | coap_status_t object_writeInstance(lwm2m_context_t * contextP, |
terencez | 0:c2dff8cbb91a | 813 | lwm2m_uri_t * uriP, |
terencez | 0:c2dff8cbb91a | 814 | lwm2m_data_t * dataP) |
terencez | 0:c2dff8cbb91a | 815 | { |
terencez | 0:c2dff8cbb91a | 816 | lwm2m_object_t * targetP; |
terencez | 0:c2dff8cbb91a | 817 | |
terencez | 0:c2dff8cbb91a | 818 | LOG_URI(uriP); |
terencez | 0:c2dff8cbb91a | 819 | targetP = (lwm2m_object_t *)LWM2M_LIST_FIND(contextP->objectList, uriP->objectId); |
terencez | 0:c2dff8cbb91a | 820 | if (NULL == targetP) return COAP_404_NOT_FOUND; |
terencez | 0:c2dff8cbb91a | 821 | |
terencez | 0:c2dff8cbb91a | 822 | if (NULL == targetP->writeFunc) |
terencez | 0:c2dff8cbb91a | 823 | { |
terencez | 0:c2dff8cbb91a | 824 | return COAP_405_METHOD_NOT_ALLOWED; |
terencez | 0:c2dff8cbb91a | 825 | } |
terencez | 0:c2dff8cbb91a | 826 | |
terencez | 0:c2dff8cbb91a | 827 | return targetP->writeFunc(dataP->id, dataP->value.asChildren.count, dataP->value.asChildren.array, targetP); |
terencez | 0:c2dff8cbb91a | 828 | } |
terencez | 0:c2dff8cbb91a | 829 | |
terencez | 0:c2dff8cbb91a | 830 | #endif |