pick up wakaama files from https://github.com/eclipse/wakaama
core/management.c@0:1fa43ab66921, 2017-04-19 (annotated)
- Committer:
- terencez
- Date:
- Wed Apr 19 11:30:02 2017 +0000
- Revision:
- 0:1fa43ab66921
Initial commit
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
terencez | 0:1fa43ab66921 | 1 | /******************************************************************************* |
terencez | 0:1fa43ab66921 | 2 | * |
terencez | 0:1fa43ab66921 | 3 | * Copyright (c) 2013, 2014 Intel Corporation and others. |
terencez | 0:1fa43ab66921 | 4 | * All rights reserved. This program and the accompanying materials |
terencez | 0:1fa43ab66921 | 5 | * are made available under the terms of the Eclipse Public License v1.0 |
terencez | 0:1fa43ab66921 | 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. |
terencez | 0:1fa43ab66921 | 7 | * |
terencez | 0:1fa43ab66921 | 8 | * The Eclipse Public License is available at |
terencez | 0:1fa43ab66921 | 9 | * http://www.eclipse.org/legal/epl-v10.html |
terencez | 0:1fa43ab66921 | 10 | * The Eclipse Distribution License is available at |
terencez | 0:1fa43ab66921 | 11 | * http://www.eclipse.org/org/documents/edl-v10.php. |
terencez | 0:1fa43ab66921 | 12 | * |
terencez | 0:1fa43ab66921 | 13 | * Contributors: |
terencez | 0:1fa43ab66921 | 14 | * David Navarro, Intel Corporation - initial API and implementation |
terencez | 0:1fa43ab66921 | 15 | * domedambrosio - Please refer to git log |
terencez | 0:1fa43ab66921 | 16 | * Toby Jaffey - Please refer to git log |
terencez | 0:1fa43ab66921 | 17 | * Bosch Software Innovations GmbH - Please refer to git log |
terencez | 0:1fa43ab66921 | 18 | * Pascal Rieux - Please refer to git log |
terencez | 0:1fa43ab66921 | 19 | * |
terencez | 0:1fa43ab66921 | 20 | *******************************************************************************/ |
terencez | 0:1fa43ab66921 | 21 | /* |
terencez | 0:1fa43ab66921 | 22 | Copyright (c) 2013, 2014 Intel Corporation |
terencez | 0:1fa43ab66921 | 23 | |
terencez | 0:1fa43ab66921 | 24 | Redistribution and use in source and binary forms, with or without modification, |
terencez | 0:1fa43ab66921 | 25 | are permitted provided that the following conditions are met: |
terencez | 0:1fa43ab66921 | 26 | |
terencez | 0:1fa43ab66921 | 27 | * Redistributions of source code must retain the above copyright notice, |
terencez | 0:1fa43ab66921 | 28 | this list of conditions and the following disclaimer. |
terencez | 0:1fa43ab66921 | 29 | * Redistributions in binary form must reproduce the above copyright notice, |
terencez | 0:1fa43ab66921 | 30 | this list of conditions and the following disclaimer in the documentation |
terencez | 0:1fa43ab66921 | 31 | and/or other materials provided with the distribution. |
terencez | 0:1fa43ab66921 | 32 | * Neither the name of Intel Corporation nor the names of its contributors |
terencez | 0:1fa43ab66921 | 33 | may be used to endorse or promote products derived from this software |
terencez | 0:1fa43ab66921 | 34 | without specific prior written permission. |
terencez | 0:1fa43ab66921 | 35 | |
terencez | 0:1fa43ab66921 | 36 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
terencez | 0:1fa43ab66921 | 37 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
terencez | 0:1fa43ab66921 | 38 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
terencez | 0:1fa43ab66921 | 39 | IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, |
terencez | 0:1fa43ab66921 | 40 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
terencez | 0:1fa43ab66921 | 41 | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
terencez | 0:1fa43ab66921 | 42 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
terencez | 0:1fa43ab66921 | 43 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR |
terencez | 0:1fa43ab66921 | 44 | OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
terencez | 0:1fa43ab66921 | 45 | THE POSSIBILITY OF SUCH DAMAGE. |
terencez | 0:1fa43ab66921 | 46 | |
terencez | 0:1fa43ab66921 | 47 | David Navarro <david.navarro@intel.com> |
terencez | 0:1fa43ab66921 | 48 | |
terencez | 0:1fa43ab66921 | 49 | */ |
terencez | 0:1fa43ab66921 | 50 | |
terencez | 0:1fa43ab66921 | 51 | #include "internals.h" |
terencez | 0:1fa43ab66921 | 52 | #include <stdio.h> |
terencez | 0:1fa43ab66921 | 53 | |
terencez | 0:1fa43ab66921 | 54 | |
terencez | 0:1fa43ab66921 | 55 | #ifdef LWM2M_CLIENT_MODE |
terencez | 0:1fa43ab66921 | 56 | static int prv_readAttributes(multi_option_t * query, |
terencez | 0:1fa43ab66921 | 57 | lwm2m_attributes_t * attrP) |
terencez | 0:1fa43ab66921 | 58 | { |
terencez | 0:1fa43ab66921 | 59 | int64_t intValue; |
terencez | 0:1fa43ab66921 | 60 | double floatValue; |
terencez | 0:1fa43ab66921 | 61 | |
terencez | 0:1fa43ab66921 | 62 | memset(attrP, 0, sizeof(lwm2m_attributes_t)); |
terencez | 0:1fa43ab66921 | 63 | |
terencez | 0:1fa43ab66921 | 64 | while (query != NULL) |
terencez | 0:1fa43ab66921 | 65 | { |
terencez | 0:1fa43ab66921 | 66 | if (lwm2m_strncmp((char *)query->data, ATTR_MIN_PERIOD_STR, ATTR_MIN_PERIOD_LEN) == 0) |
terencez | 0:1fa43ab66921 | 67 | { |
terencez | 0:1fa43ab66921 | 68 | if (0 != ((attrP->toSet | attrP->toClear) & LWM2M_ATTR_FLAG_MIN_PERIOD)) return -1; |
terencez | 0:1fa43ab66921 | 69 | if (query->len == ATTR_MIN_PERIOD_LEN) return -1; |
terencez | 0:1fa43ab66921 | 70 | |
terencez | 0:1fa43ab66921 | 71 | if (1 != utils_plainTextToInt64(query->data + ATTR_MIN_PERIOD_LEN, query->len - ATTR_MIN_PERIOD_LEN, &intValue)) return -1; |
terencez | 0:1fa43ab66921 | 72 | if (intValue < 0) return -1; |
terencez | 0:1fa43ab66921 | 73 | |
terencez | 0:1fa43ab66921 | 74 | attrP->toSet |= LWM2M_ATTR_FLAG_MIN_PERIOD; |
terencez | 0:1fa43ab66921 | 75 | attrP->minPeriod = intValue; |
terencez | 0:1fa43ab66921 | 76 | } |
terencez | 0:1fa43ab66921 | 77 | else if (lwm2m_strncmp((char *)query->data, ATTR_MIN_PERIOD_STR, ATTR_MIN_PERIOD_LEN - 1) == 0) |
terencez | 0:1fa43ab66921 | 78 | { |
terencez | 0:1fa43ab66921 | 79 | if (0 != ((attrP->toSet | attrP->toClear) & LWM2M_ATTR_FLAG_MIN_PERIOD)) return -1; |
terencez | 0:1fa43ab66921 | 80 | if (query->len != ATTR_MIN_PERIOD_LEN - 1) return -1; |
terencez | 0:1fa43ab66921 | 81 | |
terencez | 0:1fa43ab66921 | 82 | attrP->toClear |= LWM2M_ATTR_FLAG_MIN_PERIOD; |
terencez | 0:1fa43ab66921 | 83 | } |
terencez | 0:1fa43ab66921 | 84 | else if (lwm2m_strncmp((char *)query->data, ATTR_MAX_PERIOD_STR, ATTR_MAX_PERIOD_LEN) == 0) |
terencez | 0:1fa43ab66921 | 85 | { |
terencez | 0:1fa43ab66921 | 86 | if (0 != ((attrP->toSet | attrP->toClear) & LWM2M_ATTR_FLAG_MAX_PERIOD)) return -1; |
terencez | 0:1fa43ab66921 | 87 | if (query->len == ATTR_MAX_PERIOD_LEN) return -1; |
terencez | 0:1fa43ab66921 | 88 | |
terencez | 0:1fa43ab66921 | 89 | if (1 != utils_plainTextToInt64(query->data + ATTR_MAX_PERIOD_LEN, query->len - ATTR_MAX_PERIOD_LEN, &intValue)) return -1; |
terencez | 0:1fa43ab66921 | 90 | if (intValue < 0) return -1; |
terencez | 0:1fa43ab66921 | 91 | |
terencez | 0:1fa43ab66921 | 92 | attrP->toSet |= LWM2M_ATTR_FLAG_MAX_PERIOD; |
terencez | 0:1fa43ab66921 | 93 | attrP->maxPeriod = intValue; |
terencez | 0:1fa43ab66921 | 94 | } |
terencez | 0:1fa43ab66921 | 95 | else if (lwm2m_strncmp((char *)query->data, ATTR_MAX_PERIOD_STR, ATTR_MAX_PERIOD_LEN - 1) == 0) |
terencez | 0:1fa43ab66921 | 96 | { |
terencez | 0:1fa43ab66921 | 97 | if (0 != ((attrP->toSet | attrP->toClear) & LWM2M_ATTR_FLAG_MAX_PERIOD)) return -1; |
terencez | 0:1fa43ab66921 | 98 | if (query->len != ATTR_MAX_PERIOD_LEN - 1) return -1; |
terencez | 0:1fa43ab66921 | 99 | |
terencez | 0:1fa43ab66921 | 100 | attrP->toClear |= LWM2M_ATTR_FLAG_MAX_PERIOD; |
terencez | 0:1fa43ab66921 | 101 | } |
terencez | 0:1fa43ab66921 | 102 | else if (lwm2m_strncmp((char *)query->data, ATTR_GREATER_THAN_STR, ATTR_GREATER_THAN_LEN) == 0) |
terencez | 0:1fa43ab66921 | 103 | { |
terencez | 0:1fa43ab66921 | 104 | if (0 != ((attrP->toSet | attrP->toClear) & LWM2M_ATTR_FLAG_GREATER_THAN)) return -1; |
terencez | 0:1fa43ab66921 | 105 | if (query->len == ATTR_GREATER_THAN_LEN) return -1; |
terencez | 0:1fa43ab66921 | 106 | |
terencez | 0:1fa43ab66921 | 107 | if (1 != utils_plainTextToFloat64(query->data + ATTR_GREATER_THAN_LEN, query->len - ATTR_GREATER_THAN_LEN, &floatValue)) return -1; |
terencez | 0:1fa43ab66921 | 108 | |
terencez | 0:1fa43ab66921 | 109 | attrP->toSet |= LWM2M_ATTR_FLAG_GREATER_THAN; |
terencez | 0:1fa43ab66921 | 110 | attrP->greaterThan = floatValue; |
terencez | 0:1fa43ab66921 | 111 | } |
terencez | 0:1fa43ab66921 | 112 | else if (lwm2m_strncmp((char *)query->data, ATTR_GREATER_THAN_STR, ATTR_GREATER_THAN_LEN - 1) == 0) |
terencez | 0:1fa43ab66921 | 113 | { |
terencez | 0:1fa43ab66921 | 114 | if (0 != ((attrP->toSet | attrP->toClear) & LWM2M_ATTR_FLAG_GREATER_THAN)) return -1; |
terencez | 0:1fa43ab66921 | 115 | if (query->len != ATTR_GREATER_THAN_LEN - 1) return -1; |
terencez | 0:1fa43ab66921 | 116 | |
terencez | 0:1fa43ab66921 | 117 | attrP->toClear |= LWM2M_ATTR_FLAG_GREATER_THAN; |
terencez | 0:1fa43ab66921 | 118 | } |
terencez | 0:1fa43ab66921 | 119 | else if (lwm2m_strncmp((char *)query->data, ATTR_LESS_THAN_STR, ATTR_LESS_THAN_LEN) == 0) |
terencez | 0:1fa43ab66921 | 120 | { |
terencez | 0:1fa43ab66921 | 121 | if (0 != ((attrP->toSet | attrP->toClear) & LWM2M_ATTR_FLAG_LESS_THAN)) return -1; |
terencez | 0:1fa43ab66921 | 122 | if (query->len == ATTR_LESS_THAN_LEN) return -1; |
terencez | 0:1fa43ab66921 | 123 | |
terencez | 0:1fa43ab66921 | 124 | if (1 != utils_plainTextToFloat64(query->data + ATTR_LESS_THAN_LEN, query->len - ATTR_LESS_THAN_LEN, &floatValue)) return -1; |
terencez | 0:1fa43ab66921 | 125 | |
terencez | 0:1fa43ab66921 | 126 | attrP->toSet |= LWM2M_ATTR_FLAG_LESS_THAN; |
terencez | 0:1fa43ab66921 | 127 | attrP->lessThan = floatValue; |
terencez | 0:1fa43ab66921 | 128 | } |
terencez | 0:1fa43ab66921 | 129 | else if (lwm2m_strncmp((char *)query->data, ATTR_LESS_THAN_STR, ATTR_LESS_THAN_LEN - 1) == 0) |
terencez | 0:1fa43ab66921 | 130 | { |
terencez | 0:1fa43ab66921 | 131 | if (0 != ((attrP->toSet | attrP->toClear) & LWM2M_ATTR_FLAG_LESS_THAN)) return -1; |
terencez | 0:1fa43ab66921 | 132 | if (query->len != ATTR_LESS_THAN_LEN - 1) return -1; |
terencez | 0:1fa43ab66921 | 133 | |
terencez | 0:1fa43ab66921 | 134 | attrP->toClear |= LWM2M_ATTR_FLAG_LESS_THAN; |
terencez | 0:1fa43ab66921 | 135 | } |
terencez | 0:1fa43ab66921 | 136 | else if (lwm2m_strncmp((char *)query->data, ATTR_STEP_STR, ATTR_STEP_LEN) == 0) |
terencez | 0:1fa43ab66921 | 137 | { |
terencez | 0:1fa43ab66921 | 138 | if (0 != ((attrP->toSet | attrP->toClear) & LWM2M_ATTR_FLAG_STEP)) return -1; |
terencez | 0:1fa43ab66921 | 139 | if (query->len == ATTR_STEP_LEN) return -1; |
terencez | 0:1fa43ab66921 | 140 | |
terencez | 0:1fa43ab66921 | 141 | if (1 != utils_plainTextToFloat64(query->data + ATTR_STEP_LEN, query->len - ATTR_STEP_LEN, &floatValue)) return -1; |
terencez | 0:1fa43ab66921 | 142 | if (floatValue < 0) return -1; |
terencez | 0:1fa43ab66921 | 143 | |
terencez | 0:1fa43ab66921 | 144 | attrP->toSet |= LWM2M_ATTR_FLAG_STEP; |
terencez | 0:1fa43ab66921 | 145 | attrP->step = floatValue; |
terencez | 0:1fa43ab66921 | 146 | } |
terencez | 0:1fa43ab66921 | 147 | else if (lwm2m_strncmp((char *)query->data, ATTR_STEP_STR, ATTR_STEP_LEN - 1) == 0) |
terencez | 0:1fa43ab66921 | 148 | { |
terencez | 0:1fa43ab66921 | 149 | if (0 != ((attrP->toSet | attrP->toClear) & LWM2M_ATTR_FLAG_STEP)) return -1; |
terencez | 0:1fa43ab66921 | 150 | if (query->len != ATTR_STEP_LEN - 1) return -1; |
terencez | 0:1fa43ab66921 | 151 | |
terencez | 0:1fa43ab66921 | 152 | attrP->toClear |= LWM2M_ATTR_FLAG_STEP; |
terencez | 0:1fa43ab66921 | 153 | } |
terencez | 0:1fa43ab66921 | 154 | else return -1; |
terencez | 0:1fa43ab66921 | 155 | |
terencez | 0:1fa43ab66921 | 156 | query = query->next; |
terencez | 0:1fa43ab66921 | 157 | } |
terencez | 0:1fa43ab66921 | 158 | |
terencez | 0:1fa43ab66921 | 159 | return 0; |
terencez | 0:1fa43ab66921 | 160 | } |
terencez | 0:1fa43ab66921 | 161 | |
terencez | 0:1fa43ab66921 | 162 | coap_status_t dm_handleRequest(lwm2m_context_t * contextP, |
terencez | 0:1fa43ab66921 | 163 | lwm2m_uri_t * uriP, |
terencez | 0:1fa43ab66921 | 164 | lwm2m_server_t * serverP, |
terencez | 0:1fa43ab66921 | 165 | coap_packet_t * message, |
terencez | 0:1fa43ab66921 | 166 | coap_packet_t * response) |
terencez | 0:1fa43ab66921 | 167 | { |
terencez | 0:1fa43ab66921 | 168 | coap_status_t result; |
terencez | 0:1fa43ab66921 | 169 | lwm2m_media_type_t format; |
terencez | 0:1fa43ab66921 | 170 | |
terencez | 0:1fa43ab66921 | 171 | LOG_ARG("Code: %02X, server status: %s", message->code, STR_STATUS(serverP->status)); |
terencez | 0:1fa43ab66921 | 172 | LOG_URI(uriP); |
terencez | 0:1fa43ab66921 | 173 | |
terencez | 0:1fa43ab66921 | 174 | if (IS_OPTION(message, COAP_OPTION_CONTENT_TYPE)) |
terencez | 0:1fa43ab66921 | 175 | { |
terencez | 0:1fa43ab66921 | 176 | format = utils_convertMediaType(message->content_type); |
terencez | 0:1fa43ab66921 | 177 | } |
terencez | 0:1fa43ab66921 | 178 | else |
terencez | 0:1fa43ab66921 | 179 | { |
terencez | 0:1fa43ab66921 | 180 | format = LWM2M_CONTENT_TLV; |
terencez | 0:1fa43ab66921 | 181 | } |
terencez | 0:1fa43ab66921 | 182 | |
terencez | 0:1fa43ab66921 | 183 | if (uriP->objectId == LWM2M_SECURITY_OBJECT_ID) |
terencez | 0:1fa43ab66921 | 184 | { |
terencez | 0:1fa43ab66921 | 185 | return COAP_404_NOT_FOUND; |
terencez | 0:1fa43ab66921 | 186 | } |
terencez | 0:1fa43ab66921 | 187 | |
terencez | 0:1fa43ab66921 | 188 | if (serverP->status != STATE_REGISTERED |
terencez | 0:1fa43ab66921 | 189 | && serverP->status != STATE_REG_UPDATE_NEEDED |
terencez | 0:1fa43ab66921 | 190 | && serverP->status != STATE_REG_FULL_UPDATE_NEEDED |
terencez | 0:1fa43ab66921 | 191 | && serverP->status != STATE_REG_UPDATE_PENDING) |
terencez | 0:1fa43ab66921 | 192 | { |
terencez | 0:1fa43ab66921 | 193 | return COAP_IGNORE; |
terencez | 0:1fa43ab66921 | 194 | } |
terencez | 0:1fa43ab66921 | 195 | |
terencez | 0:1fa43ab66921 | 196 | // TODO: check ACL |
terencez | 0:1fa43ab66921 | 197 | |
terencez | 0:1fa43ab66921 | 198 | switch (message->code) |
terencez | 0:1fa43ab66921 | 199 | { |
terencez | 0:1fa43ab66921 | 200 | case COAP_GET: |
terencez | 0:1fa43ab66921 | 201 | { |
terencez | 0:1fa43ab66921 | 202 | uint8_t * buffer = NULL; |
terencez | 0:1fa43ab66921 | 203 | size_t length = 0; |
terencez | 0:1fa43ab66921 | 204 | int res; |
terencez | 0:1fa43ab66921 | 205 | |
terencez | 0:1fa43ab66921 | 206 | if (IS_OPTION(message, COAP_OPTION_OBSERVE)) |
terencez | 0:1fa43ab66921 | 207 | { |
terencez | 0:1fa43ab66921 | 208 | lwm2m_data_t * dataP = NULL; |
terencez | 0:1fa43ab66921 | 209 | int size = 0; |
terencez | 0:1fa43ab66921 | 210 | |
terencez | 0:1fa43ab66921 | 211 | result = object_readData(contextP, uriP, &size, &dataP); |
terencez | 0:1fa43ab66921 | 212 | if (COAP_205_CONTENT == result) |
terencez | 0:1fa43ab66921 | 213 | { |
terencez | 0:1fa43ab66921 | 214 | result = observe_handleRequest(contextP, uriP, serverP, size, dataP, message, response); |
terencez | 0:1fa43ab66921 | 215 | if (COAP_205_CONTENT == result) |
terencez | 0:1fa43ab66921 | 216 | { |
terencez | 0:1fa43ab66921 | 217 | res = lwm2m_data_serialize(uriP, size, dataP, &format, &buffer); |
terencez | 0:1fa43ab66921 | 218 | if (res < 0) |
terencez | 0:1fa43ab66921 | 219 | { |
terencez | 0:1fa43ab66921 | 220 | result = COAP_500_INTERNAL_SERVER_ERROR; |
terencez | 0:1fa43ab66921 | 221 | } |
terencez | 0:1fa43ab66921 | 222 | else |
terencez | 0:1fa43ab66921 | 223 | { |
terencez | 0:1fa43ab66921 | 224 | length = (size_t)res; |
terencez | 0:1fa43ab66921 | 225 | LOG_ARG("Observe Request[/%d/%d/%d]: %.*s\n", uriP->objectId, uriP->instanceId, uriP->resourceId, length, buffer); |
terencez | 0:1fa43ab66921 | 226 | } |
terencez | 0:1fa43ab66921 | 227 | } |
terencez | 0:1fa43ab66921 | 228 | lwm2m_data_free(size, dataP); |
terencez | 0:1fa43ab66921 | 229 | } |
terencez | 0:1fa43ab66921 | 230 | } |
terencez | 0:1fa43ab66921 | 231 | else if (IS_OPTION(message, COAP_OPTION_ACCEPT) |
terencez | 0:1fa43ab66921 | 232 | && message->accept_num == 1 |
terencez | 0:1fa43ab66921 | 233 | && message->accept[0] == APPLICATION_LINK_FORMAT) |
terencez | 0:1fa43ab66921 | 234 | { |
terencez | 0:1fa43ab66921 | 235 | format = LWM2M_CONTENT_LINK; |
terencez | 0:1fa43ab66921 | 236 | result = object_discover(contextP, uriP, serverP, &buffer, &length); |
terencez | 0:1fa43ab66921 | 237 | } |
terencez | 0:1fa43ab66921 | 238 | else |
terencez | 0:1fa43ab66921 | 239 | { |
terencez | 0:1fa43ab66921 | 240 | if (IS_OPTION(message, COAP_OPTION_ACCEPT)) |
terencez | 0:1fa43ab66921 | 241 | { |
terencez | 0:1fa43ab66921 | 242 | format = utils_convertMediaType(message->accept[0]); |
terencez | 0:1fa43ab66921 | 243 | } |
terencez | 0:1fa43ab66921 | 244 | |
terencez | 0:1fa43ab66921 | 245 | result = object_read(contextP, uriP, &format, &buffer, &length); |
terencez | 0:1fa43ab66921 | 246 | } |
terencez | 0:1fa43ab66921 | 247 | if (COAP_205_CONTENT == result) |
terencez | 0:1fa43ab66921 | 248 | { |
terencez | 0:1fa43ab66921 | 249 | coap_set_header_content_type(response, format); |
terencez | 0:1fa43ab66921 | 250 | coap_set_payload(response, buffer, length); |
terencez | 0:1fa43ab66921 | 251 | // lwm2m_handle_packet will free buffer |
terencez | 0:1fa43ab66921 | 252 | } |
terencez | 0:1fa43ab66921 | 253 | else |
terencez | 0:1fa43ab66921 | 254 | { |
terencez | 0:1fa43ab66921 | 255 | lwm2m_free(buffer); |
terencez | 0:1fa43ab66921 | 256 | } |
terencez | 0:1fa43ab66921 | 257 | } |
terencez | 0:1fa43ab66921 | 258 | break; |
terencez | 0:1fa43ab66921 | 259 | |
terencez | 0:1fa43ab66921 | 260 | case COAP_POST: |
terencez | 0:1fa43ab66921 | 261 | { |
terencez | 0:1fa43ab66921 | 262 | if (!LWM2M_URI_IS_SET_INSTANCE(uriP)) |
terencez | 0:1fa43ab66921 | 263 | { |
terencez | 0:1fa43ab66921 | 264 | result = object_create(contextP, uriP, format, message->payload, message->payload_len); |
terencez | 0:1fa43ab66921 | 265 | if (result == COAP_201_CREATED) |
terencez | 0:1fa43ab66921 | 266 | { |
terencez | 0:1fa43ab66921 | 267 | //longest uri is /65535/65535 = 12 + 1 (null) chars |
terencez | 0:1fa43ab66921 | 268 | char location_path[13] = ""; |
terencez | 0:1fa43ab66921 | 269 | //instanceId expected |
terencez | 0:1fa43ab66921 | 270 | if ((uriP->flag & LWM2M_URI_FLAG_INSTANCE_ID) == 0) |
terencez | 0:1fa43ab66921 | 271 | { |
terencez | 0:1fa43ab66921 | 272 | result = COAP_500_INTERNAL_SERVER_ERROR; |
terencez | 0:1fa43ab66921 | 273 | break; |
terencez | 0:1fa43ab66921 | 274 | } |
terencez | 0:1fa43ab66921 | 275 | |
terencez | 0:1fa43ab66921 | 276 | if (sprintf(location_path, "/%d/%d", uriP->objectId, uriP->instanceId) < 0) |
terencez | 0:1fa43ab66921 | 277 | { |
terencez | 0:1fa43ab66921 | 278 | result = COAP_500_INTERNAL_SERVER_ERROR; |
terencez | 0:1fa43ab66921 | 279 | break; |
terencez | 0:1fa43ab66921 | 280 | } |
terencez | 0:1fa43ab66921 | 281 | coap_set_header_location_path(response, location_path); |
terencez | 0:1fa43ab66921 | 282 | |
terencez | 0:1fa43ab66921 | 283 | lwm2m_update_registration(contextP, 0, true); |
terencez | 0:1fa43ab66921 | 284 | } |
terencez | 0:1fa43ab66921 | 285 | } |
terencez | 0:1fa43ab66921 | 286 | else if (!LWM2M_URI_IS_SET_RESOURCE(uriP)) |
terencez | 0:1fa43ab66921 | 287 | { |
terencez | 0:1fa43ab66921 | 288 | result = object_write(contextP, uriP, format, message->payload, message->payload_len); |
terencez | 0:1fa43ab66921 | 289 | } |
terencez | 0:1fa43ab66921 | 290 | else |
terencez | 0:1fa43ab66921 | 291 | { |
terencez | 0:1fa43ab66921 | 292 | result = object_execute(contextP, uriP, message->payload, message->payload_len); |
terencez | 0:1fa43ab66921 | 293 | } |
terencez | 0:1fa43ab66921 | 294 | } |
terencez | 0:1fa43ab66921 | 295 | break; |
terencez | 0:1fa43ab66921 | 296 | |
terencez | 0:1fa43ab66921 | 297 | case COAP_PUT: |
terencez | 0:1fa43ab66921 | 298 | { |
terencez | 0:1fa43ab66921 | 299 | if (IS_OPTION(message, COAP_OPTION_URI_QUERY)) |
terencez | 0:1fa43ab66921 | 300 | { |
terencez | 0:1fa43ab66921 | 301 | lwm2m_attributes_t attr; |
terencez | 0:1fa43ab66921 | 302 | |
terencez | 0:1fa43ab66921 | 303 | if (0 != prv_readAttributes(message->uri_query, &attr)) |
terencez | 0:1fa43ab66921 | 304 | { |
terencez | 0:1fa43ab66921 | 305 | result = COAP_400_BAD_REQUEST; |
terencez | 0:1fa43ab66921 | 306 | } |
terencez | 0:1fa43ab66921 | 307 | else |
terencez | 0:1fa43ab66921 | 308 | { |
terencez | 0:1fa43ab66921 | 309 | result = observe_setParameters(contextP, uriP, serverP, &attr); |
terencez | 0:1fa43ab66921 | 310 | } |
terencez | 0:1fa43ab66921 | 311 | } |
terencez | 0:1fa43ab66921 | 312 | else if (LWM2M_URI_IS_SET_INSTANCE(uriP)) |
terencez | 0:1fa43ab66921 | 313 | { |
terencez | 0:1fa43ab66921 | 314 | result = object_write(contextP, uriP, format, message->payload, message->payload_len); |
terencez | 0:1fa43ab66921 | 315 | } |
terencez | 0:1fa43ab66921 | 316 | else |
terencez | 0:1fa43ab66921 | 317 | { |
terencez | 0:1fa43ab66921 | 318 | result = COAP_400_BAD_REQUEST; |
terencez | 0:1fa43ab66921 | 319 | } |
terencez | 0:1fa43ab66921 | 320 | } |
terencez | 0:1fa43ab66921 | 321 | break; |
terencez | 0:1fa43ab66921 | 322 | |
terencez | 0:1fa43ab66921 | 323 | case COAP_DELETE: |
terencez | 0:1fa43ab66921 | 324 | { |
terencez | 0:1fa43ab66921 | 325 | if (!LWM2M_URI_IS_SET_INSTANCE(uriP) || LWM2M_URI_IS_SET_RESOURCE(uriP)) |
terencez | 0:1fa43ab66921 | 326 | { |
terencez | 0:1fa43ab66921 | 327 | result = COAP_400_BAD_REQUEST; |
terencez | 0:1fa43ab66921 | 328 | } |
terencez | 0:1fa43ab66921 | 329 | else |
terencez | 0:1fa43ab66921 | 330 | { |
terencez | 0:1fa43ab66921 | 331 | result = object_delete(contextP, uriP); |
terencez | 0:1fa43ab66921 | 332 | if (result == COAP_202_DELETED) |
terencez | 0:1fa43ab66921 | 333 | { |
terencez | 0:1fa43ab66921 | 334 | lwm2m_update_registration(contextP, 0, true); |
terencez | 0:1fa43ab66921 | 335 | } |
terencez | 0:1fa43ab66921 | 336 | } |
terencez | 0:1fa43ab66921 | 337 | } |
terencez | 0:1fa43ab66921 | 338 | break; |
terencez | 0:1fa43ab66921 | 339 | |
terencez | 0:1fa43ab66921 | 340 | default: |
terencez | 0:1fa43ab66921 | 341 | result = COAP_400_BAD_REQUEST; |
terencez | 0:1fa43ab66921 | 342 | break; |
terencez | 0:1fa43ab66921 | 343 | } |
terencez | 0:1fa43ab66921 | 344 | |
terencez | 0:1fa43ab66921 | 345 | return result; |
terencez | 0:1fa43ab66921 | 346 | } |
terencez | 0:1fa43ab66921 | 347 | |
terencez | 0:1fa43ab66921 | 348 | #endif |
terencez | 0:1fa43ab66921 | 349 | |
terencez | 0:1fa43ab66921 | 350 | #ifdef LWM2M_SERVER_MODE |
terencez | 0:1fa43ab66921 | 351 | |
terencez | 0:1fa43ab66921 | 352 | #define ID_AS_STRING_MAX_LEN 8 |
terencez | 0:1fa43ab66921 | 353 | |
terencez | 0:1fa43ab66921 | 354 | static void prv_resultCallback(lwm2m_transaction_t * transacP, |
terencez | 0:1fa43ab66921 | 355 | void * message) |
terencez | 0:1fa43ab66921 | 356 | { |
terencez | 0:1fa43ab66921 | 357 | dm_data_t * dataP = (dm_data_t *)transacP->userData; |
terencez | 0:1fa43ab66921 | 358 | |
terencez | 0:1fa43ab66921 | 359 | if (message == NULL) |
terencez | 0:1fa43ab66921 | 360 | { |
terencez | 0:1fa43ab66921 | 361 | dataP->callback(dataP->clientID, |
terencez | 0:1fa43ab66921 | 362 | &dataP->uri, |
terencez | 0:1fa43ab66921 | 363 | COAP_503_SERVICE_UNAVAILABLE, |
terencez | 0:1fa43ab66921 | 364 | LWM2M_CONTENT_TEXT, NULL, 0, |
terencez | 0:1fa43ab66921 | 365 | dataP->userData); |
terencez | 0:1fa43ab66921 | 366 | } |
terencez | 0:1fa43ab66921 | 367 | else |
terencez | 0:1fa43ab66921 | 368 | { |
terencez | 0:1fa43ab66921 | 369 | coap_packet_t * packet = (coap_packet_t *)message; |
terencez | 0:1fa43ab66921 | 370 | |
terencez | 0:1fa43ab66921 | 371 | //if packet is a CREATE response and the instanceId was assigned by the client |
terencez | 0:1fa43ab66921 | 372 | if (packet->code == COAP_201_CREATED |
terencez | 0:1fa43ab66921 | 373 | && packet->location_path != NULL) |
terencez | 0:1fa43ab66921 | 374 | { |
terencez | 0:1fa43ab66921 | 375 | char * locationString = NULL; |
terencez | 0:1fa43ab66921 | 376 | int result = 0; |
terencez | 0:1fa43ab66921 | 377 | lwm2m_uri_t locationUri; |
terencez | 0:1fa43ab66921 | 378 | |
terencez | 0:1fa43ab66921 | 379 | locationString = coap_get_multi_option_as_string(packet->location_path); |
terencez | 0:1fa43ab66921 | 380 | if (locationString == NULL) |
terencez | 0:1fa43ab66921 | 381 | { |
terencez | 0:1fa43ab66921 | 382 | LOG("Error: coap_get_multi_option_as_string() failed for Location_path option in prv_resultCallback()"); |
terencez | 0:1fa43ab66921 | 383 | return; |
terencez | 0:1fa43ab66921 | 384 | } |
terencez | 0:1fa43ab66921 | 385 | |
terencez | 0:1fa43ab66921 | 386 | result = lwm2m_stringToUri(locationString, strlen(locationString), &locationUri); |
terencez | 0:1fa43ab66921 | 387 | if (result == 0) |
terencez | 0:1fa43ab66921 | 388 | { |
terencez | 0:1fa43ab66921 | 389 | LOG("Error: lwm2m_stringToUri() failed for Location_path option in prv_resultCallback()"); |
terencez | 0:1fa43ab66921 | 390 | lwm2m_free(locationString); |
terencez | 0:1fa43ab66921 | 391 | return; |
terencez | 0:1fa43ab66921 | 392 | } |
terencez | 0:1fa43ab66921 | 393 | |
terencez | 0:1fa43ab66921 | 394 | ((dm_data_t*)transacP->userData)->uri.instanceId = locationUri.instanceId; |
terencez | 0:1fa43ab66921 | 395 | ((dm_data_t*)transacP->userData)->uri.flag = locationUri.flag; |
terencez | 0:1fa43ab66921 | 396 | |
terencez | 0:1fa43ab66921 | 397 | lwm2m_free(locationString); |
terencez | 0:1fa43ab66921 | 398 | } |
terencez | 0:1fa43ab66921 | 399 | |
terencez | 0:1fa43ab66921 | 400 | dataP->callback(dataP->clientID, |
terencez | 0:1fa43ab66921 | 401 | &dataP->uri, |
terencez | 0:1fa43ab66921 | 402 | packet->code, |
terencez | 0:1fa43ab66921 | 403 | utils_convertMediaType(packet->content_type), |
terencez | 0:1fa43ab66921 | 404 | packet->payload, |
terencez | 0:1fa43ab66921 | 405 | packet->payload_len, |
terencez | 0:1fa43ab66921 | 406 | dataP->userData); |
terencez | 0:1fa43ab66921 | 407 | } |
terencez | 0:1fa43ab66921 | 408 | lwm2m_free(dataP); |
terencez | 0:1fa43ab66921 | 409 | } |
terencez | 0:1fa43ab66921 | 410 | |
terencez | 0:1fa43ab66921 | 411 | static int prv_makeOperation(lwm2m_context_t * contextP, |
terencez | 0:1fa43ab66921 | 412 | uint16_t clientID, |
terencez | 0:1fa43ab66921 | 413 | lwm2m_uri_t * uriP, |
terencez | 0:1fa43ab66921 | 414 | coap_method_t method, |
terencez | 0:1fa43ab66921 | 415 | lwm2m_media_type_t format, |
terencez | 0:1fa43ab66921 | 416 | uint8_t * buffer, |
terencez | 0:1fa43ab66921 | 417 | int length, |
terencez | 0:1fa43ab66921 | 418 | lwm2m_result_callback_t callback, |
terencez | 0:1fa43ab66921 | 419 | void * userData) |
terencez | 0:1fa43ab66921 | 420 | { |
terencez | 0:1fa43ab66921 | 421 | lwm2m_client_t * clientP; |
terencez | 0:1fa43ab66921 | 422 | lwm2m_transaction_t * transaction; |
terencez | 0:1fa43ab66921 | 423 | dm_data_t * dataP; |
terencez | 0:1fa43ab66921 | 424 | |
terencez | 0:1fa43ab66921 | 425 | clientP = (lwm2m_client_t *)lwm2m_list_find((lwm2m_list_t *)contextP->clientList, clientID); |
terencez | 0:1fa43ab66921 | 426 | if (clientP == NULL) return COAP_404_NOT_FOUND; |
terencez | 0:1fa43ab66921 | 427 | |
terencez | 0:1fa43ab66921 | 428 | transaction = transaction_new(clientP->sessionH, method, clientP->altPath, uriP, contextP->nextMID++, 4, NULL); |
terencez | 0:1fa43ab66921 | 429 | if (transaction == NULL) return COAP_500_INTERNAL_SERVER_ERROR; |
terencez | 0:1fa43ab66921 | 430 | |
terencez | 0:1fa43ab66921 | 431 | if (method == COAP_GET) |
terencez | 0:1fa43ab66921 | 432 | { |
terencez | 0:1fa43ab66921 | 433 | coap_set_header_accept(transaction->message, format); |
terencez | 0:1fa43ab66921 | 434 | } |
terencez | 0:1fa43ab66921 | 435 | else if (buffer != NULL) |
terencez | 0:1fa43ab66921 | 436 | { |
terencez | 0:1fa43ab66921 | 437 | coap_set_header_content_type(transaction->message, format); |
terencez | 0:1fa43ab66921 | 438 | // TODO: Take care of fragmentation |
terencez | 0:1fa43ab66921 | 439 | coap_set_payload(transaction->message, buffer, length); |
terencez | 0:1fa43ab66921 | 440 | } |
terencez | 0:1fa43ab66921 | 441 | |
terencez | 0:1fa43ab66921 | 442 | if (callback != NULL) |
terencez | 0:1fa43ab66921 | 443 | { |
terencez | 0:1fa43ab66921 | 444 | dataP = (dm_data_t *)lwm2m_malloc(sizeof(dm_data_t)); |
terencez | 0:1fa43ab66921 | 445 | if (dataP == NULL) |
terencez | 0:1fa43ab66921 | 446 | { |
terencez | 0:1fa43ab66921 | 447 | transaction_free(transaction); |
terencez | 0:1fa43ab66921 | 448 | return COAP_500_INTERNAL_SERVER_ERROR; |
terencez | 0:1fa43ab66921 | 449 | } |
terencez | 0:1fa43ab66921 | 450 | memcpy(&dataP->uri, uriP, sizeof(lwm2m_uri_t)); |
terencez | 0:1fa43ab66921 | 451 | dataP->clientID = clientP->internalID; |
terencez | 0:1fa43ab66921 | 452 | dataP->callback = callback; |
terencez | 0:1fa43ab66921 | 453 | dataP->userData = userData; |
terencez | 0:1fa43ab66921 | 454 | |
terencez | 0:1fa43ab66921 | 455 | transaction->callback = prv_resultCallback; |
terencez | 0:1fa43ab66921 | 456 | transaction->userData = (void *)dataP; |
terencez | 0:1fa43ab66921 | 457 | } |
terencez | 0:1fa43ab66921 | 458 | |
terencez | 0:1fa43ab66921 | 459 | contextP->transactionList = (lwm2m_transaction_t *)LWM2M_LIST_ADD(contextP->transactionList, transaction); |
terencez | 0:1fa43ab66921 | 460 | |
terencez | 0:1fa43ab66921 | 461 | return transaction_send(contextP, transaction); |
terencez | 0:1fa43ab66921 | 462 | } |
terencez | 0:1fa43ab66921 | 463 | |
terencez | 0:1fa43ab66921 | 464 | int lwm2m_dm_read(lwm2m_context_t * contextP, |
terencez | 0:1fa43ab66921 | 465 | uint16_t clientID, |
terencez | 0:1fa43ab66921 | 466 | lwm2m_uri_t * uriP, |
terencez | 0:1fa43ab66921 | 467 | lwm2m_result_callback_t callback, |
terencez | 0:1fa43ab66921 | 468 | void * userData) |
terencez | 0:1fa43ab66921 | 469 | { |
terencez | 0:1fa43ab66921 | 470 | lwm2m_client_t * clientP; |
terencez | 0:1fa43ab66921 | 471 | lwm2m_media_type_t format; |
terencez | 0:1fa43ab66921 | 472 | |
terencez | 0:1fa43ab66921 | 473 | LOG_ARG("clientID: %d", clientID); |
terencez | 0:1fa43ab66921 | 474 | LOG_URI(uriP); |
terencez | 0:1fa43ab66921 | 475 | |
terencez | 0:1fa43ab66921 | 476 | clientP = (lwm2m_client_t *)lwm2m_list_find((lwm2m_list_t *)contextP->clientList, clientID); |
terencez | 0:1fa43ab66921 | 477 | if (clientP == NULL) return COAP_404_NOT_FOUND; |
terencez | 0:1fa43ab66921 | 478 | |
terencez | 0:1fa43ab66921 | 479 | if (clientP->supportJSON == true) |
terencez | 0:1fa43ab66921 | 480 | { |
terencez | 0:1fa43ab66921 | 481 | format = LWM2M_CONTENT_JSON; |
terencez | 0:1fa43ab66921 | 482 | } |
terencez | 0:1fa43ab66921 | 483 | else |
terencez | 0:1fa43ab66921 | 484 | { |
terencez | 0:1fa43ab66921 | 485 | format = LWM2M_CONTENT_TLV; |
terencez | 0:1fa43ab66921 | 486 | } |
terencez | 0:1fa43ab66921 | 487 | |
terencez | 0:1fa43ab66921 | 488 | return prv_makeOperation(contextP, clientID, uriP, |
terencez | 0:1fa43ab66921 | 489 | COAP_GET, |
terencez | 0:1fa43ab66921 | 490 | format, |
terencez | 0:1fa43ab66921 | 491 | NULL, 0, |
terencez | 0:1fa43ab66921 | 492 | callback, userData); |
terencez | 0:1fa43ab66921 | 493 | } |
terencez | 0:1fa43ab66921 | 494 | |
terencez | 0:1fa43ab66921 | 495 | int lwm2m_dm_write(lwm2m_context_t * contextP, |
terencez | 0:1fa43ab66921 | 496 | uint16_t clientID, |
terencez | 0:1fa43ab66921 | 497 | lwm2m_uri_t * uriP, |
terencez | 0:1fa43ab66921 | 498 | lwm2m_media_type_t format, |
terencez | 0:1fa43ab66921 | 499 | uint8_t * buffer, |
terencez | 0:1fa43ab66921 | 500 | int length, |
terencez | 0:1fa43ab66921 | 501 | lwm2m_result_callback_t callback, |
terencez | 0:1fa43ab66921 | 502 | void * userData) |
terencez | 0:1fa43ab66921 | 503 | { |
terencez | 0:1fa43ab66921 | 504 | LOG_ARG("clientID: %d, format: %s, length: %d", clientID, STR_MEDIA_TYPE(format), length); |
terencez | 0:1fa43ab66921 | 505 | LOG_URI(uriP); |
terencez | 0:1fa43ab66921 | 506 | if (!LWM2M_URI_IS_SET_INSTANCE(uriP) |
terencez | 0:1fa43ab66921 | 507 | || length == 0) |
terencez | 0:1fa43ab66921 | 508 | { |
terencez | 0:1fa43ab66921 | 509 | return COAP_400_BAD_REQUEST; |
terencez | 0:1fa43ab66921 | 510 | } |
terencez | 0:1fa43ab66921 | 511 | |
terencez | 0:1fa43ab66921 | 512 | if (LWM2M_URI_IS_SET_RESOURCE(uriP)) |
terencez | 0:1fa43ab66921 | 513 | { |
terencez | 0:1fa43ab66921 | 514 | return prv_makeOperation(contextP, clientID, uriP, |
terencez | 0:1fa43ab66921 | 515 | COAP_PUT, |
terencez | 0:1fa43ab66921 | 516 | format, buffer, length, |
terencez | 0:1fa43ab66921 | 517 | callback, userData); |
terencez | 0:1fa43ab66921 | 518 | } |
terencez | 0:1fa43ab66921 | 519 | else |
terencez | 0:1fa43ab66921 | 520 | { |
terencez | 0:1fa43ab66921 | 521 | return prv_makeOperation(contextP, clientID, uriP, |
terencez | 0:1fa43ab66921 | 522 | COAP_POST, |
terencez | 0:1fa43ab66921 | 523 | format, buffer, length, |
terencez | 0:1fa43ab66921 | 524 | callback, userData); |
terencez | 0:1fa43ab66921 | 525 | } |
terencez | 0:1fa43ab66921 | 526 | } |
terencez | 0:1fa43ab66921 | 527 | |
terencez | 0:1fa43ab66921 | 528 | int lwm2m_dm_execute(lwm2m_context_t * contextP, |
terencez | 0:1fa43ab66921 | 529 | uint16_t clientID, |
terencez | 0:1fa43ab66921 | 530 | lwm2m_uri_t * uriP, |
terencez | 0:1fa43ab66921 | 531 | lwm2m_media_type_t format, |
terencez | 0:1fa43ab66921 | 532 | uint8_t * buffer, |
terencez | 0:1fa43ab66921 | 533 | int length, |
terencez | 0:1fa43ab66921 | 534 | lwm2m_result_callback_t callback, |
terencez | 0:1fa43ab66921 | 535 | void * userData) |
terencez | 0:1fa43ab66921 | 536 | { |
terencez | 0:1fa43ab66921 | 537 | LOG_ARG("clientID: %d, format: %s, length: %d", clientID, STR_MEDIA_TYPE(format), length); |
terencez | 0:1fa43ab66921 | 538 | LOG_URI(uriP); |
terencez | 0:1fa43ab66921 | 539 | if (!LWM2M_URI_IS_SET_RESOURCE(uriP)) |
terencez | 0:1fa43ab66921 | 540 | { |
terencez | 0:1fa43ab66921 | 541 | return COAP_400_BAD_REQUEST; |
terencez | 0:1fa43ab66921 | 542 | } |
terencez | 0:1fa43ab66921 | 543 | |
terencez | 0:1fa43ab66921 | 544 | return prv_makeOperation(contextP, clientID, uriP, |
terencez | 0:1fa43ab66921 | 545 | COAP_POST, |
terencez | 0:1fa43ab66921 | 546 | format, buffer, length, |
terencez | 0:1fa43ab66921 | 547 | callback, userData); |
terencez | 0:1fa43ab66921 | 548 | } |
terencez | 0:1fa43ab66921 | 549 | |
terencez | 0:1fa43ab66921 | 550 | int lwm2m_dm_create(lwm2m_context_t * contextP, |
terencez | 0:1fa43ab66921 | 551 | uint16_t clientID, |
terencez | 0:1fa43ab66921 | 552 | lwm2m_uri_t * uriP, |
terencez | 0:1fa43ab66921 | 553 | lwm2m_media_type_t format, |
terencez | 0:1fa43ab66921 | 554 | uint8_t * buffer, |
terencez | 0:1fa43ab66921 | 555 | int length, |
terencez | 0:1fa43ab66921 | 556 | lwm2m_result_callback_t callback, |
terencez | 0:1fa43ab66921 | 557 | void * userData) |
terencez | 0:1fa43ab66921 | 558 | { |
terencez | 0:1fa43ab66921 | 559 | LOG_ARG("clientID: %d, format: %s, length: %d", clientID, STR_MEDIA_TYPE(format), length); |
terencez | 0:1fa43ab66921 | 560 | LOG_URI(uriP); |
terencez | 0:1fa43ab66921 | 561 | |
terencez | 0:1fa43ab66921 | 562 | if (LWM2M_URI_IS_SET_INSTANCE(uriP) |
terencez | 0:1fa43ab66921 | 563 | || length == 0) |
terencez | 0:1fa43ab66921 | 564 | { |
terencez | 0:1fa43ab66921 | 565 | return COAP_400_BAD_REQUEST; |
terencez | 0:1fa43ab66921 | 566 | } |
terencez | 0:1fa43ab66921 | 567 | |
terencez | 0:1fa43ab66921 | 568 | return prv_makeOperation(contextP, clientID, uriP, |
terencez | 0:1fa43ab66921 | 569 | COAP_POST, |
terencez | 0:1fa43ab66921 | 570 | format, buffer, length, |
terencez | 0:1fa43ab66921 | 571 | callback, userData); |
terencez | 0:1fa43ab66921 | 572 | } |
terencez | 0:1fa43ab66921 | 573 | |
terencez | 0:1fa43ab66921 | 574 | int lwm2m_dm_delete(lwm2m_context_t * contextP, |
terencez | 0:1fa43ab66921 | 575 | uint16_t clientID, |
terencez | 0:1fa43ab66921 | 576 | lwm2m_uri_t * uriP, |
terencez | 0:1fa43ab66921 | 577 | lwm2m_result_callback_t callback, |
terencez | 0:1fa43ab66921 | 578 | void * userData) |
terencez | 0:1fa43ab66921 | 579 | { |
terencez | 0:1fa43ab66921 | 580 | LOG_ARG("clientID: %d", clientID); |
terencez | 0:1fa43ab66921 | 581 | LOG_URI(uriP); |
terencez | 0:1fa43ab66921 | 582 | if (!LWM2M_URI_IS_SET_INSTANCE(uriP) |
terencez | 0:1fa43ab66921 | 583 | || LWM2M_URI_IS_SET_RESOURCE(uriP)) |
terencez | 0:1fa43ab66921 | 584 | { |
terencez | 0:1fa43ab66921 | 585 | return COAP_400_BAD_REQUEST; |
terencez | 0:1fa43ab66921 | 586 | } |
terencez | 0:1fa43ab66921 | 587 | |
terencez | 0:1fa43ab66921 | 588 | return prv_makeOperation(contextP, clientID, uriP, |
terencez | 0:1fa43ab66921 | 589 | COAP_DELETE, |
terencez | 0:1fa43ab66921 | 590 | LWM2M_CONTENT_TEXT, NULL, 0, |
terencez | 0:1fa43ab66921 | 591 | callback, userData); |
terencez | 0:1fa43ab66921 | 592 | } |
terencez | 0:1fa43ab66921 | 593 | |
terencez | 0:1fa43ab66921 | 594 | int lwm2m_dm_write_attributes(lwm2m_context_t * contextP, |
terencez | 0:1fa43ab66921 | 595 | uint16_t clientID, |
terencez | 0:1fa43ab66921 | 596 | lwm2m_uri_t * uriP, |
terencez | 0:1fa43ab66921 | 597 | lwm2m_attributes_t * attrP, |
terencez | 0:1fa43ab66921 | 598 | lwm2m_result_callback_t callback, |
terencez | 0:1fa43ab66921 | 599 | void * userData) |
terencez | 0:1fa43ab66921 | 600 | { |
terencez | 0:1fa43ab66921 | 601 | #define _PRV_BUFFER_SIZE 32 |
terencez | 0:1fa43ab66921 | 602 | lwm2m_client_t * clientP; |
terencez | 0:1fa43ab66921 | 603 | lwm2m_transaction_t * transaction; |
terencez | 0:1fa43ab66921 | 604 | coap_packet_t * coap_pkt; |
terencez | 0:1fa43ab66921 | 605 | uint8_t buffer[_PRV_BUFFER_SIZE]; |
terencez | 0:1fa43ab66921 | 606 | size_t length; |
terencez | 0:1fa43ab66921 | 607 | |
terencez | 0:1fa43ab66921 | 608 | LOG_ARG("clientID: %d", clientID); |
terencez | 0:1fa43ab66921 | 609 | LOG_URI(uriP); |
terencez | 0:1fa43ab66921 | 610 | if (attrP == NULL) return COAP_400_BAD_REQUEST; |
terencez | 0:1fa43ab66921 | 611 | |
terencez | 0:1fa43ab66921 | 612 | if (0 != (attrP->toSet & attrP->toClear)) return COAP_400_BAD_REQUEST; |
terencez | 0:1fa43ab66921 | 613 | if (0 != (attrP->toSet & ATTR_FLAG_NUMERIC) && !LWM2M_URI_IS_SET_RESOURCE(uriP)) return COAP_400_BAD_REQUEST; |
terencez | 0:1fa43ab66921 | 614 | if (ATTR_FLAG_NUMERIC == (attrP->toSet & ATTR_FLAG_NUMERIC) |
terencez | 0:1fa43ab66921 | 615 | && (attrP->lessThan + 2 * attrP->step >= attrP->greaterThan)) return COAP_400_BAD_REQUEST; |
terencez | 0:1fa43ab66921 | 616 | |
terencez | 0:1fa43ab66921 | 617 | clientP = (lwm2m_client_t *)lwm2m_list_find((lwm2m_list_t *)contextP->clientList, clientID); |
terencez | 0:1fa43ab66921 | 618 | if (clientP == NULL) return COAP_404_NOT_FOUND; |
terencez | 0:1fa43ab66921 | 619 | |
terencez | 0:1fa43ab66921 | 620 | transaction = transaction_new(clientP->sessionH, COAP_PUT, clientP->altPath, uriP, contextP->nextMID++, 4, NULL); |
terencez | 0:1fa43ab66921 | 621 | if (transaction == NULL) return COAP_500_INTERNAL_SERVER_ERROR; |
terencez | 0:1fa43ab66921 | 622 | |
terencez | 0:1fa43ab66921 | 623 | if (callback != NULL) |
terencez | 0:1fa43ab66921 | 624 | { |
terencez | 0:1fa43ab66921 | 625 | dm_data_t * dataP; |
terencez | 0:1fa43ab66921 | 626 | |
terencez | 0:1fa43ab66921 | 627 | dataP = (dm_data_t *)lwm2m_malloc(sizeof(dm_data_t)); |
terencez | 0:1fa43ab66921 | 628 | if (dataP == NULL) |
terencez | 0:1fa43ab66921 | 629 | { |
terencez | 0:1fa43ab66921 | 630 | transaction_free(transaction); |
terencez | 0:1fa43ab66921 | 631 | return COAP_500_INTERNAL_SERVER_ERROR; |
terencez | 0:1fa43ab66921 | 632 | } |
terencez | 0:1fa43ab66921 | 633 | memcpy(&dataP->uri, uriP, sizeof(lwm2m_uri_t)); |
terencez | 0:1fa43ab66921 | 634 | dataP->clientID = clientP->internalID; |
terencez | 0:1fa43ab66921 | 635 | dataP->callback = callback; |
terencez | 0:1fa43ab66921 | 636 | dataP->userData = userData; |
terencez | 0:1fa43ab66921 | 637 | |
terencez | 0:1fa43ab66921 | 638 | transaction->callback = prv_resultCallback; |
terencez | 0:1fa43ab66921 | 639 | transaction->userData = (void *)dataP; |
terencez | 0:1fa43ab66921 | 640 | } |
terencez | 0:1fa43ab66921 | 641 | |
terencez | 0:1fa43ab66921 | 642 | coap_pkt = (coap_packet_t *)transaction->message; |
terencez | 0:1fa43ab66921 | 643 | free_multi_option(coap_pkt->uri_query); |
terencez | 0:1fa43ab66921 | 644 | if (attrP->toSet & LWM2M_ATTR_FLAG_MIN_PERIOD) |
terencez | 0:1fa43ab66921 | 645 | { |
terencez | 0:1fa43ab66921 | 646 | memcpy(buffer, ATTR_MIN_PERIOD_STR, ATTR_MIN_PERIOD_LEN); |
terencez | 0:1fa43ab66921 | 647 | length = utils_intToText(attrP->minPeriod, buffer + ATTR_MIN_PERIOD_LEN, _PRV_BUFFER_SIZE - ATTR_MIN_PERIOD_LEN); |
terencez | 0:1fa43ab66921 | 648 | if (length == 0) |
terencez | 0:1fa43ab66921 | 649 | { |
terencez | 0:1fa43ab66921 | 650 | transaction_free(transaction); |
terencez | 0:1fa43ab66921 | 651 | return COAP_500_INTERNAL_SERVER_ERROR; |
terencez | 0:1fa43ab66921 | 652 | } |
terencez | 0:1fa43ab66921 | 653 | coap_add_multi_option(&(coap_pkt->uri_query), buffer, ATTR_MIN_PERIOD_LEN + length, 0); |
terencez | 0:1fa43ab66921 | 654 | SET_OPTION(coap_pkt, COAP_OPTION_URI_QUERY); |
terencez | 0:1fa43ab66921 | 655 | } |
terencez | 0:1fa43ab66921 | 656 | if (attrP->toSet & LWM2M_ATTR_FLAG_MAX_PERIOD) |
terencez | 0:1fa43ab66921 | 657 | { |
terencez | 0:1fa43ab66921 | 658 | memcpy(buffer, ATTR_MAX_PERIOD_STR, ATTR_MAX_PERIOD_LEN); |
terencez | 0:1fa43ab66921 | 659 | length = utils_intToText(attrP->maxPeriod, buffer + ATTR_MAX_PERIOD_LEN, _PRV_BUFFER_SIZE - ATTR_MAX_PERIOD_LEN); |
terencez | 0:1fa43ab66921 | 660 | if (length == 0) |
terencez | 0:1fa43ab66921 | 661 | { |
terencez | 0:1fa43ab66921 | 662 | transaction_free(transaction); |
terencez | 0:1fa43ab66921 | 663 | return COAP_500_INTERNAL_SERVER_ERROR; |
terencez | 0:1fa43ab66921 | 664 | } |
terencez | 0:1fa43ab66921 | 665 | coap_add_multi_option(&(coap_pkt->uri_query), buffer, ATTR_MAX_PERIOD_LEN + length, 0); |
terencez | 0:1fa43ab66921 | 666 | SET_OPTION(coap_pkt, COAP_OPTION_URI_QUERY); |
terencez | 0:1fa43ab66921 | 667 | } |
terencez | 0:1fa43ab66921 | 668 | if (attrP->toSet & LWM2M_ATTR_FLAG_GREATER_THAN) |
terencez | 0:1fa43ab66921 | 669 | { |
terencez | 0:1fa43ab66921 | 670 | memcpy(buffer, ATTR_GREATER_THAN_STR, ATTR_GREATER_THAN_LEN); |
terencez | 0:1fa43ab66921 | 671 | length = utils_floatToText(attrP->greaterThan, buffer + ATTR_GREATER_THAN_LEN, _PRV_BUFFER_SIZE - ATTR_GREATER_THAN_LEN); |
terencez | 0:1fa43ab66921 | 672 | if (length == 0) |
terencez | 0:1fa43ab66921 | 673 | { |
terencez | 0:1fa43ab66921 | 674 | transaction_free(transaction); |
terencez | 0:1fa43ab66921 | 675 | return COAP_500_INTERNAL_SERVER_ERROR; |
terencez | 0:1fa43ab66921 | 676 | } |
terencez | 0:1fa43ab66921 | 677 | coap_add_multi_option(&(coap_pkt->uri_query), buffer, ATTR_GREATER_THAN_LEN + length, 0); |
terencez | 0:1fa43ab66921 | 678 | SET_OPTION(coap_pkt, COAP_OPTION_URI_QUERY); |
terencez | 0:1fa43ab66921 | 679 | } |
terencez | 0:1fa43ab66921 | 680 | if (attrP->toSet & LWM2M_ATTR_FLAG_LESS_THAN) |
terencez | 0:1fa43ab66921 | 681 | { |
terencez | 0:1fa43ab66921 | 682 | memcpy(buffer, ATTR_LESS_THAN_STR, ATTR_LESS_THAN_LEN); |
terencez | 0:1fa43ab66921 | 683 | length = utils_floatToText(attrP->lessThan, buffer + ATTR_LESS_THAN_LEN, _PRV_BUFFER_SIZE - ATTR_LESS_THAN_LEN); |
terencez | 0:1fa43ab66921 | 684 | if (length == 0) |
terencez | 0:1fa43ab66921 | 685 | { |
terencez | 0:1fa43ab66921 | 686 | transaction_free(transaction); |
terencez | 0:1fa43ab66921 | 687 | return COAP_500_INTERNAL_SERVER_ERROR; |
terencez | 0:1fa43ab66921 | 688 | } |
terencez | 0:1fa43ab66921 | 689 | coap_add_multi_option(&(coap_pkt->uri_query), buffer, ATTR_LESS_THAN_LEN + length, 0); |
terencez | 0:1fa43ab66921 | 690 | SET_OPTION(coap_pkt, COAP_OPTION_URI_QUERY); |
terencez | 0:1fa43ab66921 | 691 | } |
terencez | 0:1fa43ab66921 | 692 | if (attrP->toSet & LWM2M_ATTR_FLAG_STEP) |
terencez | 0:1fa43ab66921 | 693 | { |
terencez | 0:1fa43ab66921 | 694 | memcpy(buffer, ATTR_STEP_STR, ATTR_STEP_LEN); |
terencez | 0:1fa43ab66921 | 695 | length = utils_floatToText(attrP->step, buffer + ATTR_STEP_LEN, _PRV_BUFFER_SIZE - ATTR_STEP_LEN); |
terencez | 0:1fa43ab66921 | 696 | if (length == 0) |
terencez | 0:1fa43ab66921 | 697 | { |
terencez | 0:1fa43ab66921 | 698 | transaction_free(transaction); |
terencez | 0:1fa43ab66921 | 699 | return COAP_500_INTERNAL_SERVER_ERROR; |
terencez | 0:1fa43ab66921 | 700 | } |
terencez | 0:1fa43ab66921 | 701 | coap_add_multi_option(&(coap_pkt->uri_query), buffer, ATTR_STEP_LEN + length, 0); |
terencez | 0:1fa43ab66921 | 702 | SET_OPTION(coap_pkt, COAP_OPTION_URI_QUERY); |
terencez | 0:1fa43ab66921 | 703 | } |
terencez | 0:1fa43ab66921 | 704 | if (attrP->toClear & LWM2M_ATTR_FLAG_MIN_PERIOD) |
terencez | 0:1fa43ab66921 | 705 | { |
terencez | 0:1fa43ab66921 | 706 | coap_add_multi_option(&(coap_pkt->uri_query), ATTR_MIN_PERIOD_STR, ATTR_MIN_PERIOD_LEN -1, 0); |
terencez | 0:1fa43ab66921 | 707 | SET_OPTION(coap_pkt, COAP_OPTION_URI_QUERY); |
terencez | 0:1fa43ab66921 | 708 | } |
terencez | 0:1fa43ab66921 | 709 | if (attrP->toClear & LWM2M_ATTR_FLAG_MAX_PERIOD) |
terencez | 0:1fa43ab66921 | 710 | { |
terencez | 0:1fa43ab66921 | 711 | coap_add_multi_option(&(coap_pkt->uri_query), ATTR_MAX_PERIOD_STR, ATTR_MAX_PERIOD_LEN - 1, 0); |
terencez | 0:1fa43ab66921 | 712 | SET_OPTION(coap_pkt, COAP_OPTION_URI_QUERY); |
terencez | 0:1fa43ab66921 | 713 | } |
terencez | 0:1fa43ab66921 | 714 | if (attrP->toClear & LWM2M_ATTR_FLAG_GREATER_THAN) |
terencez | 0:1fa43ab66921 | 715 | { |
terencez | 0:1fa43ab66921 | 716 | coap_add_multi_option(&(coap_pkt->uri_query), ATTR_GREATER_THAN_STR, ATTR_GREATER_THAN_LEN - 1, 0); |
terencez | 0:1fa43ab66921 | 717 | SET_OPTION(coap_pkt, COAP_OPTION_URI_QUERY); |
terencez | 0:1fa43ab66921 | 718 | } |
terencez | 0:1fa43ab66921 | 719 | if (attrP->toClear & LWM2M_ATTR_FLAG_LESS_THAN) |
terencez | 0:1fa43ab66921 | 720 | { |
terencez | 0:1fa43ab66921 | 721 | coap_add_multi_option(&(coap_pkt->uri_query), ATTR_LESS_THAN_STR, ATTR_LESS_THAN_LEN - 1, 0); |
terencez | 0:1fa43ab66921 | 722 | SET_OPTION(coap_pkt, COAP_OPTION_URI_QUERY); |
terencez | 0:1fa43ab66921 | 723 | } |
terencez | 0:1fa43ab66921 | 724 | if (attrP->toClear & LWM2M_ATTR_FLAG_STEP) |
terencez | 0:1fa43ab66921 | 725 | { |
terencez | 0:1fa43ab66921 | 726 | coap_add_multi_option(&(coap_pkt->uri_query), ATTR_STEP_STR, ATTR_STEP_LEN - 1, 0); |
terencez | 0:1fa43ab66921 | 727 | SET_OPTION(coap_pkt, COAP_OPTION_URI_QUERY); |
terencez | 0:1fa43ab66921 | 728 | } |
terencez | 0:1fa43ab66921 | 729 | |
terencez | 0:1fa43ab66921 | 730 | contextP->transactionList = (lwm2m_transaction_t *)LWM2M_LIST_ADD(contextP->transactionList, transaction); |
terencez | 0:1fa43ab66921 | 731 | |
terencez | 0:1fa43ab66921 | 732 | return transaction_send(contextP, transaction); |
terencez | 0:1fa43ab66921 | 733 | } |
terencez | 0:1fa43ab66921 | 734 | |
terencez | 0:1fa43ab66921 | 735 | int lwm2m_dm_discover(lwm2m_context_t * contextP, |
terencez | 0:1fa43ab66921 | 736 | uint16_t clientID, |
terencez | 0:1fa43ab66921 | 737 | lwm2m_uri_t * uriP, |
terencez | 0:1fa43ab66921 | 738 | lwm2m_result_callback_t callback, |
terencez | 0:1fa43ab66921 | 739 | void * userData) |
terencez | 0:1fa43ab66921 | 740 | { |
terencez | 0:1fa43ab66921 | 741 | lwm2m_client_t * clientP; |
terencez | 0:1fa43ab66921 | 742 | lwm2m_transaction_t * transaction; |
terencez | 0:1fa43ab66921 | 743 | dm_data_t * dataP; |
terencez | 0:1fa43ab66921 | 744 | |
terencez | 0:1fa43ab66921 | 745 | LOG_ARG("clientID: %d", clientID); |
terencez | 0:1fa43ab66921 | 746 | LOG_URI(uriP); |
terencez | 0:1fa43ab66921 | 747 | clientP = (lwm2m_client_t *)lwm2m_list_find((lwm2m_list_t *)contextP->clientList, clientID); |
terencez | 0:1fa43ab66921 | 748 | if (clientP == NULL) return COAP_404_NOT_FOUND; |
terencez | 0:1fa43ab66921 | 749 | |
terencez | 0:1fa43ab66921 | 750 | transaction = transaction_new(clientP->sessionH, COAP_GET, clientP->altPath, uriP, contextP->nextMID++, 4, NULL); |
terencez | 0:1fa43ab66921 | 751 | if (transaction == NULL) return COAP_500_INTERNAL_SERVER_ERROR; |
terencez | 0:1fa43ab66921 | 752 | |
terencez | 0:1fa43ab66921 | 753 | coap_set_header_accept(transaction->message, LWM2M_CONTENT_LINK); |
terencez | 0:1fa43ab66921 | 754 | |
terencez | 0:1fa43ab66921 | 755 | if (callback != NULL) |
terencez | 0:1fa43ab66921 | 756 | { |
terencez | 0:1fa43ab66921 | 757 | dataP = (dm_data_t *)lwm2m_malloc(sizeof(dm_data_t)); |
terencez | 0:1fa43ab66921 | 758 | if (dataP == NULL) |
terencez | 0:1fa43ab66921 | 759 | { |
terencez | 0:1fa43ab66921 | 760 | transaction_free(transaction); |
terencez | 0:1fa43ab66921 | 761 | return COAP_500_INTERNAL_SERVER_ERROR; |
terencez | 0:1fa43ab66921 | 762 | } |
terencez | 0:1fa43ab66921 | 763 | memcpy(&dataP->uri, uriP, sizeof(lwm2m_uri_t)); |
terencez | 0:1fa43ab66921 | 764 | dataP->clientID = clientP->internalID; |
terencez | 0:1fa43ab66921 | 765 | dataP->callback = callback; |
terencez | 0:1fa43ab66921 | 766 | dataP->userData = userData; |
terencez | 0:1fa43ab66921 | 767 | |
terencez | 0:1fa43ab66921 | 768 | transaction->callback = prv_resultCallback; |
terencez | 0:1fa43ab66921 | 769 | transaction->userData = (void *)dataP; |
terencez | 0:1fa43ab66921 | 770 | } |
terencez | 0:1fa43ab66921 | 771 | |
terencez | 0:1fa43ab66921 | 772 | contextP->transactionList = (lwm2m_transaction_t *)LWM2M_LIST_ADD(contextP->transactionList, transaction); |
terencez | 0:1fa43ab66921 | 773 | |
terencez | 0:1fa43ab66921 | 774 | return transaction_send(contextP, transaction); |
terencez | 0:1fa43ab66921 | 775 | } |
terencez | 0:1fa43ab66921 | 776 | |
terencez | 0:1fa43ab66921 | 777 | #endif |