Contiki-NG
ipso-control-template.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2016, SICS Swedish ICT 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 ipso-objects
33  * @{
34  *
35  */
36 
37 /**
38  * \file
39  * Implementation of OMA LWM2M / IPSO control template.
40  * Useful for implementing controllable objects
41  * \author
42  * Joakim Eriksson <joakime@sics.se>
43  * Niclas Finne <nfi@sics.se>
44  */
45 #include "ipso-control-template.h"
46 #include "lwm2m-engine.h"
47 #include "coap-timer.h"
48 #include <inttypes.h>
49 #include <string.h>
50 
51 #define DEBUG 0
52 #if DEBUG
53 #include <stdio.h>
54 #define PRINTF(...) printf(__VA_ARGS__)
55 #else
56 #define PRINTF(...)
57 #endif
58 
59 #define IPSO_ONOFF 5850
60 #define IPSO_DIMMER 5851
61 #define IPSO_ON_TIME 5852
62 
63 static const lwm2m_resource_id_t resources[] =
64  {
65  RW(IPSO_ONOFF),
66  RW(IPSO_DIMMER),
67  RW(IPSO_ON_TIME)
68  };
69 /*---------------------------------------------------------------------------*/
70 lwm2m_status_t
71 ipso_control_set_on(ipso_control_t *control, uint8_t onoroff)
72 {
73  uint8_t v;
74 
75  if(onoroff) {
76  v = control->value & 0x7f;
77  if(v == 0) {
78  v = 100;
79  }
80  } else {
81  v = 0;
82  }
83 
84  return ipso_control_set_value(control, v);
85 }
86 /*---------------------------------------------------------------------------*/
87 lwm2m_status_t
88 ipso_control_set_value(ipso_control_t *control, uint8_t value)
89 {
90  lwm2m_status_t status = LWM2M_STATUS_OK;
91  int was_on;
92 
93  was_on = ipso_control_is_on(control);
94 
95  if(value == 0) {
96  if(was_on) {
97  /* Turn off */
98  status = control->set_value(control, 0);
99  if(status == LWM2M_STATUS_OK) {
100  control->value &= 0x7f;
101  control->on_time +=
102  (coap_timer_uptime() - control->last_on_time) / 1000;
103  }
104  }
105  } else {
106  /* Restrict value between 0 - 100 */
107  if(value > 100) {
108  value = 100;
109  }
110  value |= 0x80;
111 
112  if(value != control->value) {
113  status = control->set_value(control, value & 0x7f);
114  if(status == LWM2M_STATUS_OK) {
115  control->value = value;
116  if(! was_on) {
117  control->last_on_time = coap_timer_uptime();
118  }
119  }
120  }
121  }
122  return status;
123 }
124 /*---------------------------------------------------------------------------*/
125 static lwm2m_status_t
126 lwm2m_callback(lwm2m_object_instance_t *object, lwm2m_context_t *ctx)
127 {
128  ipso_control_t *control;
129  int32_t v;
130 
131  /* Here we cast to our sensor-template struct */
132  control = (ipso_control_t *)object;
133 
134  if(ctx->operation == LWM2M_OP_READ) {
135  switch(ctx->resource_id) {
136  case IPSO_ONOFF:
137  v = ipso_control_is_on(control) ? 1 : 0;
138  break;
139  case IPSO_DIMMER:
140  v = ipso_control_get_value(control);
141  break;
142  case IPSO_ON_TIME:
143  v = control->on_time;
144  if(ipso_control_is_on(control)) {
145  v += (coap_timer_uptime() - control->last_on_time) / 1000;
146  }
147  PRINTF("ON-TIME: %"PRId32" (last on: %"PRIu32"\n", v, control->on_time);
148  break;
149  default:
150  return LWM2M_STATUS_ERROR;
151  }
152  lwm2m_object_write_int(ctx, v);
153  return LWM2M_STATUS_OK;
154 
155  } else if(ctx->operation == LWM2M_OP_WRITE) {
156  switch(ctx->resource_id) {
157  case IPSO_ONOFF:
158  if(lwm2m_object_read_int(ctx, ctx->inbuf->buffer, ctx->inbuf->size, &v) == 0) {
159  return LWM2M_STATUS_ERROR;
160  }
161  return ipso_control_set_on(control, v > 0);
162  case IPSO_DIMMER:
163  if(lwm2m_object_read_int(ctx, ctx->inbuf->buffer, ctx->inbuf->size, &v) == 0) {
164  return LWM2M_STATUS_ERROR;
165  }
166  if(v < 0) {
167  v = 0;
168  } else if(v > 100) {
169  v = 100;
170  }
171  return ipso_control_set_value(control, v & 0xff);
172  case IPSO_ON_TIME:
173  if(lwm2m_object_read_int(ctx, ctx->inbuf->buffer, ctx->inbuf->size, &v) == 0) {
174  return LWM2M_STATUS_ERROR;
175  }
176 
177  if(v == 0) {
178  control->on_time = 0;
179  control->last_on_time = coap_timer_uptime();
180  return LWM2M_STATUS_OK;
181  } else {
182  /* Only allowed to write 0 to reset ontime */
183  return LWM2M_STATUS_FORBIDDEN;
184  }
185  break;
186  default:
187  return LWM2M_STATUS_ERROR;
188  }
189  } else {
190  return LWM2M_STATUS_OPERATION_NOT_ALLOWED;
191  }
192 }
193 /*---------------------------------------------------------------------------*/
194 int
195 ipso_control_add(ipso_control_t *control)
196 {
197  control->reg_object.resource_ids = resources;
198  control->reg_object.resource_count =
199  sizeof(resources) / sizeof(lwm2m_resource_id_t);
200 
201  control->reg_object.callback = lwm2m_callback;
202  return lwm2m_engine_add_object(&control->reg_object);
203 }
204 /*---------------------------------------------------------------------------*/
205 int
206 ipso_control_remove(ipso_control_t *control)
207 {
208  lwm2m_engine_remove_object(&control->reg_object);
209  return 1;
210 }
211 /*---------------------------------------------------------------------------*/
212 /** @} */
Implementation of OMA LWM2M / IPSO sensor template.
CoAP timer API.
static uint64_t coap_timer_uptime(void)
Get the time since boot in milliseconds.
Definition: coap-timer.h:83
Header file for the Contiki OMA LWM2M engine