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 */
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
63static const lwm2m_resource_id_t resources[] =
64 {
65 RW(IPSO_ONOFF),
66 RW(IPSO_DIMMER),
67 RW(IPSO_ON_TIME)
68 };
69/*---------------------------------------------------------------------------*/
70lwm2m_status_t
71ipso_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/*---------------------------------------------------------------------------*/
87lwm2m_status_t
88ipso_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/*---------------------------------------------------------------------------*/
125static lwm2m_status_t
126lwm2m_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/*---------------------------------------------------------------------------*/
194int
195ipso_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/*---------------------------------------------------------------------------*/
205int
206ipso_control_remove(ipso_control_t *control)
207{
208 lwm2m_engine_remove_object(&control->reg_object);
209 return 1;
210}
211/*---------------------------------------------------------------------------*/
212/** @} */
CoAP timer API.
static uint64_t coap_timer_uptime(void)
Get the time since boot in milliseconds.
Definition: coap-timer.h:83
Implementation of OMA LWM2M / IPSO sensor template.
Header file for the Contiki OMA LWM2M engine.