Contiki-NG
lwm2m-plain-text.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2015-2018, Yanzi Networks AB.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the copyright holder nor the names of its
14 * contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
18 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
20 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
21 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
28 * OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31/**
32 * \addtogroup lwm2m
33 * @{
34 */
35
36/**
37 * \file
38 * Implementation of the Contiki OMA LWM2M plain text reader / writer
39 * \author
40 * Joakim Eriksson <joakime@sics.se>
41 * Niclas Finne <nfi@sics.se>
42 */
43
44#include "lwm2m-object.h"
45#include "lwm2m-plain-text.h"
46#include <stdio.h>
47#include <stdlib.h>
48#include <string.h>
49
50/* Log configuration */
51#include "coap-log.h"
52#define LOG_MODULE "lwm2m-text"
53#define LOG_LEVEL LOG_LEVEL_NONE
54
55/*---------------------------------------------------------------------------*/
56static size_t
57init_write(lwm2m_context_t *ctx)
58{
59 return 0;
60}
61/*---------------------------------------------------------------------------*/
62static size_t
63end_write(lwm2m_context_t *ctx)
64{
65 return 0;
66}
67/*---------------------------------------------------------------------------*/
68size_t
69lwm2m_plain_text_read_int(const uint8_t *inbuf, size_t len, int32_t *value)
70{
71 int i, neg = 0;
72 *value = 0;
73 for(i = 0; i < len; i++) {
74 if(inbuf[i] >= '0' && inbuf[i] <= '9') {
75 *value = *value * 10 + (inbuf[i] - '0');
76 } else if(inbuf[i] == '-' && i == 0) {
77 neg = 1;
78 } else {
79 break;
80 }
81 }
82 if(neg) {
83 *value = -*value;
84 }
85 return i;
86}
87/*---------------------------------------------------------------------------*/
88size_t
89lwm2m_plain_text_read_float32fix(const uint8_t *inbuf, size_t len,
90 int32_t *value, int bits)
91{
92 int i, dot = 0, neg = 0;
93 int32_t counter, integerpart, frac;
94
95 integerpart = 0;
96 counter = 0;
97 frac = 0;
98 for(i = 0; i < len; i++) {
99 if(inbuf[i] >= '0' && inbuf[i] <= '9') {
100 counter = counter * 10 + (inbuf[i] - '0');
101 frac = frac * 10;
102 } else if(inbuf[i] == '.' && dot == 0) {
103 integerpart = counter;
104 counter = 0;
105 frac = 1;
106 dot = 1;
107 } else if(inbuf[i] == '-' && i == 0) {
108 neg = 1;
109 } else {
110 break;
111 }
112 }
113 if(dot == 0) {
114 integerpart = counter;
115 counter = 0;
116 frac = 1;
117 }
118 *value = integerpart << bits;
119 if(frac > 1) {
120 *value += ((counter << bits) / frac);
121 }
122 LOG_DBG("READ FLOATFIX: \"%.*s\" => int(%ld) frac(%ld) f=%ld Value=%ld\n",
123 (int)len, (char *)inbuf,
124 (long)integerpart,
125 (long)counter,
126 (long)frac,
127 (long)*value);
128 if(neg) {
129 *value = -*value;
130 }
131
132 return i;
133}
134/*---------------------------------------------------------------------------*/
135size_t
136lwm2m_plain_text_write_float32fix(uint8_t *outbuf, size_t outlen,
137 int32_t value, int bits)
138{
139 int64_t v;
140 unsigned long integer_part;
141 unsigned long frac_part;
142 int n, o = 0;
143
144 if(outlen == 0) {
145 return 0;
146 }
147 if(value < 0) {
148 *outbuf++ = '-';
149 outlen--;
150 o = 1;
151 value = -value;
152 }
153
154 integer_part = (unsigned long)(value >> bits);
155 v = value - (integer_part << bits);
156 v = (v * 100) >> bits;
157 frac_part = (unsigned long)v;
158
159 n = snprintf((char *)outbuf, outlen, "%lu.%02lu", integer_part, frac_part);
160 if(n < 0 || n >= outlen) {
161 return 0;
162 }
163 return n + o;
164}
165/*---------------------------------------------------------------------------*/
166static size_t
167write_boolean(lwm2m_context_t *ctx, uint8_t *outbuf, size_t outlen,
168 int value)
169{
170 if(outlen > 0) {
171 if(value) {
172 *outbuf = '1';
173 } else {
174 *outbuf = '0';
175 }
176 return 1;
177 }
178 return 0;
179}
180/*---------------------------------------------------------------------------*/
181static size_t
182write_int(lwm2m_context_t *ctx, uint8_t *outbuf, size_t outlen,
183 int32_t value)
184{
185 int n = snprintf((char *)outbuf, outlen, "%ld", (long)value);
186 if(n < 0 || n >= outlen) {
187 return 0;
188 }
189 return n;
190}
191/*---------------------------------------------------------------------------*/
192static size_t
193write_float32fix(lwm2m_context_t *ctx, uint8_t *outbuf, size_t outlen,
194 int32_t value, int bits)
195{
196 return lwm2m_plain_text_write_float32fix(outbuf, outlen, value, bits);
197}
198/*---------------------------------------------------------------------------*/
199static size_t
200write_string(lwm2m_context_t *ctx, uint8_t *outbuf, size_t outlen,
201 const char *value, size_t stringlen)
202{
203 int totlen = stringlen;
204 if(stringlen >= outlen) {
205 return 0;
206 }
207 memmove(outbuf, value, totlen);
208 outbuf[totlen] = 0;
209 return totlen;
210}
211/*---------------------------------------------------------------------------*/
212const lwm2m_writer_t lwm2m_plain_text_writer = {
213 init_write,
214 end_write,
215 NULL, /* No support for sub resources here! */
216 NULL,
217 write_int,
218 write_string,
219 write_float32fix,
220 write_boolean
221};
222/*---------------------------------------------------------------------------*/
223static size_t
224read_int(lwm2m_context_t *ctx, const uint8_t *inbuf, size_t len,
225 int32_t *value)
226{
227 int size = lwm2m_plain_text_read_int(inbuf, len, value);
228 ctx->last_value_len = size;
229 return size;
230}
231/*---------------------------------------------------------------------------*/
232static size_t
233read_string(lwm2m_context_t *ctx, const uint8_t *inbuf, size_t len,
234 uint8_t *value, size_t stringlen)
235{
236 if(stringlen <= len) {
237 /* The outbuffer can not contain the full string including ending zero */
238 return 0;
239 }
240 memcpy(value, inbuf, len);
241 value[len] = '\0';
242 ctx->last_value_len = len;
243 return len;
244}
245/*---------------------------------------------------------------------------*/
246static size_t
247read_float32fix(lwm2m_context_t *ctx, const uint8_t *inbuf, size_t len,
248 int32_t *value, int bits)
249{
250 int size;
251 size = lwm2m_plain_text_read_float32fix(inbuf, len, value, bits);
252 ctx->last_value_len = size;
253 return size;
254}
255/*---------------------------------------------------------------------------*/
256static size_t
257read_boolean(lwm2m_context_t *ctx, const uint8_t *inbuf, size_t len,
258 int *value)
259{
260 if(len > 0) {
261 if(*inbuf == '1' || *inbuf == '0') {
262 *value = *inbuf == '1' ? 1 : 0;
263 ctx->last_value_len = 1;
264 return 1;
265 }
266 }
267 return 0;
268}
269/*---------------------------------------------------------------------------*/
270const lwm2m_reader_t lwm2m_plain_text_reader = {
271 read_int,
272 read_string,
273 read_float32fix,
274 read_boolean
275};
276/*---------------------------------------------------------------------------*/
277/** @} */
Log support for CoAP.
Header file for the LWM2M object API.
Header file for the Contiki OMA LWM2M plain text reader / writer.