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 /*---------------------------------------------------------------------------*/
56 static size_t
57 init_write(lwm2m_context_t *ctx)
58 {
59  return 0;
60 }
61 /*---------------------------------------------------------------------------*/
62 static size_t
63 end_write(lwm2m_context_t *ctx)
64 {
65  return 0;
66 }
67 /*---------------------------------------------------------------------------*/
68 size_t
69 lwm2m_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 /*---------------------------------------------------------------------------*/
88 size_t
89 lwm2m_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 /*---------------------------------------------------------------------------*/
135 size_t
136 lwm2m_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 /*---------------------------------------------------------------------------*/
166 static size_t
167 write_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 /*---------------------------------------------------------------------------*/
181 static size_t
182 write_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 /*---------------------------------------------------------------------------*/
192 static size_t
193 write_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 /*---------------------------------------------------------------------------*/
199 static size_t
200 write_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 /*---------------------------------------------------------------------------*/
212 const 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 /*---------------------------------------------------------------------------*/
223 static size_t
224 read_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 /*---------------------------------------------------------------------------*/
232 static size_t
233 read_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 /*---------------------------------------------------------------------------*/
246 static size_t
247 read_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 /*---------------------------------------------------------------------------*/
256 static size_t
257 read_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 /*---------------------------------------------------------------------------*/
270 const 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