blob: f62e9325bfa3fe9f480a419dded299dd8eacc32e [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 * Toby Jaffey - Please refer to git log
16 *
17 *******************************************************************************/
18
19/*
20 Copyright (c) 2013, 2014 Intel Corporation
21
22 Redistribution and use in source and binary forms, with or without modification,
23 are permitted provided that the following conditions are met:
24
25 * Redistributions of source code must retain the above copyright notice,
26 this list of conditions and the following disclaimer.
27 * Redistributions in binary form must reproduce the above copyright notice,
28 this list of conditions and the following disclaimer in the documentation
29 and/or other materials provided with the distribution.
30 * Neither the name of Intel Corporation nor the names of its contributors
31 may be used to endorse or promote products derived from this software
32 without specific prior written permission.
33
34 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
35 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
36 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
37 IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
38 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
39 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
40 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
41 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
42 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
43 THE POSSIBILITY OF SUCH DAMAGE.
44
45 David Navarro <david.navarro@intel.com>
46
47*/
48
49#include "internals.h"
50#include <stdlib.h>
51#include <string.h>
52#include <stdio.h>
53#include <float.h>
54
55
56int lwm2m_PlainTextToInt64(uint8_t * buffer,
57 int length,
58 int64_t * dataP)
59{
60 uint64_t result = 0;
61 int sign = 1;
62 int i = 0;
63
64 if (0 == length) return 0;
65
66 if (buffer[0] == '-')
67 {
68 sign = -1;
69 i = 1;
70 }
71
72 while (i < length)
73 {
74 if ('0' <= buffer[i] && buffer[i] <= '9')
75 {
76 if (result > (UINT64_MAX / 10)) return 0;
77 result *= 10;
78 result += buffer[i] - '0';
79 }
80 else
81 {
82 return 0;
83 }
84 i++;
85 }
86
87 if (result > INT64_MAX) return 0;
88
89 if (sign == -1)
90 {
91 *dataP = 0 - result;
92 }
93 else
94 {
95 *dataP = result;
96 }
97
98 return 1;
99}
100
101int lwm2m_PlainTextToFloat64(uint8_t * buffer,
102 int length,
103 double * dataP)
104{
105 double result;
106 int sign;
107 int i;
108
109 if (0 == length) return 0;
110
111 if (buffer[0] == '-')
112 {
113 sign = -1;
114 i = 1;
115 }
116 else
117 {
118 sign = 1;
119 i = 0;
120 }
121
122 result = 0;
123 while (i < length && buffer[i] != '.')
124 {
125 if ('0' <= buffer[i] && buffer[i] <= '9')
126 {
127 if (result > (DBL_MAX / 10)) return 0;
128 result *= 10;
129 result += (buffer[i] - '0');
130 }
131 else
132 {
133 return 0;
134 }
135 i++;
136 }
137 if (buffer[i] == '.')
138 {
139 double dec;
140
141 i++;
142 if (i == length) return 0;
143
144 dec = 0.1;
145 while (i < length)
146 {
147 if ('0' <= buffer[i] && buffer[i] <= '9')
148 {
149 if (result > (DBL_MAX - 1)) return 0;
150 result += (buffer[i] - '0') * dec;
151 dec /= 10;
152 }
153 else
154 {
155 return 0;
156 }
157 i++;
158 }
159 }
160
161 *dataP = result * sign;
162 return 1;
163}
164
165static size_t prv_intToText(int64_t data,
166 uint8_t * string,
167 size_t length)
168{
169 int index;
170 bool minus;
171
172 if (data < 0)
173 {
174 minus = true;
175 data = 0 - data;
176 }
177 else
178 {
179 minus = false;
180 }
181
182 index = length - 1;
183 do
184 {
185 string[index] = '0' + data%10;
186 data /= 10;
187 index --;
188 } while (index >= 0 && data > 0);
189
190 if (data > 0) return 0;
191
192 if (minus == true)
193 {
194 if (index == 0) return 0;
195 string[index] = '-';
196 }
197 else
198 {
199 index++;
200 }
201
202 return length - index;
203}
204
205size_t lwm2m_int64ToPlainText(int64_t data,
206 uint8_t ** bufferP)
207{
208#define _PRV_STR_LENGTH 32
209 uint8_t string[_PRV_STR_LENGTH];
210 size_t length;
211
212 length = prv_intToText(data, string, _PRV_STR_LENGTH);
213 if (length == 0) return 0;
214
215 *bufferP = (uint8_t *)lwm2m_malloc(length);
216 if (NULL == *bufferP) return 0;
217
218 memcpy(*bufferP, string + _PRV_STR_LENGTH - length, length);
219
220 return length;
221}
222
223
224size_t lwm2m_float64ToPlainText(double data,
225 uint8_t ** bufferP)
226{
227#define _PRV_PRECISION 16
228 uint8_t intString[_PRV_STR_LENGTH];
229 size_t intLength;
230 uint8_t decString[_PRV_STR_LENGTH];
231 size_t decLength;
232 int64_t intPart;
233 double decPart;
234 int i;
235
236 intPart = (int64_t)data;
237 decPart = data - intPart;
238 if (decPart < 0)
239 {
240 decPart = 1 - decPart;
241 }
242 else
243 {
244 decPart = 1 + decPart;
245 }
246
247 if (decPart <= 1 + FLT_EPSILON)
248 {
249 return lwm2m_int64ToPlainText(intPart, bufferP);
250 }
251
252 intLength = prv_intToText(intPart, intString, _PRV_STR_LENGTH);
253 if (intLength == 0) return 0;
254
255 i = 0;
256 do
257 {
258 decPart *= 10;
259 i++;
260 } while ((decPart - (int64_t)decPart > 0)
261 && (i < _PRV_PRECISION));
262
263 decLength = prv_intToText(decPart, decString, _PRV_STR_LENGTH);
264 if (decLength <= 1) return 0;
265
266 *bufferP = (uint8_t *)lwm2m_malloc(intLength + 1 + decLength);
267 if (NULL == *bufferP) return 0;
268
269 memcpy(*bufferP, intString + _PRV_STR_LENGTH - intLength, intLength);
270 (*bufferP)[intLength] = '.';
271 memcpy(*bufferP + intLength + 1, decString + _PRV_STR_LENGTH - decLength + 1, decLength - 1);
272
273 return intLength + decLength; // +1 for dot, -1 for extra "1" in decPart
274}
275
276
277size_t lwm2m_boolToPlainText(bool data,
278 uint8_t ** bufferP)
279{
280 return lwm2m_int64ToPlainText((int64_t)(data?1:0), bufferP);
281}
282
283lwm2m_binding_t lwm2m_stringToBinding(uint8_t * buffer,
284 size_t length)
285{
286 if (length == 0) return BINDING_UNKNOWN;
287
288 switch (buffer[0])
289 {
290 case 'U':
291 switch (length)
292 {
293 case 1:
294 return BINDING_U;
295 case 2:
296 switch (buffer[1])
297 {
298 case 'Q':
299 return BINDING_UQ;
300 case 'S':
301 return BINDING_US;
302 default:
303 break;
304 }
305 break;
306 case 3:
307 if (buffer[1] == 'Q' && buffer[2] == 'S')
308 {
309 return BINDING_UQS;
310 }
311 break;
312 default:
313 break;
314 }
315 break;
316
317 case 'S':
318 switch (length)
319 {
320 case 1:
321 return BINDING_S;
322 case 2:
323 if (buffer[1] == 'Q')
324 {
325 return BINDING_SQ;
326 }
327 break;
328 default:
329 break;
330 }
331 break;
332
333 default:
334 break;
335 }
336
337 return BINDING_UNKNOWN;
338}
339
340#ifdef LWM2M_CLIENT_MODE
341lwm2m_server_t * prv_findServer(lwm2m_context_t * contextP,
342 void * fromSessionH)
343{
344 lwm2m_server_t * targetP;
345
346 targetP = contextP->serverList;
347 while (targetP != NULL
348 && targetP->sessionH != fromSessionH)
349 {
350 targetP = targetP->next;
351 }
352
353 return targetP;
354}
355#endif
356
357lwm2m_server_t * utils_findBootstrapServer(lwm2m_context_t * contextP,
358 void * fromSessionH)
359{
360#ifdef LWM2M_CLIENT_MODE
361
362 lwm2m_server_t * targetP;
363
364 targetP = contextP->bootstrapServerList;
365 while (targetP != NULL
366 && targetP->sessionH != fromSessionH)
367 {
368 targetP = targetP->next;
369 }
370
371 return targetP;
372
373#else
374
375 return NULL;
376
377#endif
378}
379
380int prv_isAltPathValid(const char * altPath)
381{
382 int i;
383
384 if (altPath == NULL) return 0;
385
386 if (altPath[0] != '/') return 0;
387
388 for (i = 1 ; altPath[i] != 0 ; i++)
389 {
390 // TODO: Support multi-segment alternative path
391 if (altPath[i] == '/') return 0;
392 // TODO: Check needs for sub-delims, ':' and '@'
393 if ((altPath[i] < 'A' || altPath[i] > 'Z') // ALPHA
394 && (altPath[i] < 'a' || altPath[i] > 'z')
395 && (altPath[i] < '0' || altPath[i] > '9') // DIGIT
396 && (altPath[i] != '-') // Other unreserved
397 && (altPath[i] != '.')
398 && (altPath[i] != '_')
399 && (altPath[i] != '~')
400 && (altPath[i] != '%')) // pct_encoded
401 {
402 return 0;
403 }
404
405 }
406 return 1;
407}
408
409#ifndef LWM2M_EMBEDDED_MODE
410time_t lwm2m_gettime(void)
411{
412 struct timeval tv;
413
414 if (0 != gettimeofday(&tv, NULL))
415 {
416 return -1;
417 }
418
419 return tv.tv_sec;
420}
421#endif