blob: 9aeb03dde811630370cbfcf19165ffa1067b0342 [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001/*******************************************************************************
2 *
3 * Copyright (c) 2013, 2014 Intel Corporation and others.
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * and Eclipse Distribution License v1.0 which accompany this distribution.
7 *
8 * The Eclipse Public License is available at
9 * http://www.eclipse.org/legal/epl-v10.html
10 * The Eclipse Distribution License is available at
11 * http://www.eclipse.org/org/documents/edl-v10.php.
12 *
13 * Contributors:
14 * David Navarro, Intel Corporation - initial API and implementation
15 * Fabien Fleutot - Please refer to git log
16 * Toby Jaffey - Please refer to git log
17 * Bosch Software Innovations GmbH - Please refer to git log
18 * Pascal Rieux - Please refer to git log
19 *
20 *******************************************************************************/
21
22/*
23 Copyright (c) 2013, 2014 Intel Corporation
24
25 Redistribution and use in source and binary forms, with or without modification,
26 are permitted provided that the following conditions are met:
27
28 * Redistributions of source code must retain the above copyright notice,
29 this list of conditions and the following disclaimer.
30 * Redistributions in binary form must reproduce the above copyright notice,
31 this list of conditions and the following disclaimer in the documentation
32 and/or other materials provided with the distribution.
33 * Neither the name of Intel Corporation nor the names of its contributors
34 may be used to endorse or promote products derived from this software
35 without specific prior written permission.
36
37 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
38 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
39 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
40 IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
41 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
42 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
43 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
44 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
45 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
46 THE POSSIBILITY OF SUCH DAMAGE.
47
48 David Navarro <david.navarro@intel.com>
49
50*/
51
52#include "internals.h"
53#include <stdlib.h>
54#include <string.h>
55#include <ctype.h>
56
57
58static int prv_parse_number(uint8_t * uriString,
59 size_t uriLength,
60 size_t * headP)
61{
62 int result = 0;
63
64 if (uriString[*headP] == '/')
65 {
66 // empty Object Instance ID with resource ID is not allowed
67 return -1;
68 }
69 while (*headP < uriLength && uriString[*headP] != '/')
70 {
71 if ('0' <= uriString[*headP] && uriString[*headP] <= '9')
72 {
73 result += uriString[*headP] - '0';
74 result *= 10;
75 }
76 else
77 {
78 return -1;
79 }
80 *headP += 1;
81 }
82
83 result /= 10;
84 return result;
85}
86
87
88int prv_get_number(uint8_t * uriString,
89 size_t uriLength)
90{
91 size_t index = 0;
92
93 return prv_parse_number(uriString, uriLength, &index);
94}
95
96
97lwm2m_uri_t * lwm2m_decode_uri(char * altPath,
98 multi_option_t *uriPath)
99{
100 lwm2m_uri_t * uriP;
101 int readNum;
102
103 uriP = (lwm2m_uri_t *)lwm2m_malloc(sizeof(lwm2m_uri_t));
104 if (NULL == uriP) return NULL;
105
106 memset(uriP, 0, sizeof(lwm2m_uri_t));
107
108 // Read object ID
109 if (NULL != uriPath
110 && URI_REGISTRATION_SEGMENT_LEN == uriPath->len
111 && 0 == strncmp(URI_REGISTRATION_SEGMENT, (char *)uriPath->data, uriPath->len))
112 {
113 uriP->flag |= LWM2M_URI_FLAG_REGISTRATION;
114 uriPath = uriPath->next;
115 if (uriPath == NULL) return uriP;
116 }
117 else if (NULL != uriPath
118 && URI_BOOTSTRAP_SEGMENT_LEN == uriPath->len
119 && 0 == strncmp(URI_BOOTSTRAP_SEGMENT, (char *)uriPath->data, uriPath->len))
120 {
121 uriP->flag |= LWM2M_URI_FLAG_BOOTSTRAP;
122 uriPath = uriPath->next;
123 if (uriPath != NULL) goto error;
124 return uriP;
125 }
126
127 if ((uriP->flag & LWM2M_URI_MASK_TYPE) != LWM2M_URI_FLAG_REGISTRATION)
128 {
129 // Read altPath if any
130 if (altPath != NULL)
131 {
132 int i;
133 if (NULL == uriPath)
134 {
135 lwm2m_free(uriP);
136 return NULL;
137 }
138 for (i = 0 ; i < uriPath->len ; i++)
139 {
140 if (uriPath->data[i] != altPath[i+1])
141 {
142 lwm2m_free(uriP);
143 return NULL;
144 }
145 }
146 uriPath = uriPath->next;
147 }
148 if (NULL == uriPath || uriPath->len == 0)
149 {
150 uriP->flag |= LWM2M_URI_FLAG_DELETE_ALL;
151 return uriP;
152 }
153 }
154
155 readNum = prv_get_number(uriPath->data, uriPath->len);
156 if (readNum < 0 || readNum > LWM2M_MAX_ID) goto error;
157 uriP->objectId = (uint16_t)readNum;
158 uriP->flag |= LWM2M_URI_FLAG_OBJECT_ID;
159 uriPath = uriPath->next;
160
161 if ((uriP->flag & LWM2M_URI_MASK_TYPE) == LWM2M_URI_FLAG_REGISTRATION)
162 {
163 if (uriPath != NULL) goto error;
164 return uriP;
165 }
166 uriP->flag |= LWM2M_URI_FLAG_DM;
167
168 if (uriPath == NULL) return uriP;
169
170 // Read object instance
171 if (uriPath->len != 0)
172 {
173 readNum = prv_get_number(uriPath->data, uriPath->len);
174 if (readNum < 0 || readNum >= LWM2M_MAX_ID) goto error;
175 uriP->instanceId = (uint16_t)readNum;
176 uriP->flag |= LWM2M_URI_FLAG_INSTANCE_ID;
177 }
178 uriPath = uriPath->next;
179
180 if (uriPath == NULL) return uriP;
181
182 // Read resource ID
183 if (uriPath->len != 0)
184 {
185 // resource ID without an instance ID is not allowed
186 if ((uriP->flag & LWM2M_URI_FLAG_INSTANCE_ID) == 0) goto error;
187
188 readNum = prv_get_number(uriPath->data, uriPath->len);
189 if (readNum < 0 || readNum > LWM2M_MAX_ID) goto error;
190 uriP->resourceId = (uint16_t)readNum;
191 uriP->flag |= LWM2M_URI_FLAG_RESOURCE_ID;
192 }
193
194 // must be the last segment
195 if (NULL == uriPath->next) return uriP;
196
197error:
198 lwm2m_free(uriP);
199 return NULL;
200}
201
202int lwm2m_stringToUri(const char * buffer,
203 size_t buffer_len,
204 lwm2m_uri_t * uriP)
205{
206 size_t head;
207 int readNum;
208
209 if (buffer == NULL || buffer_len == 0 || uriP == NULL) return 0;
210
211 memset(uriP, 0, sizeof(lwm2m_uri_t));
212
213 // Skip any white space
214 head = 0;
215 while (head < buffer_len && isspace(buffer[head]&0xFF))
216 {
217 head++;
218 }
219 if (head == buffer_len) return 0;
220
221 // Check the URI start with a '/'
222 if (buffer[head] != '/') return 0;
223 head++;
224 if (head == buffer_len) return 0;
225
226 // Read object ID
227 readNum = prv_parse_number((uint8_t *)buffer, buffer_len, &head);
228 if (readNum < 0 || readNum > LWM2M_MAX_ID) return 0;
229 uriP->objectId = (uint16_t)readNum;
230 uriP->flag |= LWM2M_URI_FLAG_OBJECT_ID;
231
232 if (buffer[head] == '/') head += 1;
233 if (head >= buffer_len) return head;
234
235 readNum = prv_parse_number((uint8_t *)buffer, buffer_len, &head);
236 if (readNum < 0 || readNum >= LWM2M_MAX_ID) return 0;
237 uriP->instanceId = (uint16_t)readNum;
238 uriP->flag |= LWM2M_URI_FLAG_INSTANCE_ID;
239
240 if (buffer[head] == '/') head += 1;
241 if (head >= buffer_len) return head;
242
243 readNum = prv_parse_number((uint8_t *)buffer, buffer_len, &head);
244 if (readNum < 0 || readNum >= LWM2M_MAX_ID) return 0;
245 uriP->resourceId = (uint16_t)readNum;
246 uriP->flag |= LWM2M_URI_FLAG_RESOURCE_ID;
247
248 if (head != buffer_len) return 0;
249
250 return head;
251}
252